From 5da471919d2b7ed45be574a8cb7c88351f894797 Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Tue, 21 Mar 2017 16:48:45 +1100 Subject: [PATCH] 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 Reviewed-by: Martin Schwenke Autobuild-User(master): Martin Schwenke Autobuild-Date(master): Wed Apr 5 08:35:45 CEST 2017 on sn-devel-144 --- ctdb/include/ctdb_private.h | 4 ++ ctdb/server/ctdb_call.c | 74 +++++++++++++++++++++++++++++++++- ctdb/server/ctdb_ltdb_server.c | 9 +++++ 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h index d81ed56d763..91e98857a15 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -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); 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; +} diff --git a/ctdb/server/ctdb_ltdb_server.c b/ctdb/server/ctdb_ltdb_server.c index 8ff963419f1..677078be6a8 100644 --- a/ctdb/server/ctdb_ltdb_server.c +++ b/ctdb/server/ctdb_ltdb_server.c @@ -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", -- 2.34.1