diff --git a/src/networking.c b/src/networking.c index e8283c27..6ae4da5a 100644 --- a/src/networking.c +++ b/src/networking.c @@ -892,6 +892,12 @@ int processInlineBuffer(redisClient *c) { argv = sdssplitargs(aux,&argc); sdsfree(aux); + /* Newline from slaves can be used to refresh the last ACK time. + * This is useful for a slave to ping back while loading a big + * RDB file. */ + if (querylen == 0 && c->flags & REDIS_SLAVE) + c->repl_ack_time = server.unixtime; + /* Leave data after the first line of the query in the buffer */ sdsrange(c->querybuf,querylen+2,-1); diff --git a/src/rdb.c b/src/rdb.c index bc0957c2..ab24c642 100644 --- a/src/rdb.c +++ b/src/rdb.c @@ -1063,7 +1063,18 @@ void rdbLoadProgressCallback(rio *r, const void *buf, size_t len) { if (server.rdb_checksum) rioGenericUpdateChecksum(r, buf, len); if (server.loading_process_events_interval_bytes && - (r->processed_bytes + len)/server.loading_process_events_interval_bytes > r->processed_bytes/server.loading_process_events_interval_bytes) { + (r->processed_bytes + len)/server.loading_process_events_interval_bytes > r->processed_bytes/server.loading_process_events_interval_bytes) + { + if (server.masterhost && server.repl_state == REDIS_REPL_TRANSFER) { + /* Avoid the master to detect the slave is timing out while + * loading the RDB file in initial synchronization. We send + * a single newline character that is valid protocol but is + * guaranteed to either be sent entierly or not, since the byte + * is indivisible. */ + if (write(server.repl_transfer_s,"\n",1) == -1) { + /* Pinging back in this stage is best-effort. */ + } + } loadingProgress(r->processed_bytes); aeProcessEvents(server.el, AE_FILE_EVENTS|AE_DONT_WAIT); }