From a3e53cf9bcf05671e3ac4a170bb6791dbff62eec Mon Sep 17 00:00:00 2001
From: Zachary Marquez <zachary.marquez@mediafire.com>
Date: Thu, 1 Jun 2017 16:24:10 -0500
Subject: [PATCH] Prevent expirations and evictions while paused

Proposed fix to https://github.com/antirez/redis/issues/4027
---
 src/evict.c  | 6 ++++++
 src/expire.c | 4 ++++
 2 files changed, 10 insertions(+)

diff --git a/src/evict.c b/src/evict.c
index bf5bea6b0..77f63cba5 100644
--- a/src/evict.c
+++ b/src/evict.c
@@ -380,6 +380,12 @@ int freeMemoryIfNeeded(void) {
     long long delta;
     int slaves = listLength(server.slaves);
 
+    /* We cannot free memory while clients are paused as this will require
+     * evictions which modify the dataset and will break the guarantee that
+     * data will be static while clients are paused. */
+    if (clientsArePaused())
+        goto cant_free;
+
     /* Check if we are over the memory usage limit. If we are not, no need
      * to subtract the slaves output buffers. We can just return ASAP. */
     mem_reported = zmalloc_used_memory();
diff --git a/src/expire.c b/src/expire.c
index 22b1f1da9..0e258ecbb 100644
--- a/src/expire.c
+++ b/src/expire.c
@@ -105,6 +105,10 @@ void activeExpireCycle(int type) {
     int dbs_per_call = CRON_DBS_PER_CALL;
     long long start = ustime(), timelimit;
 
+    /* We cannot expire keys while clients are paused as the dataset is
+     * supposed to be static. */
+    if (clientsArePaused()) return;
+
     if (type == ACTIVE_EXPIRE_CYCLE_FAST) {
         /* Don't start a fast cycle if the previous cycle did not exited
          * for time limt. Also don't repeat a fast cycle for the same period