The branch, master has been updated
       via  3e5d2b61fcb4d0062d2573d99724f630a4fc4622 (commit)
       via  c6433e43ad2481d84e8d9a1ee1c6e29b90423a86 (commit)
       via  25d797f61c3b5b7090fb662adde6ed9e434e8a61 (commit)
      from  70d22efdf104db1fc951263cedfbdb95b0b44342 (commit)

http://gitweb.samba.org/?p=ctdb.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 3e5d2b61fcb4d0062d2573d99724f630a4fc4622
Author: Ronnie Sahlberg <ronniesahlb...@gmail.com>
Date:   Wed Feb 8 08:59:53 2012 +1100

    TESTS: Add a test that verifies that RecoverPDBBySeqNum works as expected.
    
    If this tunable is set to 1 AND the persistent database contains a record 
"__db_sequence_number__" then we will recover the whole database as-is instead 
of doing the record by record recovery

commit c6433e43ad2481d84e8d9a1ee1c6e29b90423a86
Author: Ronnie Sahlberg <ronniesahlb...@gmail.com>
Date:   Tue Feb 7 12:14:57 2012 +1100

    Ad test tool to store data and ctdb header into a local tdb file

commit 25d797f61c3b5b7090fb662adde6ed9e434e8a61
Author: Ronnie Sahlberg <ronniesahlb...@gmail.com>
Date:   Tue Feb 7 10:53:49 2012 +1100

    TFETCH add verbose flag to print also the record ltdb heaer

-----------------------------------------------------------------------

Summary of changes:
 tests/simple/70_recoverpdbbyseqnum.sh |  232 +++++++++++++++++++++++++++++++++
 tools/ctdb.c                          |   83 +++++++++++-
 2 files changed, 309 insertions(+), 6 deletions(-)
 create mode 100755 tests/simple/70_recoverpdbbyseqnum.sh


Changeset truncated at 500 lines:

diff --git a/tests/simple/70_recoverpdbbyseqnum.sh 
b/tests/simple/70_recoverpdbbyseqnum.sh
new file mode 100755
index 0000000..4b46cbb
--- /dev/null
+++ b/tests/simple/70_recoverpdbbyseqnum.sh
@@ -0,0 +1,232 @@
+#!/bin/bash
+
+test_info()
+{
+    cat <<EOF
+The tunable RecoverPDBBySeqNum controls how we perform recovery
+on persistent databases.
+The default is that persistent databases are recovered exactly the same
+way as normal databases. That is that we recover record by record.
+
+If RecoverPDBBySeqNum is set to 1 AND if a record with the key
+"__db_sequence_number__" can be found in the database, then instead we will
+perform the recovery by picking the copy of the database from the node
+that has the highest sequence number and ignore the content on all other
+nodes.
+
+
+Prerequisites:
+
+* An active CTDB cluster with at least 2 active nodes.
+
+Steps:
+
+1. Verify that the status on all of the ctdb nodes is 'OK'.
+2. create a persistent test database
+3. test that RecoveryPDBBySeqNum==0 and no seqnum record blends the database
+   during recovery
+4. test that RecoveryPDBBySeqNum==0 and seqnum record blends the database
+   during recovery
+5. test that RecoveryPDBBySeqNum==1 and no seqnum record blends the database
+   during recovery
+6. test that RecoveryPDBBySeqNum==1 and seqnum record does not blend the 
database
+   during recovery
+
+Expected results:
+
+* that 3,4,5 will blend the databases and that 6 will recovery the highest 
seqnum
+  database
+
+EOF
+}
+
+. ctdb_test_functions.bash
+
+ctdb_test_init "$@"
+
+set -e
+
+cluster_is_healthy
+
+try_command_on_node 0 "$CTDB listnodes"
+num_nodes=$(echo "$out" | wc -l)
+
+# create a temporary persistent database to test with
+echo create persistent test database persistent_test.tdb
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb attach persistent_test.tdb 
persistent
+
+
+# set RecoverPDBBySeqNum=0
+echo "setting RecoverPDBBySeqNum to 0"
+try_command_on_node -q all $CTDB_TEST_WRAPPER ctdb setvar RecoverPDBBySeqNum 0
+
+
+
+# 3,
+# If RecoverPDBBySeqNum==0  and no __db_sequence_number__
+# recover record by record
+#
+# wipe database
+echo
+echo test that RecoverPDBBySeqNum==0 and no __db_sequence_number__ blends the 
database during recovery
+echo wipe the test database
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb wipedb persistent_test.tdb
+
+# add one record to node 0   key==ABC  data==ABC
+TDB=`try_command_on_node -v -q 0 $CTDB_TEST_WRAPPER ctdb getdbmap | grep 
persistent_test.tdb | sed -e "s/.*path://" -e "s/ .*//"`
+echo "store key(ABC) data(ABC) on node 0"
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb tstore $TDB 0x414243 
0x070000000000000000000000000000000000000000000000414243
+#
+# add one record to node 1   key==DEF  data==DEF
+TDB=`try_command_on_node -v -q 1 $CTDB_TEST_WRAPPER ctdb getdbmap | grep 
persistent_test.tdb | sed -e "s/.*path://" -e "s/ .*//"`
+echo "store key(DEF) data(DEF) on node 1"
+try_command_on_node -q 1 $CTDB_TEST_WRAPPER ctdb tstore $TDB 0x444546 
0x070000000000000000000000000000000000000000000000444546
+
+# force a recovery
+echo force a recovery
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb recover
+
+# check that we now have both records on node 0
+num_records=$(try_command_on_node -v -pq 0 $CTDB_TEST_WRAPPER ctdb cattdb 
persistent_test.tdb | grep key | egrep "ABC|DEF" | wc -l)
+[ $num_records != "2" ] && {
+    echo "BAD: we did not end up with the expected two records after the 
recovery"
+    exit 1
+}
+echo "OK. databases were blended"
+
+
+
+# 4,
+# If RecoverPDBBySeqNum==0  and __db_sequence_number__
+# recover record by record
+#
+# wipe database
+echo
+echo test that RecoverPDBBySeqNum==0 and __db_sequence_number__ blends the 
database during recovery
+echo wipe the test database
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb wipedb persistent_test.tdb
+
+echo "add __db_sequence_number__==5 record to all nodes"
+try_command_on_node -v 0 $CTDB_TEST_WRAPPER ctdb nodestatus all | grep pnn | 
sed -e"s/^pnn://" -e "s/ .*//" | while read PNN; do
+    TDB=`try_command_on_node -v -q $PNN $CTDB_TEST_WRAPPER ctdb getdbmap | 
grep persistent_test.tdb | sed -e "s/.*path://" -e "s/ .*//"`
+    try_command_on_node -q $PNN $CTDB_TEST_WRAPPER ctdb tstore $TDB 
0x5f5f64625f73657175656e63655f6e756d6265725f5f00 
0x0700000000000000000000000000000000000000000000000500000000000000
+done
+
+# add one record to node 0   key==ABC  data==ABC
+TDB=`try_command_on_node -v -q 0 $CTDB_TEST_WRAPPER ctdb getdbmap | grep 
persistent_test.tdb | sed -e "s/.*path://" -e "s/ .*//"`
+echo "store key(ABC) data(ABC) on node 0"
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb tstore $TDB 0x414243 
0x070000000000000000000000000000000000000000000000414243
+echo "add __db_sequence_number__==7 record to node 0"
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb tstore $TDB 
0x5f5f64625f73657175656e63655f6e756d6265725f5f00 
0x0700000000000000000000000000000000000000000000000700000000000000
+
+# add one record to node 1   key==DEF  data==DEF
+TDB=`try_command_on_node -v -q 1 $CTDB_TEST_WRAPPER ctdb getdbmap | grep 
persistent_test.tdb | sed -e "s/.*path://" -e "s/ .*//"`
+echo "store key(DEF) data(DEF) on node 1"
+try_command_on_node -q 1 $CTDB_TEST_WRAPPER ctdb tstore $TDB 0x444546 
0x070000000000000000000000000000000000000000000000444546
+echo "add __db_sequence_number__==8 record to node 1"
+try_command_on_node -q 1 $CTDB_TEST_WRAPPER ctdb tstore $TDB 
0x5f5f64625f73657175656e63655f6e756d6265725f5f00 
0x0700000000000000000000000000000000000000000000000800000000000000
+
+# force a recovery
+echo force a recovery
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb recover
+
+# check that we now have both records on node 0
+num_records=$(try_command_on_node -v -pq 0 $CTDB_TEST_WRAPPER ctdb cattdb 
persistent_test.tdb | grep key | egrep "ABC|DEF" | wc -l)
+[ $num_records != "2" ] && {
+    echo "BAD: we did not end up with the expected two records after the 
recovery"
+    exit 1
+}
+echo "OK. databases were blended"
+
+
+
+# set RecoverPDBBySeqNum=1
+echo
+echo "setting RecoverPDBBySeqNum to 1"
+try_command_on_node -q all $CTDB_TEST_WRAPPER ctdb setvar RecoverPDBBySeqNum 1
+
+
+
+# 5,
+# If RecoverPDBBySeqNum==1  and no __db_sequence_number__
+# recover record by record
+#
+# wipe database
+echo
+echo test that RecoverPDBBySeqNum==1 and no __db_sequence_number__ blends the 
database during recovery
+echo wipe the test database
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb wipedb persistent_test.tdb
+
+# add one record to node 0   key==ABC  data==ABC
+TDB=`try_command_on_node -v -q 0 $CTDB_TEST_WRAPPER ctdb getdbmap | grep 
persistent_test.tdb | sed -e "s/.*path://" -e "s/ .*//"`
+echo "store key(ABC) data(ABC) on node 0"
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb tstore $TDB 0x414243 
0x070000000000000000000000000000000000000000000000414243
+
+# add one record to node 1   key==DEF  data==DEF
+TDB=`try_command_on_node -v -q 1 $CTDB_TEST_WRAPPER ctdb getdbmap | grep 
persistent_test.tdb | sed -e "s/.*path://" -e "s/ .*//"`
+echo "store key(DEF) data(DEF) on node 1"
+try_command_on_node -q 1 $CTDB_TEST_WRAPPER ctdb tstore $TDB 0x444546 
0x070000000000000000000000000000000000000000000000444546
+
+# force a recovery
+echo force a recovery
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb recover
+
+# check that we now have both records on node 0
+num_records=$(try_command_on_node -v -pq 0 $CTDB_TEST_WRAPPER ctdb cattdb 
persistent_test.tdb | grep key | egrep "ABC|DEF" | wc -l)
+[ $num_records != "2" ] && {
+    echo "BAD: we did not end up with the expected two records after the 
recovery"
+    exit 1
+}
+echo "OK. databases were blended"
+
+
+
+# 6,
+# If RecoverPDBBySeqNum==1  and __db_sequence_number__
+# recover whole database
+#
+# wipe database
+echo
+echo test that RecoverPDBBySeqNum==1 and __db_sequence_number__ does not blend 
the database during recovery
+echo wipe the test database
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb wipedb persistent_test.tdb
+
+echo "add __db_sequence_number__==5 record to all nodes"
+try_command_on_node -v 0 $CTDB_TEST_WRAPPER ctdb nodestatus all | grep pnn | 
sed -e"s/^pnn://" -e "s/ .*//" | while read PNN; do
+    TDB=`try_command_on_node -v -q $PNN $CTDB_TEST_WRAPPER ctdb getdbmap | 
grep persistent_test.tdb | sed -e "s/.*path://" -e "s/ .*//"`
+    try_command_on_node -q $PNN $CTDB_TEST_WRAPPER ctdb tstore $TDB 
0x5f5f64625f73657175656e63655f6e756d6265725f5f00 
0x0700000000000000000000000000000000000000000000000500000000000000
+done
+
+
+# add one record to node 0   key==ABC  data==ABC
+TDB=`try_command_on_node -v -q 0 $CTDB_TEST_WRAPPER ctdb getdbmap | grep 
persistent_test.tdb | sed -e "s/.*path://" -e "s/ .*//"`
+echo "store key(ABC) data(ABC) on node 0"
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb tstore $TDB 0x414243 
0x070000000000000000000000000000000000000000000000414243
+echo "add __db_sequence_number__==7 record to node 0"
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb tstore $TDB 
0x5f5f64625f73657175656e63655f6e756d6265725f5f00 
0x0700000000000000000000000000000000000000000000000700000000000000
+
+# add one record to node 1   key==DEF  data==DEF
+TDB=`try_command_on_node -v -q 1 $CTDB_TEST_WRAPPER ctdb getdbmap | grep 
persistent_test.tdb | sed -e "s/.*path://" -e "s/ .*//"`
+echo "store key(DEF) data(DEF) on node 1"
+try_command_on_node -q 1 $CTDB_TEST_WRAPPER ctdb tstore $TDB 0x444546 
0x070000000000000000000000000000000000000000000000444546
+echo "add __db_sequence_number__==8 record to node 1"
+try_command_on_node -q 1 $CTDB_TEST_WRAPPER ctdb tstore $TDB 
0x5f5f64625f73657175656e63655f6e756d6265725f5f00 
0x0700000000000000000000000000000000000000000000000800000000000000
+
+# force a recovery
+echo force a recovery
+try_command_on_node -q 0 $CTDB_TEST_WRAPPER ctdb recover
+
+# check that we now have both records on node 0
+num_records=$(try_command_on_node -v -pq 0 $CTDB_TEST_WRAPPER ctdb cattdb 
persistent_test.tdb | grep key | egrep "ABC|DEF" | wc -l)
+[ $num_records != "1" ] && {
+    echo "BAD: we did not end up with the expected single record after the 
recovery"
+    exit 1
+}
+
+echo "OK. databases were not blended"
+
+
+
+# set RecoverPDBBySeqNum=1
+echo "setting RecoverPDBBySeqNum back to 0"
+try_command_on_node -q all $CTDB_TEST_WRAPPER ctdb setvar RecoverPDBBySeqNum 0
diff --git a/tools/ctdb.c b/tools/ctdb.c
index 8ef869b..e852ca2 100644
--- a/tools/ctdb.c
+++ b/tools/ctdb.c
@@ -3487,23 +3487,24 @@ static int control_tfetch(struct ctdb_context *ctdb, 
int argc, const char **argv
 
        tdb = tdb_open(tdb_file, 0, 0, O_RDONLY, 0);
        if (tdb == NULL) {
-               fprintf(stderr, "Failed to open TDB file %s\n", tdb_file);
+               printf("Failed to open TDB file %s\n", tdb_file);
                return -1;
        }
 
        if (!strncmp(argv[1], "0x", 2)) {
                key = hextodata(tmp_ctx, argv[1] + 2);
                if (key.dsize == 0) {
-                       fprintf(stderr, "Failed to convert \"%s\" into a 
TDB_DATA\n", argv[1]);
+                       printf("Failed to convert \"%s\" into a TDB_DATA\n", 
argv[1]);
                        return -1;
                }
        } else {
                key.dptr  = discard_const(argv[1]);
                key.dsize = strlen(argv[1]);
        }
+
        data = tdb_fetch(tdb, key);
        if (data.dptr == NULL || data.dsize < sizeof(struct ctdb_ltdb_header)) {
-               fprintf(stderr, "Failed to read record %s from tdb %s\n", 
argv[1], tdb_file);
+               printf("Failed to read record %s from tdb %s\n", argv[1], 
tdb_file);
                tdb_close(tdb);
                return -1;
        }
@@ -3516,10 +3517,18 @@ static int control_tfetch(struct ctdb_context *ctdb, 
int argc, const char **argv
                        printf("Failed to open output file %s\n", argv[2]);
                        return -1;
                }
-               write(fd, data.dptr+sizeof(struct ctdb_ltdb_header), 
data.dsize-sizeof(struct ctdb_ltdb_header));
+               if (options.verbose){
+                       write(fd, data.dptr, data.dsize);
+               } else {
+                       write(fd, data.dptr+sizeof(struct ctdb_ltdb_header), 
data.dsize-sizeof(struct ctdb_ltdb_header));
+               }
                close(fd);
        } else {
-               write(1, data.dptr+sizeof(struct ctdb_ltdb_header), 
data.dsize-sizeof(struct ctdb_ltdb_header));
+               if (options.verbose){
+                       write(1, data.dptr, data.dsize);
+               } else {
+                       write(1, data.dptr+sizeof(struct ctdb_ltdb_header), 
data.dsize-sizeof(struct ctdb_ltdb_header));
+               }
        }
 
        talloc_free(tmp_ctx);
@@ -3527,6 +3536,66 @@ static int control_tfetch(struct ctdb_context *ctdb, int 
argc, const char **argv
 }
 
 /*
+  store a record and header to a tdb-file
+ */
+static int control_tstore(struct ctdb_context *ctdb, int argc, const char 
**argv)
+{
+       const char *tdb_file;
+       TDB_CONTEXT *tdb;
+       TDB_DATA key, data;
+       TALLOC_CTX *tmp_ctx = talloc_new(NULL);
+
+       if (argc < 3) {
+               usage();
+       }
+
+       tdb_file = argv[0];
+
+       tdb = tdb_open(tdb_file, 0, 0, O_RDWR, 0);
+       if (tdb == NULL) {
+               printf("Failed to open TDB file %s\n", tdb_file);
+               return -1;
+       }
+
+       if (!strncmp(argv[1], "0x", 2)) {
+               key = hextodata(tmp_ctx, argv[1] + 2);
+               if (key.dsize == 0) {
+                       printf("Failed to convert \"%s\" into a TDB_DATA\n", 
argv[1]);
+                       return -1;
+               }
+       } else {
+               key.dptr  = discard_const(argv[1]);
+               key.dsize = strlen(argv[1]);
+       }
+
+       if (!strncmp(argv[2], "0x", 2)) {
+               data = hextodata(tmp_ctx, argv[2] + 2);
+               if (data.dsize == 0) {
+                       printf("Failed to convert \"%s\" into a TDB_DATA\n", 
argv[2]);
+                       return -1;
+               }
+       } else {
+               data.dptr  = discard_const(argv[2]);
+               data.dsize = strlen(argv[2]);
+       }
+
+       if (data.dsize < sizeof(struct ctdb_ltdb_header)) {
+               printf("Not enough data. You must specify the full 
ctdb_ltdb_header too when storing\n");
+               return -1;
+       }
+       if (tdb_store(tdb, key, data, TDB_REPLACE) != 0) {
+               printf("Failed to write record %s to tdb %s\n", argv[1], 
tdb_file);
+               tdb_close(tdb);
+               return -1;
+       }
+
+       tdb_close(tdb);
+
+       talloc_free(tmp_ctx);
+       return 0;
+}
+
+/*
   write a record to a persistent database
  */
 static int control_pstore(struct ctdb_context *ctdb, int argc, const char 
**argv)
@@ -5356,7 +5425,8 @@ static const struct {
        { "sync",            control_ipreallocate,      false,  false,  "wait 
until ctdbd has synced all state changes" },
        { "pfetch",          control_pfetch,            false,  false,  "fetch 
a record from a persistent database", "<db> <key> [<file>]" },
        { "pstore",          control_pstore,            false,  false,  "write 
a record to a persistent database", "<db> <key> <file containing record>" },
-       { "tfetch",          control_tfetch,            false,  true,  "fetch a 
record from a [c]tdb-file", "<tdb-file> <key> [<file>]" },
+       { "tfetch",          control_tfetch,            false,  true,  "fetch a 
record from a [c]tdb-file [-v]", "<tdb-file> <key> [<file>]" },
+       { "tstore",          control_tstore,            false,  true,  "store a 
record (including ltdb header)", "<tdb-file> <key> <data+header>" },
        { "readkey",         control_readkey,           true,   false,  "read 
the content off a database key", "<tdb-file> <key>" },
        { "writekey",        control_writekey,          true,   false,  "write 
to a database key", "<tdb-file> <key> <value>" },
        { "checktcpport",    control_chktcpport,        false,  true,  "check 
if a service is bound to a specific tcp port or not", "<port>" },
@@ -5543,4 +5613,5 @@ int main(int argc, const char *argv[])
        (void)poptFreeContext(pc);
 
        return ret;
+
 }


-- 
CTDB repository

Reply via email to