summaryrefslogtreecommitdiffstats
path: root/ctdb
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2008-01-02 22:44:46 +1100
committerAndrew Tridgell <tridge@samba.org>2008-01-02 22:44:46 +1100
commitbb06e831a0411a93f71b28991f3bd3d68e95c1a7 (patch)
treea76799b1a1368b227f23e2f446eadb0f6c0edf7d /ctdb
parent1ebc6307f18a566be39adeeffbd5f0bfe8437316 (diff)
downloadsamba-bb06e831a0411a93f71b28991f3bd3d68e95c1a7.tar.gz
samba-bb06e831a0411a93f71b28991f3bd3d68e95c1a7.tar.xz
samba-bb06e831a0411a93f71b28991f3bd3d68e95c1a7.zip
more optimisations to recovery
(This used to be ctdb commit 9a41ad0a842cd4f3792d6e84b5c809b7ff6f342e)
Diffstat (limited to 'ctdb')
-rw-r--r--ctdb/server/ctdb_recover.c27
-rw-r--r--ctdb/server/ctdb_recoverd.c47
-rw-r--r--ctdb/tests/ctdb_store.c9
3 files changed, 50 insertions, 33 deletions
diff --git a/ctdb/server/ctdb_recover.c b/ctdb/server/ctdb_recover.c
index 8b2dfb7583..2acc190db4 100644
--- a/ctdb/server/ctdb_recover.c
+++ b/ctdb/server/ctdb_recover.c
@@ -332,10 +332,24 @@ int32_t ctdb_control_push_db(struct ctdb_context *ctdb, TDB_DATA indata)
if the rsn values are equal */
if (header.rsn < hdr->rsn ||
(header.dmaster != ctdb->pnn && header.rsn == hdr->rsn)) {
- ret = ctdb_ltdb_store(ctdb_db, key, hdr, data);
- if (ret != 0) {
- DEBUG(0, (__location__ " Unable to store record\n"));
- goto failed;
+ /* this is a push optimisation - we can skip writing the record if:
+
+ 1) this is not a persistent db
+ AND 2) we are not the recmaster
+ AND 3) we don't hold the record currently
+ AND 4) we won't hold the new record
+ */
+ if (!ctdb_db->persistent &&
+ ctdb->recovery_master != ctdb->pnn &&
+ header.dmaster != ctdb->pnn &&
+ hdr->dmaster != ctdb->pnn) {
+ DEBUG(5,("Skipping push of record\n"));
+ } else {
+ ret = ctdb_ltdb_store(ctdb_db, key, hdr, data);
+ if (ret != 0) {
+ DEBUG(0, (__location__ " Unable to store record\n"));
+ goto failed;
+ }
}
}
@@ -360,6 +374,11 @@ static int traverse_setdmaster(struct tdb_context *tdb, TDB_DATA key, TDB_DATA d
struct ctdb_ltdb_header *header = (struct ctdb_ltdb_header *)data.dptr;
int ret;
+ /* skip if already correct */
+ if (header->dmaster == *dmaster) {
+ return 0;
+ }
+
header->dmaster = *dmaster;
ret = tdb_store(tdb, key, data, TDB_REPLACE);
diff --git a/ctdb/server/ctdb_recoverd.c b/ctdb/server/ctdb_recoverd.c
index 2daac807f8..9ab9a8a69f 100644
--- a/ctdb/server/ctdb_recoverd.c
+++ b/ctdb/server/ctdb_recoverd.c
@@ -504,25 +504,19 @@ static int pull_all_remote_databases(struct ctdb_context *ctdb, struct ctdb_node
/*
change the dmaster on all databases to point to us
*/
-static int update_dmaster_on_all_databases(struct ctdb_context *ctdb, struct ctdb_node_map *nodemap,
- uint32_t pnn, struct ctdb_dbid_map *dbmap, TALLOC_CTX *mem_ctx)
+static int update_dmaster_on_our_databases(struct ctdb_context *ctdb, uint32_t pnn,
+ struct ctdb_dbid_map *dbmap, TALLOC_CTX *mem_ctx)
{
- int i, j, ret;
+ int i, ret;
/* update dmaster to point to this node for all databases/nodes */
for (i=0;i<dbmap->num;i++) {
- for (j=0; j<nodemap->num; j++) {
- /* dont repoint nodes that are unavailable */
- if (nodemap->nodes[j].flags & NODE_FLAGS_INACTIVE) {
- continue;
- }
- ret = ctdb_ctrl_setdmaster(ctdb, CONTROL_TIMEOUT(), nodemap->nodes[j].pnn,
- ctdb, dbmap->dbs[i].dbid, pnn);
- if (ret != 0) {
- DEBUG(0, (__location__ " Unable to set dmaster for node %u db:0x%08x\n",
- nodemap->nodes[j].pnn, dbmap->dbs[i].dbid));
- return -1;
- }
+ ret = ctdb_ctrl_setdmaster(ctdb, CONTROL_TIMEOUT(), pnn,
+ ctdb, dbmap->dbs[i].dbid, pnn);
+ if (ret != 0) {
+ DEBUG(0, (__location__ " Unable to set dmaster for node %u db:0x%08x\n",
+ pnn, dbmap->dbs[i].dbid));
+ return -1;
}
}
@@ -1004,6 +998,18 @@ static int do_recovery(struct ctdb_recoverd *rec,
DEBUG(1, (__location__ " Recovery - pulled remote databases\n"));
+ /* repoint all local database records to the local node as
+ being dmaster
+ */
+ ret = update_dmaster_on_our_databases(ctdb, pnn, dbmap, mem_ctx);
+ if (ret != 0) {
+ DEBUG(0, (__location__ " Unable to update dmaster on all databases\n"));
+ return -1;
+ }
+
+ DEBUG(1, (__location__ " Recovery - updated dmaster on all databases\n"));
+
+
/* push all local databases to the remote nodes */
ret = push_all_local_databases(ctdb, nodemap, pnn, dbmap, mem_ctx);
if (ret != 0) {
@@ -1047,17 +1053,6 @@ static int do_recovery(struct ctdb_recoverd *rec,
DEBUG(1, (__location__ " Recovery - updated recmaster\n"));
- /* repoint all local and remote database records to the local
- node as being dmaster
- */
- ret = update_dmaster_on_all_databases(ctdb, nodemap, pnn, dbmap, mem_ctx);
- if (ret != 0) {
- DEBUG(0, (__location__ " Unable to update dmaster on all databases\n"));
- return -1;
- }
-
- DEBUG(1, (__location__ " Recovery - updated dmaster on all databases\n"));
-
/*
update all nodes to have the same flags that we have
*/
diff --git a/ctdb/tests/ctdb_store.c b/ctdb/tests/ctdb_store.c
index 45373dd28a..70ce7fb59d 100644
--- a/ctdb/tests/ctdb_store.c
+++ b/ctdb/tests/ctdb_store.c
@@ -28,7 +28,7 @@
#include <time.h>
static int num_records = 10;
-
+static int base_rec;
static void store_records(struct ctdb_context *ctdb, struct event_context *ev)
{
@@ -43,7 +43,8 @@ static void store_records(struct ctdb_context *ctdb, struct event_context *ev)
printf("creating %d records\n", num_records);
for (i=0;i<num_records;i++) {
- key.dptr = (uint8_t *)&i;
+ int r = base_rec + i;
+ key.dptr = (uint8_t *)&r;
key.dsize = sizeof(uint32_t);
h = ctdb_fetch_lock(ctdb_db, tmp_ctx, key, &data);
@@ -71,7 +72,8 @@ static void store_records(struct ctdb_context *ctdb, struct event_context *ev)
printf("fetching all %d records\n", num_records);
while (1) {
for (i=0;i<num_records;i++) {
- key.dptr = (uint8_t *)&i;
+ int r = base_rec + i;
+ key.dptr = (uint8_t *)&r;
key.dsize = sizeof(uint32_t);
h = ctdb_fetch_lock(ctdb_db, tmp_ctx, key, &data);
@@ -103,6 +105,7 @@ int main(int argc, const char *argv[])
POPT_AUTOHELP
POPT_CTDB_CMDLINE
{ "num-records", 'r', POPT_ARG_INT, &num_records, 0, "num_records", "integer" },
+ { "base-rec", 'b', POPT_ARG_INT, &base_rec, 0, "base_rec", "integer" },
POPT_TABLEEND
};
int opt;