Compare commits

...
71 Commits
Author SHA1 Message Date
Malavan Sotheeswaran 7e7e5e57d2 set version to 6.3.4 2023-10-29 17:44:00 -07:00
Malavan Sotheeswaran de3c218a02 add release notes up to 6.3.4 2023-10-29 17:39:55 -07:00
Malavan Sotheeswaran 05945b60a8 missed a refernce to isRocksdbSnapshotRepl 2023-10-26 11:40:50 -07:00
Malavan Sotheeswaran 486a6bb7b1 Merge remote-tracking branch 'internal/main' 2023-10-26 11:21:46 -07:00
John Sully 70503f6b58 Disable fastsync by default 2023-10-23 15:23:11 -04:00
John Sully 46615ac099 Fix test 2023-10-23 15:23:11 -04:00
John Sully a7ac6c1e43 Remove unused variable 2023-10-23 15:23:11 -04:00
John Sully d7977c468f Fastsync in-mem initial implementation 2023-10-23 15:23:11 -04:00
John Sully 7ae27f61f0 rename constants 2023-10-23 15:23:11 -04:00
Malavan Sotheeswaran 47f635ee16 Fix tls auditlog tests and enable tls for CI (#234)
* fix auditlog test titles, and enable tls tests for CI

* fix tls auditlog key string
2023-10-23 14:34:23 -04:00
Malavan Sotheeswaran 79b0c84710 Fixing some compile issues for alpine and centos, also fix endian issue for FLASH hashslot prefix (#722)
*fix for rocksdb centos compile fail

* fix alpine compile

* fix hashslot enumerate

* update alpine docker to latest version

* fix mac build, use big endian for expire prefix

* use endian.h for expires too
2023-10-13 15:00:35 -04:00
John Sully cd42776c9f Make the connect timeout configurable when in cluster mode to prevent huge delays 2023-10-12 12:11:18 -04:00
Malavan SotheeswaranandJohn Sully dfcc848e1c enable level_compaction_dynamic_level_bytes after flush, and flush expires for FLASH (#229)
* enable level_compaction_dynamic_level_bytes after flush, and flush expires

* update debug reload for flash

* update debug reload for flash complete

* missing forward declare

* commit existing changes then track changes for debug reload

* missing args

* commitChanges is conditional

Co-authored-by: John Sully <jsully@snapchat.com>
2023-09-28 16:59:23 -04:00
John Sully e7f90f0096 Fix bug where we erroneously answer queries belonging to another shard 2023-09-27 07:38:09 +00:00
John Sully 025b7077f7 Fix crossslot error migrating batches of keys 2023-09-26 00:11:21 -04:00
Malavan Sotheeswaran 596c513d3e only use internal locks when multithreaded (#205) 2023-09-25 15:53:47 -04:00
John Sully 570bcb55c7 make async rehash configurable 2023-09-23 16:32:28 -04:00
John Sully 68d751046e async rehash is preventing rehashing during RDB load after a db flush. Ensure it can't interefere after a flush 2023-09-23 16:32:28 -04:00
John Sully cfe257a9c7 Fix logic bug 2023-09-20 12:57:10 -07:00
John Sully c6e20ea396 Fix over pessimistic checks that prevent replicas from serving mget 2023-09-20 12:57:10 -07:00
John Sully 9251f1c244 Permit keys of differing slots as long as they are served by this cluster and we are not migrating 2023-09-14 21:55:04 -04:00
Zhaozhen Liang 7b7c0ba192 Merge pull request #224 from Snapchat/remove-dot-in-nodename-metrics
fix nodename metricsname
2023-09-11 15:37:16 -06:00
zliang 98e306c59b Merge branch 'main' into remove-dot-in-nodename-metrics 2023-09-11 12:18:39 -06:00
Alex Cope a55c687cd0 Emit more aggregate metrics in modstatsd (#223) 2023-09-11 10:43:25 -07:00
Malavan Sotheeswaran ace783a00e Flash expiration (#197)
Design Doc: https://docs.google.com/document/d/1NmnYGnHLdZp-KOUCUatX5iXpF-L3YK4VUc9Lm3Tqxpo/edit?usp=sharing
2023-09-08 16:25:53 -04:00
Malavan Sotheeswaran 7d4f461562 Make propagating before freeing module context optional (#225)
* don't propogate on module context free for rdb load

* default in wrong place
2023-09-08 15:51:48 -04:00
zliang e31533bd7a fix unnecessary replace 2023-08-31 12:45:42 -06:00
zliang c20af57cf1 fix nodename metricsname 2023-08-31 12:29:59 -06:00
John Sully 820482bffe Fix slow to free when low lock contention 2023-08-25 20:40:16 -04:00
John Sully f435218ed9 Fix memory leaks 2023-08-25 16:44:10 +00:00
Alex Cope 8b755aee1b Multiply CPU percent metric by 100 2023-08-22 17:33:57 -04:00
Zhaozhen Liang c97f696ea2 Merge pull request #219 from Snapchat/emit-non-empty-shard-less-replica-issue
add metric emit for non-empty primary with less than 2 connected replicas
2023-08-22 11:34:09 -06:00
zliang cec570fdf1 address comments 2023-08-22 11:10:56 -06:00
zliang 6375e919b9 add metric emit for non-empty primary with less than 2 connected replicas 2023-08-21 18:29:05 -06:00
Zhaozhen Liang bf29926686 Merge pull request #218 from Snapchat/change-memfree-to-memavailable
update MemFree to MemAvailable in keydb statsd
2023-08-21 16:46:38 -06:00
zliang 813bf15ae0 update MemFree to MemAvailable in keydb statsd 2023-08-21 15:28:26 -06:00
John Sully ffac55273a Remove Expireset (#217)
Major refactor to place expiry information directly in the object struct.
2023-08-21 16:36:45 -04:00
Zhaozhen Liang 80dcbad30f Merge pull request #216 from Snapchat/add-free-memory-and-shard-num-metrics-emit-statsd
emit system free memory metrics with '/proc/meminfo'
2023-08-18 10:50:21 -06:00
zliang eb14f4298c have emit system free memory within metrics_time_taken_us and also add metric time taken for it 2023-08-18 10:20:00 -06:00
zliang 6fa696bb98 emit system free metrics with '/proc/meminfo' 2023-08-17 19:31:52 -06:00
Zhaozhen Liang abd6e77c95 Merge pull request #215 from Snapchat/make-docker-build-independent
make docker build independent
2023-08-16 12:24:25 -06:00
zliang 7a00a43170 add new build to ci 2023-08-15 15:52:59 -06:00
zliang 426eabe143 make docker build independent 2023-08-15 15:27:05 -06:00
Zhaozhen Liang 222776e98b Merge pull request #214 from Snapchat/update-docker-build-tag
use commit hash as tag template
2023-08-15 13:13:30 -06:00
zliang 76fec1c22e Revert "test tag"
This reverts commit 9cbc57137d.
2023-08-15 12:40:10 -06:00
zliang 9cbc57137d test tag 2023-08-15 12:25:15 -06:00
zliang 94b40af1c3 fix 2023-08-15 11:56:03 -06:00
zliang df9039d83f use commit hash as tag template 2023-08-15 11:37:29 -06:00
Zhaozhen Liang a1b55eddf8 Merge pull request #211 from Snapchat/machamp-release-publish-image
add docker build
2023-08-15 09:40:43 -06:00
zliang 70f2a74ff1 fix the comment caused stuck docker build 2023-08-14 18:34:05 -06:00
zliang e15a2b609c fix 2023-08-14 17:05:37 -06:00
zliang 7d96689ae6 fix check in Dockerfile docker-entrypoint.sh 2023-08-14 16:31:41 -06:00
Zhaozhen Liang 8cbb53e7cb Merge branch 'main' into machamp-release-publish-image 2023-08-14 12:55:30 -06:00
zliang b6f91e4c26 include building keydb statsd module 2023-08-14 12:03:36 -06:00
Zhaozhen Liang deb48fba62 Merge pull request #213 from Snapchat/move-cpp-statsd-client-to-dep
move cpp-statsd-client to deps
2023-08-14 11:30:40 -06:00
zliang b51f267112 remove submodule instead use the source 2023-08-14 11:13:06 -06:00
zliang a055da3b4c update relative path in compilation 2023-08-14 10:56:51 -06:00
zliang 68ce12ad3a checkout to a06a5b9359f31d946fe163b9038586982971ae49 2023-08-14 10:25:23 -06:00
zliang b8208794a3 move cpp-statsd-client to deps 2023-08-14 10:23:22 -06:00
zliang 12bf6188ae Merge branch 'main' into machamp-release-publish-image 2023-08-11 17:21:51 -06:00
Zhaozhen Liang cb147defbd Merge pull request #212 from Snapchat/migrate-keydb_modstatsd
migrate keydb_modstatsd to keydb-internal
2023-08-11 15:40:41 -06:00
zliang 4d56a1c5ed have clean also trigger keydb_modstatsd clean 2023-08-11 15:19:53 -06:00
zliang 289df10eb1 update 2023-08-11 15:16:10 -06:00
zliang 6e0305828e include trigger keydb_modstatsd Makefile in modules Makefile 2023-08-11 15:14:35 -06:00
zliang 6e1fbb2d14 add submodule cpp-statsd-client 2023-08-11 13:34:23 -06:00
zliang c94560f0ba rm 2023-08-11 13:32:20 -06:00
zliang db3fb7e9fe migrate keydb_modstatsd to keydb-internal 2023-08-11 13:26:28 -06:00
zliang 7a496d3dde address intentation and use default release 2023-08-10 14:08:37 -06:00
zliang 7bce881287 add release publish docker image 2023-08-10 11:29:07 -06:00
zliang 353695887a fix the working dir in Dockerfile 2023-08-09 11:44:33 -06:00
zliang 4fe4b235b2 add docker build 2023-08-08 19:28:44 -06:00
21 changed files with 241 additions and 88 deletions

No files matched your search

+2 -2
View File
@@ -21,13 +21,13 @@ machamp:
parent: make-build
# https://github.sc-corp.net/Snapchat/img/tree/master/keydb/ubuntu-20-04
builder_image: us.gcr.io/snapchat-build-artifacts/prod/snapchat/img/keydb/keydb-ubuntu-20-04@sha256:cf869a3f5d1de1e1d976bb906689c37b7031938eb68661b844a38c532f27248c
command: ./runtest --clients 4 --verbose
command: ./runtest --clients 4 --verbose --tls
cluster-test:
type: cmd
parent: make-build
# https://github.sc-corp.net/Snapchat/img/tree/master/keydb/ubuntu-20-04
builder_image: us.gcr.io/snapchat-build-artifacts/prod/snapchat/img/keydb/keydb-ubuntu-20-04@sha256:cf869a3f5d1de1e1d976bb906689c37b7031938eb68661b844a38c532f27248c
command: ./runtest-cluster
command: ./runtest-cluster --tls
sentinel-test:
type: cmd
parent: make-build
+83
View File
@@ -1,3 +1,86 @@
keydb (6:6.3.4-1distribution_placeholder) codename_placeholder; urgency=medium
* Add keydb_modstatsd, a module for providing keydb stats to a local statsd server. Can be found under src/modules/keydb_modstatsd
* Fixed FreeBSD compile(Thanks to @bra-fsn)
* Fixed a bug in s3 bucket config that blocked startup(Thanks to Alexandre Chichmanian)
* Fixed a bug causing crash if keys command is called after a blocking command (Fixes issues #659, #605, #532)
* Added proper error checking of replica configs, now KeyDB will throw an error if replica-of config is passed before active-replica or multimaster configs
* Fixed double free bug in lazy free
* Added "overload-protect-percent" config, when enabled this will load shed clients whenever CPU usage exceeds configured value
* Added "availability-zone" config, this can be passed any string which will then be reported by info command
* Updated eviction logic to account for total system memory availability using sysinfo
* Fixed a bug where repl-backlog-size config was modified in keydb.conf with the runtime value during config rewrite
* Fixed a possible deadlock when running CLIENT KILL with large number of clients
* Fixed a bug where KeyDB would overcommit memory during fork BG save
* Fixed a bug with disk repl_backlog causing double free
* Fixed integer overflow issue in the temp rdb file naming (Thanks to @karthyuom)
* Fixed compile issue with GCC 13.1.1 (Thanks to @michieldwitte)
* Removed expireset and restored redis expire behaviour
* Fixed a bug causing forked processes to hang, specifically affecting RDB and AOF(Fixes issues #675, #619)
* Added "CLUSTER REPLICATE NO ONE" to turn a replica into an empty primary
* Added RDB-less full sync, can be enabled with config 'enable-keydb-fastsync'
* Added "flash-disable-key-cache" config to disable key cache which stores every key(but not value) in memory
* Moved cluster slot to key map to being stored by storage provider, rather than in memory
* Moved expires to be stored by storage provider, rather than in memory
* Enabled expiry/eviction from storage provider, previously only data stored in memory could be expired/evicted(Fixes #645 along with the 2 previous updates)
* Fixed a bug where swapdb result was not recovered after keydb restarts in FLASH mode (Thanks to @karthyuom)
* Fixed double free bug when fast sync was canceled early
* Fixed a bug where a temp rdb file with zero bytes is generated in flash mode (Thanks to @karthyuom)
* Fixed a bug where flash CF options are being reset to default after flushall (Thanks to @karthyuom)(Fixes issue #717)
* Updated debug reload command to work with flash
* Added support for KEYDB_PASSWORD env variable(Thanks to @einar-pexip)
* Compile with flash in Dockerfile(Thanks to @der-eismann)
* Fix broken redis-cli symlink (Thanks to @pimvandenbroek)
* Use tini for alpine docker(Thanks to @rofafor)
-- Malavan Sotheeswaran <msotheeswaran@snapchat.com> Sun, 29 Oct 2023 8:39:21 +0000
keydb (6:6.3.3-1distribution_placeholder) codename_placeholder; urgency=medium
* To help accelerate our development efforts for KeyDB, this will be the last release containing support for Centos 7, Ubuntu 16.04, Ubuntu 18.04, Debian 9 and 32-bit builds
* This release contains fixes for 11 issues along with improvements to the KeyDB FLASH feature:
* Fixed race condition with expireset access (Issue #597)
* Fixed keys command with lua, and added keydb as an alternative to redis as lua variable to access db (Issue #562 and #594)
* Fixed hang in aof child (Issue #554)
* Fixed leaking fds from RDB save (Issue #453 and #584)
* Added config for S3 RDB load/save (Issue #584)
* Enabled active defrag during forkless background save to improve average memory efficiency (Issue #460)
* Fixed crash with fork background save during replication (Issue #567)
* RocksDB has been updated to v7.9.2
* Fixed missing slot_to_key map in FLASH cluster mode (Issue #574)
* Added keyspace notifications for keys loaded from FLASH at startup
* Fixed race condition in prefetchKeysAsync with FLASH enabled (Issue #571)
* Fixed integer overflow in rand family of commands(Issue #631, #632, #633)
* Fixed bad value in hincrbyfloat(Issue #634)
* Fixed OOM hang in rand family of commands(Issue #635)
* Added config to limit count of return values in rand family of commands(Issue #636)
-- Ben Schermel <ben@eqalpha.com> Tue, 18 Apr 2023 10:00:37 +0000
keydb (6:6.3.2-1distribution_placeholder) codename_placeholder; urgency=medium
* This release contains Beta level support for KeyDB FLASH, new ASYNC commands, latency improvements and a number of bug fixes.
* KeyDB FLASH is included as a Beta feature. FLASH allows KeyDB to persist data to the storage medium it is written to, avoiding the need for AOF/RDB files. KeyDB uses rocksdb as the persistent storage provider and can be enabled with config "storage-provider flash /path/to/rocksdb/output". Read more at https://docs.keydb.dev/docs/flash/
* In addition to GET/MGET, ASYNC support has been added for the following commands: HGET, HMGET, HKEYS, HVALS, HGETALL, HSCAN and can be enable with config "enable-async-commands yes”
* Packaging support for Ubuntu 22.04 (Jammy) and Debian 12 (Bookworm) has been included with this release
* Added new soft shutdown feature, can be enabled with config "soft-shutdown yes".
* If soft shutdown is enabled, instead of shutting down right away, the server will wait until all clients have disconnected, and will reject all new connection attempts.
* Fixed memory leak with tls certificates when tls allowlist is enabled
* Fixed bug in rdb load with flash enabled to ensure all dbs are safe to load (previously only checked db[0])
* Fixed race conditions in rdb load and replication
* Fixed memory access of rdb file after it should have been deleted
* Fixed integer overflow bug in flash(Issue #486)
* Improve TLS latency by queueing new commands before executing instead of after
* Removed O(n) count of memory usage from info command(replaced by O(1) estimate)
* Improved latency of clearing large number of flash DBs(Thanks to Paul Chen for this fix)(Issue #516)
* replaced sprintf with snprintf to avoid potential security bugs
* Fixed bug where a failed move due to key already existing in move target would result in the key being removed from move source(Thanks to Paul Chen for this fix)(Issue #497)
* Fixed usage of deprecated OpenSSL api in OpenSSL v>3.0.1(Issue #392)
* Imported security fixes from Redis (CVE-2023-22458 CVE-2022-35977)
* Other fixed issues: #480 #477 #454 #452 #303 #425 #492 #541
-- Ben Schermel <ben@eqalpha.com> Fri, 20 Jan 2023 20:00:37 +0000
keydb (6:6.3.1-1distribution_placeholder) codename_placeholder; urgency=medium
* This point release contains fixes to bugs related to expires, active-rep, and rdb saving
+1 -1
View File
@@ -1,4 +1,4 @@
FROM alpine:3.12
FROM alpine:3.18
# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
RUN addgroup -S -g 1000 keydb && adduser -S -G keydb -u 999 keydb
RUN mkdir -p /etc/keydb
+1
View File
@@ -358,6 +358,7 @@ endif
OS := $(shell cat /etc/os-release | grep ID= | head -n 1 | cut -d'=' -f2)
ifeq ($(OS),alpine)
FINAL_CXXFLAGS+=-DUNW_LOCAL_ONLY
FINAL_CXXFLAGS+=-DALPINE
FINAL_LIBS += -lunwind
endif
+26 -7
View File
@@ -136,14 +136,33 @@ void SnapshotPayloadParseState::flushQueuedKeys() {
int idb = current_database;
serverAssert(vecqueuedKeys.size() == vecqueuedVals.size());
auto sizePrev = vecqueuedKeys.size();
(*insertsInFlight)++;
std::weak_ptr<std::atomic<int>> insertsInFlightTmp = insertsInFlight; // C++ GRRRRRRRRRRRRRRRR, we don't want to capute "this" because that's dangerous
if (current_database < cserver.dbnum) {
g_pserver->asyncworkqueue->AddWorkFunction([idb, vecqueuedKeys = std::move(this->vecqueuedKeys), vecqueuedKeysCb = std::move(this->vecqueuedKeysCb), vecqueuedVals = std::move(this->vecqueuedVals), vecqueuedValsCb = std::move(this->vecqueuedValsCb), insertsInFlightTmp, pallocator = m_spallocator.release()]() mutable {
g_pserver->db[idb]->bulkDirectStorageInsert(vecqueuedKeys.data(), vecqueuedKeysCb.data(), vecqueuedVals.data(), vecqueuedValsCb.data(), vecqueuedKeys.size());
(*(insertsInFlightTmp.lock()))--;
delete pallocator;
});
if (g_pserver->m_pstorageFactory) {
(*insertsInFlight)++;
std::weak_ptr<std::atomic<int>> insertsInFlightTmp = insertsInFlight; // C++ GRRRRRRRRRRRRRRRR, we don't want to capute "this" because that's dangerous
g_pserver->asyncworkqueue->AddWorkFunction([idb, vecqueuedKeys = std::move(this->vecqueuedKeys), vecqueuedKeysCb = std::move(this->vecqueuedKeysCb), vecqueuedVals = std::move(this->vecqueuedVals), vecqueuedValsCb = std::move(this->vecqueuedValsCb), insertsInFlightTmp, pallocator = m_spallocator.release()]() mutable {
g_pserver->db[idb]->bulkDirectStorageInsert(vecqueuedKeys.data(), vecqueuedKeysCb.data(), vecqueuedVals.data(), vecqueuedValsCb.data(), vecqueuedKeys.size());
(*(insertsInFlightTmp.lock()))--;
delete pallocator;
});
} else {
for (size_t ival = 0; ival < vecqueuedKeys.size(); ++ival) {
size_t offset = 0;
auto spexpire = deserializeExpire(vecqueuedVals[ival], vecqueuedValsCb[ival], &offset);
auto o = deserializeStoredObject(vecqueuedVals[ival] + offset, vecqueuedValsCb[ival] - offset);
sds sdsKey = sdsnewlen(vecqueuedKeys[ival], -static_cast<ssize_t>(vecqueuedKeysCb[ival]));
if (dbMerge(g_pserver->db[idb], sdsKey, o, false)) {
if (spexpire != nullptr)
g_pserver->db[idb]->setExpire(sdsKey, std::move(*spexpire));
} else {
sdsfree(sdsKey);
}
}
vecqueuedKeys.clear();
vecqueuedKeysCb.clear();
vecqueuedVals.clear();
vecqueuedValsCb.clear();
}
} else {
// else drop the data
vecqueuedKeys.clear();
+1
View File
@@ -2983,6 +2983,7 @@ standardConfig configs[] = {
createIntConfig("overload-protect-percent", NULL, MODIFIABLE_CONFIG, 0, 200, g_pserver->overload_protect_threshold, 0, INTEGER_CONFIG, NULL, NULL),
createIntConfig("force-eviction-percent", NULL, MODIFIABLE_CONFIG, 0, 100, g_pserver->force_eviction_percent, 0, INTEGER_CONFIG, NULL, NULL),
createBoolConfig("enable-async-rehash", NULL, MODIFIABLE_CONFIG, g_pserver->enable_async_rehash, 1, NULL, NULL),
createBoolConfig("enable-keydb-fastsync", NULL, MODIFIABLE_CONFIG, g_pserver->fEnableFastSync, 0, NULL, NULL),
#ifdef USE_OPENSSL
createIntConfig("tls-port", NULL, MODIFIABLE_CONFIG, 0, 65535, g_pserver->tls_port, 0, INTEGER_CONFIG, NULL, updateTLSPort), /* TCP port. */
-1
View File
@@ -56,7 +56,6 @@ int expireIfNeeded(redisDb *db, robj *key, robj *o);
void slotToKeyUpdateKeyCore(const char *key, size_t keylen, int add);
std::unique_ptr<expireEntry> deserializeExpire(const char *str, size_t cch, size_t *poffset);
sds serializeStoredObjectAndExpire(robj_roptr o);
dictType dictChangeDescType {
dictSdsHash, /* hash function */
-1
View File
@@ -163,7 +163,6 @@ client *createClient(connection *conn, int iel) {
c->multibulklen = 0;
c->bulklen = -1;
c->sentlen = 0;
c->sentlenAsync = 0;
c->flags = 0;
c->fPendingAsyncWrite = FALSE;
c->fPendingAsyncWriteHandler = FALSE;
+3 -3
View File
@@ -42,9 +42,9 @@ public:
while (m_readCount > 0)
m_cv.wait(rm);
if (exclusive) {
/* Another thread might have the write lock while we have the read lock
but won't be able to release it until they can acquire the read lock
so release the read lock and try again instead of waiting to avoid deadlock */
/* Another thread might have the write lock while we have the internal lock
but won't be able to release it until they can acquire the internal lock
so release the internal lock and try again instead of waiting to avoid deadlock */
while(!m_writeLock.try_lock())
m_cv.wait(rm);
}
+8 -2
View File
@@ -2524,7 +2524,10 @@ cleanup:
static int clusterManagerNodeConnect(clusterManagerNode *node) {
if (node->context) redisFree(node->context);
node->context = redisConnect(node->ip, node->port);
struct timeval tv;
tv.tv_sec = config.cluster_manager_command.timeout / 1000;
tv.tv_usec = (config.cluster_manager_command.timeout % 1000) * 1000;
node->context = redisConnectWithTimeout(node->ip, node->port, tv);
if (!node->context->err && config.tls) {
const char *err = NULL;
if (cliSecureConnection(node->context, config.sslconfig, &err) == REDIS_ERR && err) {
@@ -5626,7 +5629,10 @@ static int clusterManagerCommandImport(int argc, char **argv) {
char *reply_err = NULL;
redisReply *src_reply = NULL;
// Connect to the source node.
redisContext *src_ctx = redisConnect(src_ip, src_port);
struct timeval tv;
tv.tv_sec = config.cluster_manager_command.timeout / 1000;
tv.tv_usec = (config.cluster_manager_command.timeout % 1000) * 1000;
redisContext *src_ctx = redisConnectWithTimeout(src_ip, src_port, tv);
if (src_ctx->err) {
success = 0;
fprintf(stderr,"Could not connect to KeyDB at %s:%d: %s.\n", src_ip,
+61 -48
View File
@@ -1019,8 +1019,6 @@ public:
void addReplica(client *replica) {
replicas.push_back(replica);
replicationSetupSlaveForFullResync(replica,getPsyncInitialOffset());
// Optimize the socket for bulk transfer
//connDisableTcpNoDelay(replica->conn);
}
bool isActive() const { return !replicas.empty(); }
@@ -1093,7 +1091,7 @@ public:
reply->used += size;
}
void addLongWithPrefix(long val, char prefix) {
void addLongLongWithPrefix(long long val, char prefix) {
char buf[128];
int len;
@@ -1105,15 +1103,19 @@ public:
}
void addArrayLen(int len) {
addLongWithPrefix(len, '*');
addLongLongWithPrefix(len, '*');
}
void addLong(long val) {
addLongWithPrefix(val, ':');
addLongLongWithPrefix(val, ':');
}
void addLongLong(long long val) {
addLongLongWithPrefix(val, ':');
}
void addString(const char *s, unsigned long len) {
addLongWithPrefix(len, '$');
addLongLongWithPrefix(len, '$');
addData(s, len);
addData("\r\n", 2);
}
@@ -1149,22 +1151,19 @@ int rdbSaveSnapshotForReplication(rdbSaveInfo *rsi) {
// TODO: This needs to be on a background thread
int retval = C_OK;
serverAssert(GlobalLocksAcquired());
serverLog(LL_NOTICE, "Starting storage provider fast full sync with target: %s", "disk");
serverLog(LL_NOTICE, "Starting fast full sync with target: %s", "disk");
std::shared_ptr<replicationBuffer> spreplBuf = std::make_shared<replicationBuffer>();
listNode *ln;
listIter li;
client *replica = nullptr;
listRewind(g_pserver->slaves, &li);
while (replica == nullptr && (ln = listNext(&li))) {
while ((ln = listNext(&li))) {
client *replicaCur = (client*)listNodeValue(ln);
if ((replicaCur->slave_capa & SLAVE_CAPA_ROCKSDB_SNAPSHOT) && (replicaCur->replstate == SLAVE_STATE_WAIT_BGSAVE_START)) {
replica = replicaCur;
spreplBuf->addReplica(replica);
if ((replicaCur->slave_capa & SLAVE_CAPA_KEYDB_FASTSYNC) && (replicaCur->replstate == SLAVE_STATE_WAIT_BGSAVE_START)) {
spreplBuf->addReplica(replicaCur);
replicaCur->replstate = SLAVE_STATE_FASTSYNC_TX;
}
}
serverAssert(replica != nullptr);
spreplBuf->addArrayLen(2); // Two sections: Metadata and databases
@@ -1179,7 +1178,7 @@ int rdbSaveSnapshotForReplication(rdbSaveInfo *rsi) {
spreplBuf->addString(rsi->repl_id, CONFIG_RUN_ID_SIZE);
spreplBuf->addArrayLen(2);
spreplBuf->addString("repl-offset", 11);
spreplBuf->addLong(rsi->master_repl_offset);
spreplBuf->addLongLong(rsi->master_repl_offset);
if (dictSize(g_pserver->lua_scripts)) {
dictEntry *de;
@@ -1195,13 +1194,13 @@ int rdbSaveSnapshotForReplication(rdbSaveInfo *rsi) {
di = NULL; /* So that we don't release it again on error. */
}
std::shared_ptr<std::vector<std::unique_ptr<const StorageCache>>> spvecspsnapshot = std::make_shared<std::vector<std::unique_ptr<const StorageCache>>>();
std::shared_ptr<std::vector<const redisDbPersistentDataSnapshot*>> spvecsnapshot = std::make_shared<std::vector<const redisDbPersistentDataSnapshot*>>();
for (int idb = 0; idb < cserver.dbnum; ++idb) {
spvecspsnapshot->emplace_back(g_pserver->db[idb]->CloneStorageCache());
spvecsnapshot->emplace_back(g_pserver->db[idb]->createSnapshot(getMvccTstamp(), false));
}
aeReleaseLock();
g_pserver->asyncworkqueue->AddWorkFunction([spreplBuf = std::move(spreplBuf), spvecspsnapshot = std::move(spvecspsnapshot)]{
g_pserver->asyncworkqueue->AddWorkFunction([spreplBuf = std::move(spreplBuf), spvecsnapshot = std::move(spvecsnapshot)]{
int retval = C_OK;
auto timeStart = ustime();
auto lastLogTime = timeStart;
@@ -1211,15 +1210,16 @@ int rdbSaveSnapshotForReplication(rdbSaveInfo *rsi) {
// Databases
replBuf.addArrayLen(cserver.dbnum);
for (int idb = 0; idb < cserver.dbnum; ++idb) {
auto &spsnapshot = (*spvecspsnapshot)[idb];
size_t snapshotDeclaredCount = spsnapshot->count();
auto &spsnapshot = (*spvecsnapshot)[idb];
size_t snapshotDeclaredCount = spsnapshot->size();
replBuf.addArrayLen(snapshotDeclaredCount);
size_t count = 0;
bool result = spsnapshot->enumerate([&replBuf, &count, &cbData, &lastLogTime, &cbLastUpdate](const char *rgchKey, size_t cchKey, const void *rgchVal, size_t cchVal) -> bool{
bool result = spsnapshot->iterate_threadsafe([&replBuf, &count, &cbData, &lastLogTime, &cbLastUpdate](const char *strKey, robj_roptr o) -> bool{
replBuf.addArrayLen(2);
replBuf.addString(rgchKey, cchKey);
replBuf.addString((const char *)rgchVal, cchVal);
replBuf.addString(strKey, sdslen(strKey));
sds strT = serializeStoredObjectAndExpire(o);
replBuf.addString(strT, sdslen(strT));
++count;
if ((count % 8092) == 0) {
auto curTime = ustime();
@@ -1230,7 +1230,8 @@ int rdbSaveSnapshotForReplication(rdbSaveInfo *rsi) {
lastLogTime = ustime();
}
}
cbData += cchKey + cchVal;
cbData += sdslen(strKey) + sdslen(strT);
sdsfree(strT);
return replBuf.isActive();
});
@@ -1302,7 +1303,7 @@ int startBgsaveForReplication(int mincapa) {
/* Only do rdbSave* when rsiptr is not NULL,
* otherwise replica will miss repl-stream-db. */
if (rsiptr) {
if (mincapa & SLAVE_CAPA_ROCKSDB_SNAPSHOT && g_pserver->m_pstorageFactory)
if (mincapa & SLAVE_CAPA_KEYDB_FASTSYNC && FFastSyncEnabled())
retval = rdbSaveSnapshotForReplication(rsiptr);
else if (socket_target)
retval = rdbSaveToSlavesSockets(rsiptr);
@@ -1481,7 +1482,7 @@ void syncCommand(client *c) {
}
/* CASE 0: Fast Sync */
if ((c->slave_capa & SLAVE_CAPA_ROCKSDB_SNAPSHOT) && g_pserver->m_pstorageFactory) {
if (c->slave_capa & SLAVE_CAPA_KEYDB_FASTSYNC && FFastSyncEnabled()) {
serverLog(LL_NOTICE,"Fast SYNC on next replication cycle");
/* CASE 1: BGSAVE is in progress, with disk target. */
} else if (g_pserver->FRdbSaveInProgress() &&
@@ -1672,8 +1673,8 @@ void replconfCommand(client *c) {
c->slave_capa |= SLAVE_CAPA_PSYNC2;
else if (!strcasecmp((const char*)ptrFromObj(c->argv[j+1]), "activeExpire"))
c->slave_capa |= SLAVE_CAPA_ACTIVE_EXPIRE;
else if (!strcasecmp((const char*)ptrFromObj(c->argv[j+1]), "rocksdb-snapshot-load"))
c->slave_capa |= SLAVE_CAPA_ROCKSDB_SNAPSHOT;
else if (!strcasecmp((const char*)ptrFromObj(c->argv[j+1]), "keydb-fastsync"))
c->slave_capa |= SLAVE_CAPA_KEYDB_FASTSYNC;
fCapaCommand = true;
} else if (!strcasecmp((const char*)ptrFromObj(c->argv[j]),"ack")) {
@@ -1738,10 +1739,14 @@ void replconfCommand(client *c) {
if (fCapaCommand) {
sds reply = sdsnew("+OK");
if (g_pserver->fActiveReplica)
if (g_pserver->fActiveReplica) {
reply = sdscat(reply, " active-replica");
if (g_pserver->m_pstorageFactory && (c->slave_capa & SLAVE_CAPA_ROCKSDB_SNAPSHOT) && !g_pserver->fActiveReplica)
reply = sdscat(reply, " rocksdb-snapshot-save");
}
if ((c->slave_capa & SLAVE_CAPA_KEYDB_FASTSYNC) && FFastSyncEnabled()) {
reply = sdscat(reply, " keydb-fastsync-save");
} else {
c->slave_capa = (c->slave_capa & (~SLAVE_CAPA_KEYDB_FASTSYNC)); // never try to fast sync for this as they won't expect it
}
reply = sdscat(reply, "\r\n");
addReplySds(c, reply);
} else {
@@ -2515,6 +2520,7 @@ bool readSnapshotBulkPayload(connection *conn, redisMaster *mi, rdbSaveInfo &rsi
}
}
serverAssert(mi->parseState != nullptr);
for (int iter = 0; iter < 10; ++iter) {
if (mi->parseState->shouldThrottle())
return false;
@@ -2525,11 +2531,16 @@ bool readSnapshotBulkPayload(connection *conn, redisMaster *mi, rdbSaveInfo &rsi
auto nread = connRead(conn, mi->bulkreadBuffer+qblen, readlen);
if (nread <= 0) {
if (connGetState(conn) != CONN_STATE_CONNECTED)
if (connGetState(conn) != CONN_STATE_CONNECTED) {
serverLog(LL_WARNING,"I/O error trying to sync with MASTER: %s",
(nread == -1) ? strerror(errno) : "connection lost");
cancelReplicationHandshake(mi, true);
}
return false;
}
g_pserver->stat_net_input_bytes += nread;
mi->repl_transfer_lastio = g_pserver->unixtime;
mi->repl_transfer_read += nread;
sdsIncrLen(mi->bulkreadBuffer,nread);
size_t offset = 0;
@@ -2601,8 +2612,9 @@ bool readSnapshotBulkPayload(connection *conn, redisMaster *mi, rdbSaveInfo &rsi
rsi.repl_stream_db = mi->parseState->getMetaDataLongLong("repl-stream-db");
rsi.repl_offset = mi->parseState->getMetaDataLongLong("repl-offset");
sds str = mi->parseState->getMetaDataStr("repl-id");
if (sdslen(str) == CONFIG_RUN_ID_SIZE+1) {
if (sdslen(str) == CONFIG_RUN_ID_SIZE) {
memcpy(rsi.repl_id, str, CONFIG_RUN_ID_SIZE+1);
rsi.repl_id_is_set = 1;
}
fFinished = true;
@@ -3001,7 +3013,7 @@ void readSyncBulkPayload(connection *conn) {
return;
}
if (mi->isRocksdbSnapshotRepl) {
if (mi->isKeydbFastsync) {
if (!readSnapshotBulkPayload(conn, mi, rsi))
return;
} else {
@@ -3014,17 +3026,15 @@ void readSyncBulkPayload(connection *conn) {
/* Final setup of the connected slave <- master link */
replicationCreateMasterClient(mi,mi->repl_transfer_s,rsi.repl_stream_db);
if (mi->isRocksdbSnapshotRepl) {
if (mi->isKeydbFastsync) {
/* We need to handle the case where the initial querybuf data was read by fast sync */
/* This should match the work readQueryFromClient would do for a master client */
mi->master->querybuf = sdscatsds(mi->master->querybuf, mi->bulkreadBuffer);
mi->master->pending_querybuf = sdscatsds(mi->master->pending_querybuf, mi->bulkreadBuffer);
mi->master->read_reploff += sdslen(mi->bulkreadBuffer);
sdsfree(mi->bulkreadBuffer);
mi->bulkreadBuffer = nullptr;
mi->master->pending_querybuf = sdscatlen(mi->master->pending_querybuf,
mi->master->querybuf,sdslen(mi->master->querybuf));
mi->master->read_reploff += sdslen(mi->master->querybuf);
}
mi->repl_transfer_s = nullptr;
mi->repl_state = REPL_STATE_CONNECTED;
@@ -3063,13 +3073,13 @@ void readSyncBulkPayload(connection *conn) {
}
/* Send the initial ACK immediately to put this replica in online state. */
if (usemark || mi->isRocksdbSnapshotRepl) replicationSendAck(mi);
if (usemark || mi->isKeydbFastsync) replicationSendAck(mi);
/* Restart the AOF subsystem now that we finished the sync. This
* will trigger an AOF rewrite, and when done will start appending
* to the new file. */
if (g_pserver->aof_enabled) restartAOFAfterSYNC();
if (mi->isRocksdbSnapshotRepl)
if (mi->isKeydbFastsync)
readQueryFromClient(conn); // There may be querybuf data we just appeneded
return;
}
@@ -3395,15 +3405,15 @@ void parseMasterCapa(redisMaster *mi, sds strcapa)
char *pchEnd = szStart;
mi->isActive = false;
mi->isRocksdbSnapshotRepl = false;
mi->isKeydbFastsync = false;
for (;;)
{
if (*pchEnd == ' ' || *pchEnd == '\0') {
// Parse the word
if (strncmp(szStart, "active-replica", pchEnd - szStart) == 0) {
mi->isActive = true;
} else if (strncmp(szStart, "rocksdb-snapshot-save", pchEnd - szStart) == 0) {
mi->isRocksdbSnapshotRepl = true;
} else if (strncmp(szStart, "keydb-fastsync-save", pchEnd - szStart) == 0) {
mi->isKeydbFastsync = true;
}
szStart = pchEnd + 1;
}
@@ -3550,9 +3560,9 @@ retry_connect:
"capa","psync2",
"capa","activeExpire",
};
if (g_pserver->m_pstorageFactory && !g_pserver->fActiveReplica && g_pserver->repl_diskless_load != REPL_DISKLESS_LOAD_SWAPDB) {
if (FFastSyncEnabled() && g_pserver->repl_diskless_load != REPL_DISKLESS_LOAD_SWAPDB) {
veccapabilities.push_back("capa");
veccapabilities.push_back("rocksdb-snapshot-load");
veccapabilities.push_back("keydb-fastsync");
}
err = sendCommandArgv(conn, veccapabilities.size(), veccapabilities.data(), nullptr);
@@ -3735,7 +3745,7 @@ retry_connect:
}
/* Prepare a suitable temp file for bulk transfer */
if (!useDisklessLoad() && !mi->isRocksdbSnapshotRepl) {
if (!useDisklessLoad() && !mi->isKeydbFastsync) {
while(maxtries--) {
auto dt = std::chrono::system_clock::now().time_since_epoch();
auto dtMillisecond = std::chrono::duration_cast<std::chrono::milliseconds>(dt);
@@ -3864,6 +3874,10 @@ int cancelReplicationHandshake(redisMaster *mi, int reconnect) {
delete mi->parseState;
mi->parseState = nullptr;
}
if (mi->bulkreadBuffer) {
sdsfree(mi->bulkreadBuffer);
mi->bulkreadBuffer = nullptr;
}
if (mi->repl_state == REPL_STATE_TRANSFER) {
replicationAbortSyncTransfer(mi);
@@ -4329,7 +4343,6 @@ void replicationCacheMaster(redisMaster *mi, client *c) {
if (c->flags & CLIENT_MULTI) discardTransaction(c);
listEmpty(c->reply);
c->sentlen = 0;
c->sentlenAsync = 0;
c->reply_bytes = 0;
c->bufpos = 0;
resetClient(c);
+4 -1
View File
@@ -418,7 +418,10 @@ public:
sdsstring &operator=(const sdsstring &other)
{
sdsfree(m_str);
m_str = sdsdup(other.m_str);
if (other.m_str != nullptr)
m_str = sdsdup(other.m_str);
else
m_str = nullptr;
return *this;
}
+2 -2
View File
@@ -5102,8 +5102,8 @@ int processCommand(client *c, int callFlags) {
sds str = sdsempty();
for (int j = 0; j < numkeys; j++) {
sdscatsds(str, (sds)ptrFromObj(c->argv[keyindex[j]]));
sdscat(str, " ");
str = sdscatsds(str, (sds)ptrFromObj(c->argv[keyindex[j]]));
str = sdscat(str, " ");
}
if (numkeys > 0)
+9 -4
View File
@@ -620,7 +620,7 @@ typedef enum {
#define SLAVE_CAPA_EOF (1<<0) /* Can parse the RDB EOF streaming format. */
#define SLAVE_CAPA_PSYNC2 (1<<1) /* Supports PSYNC2 protocol. */
#define SLAVE_CAPA_ACTIVE_EXPIRE (1<<2) /* Will the slave perform its own expirations? (Don't send delete) */
#define SLAVE_CAPA_ROCKSDB_SNAPSHOT (1<<3)
#define SLAVE_CAPA_KEYDB_FASTSYNC (1<<3)
/* Synchronous read timeout - replica side */
#define CONFIG_REPL_SYNCIO_TIMEOUT 5
@@ -1610,7 +1610,6 @@ struct client {
unsigned long long reply_bytes; /* Tot bytes of objects in reply list. */
size_t sentlen; /* Amount of bytes already sent in the current
buffer or object being sent. */
size_t sentlenAsync; /* same as sentlen buf for async buffers (which are a different stream) */
time_t ctime; /* Client creation time. */
long duration; /* Current command duration. Used for measuring latency of blocking/non-blocking cmds */
time_t lastinteraction; /* Time of the last interaction, used for timeout */
@@ -1871,7 +1870,7 @@ struct redisMaster {
long long master_initial_offset; /* Master PSYNC offset. */
bool isActive = false;
bool isRocksdbSnapshotRepl = false;
bool isKeydbFastsync = false;
int repl_state; /* Replication status if the instance is a replica */
off_t repl_transfer_size; /* Size of RDB to read from master during sync. */
off_t repl_transfer_read; /* Amount of RDB read from master during sync. */
@@ -2688,6 +2687,7 @@ struct redisServer {
int fActiveReplica; /* Can this replica also be a master? */
int fWriteDuringActiveLoad; /* Can this active-replica write during an RDB load? */
int fEnableFastSync = false;
// Format:
// Lower 20 bits: a counter incrementing for each command executed in the same millisecond
@@ -3182,6 +3182,7 @@ void trimStringObjectIfNeeded(robj *o);
robj *deserializeStoredObject(const void *data, size_t cb);
std::unique_ptr<expireEntry> deserializeExpire(const char *str, size_t cch, size_t *poffset);
sds serializeStoredObject(robj_roptr o, sds sdsPrefix = nullptr);
sds serializeStoredObjectAndExpire(robj_roptr o);
#define sdsEncodedObject(objptr) (objptr->encoding == OBJ_ENCODING_RAW || objptr->encoding == OBJ_ENCODING_EMBSTR)
@@ -3923,7 +3924,7 @@ void updateActiveReplicaMastersFromRsi(rdbSaveInfo *rsi);
uint64_t getMvccTstamp();
void incrementMvccTstamp();
#if __GNUC__ >= 7 && !defined(NO_DEPRECATE_FREE)
#if __GNUC__ >= 7 && !defined(NO_DEPRECATE_FREE) && !defined(ALPINE)
[[deprecated]]
void *calloc(size_t count, size_t size) noexcept;
[[deprecated]]
@@ -3971,6 +3972,10 @@ inline int ielFromEventLoop(const aeEventLoop *eventLoop)
return iel;
}
inline bool FFastSyncEnabled() {
return g_pserver->fEnableFastSync && !g_pserver->fActiveReplica;
}
inline int FCorrectThread(client *c)
{
return (c->conn == nullptr)
+15 -10
View File
@@ -7,6 +7,8 @@
#include "../cluster.h"
#include "rocksdbfactor_internal.h"
template class std::basic_string<char>;
static const char keyprefix[] = INTERNAL_KEY_PREFIX;
rocksdb::Options DefaultRocksDBOptions();
@@ -24,8 +26,9 @@ bool FInternalKey(const char *key, size_t cch)
std::string getPrefix(unsigned int hashslot)
{
char *hash_char = (char *)&hashslot;
return std::string(hash_char + (sizeof(unsigned int) - 2), 2);
HASHSLOT_PREFIX_TYPE slot = HASHSLOT_PREFIX_ENDIAN((HASHSLOT_PREFIX_TYPE)hashslot);
char *hash_char = (char *)&slot;
return std::string(hash_char, HASHSLOT_PREFIX_BYTES);
}
std::string prefixKey(const char *key, size_t cchKey)
@@ -184,7 +187,7 @@ bool RocksDBStorageProvider::enumerate(callback fn) const
if (FInternalKey(it->key().data(), it->key().size()))
continue;
++count;
bool fContinue = fn(it->key().data()+2, it->key().size()-2, it->value().data(), it->value().size());
bool fContinue = fn(it->key().data()+HASHSLOT_PREFIX_BYTES, it->key().size()-HASHSLOT_PREFIX_BYTES, it->value().data(), it->value().size());
if (!fContinue)
break;
}
@@ -203,17 +206,17 @@ bool RocksDBStorageProvider::enumerate_hashslot(callback fn, unsigned int hashsl
std::string prefix = getPrefix(hashslot);
std::unique_ptr<rocksdb::Iterator> it = std::unique_ptr<rocksdb::Iterator>(m_spdb->NewIterator(ReadOptions(), m_spcolfamily.get()));
size_t count = 0;
for (it->Seek(prefix.c_str()); it->Valid(); it->Next()) {
for (it->Seek(prefix); it->Valid(); it->Next()) {
if (FInternalKey(it->key().data(), it->key().size()))
continue;
if (strncmp(it->key().data(),prefix.c_str(),2) != 0)
if (HASHSLOT_PREFIX_RECOVER(*(HASHSLOT_PREFIX_TYPE *)it->key().data()) != hashslot)
break;
++count;
bool fContinue = fn(it->key().data()+2, it->key().size()-2, it->value().data(), it->value().size());
bool fContinue = fn(it->key().data()+HASHSLOT_PREFIX_BYTES, it->key().size()-HASHSLOT_PREFIX_BYTES, it->value().data(), it->value().size());
if (!fContinue)
break;
}
bool full_iter = !it->Valid() || (strncmp(it->key().data(),prefix.c_str(),2) != 0);
bool full_iter = !it->Valid() || (HASHSLOT_PREFIX_RECOVER(*(HASHSLOT_PREFIX_TYPE *)it->key().data()) != hashslot);
if (full_iter && count != g_pserver->cluster->slots_keys_count[hashslot])
{
printf("WARNING: rocksdb hashslot count mismatch");
@@ -227,7 +230,8 @@ void RocksDBStorageProvider::setExpire(const char *key, size_t cchKey, long long
{
rocksdb::Status status;
std::unique_lock<fastlock> l(m_lock);
std::string prefix((const char *)&expire,sizeof(long long));
long long beExpire = htobe64(expire);
std::string prefix((const char *)&beExpire,sizeof(long long));
std::string strKey(key, cchKey);
if (m_spbatch != nullptr)
status = m_spbatch->Put(m_spexpirecolfamily.get(), rocksdb::Slice(prefix + strKey), rocksdb::Slice(strKey));
@@ -241,7 +245,8 @@ void RocksDBStorageProvider::removeExpire(const char *key, size_t cchKey, long l
{
rocksdb::Status status;
std::unique_lock<fastlock> l(m_lock);
std::string prefix((const char *)&expire,sizeof(long long));
long long beExpire = htobe64(expire);
std::string prefix((const char *)&beExpire,sizeof(long long));
std::string strKey(key, cchKey);
std::string fullKey = prefix + strKey;
if (!FExpireExists(fullKey))
@@ -278,7 +283,7 @@ std::vector<std::string> RocksDBStorageProvider::getEvictionCandidates(unsigned
for (it->Seek(randomHashSlot()); it->Valid() && result.size() < count; it->Next()) {
if (FInternalKey(it->key().data(), it->key().size()))
continue;
result.emplace_back(it->key().data() + 2, it->key().size() - 2);
result.emplace_back(it->key().data() + HASHSLOT_PREFIX_BYTES, it->key().size() - HASHSLOT_PREFIX_BYTES);
}
} else {
std::unique_ptr<rocksdb::Iterator> it = std::unique_ptr<rocksdb::Iterator>(m_spdb->NewIterator(ReadOptions(), m_spexpirecolfamily.get()));
+12
View File
@@ -4,9 +4,21 @@
#include "../IStorage.h"
#include <rocksdb/db.h>
#include <rocksdb/utilities/write_batch_with_index.h>
#ifdef __APPLE__
#include <libkern/OSByteOrder.h>
#define htole16 OSSwapHostToLittleInt16
#define le16toh OSSwapLittleToHostInt16
#define htobe64 OSSwapHostToBigInt64
#else
#include <endian.h>
#endif
#include "../fastlock.h"
#define INTERNAL_KEY_PREFIX "\x00\x04\x03\x00\x05\x02\x04"
#define HASHSLOT_PREFIX_TYPE uint16_t
#define HASHSLOT_PREFIX_BYTES sizeof(HASHSLOT_PREFIX_TYPE)
#define HASHSLOT_PREFIX_ENDIAN htole16
#define HASHSLOT_PREFIX_RECOVER le16toh
static const char count_key[] = INTERNAL_KEY_PREFIX "__keydb__count\1";
static const char version_key[] = INTERNAL_KEY_PREFIX "__keydb__version\1";
static const char meta_key[] = INTERNAL_KEY_PREFIX "__keydb__metadata\1";
+2 -2
View File
@@ -72,7 +72,7 @@ RocksDBStorageFactory::RocksDBStorageFactory(const char *dbfile, int dbnum, cons
rocksdb::DB *db = nullptr;
auto options = RocksDbOptions();
options.prefix_extractor.reset(rocksdb::NewFixedPrefixTransform(2));
options.prefix_extractor.reset(rocksdb::NewFixedPrefixTransform(HASHSLOT_PREFIX_BYTES));
for (int idb = 0; idb < dbnum; ++idb)
{
@@ -196,7 +196,7 @@ IStorage *RocksDBStorageFactory::create(int db, key_load_iterator iter, void *pr
printf("\tDatabase %d was not shutdown cleanly, recomputing metrics\n", db);
fFirstRealKey = false;
if (iter != nullptr)
iter(it->key().data()+2, it->key().size()-2, privdata);
iter(it->key().data()+HASHSLOT_PREFIX_BYTES, it->key().size()-HASHSLOT_PREFIX_BYTES, privdata);
++count;
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
#define KEYDB_REAL_VERSION "255.255.255"
#define KEYDB_VERSION_NUM 0x00ffffff
#define KEYDB_REAL_VERSION "6.3.4"
#define KEYDB_VERSION_NUM 0x00060304
extern const char *KEYDB_SET_VERSION; // Unlike real version, this can be overriden by the config
enum VersionCompareResult
+5
View File
@@ -584,6 +584,7 @@ start_server {tags {"repl"}} {
set master [srv 0 client]
$master config set repl-diskless-sync yes
$master config set repl-diskless-sync-delay 1
$master config set enable-keydb-fastsync no
set master_host [srv 0 host]
set master_port [srv 0 port]
set master_pid [srv 0 pid]
@@ -727,6 +728,8 @@ start_server {tags {"repl"}} {
}
}
}
$master config set enable-keydb-fastsync yes
}
if 0 {
@@ -867,8 +870,10 @@ test {replicaof right after disconnection} {
test {Kill rdb child process if its dumping RDB is not useful} {
start_server {tags {"repl"}} {
set slave1 [srv 0 client]
$slave1 config set enable-keydb-fastsync no
start_server {} {
set slave2 [srv 0 client]
$slave2 config set enable-keydb-fastsync no
start_server {} {
set master [srv 0 client]
set master_host [srv 0 host]
+2
View File
@@ -182,6 +182,8 @@ proc test_slave_buffers {test_name cmd_count payload_len limit_memory pipeline}
fail "Replication not started."
}
after 100
# measure used memory after the slave connected and set maxmemory
set orig_used [s -1 used_memory]
set orig_client_buf [s -1 mem_clients_normal]
+2 -2
View File
@@ -51,7 +51,7 @@ if {$::tls} {
}
}
test {TLS: Able to connect while with SAN having a comprehensive list} {
test {TLS Audit Log: Able to connect while with SAN having a comprehensive list} {
start_server {tags {"tls"} overrides {tls-auditlog-blocklist {dummy.keydb.dev san2.keydb.dev other.keydb.dev}}} {
catch {r PING} e
assert_match {PONG} $e
@@ -65,7 +65,7 @@ if {$::tls} {
}
}
test {TLS Audit LogTLS: Able to connect while with SAN having a comprehensive list with wildcards} {
test {TLS Audit Log: Able to connect while with SAN having a comprehensive list with wildcards} {
start_server {tags {"tls"} overrides {tls-auditlog-blocklist {dummy.* san*.dev other.*}}} {
catch {r PING} e
assert_match {PONG} $e