Change pkg db journaling mode to WAL 13/207513/6
authorJunghyun Yeon <jungh.yeon@samsung.com>
Wed, 5 Jun 2019 10:49:14 +0000 (19:49 +0900)
committerJunghyun Yeon <jungh.yeon@samsung.com>
Fri, 28 Jun 2019 05:53:54 +0000 (14:53 +0900)
Related changes:
[pkgmgr-tool] : https://review.tizen.org/gerrit/#/c/platform/core/appfw/pkgmgr-tool/+/207512/

Change-Id: I835fc6a87b2a5f2b7de3bb88cdc533d05368fd97
Signed-off-by: Junghyun Yeon <jungh.yeon@samsung.com>
parser/src/pkgmgr_parser_db.c
pkg_db_version.txt.in
src/pkgmgrinfo_private.c
tool/pkg-db-recovery.c

index 3d79e4c..6829c08 100644 (file)
@@ -90,6 +90,9 @@
 #define APP_BG_CATEGORY_IOTCOMM_STR            "iot-communication"
 #define APP_BG_CATEGORY_SYSTEM                 "system"
 
+#define DB_POSTFIX_SHM                         "-shm"
+#define DB_POSTFIX_WAL                         "-wal"
+
 #define REGULAR_USER 5000
 static inline uid_t __getuid(void)
 {
@@ -234,8 +237,9 @@ do {                                                                           \
 static int __set_db_permission(const char *path, uid_t uid)
 {
        int fd;
-       const char *files[2];
-       char journal_file[BUFSIZE];
+       const char *files[3];
+       char shm_file[BUFSIZE];
+       char wal_file[BUFSIZE];
        struct stat sb;
        mode_t mode;
        struct passwd pwd;
@@ -259,9 +263,11 @@ static int __set_db_permission(const char *path, uid_t uid)
                uid = pwd.pw_uid;
        }
 
-       snprintf(journal_file, sizeof(journal_file), "%s-journal", path);
+       snprintf(shm_file, sizeof(shm_file), "%s%s", path, DB_POSTFIX_SHM);
+       snprintf(wal_file, sizeof(wal_file), "%s%s", path, DB_POSTFIX_WAL);
        files[0] = path;
-       files[1] = journal_file;
+       files[1] = shm_file;
+       files[2] = wal_file;
 
        ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &result);
        if (result == NULL) {
@@ -272,7 +278,7 @@ static int __set_db_permission(const char *path, uid_t uid)
                return -1;
        }
 
-       for (i = 0; i < 2; i++) {
+       for (i = 0; i < 3; i++) {
                fd = open(files[i], O_RDONLY);
                if (fd == -1) {
                        _LOGE("open %s failed: %d", files[i], errno);
@@ -361,10 +367,27 @@ static int __create_tables(sqlite3 *db, const char **queries)
 static int __initialize_db(sqlite3 *db, const char *dbpath, uid_t uid)
 {
        const char **queries;
-
+       int persist_wal = 1;
        if (__set_db_version(db))
                return -1;
 
+       int ret = sqlite3_exec(db, "PRAGMA journal_mode=WAL", NULL, NULL, NULL);
+       if (ret != SQLITE_OK) {
+               _LOGE("failed to set wal mode: %s",
+                               sqlite3_errmsg(db));
+               sqlite3_close_v2(db);
+               return ret;
+       }
+
+       ret = sqlite3_file_control(db, NULL,
+                       SQLITE_FCNTL_PERSIST_WAL, &persist_wal);
+       if (ret != SQLITE_OK) {
+               _LOGE("failed to execute sqlite3_file_control: %s",
+                               sqlite3_errmsg(db));
+               sqlite3_close_v2(db);
+               return ret;
+       }
+
        if (strstr(dbpath, ".pkgmgr_parser.db")) {
                queries = parser_init_queries;
        } else if (strstr(dbpath, ".pkgmgr_cert.db")) {
@@ -605,15 +628,23 @@ API int pkgmgr_parser_create_and_initialize_db(uid_t uid)
        return PM_PARSER_R_OK;
 }
 
+static int _internal_callback(void *userdata, sqlite3 *db,
+               const char *db_name, int page_num)
+{
+       int ret = sqlite3_wal_checkpoint_v2(db, NULL, SQLITE_CHECKPOINT_PASSIVE,
+                       NULL, NULL);
+       if (ret != SQLITE_OK) {
+               _LOGE("failed to checkpoint: %s",
+                               sqlite3_errmsg(db));
+               return SQLITE_ERROR;
+       }
+       return SQLITE_OK;
+}
+
 static int __open_db(uid_t uid, const char *path, sqlite3 **db, int flags)
 {
        int ret;
-
-       /* FIXME: always open with OPEN_CREATE flag for keeping previous
-        * implementation
-        */
-       if (flags & SQLITE_OPEN_READWRITE)
-               flags = flags | SQLITE_OPEN_CREATE;
+       int persist_wal = 1;
 
        ret = sqlite3_open_v2(path, db, flags, NULL);
        if (ret != SQLITE_OK)
@@ -636,6 +667,17 @@ static int __open_db(uid_t uid, const char *path, sqlite3 **db, int flags)
                }
        }
 
+       sqlite3_wal_hook(*db, _internal_callback, NULL);
+
+       ret = sqlite3_file_control(*db, NULL,
+                       SQLITE_FCNTL_PERSIST_WAL, &persist_wal);
+       if (ret != SQLITE_OK) {
+               _LOGE("failed to execute sqlite3_file_control: %s",
+                               sqlite3_errmsg(*db));
+               sqlite3_close_v2(*db);
+               return ret;
+       }
+
        ret = sqlite3_exec(*db, "PRAGMA foreign_keys=ON", NULL, NULL, NULL);
        if (ret != SQLITE_OK) {
                _LOGE("failed to enable foreign key support: %s",
index 99e5dbf..00c6570 100644 (file)
@@ -1 +1 @@
-30004
+30005
index 04cfb65..7ed3fa5 100644 (file)
@@ -571,6 +571,8 @@ static int __db_busy_handler(void *data, int count)
 int __open_db(const char *path, sqlite3 **db, int flags)
 {
        int ret;
+       int persist_wal = 1;
+       int no_checkpoint = 1;
 
        ret = sqlite3_open_v2(path, db, flags, NULL);
        if (ret != SQLITE_OK)
@@ -584,6 +586,32 @@ int __open_db(const char *path, sqlite3 **db, int flags)
                return ret;
        }
 
+       ret = sqlite3_file_control(*db, NULL,
+                       SQLITE_FCNTL_PERSIST_WAL, &persist_wal);
+       if (ret != SQLITE_OK) {
+               _LOGE("failed to sqlite3_file_control: %s",
+                               sqlite3_errmsg(*db));
+               sqlite3_close_v2(*db);
+               return ret;
+       }
+
+       ret = sqlite3_wal_autocheckpoint(*db, 0);
+       if (ret != SQLITE_OK) {
+               _LOGE("failed to sqlite3_wal_autocheckpoint: %s",
+                               sqlite3_errmsg(*db));
+               sqlite3_close_v2(*db);
+               return ret;
+       }
+
+       ret = sqlite3_db_config(*db, SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE,
+                                                       &no_checkpoint);
+       if (ret != SQLITE_OK) {
+               _LOGE("failed to execute sqlite3_db_config: %s",
+                               sqlite3_errmsg(*db));
+               sqlite3_close_v2(*db);
+               return ret;
+       }
+
        return ret;
 }
 
index e4475f1..4d92612 100644 (file)
@@ -97,6 +97,7 @@ static int __db_busy_handler(void *data, int count)
 static bool __integrity_check(const char *db_path)
 {
        int ret = -1;
+       int persist_wal = 1;
        sqlite3_stmt *stmt = NULL;
        const char *check_result;
        static const char integrity_check_query[] =
@@ -118,6 +119,14 @@ static bool __integrity_check(const char *db_path)
                return ret;
        }
 
+       ret = sqlite3_file_control(db, NULL, SQLITE_FCNTL_PERSIST_WAL, &persist_wal);
+       if (ret != SQLITE_OK) {
+               LOGE("failed to sqlite3_file_control: %s",
+                               sqlite3_errmsg(db));
+               sqlite3_close_v2(db);
+               return ret;
+       }
+
        ret = sqlite3_prepare_v2(db, integrity_check_query,
                        strlen(integrity_check_query), &stmt, NULL);
        if (ret != SQLITE_OK) {