From 261c035c7d0cd1639cc8bd0ead82c30efcc0e93f Mon Sep 17 00:00:00 2001 From: Diogenes Nunez Date: Wed, 27 Jul 2016 11:09:47 -0400 Subject: cluster/tier: Adding compaction option for metadata databases Problem: As metadata in the database fills up, querying the database take a long time. As a result, tier migration slows down. To counteract this, we added a way to enable the compaction methods of the underlying database. The goal is to reduce the size of the underlying file by eliminating database fragmentation. NOTE: There is currently a bug where sometimes a brick will attempt to activate compaction. This happens even compaction is already turned on. The cause is narrowed down to the compact_mode_switch flipping its value. Changes: libglusterfs/src/gfdb - Added a gfdb function to compact the underlying database, compact_db() This is a no-op if the database has no such option. - Added a compaction function for SQLite3 that does the following 1) Changes the auto_vacuum pragma of the database 2) Compacts the database according to the type of compaction requested - Compaction type can be changed by changing the macro GF_SQL_COMPACT_DEF to one of the 4 compaction types in gfdb_sqlite3.h It is currently set to GF_SQL_COMPACT_INCR, or incremental vacuuming. xlators/cluster/dht/src - Added the following command-line option to enable SQLite3 compaction. gluster volume set tier-compact - Added the following command-line option to change the frequency the hot and cold tier are ordered to compact. gluster volume set tier-hot-compact-frequency gluster volume set tier-cold-compact-frequency - tier daemon periodically sends the (new) GFDB_IPC_CTR_SET_COMPACT_PRAGMA IPC to the CTR xlator. The IPC triggers compaction of the database. The inputs are both gf_boolean_t. IPC Input: compact_active: Is compaction currently on for the db. compact_mode_switched: Did we flip the compaction switch recently? IPC Output: 0 if the compaction succeeds. Non-zero otherwise. xlators/features/changetimerecorder/src/ - When the CTR gets the compaction IPC, it launches a thread that will perform the compaction. The IPC ends after the thread is launched. To avoid extra allocations, the parameters are passed using static variables. Change-Id: I5e1433becb9eeff2afe8dcb4a5798977bf5ba0dd Signed-off-by: Diogenes Nunez Reviewed-on: http://review.gluster.org/15031 Reviewed-by: Milind Changire Reviewed-by: Dan Lambright Tested-by: Dan Lambright CentOS-regression: Gluster Build System NetBSD-regression: NetBSD Build System Smoke: Gluster Build System --- .../changetimerecorder/src/changetimerecorder.c | 146 ++++++++++++++++++++- .../features/changetimerecorder/src/ctr-helper.h | 4 + 2 files changed, 148 insertions(+), 2 deletions(-) (limited to 'xlators/features/changetimerecorder') diff --git a/xlators/features/changetimerecorder/src/changetimerecorder.c b/xlators/features/changetimerecorder/src/changetimerecorder.c index 5f3a074acd5..933f496028c 100644 --- a/xlators/features/changetimerecorder/src/changetimerecorder.c +++ b/xlators/features/changetimerecorder/src/changetimerecorder.c @@ -15,6 +15,8 @@ #include "ctr-messages.h" #include "syscall.h" +#include "changetimerecorder.h" + /*******************************inode forget***********************************/ int @@ -1789,6 +1791,61 @@ out: return ret; } +void * +ctr_compact_thread (void *args) +{ + int ret = -1; + void *db_conn = NULL; + + xlator_t *this = NULL; + gf_ctr_private_t *priv = NULL; + gf_boolean_t compact_active = _gf_false; + gf_boolean_t compact_mode_switched = _gf_false; + + this = (xlator_t *)args; + + GF_VALIDATE_OR_GOTO("ctr", this, out); + + priv = this->private; + + db_conn = priv->_db_conn; + compact_active = priv->compact_active; + compact_mode_switched = priv->compact_mode_switched; + + gf_msg ("ctr-compact", GF_LOG_INFO, 0, CTR_MSG_SET, + "Starting compaction"); + + ret = compact_db(db_conn, compact_active, + compact_mode_switched); + + if (ret) { + gf_msg ("ctr-compact", GF_LOG_ERROR, 0, CTR_MSG_SET, + "Failed to perform the compaction"); + } + + ret = pthread_mutex_lock (&priv->compact_lock); + + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, + "Failed to acquire lock"); + goto out; + } + + /* We are done compaction on this brick. Set all flags to false */ + priv->compact_active = _gf_false; + priv->compact_mode_switched = _gf_false; + + ret = pthread_mutex_unlock (&priv->compact_lock); + + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, + "Failed to release lock"); + goto out; + } + +out: + return NULL; +} int ctr_ipc_helper (xlator_t *this, dict_t *in_dict, @@ -1802,7 +1859,8 @@ ctr_ipc_helper (xlator_t *this, dict_t *in_dict, char *db_param = NULL; char *query_file = NULL; gfdb_ipc_ctr_params_t *ipc_ctr_params = NULL; - + int result = 0; + pthread_t compact_thread; GF_VALIDATE_OR_GOTO ("ctr", this, out); GF_VALIDATE_OR_GOTO (this->name, this->private, out); @@ -1888,12 +1946,78 @@ ctr_ipc_helper (xlator_t *this, dict_t *in_dict, SET_DB_PARAM_TO_DICT(this->name, out_dict, db_param_key, db_param, ret, error); + } /* if its an attempt to compact the database */ + else if (strncmp (ctr_ipc_ops, GFDB_IPC_CTR_SET_COMPACT_PRAGMA, + strlen (GFDB_IPC_CTR_SET_COMPACT_PRAGMA)) == 0) { + + ret = pthread_mutex_lock (&priv->compact_lock); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, + "Failed to acquire lock for compaction"); + goto out; + } + + if ((priv->compact_active || priv->compact_mode_switched)) { + /* Compaction in progress. LEAVE */ + gf_msg (this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, + "Compaction already in progress."); + pthread_mutex_unlock (&priv->compact_lock); + goto out; + } + /* At this point, we should be the only one on the brick */ + /* compacting */ + + /* Grab the arguments from the dictionary */ + ret = dict_get_int32 (in_dict, "compact_active", &result); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, + "Failed to get compaction type"); + goto out; + } + + if (result) { + priv->compact_active = _gf_true; + } + + ret = dict_get_int32 (in_dict, "compact_mode_switched" + , &result); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, + "Failed to see if compaction switched"); + goto out; + } + + if (result) { + priv->compact_mode_switched = _gf_true; + gf_msg ("ctr-compact", GF_LOG_TRACE, 0, CTR_MSG_SET, + "Pre-thread: Compact mode switch is true"); + } else { + gf_msg ("ctr-compact", GF_LOG_TRACE, 0, CTR_MSG_SET, + "Pre-thread: Compact mode switch is false"); + } + + ret = pthread_mutex_unlock (&priv->compact_lock); + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, + "Failed to release lock for compaction"); + goto out; + } + + ret = pthread_create (&compact_thread, NULL, ctr_compact_thread, + (void *)this); + + if (ret) { + gf_msg (this->name, GF_LOG_ERROR, 0, CTR_MSG_SET, + "Failed to spawn compaction thread"); + goto out; + } + + goto out; } /* default case */ else { goto out; } - ret = 0; goto out; error: @@ -2079,6 +2203,18 @@ init (xlator_t *this) priv->ctr_lookupheal_inode_timeout = CTR_DEFAULT_INODE_EXP_PERIOD; + /* For compaction */ + priv->compact_active = _gf_false; + priv->compact_mode_switched = _gf_false; + ret_db = pthread_mutex_init (&priv->compact_lock, NULL); + + if (ret_db) { + gf_msg (this->name, GF_LOG_ERROR, 0, + CTR_MSG_FATAL_ERROR, + "FATAL: Failed initializing compaction mutex"); + goto error; + } + /*Extract ctr xlator options*/ ret_db = extract_ctr_options (this, priv); if (ret_db) { @@ -2123,6 +2259,7 @@ init (xlator_t *this) goto error; } + ret_db = 0; goto out; @@ -2185,6 +2322,11 @@ fini (xlator_t *this) "db connection"); } GF_FREE (priv->ctr_db_path); + if (pthread_mutex_destroy (&priv->compact_lock)) { + gf_msg (this->name, GF_LOG_WARNING, 0, + CTR_MSG_CLOSE_DB_CONN_FAILED, "Failed to " + "destroy the compaction mutex"); + } } GF_FREE (priv); mem_pool_destroy (this->local_pool); diff --git a/xlators/features/changetimerecorder/src/ctr-helper.h b/xlators/features/changetimerecorder/src/ctr-helper.h index d5615270184..4fd4f745f4d 100644 --- a/xlators/features/changetimerecorder/src/ctr-helper.h +++ b/xlators/features/changetimerecorder/src/ctr-helper.h @@ -22,6 +22,7 @@ #include "common-utils.h" #include #include +#include #include "gfdb_data_store.h" #include "ctr-xlator-ctx.h" @@ -52,6 +53,9 @@ typedef struct gf_ctr_private { gfdb_conn_node_t *_db_conn; uint64_t ctr_lookupheal_link_timeout; uint64_t ctr_lookupheal_inode_timeout; + gf_boolean_t compact_active; + gf_boolean_t compact_mode_switched; + pthread_mutex_t compact_lock; } gf_ctr_private_t; -- cgit