From ef72ebf918820cf098876aed5238bb8f8df5d171 Mon Sep 17 00:00:00 2001 From: MartinChoo <214582617@qq.com> Date: Tue, 5 Aug 2025 22:43:12 +0800 Subject: [PATCH] Enable cksum on compress db Signed-off-by: MartinChoo <214582617@qq.com> --- patch/0012-Bugfix-on-current-version.patch | 50 +++++++++---- unittest/sqlite_cksum_test.cpp | 83 +++++++++++++++++++--- unittest/sqlite_compress_test.cpp | 2 + 3 files changed, 112 insertions(+), 23 deletions(-) diff --git a/patch/0012-Bugfix-on-current-version.patch b/patch/0012-Bugfix-on-current-version.patch index c722412..380ce4e 100644 --- a/patch/0012-Bugfix-on-current-version.patch +++ b/patch/0012-Bugfix-on-current-version.patch @@ -1,15 +1,17 @@ -From 7aa46d5a0145d24168cb25d0d8d5ce78b259ec63 Mon Sep 17 00:00:00 2001 +From cb6159523c20f6c9d0545d0a45b605743ef59c21 Mon Sep 17 00:00:00 2001 From: MartinChoo <214582617@qq.com> -Date: Fri, 1 Aug 2025 11:03:54 +0800 +Date: Tue, 5 Aug 2025 22:40:40 +0800 Subject: [PATCH] Bugfix on current version +Signed-off-by: MartinChoo <214582617@qq.com> --- - ext/misc/cksumvfs.c | 13 +- + ext/misc/cksumvfs.c | 11 +- + src/compressvfs.c | 5 +- src/sqlite3.c | 297 +++++++++++++++++++++++++++++++++++--------- - 2 files changed, 247 insertions(+), 63 deletions(-) + 3 files changed, 249 insertions(+), 64 deletions(-) diff --git a/ext/misc/cksumvfs.c b/ext/misc/cksumvfs.c -index c6ac60f..8705751 100644 +index 27b1028..e89edcd 100644 --- a/ext/misc/cksumvfs.c +++ b/ext/misc/cksumvfs.c @@ -559,17 +559,17 @@ static int cksmRead( @@ -51,17 +53,37 @@ index c6ac60f..8705751 100644 ){ ((u8*)zBuf)[iAmt-CKSUMVFS_RESERVED_SIZE]=CKSUMVFS_MAGIC_NUM; ((u8*)zBuf)[iAmt-CKSUMVFS_RESERVED_SIZE+1]=p->verifyCksm ? CKSUMVFS_CALC_CHECKSUM : CKSUMVFS_WITHOUT_CHECKSUM; -@@ -967,7 +966,7 @@ static int cksmRegisterVfs(void){ - cksm_vfs.iVersion = pOrig->iVersion; - cksm_vfs.pAppData = pOrig; - cksm_vfs.szOsFile = pOrig->szOsFile + sizeof(CksmFile); -- rc = sqlite3_vfs_register(&cksm_vfs, 0); -+ rc = sqlite3_vfs_register(&cksm_vfs, 1); - if( rc==SQLITE_OK ){ - rc = sqlite3_auto_extension((void(*)(void))cksmRegisterFunc); +diff --git a/src/compressvfs.c b/src/compressvfs.c +index f2fe169..b6f1681 100644 +--- a/src/compressvfs.c ++++ b/src/compressvfs.c +@@ -151,6 +151,7 @@ typedef INT8_TYPE i8; /* 1-byte signed integer */ + typedef u32 Pgno; + /* VFS's name */ + #define COMPRESS_VFS_NAME "compressvfs" ++#define CKSM_VFS_NAME "cksmvfs" + + /* COMPRESSION OPTIONS */ + #define COMPRESSION_UNDEFINED 0 +@@ -919,14 +920,14 @@ static int compressOpen( + } + + pFile->pMethods = &compress_io_methods; +- rc = sqlite3_open_v2(zName, &pCompress->pDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, ORIGVFS(pVfs)->zName); ++ rc = sqlite3_open_v2(zName, &pCompress->pDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, CKSM_VFS_NAME); + if( rc!=SQLITE_OK ){ + rc = SQLITE_CANTOPEN; + goto open_end; } + pCompress->bOutterDbOpen = 1; + sqlite3 *db = pCompress->pDb; +- const char *pre_pragma = "PRAGMA page_size=4096;"\ ++ const char *pre_pragma = "PRAGMA checksum_persist_enable=ON;PRAGMA page_size=4096;"\ + "PRAGMA auto_vacuum=INCREMENTAL;PRAGMA journal_mode=OFF;"; + sqlite3_busy_timeout(db, 2000); // Set time out:2s + rc = sqlite3_exec(db, pre_pragma, NULL, NULL, NULL); diff --git a/src/sqlite3.c b/src/sqlite3.c -index 2953517..1e8fc0f 100644 +index d5d6627..2bd0b71 100644 --- a/src/sqlite3.c +++ b/src/sqlite3.c @@ -5363,7 +5363,7 @@ SQLITE_API int sqlite3_set_droptable_handle(sqlite3*, void (*xFunc)(sqlite3*,con diff --git a/unittest/sqlite_cksum_test.cpp b/unittest/sqlite_cksum_test.cpp index fe066e4..1a344a2 100644 --- a/unittest/sqlite_cksum_test.cpp +++ b/unittest/sqlite_cksum_test.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -45,12 +46,15 @@ public: void SetUp(); void TearDown(); - static void UtSqliteLogPrint(const void *data, int err, const char *msg); + static void UtSqliteLogPrint(void *data, int err, const char *msg); static void UtBackupDatabase(sqlite3 *srcDb, sqlite3 *destDb); - static void UtPresetDb(const std::string &dbFile, bool enableCksum); + static void UtPresetDb(const std::string &dbFile, const std::string &vfsStr); static int UtSqliteExecCallback(void *data, int argc, char **argv, char **azColName); + static int hitCksmFault_; }; +int SQLiteCksumTest::hitCksmFault_ = 0; + void SQLiteCksumTest::SetUpTestCase(void) { Common::RemoveDir(TEST_DIR); @@ -63,7 +67,7 @@ void SQLiteCksumTest::TearDownTestCase(void) void SQLiteCksumTest::SetUp(void) { - sqlite3_config(SQLITE_CONFIG_LOG, &SQLiteCksumTest::UtSqliteLogPrint, NULL); + sqlite3_config(SQLITE_CONFIG_LOG, &SQLiteCksumTest::UtSqliteLogPrint, nullptr); EXPECT_EQ(sqlite3_register_cksumvfs(NULL), SQLITE_OK); } @@ -73,8 +77,13 @@ void SQLiteCksumTest::TearDown(void) sqlite3_config(SQLITE_CONFIG_LOG, NULL, NULL); } -void SQLiteCksumTest::UtSqliteLogPrint(const void *data, int err, const char *msg) +void SQLiteCksumTest::UtSqliteLogPrint(void *data, int err, const char *msg) { + std::string errStr = msg; + if (errStr.find("checksum fault") != std::string::npos) { + std::cout << "Hit checksum fault!!!" << std::endl; + hitCksmFault_++; + } std::cout << "SQLiteCksumTest xLog err:" << err << ", msg:" << msg << std::endl; } @@ -97,22 +106,27 @@ void SQLiteCksumTest::UtBackupDatabase(sqlite3 *srcDb, sqlite3 *destDb) sqlite3_backup_finish(back); } -void SQLiteCksumTest::UtPresetDb(const std::string &dbFile, bool enableCksum) +void SQLiteCksumTest::UtPresetDb(const std::string &dbFile, const std::string &vfsStr) { /** * @tc.steps: step1. Prepare db used to simulate corrupted * @tc.expected: step1. Execute successfully */ sqlite3 *db = NULL; - std::string dbFileUri = enableCksum ? "file:" : ""; + std::string dbFileUri = vfsStr.empty() ? "" : "file:"; dbFileUri += dbFile; - dbFileUri += enableCksum ? "?vfs=cksmvfs" : ""; + if (vfsStr.empty()) { + dbFileUri += ""; + } else { + dbFileUri += "?vfs="; + dbFileUri += vfsStr; + } EXPECT_EQ(sqlite3_open(dbFileUri.c_str(), &db), SQLITE_OK); /** * @tc.steps: step1. Enable cksumvfs using PRAGMA checksum_persist_enable, * @tc.expected: step1. Execute successfully */ - if (enableCksum) { + if (!vfsStr.empty()) { EXPECT_EQ(sqlite3_exec(db, "PRAGMA checksum_persist_enable=ON;", NULL, NULL, NULL), SQLITE_OK); } EXPECT_EQ(sqlite3_exec(db, "PRAGMA meta_double_write=enabled;", NULL, NULL, NULL), SQLITE_OK); @@ -162,7 +176,7 @@ HWTEST_F(SQLiteCksumTest, CksumTest001, TestSize.Level0) * @tc.expected: step1. Execute successfully */ std::string dbPath = TEST_DIR "/test001.db"; - UtPresetDb(dbPath, false); + UtPresetDb(dbPath, ""); sqlite3 *db = nullptr; EXPECT_EQ(sqlite3_open(dbPath.c_str(), &db),SQLITE_OK); @@ -181,6 +195,7 @@ HWTEST_F(SQLiteCksumTest, CksumTest001, TestSize.Level0) EXPECT_EQ(sqlite3_exec(slaveDb, "PRAGMA journal_mode=WAL;", NULL, NULL, NULL), SQLITE_OK); UtBackupDatabase(db, slaveDb); sqlite3_close(slaveDb); + sqlite3_close(db); /** * @tc.steps: step3. Open slave db, make an integrity check * @tc.expected: step3. Execute successfully @@ -191,4 +206,54 @@ HWTEST_F(SQLiteCksumTest, CksumTest001, TestSize.Level0) sqlite3_close(slaveDb); } +static int UtQueryResult(void *data, int argc, char **argv, char **azColName) +{ + int count = *static_cast(data); + *static_cast(data) = count + 1; + // 2 means 2 fields, entryId, entryName + EXPECT_EQ(argc, 2); + return SQLITE_OK; +} + +static void UtDestroyFile(const std::string &dbPath, int offset, const std::string replaceStr) +{ + int fd = open(dbPath.c_str(), O_WRONLY | O_CREAT); + lseek(fd, offset, SEEK_SET); + write(fd, replaceStr.c_str(), replaceStr.size()); + close(fd); +} + +/** + * @tc.name: CksumTest002 + * @tc.desc: Test to enable cksum on compress db + * @tc.type: FUNC + */ +HWTEST_F(SQLiteCksumTest, CksumTest002, TestSize.Level0) +{ + /** + * @tc.steps: step1. Create a new db as main, enable compress + * @tc.expected: step1. Execute successfully + */ + std::string dbPath = TEST_DIR "/test002.db"; + UtPresetDb(dbPath, "compressvfs"); + /** + * @tc.steps: step2. Destory the db file to simulate corrupted + * @tc.expected: step2. Execute successfully + */ + // 2 * 4096 + 512 means the corrupted position, which locate on the third page, 512 bytes offset + UtDestroyFile(dbPath, 2 * 4096 + 512, "123"); + /** + * @tc.steps: step3. Reverse the table to get the info, check log info, should print "checksum fault" + * @tc.expected: step3. Execute successfully + */ + hitCksmFault_ = 0; + sqlite3 *db = nullptr; + EXPECT_EQ(sqlite3_open_v2(dbPath.c_str(), &db, SQLITE_OPEN_READWRITE, "compressvfs"),SQLITE_OK); + int count = 0; + EXPECT_EQ(sqlite3_exec(db, "SELECT entryId, entryName FROM salary;", UtQueryResult, &count, nullptr), SQLITE_OK); + EXPECT_EQ(hitCksmFault_, 1); + EXPECT_EQ(count, TEST_PRESET_DATA_COUNT); + sqlite3_close_v2(db); +} + } // namespace Test diff --git a/unittest/sqlite_compress_test.cpp b/unittest/sqlite_compress_test.cpp index 5d715bc..c86d2b6 100644 --- a/unittest/sqlite_compress_test.cpp +++ b/unittest/sqlite_compress_test.cpp @@ -99,10 +99,12 @@ void SQLiteCompressTest::SetUpTestCase(void) { Common::RemoveDir(TEST_DIR); Common::MakeDir(TEST_DIR); + EXPECT_EQ(sqlite3_register_cksumvfs(NULL), SQLITE_OK); } void SQLiteCompressTest::TearDownTestCase(void) { + EXPECT_EQ(sqlite3_unregister_cksumvfs(), SQLITE_OK); } void SQLiteCompressTest::SetUp(void) -- Gitee