]> git.saurik.com Git - redis.git/blame - src/redis.c
version bumped to 2.9.6
[redis.git] / src / redis.c
CommitLineData
e2641e09 1/*
2 * Copyright (c) 2009-2010, Salvatore Sanfilippo <antirez at gmail dot com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Redis nor the names of its contributors may be used
14 * to endorse or promote products derived from this software without
15 * specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "redis.h"
daa70b17 31#include "slowlog.h"
8f61a72f 32#include "bio.h"
e2641e09 33
e2641e09 34#include <time.h>
35#include <signal.h>
36#include <sys/wait.h>
37#include <errno.h>
38#include <assert.h>
39#include <ctype.h>
40#include <stdarg.h>
e2641e09 41#include <arpa/inet.h>
42#include <sys/stat.h>
43#include <fcntl.h>
44#include <sys/time.h>
45#include <sys/resource.h>
46#include <sys/uio.h>
47#include <limits.h>
48#include <float.h>
49#include <math.h>
2b00385d 50#include <sys/resource.h>
5ad1faa0 51#include <sys/utsname.h>
e2641e09 52
53/* Our shared "common" objects */
54
55struct sharedObjectsStruct shared;
56
c74b7c77 57/* Global vars that are actually used as constants. The following double
e2641e09 58 * values are used for double on-disk serialization, and are initialized
59 * at runtime to avoid strange compiler optimizations. */
60
61double R_Zero, R_PosInf, R_NegInf, R_Nan;
62
63/*================================= Globals ================================= */
64
c5757662
PH
65/* Alternate stack for SIGSEGV/etc handlers */
66char altstack[SIGSTKSZ];
67
e2641e09 68/* Global vars */
69struct redisServer server; /* server global state */
70struct redisCommand *commandTable;
5d02b00f 71
7501c66f 72/* Our command table.
73 *
74 * Every entry is composed of the following fields:
75 *
76 * name: a string representing the command name.
77 * function: pointer to the C function implementing the command.
78 * arity: number of arguments, it is possible to use -N to say >= N
79 * sflags: command flags as string. See below for a table of flags.
80 * flags: flags as bitmask. Computed by Redis using the 'sflags' field.
81 * get_keys_proc: an optional function to get key arguments from a command.
82 * This is only used when the following three fields are not
83 * enough to specify what arguments are keys.
84 * first_key_index: first argument that is a key
85 * last_key_index: last argument that is a key
86 * key_step: step to get all the keys from first to last argument. For instance
87 * in MSET the step is two since arguments are key,val,key,val,...
88 * microseconds: microseconds of total execution time for this command.
89 * calls: total number of calls of this command.
90 *
91 * The flags, microseconds and calls fields are computed by Redis and should
92 * always be set to zero.
93 *
94 * Command flags are expressed using strings where every character represents
95 * a flag. Later the populateCommandTable() function will take care of
96 * populating the real 'flags' field using this characters.
5d02b00f 97 *
98 * This is the meaning of the flags:
99 *
100 * w: write command (may modify the key space).
101 * r: read command (will never modify the key space).
102 * m: may increase memory usage once called. Don't allow if out of memory.
103 * a: admin command, like SAVE or SHUTDOWN.
104 * p: Pub/Sub related command.
b60ed6e8 105 * f: force replication of this command, regarless of server.dirty.
106 * s: command not allowed in scripts.
7e14a208 107 * R: random command. Command is not deterministic, that is, the same command
b60ed6e8 108 * with the same arguments, with the same key space, may have different
548efd91 109 * results. For instance SPOP and RANDOMKEY are two random commands.
110 * S: Sort command output array if called from script, so that the output
111 * is deterministic.
112 */
d7ed7fd2 113struct redisCommand redisCommandTable[] = {
5d02b00f 114 {"get",getCommand,2,"r",0,NULL,1,1,1,0,0},
115 {"set",setCommand,3,"wm",0,noPreloadGetKeys,1,1,1,0,0},
116 {"setnx",setnxCommand,3,"wm",0,noPreloadGetKeys,1,1,1,0,0},
39da5d1f 117 {"setex",setexCommand,4,"wm",0,noPreloadGetKeys,1,1,1,0,0},
118 {"psetex",psetexCommand,4,"wm",0,noPreloadGetKeys,1,1,1,0,0},
5d02b00f 119 {"append",appendCommand,3,"wm",0,NULL,1,1,1,0,0},
120 {"strlen",strlenCommand,2,"r",0,NULL,1,1,1,0,0},
121 {"del",delCommand,-2,"w",0,noPreloadGetKeys,1,-1,1,0,0},
122 {"exists",existsCommand,2,"r",0,NULL,1,1,1,0,0},
123 {"setbit",setbitCommand,4,"wm",0,NULL,1,1,1,0,0},
124 {"getbit",getbitCommand,3,"r",0,NULL,1,1,1,0,0},
125 {"setrange",setrangeCommand,4,"wm",0,NULL,1,1,1,0,0},
126 {"getrange",getrangeCommand,4,"r",0,NULL,1,1,1,0,0},
127 {"substr",getrangeCommand,4,"r",0,NULL,1,1,1,0,0},
128 {"incr",incrCommand,2,"wm",0,NULL,1,1,1,0,0},
129 {"decr",decrCommand,2,"wm",0,NULL,1,1,1,0,0},
130 {"mget",mgetCommand,-2,"r",0,NULL,1,-1,1,0,0},
131 {"rpush",rpushCommand,-3,"wm",0,NULL,1,1,1,0,0},
132 {"lpush",lpushCommand,-3,"wm",0,NULL,1,1,1,0,0},
133 {"rpushx",rpushxCommand,3,"wm",0,NULL,1,1,1,0,0},
134 {"lpushx",lpushxCommand,3,"wm",0,NULL,1,1,1,0,0},
135 {"linsert",linsertCommand,5,"wm",0,NULL,1,1,1,0,0},
136 {"rpop",rpopCommand,2,"w",0,NULL,1,1,1,0,0},
137 {"lpop",lpopCommand,2,"w",0,NULL,1,1,1,0,0},
e41677b4 138 {"brpop",brpopCommand,-3,"ws",0,NULL,1,1,1,0,0},
139 {"brpoplpush",brpoplpushCommand,4,"wms",0,NULL,1,2,1,0,0},
140 {"blpop",blpopCommand,-3,"ws",0,NULL,1,-2,1,0,0},
5d02b00f 141 {"llen",llenCommand,2,"r",0,NULL,1,1,1,0,0},
142 {"lindex",lindexCommand,3,"r",0,NULL,1,1,1,0,0},
143 {"lset",lsetCommand,4,"wm",0,NULL,1,1,1,0,0},
144 {"lrange",lrangeCommand,4,"r",0,NULL,1,1,1,0,0},
145 {"ltrim",ltrimCommand,4,"w",0,NULL,1,1,1,0,0},
146 {"lrem",lremCommand,4,"w",0,NULL,1,1,1,0,0},
147 {"rpoplpush",rpoplpushCommand,3,"wm",0,NULL,1,2,1,0,0},
148 {"sadd",saddCommand,-3,"wm",0,NULL,1,1,1,0,0},
149 {"srem",sremCommand,-3,"w",0,NULL,1,1,1,0,0},
150 {"smove",smoveCommand,4,"w",0,NULL,1,2,1,0,0},
151 {"sismember",sismemberCommand,3,"r",0,NULL,1,1,1,0,0},
152 {"scard",scardCommand,2,"r",0,NULL,1,1,1,0,0},
15ef6053 153 {"spop",spopCommand,2,"wRs",0,NULL,1,1,1,0,0},
b60ed6e8 154 {"srandmember",srandmemberCommand,2,"rR",0,NULL,1,1,1,0,0},
548efd91 155 {"sinter",sinterCommand,-2,"rS",0,NULL,1,-1,1,0,0},
1bcfa0f6 156 {"sinterstore",sinterstoreCommand,-3,"wm",0,NULL,1,-1,1,0,0},
548efd91 157 {"sunion",sunionCommand,-2,"rS",0,NULL,1,-1,1,0,0},
1bcfa0f6 158 {"sunionstore",sunionstoreCommand,-3,"wm",0,NULL,1,-1,1,0,0},
548efd91 159 {"sdiff",sdiffCommand,-2,"rS",0,NULL,1,-1,1,0,0},
1bcfa0f6 160 {"sdiffstore",sdiffstoreCommand,-3,"wm",0,NULL,1,-1,1,0,0},
548efd91 161 {"smembers",sinterCommand,2,"rS",0,NULL,1,1,1,0,0},
5d02b00f 162 {"zadd",zaddCommand,-4,"wm",0,NULL,1,1,1,0,0},
163 {"zincrby",zincrbyCommand,4,"wm",0,NULL,1,1,1,0,0},
164 {"zrem",zremCommand,-3,"w",0,NULL,1,1,1,0,0},
165 {"zremrangebyscore",zremrangebyscoreCommand,4,"w",0,NULL,1,1,1,0,0},
166 {"zremrangebyrank",zremrangebyrankCommand,4,"w",0,NULL,1,1,1,0,0},
167 {"zunionstore",zunionstoreCommand,-4,"wm",0,zunionInterGetKeys,0,0,0,0,0},
168 {"zinterstore",zinterstoreCommand,-4,"wm",0,zunionInterGetKeys,0,0,0,0,0},
169 {"zrange",zrangeCommand,-4,"r",0,NULL,1,1,1,0,0},
170 {"zrangebyscore",zrangebyscoreCommand,-4,"r",0,NULL,1,1,1,0,0},
171 {"zrevrangebyscore",zrevrangebyscoreCommand,-4,"r",0,NULL,1,1,1,0,0},
172 {"zcount",zcountCommand,4,"r",0,NULL,1,1,1,0,0},
173 {"zrevrange",zrevrangeCommand,-4,"r",0,NULL,1,1,1,0,0},
174 {"zcard",zcardCommand,2,"r",0,NULL,1,1,1,0,0},
175 {"zscore",zscoreCommand,3,"r",0,NULL,1,1,1,0,0},
176 {"zrank",zrankCommand,3,"r",0,NULL,1,1,1,0,0},
177 {"zrevrank",zrevrankCommand,3,"r",0,NULL,1,1,1,0,0},
178 {"hset",hsetCommand,4,"wm",0,NULL,1,1,1,0,0},
179 {"hsetnx",hsetnxCommand,4,"wm",0,NULL,1,1,1,0,0},
180 {"hget",hgetCommand,3,"r",0,NULL,1,1,1,0,0},
181 {"hmset",hmsetCommand,-4,"wm",0,NULL,1,1,1,0,0},
182 {"hmget",hmgetCommand,-3,"r",0,NULL,1,1,1,0,0},
183 {"hincrby",hincrbyCommand,4,"wm",0,NULL,1,1,1,0,0},
68bfe993 184 {"hincrbyfloat",hincrbyfloatCommand,4,"wm",0,NULL,1,1,1,0,0},
5d02b00f 185 {"hdel",hdelCommand,-3,"w",0,NULL,1,1,1,0,0},
186 {"hlen",hlenCommand,2,"r",0,NULL,1,1,1,0,0},
548efd91 187 {"hkeys",hkeysCommand,2,"rS",0,NULL,1,1,1,0,0},
188 {"hvals",hvalsCommand,2,"rS",0,NULL,1,1,1,0,0},
5d02b00f 189 {"hgetall",hgetallCommand,2,"r",0,NULL,1,1,1,0,0},
190 {"hexists",hexistsCommand,3,"r",0,NULL,1,1,1,0,0},
191 {"incrby",incrbyCommand,3,"wm",0,NULL,1,1,1,0,0},
192 {"decrby",decrbyCommand,3,"wm",0,NULL,1,1,1,0,0},
5574b53e 193 {"incrbyfloat",incrbyfloatCommand,3,"wm",0,NULL,1,1,1,0,0},
5d02b00f 194 {"getset",getsetCommand,3,"wm",0,NULL,1,1,1,0,0},
195 {"mset",msetCommand,-3,"wm",0,NULL,1,-1,2,0,0},
196 {"msetnx",msetnxCommand,-3,"wm",0,NULL,1,-1,2,0,0},
b60ed6e8 197 {"randomkey",randomkeyCommand,1,"rR",0,NULL,0,0,0,0,0},
5d02b00f 198 {"select",selectCommand,2,"r",0,NULL,0,0,0,0,0},
199 {"move",moveCommand,3,"w",0,NULL,1,1,1,0,0},
200 {"rename",renameCommand,3,"w",0,renameGetKeys,1,2,1,0,0},
201 {"renamenx",renamenxCommand,3,"w",0,renameGetKeys,1,2,1,0,0},
12d293ca 202 {"expire",expireCommand,3,"w",0,NULL,1,1,1,0,0},
203 {"expireat",expireatCommand,3,"w",0,NULL,1,1,1,0,0},
204 {"pexpire",pexpireCommand,3,"w",0,NULL,1,1,1,0,0},
205 {"pexpireat",pexpireatCommand,3,"w",0,NULL,1,1,1,0,0},
548efd91 206 {"keys",keysCommand,2,"rS",0,NULL,0,0,0,0,0},
5d02b00f 207 {"dbsize",dbsizeCommand,1,"r",0,NULL,0,0,0,0,0},
e41677b4 208 {"auth",authCommand,2,"rs",0,NULL,0,0,0,0,0},
5d02b00f 209 {"ping",pingCommand,1,"r",0,NULL,0,0,0,0,0},
210 {"echo",echoCommand,2,"r",0,NULL,0,0,0,0,0},
e41677b4 211 {"save",saveCommand,1,"ars",0,NULL,0,0,0,0,0},
5d02b00f 212 {"bgsave",bgsaveCommand,1,"ar",0,NULL,0,0,0,0,0},
213 {"bgrewriteaof",bgrewriteaofCommand,1,"ar",0,NULL,0,0,0,0,0},
4ab8695d 214 {"shutdown",shutdownCommand,-1,"ar",0,NULL,0,0,0,0,0},
5d02b00f 215 {"lastsave",lastsaveCommand,1,"r",0,NULL,0,0,0,0,0},
216 {"type",typeCommand,2,"r",0,NULL,1,1,1,0,0},
b60ed6e8 217 {"multi",multiCommand,1,"rs",0,NULL,0,0,0,0,0},
f3fd419f 218 {"exec",execCommand,1,"s",0,NULL,0,0,0,0,0},
b60ed6e8 219 {"discard",discardCommand,1,"rs",0,NULL,0,0,0,0,0},
220 {"sync",syncCommand,1,"ars",0,NULL,0,0,0,0,0},
5d02b00f 221 {"flushdb",flushdbCommand,1,"w",0,NULL,0,0,0,0,0},
222 {"flushall",flushallCommand,1,"w",0,NULL,0,0,0,0,0},
2c861050 223 {"sort",sortCommand,-2,"wmS",0,NULL,1,1,1,0,0},
5d02b00f 224 {"info",infoCommand,-1,"r",0,NULL,0,0,0,0,0},
b60ed6e8 225 {"monitor",monitorCommand,1,"ars",0,NULL,0,0,0,0,0},
12d293ca 226 {"ttl",ttlCommand,2,"r",0,NULL,1,1,1,0,0},
227 {"pttl",pttlCommand,2,"r",0,NULL,1,1,1,0,0},
5d02b00f 228 {"persist",persistCommand,2,"w",0,NULL,1,1,1,0,0},
bb0fbc84 229 {"slaveof",slaveofCommand,3,"as",0,NULL,0,0,0,0,0},
7dcdd281 230 {"debug",debugCommand,-2,"as",0,NULL,0,0,0,0,0},
5d02b00f 231 {"config",configCommand,-2,"ar",0,NULL,0,0,0,0,0},
b60ed6e8 232 {"subscribe",subscribeCommand,-2,"rps",0,NULL,0,0,0,0,0},
233 {"unsubscribe",unsubscribeCommand,-1,"rps",0,NULL,0,0,0,0,0},
234 {"psubscribe",psubscribeCommand,-2,"rps",0,NULL,0,0,0,0,0},
235 {"punsubscribe",punsubscribeCommand,-1,"rps",0,NULL,0,0,0,0,0},
bb0aadbe 236 {"publish",publishCommand,3,"pf",0,NULL,0,0,0,0,0},
b60ed6e8 237 {"watch",watchCommand,-2,"rs",0,noPreloadGetKeys,1,-1,1,0,0},
238 {"unwatch",unwatchCommand,1,"rs",0,NULL,0,0,0,0,0},
5d02b00f 239 {"cluster",clusterCommand,-2,"ar",0,NULL,0,0,0,0,0},
7afc3a96 240 {"restore",restoreCommand,4,"awm",0,NULL,1,1,1,0,0},
5d02b00f 241 {"migrate",migrateCommand,6,"aw",0,NULL,0,0,0,0,0},
6856c7b4 242 {"asking",askingCommand,1,"r",0,NULL,0,0,0,0,0},
1bcfa0f6 243 {"dump",dumpCommand,2,"ar",0,NULL,1,1,1,0,0},
244 {"object",objectCommand,-2,"r",0,NULL,2,2,2,0,0},
5d02b00f 245 {"client",clientCommand,-2,"ar",0,NULL,0,0,0,0,0},
f3fd419f 246 {"eval",evalCommand,-3,"s",0,zunionInterGetKeys,0,0,0,0,0},
247 {"evalsha",evalShaCommand,-3,"s",0,zunionInterGetKeys,0,0,0,0,0},
070e3945 248 {"slowlog",slowlogCommand,-2,"r",0,NULL,0,0,0,0,0},
9494f1f1 249 {"script",scriptCommand,-2,"ras",0,NULL,0,0,0,0,0},
250 {"time",timeCommand,1,"rR",0,NULL,0,0,0,0,0}
e2641e09 251};
252
253/*============================ Utility functions ============================ */
254
9c104c68 255/* Low level logging. To use only for very big messages, otherwise
256 * redisLog() is to prefer. */
257void redisLogRaw(int level, const char *msg) {
e1a586ee
JH
258 const int syslogLevelMap[] = { LOG_DEBUG, LOG_INFO, LOG_NOTICE, LOG_WARNING };
259 const char *c = ".-*#";
e2641e09 260 FILE *fp;
23072961 261 char buf[64];
996d503d 262 int rawmode = (level & REDIS_LOG_RAW);
23072961 263
996d503d 264 level &= 0xff; /* clear flags */
23072961 265 if (level < server.verbosity) return;
e2641e09 266
267 fp = (server.logfile == NULL) ? stdout : fopen(server.logfile,"a");
268 if (!fp) return;
269
996d503d 270 if (rawmode) {
271 fprintf(fp,"%s",msg);
272 } else {
9a322ab7 273 int off;
274 struct timeval tv;
275
276 gettimeofday(&tv,NULL);
277 off = strftime(buf,sizeof(buf),"%d %b %H:%M:%S.",localtime(&tv.tv_sec));
278 snprintf(buf+off,sizeof(buf)-off,"%03d",(int)tv.tv_usec/1000);
996d503d 279 fprintf(fp,"[%d] %s %c %s\n",(int)getpid(),buf,c[level],msg);
280 }
e1a586ee
JH
281 fflush(fp);
282
e2641e09 283 if (server.logfile) fclose(fp);
e1a586ee
JH
284
285 if (server.syslog_enabled) syslog(syslogLevelMap[level], "%s", msg);
e2641e09 286}
287
9c104c68 288/* Like redisLogRaw() but with printf-alike support. This is the funciton that
289 * is used across the code. The raw version is only used in order to dump
290 * the INFO output on crash. */
291void redisLog(int level, const char *fmt, ...) {
292 va_list ap;
293 char msg[REDIS_MAX_LOGMSG_LEN];
294
996d503d 295 if ((level&0xff) < server.verbosity) return;
9c104c68 296
297 va_start(ap, fmt);
298 vsnprintf(msg, sizeof(msg), fmt, ap);
299 va_end(ap);
300
301 redisLogRaw(level,msg);
302}
303
a7d12cba 304/* Log a fixed message without printf-alike capabilities, in a way that is
305 * safe to call from a signal handler.
306 *
307 * We actually use this only for signals that are not fatal from the point
308 * of view of Redis. Signals that are going to kill the server anyway and
309 * where we need printf-alike features are served by redisLog(). */
310void redisLogFromHandler(int level, const char *msg) {
311 int fd;
312 char buf[64];
313
314 if ((level&0xff) < server.verbosity ||
315 (server.logfile == NULL && server.daemonize)) return;
316 fd = server.logfile ?
317 open(server.logfile, O_APPEND|O_CREAT|O_WRONLY, 0644) :
5471b8ba 318 STDOUT_FILENO;
a7d12cba 319 if (fd == -1) return;
320 ll2string(buf,sizeof(buf),getpid());
321 write(fd,"[",1);
322 write(fd,buf,strlen(buf));
323 write(fd," | signal handler] (",20);
324 ll2string(buf,sizeof(buf),time(NULL));
325 write(fd,buf,strlen(buf));
326 write(fd,") ",2);
327 write(fd,msg,strlen(msg));
328 write(fd,"\n",1);
5471b8ba 329 if (server.logfile) close(fd);
a7d12cba 330}
331
e2641e09 332/* Redis generally does not try to recover from out of memory conditions
333 * when allocating objects or strings, it is not clear if it will be possible
334 * to report this condition to the client since the networking layer itself
335 * is based on heap allocation for send buffers, so we simply abort.
336 * At least the code will be simpler to read... */
337void oom(const char *msg) {
338 redisLog(REDIS_WARNING, "%s: Out of memory\n",msg);
339 sleep(1);
340 abort();
341}
342
d9cb288c 343/* Return the UNIX time in microseconds */
344long long ustime(void) {
345 struct timeval tv;
346 long long ust;
347
348 gettimeofday(&tv, NULL);
349 ust = ((long long)tv.tv_sec)*1000000;
350 ust += tv.tv_usec;
351 return ust;
352}
353
2c2b2085 354/* Return the UNIX time in milliseconds */
355long long mstime(void) {
356 return ustime()/1000;
357}
358
e2641e09 359/*====================== Hash table type implementation ==================== */
360
361/* This is an hash table type that uses the SDS dynamic strings libary as
362 * keys and radis objects as values (objects can hold SDS strings,
363 * lists, sets). */
364
365void dictVanillaFree(void *privdata, void *val)
366{
367 DICT_NOTUSED(privdata);
368 zfree(val);
369}
370
371void dictListDestructor(void *privdata, void *val)
372{
373 DICT_NOTUSED(privdata);
374 listRelease((list*)val);
375}
376
377int dictSdsKeyCompare(void *privdata, const void *key1,
378 const void *key2)
379{
380 int l1,l2;
381 DICT_NOTUSED(privdata);
382
383 l1 = sdslen((sds)key1);
384 l2 = sdslen((sds)key2);
385 if (l1 != l2) return 0;
386 return memcmp(key1, key2, l1) == 0;
387}
388
1b1f47c9 389/* A case insensitive version used for the command lookup table. */
390int dictSdsKeyCaseCompare(void *privdata, const void *key1,
391 const void *key2)
392{
393 DICT_NOTUSED(privdata);
394
395 return strcasecmp(key1, key2) == 0;
396}
397
e2641e09 398void dictRedisObjectDestructor(void *privdata, void *val)
399{
400 DICT_NOTUSED(privdata);
401
402 if (val == NULL) return; /* Values of swapped out keys as set to NULL */
403 decrRefCount(val);
404}
405
406void dictSdsDestructor(void *privdata, void *val)
407{
408 DICT_NOTUSED(privdata);
409
410 sdsfree(val);
411}
412
413int dictObjKeyCompare(void *privdata, const void *key1,
414 const void *key2)
415{
416 const robj *o1 = key1, *o2 = key2;
417 return dictSdsKeyCompare(privdata,o1->ptr,o2->ptr);
418}
419
420unsigned int dictObjHash(const void *key) {
421 const robj *o = key;
422 return dictGenHashFunction(o->ptr, sdslen((sds)o->ptr));
423}
424
425unsigned int dictSdsHash(const void *key) {
426 return dictGenHashFunction((unsigned char*)key, sdslen((char*)key));
427}
428
1b1f47c9 429unsigned int dictSdsCaseHash(const void *key) {
430 return dictGenCaseHashFunction((unsigned char*)key, sdslen((char*)key));
431}
432
e2641e09 433int dictEncObjKeyCompare(void *privdata, const void *key1,
434 const void *key2)
435{
436 robj *o1 = (robj*) key1, *o2 = (robj*) key2;
437 int cmp;
438
439 if (o1->encoding == REDIS_ENCODING_INT &&
440 o2->encoding == REDIS_ENCODING_INT)
441 return o1->ptr == o2->ptr;
442
443 o1 = getDecodedObject(o1);
444 o2 = getDecodedObject(o2);
445 cmp = dictSdsKeyCompare(privdata,o1->ptr,o2->ptr);
446 decrRefCount(o1);
447 decrRefCount(o2);
448 return cmp;
449}
450
451unsigned int dictEncObjHash(const void *key) {
452 robj *o = (robj*) key;
453
454 if (o->encoding == REDIS_ENCODING_RAW) {
455 return dictGenHashFunction(o->ptr, sdslen((sds)o->ptr));
456 } else {
457 if (o->encoding == REDIS_ENCODING_INT) {
458 char buf[32];
459 int len;
460
461 len = ll2string(buf,32,(long)o->ptr);
462 return dictGenHashFunction((unsigned char*)buf, len);
463 } else {
464 unsigned int hash;
465
466 o = getDecodedObject(o);
467 hash = dictGenHashFunction(o->ptr, sdslen((sds)o->ptr));
468 decrRefCount(o);
469 return hash;
470 }
471 }
472}
473
4dd444bb 474/* Sets type hash table */
e2641e09 475dictType setDictType = {
476 dictEncObjHash, /* hash function */
477 NULL, /* key dup */
478 NULL, /* val dup */
479 dictEncObjKeyCompare, /* key compare */
480 dictRedisObjectDestructor, /* key destructor */
481 NULL /* val destructor */
482};
483
484/* Sorted sets hash (note: a skiplist is used in addition to the hash table) */
485dictType zsetDictType = {
486 dictEncObjHash, /* hash function */
487 NULL, /* key dup */
488 NULL, /* val dup */
489 dictEncObjKeyCompare, /* key compare */
490 dictRedisObjectDestructor, /* key destructor */
69ef89f2 491 NULL /* val destructor */
e2641e09 492};
493
494/* Db->dict, keys are sds strings, vals are Redis objects. */
495dictType dbDictType = {
496 dictSdsHash, /* hash function */
497 NULL, /* key dup */
498 NULL, /* val dup */
499 dictSdsKeyCompare, /* key compare */
500 dictSdsDestructor, /* key destructor */
501 dictRedisObjectDestructor /* val destructor */
502};
503
504/* Db->expires */
505dictType keyptrDictType = {
506 dictSdsHash, /* hash function */
507 NULL, /* key dup */
508 NULL, /* val dup */
509 dictSdsKeyCompare, /* key compare */
510 NULL, /* key destructor */
511 NULL /* val destructor */
512};
513
1b1f47c9 514/* Command table. sds string -> command struct pointer. */
515dictType commandTableDictType = {
516 dictSdsCaseHash, /* hash function */
517 NULL, /* key dup */
518 NULL, /* val dup */
519 dictSdsKeyCaseCompare, /* key compare */
520 dictSdsDestructor, /* key destructor */
521 NULL /* val destructor */
522};
523
e2641e09 524/* Hash type hash table (note that small hashes are represented with zimpaps) */
525dictType hashDictType = {
526 dictEncObjHash, /* hash function */
527 NULL, /* key dup */
528 NULL, /* val dup */
529 dictEncObjKeyCompare, /* key compare */
530 dictRedisObjectDestructor, /* key destructor */
531 dictRedisObjectDestructor /* val destructor */
532};
533
534/* Keylist hash table type has unencoded redis objects as keys and
535 * lists as values. It's used for blocking operations (BLPOP) and to
536 * map swapped keys to a list of clients waiting for this keys to be loaded. */
537dictType keylistDictType = {
538 dictObjHash, /* hash function */
539 NULL, /* key dup */
540 NULL, /* val dup */
541 dictObjKeyCompare, /* key compare */
542 dictRedisObjectDestructor, /* key destructor */
543 dictListDestructor /* val destructor */
544};
545
ecc91094 546/* Cluster nodes hash table, mapping nodes addresses 1.2.3.4:6379 to
547 * clusterNode structures. */
548dictType clusterNodesDictType = {
549 dictSdsHash, /* hash function */
550 NULL, /* key dup */
551 NULL, /* val dup */
552 dictSdsKeyCompare, /* key compare */
553 dictSdsDestructor, /* key destructor */
554 NULL /* val destructor */
555};
556
e2641e09 557int htNeedsResize(dict *dict) {
558 long long size, used;
559
560 size = dictSlots(dict);
561 used = dictSize(dict);
562 return (size && used && size > DICT_HT_INITIAL_SIZE &&
563 (used*100/size < REDIS_HT_MINFILL));
564}
565
566/* If the percentage of used slots in the HT reaches REDIS_HT_MINFILL
567 * we resize the hash table to save memory */
568void tryResizeHashTables(void) {
569 int j;
570
571 for (j = 0; j < server.dbnum; j++) {
572 if (htNeedsResize(server.db[j].dict))
573 dictResize(server.db[j].dict);
574 if (htNeedsResize(server.db[j].expires))
575 dictResize(server.db[j].expires);
576 }
577}
578
579/* Our hash table implementation performs rehashing incrementally while
580 * we write/read from the hash table. Still if the server is idle, the hash
581 * table will use two tables for a long time. So we try to use 1 millisecond
582 * of CPU time at every serverCron() loop in order to rehash some key. */
583void incrementallyRehash(void) {
584 int j;
585
586 for (j = 0; j < server.dbnum; j++) {
587 if (dictIsRehashing(server.db[j].dict)) {
588 dictRehashMilliseconds(server.db[j].dict,1);
589 break; /* already used our millisecond for this loop... */
590 }
591 }
592}
593
594/* This function is called once a background process of some kind terminates,
595 * as we want to avoid resizing the hash tables when there is a child in order
596 * to play well with copy-on-write (otherwise when a resize happens lots of
597 * memory pages are copied). The goal of this function is to update the ability
598 * for dict.c to resize the hash tables accordingly to the fact we have o not
599 * running childs. */
600void updateDictResizePolicy(void) {
f48cd4b9 601 if (server.rdb_child_pid == -1 && server.aof_child_pid == -1)
e2641e09 602 dictEnableResize();
603 else
604 dictDisableResize();
605}
606
607/* ======================= Cron: called every 100 ms ======================== */
608
bcf2995c 609/* Try to expire a few timed out keys. The algorithm used is adaptive and
610 * will use few CPU cycles if there are few expiring keys, otherwise
611 * it will get more aggressive to avoid that too much memory is used by
612 * keys that can be removed from the keyspace. */
613void activeExpireCycle(void) {
614 int j;
615
616 for (j = 0; j < server.dbnum; j++) {
617 int expired;
618 redisDb *db = server.db+j;
619
620 /* Continue to expire if at the end of the cycle more than 25%
621 * of the keys were expired. */
622 do {
623 long num = dictSize(db->expires);
4be855e7 624 long long now = mstime();
bcf2995c 625
626 expired = 0;
627 if (num > REDIS_EXPIRELOOKUPS_PER_CRON)
628 num = REDIS_EXPIRELOOKUPS_PER_CRON;
629 while (num--) {
630 dictEntry *de;
4be855e7 631 long long t;
bcf2995c 632
633 if ((de = dictGetRandomKey(db->expires)) == NULL) break;
4be855e7 634 t = dictGetSignedIntegerVal(de);
bcf2995c 635 if (now > t) {
c0ba9ebe 636 sds key = dictGetKey(de);
bcf2995c 637 robj *keyobj = createStringObject(key,sdslen(key));
638
639 propagateExpire(db,keyobj);
640 dbDelete(db,keyobj);
641 decrRefCount(keyobj);
642 expired++;
643 server.stat_expiredkeys++;
644 }
645 }
646 } while (expired > REDIS_EXPIRELOOKUPS_PER_CRON/4);
647 }
648}
649
165346ca 650void updateLRUClock(void) {
d1949054 651 server.lruclock = (server.unixtime/REDIS_LRU_CLOCK_RESOLUTION) &
165346ca 652 REDIS_LRU_CLOCK_MAX;
653}
bcf2995c 654
250e7f69 655
656/* Add a sample to the operations per second array of samples. */
657void trackOperationsPerSecond(void) {
658 long long t = mstime() - server.ops_sec_last_sample_time;
659 long long ops = server.stat_numcommands - server.ops_sec_last_sample_ops;
660 long long ops_sec;
661
662 ops_sec = t > 0 ? (ops*1000/t) : 0;
663
664 server.ops_sec_samples[server.ops_sec_idx] = ops_sec;
665 server.ops_sec_idx = (server.ops_sec_idx+1) % REDIS_OPS_SEC_SAMPLES;
666 server.ops_sec_last_sample_time = mstime();
667 server.ops_sec_last_sample_ops = server.stat_numcommands;
668}
669
670/* Return the mean of all the samples. */
671long long getOperationsPerSecond(void) {
672 int j;
673 long long sum = 0;
674
675 for (j = 0; j < REDIS_OPS_SEC_SAMPLES; j++)
676 sum += server.ops_sec_samples[j];
677 return sum / REDIS_OPS_SEC_SAMPLES;
678}
679
c9d3dda2 680/* Check for timeouts. Returns non-zero if the client was terminated */
681int clientsCronHandleTimeout(redisClient *c) {
ae22bf1e 682 time_t now = server.unixtime;
d19015be 683
684 if (server.maxidletime &&
685 !(c->flags & REDIS_SLAVE) && /* no timeout for slaves */
686 !(c->flags & REDIS_MASTER) && /* no timeout for masters */
687 !(c->flags & REDIS_BLOCKED) && /* no timeout for BLPOP */
688 dictSize(c->pubsub_channels) == 0 && /* no timeout for pubsub */
689 listLength(c->pubsub_patterns) == 0 &&
690 (now - c->lastinteraction > server.maxidletime))
691 {
692 redisLog(REDIS_VERBOSE,"Closing idle client");
693 freeClient(c);
c9d3dda2 694 return 1;
d19015be 695 } else if (c->flags & REDIS_BLOCKED) {
696 if (c->bpop.timeout != 0 && c->bpop.timeout < now) {
697 addReply(c,shared.nullmultibulk);
698 unblockClientWaitingData(c);
699 }
700 }
c9d3dda2 701 return 0;
d19015be 702}
703
ae22bf1e 704/* The client query buffer is an sds.c string that can end with a lot of
c9d3dda2 705 * free space not used, this function reclaims space if needed.
706 *
707 * The funciton always returns 0 as it never terminates the client. */
708int clientsCronResizeQueryBuffer(redisClient *c) {
ae22bf1e 709 size_t querybuf_size = sdsAllocSize(c->querybuf);
710 time_t idletime = server.unixtime - c->lastinteraction;
711
712 /* There are two conditions to resize the query buffer:
713 * 1) Query buffer is > BIG_ARG and too big for latest peak.
714 * 2) Client is inactive and the buffer is bigger than 1k. */
715 if (((querybuf_size > REDIS_MBULK_BIG_ARG) &&
716 (querybuf_size/(c->querybuf_peak+1)) > 2) ||
717 (querybuf_size > 1024 && idletime > 2))
718 {
719 /* Only resize the query buffer if it is actually wasting space. */
720 if (sdsavail(c->querybuf) > 1024) {
721 c->querybuf = sdsRemoveFreeSpace(c->querybuf);
722 }
723 }
724 /* Reset the peak again to capture the peak memory usage in the next
725 * cycle. */
726 c->querybuf_peak = 0;
c9d3dda2 727 return 0;
ae22bf1e 728}
729
d19015be 730void clientsCron(void) {
731 /* Make sure to process at least 1/100 of clients per call.
732 * Since this function is called 10 times per second we are sure that
733 * in the worst case we process all the clients in 10 seconds.
734 * In normal conditions (a reasonable number of clients) we process
735 * all the clients in a shorter time. */
ae22bf1e 736 int numclients = listLength(server.clients);
737 int iterations = numclients/100;
d19015be 738
ae22bf1e 739 if (iterations < 50)
740 iterations = (numclients < 50) ? numclients : 50;
d19015be 741 while(listLength(server.clients) && iterations--) {
742 redisClient *c;
743 listNode *head;
744
745 /* Rotate the list, take the current head, process.
746 * This way if the client must be removed from the list it's the
747 * first element and we don't incur into O(N) computation. */
748 listRotate(server.clients);
749 head = listFirst(server.clients);
750 c = listNodeValue(head);
c9d3dda2 751 /* The following functions do different service checks on the client.
752 * The protocol is that they return non-zero if the client was
753 * terminated. */
754 if (clientsCronHandleTimeout(c)) continue;
755 if (clientsCronResizeQueryBuffer(c)) continue;
d19015be 756 }
757}
758
e2641e09 759int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
89a1433e 760 int j, loops = server.cronloops;
e2641e09 761 REDIS_NOTUSED(eventLoop);
762 REDIS_NOTUSED(id);
763 REDIS_NOTUSED(clientData);
764
39bd025c 765 /* Software watchdog: deliver the SIGALRM that will reach the signal
766 * handler if we don't return here fast enough. */
767 if (server.watchdog_period) watchdogScheduleSignal(server.watchdog_period);
768
e2641e09 769 /* We take a cached value of the unix time in the global state because
770 * with virtual memory and aging there is to store the current time
771 * in objects at every object access, and accuracy is not needed.
772 * To access a global var is faster than calling time(NULL) */
773 server.unixtime = time(NULL);
4f06867a 774
250e7f69 775 trackOperationsPerSecond();
776
ef59a8bc 777 /* We have just 22 bits per object for LRU information.
165346ca 778 * So we use an (eventually wrapping) LRU clock with 10 seconds resolution.
779 * 2^22 bits with 10 seconds resoluton is more or less 1.5 years.
e2641e09 780 *
165346ca 781 * Note that even if this will wrap after 1.5 years it's not a problem,
ef59a8bc 782 * everything will still work but just some object will appear younger
165346ca 783 * to Redis. But for this to happen a given object should never be touched
784 * for 1.5 years.
785 *
786 * Note that you can change the resolution altering the
787 * REDIS_LRU_CLOCK_RESOLUTION define.
e2641e09 788 */
165346ca 789 updateLRUClock();
e2641e09 790
17b24ff3 791 /* Record the max memory used since the server was started. */
792 if (zmalloc_used_memory() > server.stat_peak_memory)
793 server.stat_peak_memory = zmalloc_used_memory();
794
e2641e09 795 /* We received a SIGTERM, shutting down here in a safe way, as it is
796 * not ok doing so inside the signal handler. */
797 if (server.shutdown_asap) {
4ab8695d 798 if (prepareForShutdown(0) == REDIS_OK) exit(0);
e2641e09 799 redisLog(REDIS_WARNING,"SIGTERM received but errors trying to shut down the server, check the logs for more information");
800 }
801
802 /* Show some info about non-empty databases */
803 for (j = 0; j < server.dbnum; j++) {
804 long long size, used, vkeys;
805
806 size = dictSlots(server.db[j].dict);
807 used = dictSize(server.db[j].dict);
808 vkeys = dictSize(server.db[j].expires);
809 if (!(loops % 50) && (used || vkeys)) {
810 redisLog(REDIS_VERBOSE,"DB %d: %lld keys (%lld volatile) in %lld slots HT.",j,used,vkeys,size);
811 /* dictPrintStats(server.dict); */
812 }
813 }
814
815 /* We don't want to resize the hash tables while a bacground saving
816 * is in progress: the saving child is created using fork() that is
817 * implemented with a copy-on-write semantic in most modern systems, so
818 * if we resize the HT while there is the saving child at work actually
819 * a lot of memory movements in the parent will cause a lot of pages
820 * copied. */
f48cd4b9 821 if (server.rdb_child_pid == -1 && server.aof_child_pid == -1) {
e2641e09 822 if (!(loops % 10)) tryResizeHashTables();
823 if (server.activerehashing) incrementallyRehash();
824 }
825
826 /* Show information about connected clients */
827 if (!(loops % 50)) {
828 redisLog(REDIS_VERBOSE,"%d clients connected (%d slaves), %zu bytes in use",
829 listLength(server.clients)-listLength(server.slaves),
830 listLength(server.slaves),
ca734d17 831 zmalloc_used_memory());
e2641e09 832 }
833
d19015be 834 /* We need to do a few operations on clients asynchronously. */
835 clientsCron();
e2641e09 836
b333e239 837 /* Start a scheduled AOF rewrite if this was requested by the user while
838 * a BGSAVE was in progress. */
f48cd4b9 839 if (server.rdb_child_pid == -1 && server.aof_child_pid == -1 &&
2c915bcf 840 server.aof_rewrite_scheduled)
b333e239 841 {
842 rewriteAppendOnlyFileBackground();
843 }
844
f03fe802 845 /* Check if a background saving or AOF rewrite in progress terminated. */
f48cd4b9 846 if (server.rdb_child_pid != -1 || server.aof_child_pid != -1) {
e2641e09 847 int statloc;
848 pid_t pid;
849
850 if ((pid = wait3(&statloc,WNOHANG,NULL)) != 0) {
36c17a53 851 int exitcode = WEXITSTATUS(statloc);
852 int bysignal = 0;
853
854 if (WIFSIGNALED(statloc)) bysignal = WTERMSIG(statloc);
855
f48cd4b9 856 if (pid == server.rdb_child_pid) {
36c17a53 857 backgroundSaveDoneHandler(exitcode,bysignal);
e2641e09 858 } else {
36c17a53 859 backgroundRewriteDoneHandler(exitcode,bysignal);
e2641e09 860 }
861 updateDictResizePolicy();
862 }
c9d0c362 863 } else {
b333e239 864 /* If there is not a background saving/rewrite in progress check if
865 * we have to save/rewrite now */
e2641e09 866 for (j = 0; j < server.saveparamslen; j++) {
867 struct saveparam *sp = server.saveparams+j;
868
869 if (server.dirty >= sp->changes &&
d1949054 870 server.unixtime-server.lastsave > sp->seconds) {
e2641e09 871 redisLog(REDIS_NOTICE,"%d changes in %d seconds. Saving...",
872 sp->changes, sp->seconds);
f48cd4b9 873 rdbSaveBackground(server.rdb_filename);
e2641e09 874 break;
875 }
876 }
b333e239 877
878 /* Trigger an AOF rewrite if needed */
f48cd4b9 879 if (server.rdb_child_pid == -1 &&
ff2145ad 880 server.aof_child_pid == -1 &&
2c915bcf 881 server.aof_rewrite_perc &&
882 server.aof_current_size > server.aof_rewrite_min_size)
b333e239 883 {
2c915bcf 884 long long base = server.aof_rewrite_base_size ?
885 server.aof_rewrite_base_size : 1;
886 long long growth = (server.aof_current_size*100/base) - 100;
887 if (growth >= server.aof_rewrite_perc) {
19b46c9a 888 redisLog(REDIS_NOTICE,"Starting automatic rewriting of AOF on %lld%% growth",growth);
b333e239 889 rewriteAppendOnlyFileBackground();
890 }
891 }
e2641e09 892 }
893
db3c2a4f 894
895 /* If we postponed an AOF buffer flush, let's try to do it every time the
896 * cron function is called. */
897 if (server.aof_flush_postponed_start) flushAppendOnlyFile(0);
898
bcf2995c 899 /* Expire a few keys per cycle, only if this is a master.
900 * On slaves we wait for DEL operations synthesized by the master
901 * in order to guarantee a strict consistency. */
902 if (server.masterhost == NULL) activeExpireCycle();
e2641e09 903
8c43e663 904 /* Close clients that need to be closed asynchronous */
905 freeClientsInAsyncFreeQueue();
906
f4aa600b 907 /* Replication cron function -- used to reconnect to master and
908 * to detect transfer failures. */
62ec599c 909 if (!(loops % 10)) replicationCron();
f4aa600b 910
ecc91094 911 /* Run other sub-systems specific cron jobs */
912 if (server.cluster_enabled && !(loops % 10)) clusterCron();
913
89a1433e 914 server.cronloops++;
e2641e09 915 return 100;
916}
917
918/* This function gets called every time Redis is entering the
919 * main loop of the event driven library, that is, before to sleep
920 * for ready file descriptors. */
921void beforeSleep(struct aeEventLoop *eventLoop) {
922 REDIS_NOTUSED(eventLoop);
a4ce7581
PN
923 listNode *ln;
924 redisClient *c;
e2641e09 925
a4ce7581
PN
926 /* Try to process pending commands for clients that were just unblocked. */
927 while (listLength(server.unblocked_clients)) {
928 ln = listFirst(server.unblocked_clients);
929 redisAssert(ln != NULL);
930 c = ln->value;
931 listDelNode(server.unblocked_clients,ln);
3bcffcbe 932 c->flags &= ~REDIS_UNBLOCKED;
a4ce7581
PN
933
934 /* Process remaining data in the input buffer. */
00010fa9 935 if (c->querybuf && sdslen(c->querybuf) > 0) {
936 server.current_client = c;
a4ce7581 937 processInputBuffer(c);
00010fa9 938 server.current_client = NULL;
939 }
a4ce7581
PN
940 }
941
e2641e09 942 /* Write the AOF buffer on disk */
db3c2a4f 943 flushAppendOnlyFile(0);
e2641e09 944}
945
946/* =========================== Server initialization ======================== */
947
948void createSharedObjects(void) {
949 int j;
950
951 shared.crlf = createObject(REDIS_STRING,sdsnew("\r\n"));
952 shared.ok = createObject(REDIS_STRING,sdsnew("+OK\r\n"));
953 shared.err = createObject(REDIS_STRING,sdsnew("-ERR\r\n"));
954 shared.emptybulk = createObject(REDIS_STRING,sdsnew("$0\r\n\r\n"));
955 shared.czero = createObject(REDIS_STRING,sdsnew(":0\r\n"));
956 shared.cone = createObject(REDIS_STRING,sdsnew(":1\r\n"));
957 shared.cnegone = createObject(REDIS_STRING,sdsnew(":-1\r\n"));
958 shared.nullbulk = createObject(REDIS_STRING,sdsnew("$-1\r\n"));
959 shared.nullmultibulk = createObject(REDIS_STRING,sdsnew("*-1\r\n"));
960 shared.emptymultibulk = createObject(REDIS_STRING,sdsnew("*0\r\n"));
961 shared.pong = createObject(REDIS_STRING,sdsnew("+PONG\r\n"));
962 shared.queued = createObject(REDIS_STRING,sdsnew("+QUEUED\r\n"));
963 shared.wrongtypeerr = createObject(REDIS_STRING,sdsnew(
964 "-ERR Operation against a key holding the wrong kind of value\r\n"));
965 shared.nokeyerr = createObject(REDIS_STRING,sdsnew(
966 "-ERR no such key\r\n"));
967 shared.syntaxerr = createObject(REDIS_STRING,sdsnew(
968 "-ERR syntax error\r\n"));
969 shared.sameobjecterr = createObject(REDIS_STRING,sdsnew(
970 "-ERR source and destination objects are the same\r\n"));
971 shared.outofrangeerr = createObject(REDIS_STRING,sdsnew(
972 "-ERR index out of range\r\n"));
7229d60d 973 shared.noscripterr = createObject(REDIS_STRING,sdsnew(
974 "-NOSCRIPT No matching script. Please use EVAL.\r\n"));
97e7f8ae 975 shared.loadingerr = createObject(REDIS_STRING,sdsnew(
976 "-LOADING Redis is loading the dataset in memory\r\n"));
115e3ff3 977 shared.slowscripterr = createObject(REDIS_STRING,sdsnew(
4ab8695d 978 "-BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.\r\n"));
c25e7eaf 979 shared.bgsaveerr = createObject(REDIS_STRING,sdsnew(
f3fd419f 980 "-MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.\r\n"));
981 shared.roslaveerr = createObject(REDIS_STRING,sdsnew(
982 "-READONLY You can't write against a read only slave.\r\n"));
b22eab8f 983 shared.oomerr = createObject(REDIS_STRING,sdsnew(
984 "-OOM command not allowed when used memory > 'maxmemory'.\r\n"));
e2641e09 985 shared.space = createObject(REDIS_STRING,sdsnew(" "));
986 shared.colon = createObject(REDIS_STRING,sdsnew(":"));
987 shared.plus = createObject(REDIS_STRING,sdsnew("+"));
f892797e
JJ
988
989 for (j = 0; j < REDIS_SHARED_SELECT_CMDS; j++) {
990 shared.select[j] = createObject(REDIS_STRING,
991 sdscatprintf(sdsempty(),"select %d\r\n", j));
992 }
e2641e09 993 shared.messagebulk = createStringObject("$7\r\nmessage\r\n",13);
994 shared.pmessagebulk = createStringObject("$8\r\npmessage\r\n",14);
995 shared.subscribebulk = createStringObject("$9\r\nsubscribe\r\n",15);
996 shared.unsubscribebulk = createStringObject("$11\r\nunsubscribe\r\n",18);
997 shared.psubscribebulk = createStringObject("$10\r\npsubscribe\r\n",17);
998 shared.punsubscribebulk = createStringObject("$12\r\npunsubscribe\r\n",19);
355f8591 999 shared.del = createStringObject("DEL",3);
c1db214e 1000 shared.rpop = createStringObject("RPOP",4);
1001 shared.lpop = createStringObject("LPOP",4);
e2641e09 1002 for (j = 0; j < REDIS_SHARED_INTEGERS; j++) {
1003 shared.integers[j] = createObject(REDIS_STRING,(void*)(long)j);
1004 shared.integers[j]->encoding = REDIS_ENCODING_INT;
1005 }
355f8591 1006 for (j = 0; j < REDIS_SHARED_BULKHDR_LEN; j++) {
1007 shared.mbulkhdr[j] = createObject(REDIS_STRING,
1008 sdscatprintf(sdsempty(),"*%d\r\n",j));
1009 shared.bulkhdr[j] = createObject(REDIS_STRING,
1010 sdscatprintf(sdsempty(),"$%d\r\n",j));
1011 }
e2641e09 1012}
1013
1014void initServerConfig() {
91d664d6 1015 getRandomHexChars(server.runid,REDIS_RUN_ID_SIZE);
1016 server.runid[REDIS_RUN_ID_SIZE] = '\0';
75eaac5c 1017 server.arch_bits = (sizeof(long) == 8) ? 64 : 32;
e2641e09 1018 server.port = REDIS_SERVERPORT;
a5639e7d 1019 server.bindaddr = NULL;
5d10923f 1020 server.unixsocket = NULL;
85238765 1021 server.unixsocketperm = 0;
a5639e7d
PN
1022 server.ipfd = -1;
1023 server.sofd = -1;
1024 server.dbnum = REDIS_DEFAULT_DBNUM;
c6f9ee88 1025 server.verbosity = REDIS_NOTICE;
e2641e09 1026 server.maxidletime = REDIS_MAXIDLETIME;
becf5fdb 1027 server.client_max_querybuf_len = REDIS_MAX_QUERYBUF_LEN;
e2641e09 1028 server.saveparams = NULL;
97e7f8ae 1029 server.loading = 0;
e2641e09 1030 server.logfile = NULL; /* NULL = log on standard output */
e1a586ee
JH
1031 server.syslog_enabled = 0;
1032 server.syslog_ident = zstrdup("redis");
1033 server.syslog_facility = LOG_LOCAL0;
e2641e09 1034 server.daemonize = 0;
e394114d 1035 server.aof_state = REDIS_AOF_OFF;
2c915bcf 1036 server.aof_fsync = AOF_FSYNC_EVERYSEC;
1037 server.aof_no_fsync_on_rewrite = 0;
1038 server.aof_rewrite_perc = REDIS_AOF_REWRITE_PERC;
1039 server.aof_rewrite_min_size = REDIS_AOF_REWRITE_MIN_SIZE;
1040 server.aof_rewrite_base_size = 0;
1041 server.aof_rewrite_scheduled = 0;
ff2145ad 1042 server.aof_last_fsync = time(NULL);
c1d01b3c 1043 server.aof_delayed_fsync = 0;
ff2145ad 1044 server.aof_fd = -1;
1045 server.aof_selected_db = -1; /* Make sure the first time will not match */
db3c2a4f 1046 server.aof_flush_postponed_start = 0;
e2641e09 1047 server.pidfile = zstrdup("/var/run/redis.pid");
f48cd4b9 1048 server.rdb_filename = zstrdup("dump.rdb");
2c915bcf 1049 server.aof_filename = zstrdup("appendonly.aof");
e2641e09 1050 server.requirepass = NULL;
f48cd4b9 1051 server.rdb_compression = 1;
e2641e09 1052 server.activerehashing = 1;
58732c23 1053 server.maxclients = REDIS_MAX_CLIENTS;
5fa95ad7 1054 server.bpop_blocked_clients = 0;
e2641e09 1055 server.maxmemory = 0;
165346ca 1056 server.maxmemory_policy = REDIS_MAXMEMORY_VOLATILE_LRU;
1057 server.maxmemory_samples = 3;
ebd85e9a
PN
1058 server.hash_max_ziplist_entries = REDIS_HASH_MAX_ZIPLIST_ENTRIES;
1059 server.hash_max_ziplist_value = REDIS_HASH_MAX_ZIPLIST_VALUE;
e2641e09 1060 server.list_max_ziplist_entries = REDIS_LIST_MAX_ZIPLIST_ENTRIES;
1061 server.list_max_ziplist_value = REDIS_LIST_MAX_ZIPLIST_VALUE;
96ffb2fe 1062 server.set_max_intset_entries = REDIS_SET_MAX_INTSET_ENTRIES;
3ea204e1
PN
1063 server.zset_max_ziplist_entries = REDIS_ZSET_MAX_ZIPLIST_ENTRIES;
1064 server.zset_max_ziplist_value = REDIS_ZSET_MAX_ZIPLIST_VALUE;
e2641e09 1065 server.shutdown_asap = 0;
aeecbdfa 1066 server.repl_ping_slave_period = REDIS_REPL_PING_SLAVE_PERIOD;
1067 server.repl_timeout = REDIS_REPL_TIMEOUT;
ecc91094 1068 server.cluster_enabled = 0;
ef21ab96 1069 server.cluster.configfile = zstrdup("nodes.conf");
4ab8695d 1070 server.lua_caller = NULL;
eeffcf38 1071 server.lua_time_limit = REDIS_LUA_TIME_LIMIT;
070e3945 1072 server.lua_client = NULL;
115e3ff3 1073 server.lua_timedout = 0;
e2641e09 1074
95506e46 1075 updateLRUClock();
e2641e09 1076 resetServerSaveParams();
1077
1078 appendServerSaveParams(60*60,1); /* save after 1 hour and 1 change */
1079 appendServerSaveParams(300,100); /* save after 5 minutes and 100 changes */
1080 appendServerSaveParams(60,10000); /* save after 1 minute and 10000 changes */
1081 /* Replication related */
e2641e09 1082 server.masterauth = NULL;
1083 server.masterhost = NULL;
1084 server.masterport = 6379;
1085 server.master = NULL;
1844f990 1086 server.repl_state = REDIS_REPL_NONE;
890a2ed9 1087 server.repl_syncio_timeout = REDIS_REPL_SYNCIO_TIMEOUT;
4ebfc455 1088 server.repl_serve_stale_data = 1;
f3fd419f 1089 server.repl_slave_ro = 1;
4b8c9661 1090 server.repl_down_since = time(NULL);
e2641e09 1091
7eac2a75 1092 /* Client output buffer limits */
1093 server.client_obuf_limits[REDIS_CLIENT_LIMIT_CLASS_NORMAL].hard_limit_bytes = 0;
1094 server.client_obuf_limits[REDIS_CLIENT_LIMIT_CLASS_NORMAL].soft_limit_bytes = 0;
1095 server.client_obuf_limits[REDIS_CLIENT_LIMIT_CLASS_NORMAL].soft_limit_seconds = 0;
c8a607f2 1096 server.client_obuf_limits[REDIS_CLIENT_LIMIT_CLASS_SLAVE].hard_limit_bytes = 1024*1024*256;
1097 server.client_obuf_limits[REDIS_CLIENT_LIMIT_CLASS_SLAVE].soft_limit_bytes = 1024*1024*64;
7eac2a75 1098 server.client_obuf_limits[REDIS_CLIENT_LIMIT_CLASS_SLAVE].soft_limit_seconds = 60;
c8a607f2 1099 server.client_obuf_limits[REDIS_CLIENT_LIMIT_CLASS_PUBSUB].hard_limit_bytes = 1024*1024*32;
1100 server.client_obuf_limits[REDIS_CLIENT_LIMIT_CLASS_PUBSUB].soft_limit_bytes = 1024*1024*8;
7eac2a75 1101 server.client_obuf_limits[REDIS_CLIENT_LIMIT_CLASS_PUBSUB].soft_limit_seconds = 60;
1102
e2641e09 1103 /* Double constants initialization */
1104 R_Zero = 0.0;
1105 R_PosInf = 1.0/R_Zero;
1106 R_NegInf = -1.0/R_Zero;
1107 R_Nan = R_Zero/R_Zero;
8d3e063a 1108
1109 /* Command table -- we intiialize it here as it is part of the
1110 * initial configuration, since command names may be changed via
1111 * redis.conf using the rename-command directive. */
1112 server.commands = dictCreate(&commandTableDictType,NULL);
1113 populateCommandTable();
1114 server.delCommand = lookupCommandByCString("del");
1115 server.multiCommand = lookupCommandByCString("multi");
eeb34eff 1116 server.lpushCommand = lookupCommandByCString("lpush");
daa70b17 1117
1118 /* Slow log */
1119 server.slowlog_log_slower_than = REDIS_SLOWLOG_LOG_SLOWER_THAN;
1120 server.slowlog_max_len = REDIS_SLOWLOG_MAX_LEN;
fa5af017 1121
39bd025c 1122 /* Debugging */
fa5af017 1123 server.assert_failed = "<no assertion failed>";
1124 server.assert_file = "<no file>";
1125 server.assert_line = 0;
1126 server.bug_report_start = 0;
39bd025c 1127 server.watchdog_period = 0;
e2641e09 1128}
1129
e074416b 1130/* This function will try to raise the max number of open files accordingly to
1131 * the configured max number of clients. It will also account for 32 additional
1132 * file descriptors as we need a few more for persistence, listening
1133 * sockets, log files and so forth.
1134 *
1135 * If it will not be possible to set the limit accordingly to the configured
1136 * max number of clients, the function will do the reverse setting
1137 * server.maxclients to the value that we can actually handle. */
1138void adjustOpenFilesLimit(void) {
1139 rlim_t maxfiles = server.maxclients+32;
1140 struct rlimit limit;
1141
1142 if (maxfiles < 1024) maxfiles = 1024;
1143 if (getrlimit(RLIMIT_NOFILE,&limit) == -1) {
1144 redisLog(REDIS_WARNING,"Unable to obtain the current NOFILE limit (%s), assuming 1024 and setting the max clients configuration accordingly.",
1145 strerror(errno));
1146 server.maxclients = 1024-32;
1147 } else {
1148 rlim_t oldlimit = limit.rlim_cur;
1149
1150 /* Set the max number of files if the current limit is not enough
1151 * for our needs. */
1152 if (oldlimit < maxfiles) {
e7957ca6 1153 rlim_t f;
1154
1155 f = maxfiles;
1156 while(f > oldlimit) {
1157 limit.rlim_cur = f;
1158 limit.rlim_max = f;
1159 if (setrlimit(RLIMIT_NOFILE,&limit) != -1) break;
1160 f -= 128;
1161 }
1162 if (f < oldlimit) f = oldlimit;
1163 if (f != maxfiles) {
1164 server.maxclients = f-32;
e074416b 1165 redisLog(REDIS_WARNING,"Unable to set the max number of files limit to %d (%s), setting the max clients configuration to %d.",
1166 (int) maxfiles, strerror(errno), (int) server.maxclients);
1167 } else {
1168 redisLog(REDIS_NOTICE,"Max number of open files set to %d",
1169 (int) maxfiles);
1170 }
1171 }
1172 }
1173}
1174
e2641e09 1175void initServer() {
1176 int j;
1177
1178 signal(SIGHUP, SIG_IGN);
1179 signal(SIGPIPE, SIG_IGN);
633a9410 1180 setupSignalHandlers();
e2641e09 1181
e1a586ee
JH
1182 if (server.syslog_enabled) {
1183 openlog(server.syslog_ident, LOG_PID | LOG_NDELAY | LOG_NOWAIT,
1184 server.syslog_facility);
1185 }
1186
00010fa9 1187 server.current_client = NULL;
e2641e09 1188 server.clients = listCreate();
7eac2a75 1189 server.clients_to_close = listCreate();
e2641e09 1190 server.slaves = listCreate();
1191 server.monitors = listCreate();
a4ce7581 1192 server.unblocked_clients = listCreate();
cea8c5cd 1193
e2641e09 1194 createSharedObjects();
e074416b 1195 adjustOpenFilesLimit();
1196 server.el = aeCreateEventLoop(server.maxclients+1024);
e2641e09 1197 server.db = zmalloc(sizeof(redisDb)*server.dbnum);
68d6345d 1198
a53b4c24 1199 if (server.port != 0) {
68d6345d 1200 server.ipfd = anetTcpServer(server.neterr,server.port,server.bindaddr);
a53b4c24 1201 if (server.ipfd == ANET_ERR) {
eef17490 1202 redisLog(REDIS_WARNING, "Opening port %d: %s",
1203 server.port, server.neterr);
a53b4c24 1204 exit(1);
1205 }
a5639e7d 1206 }
5d10923f
PN
1207 if (server.unixsocket != NULL) {
1208 unlink(server.unixsocket); /* don't care if this fails */
85238765 1209 server.sofd = anetUnixServer(server.neterr,server.unixsocket,server.unixsocketperm);
a5639e7d
PN
1210 if (server.sofd == ANET_ERR) {
1211 redisLog(REDIS_WARNING, "Opening socket: %s", server.neterr);
1212 exit(1);
1213 }
c61e6925 1214 }
a5639e7d
PN
1215 if (server.ipfd < 0 && server.sofd < 0) {
1216 redisLog(REDIS_WARNING, "Configured to not listen anywhere, exiting.");
e2641e09 1217 exit(1);
1218 }
1219 for (j = 0; j < server.dbnum; j++) {
1220 server.db[j].dict = dictCreate(&dbDictType,NULL);
1221 server.db[j].expires = dictCreate(&keyptrDictType,NULL);
1222 server.db[j].blocking_keys = dictCreate(&keylistDictType,NULL);
1223 server.db[j].watched_keys = dictCreate(&keylistDictType,NULL);
e2641e09 1224 server.db[j].id = j;
1225 }
1226 server.pubsub_channels = dictCreate(&keylistDictType,NULL);
1227 server.pubsub_patterns = listCreate();
1228 listSetFreeMethod(server.pubsub_patterns,freePubsubPattern);
1229 listSetMatchMethod(server.pubsub_patterns,listMatchPubsubPattern);
1230 server.cronloops = 0;
f48cd4b9 1231 server.rdb_child_pid = -1;
ff2145ad 1232 server.aof_child_pid = -1;
1233 server.aof_rewrite_buf = sdsempty();
1234 server.aof_buf = sdsempty();
e2641e09 1235 server.lastsave = time(NULL);
1236 server.dirty = 0;
1237 server.stat_numcommands = 0;
1238 server.stat_numconnections = 0;
1239 server.stat_expiredkeys = 0;
f21779ff 1240 server.stat_evictedkeys = 0;
e2641e09 1241 server.stat_starttime = time(NULL);
53eeeaff 1242 server.stat_keyspace_misses = 0;
1243 server.stat_keyspace_hits = 0;
17b24ff3 1244 server.stat_peak_memory = 0;
615e414c 1245 server.stat_fork_time = 0;
3c95e721 1246 server.stat_rejected_conn = 0;
250e7f69 1247 memset(server.ops_sec_samples,0,sizeof(server.ops_sec_samples));
1248 server.ops_sec_idx = 0;
1249 server.ops_sec_last_sample_time = mstime();
1250 server.ops_sec_last_sample_ops = 0;
e2641e09 1251 server.unixtime = time(NULL);
c25e7eaf 1252 server.lastbgsave_status = REDIS_OK;
4d3bbf35 1253 server.stop_writes_on_bgsave_err = 1;
e2641e09 1254 aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL);
a5639e7d 1255 if (server.ipfd > 0 && aeCreateFileEvent(server.el,server.ipfd,AE_READABLE,
ab17b909 1256 acceptTcpHandler,NULL) == AE_ERR) oom("creating file event");
a5639e7d 1257 if (server.sofd > 0 && aeCreateFileEvent(server.el,server.sofd,AE_READABLE,
ab17b909 1258 acceptUnixHandler,NULL) == AE_ERR) oom("creating file event");
e2641e09 1259
e394114d 1260 if (server.aof_state == REDIS_AOF_ON) {
ff2145ad 1261 server.aof_fd = open(server.aof_filename,
e394114d 1262 O_WRONLY|O_APPEND|O_CREAT,0644);
ff2145ad 1263 if (server.aof_fd == -1) {
e2641e09 1264 redisLog(REDIS_WARNING, "Can't open the append-only file: %s",
1265 strerror(errno));
1266 exit(1);
1267 }
1268 }
1269
d876678b 1270 /* 32 bit instances are limited to 4GB of address space, so if there is
1271 * no explicit limit in the user provided configuration we set a limit
1272 * at 3.5GB using maxmemory with 'noeviction' policy'. This saves
1273 * useless crashes of the Redis instance. */
1274 if (server.arch_bits == 32 && server.maxmemory == 0) {
1275 redisLog(REDIS_WARNING,"Warning: 32 bit instance detected but no memory limit set. Setting 3.5 GB maxmemory limit with 'noeviction' policy now.");
1276 server.maxmemory = 3584LL*(1024*1024); /* 3584 MB = 3.5 GB */
1277 server.maxmemory_policy = REDIS_MAXMEMORY_NO_EVICTION;
1278 }
1279
ecc91094 1280 if (server.cluster_enabled) clusterInit();
7585836e 1281 scriptingInit();
daa70b17 1282 slowlogInit();
8f61a72f 1283 bioInit();
e2641e09 1284}
1285
1b1f47c9 1286/* Populates the Redis Command Table starting from the hard coded list
1287 * we have on top of redis.c file. */
1288void populateCommandTable(void) {
1289 int j;
d7ed7fd2 1290 int numcommands = sizeof(redisCommandTable)/sizeof(struct redisCommand);
1b1f47c9 1291
1292 for (j = 0; j < numcommands; j++) {
d7ed7fd2 1293 struct redisCommand *c = redisCommandTable+j;
5d02b00f 1294 char *f = c->sflags;
1b1f47c9 1295 int retval;
e2641e09 1296
5d02b00f 1297 while(*f != '\0') {
1298 switch(*f) {
1299 case 'w': c->flags |= REDIS_CMD_WRITE; break;
1300 case 'r': c->flags |= REDIS_CMD_READONLY; break;
1301 case 'm': c->flags |= REDIS_CMD_DENYOOM; break;
1302 case 'a': c->flags |= REDIS_CMD_ADMIN; break;
1303 case 'p': c->flags |= REDIS_CMD_PUBSUB; break;
1304 case 'f': c->flags |= REDIS_CMD_FORCE_REPLICATION; break;
b60ed6e8 1305 case 's': c->flags |= REDIS_CMD_NOSCRIPT; break;
1306 case 'R': c->flags |= REDIS_CMD_RANDOM; break;
548efd91 1307 case 'S': c->flags |= REDIS_CMD_SORT_FOR_SCRIPT; break;
5d02b00f 1308 default: redisPanic("Unsupported command flag"); break;
1309 }
1310 f++;
1311 }
1312
1b1f47c9 1313 retval = dictAdd(server.commands, sdsnew(c->name), c);
1314 assert(retval == DICT_OK);
1315 }
e2641e09 1316}
1317
d7ed7fd2 1318void resetCommandTableStats(void) {
1319 int numcommands = sizeof(redisCommandTable)/sizeof(struct redisCommand);
1320 int j;
1321
1322 for (j = 0; j < numcommands; j++) {
1323 struct redisCommand *c = redisCommandTable+j;
1324
1325 c->microseconds = 0;
1326 c->calls = 0;
1327 }
1328}
1329
78d6a22d 1330/* ========================== Redis OP Array API ============================ */
1331
1332void redisOpArrayInit(redisOpArray *oa) {
1333 oa->ops = NULL;
1334 oa->numops = 0;
1335}
1336
1337int redisOpArrayAppend(redisOpArray *oa, struct redisCommand *cmd, int dbid,
1338 robj **argv, int argc, int target)
1339{
1340 redisOp *op;
1341
1342 oa->ops = zrealloc(oa->ops,sizeof(redisOp)*(oa->numops+1));
1343 op = oa->ops+oa->numops;
1344 op->cmd = cmd;
1345 op->dbid = dbid;
1346 op->argv = argv;
1347 op->argc = argc;
1348 op->target = target;
1349 oa->numops++;
1350 return oa->numops;
1351}
1352
1353void redisOpArrayFree(redisOpArray *oa) {
1354 while(oa->numops) {
1355 int j;
1356 redisOp *op;
1357
1358 oa->numops--;
1359 op = oa->ops+oa->numops;
1360 for (j = 0; j < op->argc; j++)
1361 decrRefCount(op->argv[j]);
1362 zfree(op->argv);
1363 }
1364 zfree(oa->ops);
1365}
1366
e2641e09 1367/* ====================== Commands lookup and execution ===================== */
1368
1b1f47c9 1369struct redisCommand *lookupCommand(sds name) {
1370 return dictFetchValue(server.commands, name);
1371}
1372
1373struct redisCommand *lookupCommandByCString(char *s) {
1374 struct redisCommand *cmd;
1375 sds name = sdsnew(s);
1376
1377 cmd = dictFetchValue(server.commands, name);
1378 sdsfree(name);
1379 return cmd;
e2641e09 1380}
1381
ad08d059 1382/* Propagate the specified command (in the context of the specified database id)
1383 * to AOF, Slaves and Monitors.
1384 *
1385 * flags are an xor between:
1386 * + REDIS_PROPAGATE_NONE (no propagation of command at all)
1387 * + REDIS_PROPAGATE_AOF (propagate into the AOF file if is enabled)
1388 * + REDIS_PROPAGATE_REPL (propagate into the replication link)
1389 */
1390void propagate(struct redisCommand *cmd, int dbid, robj **argv, int argc,
1391 int flags)
1392{
1393 if (server.aof_state != REDIS_AOF_OFF && flags & REDIS_PROPAGATE_AOF)
1394 feedAppendOnlyFile(cmd,dbid,argv,argc);
1395 if (flags & REDIS_PROPAGATE_REPL && listLength(server.slaves))
1396 replicationFeedSlaves(server.slaves,dbid,argv,argc);
1397}
1398
78d6a22d 1399/* Used inside commands to schedule the propagation of additional commands
1400 * after the current command is propagated to AOF / Replication. */
eeb34eff 1401void alsoPropagate(struct redisCommand *cmd, int dbid, robj **argv, int argc,
1402 int target)
1403{
78d6a22d 1404 redisOpArrayAppend(&server.also_propagate,cmd,dbid,argv,argc,target);
eeb34eff 1405}
1406
e2641e09 1407/* Call() is the core of Redis execution of a command */
ce8b772b 1408void call(redisClient *c, int flags) {
daa70b17 1409 long long dirty, start = ustime(), duration;
e2641e09 1410
ad08d059 1411 /* Sent the command to clients in MONITOR mode, only if the commands are
1412 * not geneated from reading an AOF. */
1413 if (listLength(server.monitors) && !server.loading)
e31b615e 1414 replicationFeedMonitors(c,server.monitors,c->db->id,c->argv,c->argc);
ad08d059 1415
1416 /* Call the command. */
78d6a22d 1417 redisOpArrayInit(&server.also_propagate);
e2641e09 1418 dirty = server.dirty;
09e2d9ee 1419 c->cmd->proc(c);
e2641e09 1420 dirty = server.dirty-dirty;
daa70b17 1421 duration = ustime()-start;
ce8b772b 1422
1423 /* When EVAL is called loading the AOF we don't want commands called
1424 * from Lua to go into the slowlog or to populate statistics. */
1425 if (server.loading && c->flags & REDIS_LUA_CLIENT)
1426 flags &= ~(REDIS_CALL_SLOWLOG | REDIS_CALL_STATS);
1427
ad08d059 1428 /* Log the command into the Slow log if needed, and populate the
1429 * per-command statistics that we show in INFO commandstats. */
ce8b772b 1430 if (flags & REDIS_CALL_SLOWLOG)
1431 slowlogPushEntryIfNeeded(c->argv,c->argc,duration);
1432 if (flags & REDIS_CALL_STATS) {
1433 c->cmd->microseconds += duration;
1434 c->cmd->calls++;
1435 }
ad08d059 1436
1437 /* Propagate the command into the AOF and replication link */
ce8b772b 1438 if (flags & REDIS_CALL_PROPAGATE) {
ad08d059 1439 int flags = REDIS_PROPAGATE_NONE;
1440
1441 if (c->cmd->flags & REDIS_CMD_FORCE_REPLICATION)
1442 flags |= REDIS_PROPAGATE_REPL;
1443 if (dirty)
1444 flags |= (REDIS_PROPAGATE_REPL | REDIS_PROPAGATE_AOF);
1445 if (flags != REDIS_PROPAGATE_NONE)
1446 propagate(c->cmd,c->db->id,c->argv,c->argc,flags);
ce8b772b 1447 }
eeb34eff 1448 /* Commands such as LPUSH or BRPOPLPUSH may propagate an additional
1449 * PUSH command. */
78d6a22d 1450 if (server.also_propagate.numops) {
eeb34eff 1451 int j;
78d6a22d 1452 redisOp *rop;
eeb34eff 1453
78d6a22d 1454 for (j = 0; j < server.also_propagate.numops; j++) {
1455 rop = &server.also_propagate.ops[j];
1456 propagate(rop->cmd, rop->dbid, rop->argv, rop->argc, rop->target);
1457 }
1458 redisOpArrayFree(&server.also_propagate);
eeb34eff 1459 }
e2641e09 1460 server.stat_numcommands++;
1461}
1462
1463/* If this function gets called we already read a whole
1464 * command, argments are in the client argv/argc fields.
1465 * processCommand() execute the command or prepare the
1466 * server for a bulk read from the client.
1467 *
1468 * If 1 is returned the client is still alive and valid and
1469 * and other operations can be performed by the caller. Otherwise
1470 * if 0 is returned the client was destroied (i.e. after QUIT). */
1471int processCommand(redisClient *c) {
941c9fa2
PN
1472 /* The QUIT command is handled separately. Normal command procs will
1473 * go through checking for replication and QUIT will cause trouble
1474 * when FORCE_REPLICATION is enabled and would be implemented in
1475 * a regular command proc. */
e2641e09 1476 if (!strcasecmp(c->argv[0]->ptr,"quit")) {
941c9fa2 1477 addReply(c,shared.ok);
5e78edb3 1478 c->flags |= REDIS_CLOSE_AFTER_REPLY;
cd8788f2 1479 return REDIS_ERR;
e2641e09 1480 }
1481
1482 /* Now lookup the command and check ASAP about trivial error conditions
09e2d9ee 1483 * such as wrong arity, bad command name and so forth. */
2c74a9f9 1484 c->cmd = c->lastcmd = lookupCommand(c->argv[0]->ptr);
09e2d9ee 1485 if (!c->cmd) {
3ab20376
PN
1486 addReplyErrorFormat(c,"unknown command '%s'",
1487 (char*)c->argv[0]->ptr);
cd8788f2 1488 return REDIS_OK;
09e2d9ee 1489 } else if ((c->cmd->arity > 0 && c->cmd->arity != c->argc) ||
1490 (c->argc < -c->cmd->arity)) {
3ab20376 1491 addReplyErrorFormat(c,"wrong number of arguments for '%s' command",
09e2d9ee 1492 c->cmd->name);
cd8788f2 1493 return REDIS_OK;
e2641e09 1494 }
e2641e09 1495
1496 /* Check if the user is authenticated */
09e2d9ee 1497 if (server.requirepass && !c->authenticated && c->cmd->proc != authCommand)
1498 {
3ab20376 1499 addReplyError(c,"operation not permitted");
cd8788f2 1500 return REDIS_OK;
e2641e09 1501 }
1502
ecc91094 1503 /* If cluster is enabled, redirect here */
1504 if (server.cluster_enabled &&
09e2d9ee 1505 !(c->cmd->getkeys_proc == NULL && c->cmd->firstkey == 0)) {
ecc91094 1506 int hashslot;
1507
1508 if (server.cluster.state != REDIS_CLUSTER_OK) {
1509 addReplyError(c,"The cluster is down. Check with CLUSTER INFO for more information");
1510 return REDIS_OK;
1511 } else {
eda827f8 1512 int ask;
09e2d9ee 1513 clusterNode *n = getNodeByQuery(c,c->cmd,c->argv,c->argc,&hashslot,&ask);
ecc91094 1514 if (n == NULL) {
eda827f8 1515 addReplyError(c,"Multi keys request invalid in cluster");
ecc91094 1516 return REDIS_OK;
1517 } else if (n != server.cluster.myself) {
1518 addReplySds(c,sdscatprintf(sdsempty(),
eda827f8 1519 "-%s %d %s:%d\r\n", ask ? "ASK" : "MOVED",
1520 hashslot,n->ip,n->port));
ecc91094 1521 return REDIS_OK;
1522 }
1523 }
1524 }
1525
1dd10ca2 1526 /* Handle the maxmemory directive.
1527 *
1528 * First we try to free some memory if possible (if there are volatile
1529 * keys in the dataset). If there are not the only thing we can do
1530 * is returning an error. */
f6b32c14 1531 if (server.maxmemory) {
1532 int retval = freeMemoryIfNeeded();
1533 if ((c->cmd->flags & REDIS_CMD_DENYOOM) && retval == REDIS_ERR) {
f3fd419f 1534 addReply(c, shared.oomerr);
f6b32c14 1535 return REDIS_OK;
1536 }
e2641e09 1537 }
1538
c25e7eaf 1539 /* Don't accept write commands if there are problems persisting on disk. */
4d3bbf35 1540 if (server.stop_writes_on_bgsave_err &&
1541 server.saveparamslen > 0
1542 && server.lastbgsave_status == REDIS_ERR &&
c25e7eaf 1543 c->cmd->flags & REDIS_CMD_WRITE)
1544 {
1545 addReply(c, shared.bgsaveerr);
1546 return REDIS_OK;
1547 }
1548
f3fd419f 1549 /* Don't accept wirte commands if this is a read only slave. But
1550 * accept write commands if this is our master. */
1551 if (server.masterhost && server.repl_slave_ro &&
1552 !(c->flags & REDIS_MASTER) &&
1553 c->cmd->flags & REDIS_CMD_WRITE)
1554 {
1555 addReply(c, shared.roslaveerr);
1556 return REDIS_OK;
1557 }
1558
e2641e09 1559 /* Only allow SUBSCRIBE and UNSUBSCRIBE in the context of Pub/Sub */
1560 if ((dictSize(c->pubsub_channels) > 0 || listLength(c->pubsub_patterns) > 0)
1561 &&
09e2d9ee 1562 c->cmd->proc != subscribeCommand &&
1563 c->cmd->proc != unsubscribeCommand &&
1564 c->cmd->proc != psubscribeCommand &&
1565 c->cmd->proc != punsubscribeCommand) {
3ab20376 1566 addReplyError(c,"only (P)SUBSCRIBE / (P)UNSUBSCRIBE / QUIT allowed in this context");
cd8788f2 1567 return REDIS_OK;
e2641e09 1568 }
1569
4ebfc455 1570 /* Only allow INFO and SLAVEOF when slave-serve-stale-data is no and
1571 * we are a slave with a broken link with master. */
1844f990 1572 if (server.masterhost && server.repl_state != REDIS_REPL_CONNECTED &&
4ebfc455 1573 server.repl_serve_stale_data == 0 &&
09e2d9ee 1574 c->cmd->proc != infoCommand && c->cmd->proc != slaveofCommand)
4ebfc455 1575 {
1576 addReplyError(c,
1577 "link with MASTER is down and slave-serve-stale-data is set to no");
1578 return REDIS_OK;
1579 }
1580
97e7f8ae 1581 /* Loading DB? Return an error if the command is not INFO */
09e2d9ee 1582 if (server.loading && c->cmd->proc != infoCommand) {
97e7f8ae 1583 addReply(c, shared.loadingerr);
1584 return REDIS_OK;
1585 }
1586
4ab8695d 1587 /* Lua script too slow? Only allow SHUTDOWN NOSAVE and SCRIPT KILL. */
1588 if (server.lua_timedout &&
1589 !(c->cmd->proc != shutdownCommand &&
1590 c->argc == 2 &&
1591 tolower(((char*)c->argv[1]->ptr)[0]) == 'n') &&
1592 !(c->cmd->proc == scriptCommand &&
1593 c->argc == 2 &&
1594 tolower(((char*)c->argv[1]->ptr)[0]) == 'k'))
1595 {
115e3ff3 1596 addReply(c, shared.slowscripterr);
1597 return REDIS_OK;
1598 }
1599
e2641e09 1600 /* Exec the command */
1601 if (c->flags & REDIS_MULTI &&
09e2d9ee 1602 c->cmd->proc != execCommand && c->cmd->proc != discardCommand &&
1603 c->cmd->proc != multiCommand && c->cmd->proc != watchCommand)
e2641e09 1604 {
09e2d9ee 1605 queueMultiCommand(c);
e2641e09 1606 addReply(c,shared.queued);
1607 } else {
ce8b772b 1608 call(c,REDIS_CALL_FULL);
e2641e09 1609 }
cd8788f2 1610 return REDIS_OK;
e2641e09 1611}
1612
1613/*================================== Shutdown =============================== */
1614
4ab8695d 1615int prepareForShutdown(int flags) {
1616 int save = flags & REDIS_SHUTDOWN_SAVE;
1617 int nosave = flags & REDIS_SHUTDOWN_NOSAVE;
1618
adae85cd 1619 redisLog(REDIS_WARNING,"User requested shutdown...");
e2641e09 1620 /* Kill the saving child if there is a background saving in progress.
1621 We want to avoid race conditions, for instance our saving child may
1622 overwrite the synchronous saving did by SHUTDOWN. */
f48cd4b9 1623 if (server.rdb_child_pid != -1) {
adae85cd 1624 redisLog(REDIS_WARNING,"There is a child saving an .rdb. Killing it!");
f48cd4b9 1625 kill(server.rdb_child_pid,SIGKILL);
1626 rdbRemoveTempFile(server.rdb_child_pid);
e2641e09 1627 }
e394114d 1628 if (server.aof_state != REDIS_AOF_OFF) {
adae85cd 1629 /* Kill the AOF saving child as the AOF we already have may be longer
1630 * but contains the full dataset anyway. */
ff2145ad 1631 if (server.aof_child_pid != -1) {
adae85cd 1632 redisLog(REDIS_WARNING,
1633 "There is a child rewriting the AOF. Killing it!");
ff2145ad 1634 kill(server.aof_child_pid,SIGKILL);
adae85cd 1635 }
e2641e09 1636 /* Append only file: fsync() the AOF and exit */
adae85cd 1637 redisLog(REDIS_NOTICE,"Calling fsync() on the AOF file.");
ff2145ad 1638 aof_fsync(server.aof_fd);
adae85cd 1639 }
4ab8695d 1640 if ((server.saveparamslen > 0 && !nosave) || save) {
adae85cd 1641 redisLog(REDIS_NOTICE,"Saving the final RDB snapshot before exiting.");
e2641e09 1642 /* Snapshotting. Perform a SYNC SAVE and exit */
f48cd4b9 1643 if (rdbSave(server.rdb_filename) != REDIS_OK) {
e2641e09 1644 /* Ooops.. error saving! The best we can do is to continue
1645 * operating. Note that if there was a background saving process,
1646 * in the next cron() Redis will be notified that the background
1647 * saving aborted, handling special stuff like slaves pending for
1648 * synchronization... */
adae85cd 1649 redisLog(REDIS_WARNING,"Error trying to save the DB, can't exit.");
e2641e09 1650 return REDIS_ERR;
1651 }
1652 }
adae85cd 1653 if (server.daemonize) {
1654 redisLog(REDIS_NOTICE,"Removing the pid file.");
1655 unlink(server.pidfile);
1656 }
80e87a46 1657 /* Close the listening sockets. Apparently this allows faster restarts. */
1658 if (server.ipfd != -1) close(server.ipfd);
1659 if (server.sofd != -1) close(server.sofd);
56209f72
NF
1660 if (server.unixsocket) {
1661 redisLog(REDIS_NOTICE,"Removing the unix socket file.");
1662 unlink(server.unixsocket); /* don't care if this fails */
1663 }
80e87a46 1664
adae85cd 1665 redisLog(REDIS_WARNING,"Redis is now ready to exit, bye bye...");
e2641e09 1666 return REDIS_OK;
1667}
1668
1669/*================================== Commands =============================== */
1670
1671void authCommand(redisClient *c) {
ab52d1f4 1672 if (!server.requirepass) {
1673 addReplyError(c,"Client sent AUTH, but no password is set");
1674 } else if (!strcmp(c->argv[1]->ptr, server.requirepass)) {
e2641e09 1675 c->authenticated = 1;
1676 addReply(c,shared.ok);
1677 } else {
1678 c->authenticated = 0;
3ab20376 1679 addReplyError(c,"invalid password");
e2641e09 1680 }
1681}
1682
1683void pingCommand(redisClient *c) {
1684 addReply(c,shared.pong);
1685}
1686
1687void echoCommand(redisClient *c) {
1688 addReplyBulk(c,c->argv[1]);
1689}
1690
9494f1f1 1691void timeCommand(redisClient *c) {
1692 struct timeval tv;
1693
1694 /* gettimeofday() can only fail if &tv is a bad addresss so we
1695 * don't check for errors. */
1696 gettimeofday(&tv,NULL);
1697 addReplyMultiBulkLen(c,2);
1698 addReplyBulkLongLong(c,tv.tv_sec);
1699 addReplyBulkLongLong(c,tv.tv_usec);
1700}
1701
e2641e09 1702/* Convert an amount of bytes into a human readable string in the form
1703 * of 100B, 2G, 100M, 4K, and so forth. */
1704void bytesToHuman(char *s, unsigned long long n) {
1705 double d;
1706
1707 if (n < 1024) {
1708 /* Bytes */
1709 sprintf(s,"%lluB",n);
1710 return;
1711 } else if (n < (1024*1024)) {
1712 d = (double)n/(1024);
1713 sprintf(s,"%.2fK",d);
1714 } else if (n < (1024LL*1024*1024)) {
1715 d = (double)n/(1024*1024);
1716 sprintf(s,"%.2fM",d);
1717 } else if (n < (1024LL*1024*1024*1024)) {
1718 d = (double)n/(1024LL*1024*1024);
1719 sprintf(s,"%.2fG",d);
1720 }
1721}
1722
1723/* Create the string returned by the INFO command. This is decoupled
1724 * by the INFO command itself as we need to report the same information
1725 * on memory corruption problems. */
1b085c9f 1726sds genRedisInfoString(char *section) {
1727 sds info = sdsempty();
d1949054 1728 time_t uptime = server.unixtime-server.stat_starttime;
d9cb288c 1729 int j, numcommands;
2b00385d 1730 struct rusage self_ru, c_ru;
7a1fd61e 1731 unsigned long lol, bib;
1b085c9f 1732 int allsections = 0, defsections = 0;
1733 int sections = 0;
1734
1735 if (section) {
1736 allsections = strcasecmp(section,"all") == 0;
0d808ef2 1737 defsections = strcasecmp(section,"default") == 0;
1b085c9f 1738 }
2b00385d 1739
1740 getrusage(RUSAGE_SELF, &self_ru);
1741 getrusage(RUSAGE_CHILDREN, &c_ru);
7a1fd61e 1742 getClientsMaxBuffers(&lol,&bib);
1b085c9f 1743
1744 /* Server */
1745 if (allsections || defsections || !strcasecmp(section,"server")) {
5ad1faa0 1746 struct utsname name;
1747
1b085c9f 1748 if (sections++) info = sdscat(info,"\r\n");
5ad1faa0 1749 uname(&name);
e2641e09 1750 info = sdscatprintf(info,
1b085c9f 1751 "# Server\r\n"
1752 "redis_version:%s\r\n"
1753 "redis_git_sha1:%s\r\n"
1754 "redis_git_dirty:%d\r\n"
5ad1faa0 1755 "os:%s %s %s\r\n"
75eaac5c 1756 "arch_bits:%d\r\n"
1b085c9f 1757 "multiplexing_api:%s\r\n"
5db904bd 1758 "gcc_version:%d.%d.%d\r\n"
1b085c9f 1759 "process_id:%ld\r\n"
91d664d6 1760 "run_id:%s\r\n"
1b085c9f 1761 "tcp_port:%d\r\n"
1762 "uptime_in_seconds:%ld\r\n"
1763 "uptime_in_days:%ld\r\n"
1764 "lru_clock:%ld\r\n",
1765 REDIS_VERSION,
1766 redisGitSHA1(),
1767 strtol(redisGitDirty(),NULL,10) > 0,
5ad1faa0 1768 name.sysname, name.release, name.machine,
75eaac5c 1769 server.arch_bits,
1b085c9f 1770 aeGetApiName(),
5db904bd 1771#ifdef __GNUC__
1772 __GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__,
1773#else
1774 0,0,0,
1775#endif
1b085c9f 1776 (long) getpid(),
91d664d6 1777 server.runid,
1b085c9f 1778 server.port,
1779 uptime,
1780 uptime/(3600*24),
1781 (unsigned long) server.lruclock);
1782 }
1783
1784 /* Clients */
1785 if (allsections || defsections || !strcasecmp(section,"clients")) {
1786 if (sections++) info = sdscat(info,"\r\n");
1787 info = sdscatprintf(info,
1788 "# Clients\r\n"
3c08fdae 1789 "connected_clients:%lu\r\n"
1b085c9f 1790 "client_longest_output_list:%lu\r\n"
1791 "client_biggest_input_buf:%lu\r\n"
1792 "blocked_clients:%d\r\n",
1793 listLength(server.clients)-listLength(server.slaves),
1794 lol, bib,
1795 server.bpop_blocked_clients);
1796 }
1797
1798 /* Memory */
1799 if (allsections || defsections || !strcasecmp(section,"memory")) {
17b24ff3 1800 char hmem[64];
1801 char peak_hmem[64];
1802
1803 bytesToHuman(hmem,zmalloc_used_memory());
1804 bytesToHuman(peak_hmem,server.stat_peak_memory);
1b085c9f 1805 if (sections++) info = sdscat(info,"\r\n");
1806 info = sdscatprintf(info,
1807 "# Memory\r\n"
1808 "used_memory:%zu\r\n"
1809 "used_memory_human:%s\r\n"
1810 "used_memory_rss:%zu\r\n"
17b24ff3 1811 "used_memory_peak:%zu\r\n"
1812 "used_memory_peak_human:%s\r\n"
8c3402df 1813 "used_memory_lua:%lld\r\n"
1b085c9f 1814 "mem_fragmentation_ratio:%.2f\r\n"
32f99c51 1815 "mem_allocator:%s\r\n",
1b085c9f 1816 zmalloc_used_memory(),
1817 hmem,
1818 zmalloc_get_rss(),
17b24ff3 1819 server.stat_peak_memory,
1820 peak_hmem,
8c3402df 1821 ((long long)lua_gc(server.lua,LUA_GCCOUNT,0))*1024LL,
1b085c9f 1822 zmalloc_get_fragmentation_ratio(),
fec5a664 1823 ZMALLOC_LIB
12ebe2ac 1824 );
0d808ef2 1825 }
1826
1b085c9f 1827 /* Persistence */
1828 if (allsections || defsections || !strcasecmp(section,"persistence")) {
1829 if (sections++) info = sdscat(info,"\r\n");
e2641e09 1830 info = sdscatprintf(info,
1b085c9f 1831 "# Persistence\r\n"
1832 "loading:%d\r\n"
1833 "aof_enabled:%d\r\n"
1834 "changes_since_last_save:%lld\r\n"
1835 "bgsave_in_progress:%d\r\n"
1836 "last_save_time:%ld\r\n"
c25e7eaf 1837 "last_bgsave_status:%s\r\n"
1b085c9f 1838 "bgrewriteaof_in_progress:%d\r\n",
1839 server.loading,
e394114d 1840 server.aof_state != REDIS_AOF_OFF,
1b085c9f 1841 server.dirty,
f48cd4b9 1842 server.rdb_child_pid != -1,
1b085c9f 1843 server.lastsave,
c25e7eaf 1844 server.lastbgsave_status == REDIS_OK ? "ok" : "err",
ff2145ad 1845 server.aof_child_pid != -1);
1b085c9f 1846
e394114d 1847 if (server.aof_state != REDIS_AOF_OFF) {
d630abcd 1848 info = sdscatprintf(info,
1849 "aof_current_size:%lld\r\n"
1850 "aof_base_size:%lld\r\n"
e7ef418c 1851 "aof_pending_rewrite:%d\r\n"
1852 "aof_buffer_length:%zu\r\n"
c1d01b3c 1853 "aof_pending_bio_fsync:%llu\r\n"
1854 "aof_delayed_fsync:%lu\r\n",
2c915bcf 1855 (long long) server.aof_current_size,
1856 (long long) server.aof_rewrite_base_size,
1857 server.aof_rewrite_scheduled,
ff2145ad 1858 sdslen(server.aof_buf),
c1d01b3c 1859 bioPendingJobsOfType(REDIS_BIO_AOF_FSYNC),
1860 server.aof_delayed_fsync);
d630abcd 1861 }
1862
1b085c9f 1863 if (server.loading) {
1864 double perc;
1865 time_t eta, elapsed;
1866 off_t remaining_bytes = server.loading_total_bytes-
1867 server.loading_loaded_bytes;
1868
1869 perc = ((double)server.loading_loaded_bytes /
1870 server.loading_total_bytes) * 100;
1871
d1949054 1872 elapsed = server.unixtime-server.loading_start_time;
1b085c9f 1873 if (elapsed == 0) {
1874 eta = 1; /* A fake 1 second figure if we don't have
1875 enough info */
1876 } else {
1877 eta = (elapsed*remaining_bytes)/server.loading_loaded_bytes;
1878 }
1879
1880 info = sdscatprintf(info,
1881 "loading_start_time:%ld\r\n"
1882 "loading_total_bytes:%llu\r\n"
1883 "loading_loaded_bytes:%llu\r\n"
1884 "loading_loaded_perc:%.2f\r\n"
1885 "loading_eta_seconds:%ld\r\n"
1886 ,(unsigned long) server.loading_start_time,
1887 (unsigned long long) server.loading_total_bytes,
1888 (unsigned long long) server.loading_loaded_bytes,
1889 perc,
1890 eta
1891 );
1892 }
e2641e09 1893 }
1b085c9f 1894
1b085c9f 1895 /* Stats */
1896 if (allsections || defsections || !strcasecmp(section,"stats")) {
1897 if (sections++) info = sdscat(info,"\r\n");
97e7f8ae 1898 info = sdscatprintf(info,
1b085c9f 1899 "# Stats\r\n"
1900 "total_connections_received:%lld\r\n"
1901 "total_commands_processed:%lld\r\n"
250e7f69 1902 "instantaneous_ops_per_sec:%lld\r\n"
3c95e721 1903 "rejected_connections:%lld\r\n"
1b085c9f 1904 "expired_keys:%lld\r\n"
1905 "evicted_keys:%lld\r\n"
1906 "keyspace_hits:%lld\r\n"
1907 "keyspace_misses:%lld\r\n"
1908 "pubsub_channels:%ld\r\n"
3c08fdae 1909 "pubsub_patterns:%lu\r\n"
615e414c 1910 "latest_fork_usec:%lld\r\n",
1b085c9f 1911 server.stat_numconnections,
1912 server.stat_numcommands,
250e7f69 1913 getOperationsPerSecond(),
3c95e721 1914 server.stat_rejected_conn,
1b085c9f 1915 server.stat_expiredkeys,
1916 server.stat_evictedkeys,
1917 server.stat_keyspace_hits,
1918 server.stat_keyspace_misses,
1919 dictSize(server.pubsub_channels),
615e414c 1920 listLength(server.pubsub_patterns),
1921 server.stat_fork_time);
97e7f8ae 1922 }
67a1810b 1923
1b085c9f 1924 /* Replication */
1925 if (allsections || defsections || !strcasecmp(section,"replication")) {
1926 if (sections++) info = sdscat(info,"\r\n");
1927 info = sdscatprintf(info,
1928 "# Replication\r\n"
1929 "role:%s\r\n",
1930 server.masterhost == NULL ? "master" : "slave");
1931 if (server.masterhost) {
1932 info = sdscatprintf(info,
1933 "master_host:%s\r\n"
1934 "master_port:%d\r\n"
1935 "master_link_status:%s\r\n"
1936 "master_last_io_seconds_ago:%d\r\n"
1937 "master_sync_in_progress:%d\r\n"
1938 ,server.masterhost,
1939 server.masterport,
1844f990 1940 (server.repl_state == REDIS_REPL_CONNECTED) ?
1b085c9f 1941 "up" : "down",
1942 server.master ?
d1949054 1943 ((int)(server.unixtime-server.master->lastinteraction)) : -1,
1844f990 1944 server.repl_state == REDIS_REPL_TRANSFER
1b085c9f 1945 );
1946
1844f990 1947 if (server.repl_state == REDIS_REPL_TRANSFER) {
1b085c9f 1948 info = sdscatprintf(info,
1949 "master_sync_left_bytes:%ld\r\n"
1950 "master_sync_last_io_seconds_ago:%d\r\n"
1951 ,(long)server.repl_transfer_left,
d1949054 1952 (int)(server.unixtime-server.repl_transfer_lastio)
1b085c9f 1953 );
1954 }
07486df6 1955
1844f990 1956 if (server.repl_state != REDIS_REPL_CONNECTED) {
07486df6 1957 info = sdscatprintf(info,
1958 "master_link_down_since_seconds:%ld\r\n",
d1949054 1959 (long)server.unixtime-server.repl_down_since);
07486df6 1960 }
67a1810b 1961 }
1b085c9f 1962 info = sdscatprintf(info,
3c08fdae 1963 "connected_slaves:%lu\r\n",
1b085c9f 1964 listLength(server.slaves));
503d87a8 1965 if (listLength(server.slaves)) {
1966 int slaveid = 0;
1967 listNode *ln;
1968 listIter li;
1969
1970 listRewind(server.slaves,&li);
1971 while((ln = listNext(&li))) {
1972 redisClient *slave = listNodeValue(ln);
1973 char *state = NULL;
1974 char ip[32];
1975 int port;
1976
1977 if (anetPeerToString(slave->fd,ip,&port) == -1) continue;
1978 switch(slave->replstate) {
1979 case REDIS_REPL_WAIT_BGSAVE_START:
1980 case REDIS_REPL_WAIT_BGSAVE_END:
1981 state = "wait_bgsave";
1982 break;
1983 case REDIS_REPL_SEND_BULK:
1984 state = "send_bulk";
1985 break;
1986 case REDIS_REPL_ONLINE:
1987 state = "online";
1988 break;
1989 }
1990 if (state == NULL) continue;
1991 info = sdscatprintf(info,"slave%d:%s,%d,%s\r\n",
1992 slaveid,ip,port,state);
1993 slaveid++;
1994 }
1995 }
67a1810b 1996 }
67a1810b 1997
0d808ef2 1998 /* CPU */
1999 if (allsections || defsections || !strcasecmp(section,"cpu")) {
1b085c9f 2000 if (sections++) info = sdscat(info,"\r\n");
2001 info = sdscatprintf(info,
0d808ef2 2002 "# CPU\r\n"
1b085c9f 2003 "used_cpu_sys:%.2f\r\n"
2004 "used_cpu_user:%.2f\r\n"
5a9dd97c 2005 "used_cpu_sys_children:%.2f\r\n"
2006 "used_cpu_user_children:%.2f\r\n",
1b085c9f 2007 (float)self_ru.ru_stime.tv_sec+(float)self_ru.ru_stime.tv_usec/1000000,
d83eda48 2008 (float)self_ru.ru_utime.tv_sec+(float)self_ru.ru_utime.tv_usec/1000000,
2009 (float)c_ru.ru_stime.tv_sec+(float)c_ru.ru_stime.tv_usec/1000000,
2010 (float)c_ru.ru_utime.tv_sec+(float)c_ru.ru_utime.tv_usec/1000000);
0d808ef2 2011 }
1b085c9f 2012
0d808ef2 2013 /* cmdtime */
2014 if (allsections || !strcasecmp(section,"commandstats")) {
2015 if (sections++) info = sdscat(info,"\r\n");
2016 info = sdscatprintf(info, "# Commandstats\r\n");
d7ed7fd2 2017 numcommands = sizeof(redisCommandTable)/sizeof(struct redisCommand);
1b085c9f 2018 for (j = 0; j < numcommands; j++) {
d7ed7fd2 2019 struct redisCommand *c = redisCommandTable+j;
0d808ef2 2020
d7ed7fd2 2021 if (!c->calls) continue;
2022 info = sdscatprintf(info,
2023 "cmdstat_%s:calls=%lld,usec=%lld,usec_per_call=%.2f\r\n",
2024 c->name, c->calls, c->microseconds,
2025 (c->calls == 0) ? 0 : ((float)c->microseconds/c->calls));
1b085c9f 2026 }
d9cb288c 2027 }
2028
1c708b25
SS
2029 /* Clusetr */
2030 if (allsections || defsections || !strcasecmp(section,"cluster")) {
2031 if (sections++) info = sdscat(info,"\r\n");
2032 info = sdscatprintf(info,
2033 "# Cluster\r\n"
2034 "cluster_enabled:%d\r\n",
2035 server.cluster_enabled);
2036 }
2037
1b085c9f 2038 /* Key space */
2039 if (allsections || defsections || !strcasecmp(section,"keyspace")) {
2040 if (sections++) info = sdscat(info,"\r\n");
2041 info = sdscatprintf(info, "# Keyspace\r\n");
2042 for (j = 0; j < server.dbnum; j++) {
2043 long long keys, vkeys;
e2641e09 2044
1b085c9f 2045 keys = dictSize(server.db[j].dict);
2046 vkeys = dictSize(server.db[j].expires);
2047 if (keys || vkeys) {
2048 info = sdscatprintf(info, "db%d:keys=%lld,expires=%lld\r\n",
2049 j, keys, vkeys);
2050 }
e2641e09 2051 }
2052 }
2053 return info;
2054}
2055
2056void infoCommand(redisClient *c) {
1b085c9f 2057 char *section = c->argc == 2 ? c->argv[1]->ptr : "default";
2058
2059 if (c->argc > 2) {
2060 addReply(c,shared.syntaxerr);
2061 return;
2062 }
2063 sds info = genRedisInfoString(section);
e2641e09 2064 addReplySds(c,sdscatprintf(sdsempty(),"$%lu\r\n",
2065 (unsigned long)sdslen(info)));
2066 addReplySds(c,info);
2067 addReply(c,shared.crlf);
2068}
2069
2070void monitorCommand(redisClient *c) {
2071 /* ignore MONITOR if aleady slave or in monitor mode */
2072 if (c->flags & REDIS_SLAVE) return;
2073
2074 c->flags |= (REDIS_SLAVE|REDIS_MONITOR);
2075 c->slaveseldb = 0;
2076 listAddNodeTail(server.monitors,c);
2077 addReply(c,shared.ok);
2078}
2079
2080/* ============================ Maxmemory directive ======================== */
2081
e2641e09 2082/* This function gets called when 'maxmemory' is set on the config file to limit
f6b32c14 2083 * the max memory used by the server, before processing a command.
e2641e09 2084 *
f6b32c14 2085 * The goal of the function is to free enough memory to keep Redis under the
2086 * configured memory limit.
e2641e09 2087 *
f6b32c14 2088 * The function starts calculating how many bytes should be freed to keep
2089 * Redis under the limit, and enters a loop selecting the best keys to
2090 * evict accordingly to the configured policy.
2091 *
2092 * If all the bytes needed to return back under the limit were freed the
2093 * function returns REDIS_OK, otherwise REDIS_ERR is returned, and the caller
2094 * should block the execution of commands that will result in more memory
2095 * used by the server.
e2641e09 2096 */
f6b32c14 2097int freeMemoryIfNeeded(void) {
2098 size_t mem_used, mem_tofree, mem_freed;
2099 int slaves = listLength(server.slaves);
2100
c1ef6ffe 2101 /* Remove the size of slaves output buffers and AOF buffer from the
2102 * count of used memory. */
f6b32c14 2103 mem_used = zmalloc_used_memory();
2104 if (slaves) {
2105 listIter li;
2106 listNode *ln;
2107
2108 listRewind(server.slaves,&li);
2109 while((ln = listNext(&li))) {
2110 redisClient *slave = listNodeValue(ln);
2111 unsigned long obuf_bytes = getClientOutputBufferMemoryUsage(slave);
2112 if (obuf_bytes > mem_used)
2113 mem_used = 0;
2114 else
2115 mem_used -= obuf_bytes;
2116 }
2117 }
c1ef6ffe 2118 if (server.aof_state != REDIS_AOF_OFF) {
2119 mem_used -= sdslen(server.aof_buf);
2120 mem_used -= sdslen(server.aof_rewrite_buf);
2121 }
5402c426 2122
f6b32c14 2123 /* Check if we are over the memory limit. */
2124 if (mem_used <= server.maxmemory) return REDIS_OK;
2125
2126 if (server.maxmemory_policy == REDIS_MAXMEMORY_NO_EVICTION)
2127 return REDIS_ERR; /* We need to free memory, but policy forbids. */
2128
2129 /* Compute how much memory we need to free. */
2130 mem_tofree = mem_used - server.maxmemory;
f6b32c14 2131 mem_freed = 0;
2132 while (mem_freed < mem_tofree) {
2133 int j, k, keys_freed = 0;
e2641e09 2134
165346ca 2135 for (j = 0; j < server.dbnum; j++) {
10c12171 2136 long bestval = 0; /* just to prevent warning */
165346ca 2137 sds bestkey = NULL;
2138 struct dictEntry *de;
2139 redisDb *db = server.db+j;
2140 dict *dict;
2141
2142 if (server.maxmemory_policy == REDIS_MAXMEMORY_ALLKEYS_LRU ||
2143 server.maxmemory_policy == REDIS_MAXMEMORY_ALLKEYS_RANDOM)
2144 {
2145 dict = server.db[j].dict;
2146 } else {
2147 dict = server.db[j].expires;
2148 }
2149 if (dictSize(dict) == 0) continue;
2150
2151 /* volatile-random and allkeys-random policy */
2152 if (server.maxmemory_policy == REDIS_MAXMEMORY_ALLKEYS_RANDOM ||
2153 server.maxmemory_policy == REDIS_MAXMEMORY_VOLATILE_RANDOM)
2154 {
2155 de = dictGetRandomKey(dict);
c0ba9ebe 2156 bestkey = dictGetKey(de);
165346ca 2157 }
2158
2159 /* volatile-lru and allkeys-lru policy */
2160 else if (server.maxmemory_policy == REDIS_MAXMEMORY_ALLKEYS_LRU ||
2161 server.maxmemory_policy == REDIS_MAXMEMORY_VOLATILE_LRU)
2162 {
2163 for (k = 0; k < server.maxmemory_samples; k++) {
2164 sds thiskey;
2165 long thisval;
2166 robj *o;
2167
2168 de = dictGetRandomKey(dict);
c0ba9ebe 2169 thiskey = dictGetKey(de);
0c2f75c6 2170 /* When policy is volatile-lru we need an additonal lookup
2171 * to locate the real key, as dict is set to db->expires. */
2172 if (server.maxmemory_policy == REDIS_MAXMEMORY_VOLATILE_LRU)
2173 de = dictFind(db->dict, thiskey);
c0ba9ebe 2174 o = dictGetVal(de);
165346ca 2175 thisval = estimateObjectIdleTime(o);
2176
2177 /* Higher idle time is better candidate for deletion */
2178 if (bestkey == NULL || thisval > bestval) {
2179 bestkey = thiskey;
2180 bestval = thisval;
2181 }
2182 }
2183 }
2184
2185 /* volatile-ttl */
2186 else if (server.maxmemory_policy == REDIS_MAXMEMORY_VOLATILE_TTL) {
2187 for (k = 0; k < server.maxmemory_samples; k++) {
2188 sds thiskey;
2189 long thisval;
2190
2191 de = dictGetRandomKey(dict);
c0ba9ebe 2192 thiskey = dictGetKey(de);
2193 thisval = (long) dictGetVal(de);
165346ca 2194
2195 /* Expire sooner (minor expire unix timestamp) is better
2196 * candidate for deletion */
2197 if (bestkey == NULL || thisval < bestval) {
2198 bestkey = thiskey;
2199 bestval = thisval;
2200 }
2201 }
2202 }
2203
2204 /* Finally remove the selected key. */
2205 if (bestkey) {
f6b32c14 2206 long long delta;
2207
165346ca 2208 robj *keyobj = createStringObject(bestkey,sdslen(bestkey));
452229b6 2209 propagateExpire(db,keyobj);
f6b32c14 2210 /* We compute the amount of memory freed by dbDelete() alone.
2211 * It is possible that actually the memory needed to propagate
2212 * the DEL in AOF and replication link is greater than the one
2213 * we are freeing removing the key, but we can't account for
2214 * that otherwise we would never exit the loop.
2215 *
2216 * AOF and Output buffer memory will be freed eventually so
2217 * we only care about memory used by the key space. */
2218 delta = (long long) zmalloc_used_memory();
165346ca 2219 dbDelete(db,keyobj);
f6b32c14 2220 delta -= (long long) zmalloc_used_memory();
f6b32c14 2221 mem_freed += delta;
f21779ff 2222 server.stat_evictedkeys++;
165346ca 2223 decrRefCount(keyobj);
f6b32c14 2224 keys_freed++;
2225
2226 /* When the memory to free starts to be big enough, we may
2227 * start spending so much time here that is impossible to
2228 * deliver data to the slaves fast enough, so we force the
2229 * transmission here inside the loop. */
8b7c3455 2230 if (slaves) flushSlavesOutputBuffers();
165346ca 2231 }
2232 }
b129c6df 2233 if (!keys_freed) return REDIS_ERR; /* nothing to free... */
165346ca 2234 }
f6b32c14 2235 return REDIS_OK;
e2641e09 2236}
2237
2238/* =================================== Main! ================================ */
2239
2240#ifdef __linux__
2241int linuxOvercommitMemoryValue(void) {
2242 FILE *fp = fopen("/proc/sys/vm/overcommit_memory","r");
2243 char buf[64];
2244
2245 if (!fp) return -1;
2246 if (fgets(buf,64,fp) == NULL) {
2247 fclose(fp);
2248 return -1;
2249 }
2250 fclose(fp);
2251
2252 return atoi(buf);
2253}
2254
2255void linuxOvercommitMemoryWarning(void) {
2256 if (linuxOvercommitMemoryValue() == 0) {
2257 redisLog(REDIS_WARNING,"WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.");
2258 }
2259}
2260#endif /* __linux__ */
2261
695fe874 2262void createPidFile(void) {
2263 /* Try to write the pid file in a best-effort way. */
2264 FILE *fp = fopen(server.pidfile,"w");
2265 if (fp) {
8ce39260 2266 fprintf(fp,"%d\n",(int)getpid());
695fe874 2267 fclose(fp);
2268 }
2269}
2270
e2641e09 2271void daemonize(void) {
2272 int fd;
e2641e09 2273
2274 if (fork() != 0) exit(0); /* parent exits */
2275 setsid(); /* create a new session */
2276
2277 /* Every output goes to /dev/null. If Redis is daemonized but
2278 * the 'logfile' is set to 'stdout' in the configuration file
2279 * it will not log at all. */
2280 if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
2281 dup2(fd, STDIN_FILENO);
2282 dup2(fd, STDOUT_FILENO);
2283 dup2(fd, STDERR_FILENO);
2284 if (fd > STDERR_FILENO) close(fd);
2285 }
e2641e09 2286}
2287
2288void version() {
1b247d13 2289 printf("Redis server v=%s sha=%s:%d malloc=%s\n", REDIS_VERSION,
2290 redisGitSHA1(), atoi(redisGitDirty()) > 0, ZMALLOC_LIB);
e2641e09 2291 exit(0);
2292}
2293
2294void usage() {
9268a5b5 2295 fprintf(stderr,"Usage: ./redis-server [/path/to/redis.conf] [options]\n");
e2641e09 2296 fprintf(stderr," ./redis-server - (read config from stdin)\n");
9268a5b5 2297 fprintf(stderr," ./redis-server -v or --version\n");
c5166e3f 2298 fprintf(stderr," ./redis-server -h or --help\n");
2299 fprintf(stderr," ./redis-server --test-memory <megabytes>\n\n");
9268a5b5 2300 fprintf(stderr,"Examples:\n");
2301 fprintf(stderr," ./redis-server (run the server with default conf)\n");
2302 fprintf(stderr," ./redis-server /etc/redis/6379.conf\n");
2303 fprintf(stderr," ./redis-server --port 7777\n");
2304 fprintf(stderr," ./redis-server --port 7777 --slaveof 127.0.0.1 8888\n");
2305 fprintf(stderr," ./redis-server /etc/myredis.conf --loglevel verbose\n");
e2641e09 2306 exit(1);
2307}
2308
996d503d 2309void redisAsciiArt(void) {
2310#include "asciilogo.h"
2311 char *buf = zmalloc(1024*16);
2312
2313 snprintf(buf,1024*16,ascii_logo,
2314 REDIS_VERSION,
2315 redisGitSHA1(),
2316 strtol(redisGitDirty(),NULL,10) > 0,
2317 (sizeof(long) == 8) ? "64" : "32",
2318 server.cluster_enabled ? "cluster" : "stand alone",
2319 server.port,
2320 (long) getpid()
2321 );
2322 redisLogRaw(REDIS_NOTICE|REDIS_LOG_RAW,buf);
2323 zfree(buf);
2324}
2325
633a9410 2326static void sigtermHandler(int sig) {
e2641e09 2327 REDIS_NOTUSED(sig);
2328
a7d12cba 2329 redisLogFromHandler(REDIS_WARNING,"Received SIGTERM, scheduling shutdown...");
e2641e09 2330 server.shutdown_asap = 1;
2331}
2332
633a9410 2333void setupSignalHandlers(void) {
e2641e09 2334 struct sigaction act;
c5757662
PH
2335 stack_t stack;
2336
2337 stack.ss_sp = altstack;
2338 stack.ss_flags = 0;
2339 stack.ss_size = SIGSTKSZ;
2340
2341 sigaltstack(&stack, NULL);
e2641e09 2342
633a9410
PN
2343 /* When the SA_SIGINFO flag is set in sa_flags then sa_sigaction is used.
2344 * Otherwise, sa_handler is used. */
2345 sigemptyset(&act.sa_mask);
c5757662 2346 act.sa_flags = 0;
e2641e09 2347 act.sa_handler = sigtermHandler;
633a9410 2348 sigaction(SIGTERM, &act, NULL);
e2641e09 2349
633a9410 2350#ifdef HAVE_BACKTRACE
c5757662
PH
2351 /* Use alternate stack so we don't clobber stack in case of segv, or when we run out of stack ..
2352 * also resethand & nodefer so we can get interrupted (and killed) if we cause SEGV during SEGV handler */
633a9410
PN
2353 sigemptyset(&act.sa_mask);
2354 act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
2355 act.sa_sigaction = sigsegvHandler;
2356 sigaction(SIGSEGV, &act, NULL);
2357 sigaction(SIGBUS, &act, NULL);
2358 sigaction(SIGFPE, &act, NULL);
2359 sigaction(SIGILL, &act, NULL);
2360#endif
2361 return;
e2641e09 2362}
e2641e09 2363
c5166e3f 2364void memtest(size_t megabytes, int passes);
2365
39ca1713 2366int main(int argc, char **argv) {
2367 long long start;
a48c8d87 2368 struct timeval tv;
39ca1713 2369
06c5523a 2370 /* We need to initialize our libraries, and the server configuration. */
39ca1713 2371 zmalloc_enable_thread_safeness();
a48c8d87 2372 srand(time(NULL)^getpid());
2373 gettimeofday(&tv,NULL);
2374 dictSetHashFunctionSeed(tv.tv_sec^tv.tv_usec^getpid());
39ca1713 2375 initServerConfig();
a48c8d87 2376
67c6f0f6 2377 if (argc >= 2) {
2378 int j = 1; /* First option to parse in argv[] */
2379 sds options = sdsempty();
2380 char *configfile = NULL;
2381
2382 /* Handle special options --help and --version */
39ca1713 2383 if (strcmp(argv[1], "-v") == 0 ||
2384 strcmp(argv[1], "--version") == 0) version();
4c8bd905 2385 if (strcmp(argv[1], "--help") == 0 ||
2386 strcmp(argv[1], "-h") == 0) usage();
c5166e3f 2387 if (strcmp(argv[1], "--test-memory") == 0) {
2388 if (argc == 3) {
d033ccb0 2389 memtest(atoi(argv[2]),50);
c5166e3f 2390 exit(0);
2391 } else {
2392 fprintf(stderr,"Please specify the amount of memory to test in megabytes.\n");
2393 fprintf(stderr,"Example: ./redis-server --test-memory 4096\n\n");
2394 exit(1);
2395 }
2396 }
2397
67c6f0f6 2398 /* First argument is the config file name? */
2399 if (argv[j][0] != '-' || argv[j][1] != '-')
2400 configfile = argv[j++];
2401 /* All the other options are parsed and conceptually appended to the
2402 * configuration file. For instance --port 6380 will generate the
2403 * string "port 6380\n" to be parsed after the actual file name
2404 * is parsed, if any. */
2405 while(j != argc) {
2406 if (argv[j][0] == '-' && argv[j][1] == '-') {
2407 /* Option name */
2408 if (sdslen(options)) options = sdscat(options,"\n");
2409 options = sdscat(options,argv[j]+2);
2410 options = sdscat(options," ");
2411 } else {
2412 /* Option argument */
2413 options = sdscatrepr(options,argv[j],strlen(argv[j]));
2414 options = sdscat(options," ");
2415 }
2416 j++;
2417 }
39ca1713 2418 resetServerSaveParams();
67c6f0f6 2419 loadServerConfig(configfile,options);
2420 sdsfree(options);
39ca1713 2421 } else {
2422 redisLog(REDIS_WARNING,"Warning: no config file specified, using the default config. In order to specify a config file use 'redis-server /path/to/redis.conf'");
2423 }
2424 if (server.daemonize) daemonize();
2425 initServer();
2426 if (server.daemonize) createPidFile();
2427 redisAsciiArt();
27ccb94a 2428 redisLog(REDIS_WARNING,"Server started, Redis version " REDIS_VERSION);
39ca1713 2429#ifdef __linux__
2430 linuxOvercommitMemoryWarning();
2431#endif
2432 start = ustime();
e394114d 2433 if (server.aof_state == REDIS_AOF_ON) {
2c915bcf 2434 if (loadAppendOnlyFile(server.aof_filename) == REDIS_OK)
39ca1713 2435 redisLog(REDIS_NOTICE,"DB loaded from append only file: %.3f seconds",(float)(ustime()-start)/1000000);
2436 } else {
f48cd4b9 2437 if (rdbLoad(server.rdb_filename) == REDIS_OK) {
39ca1713 2438 redisLog(REDIS_NOTICE,"DB loaded from disk: %.3f seconds",
2439 (float)(ustime()-start)/1000000);
2440 } else if (errno != ENOENT) {
2441 redisLog(REDIS_WARNING,"Fatal error loading the DB. Exiting.");
2442 exit(1);
2443 }
2444 }
2445 if (server.ipfd > 0)
2446 redisLog(REDIS_NOTICE,"The server is now ready to accept connections on port %d", server.port);
2447 if (server.sofd > 0)
2448 redisLog(REDIS_NOTICE,"The server is now ready to accept connections at %s", server.unixsocket);
2449 aeSetBeforeSleepProc(server.el,beforeSleep);
2450 aeMain(server.el);
2451 aeDeleteEventLoop(server.el);
2452 return 0;
2453}
2454
e2641e09 2455/* The End */