ParadoxV5, thanks for coming back to this!
Imagine a PrimaryâPrimary setup where both primaries write (with separate Domain IDs).
This use case wouldn't lead to the same problem, as each primary would have a separate domain-id (as you note), and when one server would restart, it would log the DELETE using its unique domain-id and replication wouldn't break.
I think the MDEV description still highlights the main use case:
this behaviour breaks simple single level replication setups with strict GTIDs
which would be any simple master->slave[->slave]+ topology where the slave isn't configured with its own domain_id (and uses strict GTID mode). And in such cases, simply viewing some memory table after restarting the slave would then break replication.
Taking a quote from Serg's comment:
We've established that if the MEMORY table on the slave is cleared because the server was restarted â this table cannot be part of the replication set, must've been ignored by the replication. Otherwise the replication will break because table's content on the slave will differ from the master's.
I'd extend this to two cases:
1. When the memory table is part of the active replication set, replication will naturally break because the content will differ.
2. When the memory table is not part of the active replication set, then running a `SELECT` against this table will break replication when we don't actually know if any updates to that table would ever come in.
I think we need to fix the second case here, where just because we are viewing some table, we shouldn't then binlog some DELETE DDL. I mean, it may even be some query to check if the master and slave table are in sync in the first place.
Another consideration is the case about what if the server was shut-down as a slave but restarted to be a primary. Then we would want to binlog the DELETE.
Now to the second part of Serg's comment:
But this slave might be a master for some other slave or at least can write its own binlog (for fail-over or backup). In this case it can put the auto-delete into the next existing GTID that would've used this table anyway. Like INSERT...SELECT in SBR or any row event that uses this table in RBR.
Here, I agree with Jimmy
I doubt hiding the desync is correct.
I'd imagine we want to fail fast. Taking Serg's example of "But this slave might be a master for some other slave", if we hide a DELETE/TRUNCATE in the next modifying GTID and it gets replicated by the next slave, then both slaves are subjected to the de-sync. On the other hand, if we don't log it at all on the restarting slave, then when some replication error does arise, we can switch the 2nd slave in line to be the 1st slave in line so replication can continue.
Additionally, the point "can write its own binlog (for fail-over or backup)", if we induce some DELETE in some future transaction, that may further break fail-over/backup, as it could take some restored server state which has a correct memory table state, and then replay the binlog to DELETE/TRUNCATE the table.
Ultimately, I think Elkin's suggestion (done in a meeting, no quote
) of using the startup option --init-rpl-role would suffice to determine whether or not we want to log the DELETE. A master would want to binlog the DELETE, whereas a slave would not. Then, if this table is updated on the master, the slave would error due to data divergence. And if a server is to function as both master-and-slave it would have its own domain-id, and we would want to binlog the DELETE, and so we would fix this via documentation by mentioning users should use option --init-rpl-role=MASTER.
Though note, if a server is configured with --init-rpl-role=SLAVE and we skip binlogging the DELETE, we should write a warning into the error log so it is easier to track down for users.
ParadoxV5, thanks for coming back to this!
This use case wouldn't lead to the same problem, as each primary would have a separate domain-id (as you note), and when one server would restart, it would log the DELETE using its unique domain-id and replication wouldn't break.
I think the MDEV description still highlights the main use case:
which would be any simple master->slave[->slave]+ topology where the slave isn't configured with its own domain_id (and uses strict GTID mode). And in such cases, simply viewing some memory table after restarting the slave would then break replication.
Taking a quote from Serg's comment:
I'd extend this to two cases:
1. When the memory table is part of the active replication set, replication will naturally break because the content will differ.
2. When the memory table is not part of the active replication set, then running a `SELECT` against this table will break replication when we don't actually know if any updates to that table would ever come in.
I think we need to fix the second case here, where just because we are viewing some table, we shouldn't then binlog some DELETE DDL. I mean, it may even be some query to check if the master and slave table are in sync in the first place.
Another consideration is the case about what if the server was shut-down as a slave but restarted to be a primary. Then we would want to binlog the DELETE.
Now to the second part of Serg's comment:
Here, I agree with Jimmy
I'd imagine we want to fail fast. Taking Serg's example of "But this slave might be a master for some other slave", if we hide a DELETE/TRUNCATE in the next modifying GTID and it gets replicated by the next slave, then both slaves are subjected to the de-sync. On the other hand, if we don't log it at all on the restarting slave, then when some replication error does arise, we can switch the 2nd slave in line to be the 1st slave in line so replication can continue.
Additionally, the point "can write its own binlog (for fail-over or backup)", if we induce some DELETE in some future transaction, that may further break fail-over/backup, as it could take some restored server state which has a correct memory table state, and then replay the binlog to DELETE/TRUNCATE the table.
Ultimately, I think Elkin's suggestion (done in a meeting, no quote
) of using the startup option --init-rpl-role would suffice to determine whether or not we want to log the DELETE. A master would want to binlog the DELETE, whereas a slave would not. Then, if this table is updated on the master, the slave would error due to data divergence. And if a server is to function as both master-and-slave it would have its own domain-id, and we would want to binlog the DELETE, and so we would fix this via documentation by mentioning users should use option --init-rpl-role=MASTER.
Though note, if a server is configured with --init-rpl-role=SLAVE and we skip binlogging the DELETE, we should write a warning into the error log so it is easier to track down for users.