* for dict.c to resize the hash tables accordingly to the fact we have o not
* running childs. */
void updateDictResizePolicy(void) {
- if (server.bgsavechildpid == -1 && server.bgrewritechildpid == -1)
+ if (server.rdb_child_pid == -1 && server.aof_child_pid == -1)
dictEnableResize();
else
dictDisableResize();
* if we resize the HT while there is the saving child at work actually
* a lot of memory movements in the parent will cause a lot of pages
* copied. */
- if (server.bgsavechildpid == -1 && server.bgrewritechildpid == -1) {
+ if (server.rdb_child_pid == -1 && server.aof_child_pid == -1) {
if (!(loops % 10)) tryResizeHashTables();
if (server.activerehashing) incrementallyRehash();
}
/* Start a scheduled AOF rewrite if this was requested by the user while
* a BGSAVE was in progress. */
- if (server.bgsavechildpid == -1 && server.bgrewritechildpid == -1 &&
- server.aofrewrite_scheduled)
+ if (server.rdb_child_pid == -1 && server.aof_child_pid == -1 &&
+ server.aof_rewrite_scheduled)
{
rewriteAppendOnlyFileBackground();
}
/* Check if a background saving or AOF rewrite in progress terminated. */
- if (server.bgsavechildpid != -1 || server.bgrewritechildpid != -1) {
+ if (server.rdb_child_pid != -1 || server.aof_child_pid != -1) {
int statloc;
pid_t pid;
if (WIFSIGNALED(statloc)) bysignal = WTERMSIG(statloc);
- if (pid == server.bgsavechildpid) {
+ if (pid == server.rdb_child_pid) {
backgroundSaveDoneHandler(exitcode,bysignal);
} else {
backgroundRewriteDoneHandler(exitcode,bysignal);
now-server.lastsave > sp->seconds) {
redisLog(REDIS_NOTICE,"%d changes in %d seconds. Saving...",
sp->changes, sp->seconds);
- rdbSaveBackground(server.dbfilename);
+ rdbSaveBackground(server.rdb_filename);
break;
}
}
/* Trigger an AOF rewrite if needed */
- if (server.bgsavechildpid == -1 &&
- server.bgrewritechildpid == -1 &&
- server.auto_aofrewrite_perc &&
- server.appendonly_current_size > server.auto_aofrewrite_min_size)
+ if (server.rdb_child_pid == -1 &&
+ server.aof_child_pid == -1 &&
+ server.aof_rewrite_perc &&
+ server.aof_current_size > server.aof_rewrite_min_size)
{
- long long base = server.auto_aofrewrite_base_size ?
- server.auto_aofrewrite_base_size : 1;
- long long growth = (server.appendonly_current_size*100/base) - 100;
- if (growth >= server.auto_aofrewrite_perc) {
+ long long base = server.aof_rewrite_base_size ?
+ server.aof_rewrite_base_size : 1;
+ long long growth = (server.aof_current_size*100/base) - 100;
+ if (growth >= server.aof_rewrite_perc) {
redisLog(REDIS_NOTICE,"Starting automatic rewriting of AOF on %lld%% growth",growth);
rewriteAppendOnlyFileBackground();
}
server.syslog_ident = zstrdup("redis");
server.syslog_facility = LOG_LOCAL0;
server.daemonize = 0;
- server.appendonly = 0;
- server.appendfsync = APPENDFSYNC_EVERYSEC;
- server.no_appendfsync_on_rewrite = 0;
- server.auto_aofrewrite_perc = REDIS_AUTO_AOFREWRITE_PERC;
- server.auto_aofrewrite_min_size = REDIS_AUTO_AOFREWRITE_MIN_SIZE;
- server.auto_aofrewrite_base_size = 0;
- server.aofrewrite_scheduled = 0;
- server.lastfsync = time(NULL);
- server.appendfd = -1;
- server.appendseldb = -1; /* Make sure the first time will not match */
+ server.aof_state = REDIS_AOF_OFF;
+ server.aof_fsync = AOF_FSYNC_EVERYSEC;
+ server.aof_no_fsync_on_rewrite = 0;
+ server.aof_rewrite_perc = REDIS_AOF_REWRITE_PERC;
+ server.aof_rewrite_min_size = REDIS_AOF_REWRITE_MIN_SIZE;
+ server.aof_rewrite_base_size = 0;
+ server.aof_rewrite_scheduled = 0;
+ server.aof_last_fsync = time(NULL);
+ server.aof_fd = -1;
+ server.aof_selected_db = -1; /* Make sure the first time will not match */
server.aof_flush_postponed_start = 0;
server.pidfile = zstrdup("/var/run/redis.pid");
- server.dbfilename = zstrdup("dump.rdb");
- server.appendfilename = zstrdup("appendonly.aof");
+ server.rdb_filename = zstrdup("dump.rdb");
+ server.aof_filename = zstrdup("appendonly.aof");
server.requirepass = NULL;
- server.rdbcompression = 1;
+ server.rdb_compression = 1;
server.activerehashing = 1;
server.maxclients = REDIS_MAX_CLIENTS;
server.bpop_blocked_clients = 0;
appendServerSaveParams(300,100); /* save after 5 minutes and 100 changes */
appendServerSaveParams(60,10000); /* save after 1 minute and 10000 changes */
/* Replication related */
- server.isslave = 0;
server.masterauth = NULL;
server.masterhost = NULL;
server.masterport = 6379;
server.master = NULL;
- server.replstate = REDIS_REPL_NONE;
+ server.repl_state = REDIS_REPL_NONE;
server.repl_syncio_timeout = REDIS_REPL_SYNCIO_TIMEOUT;
server.repl_serve_stale_data = 1;
server.repl_down_since = -1;
server.bug_report_start = 0;
}
+/* This function will try to raise the max number of open files accordingly to
+ * the configured max number of clients. It will also account for 32 additional
+ * file descriptors as we need a few more for persistence, listening
+ * sockets, log files and so forth.
+ *
+ * If it will not be possible to set the limit accordingly to the configured
+ * max number of clients, the function will do the reverse setting
+ * server.maxclients to the value that we can actually handle. */
+void adjustOpenFilesLimit(void) {
+ rlim_t maxfiles = server.maxclients+32;
+ struct rlimit limit;
+
+ if (maxfiles < 1024) maxfiles = 1024;
+ if (getrlimit(RLIMIT_NOFILE,&limit) == -1) {
+ redisLog(REDIS_WARNING,"Unable to obtain the current NOFILE limit (%s), assuming 1024 and setting the max clients configuration accordingly.",
+ strerror(errno));
+ server.maxclients = 1024-32;
+ } else {
+ rlim_t oldlimit = limit.rlim_cur;
+
+ /* Set the max number of files if the current limit is not enough
+ * for our needs. */
+ if (oldlimit < maxfiles) {
+ limit.rlim_cur = maxfiles;
+ limit.rlim_max = maxfiles;
+ if (setrlimit(RLIMIT_NOFILE,&limit) == -1) {
+ server.maxclients = oldlimit-32;
+ redisLog(REDIS_WARNING,"Unable to set the max number of files limit to %d (%s), setting the max clients configuration to %d.",
+ (int) maxfiles, strerror(errno), (int) server.maxclients);
+ } else {
+ redisLog(REDIS_NOTICE,"Max number of open files set to %d",
+ (int) maxfiles);
+ }
+ }
+ }
+}
+
void initServer() {
int j;
server.unblocked_clients = listCreate();
createSharedObjects();
- server.el = aeCreateEventLoop();
+ adjustOpenFilesLimit();
+ server.el = aeCreateEventLoop(server.maxclients+1024);
server.db = zmalloc(sizeof(redisDb)*server.dbnum);
if (server.port != 0) {
listSetFreeMethod(server.pubsub_patterns,freePubsubPattern);
listSetMatchMethod(server.pubsub_patterns,listMatchPubsubPattern);
server.cronloops = 0;
- server.bgsavechildpid = -1;
- server.bgrewritechildpid = -1;
- server.bgrewritebuf = sdsempty();
- server.aofbuf = sdsempty();
+ server.rdb_child_pid = -1;
+ server.aof_child_pid = -1;
+ server.aof_rewrite_buf = sdsempty();
+ server.aof_buf = sdsempty();
server.lastsave = time(NULL);
server.dirty = 0;
server.stat_numcommands = 0;
if (server.sofd > 0 && aeCreateFileEvent(server.el,server.sofd,AE_READABLE,
acceptUnixHandler,NULL) == AE_ERR) oom("creating file event");
- if (server.appendonly) {
- server.appendfd = open(server.appendfilename,O_WRONLY|O_APPEND|O_CREAT,0644);
- if (server.appendfd == -1) {
+ if (server.aof_state == REDIS_AOF_ON) {
+ server.aof_fd = open(server.aof_filename,
+ O_WRONLY|O_APPEND|O_CREAT,0644);
+ if (server.aof_fd == -1) {
redisLog(REDIS_WARNING, "Can't open the append-only file: %s",
strerror(errno));
exit(1);
bioInit();
srand(time(NULL)^getpid());
- /* Try to raise the max number of open files accordingly to the
- * configured max number of clients. Also account for 32 additional
- * file descriptors as we need a few more for persistence, listening
- * sockets, log files and so forth. */
- {
- rlim_t maxfiles = server.maxclients+32;
- struct rlimit limit;
-
- if (maxfiles < 1024) maxfiles = 1024;
- if (getrlimit(RLIMIT_NOFILE,&limit) == -1) {
- redisLog(REDIS_WARNING,"Unable to obtain the current NOFILE limit (%s), assuming 1024 and setting the max clients configuration accordingly.",
- strerror(errno));
- server.maxclients = 1024-32;
- } else {
- rlim_t oldlimit = limit.rlim_cur;
-
- /* Set the max number of files if the current limit is not enough
- * for our needs. */
- if (oldlimit < maxfiles) {
- limit.rlim_cur = maxfiles;
- limit.rlim_max = maxfiles;
- if (setrlimit(RLIMIT_NOFILE,&limit) == -1) {
- server.maxclients = oldlimit-32;
- redisLog(REDIS_WARNING,"Unable to set the max number of files limit to %d (%s), setting the max clients configuration to %d.",
- (int) maxfiles, strerror(errno), (int) server.maxclients);
- } else {
- redisLog(REDIS_NOTICE,"Max number of open files set to %d",
- (int) maxfiles);
- }
- }
- }
- }
}
/* Populates the Redis Command Table starting from the hard coded list
slowlogPushEntryIfNeeded(c->argv,c->argc,duration);
c->cmd->calls++;
- if (server.appendonly && dirty > 0)
+ if (server.aof_state != REDIS_AOF_OFF && dirty > 0)
feedAppendOnlyFile(c->cmd,c->db->id,c->argv,c->argc);
if ((dirty > 0 || c->cmd->flags & REDIS_CMD_FORCE_REPLICATION) &&
listLength(server.slaves))
/* Only allow INFO and SLAVEOF when slave-serve-stale-data is no and
* we are a slave with a broken link with master. */
- if (server.masterhost && server.replstate != REDIS_REPL_CONNECTED &&
+ if (server.masterhost && server.repl_state != REDIS_REPL_CONNECTED &&
server.repl_serve_stale_data == 0 &&
c->cmd->proc != infoCommand && c->cmd->proc != slaveofCommand)
{
/* Kill the saving child if there is a background saving in progress.
We want to avoid race conditions, for instance our saving child may
overwrite the synchronous saving did by SHUTDOWN. */
- if (server.bgsavechildpid != -1) {
+ if (server.rdb_child_pid != -1) {
redisLog(REDIS_WARNING,"There is a child saving an .rdb. Killing it!");
- kill(server.bgsavechildpid,SIGKILL);
- rdbRemoveTempFile(server.bgsavechildpid);
+ kill(server.rdb_child_pid,SIGKILL);
+ rdbRemoveTempFile(server.rdb_child_pid);
}
- if (server.appendonly) {
+ if (server.aof_state != REDIS_AOF_OFF) {
/* Kill the AOF saving child as the AOF we already have may be longer
* but contains the full dataset anyway. */
- if (server.bgrewritechildpid != -1) {
+ if (server.aof_child_pid != -1) {
redisLog(REDIS_WARNING,
"There is a child rewriting the AOF. Killing it!");
- kill(server.bgrewritechildpid,SIGKILL);
+ kill(server.aof_child_pid,SIGKILL);
}
/* Append only file: fsync() the AOF and exit */
redisLog(REDIS_NOTICE,"Calling fsync() on the AOF file.");
- aof_fsync(server.appendfd);
+ aof_fsync(server.aof_fd);
}
if ((server.saveparamslen > 0 && !nosave) || save) {
redisLog(REDIS_NOTICE,"Saving the final RDB snapshot before exiting.");
/* Snapshotting. Perform a SYNC SAVE and exit */
- if (rdbSave(server.dbfilename) != REDIS_OK) {
+ if (rdbSave(server.rdb_filename) != REDIS_OK) {
/* Ooops.. error saving! The best we can do is to continue
* operating. Note that if there was a background saving process,
* in the next cron() Redis will be notified that the background
"last_save_time:%ld\r\n"
"bgrewriteaof_in_progress:%d\r\n",
server.loading,
- server.appendonly,
+ server.aof_state != REDIS_AOF_OFF,
server.dirty,
- server.bgsavechildpid != -1,
+ server.rdb_child_pid != -1,
server.lastsave,
- server.bgrewritechildpid != -1);
+ server.aof_child_pid != -1);
- if (server.appendonly) {
+ if (server.aof_state != REDIS_AOF_OFF) {
info = sdscatprintf(info,
"aof_current_size:%lld\r\n"
"aof_base_size:%lld\r\n"
"aof_pending_rewrite:%d\r\n"
"aof_buffer_length:%zu\r\n"
"aof_pending_bio_fsync:%llu\r\n",
- (long long) server.appendonly_current_size,
- (long long) server.auto_aofrewrite_base_size,
- server.aofrewrite_scheduled,
- sdslen(server.aofbuf),
+ (long long) server.aof_current_size,
+ (long long) server.aof_rewrite_base_size,
+ server.aof_rewrite_scheduled,
+ sdslen(server.aof_buf),
bioPendingJobsOfType(REDIS_BIO_AOF_FSYNC));
}
"master_sync_in_progress:%d\r\n"
,server.masterhost,
server.masterport,
- (server.replstate == REDIS_REPL_CONNECTED) ?
+ (server.repl_state == REDIS_REPL_CONNECTED) ?
"up" : "down",
server.master ?
((int)(time(NULL)-server.master->lastinteraction)) : -1,
- server.replstate == REDIS_REPL_TRANSFER
+ server.repl_state == REDIS_REPL_TRANSFER
);
- if (server.replstate == REDIS_REPL_TRANSFER) {
+ if (server.repl_state == REDIS_REPL_TRANSFER) {
info = sdscatprintf(info,
"master_sync_left_bytes:%ld\r\n"
"master_sync_last_io_seconds_ago:%d\r\n"
);
}
- if (server.replstate != REDIS_REPL_CONNECTED) {
+ if (server.repl_state != REDIS_REPL_CONNECTED) {
info = sdscatprintf(info,
"master_link_down_since_seconds:%ld\r\n",
(long)time(NULL)-server.repl_down_since);
info = sdscatprintf(info,
"connected_slaves:%d\r\n",
listLength(server.slaves));
+ if (listLength(server.slaves)) {
+ int slaveid = 0;
+ listNode *ln;
+ listIter li;
+
+ listRewind(server.slaves,&li);
+ while((ln = listNext(&li))) {
+ redisClient *slave = listNodeValue(ln);
+ char *state = NULL;
+ char ip[32];
+ int port;
+
+ if (anetPeerToString(slave->fd,ip,&port) == -1) continue;
+ switch(slave->replstate) {
+ case REDIS_REPL_WAIT_BGSAVE_START:
+ case REDIS_REPL_WAIT_BGSAVE_END:
+ state = "wait_bgsave";
+ break;
+ case REDIS_REPL_SEND_BULK:
+ state = "send_bulk";
+ break;
+ case REDIS_REPL_ONLINE:
+ state = "online";
+ break;
+ }
+ if (state == NULL) continue;
+ info = sdscatprintf(info,"slave%d:%s,%d,%s\r\n",
+ slaveid,ip,port,state);
+ slaveid++;
+ }
+ }
}
/* CPU */
}
void usage() {
- fprintf(stderr,"Usage: ./redis-server [/path/to/redis.conf]\n");
+ fprintf(stderr,"Usage: ./redis-server [/path/to/redis.conf] [options]\n");
fprintf(stderr," ./redis-server - (read config from stdin)\n");
+ fprintf(stderr," ./redis-server -v or --version\n");
+ fprintf(stderr," ./redis-server -h or --help\n\n");
+ fprintf(stderr,"Examples:\n");
+ fprintf(stderr," ./redis-server (run the server with default conf)\n");
+ fprintf(stderr," ./redis-server /etc/redis/6379.conf\n");
+ fprintf(stderr," ./redis-server --port 7777\n");
+ fprintf(stderr," ./redis-server --port 7777 --slaveof 127.0.0.1 8888\n");
+ fprintf(stderr," ./redis-server /etc/myredis.conf --loglevel verbose\n");
exit(1);
}
initServer();
if (server.daemonize) createPidFile();
redisAsciiArt();
- redisLog(REDIS_NOTICE,"Server started, Redis version " REDIS_VERSION);
+ redisLog(REDIS_WARNING,"Server started, Redis version " REDIS_VERSION);
#ifdef __linux__
linuxOvercommitMemoryWarning();
#endif
start = ustime();
- if (server.appendonly) {
- if (loadAppendOnlyFile(server.appendfilename) == REDIS_OK)
+ if (server.aof_state == REDIS_AOF_ON) {
+ if (loadAppendOnlyFile(server.aof_filename) == REDIS_OK)
redisLog(REDIS_NOTICE,"DB loaded from append only file: %.3f seconds",(float)(ustime()-start)/1000000);
} else {
- if (rdbLoad(server.dbfilename) == REDIS_OK) {
+ if (rdbLoad(server.rdb_filename) == REDIS_OK) {
redisLog(REDIS_NOTICE,"DB loaded from disk: %.3f seconds",
(float)(ustime()-start)/1000000);
} else if (errno != ENOENT) {