Compare commits

...
Author SHA1 Message Date
Malavan Sotheeswaran b0728af6aa don't do if statement on every key, use stack object for module notify 2023-03-13 14:14:40 -07:00
Malavan Sotheeswaran 715f832b00 make connectWithMaster error message less confusing (#592) 2023-03-08 16:00:53 -05:00
Malavan Sotheeswaran c8dd6744da Add config for AWS s3 rdb save/load. (#591)
* add s3 config

* missing include

* ignore s3 config in config test

* Update introspection.tcl

* Update config.cpp
2023-03-08 16:00:44 -05:00
Malavan Sotheeswaran b398021b2c update slotToKey during fast load (#589) 2023-03-08 15:54:50 -05:00
Malavan Sotheeswaran c2077a2fbd Fix rdb fd leak (#579)
* close tempfile when done bgsave

* declare getTempFileName

* open close child pipes in correct place

* assert no existing child pipe when opening new child pipe
2023-03-02 13:51:47 -05:00
Malavan Sotheeswaran a9995d2e54 Upgrade rocksdb to v7.9.2 (#555)
* upgrade to rocksdb v7.9.2

* need c++17 for rocksdb

* don't prefix jemalloc

* different exception specifier
2023-03-02 13:51:21 -05:00
Malavan Sotheeswaran 81c6c7902d Fix possible crash in prefetchKeysAsync with flash enabled. (#578)
* remove short circuit as it is unsafe
2023-02-22 19:27:24 -05:00
Malavan Sotheeswaran 4ac449aee7 Merge pull request #575 from EreMaijala/main-issue-537
Close child info pipes when RDB save thread is done.
2023-02-21 17:47:43 -05:00
Ere Maijala db2c3cd7e8 Close child info pipes when RDB save thread is done. 2023-02-20 11:07:21 +02:00
19 changed files with 100 additions and 74 deletions

No files matched your search

+1 -1
View File
@@ -95,7 +95,7 @@ JEMALLOC_LDFLAGS= $(LDFLAGS)
jemalloc: .make-prerequisites
@printf '%b %b\n' $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR)
cd jemalloc && ./configure --with-version=5.2.1-0-g0 --with-lg-quantum=3 --with-jemalloc-prefix=je_ --disable-cxx CFLAGS="$(JEMALLOC_CFLAGS)" LDFLAGS="$(JEMALLOC_LDFLAGS)"
cd jemalloc && ./configure --with-version=5.2.1-0-g0 --with-lg-quantum=3 --disable-cxx CFLAGS="$(JEMALLOC_CFLAGS)" LDFLAGS="$(JEMALLOC_LDFLAGS)"
cd jemalloc && $(MAKE) CFLAGS="$(JEMALLOC_CFLAGS)" LDFLAGS="$(JEMALLOC_LDFLAGS)" lib/libjemalloc.a
.PHONY: jemalloc
+1 -1
+1 -1
View File
@@ -25,7 +25,7 @@ NODEPS:=clean distclean
# Default settings
STD=-pedantic -DREDIS_STATIC=''
CXX_STD=-std=c++14 -pedantic -fno-rtti -D__STDC_FORMAT_MACROS
CXX_STD=-std=c++17 -pedantic -fno-rtti -D__STDC_FORMAT_MACROS
ifneq (,$(findstring clang,$(CC)))
STD+=-Wno-c11-extensions
else
+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]->bulkStorageInsert(vecqueuedKeys.data(), vecqueuedKeysCb.data(), vecqueuedVals.data(), vecqueuedValsCb.data(), vecqueuedKeys.size());
g_pserver->db[idb]->bulkDirectStorageInsert(vecqueuedKeys.data(), vecqueuedKeysCb.data(), vecqueuedVals.data(), vecqueuedValsCb.data(), vecqueuedKeys.size());
--insertsInFlightTmp;
delete pallocator;
});
+1
View File
@@ -42,6 +42,7 @@ typedef struct {
* RDB / AOF saving process from the child to the parent (for instance
* the amount of copy on write memory used) */
void openChildInfoPipe(void) {
serverAssert(g_pserver->child_info_pipe[0] == -1);
if (pipe(g_pserver->child_info_pipe) == -1) {
/* On error our two file descriptors should be still set to -1,
* but we call anyway closeChildInfoPipe() since can't hurt. */
+28
View File
@@ -35,6 +35,7 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#ifdef __linux__
#include <sys/sysinfo.h>
#endif
@@ -2456,6 +2457,32 @@ 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)) {
@@ -2803,6 +2830,7 @@ 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),
+26 -25
View File
@@ -2607,12 +2607,15 @@ void clusterStorageLoadCallback(const char *rgchkey, size_t cch, void *)
slotToKeyUpdateKeyCore(rgchkey, cch, true /*add*/);
}
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 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 redisDb::initialize(int id)
@@ -2633,7 +2636,7 @@ void redisDb::storageProviderInitialize()
{
if (g_pserver->m_pstorageFactory != nullptr)
{
IStorageFactory::key_load_iterator itr = moduleLoadCallback;
IStorageFactory::key_load_iterator itr = g_pserver->cluster_enabled ? moduleClusterLoadCallback : moduleLoadCallback;
this->setStorageProvider(StorageCache::create(g_pserver->m_pstorageFactory, id, itr, &id));
}
}
@@ -3002,8 +3005,16 @@ void redisDbPersistentData::processChangesAsync(std::atomic<int> &pendingJobs)
});
}
void redisDbPersistentData::bulkStorageInsert(char **rgKeys, size_t *rgcbKeys, char **rgVals, size_t *rgcbVals, size_t celem)
/* 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)
{
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);
}
@@ -3265,7 +3276,7 @@ int dbnumFromDb(redisDb *db)
serverPanic("invalid database pointer");
}
bool redisDbPersistentData::prefetchKeysAsync(client *c, parsed_command &command, bool fExecOK)
void redisDbPersistentData::prefetchKeysAsync(client *c, parsed_command &command)
{
if (m_spstorage == nullptr) {
#if defined(__x86_64__) || defined(__i386__)
@@ -3277,7 +3288,7 @@ bool redisDbPersistentData::prefetchKeysAsync(client *c, parsed_command &command
const char *cmd = szFromObj(command.argv[0]);
if (!strcasecmp(cmd, "set") || !strcasecmp(cmd, "get")) {
if (c->db->m_spdbSnapshotHOLDER != nullptr)
return false; // this is dangerous enough without a snapshot around
return; // this is dangerous enough without a snapshot around
auto h = dictSdsHash(szFromObj(command.argv[1]));
for (int iht = 0; iht < 2; ++iht) {
auto hT = h & c->db->m_pdict->ht[iht].sizemask;
@@ -3297,7 +3308,7 @@ bool redisDbPersistentData::prefetchKeysAsync(client *c, parsed_command &command
}
}
#endif
return false;
return;
}
AeLocker lock;
@@ -3307,10 +3318,10 @@ bool redisDbPersistentData::prefetchKeysAsync(client *c, parsed_command &command
getKeysResult result = GETKEYS_RESULT_INIT;
auto cmd = lookupCommand(szFromObj(command.argv[0]));
if (cmd == nullptr)
return false; // Bad command? It's not for us to judge, just bail
return; // Bad command? It's not for us to judge, just bail
if (command.argc < std::abs(cmd->arity))
return false; // Invalid number of args
return; // Invalid number of args
int numkeys = getKeysFromCommand(cmd, command.argv, command.argc, &result);
for (int ikey = 0; ikey < numkeys; ++ikey)
@@ -3343,7 +3354,6 @@ bool redisDbPersistentData::prefetchKeysAsync(client *c, parsed_command &command
}
}
bool fNoInsert = false;
if (!vecInserts.empty()) {
lock.arm(c);
for (auto &tuple : vecInserts)
@@ -3359,13 +3369,11 @@ bool redisDbPersistentData::prefetchKeysAsync(client *c, parsed_command &command
// While unlocked this was already ensured
decrRefCount(o);
sdsfree(sharedKey);
fNoInsert = true;
}
else
{
if (spexpire != nullptr) {
if (spexpire->when() < mstime()) {
fNoInsert = true;
break;
}
}
@@ -3392,12 +3400,5 @@ bool redisDbPersistentData::prefetchKeysAsync(client *c, parsed_command &command
lock.disarm();
}
if (fExecOK && !fNoInsert && cmd->proc == getCommand && !vecInserts.empty()) {
robj *o = std::get<1>(vecInserts[0]);
if (o != nullptr) {
addReplyBulk(c, o);
return true;
}
}
return false;
}
return;
}
+4 -4
View File
@@ -341,10 +341,10 @@ void mallctl_int(client *c, robj **argv, int argc) {
}
size_t sz = sizeof(old);
while (sz > 0) {
if ((ret=je_mallctl(szFromObj(argv[0]), &old, &sz, argc > 1? &val: NULL, argc > 1?sz: 0))) {
if ((ret=mallctl(szFromObj(argv[0]), &old, &sz, argc > 1? &val: NULL, argc > 1?sz: 0))) {
if (ret == EPERM && argc > 1) {
/* if this option is write only, try just writing to it. */
if (!(ret=je_mallctl(szFromObj(argv[0]), NULL, 0, &val, sz))) {
if (!(ret=mallctl(szFromObj(argv[0]), NULL, 0, &val, sz))) {
addReply(c, shared.ok);
return;
}
@@ -375,7 +375,7 @@ void mallctl_string(client *c, robj **argv, int argc) {
char *old;
size_t sz = sizeof(old);
/* for strings, it seems we need to first get the old value, before overriding it. */
if ((rret=je_mallctl(szFromObj(argv[0]), &old, &sz, NULL, 0))) {
if ((rret=mallctl(szFromObj(argv[0]), &old, &sz, NULL, 0))) {
/* return error unless this option is write only. */
if (!(rret == EPERM && argc > 1)) {
addReplyErrorFormat(c,"%s", strerror(rret));
@@ -387,7 +387,7 @@ void mallctl_string(client *c, robj **argv, int argc) {
char **valref = &val;
if ((!strcmp(val,"VOID")))
valref = NULL, sz = 0;
wret = je_mallctl(szFromObj(argv[0]), NULL, 0, valref, sz);
wret = mallctl(szFromObj(argv[0]), NULL, 0, valref, sz);
}
if (!rret)
addReplyBulkCString(c, old);
+1 -3
View File
@@ -2595,9 +2595,7 @@ void parseClientCommandBuffer(client *c) {
(g_pserver->m_pstorageFactory || aeLockContested(cserver.cthreads/2) || cserver.cthreads == 1) && !GlobalLocksAcquired()) {
auto &query = c->vecqueuedcmd.back();
if (query.argc > 0 && query.argc == query.argcMax) {
if (c->db->prefetchKeysAsync(c, query, c->vecqueuedcmd.size() == 1)) {
c->vecqueuedcmd.erase(c->vecqueuedcmd.begin());
}
c->db->prefetchKeysAsync(c, query);
}
}
c->reqtype = 0;
-7
View File
@@ -41,10 +41,3 @@ void operator delete(void *p, std::size_t) noexcept
}
#endif
#if defined(USE_JEMALLOC)
extern "C" size_t malloc_usable_size(void *ptr)
{
return zmalloc_usable_size(ptr);
}
#endif
+1 -1
View File
@@ -1541,7 +1541,7 @@ void memoryCommand(client *c) {
} else if (!strcasecmp(szFromObj(c->argv[1]),"malloc-stats") && c->argc == 2) {
#if defined(USE_JEMALLOC)
sds info = sdsempty();
je_malloc_stats_print(inputCatSds, &info, NULL);
malloc_stats_print(inputCatSds, &info, NULL);
addReplyVerbatim(c,info,sdslen(info),"txt");
sdsfree(info);
#else
+3 -3
View File
@@ -1490,7 +1490,7 @@ int rdbSaveFile(char *filename, const redisDbPersistentDataSnapshot **rgpdb, rdb
rio rdb;
int error = 0;
snprintf(tmpfile,sizeof(tmpfile),"temp-%d-%d.rdb", getpid(), g_pserver->rdbThreadVars.tmpfileNum);
getTempFileName(tmpfile, g_pserver->rdbThreadVars.tmpfileNum);
fp = fopen(tmpfile,"w");
if (!fp) {
char *cwdp = getcwd(cwd,MAXPATHLEN);
@@ -1660,12 +1660,14 @@ int launchRdbSaveThread(pthread_t &child, rdbSaveInfo *rsi)
pthread_attr_t tattr;
pthread_attr_init(&tattr);
pthread_attr_setstacksize(&tattr, 1 << 23); // 8 MB
openChildInfoPipe();
if (pthread_create(&child, &tattr, rdbSaveThread, args)) {
pthread_attr_destroy(&tattr);
for (int idb = 0; idb < cserver.dbnum; ++idb)
g_pserver->db[idb]->endSnapshot(args->rgpdb[idb]);
args->~rdbSaveThreadArgs();
zfree(args);
closeChildInfoPipe();
return C_ERR;
}
pthread_attr_destroy(&tattr);
@@ -1683,13 +1685,11 @@ int rdbSaveBackground(rdbSaveInfo *rsi) {
g_pserver->dirty_before_bgsave = g_pserver->dirty;
g_pserver->lastbgsave_try = time(NULL);
openChildInfoPipe();
start = ustime();
latencyStartMonitor(g_pserver->rdb_save_latency);
if (launchRdbSaveThread(child, rsi) != C_OK) {
closeChildInfoPipe();
g_pserver->lastbgsave_status = C_ERR;
serverLog(LL_WARNING,"Can't save in background: fork: %s",
strerror(errno));
+1
View File
@@ -151,6 +151,7 @@ int rdbLoad(rdbSaveInfo *rsi, int rdbflags);
int rdbLoadFile(const char *filename, rdbSaveInfo *rsi, int rdbflags);
int rdbSaveBackground(rdbSaveInfo *rsi);
int rdbSaveToSlavesSockets(rdbSaveInfo *rsi);
void getTempFileName(char tmpfile[], int tmpfileNum);
void rdbRemoveTempFile(pid_t childpid, int from_signal);
int rdbSave(const redisDbPersistentDataSnapshot **rgpdb, rdbSaveInfo *rsi);
int rdbSaveFile(char *filename, const redisDbPersistentDataSnapshot **rgpdb, rdbSaveInfo *rsi);
+5 -3
View File
@@ -3797,9 +3797,11 @@ int connectWithMaster(redisMaster *mi) {
connSetPrivateData(mi->repl_transfer_s, mi);
if (connConnect(mi->repl_transfer_s, mi->masterhost, mi->masterport,
NET_FIRST_BIND_ADDR, syncWithMaster) == C_ERR) {
int sev = g_pserver->enable_multimaster ? LL_NOTICE : LL_WARNING; // with multimaster its not unheard of to intentiallionall have downed masters
serverLog(sev,"Unable to connect to MASTER: %s",
connGetLastError(mi->repl_transfer_s));
const char *err = "Unknown Error";
if (mi->repl_transfer_s->last_errno != 0)
err = connGetLastError(mi->repl_transfer_s);
int sev = g_pserver->enable_multimaster ? LL_NOTICE : LL_WARNING; // with multimaster its not unheard of to intentionally have downed masters
serverLog(sev, "Unable to connect to MASTER: %s", err);
connClose(mi->repl_transfer_s);
mi->repl_transfer_s = NULL;
return C_ERR;
+1
View File
@@ -2219,6 +2219,7 @@ void checkChildrenDone(void) {
g_pserver->rdbThreadVars.fRdbThreadCancel = false;
g_pserver->rdbThreadVars.fDone = false;
if (exitcode == 0) receiveChildInfo();
closeChildInfoPipe();
}
}
else if ((pid = waitpid(-1, &statloc, WNOHANG)) != 0) {
+7 -7
View File
@@ -1204,12 +1204,12 @@ public:
void disableKeyCache();
bool keycacheIsEnabled();
bool prefetchKeysAsync(client *c, struct parsed_command &command, bool fExecOK);
void prefetchKeysAsync(client *c, struct parsed_command &command);
bool FSnapshot() const { return m_spdbSnapshotHOLDER != nullptr; }
std::unique_ptr<const StorageCache> CloneStorageCache() { return std::unique_ptr<const StorageCache>(m_spstorage->clone()); }
void bulkStorageInsert(char **rgKeys, size_t *rgcbKeys, char **rgVals, size_t *rgcbVals, size_t celem);
void bulkDirectStorageInsert(char **rgKeys, size_t *rgcbKeys, char **rgVals, size_t *rgcbVals, size_t celem);
dict_iter find_cached_threadsafe(const char *key) const;
@@ -1370,7 +1370,7 @@ struct redisDb : public redisDbPersistentDataSnapshot
using redisDbPersistentData::FRehashing;
using redisDbPersistentData::FTrackingChanges;
using redisDbPersistentData::CloneStorageCache;
using redisDbPersistentData::bulkStorageInsert;
using redisDbPersistentData::bulkDirectStorageInsert;
public:
const redisDbPersistentDataSnapshot *createSnapshot(uint64_t mvccCheckpoint, bool fOptional) {
@@ -3894,13 +3894,13 @@ void incrementMvccTstamp();
#if __GNUC__ >= 7 && !defined(NO_DEPRECATE_FREE)
[[deprecated]]
void *calloc(size_t count, size_t size);
void *calloc(size_t count, size_t size) noexcept;
[[deprecated]]
void free(void *ptr);
void free(void *ptr) noexcept;
[[deprecated]]
void *malloc(size_t size);
void *malloc(size_t size) noexcept;
[[deprecated]]
void *realloc(void *ptr, size_t size);
void *realloc(void *ptr, size_t size) noexcept;
#endif
/* Debugging stuff */
+13 -13
View File
@@ -80,12 +80,12 @@ static_assert((PREFIX_SIZE % 16) == 0, "Our prefix must be modulo 16-bytes or ou
#define realloc(ptr,size, type) tc_realloc(ptr,size)
#define free(ptr) tc_free(ptr)
#elif defined(USE_JEMALLOC)
#define malloc(size, type) je_malloc(size)
#define calloc(count,size,type) je_calloc(count,size)
#define realloc(ptr,size,type) je_realloc(ptr,size)
#define free(ptr) je_free(ptr)
#define mallocx(size,flags) je_mallocx(size,flags)
#define dallocx(ptr,flags) je_dallocx(ptr,flags)
#define malloc(size, type) malloc(size)
#define calloc(count,size,type) calloc(count,size)
#define realloc(ptr,size,type) realloc(ptr,size)
#define free(ptr) free(ptr)
#define mallocx(size,flags) mallocx(size,flags)
#define dallocx(ptr,flags) dallocx(ptr,flags)
#else
#define malloc(size, type) malloc(size)
#define calloc(count,size,type) calloc(count,size)
@@ -494,17 +494,17 @@ int zmalloc_get_allocator_info(size_t *allocated,
*allocated = *resident = *active = 0;
/* Update the statistics cached by mallctl. */
sz = sizeof(epoch);
je_mallctl("epoch", &epoch, &sz, &epoch, sz);
mallctl("epoch", &epoch, &sz, &epoch, sz);
sz = sizeof(size_t);
/* Unlike RSS, this does not include RSS from shared libraries and other non
* heap mappings. */
je_mallctl("stats.resident", resident, &sz, NULL, 0);
mallctl("stats.resident", resident, &sz, NULL, 0);
/* Unlike resident, this doesn't not include the pages jemalloc reserves
* for re-use (purge will clean that). */
je_mallctl("stats.active", active, &sz, NULL, 0);
mallctl("stats.active", active, &sz, NULL, 0);
/* Unlike zmalloc_used_memory, this matches the stats.resident by taking
* into account all allocations done by this process (not only zmalloc). */
je_mallctl("stats.allocated", allocated, &sz, NULL, 0);
mallctl("stats.allocated", allocated, &sz, NULL, 0);
return 1;
}
@@ -512,7 +512,7 @@ void set_jemalloc_bg_thread(int enable) {
/* let jemalloc do purging asynchronously, required when there's no traffic
* after flushdb */
char val = !!enable;
je_mallctl("background_thread", NULL, 0, &val, 1);
mallctl("background_thread", NULL, 0, &val, 1);
}
int jemalloc_purge() {
@@ -520,9 +520,9 @@ int jemalloc_purge() {
char tmp[32];
unsigned narenas = 0;
size_t sz = sizeof(unsigned);
if (!je_mallctl("arenas.narenas", &narenas, &sz, NULL, 0)) {
if (!mallctl("arenas.narenas", &narenas, &sz, NULL, 0)) {
snprintf(tmp, sizeof(tmp), "arena.%d.purge", narenas);
if (!je_mallctl(tmp, NULL, 0, NULL, 0))
if (!mallctl(tmp, NULL, 0, NULL, 0))
return 0;
}
return -1;
+1 -1
View File
@@ -55,7 +55,7 @@
#include <jemalloc/jemalloc.h>
#if (JEMALLOC_VERSION_MAJOR == 2 && JEMALLOC_VERSION_MINOR >= 1) || (JEMALLOC_VERSION_MAJOR > 2)
#define HAVE_MALLOC_SIZE 1
#define zmalloc_size(p) je_malloc_usable_size(p)
#define zmalloc_size(p) malloc_usable_size(p)
#else
#error "Newer version of jemalloc required"
#endif
+4 -3
View File
@@ -162,15 +162,16 @@ 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} {