Compare commits

..
Author SHA1 Message Date
Malavan Sotheeswaran 6f7beb405f make connectWithMaster error message less confusing 2023-03-07 01:04:56 -08:00
33 changed files with 141 additions and 519 deletions

No files matched your search

-53
View File
@@ -1,53 +0,0 @@
# Doc: https://wiki.sc-corp.net/pages/viewpage.action?pageId=121500284
version: 1
machamp:
keydb-build:
# Optional - build counter is linked to the build def
tag_template: 0.0.%build.counter%
# Optional - value in seconds before a build is terminated, default is 3600 seconds
timeout: 3600
# Optional - update ghe or not, default to true
update_ghe: true
code_coverage: false
# Required
steps:
make-build:
type: cmd
# 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: ./machamp_scripts/build.sh
tls-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 --clients 4 --verbose
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
sentinel-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-sentinel
module-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-moduleapi
rotation-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-rotation
keyproxy-test:
type: cmd
parent: make-build
command: ./runtest-keyproxy --tls
builder_image: us.gcr.io/snapchat-build-artifacts/prod/snapchat/img/keydb/keydb-ubuntu-20-04@sha256:cf869a3f5d1de1e1d976bb906689c37b7031938eb68661b844a38c532f27248c
-16
View File
@@ -1,16 +0,0 @@
# Doc: https://wiki.sc-corp.net/display/TOOL/ci.yaml+User+Guide
version: 1
on:
pull_request:
- workflows:
# All builds that use machamp should use the defined `backend_workflow`
- workflow_type: backend_workflow
# references a build defined in build.yaml
build_name: keydb-build
arch_types: ["amd64", "arm64"]
push:
- branches: [main]
workflows:
- workflow_type: backend_workflow
build_name: keydb-build
arch_types: ["amd64", "arm64"]
-8
View File
@@ -1,8 +0,0 @@
#!/bin/bash
# make the build
git submodule init && git submodule update
make BUILD_TLS=yes -j$(nproc) KEYDB_CFLAGS='-Werror' KEYDB_CXXFLAGS='-Werror'
# gen-cert
./utils/gen-test-certs.sh
-1
View File
@@ -31,7 +31,6 @@ public:
virtual void retrieve(const char *key, size_t cchKey, callbackSingle fn) const = 0;
virtual size_t clear() = 0;
virtual bool enumerate(callback fn) const = 0;
virtual bool enumerate_hashslot(callback fn, unsigned int hashslot) const = 0;
virtual size_t count() const = 0;
virtual void bulkInsert(char **rgkeys, size_t *rgcbkeys, char **rgvals, size_t *rgcbvals, size_t celem) {
+1 -9
View File
@@ -145,9 +145,7 @@ FINAL_LDFLAGS=$(LDFLAGS) $(KEYDB_LDFLAGS) $(DEBUG)
FINAL_LIBS+=-lm -lz -lcrypto -lbz2 -lzstd -llz4 -lsnappy
ifneq ($(uname_S),Darwin)
ifneq ($(uname_S),FreeBSD)
FINAL_LIBS+=-latomic
endif
endif
# Linux ARM32 needs -latomic at linking time
ifneq (,$(findstring armv,$(uname_M)))
@@ -213,13 +211,7 @@ ifeq ($(uname_S),NetBSD)
else
ifeq ($(uname_S),FreeBSD)
# FreeBSD
FINAL_LIBS+= -lpthread -luuid -lexecinfo
FINAL_CFLAGS+= -I/usr/local/include
FINAL_CXXFLAGS+= -I/usr/local/include
FINAL_LDFLAGS+= -L/usr/local/lib
ifeq ($(USE_BACKTRACE),yes)
FINAL_CFLAGS+= -DUSE_BACKTRACE
endif
FINAL_LIBS+= -lpthread -lexecinfo
else
ifeq ($(uname_S),DragonFly)
# DragonFly
+1 -1
View File
@@ -140,7 +140,7 @@ void SnapshotPayloadParseState::flushQueuedKeys() {
auto &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());
g_pserver->db[idb]->bulkStorageInsert(vecqueuedKeys.data(), vecqueuedKeysCb.data(), vecqueuedVals.data(), vecqueuedValsCb.data(), vecqueuedKeys.size());
--insertsInFlightTmp;
delete pallocator;
});
+1 -1
View File
@@ -21,7 +21,7 @@ dictType dbStorageCacheType = {
StorageCache::StorageCache(IStorage *storage, bool fCache)
: m_spstorage(storage)
{
if (!g_pserver->flash_disable_key_cache && fCache)
if (fCache)
m_pdict = dictCreate(&dbStorageCacheType, nullptr);
}
-1
View File
@@ -49,7 +49,6 @@ public:
void expand(uint64_t slots);
bool enumerate(IStorage::callback fn) const { return m_spstorage->enumerate(fn); }
bool enumerate_hashslot(IStorage::callback fn, unsigned int hashslot) const { return m_spstorage->enumerate_hashslot(fn, hashslot); }
void beginWriteBatch();
void endWriteBatch() { m_spstorage->endWriteBatch(); }
+1 -31
View File
@@ -35,7 +35,6 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#ifdef __linux__
#include <sys/sysinfo.h>
#endif
@@ -2457,32 +2456,6 @@ static int isValidAOFfilename(char *val, const char **err) {
return 1;
}
static int isValidS3Bucket(char *s3bucket, const char **err) {
int status = EXIT_FAILURE;
pid_t pid = fork();
if (pid < 0)
{
*err = "couldn't fork to call aws cli";
return 0;
}
if (pid == 0)
{
execlp("aws", "aws", "s3", "ls", s3bucket);
exit(EXIT_FAILURE);
}
else
{
waitpid(pid, &status, 0);
}
if (status != EXIT_SUCCESS) {
*err = "could not access s3 bucket";
return 0;
}
return 1;
}
/* Validate specified string is a valid proc-title-template */
static int isValidProcTitleTemplate(char *val, const char **err) {
if (!validateProcTitleTemplate(val)) {
@@ -2806,7 +2779,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("use-fork", NULL, IMMUTABLE_CONFIG, cserver.fForkBgSave, 1, NULL, NULL),
createBoolConfig("use-fork", NULL, IMMUTABLE_CONFIG, cserver.fForkBgSave, 0, NULL, NULL),
createBoolConfig("io-threads-do-reads", NULL, IMMUTABLE_CONFIG, fDummy, 0, NULL, NULL),
createBoolConfig("time-thread-priority", NULL, IMMUTABLE_CONFIG, cserver.time_thread_priority, 0, NULL, NULL),
createBoolConfig("prefetch-enabled", NULL, MODIFIABLE_CONFIG, g_pserver->prefetch_enabled, 1, NULL, NULL),
@@ -2830,7 +2803,6 @@ standardConfig configs[] = {
createStringConfig("cluster-announce-ip", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, g_pserver->cluster_announce_ip, NULL, NULL, NULL),
createStringConfig("syslog-ident", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, g_pserver->syslog_ident, "redis", NULL, NULL),
createStringConfig("dbfilename", NULL, MODIFIABLE_CONFIG, ALLOW_EMPTY_STRING, g_pserver->rdb_filename, CONFIG_DEFAULT_RDB_FILENAME, isValidDBfilename, NULL),
createStringConfig("db-s3-object", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, g_pserver->rdb_s3bucketpath, NULL, isValidS3Bucket, NULL),
createStringConfig("appendfilename", NULL, IMMUTABLE_CONFIG, ALLOW_EMPTY_STRING, g_pserver->aof_filename, "appendonly.aof", isValidAOFfilename, NULL),
createStringConfig("server_cpulist", NULL, IMMUTABLE_CONFIG, EMPTY_STRING_IS_NULL, g_pserver->server_cpulist, NULL, NULL, NULL),
createStringConfig("bio_cpulist", NULL, IMMUTABLE_CONFIG, EMPTY_STRING_IS_NULL, g_pserver->bio_cpulist, NULL, NULL, NULL),
@@ -2912,7 +2884,6 @@ standardConfig configs[] = {
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-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),
/* Unsigned Long Long configs */
createULongLongConfig("maxmemory", NULL, MODIFIABLE_CONFIG, 0, LLONG_MAX, g_pserver->maxmemory, 0, MEMORY_CONFIG, NULL, updateMaxmemory),
@@ -2940,7 +2911,6 @@ standardConfig configs[] = {
createBoolConfig("allow-write-during-load", NULL, MODIFIABLE_CONFIG, g_pserver->fWriteDuringActiveLoad, 0, NULL, NULL),
createBoolConfig("force-backlog-disk-reserve", NULL, MODIFIABLE_CONFIG, cserver.force_backlog_disk, 0, NULL, NULL),
createBoolConfig("soft-shutdown", NULL, MODIFIABLE_CONFIG, g_pserver->config_soft_shutdown, 0, NULL, NULL),
createBoolConfig("flash-disable-key-cache", NULL, MODIFIABLE_CONFIG, g_pserver->flash_disable_key_cache, 0, NULL, NULL),
createSizeTConfig("semi-ordered-set-bucket-size", NULL, MODIFIABLE_CONFIG, 0, 1024, g_semiOrderedSetTargetBucketSize, 0, INTEGER_CONFIG, NULL, NULL),
#ifdef USE_OPENSSL
+57 -109
View File
@@ -1737,9 +1737,6 @@ int dbSwapDatabases(int id1, int id2) {
id2 < 0 || id2 >= cserver.dbnum) return C_ERR;
if (id1 == id2) return C_OK;
std::swap(g_pserver->db[id1], g_pserver->db[id2]);
//swap db's id too, otherwise db does not match its id
std::swap(g_pserver->db[id1]->id, g_pserver->db[id2]->id);
/* Note that we don't swap blocking_keys,
* ready_keys and watched_keys, since we want clients to
@@ -1769,7 +1766,7 @@ int dbSwapDatabases(int id1, int id2) {
/* SWAPDB db1 db2 */
void swapdbCommand(client *c) {
int id1, id2, oriId;
int id1, id2;
/* Not allowed in cluster mode: we have just DB 0 there. */
if (g_pserver->cluster_enabled) {
@@ -1786,9 +1783,6 @@ void swapdbCommand(client *c) {
"invalid second DB index") != C_OK)
return;
//get client's original db's id
oriId=c->db->id;
/* Swap... */
if (dbSwapDatabases(id1,id2) == C_ERR) {
addReplyError(c,"DB index is out of range");
@@ -1797,10 +1791,6 @@ void swapdbCommand(client *c) {
RedisModuleSwapDbInfo si = {REDISMODULE_SWAPDBINFO_VERSION,(int32_t)id1,(int32_t)id2};
moduleFireServerEvent(REDISMODULE_EVENT_SWAPDB,0,&si);
g_pserver->dirty++;
//set client's db to original db
c->db=g_pserver->db[oriId];
addReply(c,shared.ok);
}
}
@@ -1941,7 +1931,6 @@ void setExpire(client *c, redisDb *db, robj *key, expireEntry &&e)
* is associated with this key (i.e. the key is non volatile) */
expireEntry *redisDbPersistentDataSnapshot::getExpire(const char *key) {
/* No expire? return ASAP */
std::unique_lock<fastlock> ul(g_expireLock);
if (expireSize() == 0)
return nullptr;
@@ -2490,28 +2479,25 @@ void slotToKeyUpdateKeyCore(const char *key, size_t keylen, int add) {
serverAssert(GlobalLocksAcquired());
unsigned int hashslot = keyHashSlot(key,keylen);
unsigned char buf[64];
unsigned char *indexed = buf;
g_pserver->cluster->slots_keys_count[hashslot] += add ? 1 : -1;
if (g_pserver->m_pstorageFactory == nullptr) {
unsigned char buf[64];
unsigned char *indexed = buf;
if (keylen+2 > 64) indexed = (unsigned char*)zmalloc(keylen+2, MALLOC_SHARED);
indexed[0] = (hashslot >> 8) & 0xff;
indexed[1] = hashslot & 0xff;
memcpy(indexed+2,key,keylen);
int fModified = false;
if (add) {
fModified = raxInsert(g_pserver->cluster->slots_to_keys,indexed,keylen+2,NULL,NULL);
} else {
fModified = raxRemove(g_pserver->cluster->slots_to_keys,indexed,keylen+2,NULL);
}
// This assert is disabled when a snapshot depth is >0 because prepOverwriteForSnapshot will add in a tombstone,
// this prevents ensure from adding the key to the dictionary which means the caller isn't aware we're already tracking
// the key.
serverAssert(fModified || g_pserver->db[0]->snapshot_depth() > 0);
if (indexed != buf) zfree(indexed);
if (keylen+2 > 64) indexed = (unsigned char*)zmalloc(keylen+2, MALLOC_SHARED);
indexed[0] = (hashslot >> 8) & 0xff;
indexed[1] = hashslot & 0xff;
memcpy(indexed+2,key,keylen);
int fModified = false;
if (add) {
fModified = raxInsert(g_pserver->cluster->slots_to_keys,indexed,keylen+2,NULL,NULL);
} else {
fModified = raxRemove(g_pserver->cluster->slots_to_keys,indexed,keylen+2,NULL);
}
// This assert is disabled when a snapshot depth is >0 because prepOverwriteForSnapshot will add in a tombstone,
// this prevents ensure from adding the key to the dictionary which means the caller isn't aware we're already tracking
// the key.
serverAssert(fModified || g_pserver->db[0]->snapshot_depth() > 0);
if (indexed != buf) zfree(indexed);
}
void slotToKeyAdd(sds key) {
@@ -2547,67 +2533,47 @@ void slotToKeyFlush(int async) {
* New objects are returned to represent keys, it's up to the caller to
* decrement the reference count to release the keys names. */
unsigned int getKeysInSlot(unsigned int hashslot, robj **keys, unsigned int count) {
if (g_pserver->m_pstorageFactory != nullptr) {
int j = 0;
g_pserver->db[0]->getStorageCache()->enumerate_hashslot([&](const char *key, size_t cchKey, const void *, size_t )->bool {
keys[j++] = createStringObject(key, cchKey);
return --count;
}, hashslot);
return j;
} else {
raxIterator iter;
int j = 0;
unsigned char indexed[2];
raxIterator iter;
int j = 0;
unsigned char indexed[2];
indexed[0] = (hashslot >> 8) & 0xff;
indexed[1] = hashslot & 0xff;
raxStart(&iter,g_pserver->cluster->slots_to_keys);
raxSeek(&iter,">=",indexed,2);
while(count-- && raxNext(&iter)) {
if (iter.key[0] != indexed[0] || iter.key[1] != indexed[1]) break;
keys[j++] = createStringObject((char*)iter.key+2,iter.key_len-2);
}
raxStop(&iter);
return j;
indexed[0] = (hashslot >> 8) & 0xff;
indexed[1] = hashslot & 0xff;
raxStart(&iter,g_pserver->cluster->slots_to_keys);
raxSeek(&iter,">=",indexed,2);
while(count-- && raxNext(&iter)) {
if (iter.key[0] != indexed[0] || iter.key[1] != indexed[1]) break;
keys[j++] = createStringObject((char*)iter.key+2,iter.key_len-2);
}
raxStop(&iter);
return j;
}
/* Remove all the keys in the specified hash slot.
* The number of removed items is returned. */
unsigned int delKeysInSlot(unsigned int hashslot) {
serverAssert(GlobalLocksAcquired());
if (g_pserver->m_pstorageFactory != nullptr) {
int j = 0;
g_pserver->db[0]->getStorageCache()->enumerate_hashslot([&](const char *key, size_t cchKey, const void *, size_t )->bool {
robj *keyobj = createStringObject(key, cchKey);
dbDelete(g_pserver->db[0], keyobj);
decrRefCount(keyobj);
j++;
return true;
}, hashslot);
return j;
} else {
raxIterator iter;
int j = 0;
unsigned char indexed[2];
raxIterator iter;
int j = 0;
unsigned char indexed[2];
indexed[0] = (hashslot >> 8) & 0xff;
indexed[1] = hashslot & 0xff;
raxStart(&iter,g_pserver->cluster->slots_to_keys);
while(g_pserver->cluster->slots_keys_count[hashslot]) {
raxSeek(&iter,">=",indexed,2);
raxNext(&iter);
indexed[0] = (hashslot >> 8) & 0xff;
indexed[1] = hashslot & 0xff;
raxStart(&iter,g_pserver->cluster->slots_to_keys);
while(g_pserver->cluster->slots_keys_count[hashslot]) {
raxSeek(&iter,">=",indexed,2);
raxNext(&iter);
auto count = g_pserver->cluster->slots_keys_count[hashslot];
robj *key = createStringObject((char*)iter.key+2,iter.key_len-2);
dbDelete(g_pserver->db[0],key);
serverAssert(count > g_pserver->cluster->slots_keys_count[hashslot]); // we should have deleted something or we will be in an infinite loop
decrRefCount(key);
j++;
}
raxStop(&iter);
return j;
auto count = g_pserver->cluster->slots_keys_count[hashslot];
robj *key = createStringObject((char*)iter.key+2,iter.key_len-2);
dbDelete(g_pserver->db[0],key);
serverAssert(count > g_pserver->cluster->slots_keys_count[hashslot]); // we should have deleted something or we will be in an infinite loop
decrRefCount(key);
j++;
}
raxStop(&iter);
return j;
}
unsigned int countKeysInSlot(unsigned int hashslot) {
@@ -2641,15 +2607,12 @@ void clusterStorageLoadCallback(const char *rgchkey, size_t cch, void *)
slotToKeyUpdateKeyCore(rgchkey, cch, true /*add*/);
}
void moduleLoadCallback(const char * rgchKey, size_t, void *data) {
redisObjectStack keyobj;
initStaticStringObject(keyobj, const_cast<char *>(rgchKey));
moduleNotifyKeyspaceEvent(NOTIFY_LOADED, "loaded", &keyobj, *(int *)data);
}
void moduleClusterLoadCallback(const char * rgchKey, size_t cchKey, void *data) {
clusterStorageLoadCallback(rgchKey, cchKey, data);
moduleLoadCallback(rgchKey, cchKey, data);
void moduleLoadCallback(const char * rgchKey, size_t cchKey, void *data) {
if (g_pserver->cluster_enabled) {
clusterStorageLoadCallback(rgchKey, cchKey, data);
}
robj *keyobj = createEmbeddedStringObject(rgchKey, cchKey);
moduleNotifyKeyspaceEvent(NOTIFY_LOADED, "loaded", keyobj, *(int *)data);
}
void redisDb::initialize(int id)
@@ -2670,7 +2633,7 @@ void redisDb::storageProviderInitialize()
{
if (g_pserver->m_pstorageFactory != nullptr)
{
IStorageFactory::key_load_iterator itr = g_pserver->cluster_enabled ? moduleClusterLoadCallback : moduleLoadCallback;
IStorageFactory::key_load_iterator itr = moduleLoadCallback;
this->setStorageProvider(StorageCache::create(g_pserver->m_pstorageFactory, id, itr, &id));
}
}
@@ -2761,11 +2724,8 @@ void redisDbPersistentData::clear(void(callback)(void*))
m_cnewKeysPending = 0;
m_fAllChanged++;
}
{
std::unique_lock<fastlock> ul(g_expireLock);
delete m_setexpire;
m_setexpire = new (MALLOC_LOCAL) expireset();
}
if (m_spstorage != nullptr)
m_spstorage->clear(callback);
dictEmpty(m_pdictTombstone,callback);
@@ -2898,8 +2858,7 @@ LNotFound:
{
dictAdd(m_pdict, sdsNewKey, o);
o->SetFExpires(spexpire != nullptr);
std::unique_lock<fastlock> ul(g_expireLock);
if (spexpire != nullptr)
{
auto itr = m_setexpire->find(sdsKey);
@@ -2922,7 +2881,6 @@ LNotFound:
if (*pde != nullptr && dictGetVal(*pde) != nullptr)
{
robj *o = (robj*)dictGetVal(*pde);
std::unique_lock<fastlock> ul(g_expireLock);
serverAssert(o->FExpires() == (m_setexpire->find(sdsKey) != m_setexpire->end()));
}
}
@@ -3044,16 +3002,8 @@ void redisDbPersistentData::processChangesAsync(std::atomic<int> &pendingJobs)
});
}
/* This function is to bulk insert directly to storage provider bypassing in memory, assumes rgKeys and rgVals are not sds strings */
void redisDbPersistentData::bulkDirectStorageInsert(char **rgKeys, size_t *rgcbKeys, char **rgVals, size_t *rgcbVals, size_t celem)
void redisDbPersistentData::bulkStorageInsert(char **rgKeys, size_t *rgcbKeys, char **rgVals, size_t *rgcbVals, size_t celem)
{
if (g_pserver->cluster_enabled) {
aeAcquireLock();
for (size_t i = 0; i < celem; i++) {
slotToKeyUpdateKeyCore(rgKeys[i], rgcbKeys[i], 1);
}
aeReleaseLock();
}
m_spstorage->bulkInsert(rgKeys, rgcbKeys, rgVals, rgcbVals, celem);
}
@@ -3295,7 +3245,6 @@ std::unique_ptr<expireEntry> deserializeExpire(sds key, const char *str, size_t
sds serializeStoredObjectAndExpire(redisDbPersistentData *db, const char *key, robj_roptr o)
{
std::unique_lock<fastlock> ul(g_expireLock);
auto itrExpire = db->setexpire()->find(key);
const expireEntry *pexpire = nullptr;
if (itrExpire != db->setexpire()->end())
@@ -3420,7 +3369,6 @@ void redisDbPersistentData::prefetchKeysAsync(client *c, parsed_command &command
dictAdd(m_pdict, sharedKey, o);
o->SetFExpires(spexpire != nullptr);
std::unique_lock<fastlock> ul(g_expireLock);
if (spexpire != nullptr)
{
auto itr = m_setexpire->find(sharedKey);
+1 -2
View File
@@ -380,7 +380,7 @@ size_t freeMemoryGetNotCountedMemory(void) {
/* also don't count the replication backlog memory
* that's where the replication clients get their memory from */
overhead += g_pserver->repl_backlog_size - g_pserver->repl_backlog_config_size;
overhead += g_pserver->repl_backlog_size;
if (g_pserver->aof_state != AOF_OFF) {
overhead += sdsalloc(g_pserver->aof_buf)+aofRewriteBufferSize();
@@ -771,7 +771,6 @@ int performEvictions(bool fPreSnapshot) {
if (db->removeCachedValue(bestkey, &deT)) {
mem_freed += splazy->addEntry(db->dictUnsafeKeyOnly(), deT);
ckeysFailed = 0;
g_pserver->stat_evictedkeys++;
}
else {
delta = 0;
-1
View File
@@ -481,7 +481,6 @@ void expireSlaveKeys(void) {
if (slaveKeysWithExpire == NULL ||
dictSize(slaveKeysWithExpire) == 0) return;
std::unique_lock<fastlock> ul(g_expireLock);
int cycles = 0, noexpire = 0;
mstime_t start = mstime();
while(1) {
-1
View File
@@ -1668,7 +1668,6 @@ robj *deserializeStoredObjectCore(const void *data, size_t cb)
robj *deserializeStoredObject(const redisDbPersistentData *db, const char *key, const void *data, size_t cb)
{
robj *o = deserializeStoredObjectCore(data, cb);
std::unique_lock<fastlock> ul(g_expireLock);
o->SetFExpires(db->setexpire()->exists(key));
return o;
}
+47 -120
View File
@@ -1334,7 +1334,7 @@ int rdbSaveRio(rio *rdb, const redisDbPersistentDataSnapshot **rgpdb, int *error
if (rdbSaveModulesAux(rdb, REDISMODULE_AUX_BEFORE_RDB) == -1) goto werr;
for (j = 0; j < cserver.dbnum; j++) {
const redisDbPersistentDataSnapshot *db = rgpdb != nullptr ? rgpdb[j] : g_pserver->db[j];
const redisDbPersistentDataSnapshot *db = rgpdb[j];
if (db->size() == 0) continue;
/* Write the SELECT DB opcode */
@@ -1715,7 +1715,7 @@ void getTempFileName(char tmpfile[], int tmpfileNum) {
char tmpfileNumString[214];
/* Generate temp rdb file name using aync-signal safe functions. */
int pid_len = ll2string(pid, sizeof(pid), g_pserver->in_fork_child ? getppid() : getpid());
int pid_len = ll2string(pid, sizeof(pid), getpid());
int tmpfileNum_len = ll2string(tmpfileNumString, sizeof(tmpfileNumString), tmpfileNum);
strcpy(tmpfile, "temp-");
strncpy(tmpfile+5, pid, pid_len);
@@ -3832,130 +3832,57 @@ int rdbSaveToSlavesSockets(rdbSaveInfo *rsi) {
}
/* Create the child process. */
if (cserver.fForkBgSave) {
pid_t childpid;
if ((childpid = redisFork(CHILD_TYPE_RDB)) == 0) {
/* Child */
int retval, dummy;
rio rdb;
openChildInfoPipe();
rioInitWithFd(&rdb,args->rdb_pipe_write);
for (int idb = 0; idb < cserver.dbnum; ++idb)
args->rgpdb[idb] = g_pserver->db[idb]->createSnapshot(getMvccTstamp(), false /*fOptional*/);
redisSetProcTitle("keydb-rdb-to-slaves");
redisSetCpuAffinity(g_pserver->bgsave_cpulist);
retval = rdbSaveRioWithEOFMark(&rdb,nullptr,nullptr,rsi);
if (retval == C_OK && rioFlush(&rdb) == 0)
retval = C_ERR;
if (retval == C_OK) {
sendChildCowInfo(CHILD_INFO_TYPE_RDB_COW_SIZE, "RDB");
}
rioFreeFd(&rdb);
/* wake up the reader, tell it we're done. */
close(args->rdb_pipe_write);
close(g_pserver->rdb_child_exit_pipe); /* close write end so that we can detect the close on the parent. */
/* hold exit until the parent tells us it's safe. we're not expecting
* to read anything, just get the error when the pipe is closed. */
dummy = read(args->safe_to_exit_pipe, pipefds, 1);
UNUSED(dummy);
exitFromChild((retval == C_OK) ? 0 : 1);
} else {
/* Parent */
close(args->safe_to_exit_pipe);
if (childpid == -1) {
serverLog(LL_WARNING,"Can't save in background: fork: %s",
strerror(errno));
/* Undo the state change. The caller will perform cleanup on
* all the slaves in BGSAVE_START state, but an early call to
* replicationSetupSlaveForFullResync() turned it into BGSAVE_END */
listRewind(g_pserver->slaves,&li);
while((ln = listNext(&li))) {
client *replica = (client*)ln->value;
if (replica->replstate == SLAVE_STATE_WAIT_BGSAVE_END) {
replica->replstate = SLAVE_STATE_WAIT_BGSAVE_START;
}
}
close(args->rdb_pipe_write);
close(g_pserver->rdb_pipe_read);
zfree(g_pserver->rdb_pipe_conns);
g_pserver->rdb_pipe_conns = NULL;
g_pserver->rdb_pipe_numconns = 0;
g_pserver->rdb_pipe_numconns_writing = 0;
args->rsi.~rdbSaveInfo();
zfree(args);
} else {
serverLog(LL_NOTICE,"Background RDB transfer started by pid %ld",
(long)childpid);
g_pserver->rdb_save_time_start = time(NULL);
g_pserver->rdb_child_type = RDB_CHILD_TYPE_SOCKET;
g_pserver->rdbThreadVars.fRdbThreadActive = true;
updateDictResizePolicy();
close(args->rdb_pipe_write); /* close write in parent so that it can detect the close on the child. */
aePostFunction(g_pserver->rgthreadvar[IDX_EVENT_LOOP_MAIN].el, []{
if (aeCreateFileEvent(serverTL->el, g_pserver->rdb_pipe_read, AE_READABLE, rdbPipeReadHandler, nullptr) == AE_ERR) {
serverPanic("Unrecoverable error creating g_pserver->rdb_pipe_read file event.");
}
});
}
return (childpid == -1) ? C_ERR : C_OK;
}
}
else {
openChildInfoPipe();
for (int idb = 0; idb < cserver.dbnum; ++idb)
args->rgpdb[idb] = g_pserver->db[idb]->createSnapshot(getMvccTstamp(), false /*fOptional*/);
g_pserver->rdbThreadVars.tmpfileNum++;
g_pserver->rdbThreadVars.fRdbThreadCancel = false;
pthread_attr_t tattr;
pthread_attr_init(&tattr);
pthread_attr_setstacksize(&tattr, 1 << 23); // 8 MB
if (pthread_create(&child, &tattr, rdbSaveToSlavesSocketsThread, args)) {
pthread_attr_destroy(&tattr);
serverLog(LL_WARNING,"Can't save in background: fork: %s",
strerror(errno));
/* Undo the state change. The caller will perform cleanup on
* all the slaves in BGSAVE_START state, but an early call to
* replicationSetupSlaveForFullResync() turned it into BGSAVE_END */
listRewind(g_pserver->slaves,&li);
while((ln = listNext(&li))) {
client *replica = (client*)ln->value;
if (replica->replstate == SLAVE_STATE_WAIT_BGSAVE_END) {
replica->replstate = SLAVE_STATE_WAIT_BGSAVE_START;
}
}
close(args->rdb_pipe_write);
close(g_pserver->rdb_pipe_read);
zfree(g_pserver->rdb_pipe_conns);
close(args->safe_to_exit_pipe);
g_pserver->rdb_pipe_conns = NULL;
g_pserver->rdb_pipe_numconns = 0;
g_pserver->rdb_pipe_numconns_writing = 0;
args->rsi.~rdbSaveInfo();
zfree(args);
closeChildInfoPipe();
return C_ERR;
}
g_pserver->rdbThreadVars.tmpfileNum++;
g_pserver->rdbThreadVars.fRdbThreadCancel = false;
pthread_attr_t tattr;
pthread_attr_init(&tattr);
pthread_attr_setstacksize(&tattr, 1 << 23); // 8 MB
if (pthread_create(&child, &tattr, rdbSaveToSlavesSocketsThread, args)) {
pthread_attr_destroy(&tattr);
g_pserver->child_type = CHILD_TYPE_RDB;
serverLog(LL_WARNING,"Can't save in background: fork: %s",
strerror(errno));
serverLog(LL_NOTICE,"Background RDB transfer started");
g_pserver->rdb_save_time_start = time(NULL);
serverAssert(!g_pserver->rdbThreadVars.fRdbThreadActive);
g_pserver->rdbThreadVars.rdb_child_thread = child;
g_pserver->rdbThreadVars.fRdbThreadActive = true;
g_pserver->rdb_child_type = RDB_CHILD_TYPE_SOCKET;
aePostFunction(g_pserver->rgthreadvar[IDX_EVENT_LOOP_MAIN].el, []{
if (aeCreateFileEvent(serverTL->el, g_pserver->rdb_pipe_read, AE_READABLE, rdbPipeReadHandler, nullptr) == AE_ERR) {
serverPanic("Unrecoverable error creating server.rdb_pipe_read file event.");
/* Undo the state change. The caller will perform cleanup on
* all the slaves in BGSAVE_START state, but an early call to
* replicationSetupSlaveForFullResync() turned it into BGSAVE_END */
listRewind(g_pserver->slaves,&li);
while((ln = listNext(&li))) {
client *replica = (client*)ln->value;
if (replica->replstate == SLAVE_STATE_WAIT_BGSAVE_END) {
replica->replstate = SLAVE_STATE_WAIT_BGSAVE_START;
}
});
}
close(args->rdb_pipe_write);
close(g_pserver->rdb_pipe_read);
zfree(g_pserver->rdb_pipe_conns);
close(args->safe_to_exit_pipe);
g_pserver->rdb_pipe_conns = NULL;
g_pserver->rdb_pipe_numconns = 0;
g_pserver->rdb_pipe_numconns_writing = 0;
args->rsi.~rdbSaveInfo();
zfree(args);
closeChildInfoPipe();
return C_ERR;
}
pthread_attr_destroy(&tattr);
g_pserver->child_type = CHILD_TYPE_RDB;
serverLog(LL_NOTICE,"Background RDB transfer started");
g_pserver->rdb_save_time_start = time(NULL);
serverAssert(!g_pserver->rdbThreadVars.fRdbThreadActive);
g_pserver->rdbThreadVars.rdb_child_thread = child;
g_pserver->rdbThreadVars.fRdbThreadActive = true;
g_pserver->rdb_child_type = RDB_CHILD_TYPE_SOCKET;
aePostFunction(g_pserver->rgthreadvar[IDX_EVENT_LOOP_MAIN].el, []{
if (aeCreateFileEvent(serverTL->el, g_pserver->rdb_pipe_read, AE_READABLE, rdbPipeReadHandler,NULL) == AE_ERR) {
serverPanic("Unrecoverable error creating server.rdb_pipe_read file event.");
}
});
return C_OK; /* Unreached. */
}
-3
View File
@@ -1264,9 +1264,6 @@ void scriptingInit(int setup) {
/* Finally set the table as 'redis' global var. */
lua_setglobal(lua,"redis");
/* Set table as 'keydb' global var as well */
lua_getglobal(lua,"redis");
lua_setglobal(lua,"keydb");
/* Replace math.random and math.randomseed with our implementations. */
lua_getglobal(lua,"math");
+1 -1
View File
@@ -5172,7 +5172,7 @@ int prepareForShutdown(int flags) {
* to unlink file actully) in background thread.
* The temp rdb file fd may won't be closed when redis exits quickly,
* but OS will close this fd when process exits. */
rdbRemoveTempFile(g_pserver->rdbThreadVars.tmpfileNum, 0);
rdbRemoveTempFile(g_pserver->child_pid, 0);
}
/* Kill module child if there is one. */
+2 -8
View File
@@ -1209,8 +1209,7 @@ public:
bool FSnapshot() const { return m_spdbSnapshotHOLDER != nullptr; }
std::unique_ptr<const StorageCache> CloneStorageCache() { return std::unique_ptr<const StorageCache>(m_spstorage->clone()); }
std::shared_ptr<StorageCache> getStorageCache() { return m_spstorage; }
void bulkDirectStorageInsert(char **rgKeys, size_t *rgcbKeys, char **rgVals, size_t *rgcbVals, size_t celem);
void bulkStorageInsert(char **rgKeys, size_t *rgcbKeys, char **rgVals, size_t *rgcbVals, size_t celem);
dict_iter find_cached_threadsafe(const char *key) const;
@@ -1371,8 +1370,7 @@ struct redisDb : public redisDbPersistentDataSnapshot
using redisDbPersistentData::FRehashing;
using redisDbPersistentData::FTrackingChanges;
using redisDbPersistentData::CloneStorageCache;
using redisDbPersistentData::getStorageCache;
using redisDbPersistentData::bulkDirectStorageInsert;
using redisDbPersistentData::bulkStorageInsert;
public:
const redisDbPersistentDataSnapshot *createSnapshot(uint64_t mvccCheckpoint, bool fOptional) {
@@ -2731,13 +2729,9 @@ struct redisServer {
long long repl_batch_offStart = -1;
long long repl_batch_idxStart = -1;
long long rand_total_threshold;
int config_soft_shutdown = false;
bool soft_shutdown = false;
int flash_disable_key_cache = false;
/* Lock Contention Ring Buffer */
static const size_t s_lockContentionSamples = 64;
uint16_t rglockSamples[s_lockContentionSamples];
+12 -55
View File
@@ -3,8 +3,6 @@
#include <sstream>
#include <mutex>
#include <unistd.h>
#include "../server.h"
#include "../cluster.h"
#include "rocksdbfactor_internal.h"
static const char keyprefix[] = INTERNAL_KEY_PREFIX;
@@ -22,17 +20,6 @@ bool FInternalKey(const char *key, size_t cch)
return false;
}
std::string getPrefix(unsigned int hashslot)
{
char *hash_char = (char *)&hashslot;
return std::string(hash_char + (sizeof(unsigned int) - 2), 2);
}
std::string prefixKey(const char *key, size_t cchKey)
{
return FInternalKey(key, cchKey) ? std::string(key, cchKey) : getPrefix(keyHashSlot(key, cchKey)) + std::string(key, cchKey);
}
RocksDBStorageProvider::RocksDBStorageProvider(RocksDBStorageFactory *pfactory, std::shared_ptr<rocksdb::DB> &spdb, std::shared_ptr<rocksdb::ColumnFamilyHandle> &spcolfam, const rocksdb::Snapshot *psnapshot, size_t count)
: m_pfactory(pfactory), m_spdb(spdb), m_psnapshot(psnapshot), m_spcolfamily(spcolfam), m_count(count)
{
@@ -45,11 +32,10 @@ void RocksDBStorageProvider::insert(const char *key, size_t cchKey, void *data,
{
rocksdb::Status status;
std::unique_lock<fastlock> l(m_lock);
std::string prefixed_key = prefixKey(key, cchKey);
if (m_spbatch != nullptr)
status = m_spbatch->Put(m_spcolfamily.get(), rocksdb::Slice(prefixed_key), rocksdb::Slice((const char*)data, cb));
status = m_spbatch->Put(m_spcolfamily.get(), rocksdb::Slice(key, cchKey), rocksdb::Slice((const char*)data, cb));
else
status = m_spdb->Put(WriteOptions(), m_spcolfamily.get(), rocksdb::Slice(prefixed_key), rocksdb::Slice((const char*)data, cb));
status = m_spdb->Put(WriteOptions(), m_spcolfamily.get(), rocksdb::Slice(key, cchKey), rocksdb::Slice((const char*)data, cb));
if (!status.ok())
throw status.ToString();
@@ -73,8 +59,7 @@ void RocksDBStorageProvider::bulkInsert(char **rgkeys, size_t *rgcbkeys, char **
// Insert rows into the SST file, note that inserted keys must be
// strictly increasing (based on options.comparator)
for (size_t ielem = 0; ielem < celem; ++ielem) {
std::string prefixed_key = prefixKey(rgkeys[ielem], rgcbkeys[ielem]);
s = sst_file_writer.Put(rocksdb::Slice(prefixed_key), rocksdb::Slice(rgvals[ielem], rgcbvals[ielem]));
s = sst_file_writer.Put(rocksdb::Slice(rgkeys[ielem], rgcbkeys[ielem]), rocksdb::Slice(rgvals[ielem], rgcbvals[ielem]));
if (!s.ok()) {
unlink(file_path.c_str());
goto LFallback;
@@ -102,8 +87,7 @@ void RocksDBStorageProvider::bulkInsert(char **rgkeys, size_t *rgcbkeys, char **
LFallback:
auto spbatch = std::make_unique<rocksdb::WriteBatch>();
for (size_t ielem = 0; ielem < celem; ++ielem) {
std::string prefixed_key = prefixKey(rgkeys[ielem], rgcbkeys[ielem]);
spbatch->Put(m_spcolfamily.get(), rocksdb::Slice(prefixed_key), rocksdb::Slice(rgvals[ielem], rgcbvals[ielem]));
spbatch->Put(m_spcolfamily.get(), rocksdb::Slice(rgkeys[ielem], rgcbkeys[ielem]), rocksdb::Slice(rgvals[ielem], rgcbvals[ielem]));
}
m_spdb->Write(WriteOptions(), spbatch.get());
}
@@ -116,16 +100,15 @@ bool RocksDBStorageProvider::erase(const char *key, size_t cchKey)
{
rocksdb::Status status;
std::unique_lock<fastlock> l(m_lock);
std::string prefixed_key = prefixKey(key, cchKey);
if (!FKeyExists(prefixed_key))
if (!FKeyExists(key, cchKey))
return false;
if (m_spbatch != nullptr)
{
status = m_spbatch->Delete(m_spcolfamily.get(), rocksdb::Slice(prefixed_key));
status = m_spbatch->Delete(m_spcolfamily.get(), rocksdb::Slice(key, cchKey));
}
else
{
status = m_spdb->Delete(WriteOptions(), m_spcolfamily.get(), rocksdb::Slice(prefixed_key));
status = m_spdb->Delete(WriteOptions(), m_spcolfamily.get(), rocksdb::Slice(key, cchKey));
}
if (status.ok())
--m_count;
@@ -135,8 +118,7 @@ bool RocksDBStorageProvider::erase(const char *key, size_t cchKey)
void RocksDBStorageProvider::retrieve(const char *key, size_t cchKey, callbackSingle fn) const
{
rocksdb::PinnableSlice slice;
std::string prefixed_key = prefixKey(key, cchKey);
auto status = m_spdb->Get(ReadOptions(), m_spcolfamily.get(), rocksdb::Slice(prefixed_key), &slice);
auto status = m_spdb->Get(ReadOptions(), m_spcolfamily.get(), rocksdb::Slice(key, cchKey), &slice);
if (status.ok())
fn(key, cchKey, slice.data(), slice.size());
}
@@ -172,7 +154,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(), it->key().size(), it->value().data(), it->value().size());
if (!fContinue)
break;
}
@@ -186,31 +168,6 @@ bool RocksDBStorageProvider::enumerate(callback fn) const
return !it->Valid();
}
bool RocksDBStorageProvider::enumerate_hashslot(callback fn, unsigned int hashslot) const
{
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()) {
if (FInternalKey(it->key().data(), it->key().size()))
continue;
if (strncmp(it->key().data(),prefix.c_str(),2) != 0)
break;
++count;
bool fContinue = fn(it->key().data()+2, it->key().size()-2, it->value().data(), it->value().size());
if (!fContinue)
break;
}
bool full_iter = !it->Valid() || (strncmp(it->key().data(),prefix.c_str(),2) != 0);
if (full_iter && count != g_pserver->cluster->slots_keys_count[hashslot])
{
printf("WARNING: rocksdb hashslot count mismatch");
}
assert(!full_iter || count == g_pserver->cluster->slots_keys_count[hashslot]);
assert(it->status().ok()); // Check for any errors found during the scan
return full_iter;
}
const IStorage *RocksDBStorageProvider::clone() const
{
std::unique_lock<fastlock> l(m_lock);
@@ -270,10 +227,10 @@ void RocksDBStorageProvider::flush()
m_spdb->SyncWAL();
}
bool RocksDBStorageProvider::FKeyExists(std::string& key) const
bool RocksDBStorageProvider::FKeyExists(const char *key, size_t cch) const
{
rocksdb::PinnableSlice slice;
if (m_spbatch)
return m_spbatch->GetFromBatchAndDB(m_spdb.get(), ReadOptions(), m_spcolfamily.get(), rocksdb::Slice(key), &slice).ok();
return m_spdb->Get(ReadOptions(), m_spcolfamily.get(), rocksdb::Slice(key), &slice).ok();
return m_spbatch->GetFromBatchAndDB(m_spdb.get(), ReadOptions(), m_spcolfamily.get(), rocksdb::Slice(key, cch), &slice).ok();
return m_spdb->Get(ReadOptions(), m_spcolfamily.get(), rocksdb::Slice(key, cch), &slice).ok();
}
+1 -2
View File
@@ -32,7 +32,6 @@ public:
virtual void retrieve(const char *key, size_t cchKey, callbackSingle fn) const override;
virtual size_t clear() override;
virtual bool enumerate(callback fn) const override;
virtual bool enumerate_hashslot(callback fn, unsigned int hashslot) const override;
virtual const IStorage *clone() const override;
@@ -49,7 +48,7 @@ public:
size_t count() const override;
protected:
bool FKeyExists(std::string&) const;
bool FKeyExists(const char *key, size_t cchKey) const;
const rocksdb::ReadOptions &ReadOptions() const { return m_readOptionsTemplate; }
rocksdb::WriteOptions WriteOptions() const;
+1 -2
View File
@@ -71,7 +71,6 @@ RocksDBStorageFactory::RocksDBStorageFactory(const char *dbfile, int dbnum, cons
rocksdb::DB *db = nullptr;
auto options = RocksDbOptions();
options.prefix_extractor.reset(rocksdb::NewFixedPrefixTransform(2));
for (int idb = 0; idb < dbnum; ++idb)
{
@@ -187,7 +186,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(), it->key().size(), privdata);
++count;
}
}
+1 -16
View File
@@ -73,22 +73,7 @@ bool TestStorageProvider::enumerate(callback fn) const
}
return fAll;
}
bool TestStorageProvider::enumerate_hashslot(callback fn, unsigned int hashslot) const
{
bool fAll = true;
for (auto &pair : m_map)
{
if (keyHashSlot(pair.first.data(), pair.first.size()) == hashslot)
if (!fn(pair.first.data(), pair.first.size(), pair.second.data(), pair.second.size()))
{
fAll = false;
break;
}
}
return fAll;
}
size_t TestStorageProvider::count() const
{
return m_map.size();
-1
View File
@@ -24,7 +24,6 @@ public:
virtual void retrieve(const char *key, size_t cchKey, callbackSingle fn) const override;
virtual size_t clear() override;
virtual bool enumerate(callback fn) const override;
virtual bool enumerate_hashslot(callback fn, unsigned int hashslot) const override;
virtual size_t count() const override;
virtual void flush() override;
+2 -10
View File
@@ -729,10 +729,6 @@ void hincrbyfloatCommand(client *c) {
unsigned int vlen;
if (getLongDoubleFromObjectOrReply(c,c->argv[3],&incr,NULL) != C_OK) return;
if (isnan(incr) || isinf(incr)) {
addReplyError(c,"value is NaN or Infinity");
return;
}
if ((o = hashTypeLookupWriteOrCreate(c,c->argv[1])) == NULL) return;
if (hashTypeGetValue(o,szFromObj(c->argv[2]),&vstr,&vlen,&ll) == C_OK) {
if (vstr) {
@@ -1066,8 +1062,6 @@ void hrandfieldWithCountCommand(client *c, long l, int withvalues) {
addReplyBulkCBuffer(c, key, sdslen(key));
if (withvalues)
addReplyBulkCBuffer(c, value, sdslen(value));
if (c->flags & CLIENT_CLOSE_ASAP)
break;
}
} else if (hash->encoding == OBJ_ENCODING_ZIPLIST) {
ziplistEntry *keys, *vals = NULL;
@@ -1081,8 +1075,6 @@ void hrandfieldWithCountCommand(client *c, long l, int withvalues) {
count -= sample_count;
ziplistRandomPairs((unsigned char*)ptrFromObj(hash), sample_count, keys, vals);
harndfieldReplyWithZiplist(c, sample_count, keys, vals);
if (c->flags & CLIENT_CLOSE_ASAP)
break;
}
zfree(keys);
zfree(vals);
@@ -1229,13 +1221,13 @@ void hrandfieldCommand(client *c) {
ziplistEntry ele;
if (c->argc >= 3) {
if (getRangeLongFromObjectOrReply(c,c->argv[2],-LONG_MAX,LONG_MAX,&l,NULL) != C_OK) return;
if (getLongFromObjectOrReply(c,c->argv[2],&l,NULL) != C_OK) return;
if (c->argc > 4 || (c->argc == 4 && strcasecmp(szFromObj(c->argv[3]),"withvalues"))) {
addReplyErrorObject(c,shared.syntaxerr);
return;
} else if (c->argc == 4) {
withvalues = 1;
if (l < -g_pserver->rand_total_threshold || l > g_pserver->rand_total_threshold) {
if (l < LONG_MIN/2 || l > LONG_MAX/2) {
addReplyError(c,"value is out of range");
return;
}
+1 -7
View File
@@ -672,11 +672,7 @@ void srandmemberWithCountCommand(client *c) {
dict *d;
if (getRangeLongFromObjectOrReply(c,c->argv[2],-LONG_MAX,LONG_MAX,&l,NULL) != C_OK) return;
if (l < -g_pserver->rand_total_threshold || l > g_pserver->rand_total_threshold) {
addReplyError(c,"value is out of range");
return;
}
if (getLongFromObjectOrReply(c,c->argv[2],&l,NULL) != C_OK) return;
if (l >= 0) {
count = (unsigned long) l;
} else {
@@ -710,8 +706,6 @@ void srandmemberWithCountCommand(client *c) {
} else {
addReplyBulkCBuffer(c,ele,sdslen(ele));
}
if (c->flags & CLIENT_CLOSE_ASAP)
break;
}
return;
}
+2 -6
View File
@@ -4054,8 +4054,6 @@ void zrandmemberWithCountCommand(client *c, long l, int withscores) {
addReplyBulkCBuffer(c, key, sdslen(key));
if (withscores)
addReplyDouble(c, *(double*)dictGetVal(de));
if (c->flags & CLIENT_CLOSE_ASAP)
break;
}
} else if (zsetobj->encoding == OBJ_ENCODING_ZIPLIST) {
ziplistEntry *keys, *vals = NULL;
@@ -4069,8 +4067,6 @@ void zrandmemberWithCountCommand(client *c, long l, int withscores) {
count -= sample_count;
ziplistRandomPairs((unsigned char*)ptrFromObj(zsetobj), sample_count, keys, vals);
zarndmemberReplyWithZiplist(c, sample_count, keys, vals);
if (c->flags & CLIENT_CLOSE_ASAP)
break;
}
zfree(keys);
zfree(vals);
@@ -4214,13 +4210,13 @@ void zrandmemberCommand(client *c) {
ziplistEntry ele;
if (c->argc >= 3) {
if (getRangeLongFromObjectOrReply(c,c->argv[2],-LONG_MAX,LONG_MAX,&l,NULL) != C_OK) return;
if (getLongFromObjectOrReply(c,c->argv[2],&l,NULL) != C_OK) return;
if (c->argc > 4 || (c->argc == 4 && strcasecmp(szFromObj(c->argv[3]),"withscores"))) {
addReplyErrorObject(c,shared.syntaxerr);
return;
} else if (c->argc == 4) {
withscores = 1;
if (l < -g_pserver->rand_total_threshold || l > g_pserver->rand_total_threshold) {
if (l < LONG_MIN/2 || l > LONG_MAX/2) {
addReplyError(c,"value is out of range");
return;
}
+4 -16
View File
@@ -21,7 +21,6 @@ set ::tls 0
set ::pause_on_error 0
set ::dont_clean 0
set ::simulate_error 0
set ::flash 0
set ::failed 0
set ::sentinel_instances {}
set ::redis_instances {}
@@ -82,10 +81,6 @@ proc spawn_instance {type base_port count {conf {}} {base_conf_file ""}} {
set cfg [open $cfgfile w]
}
if {$::flash} {
puts $cfg "storage-provider flash ./flash_$base_port"
}
if {$::tls} {
puts $cfg "tls-port $port"
puts $cfg "tls-replication yes"
@@ -271,8 +266,6 @@ proc parse_options {} {
set val2 [lindex $::argv [expr $j+2]]
dict set ::global_config $val $val2
incr j 2
} elseif {$opt eq {--flash}} {
set ::flash 1
} elseif {$opt eq "--help"} {
puts "--single <pattern> Only runs tests specified by pattern."
puts "--dont-clean Keep log files on exit."
@@ -282,7 +275,6 @@ proc parse_options {} {
puts "--tls Run tests in TLS mode."
puts "--host <host> Use hostname instead of 127.0.0.1."
puts "--config <k> <v> Extra config argument(s)."
puts "--flash Run the whole suite with flash enabled"
puts "--help Shows this help."
exit 0
} else {
@@ -309,15 +301,11 @@ proc pause_on_error {} {
break
} elseif {$cmd eq {show-keydb-logs}} {
set count 10
set instance {}
if {[lindex $argv 1] ne {}} {set count [lindex $argv 1]}
if {[lindex $argv 2] ne {}} {set instance [lindex $argv 2]}
foreach_redis_id id {
if {$instance eq $id || $instance eq {}} {
puts "=== KeyDB $id ===="
puts [exec tail -$count redis_$id/log.txt]
puts "---------------------\n"
}
puts "=== KeyDB $id ===="
puts [exec tail -$count redis_$id/log.txt]
puts "---------------------\n"
}
} elseif {$cmd eq {show-sentinel-logs}} {
set count 10
@@ -362,7 +350,7 @@ proc pause_on_error {} {
} elseif {$cmd eq {help}} {
puts "ls List Sentinel and KeyDB instances."
puts "show-sentinel-logs \[N\] Show latest N lines of logs."
puts "show-keydb-logs \[N\] \[id\] Show latest N lines of logs of server id."
puts "show-keydb-logs \[N\] Show latest N lines of logs."
puts "S <id> cmd ... arg Call command in Sentinel <id>."
puts "R <id> cmd ... arg Call command in KeyDB <id>."
puts "SI <id> <field> Show Sentinel <id> INFO <field>."
+3 -4
View File
@@ -162,16 +162,15 @@ start_server {tags {"introspection"}} {
aof_rewrite_cpulist
time-thread-priority
bgsave_cpulist
storage-cache-mode
storage-provider-options
use-fork
storage-cache-mode
storage-provider-options
use-fork
multi-master
active-replica
bind
set-proc-title
repl-backlog-disk-reserve
tls-allowlist
db-s3-object
}
if {!$::tls} {
-8
View File
@@ -182,12 +182,4 @@ start_server {tags {"obuf-limits"} overrides { server-threads 1 }} {
assert_equal "v2" [r get k2]
assert_equal "v3" [r get k3]
}
test "Obuf limit, HRANDFIELD with huge count stopped mid-run" {
r config set client-output-buffer-limit {normal 1000000 0 0}
r hset myhash a b
catch {r hrandfield myhash -999999999} e
assert_match "*I/O error*" $e
reconnect
}
}
+1 -6
View File
@@ -43,15 +43,10 @@ start_server {tags {"scripting"}} {
r eval {return redis.call('get',KEYS[1])} 1 mykey
} {myval}
test {EVAL - keys command works? } {
test { EVAL - keys command works? } {
r eval {return redis.call('keys', 'test')} 0
}
test {EVAL - KeyDB global works } {
r eval {return keydb.call('get', KEYS[1])} 1 mykey
assert_equal [r eval {return redis.call('get',KEYS[1])} 1 mykey] [r eval {return keydb.call('get', KEYS[1])} 1 mykey]
}
test {EVALSHA - Can we call a SHA1 if already defined?} {
r evalsha fd758d1589d044dd850a6f05d52f2eefd27f033f 1 mykey
} {myval}
-6
View File
@@ -71,8 +71,6 @@ start_server {tags {"hash"}} {
test "HRANDFIELD count overflow" {
r hmset myhash a 1
assert_error {*value is out of range*} {r hrandfield myhash -9223372036854770000 withvalues}
assert_error {*value is out of range*} {r hrandfield myhash -9223372036854775808 withvalues}
assert_error {*value is out of range*} {r hrandfield myhash -9223372036854775808}
} {}
test "HRANDFIELD with <count> against non existing key" {
@@ -833,8 +831,4 @@ start_server {tags {"hash"}} {
set _ $k
} {ZIP_INT_8B 127 ZIP_INT_16B 32767 ZIP_INT_32B 2147483647 ZIP_INT_64B 9223372036854775808 ZIP_INT_IMM_MIN 0 ZIP_INT_IMM_MAX 12}
test {HINCRBYFLOAT does not allow NaN or Infinity} {
assert_error "*value is NaN or Infinity*" {r hincrbyfloat hfoo field +inf}
assert_equal 0 [r exists hfoo]
}
}
-5
View File
@@ -588,11 +588,6 @@ start_server {
r srandmember nonexisting_key 100
} {}
test "SRANDMEMBER count overflow" {
r sadd myset a
assert_error {*value is out of range*} {r srandmember myset -9223372036854775808}
} {}
# Make sure we can distinguish between an empty array and a null response
r readraw 1
-2
View File
@@ -1717,8 +1717,6 @@ start_server {tags {"zset"}} {
test "ZRANDMEMBER count overflow" {
r zadd myzset 0 a
assert_error {*value is out of range*} {r zrandmember myzset -9223372036854770000 withscores}
assert_error {*value is out of range*} {r zrandmember myzset -9223372036854775808 withscores}
assert_error {*value is out of range*} {r zrandmember myzset -9223372036854775808}
} {}
# Make sure we can distinguish between an empty array and a null response
+1 -7
View File
@@ -26,11 +26,7 @@ then
while [ $((PORT < ENDPORT)) != "0" ]; do
PORT=$((PORT+1))
echo "Starting $PORT"
if [ "$2" == "flash" ]
then
ADDITIONAL_OPTIONS="--save \"\" \"\" \"\" --semi-ordered-set-bucket-size 8 --client-output-buffer-limit replica 1 1 0 --maxmemory 100000000 --storage-provider flash ./$PORT.flash"
fi
$BIN_PATH/keydb-server --server-threads 4 --port $PORT --protected-mode $PROTECTED_MODE --cluster-enabled yes --cluster-config-file nodes-${PORT}.conf --cluster-node-timeout $TIMEOUT --dbfilename dump-${PORT}.rdb --logfile ${PORT}.log --daemonize yes ${ADDITIONAL_OPTIONS}
$BIN_PATH/keydb-server --port $PORT --protected-mode $PROTECTED_MODE --cluster-enabled yes --cluster-config-file nodes-${PORT}.conf --cluster-node-timeout $TIMEOUT --appendonly yes --appendfilename appendonly-${PORT}.aof --dbfilename dump-${PORT}.rdb --logfile ${PORT}.log --daemonize yes ${ADDITIONAL_OPTIONS}
done
exit 0
fi
@@ -101,8 +97,6 @@ then
rm -rf appendonly*.aof
rm -rf dump*.rdb
rm -rf nodes*.conf
rm -rf *.flash
rm -rf temp*.rdb
exit 0
fi