summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/gfdb/gfdb_sqlite3.c
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src/gfdb/gfdb_sqlite3.c')
-rw-r--r--libglusterfs/src/gfdb/gfdb_sqlite3.c187
1 files changed, 183 insertions, 4 deletions
diff --git a/libglusterfs/src/gfdb/gfdb_sqlite3.c b/libglusterfs/src/gfdb/gfdb_sqlite3.c
index 04781be562a..094028361c5 100644
--- a/libglusterfs/src/gfdb/gfdb_sqlite3.c
+++ b/libglusterfs/src/gfdb/gfdb_sqlite3.c
@@ -239,6 +239,7 @@ gf_sqlite3_fill_db_operations(gfdb_db_operations_t *gfdb_db_ops)
gfdb_db_ops->insert_record_op = gf_sqlite3_insert;
gfdb_db_ops->delete_record_op = gf_sqlite3_delete;
+ gfdb_db_ops->compact_db_op = gf_sqlite3_vacuum;
gfdb_db_ops->find_all_op = gf_sqlite3_find_all;
gfdb_db_ops->find_unchanged_for_time_op =
@@ -1327,10 +1328,14 @@ gf_sqlite3_pragma (void *db_conn, char *pragma_key, char **pragma_value)
goto out;
}
- ret = gf_asprintf (pragma_value, "%s", sqlite3_column_text (pre_stmt, 0));
- if (ret <= 0) {
- gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0, LG_MSG_QUERY_FAILED,
- "Failed to get %s from db", pragma_key);
+ if (pragma_value) {
+ ret = gf_asprintf (pragma_value, "%s",
+ sqlite3_column_text (pre_stmt, 0));
+ if (ret <= 0) {
+ gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
+ LG_MSG_QUERY_FAILED, "Failed to get %s from db",
+ pragma_key);
+ }
}
ret = 0;
@@ -1382,3 +1387,177 @@ out:
return ret;
}
+
+/* Function to vacuum of sqlite db
+ * Input:
+ * void *db_conn : Sqlite connection
+ * gf_boolean_t compact_active : Is compaction on?
+ * gf_boolean_t compact_mode_switched : Did we just flip the compaction swtich?
+ * Return:
+ * On success return 0
+ * On failure return -1
+ * */
+int
+gf_sqlite3_vacuum (void *db_conn, gf_boolean_t compact_active,
+ gf_boolean_t compact_mode_switched)
+{
+ int ret = -1;
+ gf_sql_connection_t *sql_conn = db_conn;
+ char *sqlstring = NULL;
+ char *sql_strerror = NULL;
+ gf_boolean_t changing_pragma = _gf_true;
+
+ CHECK_SQL_CONN (sql_conn, out);
+
+ if (GF_SQL_COMPACT_DEF == GF_SQL_COMPACT_NONE) {
+ gf_msg (GFDB_STR_SQLITE3, GF_LOG_INFO, 0,
+ LG_MSG_COMPACT_STATUS,
+ "VACUUM type is off: no VACUUM to do");
+ goto out;
+ }
+
+ if (compact_mode_switched) {
+ if (compact_active) { /* Then it was OFF before.
+ So turn everything on */
+ ret = 0;
+ switch (GF_SQL_COMPACT_DEF) {
+ case GF_SQL_COMPACT_FULL:
+ ret = gf_sqlite3_set_pragma (db_conn,
+ "auto_vacuum",
+ GF_SQL_AV_FULL);
+ break;
+ case GF_SQL_COMPACT_INCR:
+ ret = gf_sqlite3_set_pragma (db_conn,
+ "auto_vacuum",
+ GF_SQL_AV_INCR);
+ break;
+ case GF_SQL_COMPACT_MANUAL:
+ changing_pragma = _gf_false;
+ default:
+ ret = -1;
+ gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
+ LG_MSG_COMPACT_FAILED,
+ "VACUUM type undefined");
+ goto out;
+ break;
+ }
+
+ } else { /* Then it was ON before, so turn it all off */
+ if (GF_SQL_COMPACT_DEF == GF_SQL_COMPACT_FULL ||
+ GF_SQL_COMPACT_DEF == GF_SQL_COMPACT_INCR) {
+ ret = gf_sqlite3_set_pragma (db_conn,
+ "auto_vacuum",
+ GF_SQL_AV_NONE);
+ } else {
+ changing_pragma = _gf_false;
+ }
+ }
+
+ if (ret) {
+ gf_msg (GFDB_STR_SQLITE3, GF_LOG_TRACE, 0,
+ LG_MSG_PREPARE_FAILED,
+ "Failed to set the pragma");
+ goto out;
+ }
+
+ gf_msg (GFDB_STR_SQLITE3, GF_LOG_INFO, 0,
+ LG_MSG_COMPACT_STATUS, "Turning compaction %i",
+ GF_SQL_COMPACT_DEF);
+
+ /* If we move from an auto_vacuum scheme to off, */
+ /* or vice-versa, we must VACUUM to save the change. */
+ /* In the case of a manual VACUUM scheme, we might as well */
+ /* run a manual VACUUM now if we */
+ if (changing_pragma || compact_active) {
+ ret = gf_asprintf (&sqlstring, "VACUUM;");
+ if (ret <= 0) {
+ gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
+ LG_MSG_PREPARE_FAILED,
+ "Failed allocating memory");
+ goto out;
+ }
+ gf_msg(GFDB_STR_SQLITE3, GF_LOG_INFO, 0,
+ LG_MSG_COMPACT_STATUS, "Sealed with a VACUUM");
+ }
+ } else { /* We are active, so it's time to VACUUM */
+ if (!compact_active) { /* Did we somehow enter an inconsistent
+ state? */
+ ret = -1;
+ gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
+ LG_MSG_PREPARE_FAILED,
+ "Tried to VACUUM when compaction inactive");
+ goto out;
+ }
+
+ gf_msg(GFDB_STR_SQLITE3, GF_LOG_TRACE, 0,
+ LG_MSG_COMPACT_STATUS,
+ "Doing regular vacuum of type %i", GF_SQL_COMPACT_DEF);
+
+ switch (GF_SQL_COMPACT_DEF) {
+ case GF_SQL_COMPACT_INCR: /* INCR auto_vacuum */
+ ret = gf_asprintf(&sqlstring,
+ "PRAGMA incremental_vacuum;");
+ if (ret <= 0) {
+ gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
+ LG_MSG_PREPARE_FAILED,
+ "Failed allocating memory");
+ goto out;
+ }
+ gf_msg(GFDB_STR_SQLITE3, GF_LOG_INFO, 0,
+ LG_MSG_COMPACT_STATUS,
+ "Will commence an incremental VACUUM");
+ break;
+ /* (MANUAL) Invoke the VACUUM command */
+ case GF_SQL_COMPACT_MANUAL:
+ ret = gf_asprintf(&sqlstring, "VACUUM;");
+ if (ret <= 0) {
+ gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
+ LG_MSG_PREPARE_FAILED,
+ "Failed allocating memory");
+ goto out;
+ }
+ gf_msg(GFDB_STR_SQLITE3, GF_LOG_INFO, 0,
+ LG_MSG_COMPACT_STATUS,
+ "Will commence a VACUUM");
+ break;
+ /* (FULL) The database does the compaction itself. */
+ /* We cannot do anything else, so we can leave */
+ /* without sending anything to the database */
+ case GF_SQL_COMPACT_FULL:
+ ret = 0;
+ goto success;
+ /* Any other state must be an error. Note that OFF */
+ /* cannot hit this statement since we immediately leave */
+ /* in that case */
+ default:
+ ret = -1;
+ gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
+ LG_MSG_COMPACT_FAILED,
+ "VACUUM type undefined");
+ goto out;
+ break;
+ }
+ }
+
+ gf_msg(GFDB_STR_SQLITE3, GF_LOG_TRACE, 0, LG_MSG_COMPACT_STATUS,
+ "SQLString == %s", sqlstring);
+
+ ret = sqlite3_exec(sql_conn->sqlite3_db_conn, sqlstring, NULL, NULL,
+ &sql_strerror);
+
+ if (ret != SQLITE_OK) {
+ gf_msg (GFDB_STR_SQLITE3, GF_LOG_ERROR, 0,
+ LG_MSG_GET_RECORD_FAILED, "Failed to vacuum "
+ "the db : %s", sqlite3_errmsg (db_conn));
+ ret = -1;
+ goto out;
+ }
+success:
+ gf_msg(GFDB_STR_SQLITE3, GF_LOG_INFO, 0, LG_MSG_COMPACT_STATUS,
+ compact_mode_switched ? "Successfully changed VACUUM on/off"
+ : "DB successfully VACUUM");
+out:
+ GF_FREE(sqlstring);
+
+ return ret;
+}