Question 1
Does the DML operations committed by db2 during the replication process gets included in its own bin-log?
Answer to Question 1
Yes it will, provided you have this in /etc/my.cnf on both db1 and db2
[mysqld]
log-slave-updates
If you do not have this, add it and restart mysql
Question 2
Would the resulting bin-log in db2 be exactly the same with the bin-log of db1, to the letter?
Answer to Question 2
Yes. Make sure the clocks on both DB servers are synchronized
Question 3
What happens to the entries in db2 relay-log once they are committed to the database during the replication process, are they discarded? What role does the relay-log info log has in this?
Answer to Question 3
In MySQL Replication, the IO Thread of a Slave will read its Master's bin-log entries and store them in a FIFO queue. For each relay log in a slave, when every entry in the currently processed relay is executed it is rotated out and discarded. If relay logs are piling up, this quickly indicates that the SQL thread died because of any SQL error. Just do SHOW SLAVE STATUS\G
to find out what stopped the SQL thread. The IO Thread would conitnue collecting completed SQL statements from its Master.
Question 4
How does db1 know where in the bin-log of db2 (somehow dependent on the answer of Question 2), it will start the replication process?
Answer to Question 4
When you do SHOW SLAVE STATUS\G
, look for the following lines:
- Master_Log_File : The latest binary log whose most recently command was copied to the Slave
- Read_Master_Log_Pos : The latest position of the latest binary log whose most recently command was copied to the Slave
- Relay_Master_Log_File : The latest binary log whose most recently command was executed on the Slave
- Exec_Master_Log_Pos : The latest binary log whose most recently command was executed on the Slave
- Relay_Log_Space : The sum total (in bytes) of all relay logs. By default, each relay log is the default size of a binary log (1G). If Relay_Log_Space starts to significant exceed 1G, this indicates one of two things:
- SQL thread died due to SQL Error
- SQL thread is busy with a long-running query
Question 4.1
If you enable log-slave-updates on both databases i.e. dB1 & dB2, then that would mean all items from the binary log of dB1, which was successfully replicated by dB2 will be written into dB2's binary log and vice-versa. Would not this result to some sort of infinite circular replication or duplications of entries on both databases, if it's possible at all, considering the possible key-collision issues that would arise? What I'm trying to say is, How would dB1 know once it checks on the binary log of dB2 that, "I should not replicate those entries in there because they all just came from me"?
Answer to Question 4.1
You must have log-slave-updates available on both DB servers in order to have an audit trail that the SQL executed on on DB server made it to the other. If you don't, you would have to do your due diligence to compare the data explicitly. Such ways would include:
- Running CHECKSUM TABLE on every table you have in both DB servers to compare their contents.
- Using pt-table-checksum, which is an automated version of running CHECKSUM TABLE between Master and one or more Slaves
You need not worry about infinite circular replication unless you are dealing with more that two masters. There have been rare times when someone with, let's say four Masters, removes one of the four servers from circular rep cluster. Let's suppose the the server_id is 13. It is remotely, but still, possible for binary log entries whose server_id belongs to the server that removed to be inside the relay logs on other servers. Only in such a scenario would you worry about infinite circular replication.
To circumvent such situations, MySQL 5.5 has a new option for the CHANGE MASTER TO command called IGNORE_SERVER_IDS
. You would do the following to repair things on all the remaining servers:
STOP SLAVE;
CHANGE MASTER TO IGNORE_SERVER_IDS = (13);
START SLAVE;
In fact, here is what the MySQL Documentation says on this:
IGNORE_SERVER_IDS was added in MySQL 5.5. This option takes a comma-separated list of 0 or more server IDs. Events originating from
the corresponding servers are ignored, with the exception of log
rotation and deletion events, which are still recorded in the relay
log.
In circular replication, the originating server normally acts as the terminator of its own events, so that they are not applied more
than once. Thus, this option is useful in circular replication when
one of the servers in the circle is removed. Suppose that you have a
circular replication setup with 4 servers, having server IDs 1, 2, 3,
and 4, and server 3 fails. When bridging the gap by starting
replication from server 2 to server 4, you can include
IGNORE_SERVER_IDS = (3) in the CHANGE MASTER TO statement that you
issue on server 4 to tell it to use server 2 as its master instead of
server 3. Doing so causes it to ignore and not to propagate any
statements that originated with the server that is no longer in use.
Question 5
On INSERT queries on the master, what form of the query is written into the binary log? Is it the 'raw' form of the query, or the one which already has the auto-generated value of the auto-increment key?
Answer to Question 5
Whichever form is presented. Here is what I mean: The raw form would usually not include the auto_increment column expressed explicitly. On the other hand, it you import a mysqldump into a DB server with binary logging, the rows being inserted would explicitly be given. Either version of INSERT would be allowed execution in mysqld. In like fashion, either version of INSERT would be recorded AS IS...
What you want is server1
to binlog not only its own updates, but also those updates he received from server2
, so that slave1
will get all updates.
You just need to tell server1
to do this, which can be accomplished by setting log-slave-updates
to yes.
You might want to set this option on server2
too, if the server topology should change someday (as Rolando kindly remarked in the comments below).
This does not loop endlessly as the default setting for replicate-same-server-id
is 0
(and cannot be changed as long as log-slave-updates
is on). This setting set to 0 means the slave will skip statements he receives with his own server-id.
Your infrastructure decision in general seems fine to me.
Best Answer
The tutorial you linked to is, I'm afraid, very optimistic. It forgets to note that it only covers the case of an auto generated
AUTO_INCREMENT PRIMARY KEY
.The methods it suggests do not cover the general case for a
UNIQUE KEY
, including, of course, a generalPRIMARY KEY
.The article does mention that "The most common problem with replication is primary key collision". It then completely fails to mention all the other problems...
So, anyway, any
UNIQUE KEY
collision will render your replication broken, possibly in both directions.Which table was it that failed your replication? Was that a table with an
AUTO_INCREMENT PRIMARY KEY
or a "general"PRIMARY KEY
(ie on non-AUTO_ICNREMENT
columns)?To solve the general case of unique keys, your application must be very aware of its location (Netherlands or Washington DC), and must refrain from writing data that may cause collision. Alternatively it might want to use some synchronizing/locking mechanism; that would of course induce latency as data must cross the Atlantic.
Might I also suggest that the use of
binlog_do_db
is also naive and dangerous. Are you sure you don't want to replicate themysql
schema? What happens when you add new schemas? The general correct solution is to have full replication without filtering, or otherwise have a very good explanation why not to do so.Finally, I highly discourage the use of active-active master-master replication. I had customers using it in the past. The amount of trouble they went into because of that setup, and in spite of my counter-recommendations, led to many ruined weekends and holidays.
You might want to look at Galera replication. It's a synchronized master replication solution, and I hear it works over WAN. This will allow your application to remain ignorant. Watch out for network failures, as one part of your cluster will turn immutable.