diff --git a/src/rdb.cpp b/src/rdb.cpp index 0f7b2f51e..3a4d4be74 100644 --- a/src/rdb.cpp +++ b/src/rdb.cpp @@ -1101,8 +1101,8 @@ int rdbSaveKeyValuePair(rio *rdb, robj_roptr key, robj_roptr val, const expireEn if (rdbSaveObject(rdb,val,key) == -1) return -1; /* Delay return if required (for testing) */ - if (g_pserver->rdb_key_save_delay) - usleep(g_pserver->rdb_key_save_delay); + if (serverTL->getRdbKeySaveDelay()) + usleep(serverTL->getRdbKeySaveDelay()); /* Save expire entry after as it will apply to the previously loaded key */ /* This is because we update the expire datastructure directly without buffering */ diff --git a/src/replication.cpp b/src/replication.cpp index a6f28bac9..21768a89a 100644 --- a/src/replication.cpp +++ b/src/replication.cpp @@ -2068,15 +2068,14 @@ void readSyncBulkPayload(connection *conn) { "from socket"); cancelReplicationHandshake(mi); rioFreeConn(&rdb, NULL); - if (!fUpdate) { - if (g_pserver->repl_diskless_load == REPL_DISKLESS_LOAD_SWAPDB) { - /* Restore the backed up databases. */ - disklessLoadRestoreBackups(diskless_load_backup,1); - } else { - /* Remove the half-loaded data in case we started with - * an empty replica. */ - emptyDb(-1,empty_db_flags,replicationEmptyDbCallback); - } + if (g_pserver->repl_diskless_load == REPL_DISKLESS_LOAD_SWAPDB) { + /* Restore the backed up databases. */ + disklessLoadRestoreBackups(diskless_load_backup,1); + } + else if (!fUpdate) { + /* Remove the half-loaded data in case we started with + * an empty replica. */ + emptyDb(-1,empty_db_flags,replicationEmptyDbCallback); } /* Note that there's no point in restarting the AOF on SYNC @@ -2086,14 +2085,12 @@ void readSyncBulkPayload(connection *conn) { } stopLoading(1); - if (!fUpdate) { - /* RDB loading succeeded if we reach this point. */ - if (g_pserver->repl_diskless_load == REPL_DISKLESS_LOAD_SWAPDB) { - /* Delete the backup databases we created before starting to load - * the new RDB. Now the RDB was loaded with success so the old - * data is useless. */ - disklessLoadRestoreBackups(diskless_load_backup,0); - } + /* RDB loading succeeded if we reach this point. */ + if (g_pserver->repl_diskless_load == REPL_DISKLESS_LOAD_SWAPDB) { + /* Delete the backup databases we created before starting to load + * the new RDB. Now the RDB was loaded with success so the old + * data is useless. */ + disklessLoadRestoreBackups(diskless_load_backup,0); } /* Verify the end mark is correct. */ diff --git a/src/server.cpp b/src/server.cpp index 5c53d7157..15f5729d1 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -4085,7 +4085,7 @@ int processCommand(client *c, int callFlags, AeLocker &locker) { queueMultiCommand(c); addReply(c,shared.queued); } else { - if (cserver.cthreads >= 2 && g_pserver->m_pstorageFactory == nullptr && listLength(g_pserver->monitors) == 0 && c->cmd->proc == getCommand) + if (cserver.cthreads >= 2 && !g_fTestMode && g_pserver->m_pstorageFactory == nullptr && listLength(g_pserver->monitors) == 0 && c->cmd->proc == getCommand) { if (getCommandAsync(c)) return C_OK; diff --git a/src/server.h b/src/server.h index d29d77e00..99167d040 100644 --- a/src/server.h +++ b/src/server.h @@ -111,6 +111,7 @@ typedef long long ustime_t; /* microsecond time type. */ #define FImplies(x, y) (!(x) || (y)) extern int g_fTestMode; +extern struct redisServer *g_pserver; struct redisObject; class robj_roptr @@ -1936,6 +1937,10 @@ struct redisServerThreadVars { uint64_t gcEpoch = 0; const redisDbPersistentDataSnapshot **rgdbSnapshot = nullptr; bool fRetrySetAofEvent = false; + + int getRdbKeySaveDelay(); +private: + int rdb_key_save_delay = -1; // thread local cache }; struct redisMaster { @@ -2400,6 +2405,15 @@ struct redisServer { bool FRdbSaveInProgress() const { return rdbThreadVars.fRdbThreadActive; } }; +inline int redisServerThreadVars::getRdbKeySaveDelay() { + if (rdb_key_save_delay < 0) { + aeAcquireLock(); + rdb_key_save_delay = g_pserver->rdb_key_save_delay; + aeReleaseLock(); + } + return rdb_key_save_delay; +} + typedef struct pubsubPattern { client *pclient; robj *pattern; @@ -2492,7 +2506,6 @@ typedef struct { *----------------------------------------------------------------------------*/ //extern struct redisServer server; -extern redisServer *g_pserver; extern struct redisServerConst cserver; extern thread_local struct redisServerThreadVars *serverTL; // thread local server vars extern struct sharedObjectsStruct shared;