|
依据数据构建日志)
//那么将当前命令的buff添加到server.aof_rewrite_buf_blocks内存中(该部分内存
//专门记录在重构AOF期间redis处理的操作)
if (server.aof_child_pid != -1)
aofRewriteBufferAppend((unsigned char*)buf,sdslen(buf));
sdsfree(buf);
}
////////////////////////////////////////////////////////////////////////////////////////
int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) {
int j;
REDIS_NOTUSED(eventLoop);
REDIS_NOTUSED(id);
REDIS_NOTUSED(clientData);
/* Software watchdog: deliver the SIGALRM that will reach the signal
* handler if we don't return here fast enough. */
if (server.watchdog_period) watchdogScheduleSignal(server.watchdog_period);
/* We take a cached value of the unix time in the global state because
* with virtual memory and aging there is to store the current time
* in objects at every object access, and accuracy is not needed.
* To access a global var is faster than calling time(NULL) */
//缓存系统时间...
server.unixtime = time(NULL);
server.mstime = mstime();
...
/* Start a scheduled AOF rewrite if this was requested by the user while
* a BGSAVE was in progress. */
//开启AOF日志重建的子进程(简化日志)
//后台AOF子进程通过扫描redis.db[16]数据,生成可重建当前数据库的命令,
//并写入临时文件tmpfile
if (server.rdb_child_pid == -1 && server.aof_child_pid == -1 &&
server.aof_rewrite_scheduled)
{
//AOF
rewriteAppendOnlyFileBackground();
}
/* Check if a background saving or AOF rewrite in progress terminated. */
//后台AOF进程结束:将在后台AOF子进程构建AOF日志期间redis执行的新命令
//(记录于server.aof_rewrite_buf_blocks)append 到后台子进程构建的tmpfile中
//最后将tmpfile重名为server.aof_filename 替换原有AOF
if (server.rdb_child_pid != -1 || server.aof_child_pid != -1) {
int statloc;
pid_t pid;
if ((pid = wait3(&statloc,WNOHANG,NULL)) != 0) {
int exitcode = WEXITSTATUS(statloc);
int bysignal = 0;
if (WIFSIGNALED(statloc)) bysignal = WTERMSIG(statloc);
if (pid == server.rdb_child_pid) {
backgroundSaveDoneHandler(exitcode,bysignal);
} else if (pid == server.aof_child_pid) {
backgroundRewriteDoneHandler(exitcode,bysignal);
} else {
redisLog(REDIS_WARNING,
"Warning, detected child with unmatched pid: %ld",
(long)pid);
}
updateDictResizePolicy();
}
} else {
/* If there is not a background saving/rewrite in progress check if
* we have to save/rewrite now */
//没有后台子进程在跑,那么检查是否要开启一个AOF或者RDB的子进程。。。
...
}
/* If we postponed an AOF buffer flush, let's try to do it every time the
* cron function is called. */
//将server.aof_buf(缓存redis最近执行过的命名)flush到磁盘AOF文件中
//flush的策略有如下:
//每个操作,调用fync将命令持久化
//间隔1秒,调用fync将aof_buf持久化
//从不调用fync,由系统自行安排时机
if (server.aof_flush_postponed_start) flushAppendOnlyFile(0);
...
server.cronloops++;
return 1000/server.hz;
}
/* This is how rewriting of the append only file in background works:
*
* 1) The user calls BGREWRITEAOF
* 2) Redis calls this function, that forks():
* 2a) the child rewrite the append only file in a temp file.
* 2b) the parent accumulates differences in server.aof_rewrite_buf.
* 3) When the child finished '2a' exists.
* 4) The parent will trap the exit code, if it's OK, will append the
* data accumulated into server.aof_rewrite_buf into the temp file, and
* finally will rename(2) the temp file in the actual file name.
* The the new file is reopened as the new append only file. Profit!
*/
int rewrite |