ctdb-daemon: Add tracking of migration records
authorAmitay Isaacs <amitay@gmail.com>
Tue, 21 Mar 2017 05:48:45 +0000 (16:48 +1100)
committerMartin Schwenke <martins@samba.org>
Wed, 5 Apr 2017 06:35:45 +0000 (08:35 +0200)
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

ctdb/include/ctdb_private.h
ctdb/server/ctdb_call.c
ctdb/server/ctdb_ltdb_server.c

index d81ed56d76306954d5d1ee4ad41892f5f98499c6..91e98857a15a44d1a9572b18b7e3f6b1e25eae33 100644 (file)
@@ -387,6 +387,8 @@ struct ctdb_db_context {
 
        bool push_started;
        void *push_state;
+
+       struct hash_count_context *migratedb;
 };
 
 
@@ -521,6 +523,8 @@ int ctdb_add_revoke_deferred_call(struct ctdb_context *ctdb,
                                  TDB_DATA key, struct ctdb_req_header *hdr,
                                  deferred_requeue_fn fn, void *call_context);
 
+int ctdb_migration_init(struct ctdb_db_context *ctdb_db);
+
 /* from server/ctdb_control.c */
 
 int32_t ctdb_dump_memory(struct ctdb_context *ctdb, TDB_DATA *outdata);
index a1f897c8f19f7e6b991c5a2e19c6d39d249a77b3..ed943f91b3cbad9a679a5e6736089b0b4da1103f 100644 (file)
@@ -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;
+}
index 8ff963419f15197fd0236d6bedad26fc40098b23..677078be6a87e3d3b29b9b56c4be2b32e02d274c 100644 (file)
@@ -1027,6 +1027,15 @@ again:
                return -1;
        }
 
+       ret = ctdb_migration_init(ctdb_db);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR,
+                     ("Failed to setup migration tracking for db '%s'\n",
+                      ctdb_db->db_name));
+               talloc_free(ctdb_db);
+               return -1;
+       }
+
        ctdb_db->generation = ctdb->vnn_map->generation;
 
        DEBUG(DEBUG_NOTICE,("Attached to database '%s' with flags 0x%x\n",