mirror of
https://github.com/fluencelabs/redis
synced 2025-06-12 16:51:22 +00:00
PSYNC2: Fix the way replication info is saved/loaded from RDB.
This commit attempts to fix a number of bugs reported in #4316. They are related to the way replication info like replication ID, offsets, and currently selected DB in the master client, are stored and loaded by Redis. In order to avoid inconsistencies the changes in this commit try to enforce that: 1. Replication information are only stored when the RDB file is generated by a slave that has a valid 'master' client, so that we can always extract the currently selected DB. 2. When replication informations are persisted in the RDB file, all the info for a successful PSYNC or nothing is persisted. 3. The RDB replication informations are only loaded if the instance is configured as a slave, otherwise a master can start with IDs that relate to a different history of the data set, and stil retain such IDs in the future while receiving unrelated writes.
This commit is contained in:
34
src/rdb.c
34
src/rdb.c
@ -858,16 +858,14 @@ int rdbSaveInfoAuxFields(rio *rdb, int flags, rdbSaveInfo *rsi) {
|
||||
|
||||
/* Handle saving options that generate aux fields. */
|
||||
if (rsi) {
|
||||
if (rsi->repl_stream_db &&
|
||||
rdbSaveAuxFieldStrInt(rdb,"repl-stream-db",rsi->repl_stream_db)
|
||||
== -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (rdbSaveAuxFieldStrInt(rdb,"repl-stream-db",rsi->repl_stream_db)
|
||||
== -1) return -1;
|
||||
if (rdbSaveAuxFieldStrStr(rdb,"repl-id",server.replid)
|
||||
== -1) return -1;
|
||||
if (rdbSaveAuxFieldStrInt(rdb,"repl-offset",server.master_repl_offset)
|
||||
== -1) return -1;
|
||||
}
|
||||
if (rdbSaveAuxFieldStrInt(rdb,"aof-preamble",aof_preamble) == -1) return -1;
|
||||
if (rdbSaveAuxFieldStrStr(rdb,"repl-id",server.replid) == -1) return -1;
|
||||
if (rdbSaveAuxFieldStrInt(rdb,"repl-offset",server.master_repl_offset) == -1) return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2017,3 +2015,23 @@ void bgsaveCommand(client *c) {
|
||||
addReply(c,shared.err);
|
||||
}
|
||||
}
|
||||
|
||||
/* Populate the rdbSaveInfo structure used to persist the replication
|
||||
* information inside the RDB file. Currently the structure explicitly
|
||||
* contains just the currently selected DB from the master stream, however
|
||||
* if the rdbSave*() family functions receive a NULL rsi structure also
|
||||
* the Replication ID/offset is not saved. The function popultes 'rsi'
|
||||
* that is normally stack-allocated in the caller, returns the populated
|
||||
* pointer if the instance has a valid master client, otherwise NULL
|
||||
* is returned, and the RDB savign wil not persist any replication related
|
||||
* information. */
|
||||
rdbSaveInfo *rdbPopulateSaveInfo(rdbSaveInfo *rsi) {
|
||||
rdbSaveInfo rsi_init = RDB_SAVE_INFO_INIT;
|
||||
*rsi = rsi_init;
|
||||
if (server.master) {
|
||||
rsi->repl_stream_db = server.master->db->id;
|
||||
return rsi;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user