Start a BGSAVE for replication goals, which is, selecting the disk or * socket target depending on the configuration, and making sure that * the script cache is flushed before to start. * * The mincapa argument is the bitwise AND among all the slaves capabilities * of the slaves waiting for this BGSAVE, so represents the replica capabilities * all the slaves support. Can be tested via SLAVE_
| 1284 | * |
| 1285 | * Returns C_OK on success or C_ERR otherwise. */ |
| 1286 | int startBgsaveForReplication(int mincapa) { |
| 1287 | serverAssert(GlobalLocksAcquired()); |
| 1288 | int retval; |
| 1289 | int socket_target = g_pserver->repl_diskless_sync && (mincapa & SLAVE_CAPA_EOF); |
| 1290 | listIter li; |
| 1291 | listNode *ln; |
| 1292 | |
| 1293 | if (g_pserver->loading && g_pserver->fActiveReplica) { |
| 1294 | serverLog(LL_NOTICE, "Can't bgsave while loading in active replication mode"); |
| 1295 | return C_ERR; |
| 1296 | } |
| 1297 | |
| 1298 | serverLog(LL_NOTICE,"Starting BGSAVE for SYNC with target: %s", |
| 1299 | socket_target ? "replicas sockets" : "disk"); |
| 1300 | |
| 1301 | rdbSaveInfo rsi, *rsiptr; |
| 1302 | rsiptr = rdbPopulateSaveInfo(&rsi); |
| 1303 | /* Only do rdbSave* when rsiptr is not NULL, |
| 1304 | * otherwise replica will miss repl-stream-db. */ |
| 1305 | if (rsiptr) { |
| 1306 | if (mincapa & SLAVE_CAPA_KEYDB_FASTSYNC && FFastSyncEnabled()) |
| 1307 | retval = rdbSaveSnapshotForReplication(rsiptr); |
| 1308 | else if (socket_target) |
| 1309 | retval = rdbSaveToSlavesSockets(rsiptr); |
| 1310 | else |
| 1311 | retval = rdbSaveBackground(rsiptr); |
| 1312 | } else { |
| 1313 | serverLog(LL_WARNING,"BGSAVE for replication: replication information not available, can't generate the RDB file right now. Try later."); |
| 1314 | retval = C_ERR; |
| 1315 | } |
| 1316 | |
| 1317 | /* If we succeeded to start a BGSAVE with disk target, let's remember |
| 1318 | * this fact, so that we can later delete the file if needed. Note |
| 1319 | * that we don't set the flag to 1 if the feature is disabled, otherwise |
| 1320 | * it would never be cleared: the file is not deleted. This way if |
| 1321 | * the user enables it later with CONFIG SET, we are fine. */ |
| 1322 | if (retval == C_OK && !socket_target && g_pserver->rdb_del_sync_files) |
| 1323 | RDBGeneratedByReplication = 1; |
| 1324 | |
| 1325 | /* If we failed to BGSAVE, remove the slaves waiting for a full |
| 1326 | * resynchronization from the list of slaves, inform them with |
| 1327 | * an error about what happened, close the connection ASAP. */ |
| 1328 | if (retval == C_ERR) { |
| 1329 | serverLog(LL_WARNING,"BGSAVE for replication failed"); |
| 1330 | listRewind(g_pserver->slaves,&li); |
| 1331 | while((ln = listNext(&li))) { |
| 1332 | client *replica = (client*)ln->value; |
| 1333 | std::unique_lock<decltype(replica->lock)> lock(replica->lock); |
| 1334 | |
| 1335 | if (replica->replstate == SLAVE_STATE_WAIT_BGSAVE_START) { |
| 1336 | replica->replstate = REPL_STATE_NONE; |
| 1337 | replica->flags &= ~CLIENT_SLAVE; |
| 1338 | listDelNode(g_pserver->slaves,ln); |
| 1339 | g_pserver->rgthreadvar[replica->iel].cclientsReplica--; |
| 1340 | addReplyError(replica, |
| 1341 | "BGSAVE failed, replication can't continue"); |
| 1342 | replica->flags |= CLIENT_CLOSE_AFTER_REPLY; |
| 1343 | } |
no test coverage detected