MB-20105: Ensure purge_seq is not reset when no items are purged in a compaction 26/65626/5 v3.1.6
authorManu Dhundi <manu@couchbase.com>
Mon, 11 Jul 2016 21:38:15 +0000 (14:38 -0700)
committerManu Dhundi <manu@couchbase.com>
Mon, 11 Jul 2016 21:56:11 +0000 (21:56 +0000)
When a compaction request is made, we initially set the purge_seqno in the req
to 0, hoping to update it when we purge items. However, if there are no purged
items in a compaction call, then we end up reseting the purge_seqno
(correct one) set by the previous compaction call.

This commit addresses the problem by setting the purge seqno in the request
to current purge seqno in the ep-engine.

Change-Id: I9581abe7a4cb9d7cd84c1bf5563b98c91dc67525
Reviewed-on: http://review.couchbase.org/65626
Well-Formed: buildbot <build@couchbase.com>
Tested-by: buildbot <build@couchbase.com>
Reviewed-by: Dave Rigby <daver@couchbase.com>
src/ep.cc
tests/ep_testsuite.cc

index 11e6e8f..dc6e304 100644 (file)
--- a/src/ep.cc
+++ b/src/ep.cc
@@ -1221,6 +1221,9 @@ ENGINE_ERROR_CODE EventuallyPersistentStore::compactDB(uint16_t vbid,
         return ENGINE_NOT_MY_VBUCKET;
     }
 
+    /* Update the compaction ctx with the previous purge seqno */
+    c.max_purged_seq = vb->getPurgeSeqno();
+
     LockHolder lh(compactionLock);
     ExTask task = new CompactVBucketTask(&engine, Priority::CompactorPriority,
                                          vbid, c, cookie);
index 6e44285..50a77db 100644 (file)
@@ -2694,6 +2694,65 @@ static enum test_result test_vbucket_compact(ENGINE_HANDLE *h,
     return SUCCESS;
 }
 
+/* This test case checks the purge seqno validity when no items are actually
+   purged in a compaction call */
+static enum test_result test_vbucket_compact_no_purge(ENGINE_HANDLE *h,
+                                                      ENGINE_HANDLE_V1 *h1) {
+    const int num_items = 2;
+    const char* key[num_items] = {"k1", "k2"};
+    const char* value = "somevalue";
+
+    /* Write 2 keys */
+    for (int count = 0; count < num_items; count++){
+        checkeq(ENGINE_SUCCESS, store(h, h1, NULL, OPERATION_SET, key[count],
+                                      value, NULL, 0, 0, 0),
+                "Error setting.");
+    }
+
+    /* Delete one key */
+    checkeq(ENGINE_SUCCESS, del(h, h1, key[0], 0, 0),
+            "Failed remove with value.");
+
+    /* Store a dummy item since we do not purge the item with highest seqno */
+    checkeq(ENGINE_SUCCESS,
+            store(h, h1, NULL, OPERATION_SET, "dummy_key", value, NULL,
+                  0, 0, 0),
+            "Error setting.");
+    wait_for_flusher_to_settle(h, h1);
+
+    /* Compact once */
+    int exp_purge_seqno = get_int_stat(h, h1, "vb_0:high_seqno",
+                                       "vbucket-seqno") - 1;
+    compact_db(h, h1, 0, 2,
+               get_int_stat(h, h1, "vb_0:high_seqno", "vbucket-seqno"), 1);
+    wait_for_stat_to_be(h, h1, "ep_pending_compactions", 0);
+    checkeq(exp_purge_seqno,
+            get_int_stat(h, h1, "vb_0:purge_seqno", "vbucket-seqno"),
+            "purge_seqno didn't match expected value");
+
+    /* Compact again, this time we don't expect to purge any items */
+    compact_db(h, h1, 0, 2,
+               get_int_stat(h, h1, "vb_0:high_seqno", "vbucket-seqno"), 1);
+    wait_for_stat_to_be(h, h1, "ep_pending_compactions", 0);
+    checkeq(exp_purge_seqno,
+            get_int_stat(h, h1, "vb_0:purge_seqno", "vbucket-seqno"),
+            "purge_seqno didn't match expected value after another compaction");
+
+    /* Reload the engine */
+    testHarness.reload_engine(&h, &h1,
+                              testHarness.engine_path,
+                              testHarness.get_current_testcase()->cfg,
+                              true, false);
+    wait_for_warmup_complete(h, h1);
+
+    /* Purge seqno should not change after reload */
+    checkeq(exp_purge_seqno,
+            get_int_stat(h, h1, "vb_0:purge_seqno", "vbucket-seqno"),
+            "purge_seqno didn't match expected value after reload");
+
+    return SUCCESS;
+}
+
 static enum test_result test_compaction_config(ENGINE_HANDLE *h,
                                                ENGINE_HANDLE_V1 *h1) {
 
@@ -12599,6 +12658,8 @@ engine_test_t* get_tests(void) {
                  test_setup, teardown, NULL, prepare, cleanup),
         TestCase("test vbucket compact", test_vbucket_compact,
                  test_setup, teardown, NULL, prepare, cleanup),
+        TestCase("test vbucket compact no purge", test_vbucket_compact_no_purge,
+                 test_setup, teardown, NULL, prepare, cleanup),
         TestCase("test compaction config", test_compaction_config,
                  test_setup, teardown, NULL, prepare, cleanup),
         TestCase("test multiple vb compactions", test_multiple_vb_compactions,