Compare commits
58
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7e7e5e57d2 | ||
|
|
de3c218a02 | ||
|
|
05945b60a8 | ||
|
|
486a6bb7b1 | ||
|
|
79b0c84710 | ||
|
|
7049b5f4e8 | ||
|
|
5b12251627 | ||
|
|
a0f280e1a2 | ||
|
|
57f4a2e8b1 | ||
|
|
38169682f0 | ||
|
|
5f5753ae53 | ||
|
|
e42d83d208 | ||
|
|
9c32d4c1c8 | ||
|
|
337eb297a1 | ||
|
|
cf13e7b594 | ||
|
|
441b74a936 | ||
|
|
ce70e8cd0c | ||
|
|
e3a1ea3928 | ||
|
|
a464a7173d | ||
|
|
806175df99 | ||
|
|
bcb542128a | ||
|
|
870b0db23d | ||
|
|
a4c19e3430 | ||
|
|
9a8a36e8ee | ||
|
|
aef01878a5 | ||
|
|
bd6eb379d5 | ||
|
|
06a49a6179 | ||
|
|
9ab1278cf1 | ||
|
|
cc8ed88577 | ||
|
|
0d2f98d6e1 | ||
|
|
872c60566f | ||
|
|
b5a20a4f91 | ||
|
|
cf4735b61e | ||
|
|
b2ecf2c856 | ||
|
|
e80aba694c | ||
|
|
f774a17d8a | ||
|
|
329bf17e97 | ||
|
|
4da21dd328 | ||
|
|
3792ffb580 | ||
|
|
271c2cb92c | ||
|
|
4c0cf9e5cd | ||
|
|
e3cdc765a1 | ||
|
|
60d74262dc | ||
|
|
65b7fafd29 | ||
|
|
ac7e6c0691 | ||
|
|
87012bf98e | ||
|
|
1dc5ea40f3 | ||
|
|
22d5ce41f3 | ||
|
|
c9d63c50c0 | ||
|
|
39e3141a0a | ||
|
|
1f2c179124 | ||
|
|
4c3d9341fd | ||
|
|
821b39acac | ||
|
|
0d01b810c3 | ||
|
|
501ae473e1 | ||
|
|
6f77a82480 | ||
|
|
8e052f728c | ||
|
|
26285d3dd5 |
No files matched your search
@@ -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
|
||||
|
||||
@@ -53,7 +53,7 @@ RUN set -eux; \
|
||||
grep -E '^ *createBoolConfig[(]"protected-mode",.*, *1 *,.*[)],$' ./src/config.cpp; \
|
||||
sed -ri 's!^( *createBoolConfig[(]"protected-mode",.*, *)1( *,.*[)],)$!\10\2!' ./src/config.cpp; \
|
||||
grep -E '^ *createBoolConfig[(]"protected-mode",.*, *0 *,.*[)],$' ./src/config.cpp; \
|
||||
make -j$(nproc) BUILD_TLS=yes; \
|
||||
make -j$(nproc) BUILD_TLS=yes ENABLE_FLASH=yes; \
|
||||
cd src; \
|
||||
strip keydb-cli keydb-benchmark keydb-check-rdb keydb-check-aof keydb-diagnostic-tool keydb-sentinel keydb-server; \
|
||||
mv keydb-server keydb-cli keydb-benchmark keydb-check-rdb keydb-check-aof keydb-diagnostic-tool keydb-sentinel /usr/local/bin/; \
|
||||
@@ -83,6 +83,7 @@ RUN \
|
||||
sed -i 's/^\(logfile .*\)$/# \1/' /etc/keydb/keydb.conf; \
|
||||
sed -i 's/protected-mode yes/protected-mode no/g' /etc/keydb/keydb.conf; \
|
||||
sed -i 's/^\(bind .*\)$/# \1/' /etc/keydb/keydb.conf; \
|
||||
cd /usr/local/bin; \
|
||||
ln -s keydb-cli redis-cli; \
|
||||
cd /etc/keydb; \
|
||||
ln -s keydb.conf redis.conf; \
|
||||
@@ -96,6 +97,10 @@ RUN set -eux; \
|
||||
echo 'if [ "${1#-}" != "$1" ] || [ "${1%.conf}" != "$1" ]; then' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||
echo ' set -- keydb-server "$@"' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||
echo 'fi' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||
echo '# if KEYDB_PASSWORD is set, add it to the arguments' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||
echo 'if [ -n "$KEYDB_PASSWORD" ]; then' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||
echo ' set -- "$@" --requirepass "${KEYDB_PASSWORD}"' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||
echo 'fi' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||
echo "# allow the container to be started with `--user`" >> /usr/local/bin/docker-entrypoint.sh; \
|
||||
echo 'if [ "$1" = "keydb-server" -a "$(id -u)" = "0" ]; then' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||
echo " find . \! -user keydb -exec chown keydb '{}' +" >> /usr/local/bin/docker-entrypoint.sh; \
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
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
|
||||
ARG BRANCH
|
||||
RUN set -eux; \
|
||||
\
|
||||
apk add --no-cache su-exec; \
|
||||
apk add --no-cache su-exec tini; \
|
||||
apk add --no-cache --virtual .build-deps \
|
||||
coreutils \
|
||||
gcc \
|
||||
@@ -32,7 +32,7 @@ RUN set -eux; \
|
||||
grep -E '^ *createBoolConfig[(]"protected-mode",.*, *1 *,.*[)],$' ./src/config.cpp; \
|
||||
sed -ri 's!^( *createBoolConfig[(]"protected-mode",.*, *)1( *,.*[)],)$!\10\2!' ./src/config.cpp; \
|
||||
grep -E '^ *createBoolConfig[(]"protected-mode",.*, *0 *,.*[)],$' ./src/config.cpp; \
|
||||
make -j$(nproc) BUILD_TLS=yes; \
|
||||
make -j$(nproc) BUILD_TLS=yes ENABLE_FLASH=yes; \
|
||||
cd src; \
|
||||
strip keydb-cli keydb-benchmark keydb-check-rdb keydb-check-aof keydb-diagnostic-tool keydb-sentinel keydb-server; \
|
||||
mv keydb-server keydb-cli keydb-benchmark keydb-check-rdb keydb-check-aof keydb-diagnostic-tool keydb-sentinel /usr/local/bin/; \
|
||||
@@ -54,6 +54,7 @@ RUN set -eux; \
|
||||
sed -i 's/^\(logfile .*\)$/# \1/' /etc/keydb/keydb.conf; \
|
||||
sed -i 's/protected-mode yes/protected-mode no/g' /etc/keydb/keydb.conf; \
|
||||
sed -i 's/^\(bind .*\)$/# \1/' /etc/keydb/keydb.conf; \
|
||||
cd /usr/local/bin; \
|
||||
ln -s keydb-cli redis-cli; \
|
||||
cd /etc/keydb; \
|
||||
ln -s keydb.conf redis.conf; \
|
||||
@@ -67,6 +68,10 @@ RUN set -eux; \
|
||||
echo 'if [ "${1#-}" != "$1" ] || [ "${1%.conf}" != "$1" ]; then' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||
echo ' set -- keydb-server "$@"' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||
echo 'fi' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||
echo '# if KEYDB_PASSWORD is set, add it to the arguments' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||
echo 'if [ -n "$KEYDB_PASSWORD" ]; then' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||
echo ' set -- "$@" --requirepass "${KEYDB_PASSWORD}"' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||
echo 'fi' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||
echo "# allow the container to be started with `--user`" >> /usr/local/bin/docker-entrypoint.sh; \
|
||||
echo 'if [ "$1" = "keydb-server" -a "$(id -u)" = "0" ]; then' >> /usr/local/bin/docker-entrypoint.sh; \
|
||||
echo " find . \! -user keydb -exec chown keydb '{}' +" >> /usr/local/bin/docker-entrypoint.sh; \
|
||||
@@ -76,6 +81,6 @@ RUN set -eux; \
|
||||
chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||
VOLUME /data
|
||||
WORKDIR /data
|
||||
ENTRYPOINT ["docker-entrypoint.sh"]
|
||||
ENTRYPOINT ["tini", "--", "docker-entrypoint.sh"]
|
||||
EXPOSE 6379
|
||||
CMD ["keydb-server", "/etc/keydb/keydb.conf"]
|
||||
@@ -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
|
||||
|
||||
|
||||
+29
@@ -113,6 +113,8 @@ enum class AE_ASYNC_OP
|
||||
PostCppFunction,
|
||||
DeleteFileEvent,
|
||||
CreateFileEvent,
|
||||
PostAsynDBFunction,
|
||||
|
||||
};
|
||||
|
||||
struct aeCommand
|
||||
@@ -125,6 +127,8 @@ struct aeCommand
|
||||
aePostFunctionProc *proc;
|
||||
aeFileProc *fproc;
|
||||
std::function<void()> *pfn;
|
||||
aePostFunctionTokenProc* tproc;
|
||||
|
||||
};
|
||||
void *clientData;
|
||||
};
|
||||
@@ -175,6 +179,17 @@ void aeProcessCmd(aeEventLoop *eventLoop, int fd, void *, int )
|
||||
(*cmd.pfn)();
|
||||
|
||||
delete cmd.pfn;
|
||||
break;
|
||||
}
|
||||
case AE_ASYNC_OP::PostAsynDBFunction:
|
||||
{ //added to support async api IStorage
|
||||
if (cmd.fLock && !ulock.owns_lock()) {
|
||||
g_forkLock.releaseRead();
|
||||
ulock.lock();
|
||||
g_forkLock.acquireRead();
|
||||
}
|
||||
((aePostFunctionTokenProc*)cmd.tproc)(eventLoop,(StorageToken*)cmd.clientData);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -256,6 +271,20 @@ int aePostFunction(aeEventLoop *eventLoop, aePostFunctionProc *proc, void *arg)
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
int aePostFunction(aeEventLoop *eventLoop, aePostFunctionTokenProc *proc, StorageToken *token)
|
||||
{
|
||||
//added to support async api IStorage
|
||||
aeCommand cmd = {};
|
||||
cmd.op = AE_ASYNC_OP::PostAsynDBFunction;
|
||||
cmd.tproc = proc;
|
||||
cmd.clientData = (void*)token;
|
||||
cmd.fLock = true;
|
||||
auto size = write(eventLoop->fdCmdWrite, &cmd, sizeof(cmd));
|
||||
if (size != sizeof(cmd))
|
||||
return AE_ERR;
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
int aePostFunction(aeEventLoop *eventLoop, std::function<void()> fn, bool fLock, bool fForceQueue)
|
||||
{
|
||||
if (eventLoop == g_eventLoopThisThread && !fForceQueue)
|
||||
|
||||
@@ -72,13 +72,15 @@ extern "C" {
|
||||
#define AE_NOTUSED(V) ((void) V)
|
||||
|
||||
struct aeEventLoop;
|
||||
|
||||
/* Types and data structures */
|
||||
typedef void aeFileProc(struct aeEventLoop *eventLoop, int fd, void *clientData, int mask);
|
||||
typedef int aeTimeProc(struct aeEventLoop *eventLoop, long long id, void *clientData);
|
||||
typedef void aeEventFinalizerProc(struct aeEventLoop *eventLoop, void *clientData);
|
||||
typedef void aeBeforeSleepProc(struct aeEventLoop *eventLoop);
|
||||
typedef void aePostFunctionProc(void *pvArgs);
|
||||
//added to support async api IStorage
|
||||
struct StorageToken;
|
||||
typedef void aePostFunctionTokenProc(struct aeEventLoop *el, struct StorageToken *token);
|
||||
|
||||
/* File event structure */
|
||||
typedef struct aeFileEvent {
|
||||
@@ -134,6 +136,8 @@ int aePostFunction(aeEventLoop *eventLoop, aePostFunctionProc *proc, void *arg);
|
||||
#ifdef __cplusplus
|
||||
} // EXTERN C
|
||||
int aePostFunction(aeEventLoop *eventLoop, std::function<void()> fn, bool fLock = true, bool fForceQueue = false);
|
||||
//added to support async api IStorage
|
||||
int aePostFunction(aeEventLoop *eventLoop, aePostFunctionTokenProc *proc, StorageToken *token);
|
||||
extern "C" {
|
||||
#endif
|
||||
void aeDeleteEventLoop(aeEventLoop *eventLoop);
|
||||
|
||||
+1
-1
@@ -2946,7 +2946,7 @@ standardConfig configs[] = {
|
||||
createLongLongConfig("latency-monitor-threshold", NULL, MODIFIABLE_CONFIG, 0, LLONG_MAX, g_pserver->latency_monitor_threshold, 0, INTEGER_CONFIG, NULL, NULL),
|
||||
createLongLongConfig("proto-max-bulk-len", NULL, MODIFIABLE_CONFIG, 1024*1024, LLONG_MAX, g_pserver->proto_max_bulk_len, 512ll*1024*1024, MEMORY_CONFIG, NULL, NULL), /* Bulk request max size */
|
||||
createLongLongConfig("stream-node-max-entries", NULL, MODIFIABLE_CONFIG, 0, LLONG_MAX, g_pserver->stream_node_max_entries, 100, INTEGER_CONFIG, NULL, NULL),
|
||||
createLongLongConfig("repl-backlog-size", NULL, MODIFIABLE_CONFIG, 1, LLONG_MAX, g_pserver->repl_backlog_size, 1024*1024, MEMORY_CONFIG, NULL, updateReplBacklogSize), /* Default: 1mb */
|
||||
createLongLongConfig("repl-backlog-size", NULL, MODIFIABLE_CONFIG, 1, LLONG_MAX, g_pserver->repl_backlog_config_size, 1024*1024, MEMORY_CONFIG, NULL, updateReplBacklogSize), /* Default: 1mb */
|
||||
createLongLongConfig("repl-backlog-disk-reserve", NULL, IMMUTABLE_CONFIG, 0, LLONG_MAX, cserver.repl_backlog_disk_size, 0, MEMORY_CONFIG, NULL, NULL),
|
||||
createLongLongConfig("max-snapshot-slip", NULL, MODIFIABLE_CONFIG, 0, 5000, g_pserver->snapshot_slip, 400, 0, NULL, NULL),
|
||||
createLongLongConfig("max-rand-count", NULL, MODIFIABLE_CONFIG, 0, LONG_MAX/2, g_pserver->rand_total_threshold, LONG_MAX/2, 0, NULL, NULL),
|
||||
|
||||
@@ -19,6 +19,7 @@ static size_t getMemKey(std::string key) {
|
||||
}
|
||||
return 0;
|
||||
# else
|
||||
(void)key;
|
||||
return 0;
|
||||
# endif
|
||||
}
|
||||
|
||||
+1
-1
@@ -7058,7 +7058,7 @@ RedisModuleString *RM_DictPrev(RedisModuleCtx *ctx, RedisModuleDictIter *di, voi
|
||||
/* Compare the element currently pointed by the iterator to the specified
|
||||
* element given by key/keylen, according to the operator 'op' (the set of
|
||||
* valid operators are the same valid for RedisModule_DictIteratorStart).
|
||||
* If the comparision is successful the command returns REDISMODULE_OK
|
||||
* If the comparison is successful the command returns REDISMODULE_OK
|
||||
* otherwise REDISMODULE_ERR is returned.
|
||||
*
|
||||
* This is useful when we want to just emit a lexicographical range, so
|
||||
|
||||
+3
-3
@@ -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);
|
||||
}
|
||||
|
||||
+2
-2
@@ -3745,12 +3745,12 @@ retry_connect:
|
||||
}
|
||||
|
||||
/* Prepare a suitable temp file for bulk transfer */
|
||||
if (!useDisklessLoad()) {
|
||||
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);
|
||||
snprintf(tmpfile,sizeof(tmpfile),
|
||||
"temp-%d.%ld.rdb",(int)dtMillisecond.count(),(long int)getpid());
|
||||
"temp-%lld.%ld.rdb",(long long)dtMillisecond.count(),(long int)getpid());
|
||||
dfd = open(tmpfile,O_CREAT|O_WRONLY|O_EXCL,0644);
|
||||
if (dfd != -1) break;
|
||||
sleep(1);
|
||||
|
||||
+1
-1
@@ -7413,7 +7413,7 @@ static void validateConfiguration()
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
g_pserver->repl_backlog_config_size = g_pserver->repl_backlog_size; // this is normally set in the update logic, but not on initial config
|
||||
g_pserver->repl_backlog_size = g_pserver->repl_backlog_config_size; // this is normally set in the update logic, but not on initial config
|
||||
}
|
||||
|
||||
int iAmMaster(void) {
|
||||
|
||||
+1
-1
@@ -3924,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]]
|
||||
|
||||
+18
-12
@@ -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)
|
||||
@@ -144,12 +147,13 @@ void RocksDBStorageProvider::retrieve(const char *key, size_t cchKey, callbackSi
|
||||
size_t RocksDBStorageProvider::clear()
|
||||
{
|
||||
size_t celem = count();
|
||||
auto options = m_spdb->GetOptions(m_spcolfamily.get());
|
||||
auto status = m_spdb->DropColumnFamily(m_spcolfamily.get());
|
||||
auto strName = m_spcolfamily->GetName();
|
||||
|
||||
rocksdb::ColumnFamilyHandle *handle = nullptr;
|
||||
rocksdb::ColumnFamilyOptions cf_options(m_pfactory->RocksDbOptions());
|
||||
cf_options.level_compaction_dynamic_level_bytes = true;
|
||||
rocksdb::ColumnFamilyOptions cf_options(options);
|
||||
|
||||
m_spdb->CreateColumnFamily(cf_options, strName, &handle);
|
||||
m_spcolfamily = std::shared_ptr<rocksdb::ColumnFamilyHandle>(handle);
|
||||
|
||||
@@ -183,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;
|
||||
}
|
||||
@@ -202,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");
|
||||
@@ -226,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));
|
||||
@@ -240,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))
|
||||
@@ -277,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()));
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -2036,7 +2036,7 @@ struct zsetopsrc {
|
||||
zset *zs;
|
||||
zskiplistNode *node;
|
||||
} sl;
|
||||
} zset;
|
||||
} iterzset;
|
||||
} iter;
|
||||
};
|
||||
|
||||
@@ -2085,7 +2085,7 @@ void zuiInitIterator(zsetopsrc *op) {
|
||||
/* Sorted sets are traversed in reverse order to optimize for
|
||||
* the insertion of the elements in a new list as in
|
||||
* ZDIFF/ZINTER/ZUNION */
|
||||
iterzset *it = (iterzset*)&op->iter.zset;
|
||||
iterzset *it = (iterzset*)&op->iter.iterzset;
|
||||
if (op->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||
it->zl.zl = (unsigned char*)op->subject->m_ptr;
|
||||
it->zl.eptr = ziplistIndex(it->zl.zl,-2);
|
||||
@@ -2118,7 +2118,7 @@ void zuiClearIterator(zsetopsrc *op) {
|
||||
serverPanic("Unknown set encoding");
|
||||
}
|
||||
} else if (op->type == OBJ_ZSET) {
|
||||
iterzset *it = &op->iter.zset;
|
||||
iterzset *it = &op->iter.iterzset;
|
||||
if (op->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||
UNUSED(it); /* skip */
|
||||
} else if (op->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||
@@ -2194,7 +2194,7 @@ int zuiNext(zsetopsrc *op, zsetopval *val) {
|
||||
serverPanic("Unknown set encoding");
|
||||
}
|
||||
} else if (op->type == OBJ_ZSET) {
|
||||
iterzset *it = &op->iter.zset;
|
||||
iterzset *it = &op->iter.iterzset;
|
||||
if (op->encoding == OBJ_ENCODING_ZIPLIST) {
|
||||
/* No need to check both, but better be explicit. */
|
||||
if (it->zl.eptr == NULL || it->zl.sptr == NULL)
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
Reference in new issue
Block a user