• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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