summaryrefslogtreecommitdiffstats
path: root/xlators/features/changetimerecorder
diff options
context:
space:
mode:
authorDiogenes Nunez <dnunez@redhat.com>2016-07-27 11:09:47 -0400
committerDan Lambright <dlambrig@redhat.com>2016-09-04 18:37:57 -0700
commit261c035c7d0cd1639cc8bd0ead82c30efcc0e93f (patch)
treeaf3a2e498023e7ad8af417312b83ce2f969ef738 /xlators/features/changetimerecorder
parent6459fc812219551291e4be426ed8ecf2c90813a4 (diff)
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 <vol-name> tier-compact <off|on> - Added the following command-line option to change the frequency the hot and cold tier are ordered to compact. gluster volume set <vol-name> tier-hot-compact-frequency <int> gluster volume set <vol-name> tier-cold-compact-frequency <int> - 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 <dnunez@redhat.com> Reviewed-on: http://review.gluster.org/15031 Reviewed-by: Milind Changire <mchangir@redhat.com> Reviewed-by: Dan Lambright <dlambrig@redhat.com> Tested-by: Dan Lambright <dlambrig@redhat.com> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Smoke: Gluster Build System <jenkins@build.gluster.org>
Diffstat (limited to 'xlators/features/changetimerecorder')
-rw-r--r--xlators/features/changetimerecorder/src/changetimerecorder.c146
-rw-r--r--xlators/features/changetimerecorder/src/ctr-helper.h4
2 files changed, 148 insertions, 2 deletions
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 <time.h>
#include <sys/time.h>
+#include <pthread.h>
#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;