X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/09e2d9eeba3ff65fd60f905a5bcb0f684f7a883e..9fc1e1b1d4613b9d95f80c64dc909a7f8defd78a:/src/redis.c?ds=sidebyside diff --git a/src/redis.c b/src/redis.c index 0990d98a..268398f0 100644 --- a/src/redis.c +++ b/src/redis.c @@ -29,6 +29,7 @@ #include "redis.h" #include "slowlog.h" +#include "bio.h" #ifdef HAVE_BACKTRACE #include @@ -194,6 +195,8 @@ struct redisCommand redisCommandTable[] = { {"dump",dumpCommand,2,0,NULL,0,0,0,0,0}, {"object",objectCommand,-2,0,NULL,0,0,0,0,0}, {"client",clientCommand,-2,0,NULL,0,0,0,0,0}, + {"eval",evalCommand,-3,REDIS_CMD_DENYOOM,zunionInterGetKeys,0,0,0,0,0}, + {"evalsha",evalShaCommand,-3,REDIS_CMD_DENYOOM,zunionInterGetKeys,0,0,0,0,0}, {"slowlog",slowlogCommand,-2,0,NULL,0,0,0,0,0} }; @@ -381,7 +384,7 @@ unsigned int dictEncObjHash(const void *key) { } } -/* Sets type and diskstore negative caching hash table */ +/* Sets type hash table */ dictType setDictType = { dictEncObjHash, /* hash function */ NULL, /* key dup */ @@ -573,6 +576,7 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) { * in objects at every object access, and accuracy is not needed. * To access a global var is faster than calling time(NULL) */ server.unixtime = time(NULL); + /* We have just 22 bits per object for LRU information. * So we use an (eventually wrapping) LRU clock with 10 seconds resolution. * 2^22 bits with 10 seconds resoluton is more or less 1.5 years. @@ -683,7 +687,7 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) { server.auto_aofrewrite_perc && server.appendonly_current_size > server.auto_aofrewrite_min_size) { - int base = server.auto_aofrewrite_base_size ? + long long base = server.auto_aofrewrite_base_size ? server.auto_aofrewrite_base_size : 1; long long growth = (server.appendonly_current_size*100/base) - 100; if (growth >= server.auto_aofrewrite_perc) { @@ -761,6 +765,8 @@ void createSharedObjects(void) { "-ERR source and destination objects are the same\r\n")); shared.outofrangeerr = createObject(REDIS_STRING,sdsnew( "-ERR index out of range\r\n")); + shared.noscripterr = createObject(REDIS_STRING,sdsnew( + "-NOSCRIPT No matching script. Please use EVAL.\r\n")); shared.loadingerr = createObject(REDIS_STRING,sdsnew( "-LOADING Redis is loading the dataset in memory\r\n")); shared.space = createObject(REDIS_STRING,sdsnew(" ")); @@ -837,6 +843,7 @@ void initServerConfig() { server.shutdown_asap = 0; server.cluster_enabled = 0; server.cluster.configfile = zstrdup("nodes.conf"); + server.lua_time_limit = REDIS_LUA_TIME_LIMIT; updateLRUClock(); resetServerSaveParams(); @@ -958,7 +965,9 @@ void initServer() { } if (server.cluster_enabled) clusterInit(); + scriptingInit(); slowlogInit(); + bioInit(); srand(time(NULL)^getpid()); } @@ -1016,9 +1025,9 @@ void call(redisClient *c) { slowlogPushEntryIfNeeded(c->argv,c->argc,duration); c->cmd->calls++; - if (server.appendonly && dirty) + if (server.appendonly && dirty > 0) feedAppendOnlyFile(c->cmd,c->db->id,c->argv,c->argc); - if ((dirty || c->cmd->flags & REDIS_CMD_FORCE_REPLICATION) && + if ((dirty > 0 || c->cmd->flags & REDIS_CMD_FORCE_REPLICATION) && listLength(server.slaves)) replicationFeedSlaves(server.slaves,c->db->id,c->argv,c->argc); if (listLength(server.monitors)) @@ -1146,19 +1155,29 @@ int processCommand(redisClient *c) { /*================================== Shutdown =============================== */ int prepareForShutdown() { - redisLog(REDIS_WARNING,"User requested shutdown, saving DB..."); + redisLog(REDIS_WARNING,"User requested shutdown..."); /* Kill the saving child if there is a background saving in progress. We want to avoid race conditions, for instance our saving child may overwrite the synchronous saving did by SHUTDOWN. */ if (server.bgsavechildpid != -1) { - redisLog(REDIS_WARNING,"There is a live saving child. Killing it!"); + redisLog(REDIS_WARNING,"There is a child saving an .rdb. Killing it!"); kill(server.bgsavechildpid,SIGKILL); rdbRemoveTempFile(server.bgsavechildpid); } if (server.appendonly) { + /* Kill the AOF saving child as the AOF we already have may be longer + * but contains the full dataset anyway. */ + if (server.bgrewritechildpid != -1) { + redisLog(REDIS_WARNING, + "There is a child rewriting the AOF. Killing it!"); + kill(server.bgrewritechildpid,SIGKILL); + } /* Append only file: fsync() the AOF and exit */ + redisLog(REDIS_NOTICE,"Calling fsync() on the AOF file."); aof_fsync(server.appendfd); - } else if (server.saveparamslen > 0) { + } + if (server.saveparamslen > 0) { + redisLog(REDIS_NOTICE,"Saving the final RDB snapshot before exiting."); /* Snapshotting. Perform a SYNC SAVE and exit */ if (rdbSave(server.dbfilename) != REDIS_OK) { /* Ooops.. error saving! The best we can do is to continue @@ -1166,14 +1185,19 @@ int prepareForShutdown() { * in the next cron() Redis will be notified that the background * saving aborted, handling special stuff like slaves pending for * synchronization... */ - redisLog(REDIS_WARNING,"Error trying to save the DB, can't exit"); + redisLog(REDIS_WARNING,"Error trying to save the DB, can't exit."); return REDIS_ERR; } - } else { - redisLog(REDIS_WARNING,"Not saving DB."); } - if (server.daemonize) unlink(server.pidfile); - redisLog(REDIS_WARNING,"Server exit now, bye bye..."); + if (server.daemonize) { + redisLog(REDIS_NOTICE,"Removing the pid file."); + unlink(server.pidfile); + } + /* Close the listening sockets. Apparently this allows faster restarts. */ + if (server.ipfd != -1) close(server.ipfd); + if (server.sofd != -1) close(server.sofd); + + redisLog(REDIS_WARNING,"Redis is now ready to exit, bye bye..."); return REDIS_OK; } @@ -1295,6 +1319,7 @@ sds genRedisInfoString(char *section) { "used_memory_rss:%zu\r\n" "used_memory_peak:%zu\r\n" "used_memory_peak_human:%s\r\n" + "used_memory_lua:%lld\r\n" "mem_fragmentation_ratio:%.2f\r\n" "mem_allocator:%s\r\n", zmalloc_used_memory(), @@ -1302,6 +1327,7 @@ sds genRedisInfoString(char *section) { zmalloc_get_rss(), server.stat_peak_memory, peak_hmem, + ((long long)lua_gc(server.lua,LUA_GCCOUNT,0))*1024LL, zmalloc_get_fragmentation_ratio(), ZMALLOC_LIB ); @@ -1703,6 +1729,7 @@ void redisAsciiArt(void) { int main(int argc, char **argv) { long long start; + zmalloc_enable_thread_safeness(); initServerConfig(); if (argc == 2) { if (strcmp(argv[1], "-v") == 0 ||