From 98ea521303d74cfc8bb4cc7b801274f3c0cbfece Mon Sep 17 00:00:00 2001 From: Junghyun Yeon Date: Wed, 5 Jun 2019 19:49:14 +0900 Subject: [PATCH] Change pkg db journaling mode to WAL Related changes: [pkgmgr-tool] : https://review.tizen.org/gerrit/#/c/platform/core/appfw/pkgmgr-tool/+/207512/ Change-Id: I835fc6a87b2a5f2b7de3bb88cdc533d05368fd97 Signed-off-by: Junghyun Yeon --- parser/src/pkgmgr_parser_db.c | 66 +++++++++++++++++++++++++++++++++++-------- pkg_db_version.txt.in | 2 +- src/pkgmgrinfo_private.c | 28 ++++++++++++++++++ tool/pkg-db-recovery.c | 9 ++++++ 4 files changed, 92 insertions(+), 13 deletions(-) diff --git a/parser/src/pkgmgr_parser_db.c b/parser/src/pkgmgr_parser_db.c index 3d79e4c..6829c08 100644 --- a/parser/src/pkgmgr_parser_db.c +++ b/parser/src/pkgmgr_parser_db.c @@ -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", diff --git a/pkg_db_version.txt.in b/pkg_db_version.txt.in index 99e5dbf..00c6570 100644 --- a/pkg_db_version.txt.in +++ b/pkg_db_version.txt.in @@ -1 +1 @@ -30004 +30005 diff --git a/src/pkgmgrinfo_private.c b/src/pkgmgrinfo_private.c index 04cfb65..7ed3fa5 100644 --- a/src/pkgmgrinfo_private.c +++ b/src/pkgmgrinfo_private.c @@ -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; } diff --git a/tool/pkg-db-recovery.c b/tool/pkg-db-recovery.c index e4475f1..4d92612 100644 --- a/tool/pkg-db-recovery.c +++ b/tool/pkg-db-recovery.c @@ -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) { -- 2.7.4