summaryrefslogtreecommitdiff
path: root/ctdb/server/ctdb_call.c
diff options
context:
space:
mode:
authorAmitay Isaacs <amitay@gmail.com>2017-03-21 16:48:45 +1100
committerMartin Schwenke <martins@samba.org>2017-04-05 08:35:45 +0200
commit5da471919d2b7ed45be574a8cb7c88351f894797 (patch)
tree682e63e524bb01f183f11730e7c1f55344f8507c /ctdb/server/ctdb_call.c
parent1445fa3b7126a3e12fc795db2d7a495f9caf2a3a (diff)
downloadsamba-5da471919d2b7ed45be574a8cb7c88351f894797.tar.gz
ctdb-daemon: Add tracking of migration records
Instead of using hopcount as a metric for hot records, use the number of migrations per second as a metric. Signed-off-by: Amitay Isaacs <amitay@gmail.com> Reviewed-by: Martin Schwenke <martin@meltin.net> Autobuild-User(master): Martin Schwenke <martins@samba.org> Autobuild-Date(master): Wed Apr 5 08:35:45 CEST 2017 on sn-devel-144
Diffstat (limited to 'ctdb/server/ctdb_call.c')
-rw-r--r--ctdb/server/ctdb_call.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/ctdb/server/ctdb_call.c b/ctdb/server/ctdb_call.c
index a1f897c8f19..ed943f91b3c 100644
--- a/ctdb/server/ctdb_call.c
+++ b/ctdb/server/ctdb_call.c
@@ -41,6 +41,7 @@
#include "common/system.h"
#include "common/common.h"
#include "common/logging.h"
+#include "common/hash_count.h"
struct ctdb_sticky_record {
struct ctdb_context *ctdb;
@@ -416,6 +417,8 @@ static void ctdb_become_dmaster(struct ctdb_db_context *ctdb_db,
return;
}
+ (void) hash_count_increment(ctdb_db->migratedb, key);
+
ctdb_call_local(ctdb_db, state->call, &header, state, &data, true);
ret = ctdb_ltdb_unlock(ctdb_db, state->call->key);
@@ -1092,7 +1095,6 @@ void ctdb_request_call(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
}
CTDB_INCREMENT_STAT(ctdb, hop_count_bucket[bucket]);
CTDB_INCREMENT_DB_STAT(ctdb_db, hop_count_bucket[bucket]);
- ctdb_update_db_stat_hot_keys(ctdb_db, call->key, c->hopcount);
/* If this database supports sticky records, then check if the
hopcount is big. If it is it means the record is hot and we
@@ -1929,3 +1931,73 @@ int ctdb_add_revoke_deferred_call(struct ctdb_context *ctdb, struct ctdb_db_cont
return 0;
}
+
+static void ctdb_migration_count_handler(TDB_DATA key, uint64_t counter,
+ void *private_data)
+{
+ struct ctdb_db_context *ctdb_db = talloc_get_type_abort(
+ private_data, struct ctdb_db_context);
+ int value;
+
+ value = (counter < INT_MAX ? counter : INT_MAX);
+ ctdb_update_db_stat_hot_keys(ctdb_db, key, value);
+}
+
+static void ctdb_migration_cleandb_event(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval current_time,
+ void *private_data)
+{
+ struct ctdb_db_context *ctdb_db = talloc_get_type_abort(
+ private_data, struct ctdb_db_context);
+
+ if (ctdb_db->migratedb == NULL) {
+ return;
+ }
+
+ hash_count_expire(ctdb_db->migratedb, NULL);
+
+ te = tevent_add_timer(ctdb_db->ctdb->ev, ctdb_db->migratedb,
+ tevent_timeval_current_ofs(10, 0),
+ ctdb_migration_cleandb_event, ctdb_db);
+ if (te == NULL) {
+ DEBUG(DEBUG_ERR,
+ ("Memory error in migration cleandb event for %s\n",
+ ctdb_db->db_name));
+ TALLOC_FREE(ctdb_db->migratedb);
+ }
+}
+
+int ctdb_migration_init(struct ctdb_db_context *ctdb_db)
+{
+ struct timeval one_second = { 1, 0 };
+ struct tevent_timer *te;
+ int ret;
+
+ if (ctdb_db->persistent) {
+ return 0;
+ }
+
+ ret = hash_count_init(ctdb_db, one_second,
+ ctdb_migration_count_handler, ctdb_db,
+ &ctdb_db->migratedb);
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR,
+ ("Memory error in migration init for %s\n",
+ ctdb_db->db_name));
+ return -1;
+ }
+
+ te = tevent_add_timer(ctdb_db->ctdb->ev, ctdb_db->migratedb,
+ tevent_timeval_current_ofs(10, 0),
+ ctdb_migration_cleandb_event, ctdb_db);
+ if (te == NULL) {
+ DEBUG(DEBUG_ERR,
+ ("Memory error in migration init for %s\n",
+ ctdb_db->db_name));
+ TALLOC_FREE(ctdb_db->migratedb);
+ return -1;
+ }
+
+ return 0;
+}