MB-19635: Initialise failovers correctly from 2.5.x vbstate 55/64155/2
authorJim Walker <jim@couchbase.com>
Tue, 17 May 2016 16:41:10 +0000 (17:41 +0100)
committerDave Rigby <daver@couchbase.com>
Wed, 18 May 2016 11:14:16 +0000 (11:14 +0000)
When loading a vb file, don't force the failover table data
to be ("[{\"id\":0,\"seq\":0}]"); if the file doesn't contain
any data.

Change-Id: I41673bf848fcbab9b616edec5c7fd2ab9a3ddd6b
Reviewed-on: http://review.couchbase.org/64155
Well-Formed: buildbot <build@couchbase.com>
Tested-by: buildbot <build@couchbase.com>
Reviewed-by: Dave Rigby <daver@couchbase.com>
CMakeLists.txt
src/couch-kvstore/couch-kvstore.cc
tests/ep_testsuite.cc

index 9735d0e..c57f3d0 100644 (file)
@@ -372,7 +372,8 @@ ADD_LIBRARY(ep_testsuite SHARED
    tests/mock/mock_dcp.cc
    tests/ep_test_apis.cc ${OBJECTREGISTRY_SOURCE} ${CONFIG_SOURCE})
 SET_TARGET_PROPERTIES(ep_testsuite PROPERTIES PREFIX "")
-TARGET_LINK_LIBRARIES(ep_testsuite JSON_checker dirutils platform ${LIBEVENT_LIBRARIES} ${SNAPPY_LIBRARIES})
+TARGET_LINK_LIBRARIES(ep_testsuite couchstore dirutils JSON_checker platform
+                      ${LIBEVENT_LIBRARIES} ${SNAPPY_LIBRARIES})
 
 
 #ADD_CUSTOM_COMMAND(OUTPUT
index 8345138..5c84ae1 100644 (file)
@@ -1971,7 +1971,7 @@ void CouchKVStore::readVBState(Db *db, uint16_t vbId) {
     uint64_t checkpointId = 0;
     uint64_t maxDeletedSeqno = 0;
     int64_t highSeqno = 0;
-    std::string failovers("[{\"id\":0,\"seq\":0}]");
+    std::string failovers;
     uint64_t purgeSeqno = 0;
     uint64_t lastSnapStart = 0;
     uint64_t lastSnapEnd = 0;
index 4b05392..bff29f6 100644 (file)
@@ -48,6 +48,7 @@
 #include "ep_test_apis.h"
 #include "ep_testsuite.h"
 #include "locks.h"
+#include <libcouchstore/couch_db.h>
 #include "mock/mock_dcp.h"
 #include "mutex.h"
 
@@ -14185,6 +14186,57 @@ static enum test_result test_mb17517_tap_with_locked_key(ENGINE_HANDLE *h,
     return SUCCESS;
 }
 
+static void force_vbstate_to_25x(std::string dbname, int vbucket) {
+    std::string filename = dbname +
+                           DIRECTORY_SEPARATOR_CHARACTER +
+                           std::to_string(vbucket) +
+                           ".couch.1";
+    Db* handle;
+    couchstore_error_t err = couchstore_open_db(filename.c_str(),
+                                                COUCHSTORE_OPEN_FLAG_CREATE,
+                                                &handle);
+
+    checkeq(COUCHSTORE_SUCCESS, err, "Failed to open new database");
+
+    // Create 2.5 _local/vbstate
+    std::string vbstate2_5_x ="{\"state\": \"active\","
+                              " \"checkpoint_id\": \"1\","
+                              " \"max_deleted_seqno\": \"0\"}";
+    LocalDoc vbstate;
+    vbstate.id.buf = (char *)"_local/vbstate";
+    vbstate.id.size = sizeof("_local/vbstate") - 1;
+    vbstate.json.buf = (char *)vbstate2_5_x.c_str();
+    vbstate.json.size = vbstate2_5_x.size();
+    vbstate.deleted = 0;
+
+    err = couchstore_save_local_document(handle, &vbstate);
+    checkeq(COUCHSTORE_SUCCESS, err, "Failed to write local document");
+    couchstore_commit(handle);
+    couchstore_close_db(handle);
+}
+
+// Regression test for MB-19635
+// Check that warming up from a 2.x couchfile doesn't end up with a UUID of 0
+// we warmup 2 vbuckets and ensure they get unique IDs.
+static enum test_result test_mb19635_upgrade_from_25x(ENGINE_HANDLE *h,
+                                                      ENGINE_HANDLE_V1 *h1) {
+    std::string dbname = dbname_env;
+
+    force_vbstate_to_25x(dbname, 0);
+    force_vbstate_to_25x(dbname, 1);
+
+    // Now shutdown engine force and restart to warmup from the 2.5.x data.
+    testHarness.reload_engine(&h, &h1,
+                              testHarness.engine_path,
+                              testHarness.get_current_testcase()->cfg,
+                              true, false);
+    wait_for_warmup_complete(h, h1);
+    uint64_t vb_uuid0 = get_ull_stat(h, h1, "vb_0:uuid", "vbucket-details");
+    uint64_t vb_uuid1 = get_ull_stat(h, h1, "vb_1:uuid", "vbucket-details");
+    checkne(vb_uuid0, vb_uuid1, "UUID is not unique");
+    return SUCCESS;
+}
+
 static enum test_result prepare(engine_test_t *test) {
 #ifdef __sun
         // Some of the tests doesn't work on Solaris.. Don't know why yet..
@@ -15237,6 +15289,11 @@ engine_test_t* get_tests(void) {
                  test_mb17517_tap_with_locked_key, test_setup, teardown, NULL,
                  prepare, cleanup),
 
+         TestCase("test_mb19635_upgrade_from_25x",
+                 test_mb19635_upgrade_from_25x, test_setup, teardown, NULL,
+                 prepare, cleanup),
+
+
         TestCase(NULL, NULL, NULL, NULL, NULL, prepare, cleanup)
     };