From 6912b10aedebceec1d36182602257703002fec32 Mon Sep 17 00:00:00 2001 From: John Sully Date: Sat, 11 Jul 2020 04:23:35 +0000 Subject: [PATCH 1/5] Eliminate eviction loops. And don't OOM so often with storage providers set Former-commit-id: 6e61cd33b4366f008b07aae88f49fd0ac9cbcaec --- src/evict.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/evict.cpp b/src/evict.cpp index a6dfd9ba9..6965748c5 100644 --- a/src/evict.cpp +++ b/src/evict.cpp @@ -496,6 +496,7 @@ int freeMemoryIfNeeded(bool fPreSnapshot) { int slaves = listLength(g_pserver->slaves); const bool fEvictToStorage = !cserver.delete_on_evict && g_pserver->db[0]->FStorageProvider(); int result = C_ERR; + int ckeysFailed = 0; /* When clients are paused the dataset should be static not just from the * POV of clients not being able to write, but also from the POV of @@ -618,8 +619,16 @@ int freeMemoryIfNeeded(bool fPreSnapshot) { { // This key is in the storage so we only need to free the object delta = (long long) zmalloc_used_memory(); - db->removeCachedValue(bestkey); - delta -= (long long) zmalloc_used_memory(); + if (db->removeCachedValue(bestkey)) { + delta -= (long long) zmalloc_used_memory(); + ckeysFailed = 0; + } + else { + delta = 0; + ckeysFailed++; + if (ckeysFailed > 1024) + goto cant_free; + } mem_freed += delta; } else @@ -678,6 +687,13 @@ int freeMemoryIfNeeded(bool fPreSnapshot) { result = C_OK; cant_free: + if (g_pserver->m_pstorageFactory) + { + if (mem_reported < g_pserver->maxmemory*1.2) { + return C_OK; // Allow us to temporarily go over without OOMing + } + } + if (!cserver.delete_on_evict && result != C_OK) { for (int idb = 0; idb < cserver.dbnum; ++idb) From 4b58160c61c417f3f4828bc009addda18ae10845 Mon Sep 17 00:00:00 2001 From: John Sully Date: Sat, 11 Jul 2020 21:38:17 +0000 Subject: [PATCH 2/5] Support missing Redis 6 config options Former-commit-id: d467701c6cd8ebe2937c6fda816a706a6b17182a --- src/config.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/config.cpp b/src/config.cpp index 3dc81dc5e..64fda91b6 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -578,7 +578,7 @@ void loadServerConfigFromString(char *config) { err = "KeyDB not compliled with scratch-file support."; goto loaderr; #endif - } else if (!strcasecmp(argv[0],"server-threads") && argc == 2) { + } else if ((!strcasecmp(argv[0],"server-threads") || !strcasecmp(argv[0],"io-threads")) && argc == 2) { cserver.cthreads = atoi(argv[1]); if (cserver.cthreads <= 0 || cserver.cthreads > MAX_EVENT_LOOPS) { err = "Invalid number of threads specified"; @@ -2256,6 +2256,7 @@ static int updateTlsCfgBool(int val, int prev, const char **err) { } #endif /* USE_OPENSSL */ +int fDummy = false; standardConfig configs[] = { /* Bool configs */ createBoolConfig("rdbchecksum", NULL, IMMUTABLE_CONFIG, g_pserver->rdb_checksum, 1, NULL, NULL), @@ -2271,6 +2272,7 @@ standardConfig configs[] = { createBoolConfig("lazyfree-lazy-eviction", NULL, MODIFIABLE_CONFIG, g_pserver->lazyfree_lazy_eviction, 0, NULL, NULL), createBoolConfig("lazyfree-lazy-expire", NULL, MODIFIABLE_CONFIG, g_pserver->lazyfree_lazy_expire, 0, NULL, NULL), createBoolConfig("lazyfree-lazy-server-del", NULL, MODIFIABLE_CONFIG, g_pserver->lazyfree_lazy_server_del, 0, NULL, NULL), + createBoolConfig("lazyfree-lazy-user-del", NULL, MODIFIABLE_CONFIG, g_pserver->lazyfree_lazy_user_del , 0, NULL, NULL), createBoolConfig("repl-disable-tcp-nodelay", NULL, MODIFIABLE_CONFIG, g_pserver->repl_disable_tcp_nodelay, 0, NULL, NULL), createBoolConfig("repl-diskless-sync", NULL, MODIFIABLE_CONFIG, g_pserver->repl_diskless_sync, 0, NULL, NULL), createBoolConfig("aof-rewrite-incremental-fsync", NULL, MODIFIABLE_CONFIG, g_pserver->aof_rewrite_incremental_fsync, 1, NULL, NULL), @@ -2292,6 +2294,7 @@ standardConfig configs[] = { createBoolConfig("appendonly", NULL, MODIFIABLE_CONFIG, g_pserver->aof_enabled, 0, NULL, updateAppendonly), createBoolConfig("cluster-allow-reads-when-down", NULL, MODIFIABLE_CONFIG, g_pserver->cluster_allow_reads_when_down, 0, NULL, NULL), createBoolConfig("delete-on-evict", NULL, MODIFIABLE_CONFIG, cserver.delete_on_evict, 0, NULL, NULL), + createBoolConfig("io-threads-do-reads", NULL, IMMUTABLE_CONFIG, fDummy, 0,NULL, NULL), // Not applicable to KeyDB, just there for compatibility /* String Configs */ createStringConfig("aclfile", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, g_pserver->acl_filename, "", NULL, NULL), From 06a8e2aa2ad73905dd278f042e06541dde022638 Mon Sep 17 00:00:00 2001 From: John Sully Date: Sat, 11 Jul 2020 22:09:27 +0000 Subject: [PATCH 3/5] Fix failure to replicate with non-pro server when license key is set Former-commit-id: a69beef7d92223c8dcebb9c39ca2409183571e57 --- src/replication.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/replication.cpp b/src/replication.cpp index 7ead1e7d7..477fe6e10 100644 --- a/src/replication.cpp +++ b/src/replication.cpp @@ -2720,9 +2720,17 @@ void syncWithMaster(connection *conn) { { err = sendSynchronousCommand(mi, SYNC_CMD_READ,conn,NULL); if (err[0] == '-') { - serverLog(LL_WARNING, "Recieved error from client: %s", err); - sdsfree(err); - goto error; + if (err[1] == 'E' && err[2] == 'R' && err[3] == 'R') { + // Replicating with non-pro + serverLog(LL_WARNING, "Replicating with non-pro server."); + mi->repl_state = REPL_STATE_SEND_PORT; + sdsfree(err); + return; + } else { + serverLog(LL_WARNING, "Recieved error from client: %s", err); + sdsfree(err); + goto error; + } } sdsfree(err); mi->repl_state = REPL_STATE_SEND_PORT; From 074cb1edc125e37a8ef3268b6be9b2df5357d366 Mon Sep 17 00:00:00 2001 From: John Sully Date: Sat, 11 Jul 2020 22:13:07 +0000 Subject: [PATCH 4/5] Sentinel doesn't need a license key Former-commit-id: bc2d8c18255214b873bf45d8db8af3727ebc4723 --- src/server.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/server.cpp b/src/server.cpp index 4a1b1ff72..e3704870d 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1126,6 +1126,8 @@ void serverLog(int level, const char *fmt, ...) { static void checkTrialTimeout() { #ifndef NO_LICENSE_CHECK + if (g_pserver->sentinel_mode) + return; // sentinel is not licensed if (cserver.license_key != nullptr && FValidKey(cserver.license_key, strlen(cserver.license_key))) return; time_t curtime = time(NULL); @@ -5251,7 +5253,7 @@ void redisAsciiArt(void) { serverLogRaw(LL_NOTICE|LL_RAW,buf); } - if (cserver.license_key == nullptr) + if (cserver.license_key == nullptr && !g_pserver->sentinel_mode) { #ifndef NO_LICENSE_CHECK serverLog(LL_WARNING, "!!!! KeyDB Pro is being run in trial mode !!!!"); From ead6e22865c23034054af26bfffbf24651ba95dc Mon Sep 17 00:00:00 2001 From: John Sully Date: Sat, 11 Jul 2020 22:21:12 +0000 Subject: [PATCH 5/5] Add KeyDB Pro info section Former-commit-id: d73015fae36ece6db7b088cc55843385688b1866 --- src/server.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/server.cpp b/src/server.cpp index e3704870d..4fae6e2af 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -5095,6 +5095,16 @@ sds genRedisInfoString(const char *section) { } } + if (allsections || defsections || !strcasecmp(section,"keydb")) { + if (sections++) info = sdscat(info,"\r\n"); + info = sdscatprintf(info, + "# KeyDB\r\n" + "variant:pro\r\n" + "license_status:%s\r\n", + cserver.license_key ? "OK" : "Trial" + ); + } + /* Get info from modules. * if user asked for "everything" or "modules", or a specific section * that's not found yet. */