MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / updateSlavesWaitingBgsave

Function updateSlavesWaitingBgsave

src/replication.cpp:2099–2193  ·  view source on GitHub ↗

This function is called at the end of every background saving, * or when the replication RDB transfer strategy is modified from * disk to socket or the other way around. * * The goal of this function is to handle slaves waiting for a successful * background saving in order to perform non-blocking synchronization, and * to schedule a new BGSAVE if there are slaves that attached while a * BGS

Source from the content-addressed store, hash-verified

2097 * The 'type' argument is the type of the child that terminated
2098 * (if it had a disk or socket target). */
2099void updateSlavesWaitingBgsave(int bgsaveerr, int type)
2100{
2101 listNode *ln;
2102 listIter li;
2103 serverAssert(GlobalLocksAcquired());
2104
2105 listRewind(g_pserver->slaves,&li);
2106 while((ln = listNext(&li))) {
2107 client *replica = (client*)ln->value;
2108
2109 std::unique_lock<fastlock> ul(replica->lock);
2110
2111 if (replica->replstate == SLAVE_STATE_WAIT_BGSAVE_END) {
2112 struct redis_stat buf;
2113
2114 if (bgsaveerr != C_OK) {
2115 ul.unlock();
2116 freeClientAsync(replica);
2117 serverLog(LL_WARNING,"SYNC failed. BGSAVE child returned an error");
2118 continue;
2119 }
2120
2121 /* If this was an RDB on disk save, we have to prepare to send
2122 * the RDB from disk to the replica socket. Otherwise if this was
2123 * already an RDB -> Slaves socket transfer, used in the case of
2124 * diskless replication, our work is trivial, we can just put
2125 * the replica online. */
2126 if (type == RDB_CHILD_TYPE_SOCKET) {
2127 serverLog(LL_NOTICE,
2128 "Streamed RDB transfer with replica %s succeeded (socket). Waiting for REPLCONF ACK from slave to enable streaming",
2129 replicationGetSlaveName(replica));
2130 /* Note: we wait for a REPLCONF ACK message from the replica in
2131 * order to really put it online (install the write handler
2132 * so that the accumulated data can be transferred). However
2133 * we change the replication state ASAP, since our slave
2134 * is technically online now.
2135 *
2136 * So things work like that:
2137 *
2138 * 1. We end trasnferring the RDB file via socket.
2139 * 2. The replica is put ONLINE but the write handler
2140 * is not installed.
2141 * 3. The replica however goes really online, and pings us
2142 * back via REPLCONF ACK commands.
2143 * 4. Now we finally install the write handler, and send
2144 * the buffers accumulated so far to the replica.
2145 *
2146 * But why we do that? Because the replica, when we stream
2147 * the RDB directly via the socket, must detect the RDB
2148 * EOF (end of file), that is a special random string at the
2149 * end of the RDB (for streamed RDBs we don't know the length
2150 * in advance). Detecting such final EOF string is much
2151 * simpler and less CPU intensive if no more data is sent
2152 * after such final EOF. So we don't want to glue the end of
2153 * the RDB trasfer with the start of the other replication
2154 * data. */
2155 replica->replstate = SLAVE_STATE_ONLINE;
2156 replica->repl_put_online_on_ack = 1;

Callers 1

Calls 13

GlobalLocksAcquiredFunction · 0.85
listRewindFunction · 0.85
listNextFunction · 0.85
freeClientAsyncFunction · 0.85
serverLogFunction · 0.85
replicationGetSlaveNameFunction · 0.85
sdscatprintfFunction · 0.85
sdsemptyFunction · 0.85
FCorrectThreadFunction · 0.85
connSetWriteHandlerFunction · 0.85
postFunctionMethod · 0.80
freeClientFunction · 0.70

Tested by

no test coverage detected