/* Ok we don't have a BGSAVE in progress, let's start one */
redisLog(REDIS_NOTICE,"Starting BGSAVE for SYNC");
if (rdbSaveBackground(server.rdb_filename) != REDIS_OK) {
redisLog(REDIS_NOTICE,"Replication failed, can't BGSAVE");
addReplyError(c,"Unable to perform background save");
return;
}
// µÈ´ý BGSAVE ½áÊø
c->replstate = REDIS_REPL_WAIT_BGSAVE_END;
}
c->repldbfd = -1;
c->flags |= REDIS_SLAVE;
c->slaveseldb = 0;
listAddNodeTail(server.slaves,c);
......
}
ÕâÀï²¢²»ÊÇÕæÕý´¦Àíͬ²½µÄ£¬¶øÊǰÑslave²åÈëµ½masterÖÐslavesÁ´±íÖеȴýÕæÕýͬ²½µÄ²Ù×÷¡£ÄÇʲôʱºò²ÅÊÇÕæÕýͬ²½µÄ²Ù×÷ÄØ£¿Çë¿´updateSlavesWaitingBgsave
[cpp]
void updateSlavesWaitingBgsave(int bgsaveerr) {
......
listRewind(server.slaves,&li);
while((ln = listNext(&li))) {
redisClient *slave = ln->value;
if (slave->replstate == REDIS_REPL_WAIT_BGSAVE_START) {
// ¸æËßÄÇЩÕâ´Î²»ÄÜͬ²½µÄ¿Í»§¶Ë£¬¿ÉÒԵȴýÏ´ΠBGSAVE ÁË¡£
startbgsave = 1;
slave->replstate = REDIS_REPL_WAIT_BGSAVE_END;
} else if (slave->replstate == REDIS_REPL_WAIT_BGSAVE_END) {
// ÕâЩÊDZ¾´Î¿ÉÒÔͬ²½µÄ¿Í»§¶Ë
struct redis_stat buf;
// Èç¹û BGSAVE ʧ°Ü£¬ÊÍ·Å slave ½Úµã
if (bgsaveerr != REDIS_OK) {
freeClient(slave);
redisLog(REDIS_WARNING,"SYNC failed. BGSAVE child returned an error");
continue;
}
// ´ò¿ª .rdb Îļþ
if ((slave->repldbfd = open(server.rdb_filename,O_RDONLY)) == -1 ||
// Èç¹û´ò¿ªÊ§°Ü£¬ÊͷŲ¢Çå³ý
redis_fstat(slave->repldbfd,&buf) == -1) {
freeClient(slave);
redisLog(REDIS_WARNING,"SYNC failed. Can't open/stat DB after BGSAVE: %s", strerror(errno));
continue;
}
// Æ«ÒÆÁ¿
slave->repldboff = 0;
//
Êý¾Ý¿â´óС£¨.rdb ÎļþµÄ´óС£©
slave->repldbsize = buf.st_size;
// ״̬
slave->replstate = REDIS_REPL_SEND_BULK;
// Çå³ý slave->fd µÄдʼþ
aeDeleteFileEvent(server.el,slave->fd,AE_WRITABLE);
// ´´½¨Ò»¸ö½« .rdb ÎļþÄÚÈÝ·¢Ë͵½¸½Êô½ÚµãµÄдʼþ
if (aeCreateFileEvent(server.el, slave->fd, AE_WRITABLE, sendBulkToSlave, slave) == AE_ERR) {
freeClient(slave);
continue;
}
}
}
......
}
Õâ¸öº¯Êý»áÿ¸öslave´´½¨Ò»¸ö¿ÉдµÄʼþ£¬²¢´ÓrdbÎļþÖаÑÊý¾Ý¶Á³öÀ´£¬Í¨¹ýsendBulkToSlave·¢Ë͸øslave¡£master·¢ËÍÍêºó£¬slave½ÓÊÜÊý¾Ý²¢½øÐд¦Àí£¬ÉÏÃæÒѾ¿´µ½slave¸ø¶ÁʼþÉèÖÃÁËhandler£¨readSyncBulkPayload£©
ÒÔÉϾÍÊǶ¨Ê±Æ÷ʵÏÖÖ÷´Óͬ²½£¬µÚ¶þÖÖʵÏÖÖ÷´Óͬ²½µÄÇé¿ö±È½Ï¼òµ¥¡£
ÿ´Îmaster½ÓÊÕµ½¿Í»§¶ËÖ¸Áî¶¼»áµ÷ÓÃcallÕâ¸öº¯Êý£º
[cpp]
void call(redisClient *c, int flags) {
......
if (flags & REDIS_CALL_PROPAGATE) {
int flags = REDIS_PROPAGATE_NONE;
if (c->cmd->flags & REDIS_CMD_FORCE_REPLICATION)
flags |= REDIS_PROPAGATE_REPL;
if (dirty)
flags |= (REDIS_PROPAGATE_REPL | REDIS_PROPAGATE_AOF);
if (flags != REDIS_PROPAGATE_NONE)
propagate(c->cmd,c->db->id,c->argv,c->argc,flags);
}
......
}
propagate¾ÍÊÇʵÏÖµÚ¶þÖÖÖ÷´Óͬ²½¡£
[cpp]
void propagate(struct redisCommand *cmd, int dbid, robj **argv, int argc,
int flags)
{
if (server.aof_state != REDIS_AOF_OFF && flags & REDIS_PROPAGATE_AOF)
feedAppendOnlyFile(cmd,dbid,argv,