Alex Yurchenko <alexey.yurchenko@codership.com> writes:
Since both are configured manually, and domain ID can simply default to 0 in simple setups, I'd imagine that the possibility of having server ID configured incorrectly (just missing to configure it) is way more probable than having domain ID incorrect. Actually, being an
Are you sure? Traditional replication has always tried to make sure that server_id is configured to be unique. You cannot even start a slave if server_id is not set. And if the master and slave has same server_id, you get this error when starting the slave: 130508 13:43:04 [ERROR] Slave I/O: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the --replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it). Internal MariaDB error code: 1593
arbitrary node group ID what is "incorrect" here? ANY value just makes the node a member of the corresponding domain, so ANY domain ID value is legal. Whereas server ID can certainly be incorrect (a duplicate within the domain).
Here is how I suggest to think about it: Server_id is assumed to uniquely identify any server, there is some code to help ensure this. Each server keeps a local counter which is guaranteed to increment for each new transaction originating on that server (it can increment with more than 1, but never decrement). This ensures uniqueness of the GTID. The GTID code has the ability to locate any GTID in the binlogs on a server (or detect that the GTID is missing). The slave remembers the last GTID it replicated. This allows a slave to connect to a new master and locate the point in the binlog on the new master that corresponds to where it stopped on the old master. All of this works without any regard to replication domain ID. So in this sense, there is no incorrect configuration of domain ID possible, as you say. But now, on the next level, we consider what happens if the order of transactions in the binlog on the new master differs from that on the old master. If the order is A,B on the old but B,A on the new, and the slave was at point A on the old, then starting at A on the new will loose a transaction B (similarly we can duplicate a transaction). Different binlog order can happen for two reasons. Either by mistake (or sloppyness), or deliberately, due to transactions happening independently in parallel (such as multi-source replication). And we want to deal with both cases. To handle the mistake, I plan to implement a strict mode. Whenever we originate a new transaction on a server and write it to the binlog, we ensure it has a higher sequence number than any previous one. Then, if on replication we receive a transaction from a master where the sequence number is not bigger than the last thing logged in the slave's binlog, we have detected an out-of-order situation, and stop with an error. To handle sloppyness, users can disable strict mode. If they then get out-of-order binlog (because of not obeying read-only slave or something), things will still work (because on the basic level we have the ability to locate any GTID, even if sequence numbers are not strictly increasing). However they need to be careful if they change master around the out-of-order points, as per the A,B / B,A example above. This is no different from old-style replication (and it is required that non-strict be default, to not break upgrade of existing setups). The purpose of domain IDs is to handle the deliberate case. The user/DBA/application needs to explicitly declare that two transactions are intended to be independent, generated in parallel in arbitrary order. This declaration is done by giving independent transactions distinct domain IDs, and using same domain ID for transactions that were intended to be ordered. The slave will then remember one binlog position for every domain ID. This avoids the A,B / B,A problem or related issues, as long as order is in fact preserved within one replication domain (and with strict mode, we can detect mistakes). So the issue of "correct" configuration for domain_is is that any two transactions that can end up in different order in binlogs on different servers, should have different domain ID. A further advantage (for later) is that, knowing that GTIDs 0-1-10 and 1-2-20 are independent (different domain), a slave server is free to replicate then in parallel and commit in any order. This will later be used to implement robust, out-of-order parallel slave. So this is how domain ID should be thought of: it is a declaration, by the user, about which transactions are independent, and which are considered strictly ordered with one another.
So suppose we have nodes N0, N1 and N2 with IDs 0-0, 0-1, 0-2 respectively.
Initially N1 and N2 both replicate from N0 and have identical DB contents.
At 0-0-10 N2 goes to maintenance.
After 0-0-100 someone executes local transaction on N1 and it gets logged as 0-1-101. Right?
Yes.
So if now N0 executes another transaction, what will be its GTID? a) on N0 - 0-0-101?
Yes.
b) on N1 - 0-0-102 or 0-0-101?
0-0-101. (GTIDs are always preserved by replication.)
The server ID is set to the server ID of the server where the event group is first logged into the binlog. The sequence number is increased on a server for every event group logged. So it is actually another question, sequence number is not set on the master server but always computed locally?)
No, this is bad wording on my part. When a new transaction is first created by a user, it gets a new, increased sequence number. But as it replicates between servers, the sequence number is kept.
Or, does N1 detect a problem at this point? If yes, how exactly? How server ID is involved there?
Once strict mode is implemented, it will detect the problem that N1's binlog has 0-1-101. And now replication wants to log another GTID 0-0-101, with a sequence number that is not increasing. With strict mode on, this will be an error (replication will be stopped). I think server ID is not really involved here. It would also be an error to try to log 0-0-101 if the binlog already contained 0-0-101. Server ID is mostly used to be able to locate arbitrary GTID in the binlog, even if sequence numbers happen to be not always increasing.
Now if we can get past this point without an error at N1, and start N2 to replicate from N1, I take it will receive and commit 0-1-101. But
Yes.
will it ever record it somewhere or its state will be simply 0-0-XXX?
Just after applying 0-1-101, the state will be just that, 0-1-101. But then as we proceed with 0-0-101 and further 0-0-XXX, the state will simply be 0-0-XXX.
If at 0-0-110 we failover N0 to replicate from N2, will it receive 0-1-101?
No. Because 0-1-101 is before 0-0-110 in the binlog on N2. - Kristian.