Finally, sane MySQL clustering

This commit is contained in:
Ian Gulliver
2019-04-21 16:54:30 +00:00
parent 0b1dec18f3
commit d914fc8a83
4 changed files with 175 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
<!--# set var="title" value="Finally, sane MySQL clustering" -->
<!--# set var="date" value="January 24, 2006" -->
<!--# include file="include/top.html" -->
<p>As of MySQL 5.1.5, weve finally got <a href="http://dev.mysql.com/doc/refman/5.1/en/replication-row-based.html">row-based replication</a>. This is the last piece of the puzzle to make circular replication usable. Heres how:</p>
<p>Im assuming two MySQL servers, A and B. You can, however, use as many as you want, as long as they all somehow pull the logs from all the others.</p>
<p>Set the following config variables on both servers:</p>
<pre><code>server-id=&lt;unique number per server&gt;
log-bin=&lt;hostname&gt;-bin
relay-log=&lt;hostname&gt;-bin
log-slave-updates # really only necessary in circular replication &gt; 2 servers
binlog-format=row
</code></pre>
<p>Using the MySQL client, create replication users on both servers:</p>
<pre><code>GRANT REPLICATION SLAVE ON *.* TO repl@% IDENTIFIED BY &lt;password&gt;;
</code></pre>
<p>Then set master information on both servers, start replication and check that its working:</p>
<pre><code>CHANGE MASTER TO MASTER_HOST=&lt;address of other server&gt;, MASTER_USER=repl, MASTER_PASSWORD=&lt;password&gt;;
START SLAVE;
SHOW SLAVE STATUS\G
</code></pre>
<p>You should now be able to see multi-master replication in action:</p>
<p>On A:</p>
<pre><code>CREATE DATABASE repl_test;
SHOW DATABASES;
</code></pre>
<p>On B:</p>
<pre><code>SHOW DATABASES;
DROP DATABASE repl_test;
SHOW DATABASES;
</code></pre>
<p>On A:</p>
<pre><code>SHOW DATABASES;
</code></pre>
<h3>The AUTO_INCREMENT problem</h3>
<p>AUTO_INCREMENT-type columns get used in just about every MySQL table. Theyre a quick way to build primary keys without thinking. However, there are obvious problems in a multi-master setup (if inserts happen on both servers at the same time, theyll both get the same ID). The official MySQL solution (start the IDs on both servers at numbers significantly different from each other) is a nasty hack.</p>
<p>However, weve had <a href="http://dev.mysql.com/doc/refman/5.1/en/triggers.html">triggers</a> in InnoDB tables since MySQL 5.0, and with row-level replication, handy functions like <a href="http://dev.mysql.com/doc/refman/5.1/en/miscellaneous-functions.html#id2906147">UUID()</a> now replicate properly. This gives us a neat solution. On A:</p>
<pre><code>CREATE DATABASE IF NOT EXISTS test;
USE test;
CREATE TABLE repl_test (id CHAR(36) BINARY, test INT) ENGINE=InnoDB;
delimiter //
CREATE TRIGGER repl_test_before_insert BEFORE INSERT ON repl_test FOR EACH ROW
BEGIN
IF NEW.id IS NULL THEN
SET NEW.id = UUID();
END IF;
SET @repl_test_last_insert_id = NEW.id;
END
//
delimiter ;
INSERT INTO repl_test SET test=5;
SELECT * FROM repl_test;
SELECT @repl_test_last_insert_id;
</code></pre>
<p>On B:</p>
<pre><code>SELECT * FROM repl_test;
INSERT INTO repl_test SET test=6;
SELECT * FROM repl_test;
</code></pre>
<p>On A:</p>
<pre><code>SELECT * FROM repl_test;
</code></pre>
<!--# include file="include/bottom.html" -->

View File

@@ -40,6 +40,7 @@
<li>2009-Sep-11: <a href="2009-09-11-confusing-bind-with-cnames.html">Confusing BIND with CNAMEs</a></li>
<li>2009-Feb-19: <a href="2019-02-19-the-odd-case-of-my-mugging.html">The odd case of my mugging</a></li>
<li>2009-Feb-03: <a href="2009-02-03-5-packet-tcp-connection.html">5-packet TCP connection?</a></li>
<li>2006-Jan-24: <a href="2006-01-24-finally-sane-mysql-clustering.html">Finally, sane MySQL clustering</a></li>
<li>2006-Jan-23: <a href="2006-01-23-ibm-thinkcentre-a50-slowdown.html">IBM ThinkCentre A50 Slowdown</a></li>
<li>2006-Jan-23: <a href="2006-01-23-ssh-tunnelling-101.html">SSH Tunnelling 101</a></li>
<li>2006-Jan-23: <a href="2006-01-23-how-to-install-debian-sarge-on-an-ibm-blade.html">How to install Debian Sarge on an IBM Blade</a></li>

View File

@@ -0,0 +1,82 @@
<!--# set var="title" value="Finally, sane MySQL clustering" -->
<!--# set var="date" value="January 24, 2006" -->
<!--# include file="include/top.html" -->
As of MySQL 5.1.5, weve finally got [row-based replication](http://dev.mysql.com/doc/refman/5.1/en/replication-row-based.html). This is the last piece of the puzzle to make circular replication usable. Heres how:
Im assuming two MySQL servers, A and B. You can, however, use as many as you want, as long as they all somehow pull the logs from all the others.
Set the following config variables on both servers:
server-id=<unique number per server>
log-bin=<hostname>-bin
relay-log=<hostname>-bin
log-slave-updates # really only necessary in circular replication > 2 servers
binlog-format=row
Using the MySQL client, create replication users on both servers:
GRANT REPLICATION SLAVE ON *.* TO repl@% IDENTIFIED BY <password>;
Then set master information on both servers, start replication and check that its working:
CHANGE MASTER TO MASTER_HOST=<address of other server>, MASTER_USER=repl, MASTER_PASSWORD=<password>;
START SLAVE;
SHOW SLAVE STATUS\G
You should now be able to see multi-master replication in action:
On A:
CREATE DATABASE repl_test;
SHOW DATABASES;
On B:
SHOW DATABASES;
DROP DATABASE repl_test;
SHOW DATABASES;
On A:
SHOW DATABASES;
### The AUTO\_INCREMENT problem
AUTO\_INCREMENT-type columns get used in just about every MySQL table. Theyre a quick way to build primary keys without thinking. However, there are obvious problems in a multi-master setup (if inserts happen on both servers at the same time, theyll both get the same ID). The official MySQL solution (start the IDs on both servers at numbers significantly different from each other) is a nasty hack.
However, weve had [triggers](http://dev.mysql.com/doc/refman/5.1/en/triggers.html) in InnoDB tables since MySQL 5.0, and with row-level replication, handy functions like [UUID()](http://dev.mysql.com/doc/refman/5.1/en/miscellaneous-functions.html#id2906147) now replicate properly. This gives us a neat solution. On A:
CREATE DATABASE IF NOT EXISTS test;
USE test;
CREATE TABLE repl_test (id CHAR(36) BINARY, test INT) ENGINE=InnoDB;
delimiter //
CREATE TRIGGER repl_test_before_insert BEFORE INSERT ON repl_test FOR EACH ROW
BEGIN
IF NEW.id IS NULL THEN
SET NEW.id = UUID();
END IF;
SET @repl_test_last_insert_id = NEW.id;
END
//
delimiter ;
INSERT INTO repl_test SET test=5;
SELECT * FROM repl_test;
SELECT @repl_test_last_insert_id;
On B:
SELECT * FROM repl_test;
INSERT INTO repl_test SET test=6;
SELECT * FROM repl_test;
On A:
SELECT * FROM repl_test;
<!--# include file="include/bottom.html" -->

View File

@@ -39,6 +39,7 @@
1. 2009-Sep-11: [Confusing BIND with CNAMEs](2009-09-11-confusing-bind-with-cnames.html)
1. 2009-Feb-19: [The odd case of my mugging](2019-02-19-the-odd-case-of-my-mugging.html)
1. 2009-Feb-03: [5-packet TCP connection?](2009-02-03-5-packet-tcp-connection.html)
1. 2006-Jan-24: [Finally, sane MySQL clustering](2006-01-24-finally-sane-mysql-clustering.html)
1. 2006-Jan-23: [IBM ThinkCentre A50 Slowdown](2006-01-23-ibm-thinkcentre-a50-slowdown.html)
1. 2006-Jan-23: [SSH Tunnelling 101](2006-01-23-ssh-tunnelling-101.html)
1. 2006-Jan-23: [How to install Debian Sarge on an IBM Blade](2006-01-23-how-to-install-debian-sarge-on-an-ibm-blade.html)