MB-23664: Use max possible limit for Ephemeral backfill memory mgmt 94/76294/4
authorManu Dhundi <manu@couchbase.com>
Wed, 5 Apr 2017 17:16:51 +0000 (10:16 -0700)
committerManu Dhundi <manu@couchbase.com>
Wed, 5 Apr 2017 21:04:26 +0000 (21:04 +0000)
In-memory backfilling is currently not memory managed. Therefore set the
scan buffer (per backfill buffer for managing backfill memory usage)
byte limit, item limit to max. Also, for the same reason as above set
the overall DCP backfill limit to max.

Unlike disk backfills, where there is luxury of surplus disk memory,
we cannot retain in-memory snapshots for long in case of a memory
pressure during backfill. This is because the snapshots themselves
use memory.

Memory management can be done, but will be considered in a future
task (MB-23734).

Change-Id: I796d1b055b6948ba8bfde01556db8c16e3e16622
Reviewed-on: http://review.couchbase.org/76294
Tested-by: Build Bot <build@couchbase.com>
Reviewed-by: Premkumar <premkumar.thangamani@couchbase.com>
src/dcp/backfill-manager.h
src/ephemeral_bucket.cc
src/linked_list.cc
tests/ep_testsuite_dcp.cc

index c82a266..f999f1b 100644 (file)
@@ -93,17 +93,17 @@ private:
 
     //! The scan buffer is for the current stream being backfilled
     struct {
-        uint32_t bytesRead;
-        uint32_t itemsRead;
-        uint32_t maxBytes;
-        uint32_t maxItems;
+        size_t bytesRead;
+        size_t itemsRead;
+        size_t maxBytes;
+        size_t maxItems;
     } scanBuffer;
 
     //! The buffer is the total bytes used by all backfills for this connection
     struct {
-        uint32_t bytesRead;
-        uint32_t maxBytes;
-        uint32_t nextReadSize;
+        size_t bytesRead;
+        size_t maxBytes;
+        size_t nextReadSize;
         bool full;
     } buffer;
 };
index 34c619e..c93a30a 100644 (file)
@@ -141,6 +141,17 @@ void EphemeralBucket::reconfigureForEphemeral(Configuration& config) {
     config.setWarmup(false);
     // Disable TAP - not supported for Ephemeral.
     config.setTap(false);
+
+    // In-memory backfilling is currently not memory managed. Therefore set the
+    // scan buffer (per backfill buffer for managing backfill memory usage)
+    // byte limit, item limit to max. Otherwise, this may result in incomplete
+    // DCP backfills which may inturn cause hang or data loss in DCP clients
+    // like rebalance, xdcr etc.
+    config.setDcpScanByteLimit(std::numeric_limits<size_t>::max());
+    config.setDcpScanItemLimit(std::numeric_limits<size_t>::max());
+
+    // for the same reason as above set overall DCP backfill limit to max
+    config.setDcpBackfillByteLimit(std::numeric_limits<size_t>::max());
 }
 
 size_t EphemeralBucket::getNumPersistedDeletes(uint16_t vbid) {
index 67a08d0..bb2a827 100644 (file)
@@ -138,6 +138,10 @@ BasicLinkedList::rangeRead(seqno_t start, seqno_t end) {
         try {
             items.push_back(UniqueItemPtr(osv.toItem(false, vbid)));
         } catch (const std::bad_alloc&) {
+            /* [EPHE TODO]: Do we handle backfill in a better way ?
+                            Perhaps do backfilling partially (that is
+                            backfill ==> stream; backfill ==> stream ..so on )?
+             */
             LOG(EXTENSION_LOG_WARNING,
                 "BasicLinkedList::rangeRead(): "
                 "(vb %d) ENOMEM while trying to copy "
index faae2f5..eb2f105 100644 (file)
@@ -5858,7 +5858,8 @@ BaseTestCase testsuite_testcases[] = {
                  cleanup),
         TestCase("test producer stream request (backfill)",
                  test_dcp_producer_stream_req_backfill, test_setup, teardown,
-                 "chk_remover_stime=1;chk_max_items=100", prepare,
+                 "chk_remover_stime=1;chk_max_items=100;dcp_scan_item_limit=50",
+                 prepare,
                  cleanup),
         TestCase("test producer stream request (disk only)",
                  test_dcp_producer_stream_req_diskonly, test_setup, teardown,