1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #define LOG_TAG "RdbDoubleWriteBinlogTest"
17 #include <gtest/gtest.h>
18 #include <sys/stat.h>
19 #include <sqlite3sym.h>
20 #include <unistd.h>
21
22 #include <iostream>
23 #include <filesystem>
24 #include <chrono>
25 #include <cstdlib>
26 #include <fstream>
27 #include <string>
28
29 #include "common.h"
30 #include "file_ex.h"
31 #include "logger.h"
32 #include "rdb_common.h"
33 #include "rdb_errno.h"
34 #include "rdb_helper.h"
35 #include "rdb_open_callback.h"
36 #include "relational/relational_store_sqlite_ext.h"
37 #include "sqlite3.h"
38 #include "sqlite_connection.h"
39 #include "sqlite_utils.h"
40 #include "sqlite_global_config.h"
41 #include "sys/types.h"
42
43 using namespace testing::ext;
44 using namespace OHOS::NativeRdb;
45 using namespace OHOS::Rdb;
46
47 class RdbDoubleWriteBinlogTest : public testing::Test {
48 public:
49 static void SetUpTestCase(void);
50 static void TearDownTestCase(void);
51 void SetUp();
52 void TearDown();
53 static void CheckNumber(
54 std::shared_ptr<RdbStore> &store, int num, int errCode = E_OK, const std::string &tableName = "test");
55 static bool CheckFolderExist(const std::string &path);
56 void RemoveFolder(const std::string &path);
57 static void Insert(int64_t start, int count, bool isSlave = false, int dataSize = 0);
58 static void InsertNativeConn(sqlite3 *db, int64_t start, int count, int dataSize = 0);
59 void Update(int64_t start, int count, bool isSlave = false, int dataSize = 0);
60 void CheckProcess(std::shared_ptr<RdbStore> &store);
61 void DeleteDbFile(const RdbStoreConfig &config);
62 void PutValue(std::shared_ptr<RdbStore> &store, const std::string &data, int64_t id, int age);
63 static void WaitForBackupFinish(int32_t expectStatus, int maxTimes = 4000);
64 static void WaitForBinlogDelete(int maxTimes = 1000);
65 static void WaitForBinlogReplayFinish();
66 void InitDb(HAMode mode = HAMode::MAIN_REPLICA, bool isOpenSlave = true);
67 int64_t GetRestoreTime(HAMode haMode, bool isOpenSlave = true);
68
69 static const std::string databaseName;
70 static const std::string slaveDatabaseName;
71 static const std::string binlogDatabaseName;
72 static std::shared_ptr<RdbStore> store;
73 static std::shared_ptr<RdbStore> slaveStore;
74 static const std::string insertSql;
75
76 enum SlaveStatus : uint32_t {
77 UNDEFINED,
78 BACKING_UP,
79 BACKUP_INTERRUPT,
80 BACKUP_FINISHED,
81 DB_CLOSING,
82 };
83 };
84
85 const std::string RdbDoubleWriteBinlogTest::databaseName = RDB_TEST_PATH + "dual_write_binlog_test.db";
86 const std::string RdbDoubleWriteBinlogTest::slaveDatabaseName = RDB_TEST_PATH + "dual_write_binlog_test_slave.db";
87 const std::string RdbDoubleWriteBinlogTest::binlogDatabaseName = RDB_TEST_PATH + "dual_write_binlog_test.db_binlog";
88 std::shared_ptr<RdbStore> RdbDoubleWriteBinlogTest::store = nullptr;
89 std::shared_ptr<RdbStore> RdbDoubleWriteBinlogTest::slaveStore = nullptr;
90 const std::string RdbDoubleWriteBinlogTest::insertSql = "INSERT INTO test(id, name, age, salary, blobType) VALUES"
91 "(?,?,?,?,?)";
92
93 const int CHECKAGE = 18;
94 const double CHECKCOLUMN = 100.5;
95 const int CHANGENUM = 12;
96 const int BINLOG_DELETE_PER_WAIT_TIME = 100000; // 100000us = 100ms
97 const int BINLOG_REPLAY_WAIT_TIME = 2; // 2s
98
99 class DoubleWriteBinlogTestOpenCallback : public RdbOpenCallback {
100 public:
101 int OnCreate(RdbStore &store) override;
102 int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
103 static const std::string createTableTest;
104 };
105
106 const std::string DoubleWriteBinlogTestOpenCallback::createTableTest =
107 std::string("CREATE TABLE IF NOT EXISTS test ") + std::string("(id INTEGER PRIMARY KEY AUTOINCREMENT, "
108 "name TEXT NOT NULL, age INTEGER, salary "
109 "REAL, blobType BLOB)");
110
OnCreate(RdbStore & store)111 int DoubleWriteBinlogTestOpenCallback::OnCreate(RdbStore &store)
112 {
113 return store.ExecuteSql(DoubleWriteBinlogTestOpenCallback::createTableTest);
114 }
115
OnUpgrade(RdbStore & store,int oldVersion,int newVersion)116 int DoubleWriteBinlogTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
117 {
118 return E_OK;
119 }
120
SetUpTestCase(void)121 void RdbDoubleWriteBinlogTest::SetUpTestCase(void)
122 {
123 }
124
TearDownTestCase(void)125 void RdbDoubleWriteBinlogTest::TearDownTestCase(void)
126 {
127 }
128
SetUp(void)129 void RdbDoubleWriteBinlogTest::SetUp(void)
130 {
131 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
132 if (!SqliteConnection::IsSupportBinlog(config)) {
133 GTEST_SKIP() << "Current testcase is not compatible from current rdb";
134 }
135 testing::UnitTest *test = testing::UnitTest::GetInstance();
136 ASSERT_NE(test, nullptr);
137 const testing::TestInfo *testInfo = test->current_test_info();
138 ASSERT_NE(testInfo, nullptr);
139 LOG_INFO("---- double writebinlog test: %{public}s.%{public}s run start.",
140 testInfo->test_case_name(), testInfo->name());
141 }
142
TearDown(void)143 void RdbDoubleWriteBinlogTest::TearDown(void)
144 {
145 store = nullptr;
146 slaveStore = nullptr;
147 RdbHelper::DeleteRdbStore(RdbDoubleWriteBinlogTest::databaseName);
148 WaitForBinlogDelete();
149 testing::UnitTest *test = testing::UnitTest::GetInstance();
150 ASSERT_NE(test, nullptr);
151 const testing::TestInfo *testInfo = test->current_test_info();
152 ASSERT_NE(testInfo, nullptr);
153 LOG_INFO("---- double writebinlog test: %{public}s.%{public}s run end.",
154 testInfo->test_case_name(), testInfo->name());
155 }
156
InitDb(HAMode mode,bool isOpenSlave)157 void RdbDoubleWriteBinlogTest::InitDb(HAMode mode, bool isOpenSlave)
158 {
159 int errCode = E_OK;
160 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
161 config.SetHaMode(mode);
162 DoubleWriteBinlogTestOpenCallback helper;
163 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
164 ASSERT_NE(RdbDoubleWriteBinlogTest::store, nullptr);
165 store->ExecuteSql("DELETE FROM test");
166
167 if (isOpenSlave) {
168 RdbStoreConfig slaveConfig(RdbDoubleWriteBinlogTest::slaveDatabaseName);
169 DoubleWriteBinlogTestOpenCallback slaveHelper;
170 RdbDoubleWriteBinlogTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
171 ASSERT_NE(RdbDoubleWriteBinlogTest::slaveStore, nullptr);
172 slaveStore->ExecuteSql("DELETE FROM test");
173 }
174 }
175
Insert(int64_t start,int count,bool isSlave,int dataSize)176 void RdbDoubleWriteBinlogTest::Insert(int64_t start, int count, bool isSlave, int dataSize)
177 {
178 ValuesBucket values;
179 int64_t id = start;
180 int ret = E_OK;
181 for (int i = 0; i < count; i++) {
182 values.Clear();
183 values.PutInt("id", id);
184 if (dataSize > 0) {
185 values.PutString("name", std::string(dataSize, 'a'));
186 } else {
187 values.PutString("name", std::string("zhangsan"));
188 }
189 values.PutInt("age", CHECKAGE);
190 values.PutDouble("salary", CHECKCOLUMN);
191 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
192 if (isSlave) {
193 ret = slaveStore->Insert(id, "test", values);
194 } else {
195 ret = store->Insert(id, "test", values);
196 }
197 EXPECT_EQ(ret, E_OK);
198 id++;
199 }
200 }
201
InsertNativeConn(sqlite3 * db,int64_t start,int count,int dataSize)202 void RdbDoubleWriteBinlogTest::InsertNativeConn(sqlite3 *db, int64_t start, int count, int dataSize)
203 {
204 int64_t id = start;
205 sqlite3_stmt *stat = nullptr;
206 EXPECT_EQ(sqlite3_prepare_v2(db, RdbDoubleWriteBinlogTest::insertSql.c_str(), -1, &stat, nullptr), SQLITE_OK);
207 for (int i = 0; i < count; i++) {
208 // bind parameters, 1 is the sequence number of field
209 sqlite3_bind_int(stat, 1, id);
210 std::string nameStr;
211 if (dataSize > 0) {
212 nameStr = std::string(dataSize, 'a');
213 } else {
214 nameStr = std::string("zhangsan");
215 }
216 // bind parameters, 2 is the sequence number of field
217 sqlite3_bind_text(stat, 2, nameStr.c_str(), -1, SQLITE_STATIC);
218 // bind parameters, 3 is the sequence number of field
219 sqlite3_bind_int(stat, 3, CHECKAGE);
220 // bind parameters, 4 is the sequence number of field
221 sqlite3_bind_double(stat, 4, CHECKCOLUMN);
222 uint8_t blob[] = { 1, 2, 3 };
223 // bind parameters, 5 is the sequence number of field
224 sqlite3_bind_blob(stat, 5, blob, sizeof(blob), nullptr);
225 EXPECT_EQ(sqlite3_step(stat), SQLITE_DONE);
226 sqlite3_reset(stat);
227 id++;
228 }
229 sqlite3_finalize(stat);
230 }
231
Update(int64_t start,int count,bool isSlave,int dataSize)232 void RdbDoubleWriteBinlogTest::Update(int64_t start, int count, bool isSlave, int dataSize)
233 {
234 ValuesBucket values;
235 int64_t id = start;
236 int age = 20;
237 int ret = E_OK;
238 for (int i = 0; i < count; i++) {
239 values.Clear();
240 values.PutInt("id", id);
241 if (dataSize > 0) {
242 values.PutString("name", std::string(dataSize, 'a'));
243 } else {
244 values.PutString("name", std::string("zhangsan"));
245 }
246 values.PutInt("age", age);
247 values.PutDouble("salary", CHECKCOLUMN);
248 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
249 if (isSlave) {
250 ret = slaveStore->Replace(id, "test", values);
251 } else {
252 ret = store->Replace(id, "test", values);
253 }
254 EXPECT_EQ(ret, E_OK);
255 id++;
256 }
257 }
258
WaitForBackupFinish(int32_t expectStatus,int maxTimes)259 void RdbDoubleWriteBinlogTest::WaitForBackupFinish(int32_t expectStatus, int maxTimes)
260 {
261 int32_t curStatus = store->GetBackupStatus();
262 int tryTimes = 0;
263 while (curStatus != expectStatus && (++tryTimes <= maxTimes)) {
264 usleep(50000); // 50000 delay
265 curStatus = store->GetBackupStatus();
266 }
267 LOG_INFO("----------cur backup Status:%{public}d---------", curStatus);
268 ASSERT_EQ(curStatus, expectStatus);
269 }
270
WaitForBinlogDelete(int maxTimes)271 void RdbDoubleWriteBinlogTest::WaitForBinlogDelete(int maxTimes)
272 {
273 int waitTimes = 0;
274 while (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName) && waitTimes < maxTimes) {
275 usleep(BINLOG_DELETE_PER_WAIT_TIME);
276 waitTimes++;
277 LOG_INFO("---- Binlog replay in progress, waiting for finish");
278 RdbHelper::DeleteRdbStore(RdbDoubleWriteBinlogTest::databaseName);
279 }
280 EXPECT_FALSE(CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName));
281 }
282
WaitForBinlogReplayFinish()283 void RdbDoubleWriteBinlogTest::WaitForBinlogReplayFinish()
284 {
285 sleep(BINLOG_REPLAY_WAIT_TIME);
286 }
287
CheckNumber(std::shared_ptr<RdbStore> & store,int num,int errCode,const std::string & tableName)288 void RdbDoubleWriteBinlogTest::CheckNumber(
289 std::shared_ptr<RdbStore> &store, int num, int errCode, const std::string &tableName)
290 {
291 std::shared_ptr<ResultSet> resultSet = store->QuerySql("SELECT * FROM " + tableName);
292 ASSERT_NE(resultSet, nullptr);
293 int countNum;
294 int ret = resultSet->GetRowCount(countNum);
295 EXPECT_EQ(ret, errCode);
296 EXPECT_EQ(num, countNum);
297 }
298
CheckFolderExist(const std::string & path)299 bool RdbDoubleWriteBinlogTest::CheckFolderExist(const std::string &path)
300 {
301 if (access(path.c_str(), F_OK) != 0) {
302 return false;
303 }
304 return true;
305 }
306
RemoveFolder(const std::string & path)307 void RdbDoubleWriteBinlogTest::RemoveFolder(const std::string &path)
308 {
309 std::filesystem::path folder(path);
310 for (const auto &entry : std::filesystem::directory_iterator(folder)) {
311 if (entry.is_directory()) {
312 RemoveFolder(entry.path());
313 } else {
314 std::filesystem::remove(entry.path());
315 }
316 }
317 std::filesystem::remove(folder);
318 }
319
320 typedef int (*GtForkCallbackT)(const char *arg);
GtFork(GtForkCallbackT callback,const char * arg)321 static pid_t GtFork(GtForkCallbackT callback, const char *arg)
322 {
323 pid_t pid = fork();
324 if (pid == 0) {
325 int ret = callback(arg);
326 _exit(ret);
327 }
328 return pid;
329 }
330
InsertProcess(const char * arg)331 static int InsertProcess(const char *arg)
332 {
333 std::string test = std::string(arg);
334 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
335 int errCode = E_OK;
336 config.SetHaMode(HAMode::MAIN_REPLICA);
337 DoubleWriteBinlogTestOpenCallback helper;
338 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
339 EXPECT_NE(RdbDoubleWriteBinlogTest::store, nullptr);
340 int64_t id = 11;
341 int count = 1000;
342 RdbDoubleWriteBinlogTest::Insert(id, count);
343 int32_t num = 1010;
344 RdbDoubleWriteBinlogTest::CheckNumber(RdbDoubleWriteBinlogTest::store, num);
345 return 0;
346 }
347
InsertTwoProcess(const char * arg)348 static int InsertTwoProcess(const char *arg)
349 {
350 std::string test = std::string(arg);
351 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
352 int errCode = E_OK;
353 config.SetHaMode(HAMode::MAIN_REPLICA);
354 DoubleWriteBinlogTestOpenCallback helper;
355 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
356 EXPECT_NE(RdbDoubleWriteBinlogTest::store, nullptr);
357 bool isBinlogExist = RdbDoubleWriteBinlogTest::CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName);
358 EXPECT_TRUE(isBinlogExist);
359 int count = 10;
360 for (int i = 0; i < count; i++) {
361 errCode = RdbDoubleWriteBinlogTest::store->Backup(std::string(""), {});
362 }
363 return 0;
364 }
365
InsertManualProcess(const char * arg)366 static int InsertManualProcess(const char *arg)
367 {
368 std::string test = std::string(arg);
369 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
370 int errCode = E_OK;
371 config.SetHaMode(HAMode::MANUAL_TRIGGER);
372 DoubleWriteBinlogTestOpenCallback helper;
373 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
374 EXPECT_NE(RdbDoubleWriteBinlogTest::store, nullptr);
375 int64_t id = 11;
376 int count = 1000;
377 RdbDoubleWriteBinlogTest::Insert(id, count);
378 int32_t num = 1010;
379 RdbDoubleWriteBinlogTest::CheckNumber(RdbDoubleWriteBinlogTest::store, num);
380 return 0;
381 }
382
InsertManualTwoProcess(const char * arg)383 static int InsertManualTwoProcess(const char *arg)
384 {
385 std::string test = std::string(arg);
386 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
387 int errCode = E_OK;
388 config.SetHaMode(HAMode::MANUAL_TRIGGER);
389 DoubleWriteBinlogTestOpenCallback helper;
390 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
391 EXPECT_NE(RdbDoubleWriteBinlogTest::store, nullptr);
392 bool isBinlogExist = RdbDoubleWriteBinlogTest::CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName);
393 EXPECT_TRUE(isBinlogExist);
394 int count = 10;
395 for (int i = 0; i < count; i++) {
396 errCode = RdbDoubleWriteBinlogTest::store->Backup(std::string(""), {});
397 }
398 return 0;
399 }
400
CheckProcess(std::shared_ptr<RdbStore> & store)401 void RdbDoubleWriteBinlogTest::CheckProcess(std::shared_ptr<RdbStore> &store)
402 {
403 int64_t changeId = 2;
404 int changeCount = 4;
405 Update(changeId, changeCount);
406 int deletedRows;
407 store->Delete(deletedRows, "test", "id == 8");
408 store->Delete(deletedRows, "test", "id == 9");
409 int ret = store->BeginTransaction();
410 EXPECT_EQ(ret, E_OK);
411 std::string sqlCreateIndex = "CREATE INDEX id_index ON test (id);";
412 store->ExecuteSql(sqlCreateIndex.c_str());
413 ret = store->Commit();
414 EXPECT_EQ(ret, E_OK);
415 ret = store->BeginTransaction();
416 EXPECT_EQ(ret, E_OK);
417 changeId = CHANGENUM;
418 Update(changeId, changeCount);
419 store->Delete(deletedRows, "test", "id == 18");
420 store->Delete(deletedRows, "test", "id == 19");
421 ret = store->RollBack();
422 EXPECT_EQ(ret, E_OK);
423 }
424
DeleteDbFile(const RdbStoreConfig & config)425 void RdbDoubleWriteBinlogTest::DeleteDbFile(const RdbStoreConfig &config)
426 {
427 std::string dbFile;
428 auto errCode = SqliteGlobalConfig::GetDbPath(config, dbFile);
429 if (errCode != E_OK || dbFile.empty()) {
430 return;
431 }
432 std::ifstream binFile(dbFile);
433 if (binFile.is_open()) {
434 std::string content((std::istreambuf_iterator<char>(binFile)), (std::istreambuf_iterator<char>()));
435 std::remove(dbFile.c_str());
436 }
437 }
438
PutValue(std::shared_ptr<RdbStore> & store,const std::string & data,int64_t id,int age)439 void RdbDoubleWriteBinlogTest::PutValue(std::shared_ptr<RdbStore> &store, const std::string &data, int64_t id, int age)
440 {
441 ValuesBucket values;
442 values.PutInt("id", id);
443 values.PutString("name", data);
444 values.PutInt("age", age);
445 values.PutDouble("salary", CHECKCOLUMN);
446 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
447 int ret = store->Insert(id, "test", values);
448 EXPECT_EQ(ret, E_OK);
449 }
450
451 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_001, TestSize.Level0)
452 {
453 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
454 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
455 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
456 }
457 config.SetHaMode(HAMode::MAIN_REPLICA);
458 int errCode = E_OK;
459 DoubleWriteBinlogTestOpenCallback helper;
460 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
461 EXPECT_NE(store, nullptr);
462 ASSERT_TRUE(CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName));
463 store = nullptr;
464 RdbHelper::DeleteRdbStore(config);
465 ASSERT_FALSE(CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName));
466 }
467
468 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_002, TestSize.Level0)
469 {
470 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
471 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
472 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
473 }
474 config.SetHaMode(HAMode::MANUAL_TRIGGER);
475 int errCode = E_OK;
476 DoubleWriteBinlogTestOpenCallback helper;
477 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
478 EXPECT_NE(store, nullptr);
479 bool isBinlogExist = CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName);
480 ASSERT_FALSE(isBinlogExist);
481 errCode = store->Backup(std::string(""), {});
482 EXPECT_EQ(errCode, E_OK);
483 isBinlogExist = CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName);
484 ASSERT_TRUE(isBinlogExist);
485 }
486
487 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_003, TestSize.Level0)
488 {
489 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
490 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
491 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
492 }
493 config.SetHaMode(HAMode::MAIN_REPLICA);
494 int errCode = E_OK;
495 DoubleWriteBinlogTestOpenCallback helper;
496 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
497 EXPECT_NE(store, nullptr);
498 int64_t id = 1;
499 int count = 10;
500 Insert(id, count);
501 store = nullptr;
502 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
503 EXPECT_NE(store, nullptr);
504 bool isSlaveDbFileExist = OHOS::FileExists(RdbDoubleWriteBinlogTest::slaveDatabaseName);
505 ASSERT_TRUE(isSlaveDbFileExist);
506 bool isBinlogExist = CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName);
507 ASSERT_TRUE(isBinlogExist);
508 }
509
510 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_004, TestSize.Level0)
511 {
512 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
513 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
514 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
515 }
516 config.SetHaMode(HAMode::MANUAL_TRIGGER);
517 int errCode = E_OK;
518 DoubleWriteBinlogTestOpenCallback helper;
519 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
520 EXPECT_NE(store, nullptr);
521 int64_t id = 1;
522 int count = 10;
523 Insert(id, count);
524 store = nullptr;
525 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
526 EXPECT_NE(store, nullptr);
527 bool isSlaveDbFileExist = OHOS::FileExists(RdbDoubleWriteBinlogTest::slaveDatabaseName);
528 ASSERT_FALSE(isSlaveDbFileExist);
529 errCode = store->Backup(std::string(""), {});
530 EXPECT_EQ(errCode, E_OK);
531 isSlaveDbFileExist = OHOS::FileExists(RdbDoubleWriteBinlogTest::slaveDatabaseName);
532 ASSERT_TRUE(isSlaveDbFileExist);
533 bool isBinlogExist = CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName);
534 ASSERT_TRUE(isBinlogExist);
535 }
536
537 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_005, TestSize.Level0)
538 {
539 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
540 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
541 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
542 }
543 InitDb();
544 int64_t id = 1;
545 int count = 10;
546 Insert(id, count);
547 Insert(id, count, true);
548 store = nullptr;
549 int errCode = E_OK;
550 DoubleWriteBinlogTestOpenCallback helper;
551 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
552 EXPECT_NE(store, nullptr);
553 bool isBinlogExist = CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName);
554 ASSERT_TRUE(isBinlogExist);
555 }
556
557 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_006, TestSize.Level0)
558 {
559 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
560 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
561 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
562 }
563 int errCode = E_OK;
564 config.SetHaMode(HAMode::MANUAL_TRIGGER);
565 DoubleWriteBinlogTestOpenCallback helper;
566 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
567 EXPECT_NE(store, nullptr);
568 store->ExecuteSql("DELETE FROM test");
569
570 // open slave for conflict by compress
571 sqlite3 *db = nullptr;
572 int rc = sqlite3_open_v2(RdbDoubleWriteBinlogTest::slaveDatabaseName.c_str(),
573 &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
574 EXPECT_EQ(rc, SQLITE_OK);
575 EXPECT_NE(db, nullptr);
576 sqlite3_close_v2(db);
577
578 int64_t id = 1;
579 int count = 10;
580 Insert(id, count);
581 store = nullptr;
582 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
583 EXPECT_NE(store, nullptr);
584 bool isBinlogExist = CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName);
585 ASSERT_TRUE(isBinlogExist);
586 }
587
588 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_007, TestSize.Level0)
589 {
590 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
591 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
592 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
593 }
594 InitDb();
595 int64_t id = 1;
596 int count = 10;
597 Insert(id, count);
598 Insert(id, count, true);
599
600 SqliteUtils::SetSlaveInvalid(RdbDoubleWriteBinlogTest::databaseName);
601 std::string failureFlagPath = RdbDoubleWriteBinlogTest::databaseName + +"-slaveFailure";
602 bool isFlagFileExists = OHOS::FileExists(failureFlagPath);
603 ASSERT_TRUE(isFlagFileExists);
604 store = nullptr;
605 int errCode = E_OK;
606 DoubleWriteBinlogTestOpenCallback helper;
607 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
608 EXPECT_NE(store, nullptr);
609 bool isBinlogExist = CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName);
610 ASSERT_TRUE(isBinlogExist);
611 }
612
613 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_008, TestSize.Level0)
614 {
615 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
616 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
617 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
618 }
619 int errCode = E_OK;
620 config.SetHaMode(HAMode::MANUAL_TRIGGER);
621 DoubleWriteBinlogTestOpenCallback helper;
622 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
623 EXPECT_NE(store, nullptr);
624 store->ExecuteSql("DELETE FROM test");
625
626 // open slave for conflict by compress
627 sqlite3 *db = nullptr;
628 int rc = sqlite3_open_v2(RdbDoubleWriteBinlogTest::slaveDatabaseName.c_str(),
629 &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
630 EXPECT_EQ(rc, SQLITE_OK);
631 EXPECT_NE(db, nullptr);
632 sqlite3_close_v2(db);
633
634 int64_t id = 1;
635 int count = 10;
636 Insert(id, count);
637
638 SqliteUtils::SetSlaveInvalid(RdbDoubleWriteBinlogTest::databaseName);
639 std::string failureFlagPath = RdbDoubleWriteBinlogTest::databaseName + +"-slaveFailure";
640 bool isFlagFileExists = OHOS::FileExists(failureFlagPath);
641 ASSERT_TRUE(isFlagFileExists);
642 store = nullptr;
643 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
644 EXPECT_NE(store, nullptr);
645 bool isBinlogExist = CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName);
646 ASSERT_FALSE(isBinlogExist);
647 errCode = store->Backup(std::string(""), {});
648 EXPECT_EQ(errCode, E_OK);
649 isBinlogExist = CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName);
650 ASSERT_TRUE(isBinlogExist);
651 }
652
653 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_009, TestSize.Level0)
654 {
655 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
656 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
657 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
658 }
659 InitDb(HAMode::MAIN_REPLICA, false);
660 int errCode = E_OK;
661 DoubleWriteBinlogTestOpenCallback helper;
662 int64_t id = 1;
663 int count = 10;
664 Insert(id, count);
665
666 store = nullptr;
667 config.SetHaMode(HAMode::MAIN_REPLICA);
668 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
669 EXPECT_NE(store, nullptr);
670 bool isBinlogExist = CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName);
671 ASSERT_TRUE(isBinlogExist);
672 id = 11;
673 Insert(id, count);
674 WaitForBinlogReplayFinish();
675 store = nullptr;
676 DeleteDbFile(config);
677
678 config.SetHaMode(HAMode::MAIN_REPLICA);
679 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
680 EXPECT_NE(store, nullptr);
681 WaitForBackupFinish(BACKUP_FINISHED);
682 WaitForBinlogReplayFinish();
683 int32_t num = 20;
684 RdbDoubleWriteBinlogTest::CheckNumber(store, num);
685 }
686
687 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_010, TestSize.Level0)
688 {
689 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
690 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
691 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
692 }
693 int errCode = E_OK;
694 config.SetHaMode(HAMode::MANUAL_TRIGGER);
695 DoubleWriteBinlogTestOpenCallback helper;
696 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
697 EXPECT_NE(store, nullptr);
698 store->ExecuteSql("DELETE FROM test");
699
700 int64_t id = 1;
701 int count = 10;
702 Insert(id, count);
703
704 // open slave for conflict by compress
705 sqlite3 *db = nullptr;
706 int rc = sqlite3_open_v2(RdbDoubleWriteBinlogTest::slaveDatabaseName.c_str(),
707 &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, "compressvfs");
708 EXPECT_EQ(rc, SQLITE_OK);
709 EXPECT_NE(db, nullptr);
710 const char *ddl = DoubleWriteBinlogTestOpenCallback::createTableTest.c_str();
711 EXPECT_EQ(sqlite3_exec(db, ddl, nullptr, nullptr, nullptr), SQLITE_OK);
712 InsertNativeConn(db, id, count);
713 sqlite3_close_v2(db);
714
715 store = nullptr;
716 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
717 EXPECT_NE(store, nullptr);
718 WaitForBinlogReplayFinish();
719 bool isBinlogExist = CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName);
720 ASSERT_TRUE(isBinlogExist);
721 id = 11;
722 Insert(id, count);
723 store = nullptr;
724 DeleteDbFile(config);
725
726 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
727 EXPECT_NE(store, nullptr);
728 WaitForBackupFinish(BACKUP_FINISHED);
729 int32_t num = 20;
730 RdbDoubleWriteBinlogTest::CheckNumber(store, num);
731 }
732
733 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_011, TestSize.Level0)
734 {
735 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
736 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
737 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
738 }
739 InitDb(HAMode::MAIN_REPLICA, false);
740 int errCode = E_OK;
741 DoubleWriteBinlogTestOpenCallback helper;
742 int64_t id = 1;
743 int count = 10;
744 Insert(id, count);
745
746 bool isBinlogExist = CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName);
747 ASSERT_TRUE(isBinlogExist);
748 id = 11;
749 Insert(id, count);
750 int32_t num = 20;
751 RdbDoubleWriteBinlogTest::CheckNumber(store, num);
752 CheckProcess(store);
753
754 store = nullptr;
755 DeleteDbFile(config);
756
757 config.SetHaMode(HAMode::MAIN_REPLICA);
758 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
759 EXPECT_NE(store, nullptr);
760 WaitForBackupFinish(BACKUP_FINISHED);
761 WaitForBinlogReplayFinish();
762 num = 18;
763 RdbDoubleWriteBinlogTest::CheckNumber(store, num);
764 }
765
766 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_012, TestSize.Level0)
767 {
768 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
769 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
770 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
771 }
772
773 InitDb(HAMode::MAIN_REPLICA, false);
774 int64_t id = 1;
775 int count = 10;
776 Insert(id, count);
777
778 config.SetHaMode(HAMode::MANUAL_TRIGGER);
779 DoubleWriteBinlogTestOpenCallback helper;
780 int errCode = E_OK;
781 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
782 EXPECT_NE(store, nullptr);
783 bool isBinlogExist = CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName);
784 ASSERT_TRUE(isBinlogExist);
785 id = 11;
786 Insert(id, count);
787 int32_t num = 20;
788 RdbDoubleWriteBinlogTest::CheckNumber(store, num);
789 CheckProcess(store);
790
791 store = nullptr;
792 DeleteDbFile(config);
793
794 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
795 EXPECT_NE(store, nullptr);
796 WaitForBackupFinish(BACKUP_FINISHED);
797 num = 18;
798 RdbDoubleWriteBinlogTest::CheckNumber(store, num);
799 }
800
Callback(void * data,int argc,char ** argv,char ** azColName)801 static int Callback(void *data, int argc, char **argv, char **azColName)
802 {
803 int64_t *count = (int64_t *)data;
804 if (argc > 0 && argv[0] != NULL) {
805 *count = atoi(argv[0]);
806 }
807 return 0;
808 }
809
810 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_013, TestSize.Level0)
811 {
812 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
813 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
814 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
815 }
816 int errCode = E_OK;
817 config.SetHaMode(HAMode::MAIN_REPLICA);
818 DoubleWriteBinlogTestOpenCallback helper;
819 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
820 EXPECT_NE(store, nullptr);
821
822 bool isSlaveDbFileExists = OHOS::FileExists(RdbDoubleWriteBinlogTest::slaveDatabaseName);
823 ASSERT_TRUE(isSlaveDbFileExists);
824 bool isBinlogExist = CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName);
825 ASSERT_TRUE(isBinlogExist);
826
827 int64_t id = 1;
828 int count = 20;
829 Insert(id, count);
830 CheckProcess(store);
831
832 int64_t num = 18;
833 RdbDoubleWriteBinlogTest::CheckNumber(store, num);
834 errCode = store->Backup(std::string(""), {});
835 EXPECT_EQ(errCode, E_OK);
836
837 // open slave for conflict by compress
838 sqlite3 *db = nullptr;
839 int rc = sqlite3_open_v2(RdbDoubleWriteBinlogTest::slaveDatabaseName.c_str(),
840 &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, "compressvfs");
841 EXPECT_EQ(rc, SQLITE_OK);
842 EXPECT_NE(db, nullptr);
843
844 count = 0;
845 rc = sqlite3_exec(db, "SELECT COUNT(1) FROM test;", Callback, &count, nullptr);
846 EXPECT_EQ(rc, SQLITE_OK);
847 EXPECT_EQ(count, num);
848 sqlite3_close_v2(db);
849 }
850
851 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_014, TestSize.Level0)
852 {
853 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
854 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
855 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
856 }
857 int errCode = E_OK;
858 config.SetHaMode(HAMode::MANUAL_TRIGGER);
859 DoubleWriteBinlogTestOpenCallback helper;
860 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
861 EXPECT_NE(store, nullptr);
862
863 bool isSlaveDbFileExists = OHOS::FileExists(RdbDoubleWriteBinlogTest::slaveDatabaseName);
864 ASSERT_FALSE(isSlaveDbFileExists);
865 errCode = store->Backup(std::string(""), {});
866 EXPECT_EQ(errCode, E_OK);
867 WaitForBackupFinish(BACKUP_FINISHED);
868 isSlaveDbFileExists = OHOS::FileExists(RdbDoubleWriteBinlogTest::slaveDatabaseName);
869 ASSERT_TRUE(isSlaveDbFileExists);
870 bool isBinlogExist = CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName);
871 ASSERT_TRUE(isBinlogExist);
872
873 int64_t id = 1;
874 int count = 20;
875 Insert(id, count);
876 CheckProcess(store);
877
878 int64_t num = 18;
879 RdbDoubleWriteBinlogTest::CheckNumber(store, num);
880 errCode = store->Backup(std::string(""), {});
881 EXPECT_EQ(errCode, E_OK);
882
883 // open slave for conflict by compress
884 sqlite3 *db = nullptr;
885 int rc = sqlite3_open_v2(RdbDoubleWriteBinlogTest::slaveDatabaseName.c_str(),
886 &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, "compressvfs");
887 EXPECT_EQ(rc, SQLITE_OK);
888 EXPECT_NE(db, nullptr);
889 count = 0;
890 rc = sqlite3_exec(db, "SELECT COUNT(1) FROM test;", Callback, &count, nullptr);
891 EXPECT_EQ(rc, SQLITE_OK);
892 EXPECT_EQ(count, num);
893 sqlite3_close_v2(db);
894 }
895
896 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_015, TestSize.Level0)
897 {
898 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
899 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
900 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
901 }
902 InitDb();
903 int64_t id = 1;
904 int count = 10;
905 Insert(id, count);
906 store = nullptr;
907 std::string test = "lisi";
908 pid_t pid1 = GtFork(InsertProcess, test.c_str());
909 ASSERT_GT(pid1, 0);
910 InsertTwoProcess(test.c_str());
911 int status;
912 waitpid(pid1, &status, 0);
913 }
914
915 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_016, TestSize.Level0)
916 {
917 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
918 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
919 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
920 }
921 int errCode = E_OK;
922 config.SetHaMode(HAMode::MANUAL_TRIGGER);
923 DoubleWriteBinlogTestOpenCallback helper;
924 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
925 EXPECT_NE(store, nullptr);
926 store->ExecuteSql("DELETE FROM test");
927 int64_t id = 1;
928 int count = 10;
929 Insert(id, count);
930 EXPECT_EQ(store->Backup(std::string(""), {}), E_OK);
931 ASSERT_TRUE(CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName));
932
933 RdbStoreConfig slaveConfig(RdbDoubleWriteBinlogTest::slaveDatabaseName);
934 DoubleWriteBinlogTestOpenCallback slaveHelper;
935 RdbDoubleWriteBinlogTest::slaveStore = RdbHelper::GetRdbStore(slaveConfig, 1, slaveHelper, errCode);
936 EXPECT_NE(slaveStore, nullptr);
937
938 store = nullptr;
939 std::string test = "lisi";
940 pid_t pid1 = GtFork(InsertManualProcess, test.c_str());
941 ASSERT_GT(pid1, 0);
942 InsertManualTwoProcess(test.c_str());
943 int status;
944 waitpid(pid1, &status, 0);
945 }
946
947 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_017, TestSize.Level0)
948 {
949 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
950 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
951 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
952 }
953 InitDb();
954 int64_t id = 1;
955 int count = 10;
956 Insert(id, count);
957 store = nullptr;
958
959 config.SetHaMode(HAMode::MAIN_REPLICA);
960 int errCode = E_OK;
961 DoubleWriteBinlogTestOpenCallback helper;
962 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
963 EXPECT_NE(store, nullptr);
964
965 bool isBinlogExist = CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName);
966 ASSERT_TRUE(isBinlogExist);
967
968 size_t bigSize = 1024 * 1024 * 128;
969 std::string data(bigSize, 'a');
970 PutValue(store, data, 11, 18);
971 PutValue(store, data, 12, 19);
972
973 store = nullptr;
974 id = 13;
975 for (int i = 0; i < count; i++) {
976 config.SetHaMode(HAMode::MAIN_REPLICA);
977 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
978 EXPECT_NE(store, nullptr);
979 PutValue(store, data, id, CHECKAGE);
980 store = nullptr;
981 id++;
982 }
983 WaitForBinlogReplayFinish();
984 }
985
986 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_018, TestSize.Level0)
987 {
988 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
989 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
990 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
991 }
992 InitDb();
993 int64_t id = 1;
994 int count = 10;
995 Insert(id, count);
996 store = nullptr;
997
998 config.SetHaMode(HAMode::MAIN_REPLICA);
999 int errCode = E_OK;
1000 DoubleWriteBinlogTestOpenCallback helper;
1001 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1002 EXPECT_NE(store, nullptr);
1003
1004 bool isBinlogExist = CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName);
1005 ASSERT_TRUE(isBinlogExist);
1006
1007 size_t bigSize = 1024 * 1024 * 13;
1008 std::string data(bigSize, 'a');
1009
1010 store = nullptr;
1011 id = 11;
1012 for (int i = 0; i < count; i++) {
1013 config.SetHaMode(HAMode::MAIN_REPLICA);
1014 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1015 EXPECT_NE(store, nullptr);
1016 PutValue(store, data, id, CHECKAGE);
1017 store = nullptr;
1018 id++;
1019 }
1020 WaitForBinlogReplayFinish();
1021 }
1022
1023 /**
1024 * @tc.name: RdbStore_Binlog_019
1025 * @tc.desc: open MAIN_REPLICA db when replica is invalid,
1026 * then batch insert new data and test main and replica are the same
1027 * @tc.type: FUNC
1028 */
1029 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_019, TestSize.Level0)
1030 {
1031 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
1032 ASSERT_FALSE(CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName));
1033 InitDb();
1034 int64_t id = 1;
1035 int count = 10;
1036 Insert(id, count);
1037 store = nullptr;
1038 slaveStore = nullptr;
1039 SqliteUtils::SetSlaveInvalid(RdbDoubleWriteBinlogTest::databaseName);
1040
1041 LOG_INFO("---- open db when slave is invalid to trigger backup");
1042 config.SetHaMode(HAMode::MAIN_REPLICA);
1043 int errCode = E_OK;
1044 DoubleWriteBinlogTestOpenCallback helper;
1045 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1046 ASSERT_NE(store, nullptr);
1047 WaitForBinlogReplayFinish();
1048 LOG_INFO("---- insert after backup after wait");
1049 int totalCount = count;
1050 id += totalCount;
1051 count = 1000; // 1000 is one batch
1052 Insert(id, count);
1053 totalCount += count;
1054 EXPECT_TRUE(CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName));
1055 EXPECT_FALSE(SqliteUtils::IsSlaveInvalid(RdbDoubleWriteBinlogTest::databaseName));
1056 RdbDoubleWriteBinlogTest::CheckNumber(store, totalCount);
1057 store = nullptr;
1058 SqliteUtils::DeleteFile(databaseName);
1059 LOG_INFO("---- check for data count after restore");
1060 RdbDoubleWriteBinlogTest::store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1061 ASSERT_NE(store, nullptr);
1062 RdbDoubleWriteBinlogTest::CheckNumber(store, totalCount);
1063 }
1064
MockCleanBinlog(sqlite3 * db,BinlogFileCleanModeE mode)1065 static int MockCleanBinlog(sqlite3* db, BinlogFileCleanModeE mode)
1066 {
1067 return SQLITE_ERROR;
1068 }
1069
MockSupportBinlogOff(const char * name)1070 static int MockSupportBinlogOff(const char *name)
1071 {
1072 return SQLITE_ERROR;
1073 }
1074 /**
1075 * @tc.name: RdbStore_Binlog_020
1076 * @tc.desc: test backup when binlog clean failed will mark slave invalid
1077 * @tc.type: FUNC
1078 */
1079 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_020, TestSize.Level0)
1080 {
1081 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
1082 ASSERT_FALSE(CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName));
1083 InitDb();
1084 int64_t id = 1;
1085 int count = 10;
1086 Insert(id, count);
1087
1088 LOG_INFO("---- let binlog clean return ERROR");
1089 auto originalApi = sqlite3_export_extra_symbols;
1090 struct sqlite3_api_routines_extra mockApi = *sqlite3_export_extra_symbols;
1091 mockApi.clean_binlog = MockCleanBinlog;
1092 sqlite3_export_extra_symbols = &mockApi;
1093
1094 LOG_INFO("---- binlog clean failed should mark invalid");
1095 EXPECT_EQ(store->Backup(std::string(""), {}), E_OK);
1096 EXPECT_TRUE(SqliteUtils::IsSlaveInvalid(RdbDoubleWriteBinlogTest::databaseName));
1097 sqlite3_export_extra_symbols = originalApi;
1098 }
1099
1100 /**
1101 * @tc.name: RdbStore_Binlog_021
1102 * @tc.desc: test delete rdb store will work if binlog is not supported
1103 * @tc.type: FUNC
1104 */
1105 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_021, TestSize.Level0)
1106 {
1107 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
1108 ASSERT_FALSE(CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName));
1109 InitDb();
1110 int64_t id = 1;
1111 int count = 10;
1112 Insert(id, count);
1113 store = nullptr;
1114 slaveStore = nullptr;
1115
1116 LOG_INFO("---- let support binlog becomes off");
1117 struct sqlite3_api_routines_relational mockApi = *sqlite3_export_relational_symbols;
1118 mockApi.is_support_binlog = MockSupportBinlogOff;
1119 auto originalApi = sqlite3_export_relational_symbols;
1120 sqlite3_export_relational_symbols = &mockApi;
1121
1122 LOG_INFO("---- rdb delete store should return ok");
1123 EXPECT_EQ(RdbHelper::DeleteRdbStore(RdbDoubleWriteBinlogTest::databaseName), E_OK);
1124 sqlite3_export_relational_symbols = originalApi;
1125 }
1126
GetInsertTime(std::shared_ptr<RdbStore> & rdbStore,int repeat,size_t dataSize)1127 static int64_t GetInsertTime(std::shared_ptr<RdbStore> &rdbStore, int repeat, size_t dataSize)
1128 {
1129 size_t bigSize = dataSize;
1130 std::string data(bigSize, 'a');
1131
1132 LOG_INFO("---- start insert ----");
1133 int64_t totalCost = 0;
1134 for (int64_t id = 0; id < repeat; id++) {
1135 ValuesBucket values;
1136 values.PutInt("id", id);
1137 values.PutString("name", data);
1138 values.PutInt("age", id);
1139 values.PutDouble("salary", CHECKCOLUMN);
1140 values.PutBlob("blobType", std::vector<uint8_t>{ 1, 2, 3 });
1141 auto begin = std::chrono::high_resolution_clock::now();
1142 int ret = rdbStore->Insert(id, "test", values);
1143 auto stop = std::chrono::high_resolution_clock::now();
1144 EXPECT_EQ(ret, E_OK);
1145 totalCost += std::chrono::duration_cast<std::chrono::microseconds>(stop - begin).count();
1146 }
1147 return totalCost;
1148 }
1149
GetUpdateTime(std::shared_ptr<RdbStore> & rdbStore,int batchSize,int repeat,size_t dataSize)1150 static int64_t GetUpdateTime(std::shared_ptr<RdbStore> &rdbStore, int batchSize, int repeat, size_t dataSize)
1151 {
1152 size_t bigSize = dataSize;
1153 std::string data(bigSize, 'b');
1154 LOG_INFO("---- start update ----");
1155 int64_t totalCost = 0;
1156 for (int i = 0; i < repeat; i++) {
1157 int start = i * batchSize;
1158 int end = (i + 1) * batchSize;
1159 std::string sql = "update test set name = '" + data + "' where id >= " + std::to_string(start) +
1160 " and id < " + std::to_string(end) + ";";
1161 auto begin = std::chrono::high_resolution_clock::now();
1162 int ret = rdbStore->ExecuteSql(sql);
1163 auto stop = std::chrono::high_resolution_clock::now();
1164 EXPECT_EQ(ret, E_OK);
1165 totalCost += std::chrono::duration_cast<std::chrono::microseconds>(stop - begin).count();
1166 }
1167 return totalCost;
1168 }
1169
GetDeleteTime(std::shared_ptr<RdbStore> & rdbStore,int batchSize,int repeat)1170 static int64_t GetDeleteTime(std::shared_ptr<RdbStore> &rdbStore, int batchSize, int repeat)
1171 {
1172 LOG_INFO("---- start delete ----");
1173 int64_t totalCost = 0;
1174 for (int i = 0; i < repeat; i++) {
1175 int start = i * batchSize;
1176 int end = (i + 1) * batchSize;
1177 std::string sql =
1178 "delete from test where id >= " + std::to_string(start) + " and id < " + std::to_string(end) + ";";
1179 auto begin = std::chrono::high_resolution_clock::now();
1180 int ret = rdbStore->ExecuteSql(sql);
1181 auto stop = std::chrono::high_resolution_clock::now();
1182 EXPECT_EQ(ret, E_OK);
1183 totalCost += std::chrono::duration_cast<std::chrono::microseconds>(stop - begin).count();
1184 }
1185 return totalCost;
1186 }
1187
GetRestoreTime(HAMode haMode,bool isOpenSlave)1188 int64_t RdbDoubleWriteBinlogTest::GetRestoreTime(HAMode haMode, bool isOpenSlave)
1189 {
1190 InitDb(haMode, isOpenSlave);
1191 EXPECT_NE(store, nullptr);
1192 if (haMode == HAMode::MANUAL_TRIGGER) {
1193 int errCode = store->Backup(std::string(""), {});
1194 EXPECT_EQ(errCode, E_OK);
1195 }
1196 int id = 1;
1197 int totalCount = 20000;
1198 int size = 1024;
1199 Insert(id, totalCount, false, size);
1200 store = nullptr;
1201
1202 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
1203 DoubleWriteBinlogTestOpenCallback helper;
1204 config.SetHaMode(haMode);
1205 DeleteDbFile(config);
1206
1207 int errCode = E_OK;
1208 auto begin = std::chrono::high_resolution_clock::now();
1209 store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
1210 auto stop = std::chrono::high_resolution_clock::now();
1211 EXPECT_NE(store, nullptr);
1212 return std::chrono::duration_cast<std::chrono::microseconds>(stop - begin).count();
1213 }
1214
1215 /**
1216 * @tc.name: RdbStore_Binlog_Performance_001
1217 * @tc.desc: test performance of insert, update, query and delete in main_replica
1218 * @tc.type: FUNC
1219 */
1220 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_Performance_001, TestSize.Level2)
1221 {
1222 LOG_INFO("----RdbStore_Binlog_Performance_001 start----");
1223 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
1224 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
1225 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
1226 }
1227 InitDb(HAMode::SINGLE);
1228 EXPECT_NE(store, nullptr);
1229 if (!CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
1230 return;
1231 }
1232
1233 int totalCount = 20000;
1234 int dataSize = 1024;
1235 int batchSize = 10;
1236 auto T1_2 = GetInsertTime(store, totalCount, dataSize);
1237 auto T2_2 = GetUpdateTime(store, batchSize, totalCount / batchSize, dataSize);
1238 auto T3_2 = GetDeleteTime(store, batchSize, totalCount / batchSize);
1239 store = nullptr;
1240 slaveStore = nullptr;
1241 RdbHelper::DeleteRdbStore(RdbDoubleWriteBinlogTest::databaseName);
1242 WaitForBinlogDelete();
1243 ASSERT_FALSE(CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName));
1244
1245 InitDb(HAMode::MAIN_REPLICA);
1246 EXPECT_NE(store, nullptr);
1247
1248 auto T1 = GetInsertTime(store, totalCount, dataSize);
1249 auto T2 = GetUpdateTime(store, batchSize, totalCount / batchSize, dataSize);
1250 auto T3 = GetDeleteTime(store, batchSize, totalCount / batchSize);
1251
1252 EXPECT_LT(T1, T1_2 * 1.8);
1253 EXPECT_LT(T2, T2_2 * 1.8);
1254 EXPECT_LT(T3, T3_2 * 1.8);
1255 LOG_INFO("----RdbStore_Binlog_Performance_001----, %{public}" PRId64 ", %{public}" PRId64 ", %{public}" PRId64 ",",
1256 T1, T2, T3);
1257 LOG_INFO("----RdbStore_Binlog_Performance_001----, %{public}" PRId64 ", %{public}" PRId64 ", %{public}" PRId64 ",",
1258 T1_2, T2_2, T3_2);
1259 }
1260
1261 /**
1262 * @tc.name: RdbStore_Binlog_Performance_002
1263 * @tc.desc: test performance of insert, update, query and delete in mannual_trigger
1264 * @tc.type: FUNC
1265 */
1266 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_Performance_002, TestSize.Level2)
1267 {
1268 LOG_INFO("----RdbStore_Binlog_Performance_002 start----");
1269 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
1270 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
1271 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
1272 }
1273 InitDb(HAMode::SINGLE);
1274 ASSERT_NE(store, nullptr);
1275
1276 int totalCount = 20000;
1277 int dataSize = 200;
1278 int batchSize = 1;
1279 auto T1_2 = GetInsertTime(store, totalCount, dataSize);
1280 auto T2_2 = GetUpdateTime(store, batchSize, totalCount / batchSize, dataSize);
1281 auto T3_2 = GetDeleteTime(store, batchSize, totalCount / batchSize);
1282
1283 store = nullptr;
1284 slaveStore = nullptr;
1285 RdbHelper::DeleteRdbStore(RdbDoubleWriteBinlogTest::databaseName);
1286 WaitForBinlogDelete();
1287 ASSERT_FALSE(CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName));
1288
1289 InitDb(HAMode::MANUAL_TRIGGER);
1290 EXPECT_NE(store, nullptr);
1291 int errCode = store->Backup(std::string(""), {});
1292 EXPECT_EQ(errCode, E_OK);
1293 if (!CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
1294 return;
1295 }
1296
1297 auto T1 = GetInsertTime(store, totalCount, dataSize);
1298 auto T2 = GetUpdateTime(store, batchSize, totalCount / batchSize, dataSize);
1299 auto T3 = GetDeleteTime(store, batchSize, totalCount / batchSize);
1300
1301 EXPECT_LT(T1, T1_2 * 1.8);
1302 EXPECT_LT(T2, T2_2 * 1.8);
1303 EXPECT_LT(T3, T3_2 * 1.8);
1304 LOG_INFO("----RdbStore_Binlog_Performance_002----, %{public}" PRId64 ", %{public}" PRId64 ", %{public}" PRId64 ",",
1305 T1, T2, T3);
1306 LOG_INFO("----RdbStore_Binlog_Performance_002----, %{public}" PRId64 ", %{public}" PRId64 ", %{public}" PRId64 ",",
1307 T1_2, T2_2, T3_2);
1308 }
1309
1310 /**
1311 * @tc.name: RdbStore_Binlog_Performance_003
1312 * @tc.desc: test performance of insert, update, query and delete in main_replica with large data
1313 * @tc.type: FUNC
1314 */
1315 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_Performance_003, TestSize.Level2)
1316 {
1317 LOG_INFO("----RdbStore_Binlog_Performance_003 start----");
1318 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
1319 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
1320 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
1321 }
1322 InitDb(HAMode::SINGLE);
1323 EXPECT_NE(store, nullptr);
1324
1325 int totalCount = 200;
1326 int dataSize = 1024 * 1024;
1327 int batchSize = 10;
1328 auto T1_2 = GetInsertTime(store, totalCount, dataSize);
1329 auto T2_2 = GetUpdateTime(store, batchSize, totalCount / batchSize, dataSize);
1330 auto T3_2 = GetDeleteTime(store, batchSize, totalCount / batchSize);
1331 store = nullptr;
1332 slaveStore = nullptr;
1333 RdbHelper::DeleteRdbStore(RdbDoubleWriteBinlogTest::databaseName);
1334 WaitForBinlogDelete();
1335 ASSERT_FALSE(CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName));
1336
1337 InitDb(HAMode::MAIN_REPLICA);
1338 EXPECT_NE(store, nullptr);
1339 if (!CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
1340 return;
1341 }
1342
1343 auto T1 = GetInsertTime(store, totalCount, dataSize);
1344 auto T2 = GetUpdateTime(store, batchSize, totalCount / batchSize, dataSize);
1345 auto T3 = GetDeleteTime(store, batchSize, totalCount / batchSize);
1346
1347 EXPECT_LT(T1, T1_2 * 1.8);
1348 EXPECT_LT(T2, T2_2 * 1.8);
1349 EXPECT_LT(T3, T3_2 * 1.8);
1350 LOG_INFO("----RdbStore_Binlog_Performance_003----, %{public}" PRId64 ", %{public}" PRId64 ", %{public}" PRId64 ",",
1351 T1, T2, T3);
1352 LOG_INFO("----RdbStore_Binlog_Performance_003----, %{public}" PRId64 ", %{public}" PRId64 ", %{public}" PRId64 ",",
1353 T1_2, T2_2, T3_2);
1354 }
1355
1356 /**
1357 * @tc.name: RdbStore_Binlog_Performance_004
1358 * @tc.desc: test performance of insert, update, query and delete in mannual_trigger with large data
1359 * @tc.type: FUNC
1360 */
1361 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_Performance_004, TestSize.Level2)
1362 {
1363 LOG_INFO("----RdbStore_Binlog_Performance_004 start----");
1364 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
1365 if (CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
1366 RemoveFolder(RdbDoubleWriteBinlogTest::binlogDatabaseName);
1367 }
1368 InitDb(HAMode::SINGLE);
1369 EXPECT_NE(store, nullptr);
1370
1371 int totalCount = 200;
1372 int dataSize = 1024 * 1024;
1373 int batchSize = 10;
1374 auto T1_2 = GetInsertTime(store, totalCount, dataSize);
1375 auto T2_2 = GetUpdateTime(store, batchSize, totalCount / batchSize, dataSize);
1376 auto T3_2 = GetDeleteTime(store, batchSize, totalCount / batchSize);
1377 store = nullptr;
1378 slaveStore = nullptr;
1379 RdbHelper::DeleteRdbStore(RdbDoubleWriteBinlogTest::databaseName);
1380 WaitForBinlogDelete();
1381 ASSERT_FALSE(CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName));
1382
1383 InitDb(HAMode::MANUAL_TRIGGER);
1384 ASSERT_NE(store, nullptr);
1385 int errCode = store->Backup(std::string(""), {});
1386 EXPECT_EQ(errCode, E_OK);
1387 if (!CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName)) {
1388 return;
1389 }
1390
1391 auto T1 = GetInsertTime(store, totalCount, dataSize);
1392 auto T2 = GetUpdateTime(store, batchSize, totalCount / batchSize, dataSize);
1393 auto T3 = GetDeleteTime(store, batchSize, totalCount / batchSize);
1394
1395 EXPECT_LT(T1, T1_2 * 1.8);
1396 EXPECT_LT(T2, T2_2 * 1.8);
1397 EXPECT_LT(T3, T3_2 * 1.8);
1398 LOG_INFO("----RdbStore_Binlog_Performance_004----, %{public}" PRId64 ", %{public}" PRId64 ", %{public}" PRId64 ",",
1399 T1, T2, T3);
1400 LOG_INFO("----RdbStore_Binlog_Performance_004----, %{public}" PRId64 ", %{public}" PRId64 ", %{public}" PRId64 ",",
1401 T1_2, T2_2, T3_2);
1402 }
1403
1404 /**
1405 * @tc.name: RdbStore_Binlog_Performance_005
1406 * @tc.desc: test performance of restore in main_replica
1407 * @tc.type: FUNC
1408 */
1409 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_Performance_005, TestSize.Level3)
1410 {
1411 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
1412 struct sqlite3_api_routines_relational mockApi = *sqlite3_export_relational_symbols;
1413 mockApi.is_support_binlog = MockSupportBinlogOff;
1414 auto originalApi = sqlite3_export_relational_symbols;
1415 sqlite3_export_relational_symbols = &mockApi;
1416 EXPECT_EQ(SqliteConnection::IsSupportBinlog(config), false);
1417 LOG_INFO("----RdbStore_Binlog_Performance_005 binlog off----");
1418 auto T1 = GetRestoreTime(HAMode::MAIN_REPLICA);
1419
1420 store = nullptr;
1421 slaveStore = nullptr;
1422 RdbHelper::DeleteRdbStore(RdbDoubleWriteBinlogTest::databaseName);
1423 WaitForBinlogDelete();
1424 ASSERT_FALSE(CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName));
1425 sqlite3_export_relational_symbols = originalApi;
1426 EXPECT_EQ(SqliteConnection::IsSupportBinlog(config), true);
1427 LOG_INFO("----RdbStore_Binlog_Performance_005 binlog on----");
1428 auto T1_2 = GetRestoreTime(HAMode::MAIN_REPLICA);
1429 EXPECT_GT(T1 * 1.8, T1_2);
1430 LOG_INFO("----RdbStore_Binlog_Performance_005----, %{public}" PRId64 ", %{public}" PRId64 ",", T1, T1_2);
1431 }
1432
1433 /**
1434 * @tc.name: RdbStore_Binlog_Performance_006
1435 * @tc.desc: test performance of restore in mannual_trigger
1436 * @tc.type: FUNC
1437 */
1438 HWTEST_F(RdbDoubleWriteBinlogTest, RdbStore_Binlog_Performance_006, TestSize.Level3)
1439 {
1440 RdbStoreConfig config(RdbDoubleWriteBinlogTest::databaseName);
1441 struct sqlite3_api_routines_relational mockApi = *sqlite3_export_relational_symbols;
1442 mockApi.is_support_binlog = MockSupportBinlogOff;
1443 auto originalApi = sqlite3_export_relational_symbols;
1444 sqlite3_export_relational_symbols = &mockApi;
1445 EXPECT_EQ(SqliteConnection::IsSupportBinlog(config), false);
1446 LOG_INFO("----RdbStore_Binlog_Performance_006 binlog off----");
1447 auto T1 = GetRestoreTime(HAMode::MANUAL_TRIGGER, false);
1448
1449 store = nullptr;
1450 slaveStore = nullptr;
1451 RdbHelper::DeleteRdbStore(RdbDoubleWriteBinlogTest::databaseName);
1452 WaitForBinlogDelete();
1453 ASSERT_FALSE(CheckFolderExist(RdbDoubleWriteBinlogTest::binlogDatabaseName));
1454 sqlite3_export_relational_symbols = originalApi;
1455 EXPECT_EQ(SqliteConnection::IsSupportBinlog(config), true);
1456 LOG_INFO("----RdbStore_Binlog_Performance_006 binlog on----");
1457 auto T1_2 = GetRestoreTime(HAMode::MANUAL_TRIGGER, false);
1458 EXPECT_GT(T1 * 1.8, T1_2);
1459 LOG_INFO("----RdbStore_Binlog_Performance_006----, %{public}" PRId64 ", %{public}" PRId64 ",", T1, T1_2);
1460 }
1461