{"id":722,"date":"2014-11-15T12:39:55","date_gmt":"2014-11-15T11:39:55","guid":{"rendered":"http:\/\/it.tuxie.eu\/?p=722"},"modified":"2015-01-27T16:55:05","modified_gmt":"2015-01-27T15:55:05","slug":"master-master-replication-mariadb-on-manjaro","status":"publish","type":"post","link":"http:\/\/it.tuxie.eu\/?p=722","title":{"rendered":"Master-master replication (MariaDB on Manjaro)"},"content":{"rendered":"<p>Sometimes it&#8217;s very useful to skip well-known master-slave replication scenario and focus on master-master possibility \ud83d\ude42<\/p>\n<p><!--more--><\/p>\n<p><span style=\"color: #ff6600;\"><strong>1) Prerequisities<\/strong><\/span><\/p>\n<p>2 linux distributions with functional mysql server installed. In my case double Manjaro 0.8.11 Openbox will be working fine. Manjaro is riding modern wave of replacement MySQL-&gt;MariaDB + using systemd (please don&#8217;t kill me, sysvinit fanatics).<\/p>\n<p>VirtualBox is set to network with host only =&gt;<\/p>\n<p>M1 = 192.168.56.101, source database (sakila in this case), primary, The One \ud83d\ude42<\/p>\n<p>M2 = 192.168.56.102, new master with no data, secondary master.<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #ff6600;\"><strong>2) Setup<\/strong><\/span><\/p>\n<p><span style=\"text-decoration: underline;\">2.1 Configuration settings<\/span><\/p>\n<p>Main MySQL\/MariaDB configuration file is \/etc\/mysql\/my.cnf\u00a0 (path can differ, indeed). Find a section [mysqld], check if there are old value &#8211; if it is so, rewrite them into new values and add new variables. Values for M1:<br \/>\n[crayon lang=&#8220;shell&#8220;]<br \/>\nserver_id           = 1<br \/>\nlog_bin             = \/var\/log\/mysql\/mysql-bin.log<br \/>\nlog_bin_index       = \/var\/log\/mysql\/mysql-bin.log.index<br \/>\nrelay_log           = \/var\/log\/mysql\/mysql-relay-bin<br \/>\nrelay_log_index     = \/var\/log\/mysql\/mysql-relay-bin.index<br \/>\nexpire_logs_days    = 10<br \/>\nmax_binlog_size     = 100M<br \/>\nlog_slave_updates   = 1<br \/>\nauto-increment-increment = 2<br \/>\nauto-increment-offset = 1<br \/>\n[\/crayon]<\/p>\n<p>Just very quick info about tricky part &#8211; server_id must be unique within replication environment; auto-increment-increment + auto-increment-offset = auto-increment values are starting with 1, step is 2 = 1,3,5,7,&#8230;..\u00a0 As you can imagine, collision with another master will be critical \ud83d\ude42 Yup, odd and even numbers will be sufficient in 2 masters envrionment.<\/p>\n<p>Similar to M1 we will setup my.cnf for M2 server:<br \/>\n[crayon lang=&#8220;shell&#8220;]<br \/>\nserver_id           = 2<br \/>\nlog_bin             = \/var\/log\/mysql\/mysql-bin.log<br \/>\nlog_bin_index       = \/var\/log\/mysql\/mysql-bin.log.index<br \/>\nrelay_log           = \/var\/log\/mysql\/mysql-relay-bin<br \/>\nrelay_log_index     = \/var\/log\/mysql\/mysql-relay-bin.index<br \/>\nexpire_logs_days    = 10<br \/>\nmax_binlog_size     = 100M<br \/>\nlog_slave_updates   = 1<br \/>\nauto-increment-increment = 2<br \/>\nauto-increment-offset = 2<br \/>\n[\/crayon]<br \/>\nServer_id is set to 2, increment values starting with 2, increment 2 = 2,4,6,8,&#8230;.<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"text-decoration: underline;\">2.2 Data transfer<\/span><\/p>\n<p>As I mentioned, i have sakila database on M1 already. As we are not running any replication now, data are still just on M1. As whole this setup we made can&#8217;t run &#8222;in a past&#8220;, we will move data by mysqldump and every following action will be recorded by our replication environment. Sounds fair enough. All actions performed in M1 environment:<br \/>\n[crayon lang=&#8220;shell&#8220;]<br \/>\nMariaDB [sakila]> show master status;<br \/>\n+\u2014\u2014\u2014\u2014\u2014\u2014+\u2014\u2014\u2014-+\u2014\u2014\u2014\u2014\u2013+\u2014\u2014\u2014\u2014\u2014\u2014+<br \/>\n| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |<br \/>\n+\u2014\u2014\u2014\u2014\u2014\u2014+\u2014\u2014\u2014-+\u2014\u2014\u2014\u2014\u2013+\u2014\u2014\u2014\u2014\u2014\u2014+<br \/>\n| mysql-bin.000004 |      326 |              |                  |<br \/>\n+\u2014\u2014\u2014\u2014\u2014\u2014+\u2014\u2014\u2014-+\u2014\u2014\u2014\u2014\u2013+\u2014\u2014\u2014\u2014\u2014\u2014+<br \/>\n1 row in set (0.00 sec)<\/p>\n<p>MariaDB [sakila]> flush tables with read lock;<br \/>\nQuery OK, 0 rows affected (0.00 sec)<\/p>\n<p>[j@manjaro001 ~]$ mysqldump -u root -p sakila > ~\/sakila.sql<br \/>\nEnter password:<br \/>\n[j@manjaro001 ~]$ ll *sql<br \/>\n-rw-r\u2013r\u2013 1 j users 3350638 15.11.2014 10:12 sakila.sql<br \/>\n[j@manjaro001 ~]$<br \/>\n[\/crayon]<br \/>\nSmall explanation &#8211; first command is saying that 4th binary log file, 326th position is having the last transaction in sakila database. Followed by next locking command we are ensured that data will be consistent and continuing (dump + binary log). This number + file name will be used at the end of setting.<\/p>\n<p>Mysqldump command is well documented.<\/p>\n<p>There are a lot of ways how this sql server is transfered to M2 machine such as scp, ftp, etc.<\/p>\n<p>Following actions are done in M2 environment:<br \/>\n[crayon lang=&#8220;shell&#8220;]<br \/>\n[j@manjaro002 ~]$ mysqladmin -u root -p create sakila<br \/>\nEnter password:<br \/>\n[j@manjaro002 ~]$ time pv sakila.sql | mysql -u root -p sakila<br \/>\nEnter password:<br \/>\n3.2MiB 0:00:09 [ 349KiB\/s] [====================================================>] 100%<\/p>\n<p>real    0m10.030s<br \/>\nuser    0m0.053s<br \/>\nsys    0m0.020s<br \/>\n[j@manjaro002 ~]$<br \/>\n[\/crayon]<\/p>\n<p>Ok now we have same data on M1 and M2. In next part we will&#8230;.<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"text-decoration: underline;\">2.2 Setup mysql internal permissions<br \/>\n<\/span><\/p>\n<p>Now we create user named &#8222;replication&#8220; with &#8222;eagle&#8220; password. Please beware while writing ip address &#8211; M1 is linked to M2 account and reversed.<\/p>\n<p>M1 command:<br \/>\n[crayon lang=&#8220;shell&#8220;]<br \/>\nMariaDB [mysql]> GRANT REPLICATION SLAVE ON *.* TO &#8218;replication&#8217;@&#8217;192.168.56.102&#8216; IDENTIFIED BY &#8218;eagle&#8216;;<br \/>\nQuery OK, 0 rows affected (0.00 sec)<br \/>\n[\/crayon]<\/p>\n<p>M2 command:<br \/>\n[crayon lang=&#8220;shell&#8220;]<br \/>\nMariaDB [mysql]> GRANT REPLICATION SLAVE ON *.* TO &#8218;replication&#8217;@&#8217;192.168.56.101&#8216; IDENTIFIED BY &#8218;eagle&#8216;;<br \/>\nQuery OK, 0 rows affected (0.00 sec)<br \/>\n[\/crayon]<br \/>\n&nbsp;<\/p>\n<p><span style=\"color: #ff6600;\"><strong>3) Run, Forrest, run!<\/strong><\/span><\/p>\n<p><span style=\"text-decoration: underline;\">3.1 M1(Master)-&gt;M2(Slave) setup<\/span><\/p>\n<p>Ok, now we need to tell M2 to behave as slave for M1. So in M2 environment run:<br \/>\n[crayon lang=&#8220;shell&#8220;]<br \/>\nMariaDB [mysql]> CHANGE MASTER TO master_host=&#8217;192.168.56.101&#8242;, master_port=3306, master_user=&#8217;replication&#8216;, master_password=&#8217;eagle&#8216;, master_log_file=&#8217;mysql-bin.000004&#8242;, master_log_pos=326;<br \/>\nQuery OK, 0 rows affected (0.26 sec)<br \/>\n[\/crayon]<br \/>\nOk, setup is done, we can start slave:<br \/>\n[crayon lang=&#8220;shell&#8220;]<br \/>\nMariaDB [mysql]> start slave;<br \/>\nQuery OK, 0 rows affected (0.11 sec)<br \/>\n[\/crayon]<br \/>\nAnd check its status:<br \/>\n[crayon lang=&#8220;shell&#8220;]<br \/>\nMariaDB [mysql]> show slave status\\G<br \/>\n*************************** 1. row ***************************<br \/>\n               Slave_IO_State: Waiting for master to send event<br \/>\n                  Master_Host: 192.168.56.101<br \/>\n                  Master_User: replication<br \/>\n                  Master_Port: 3306<br \/>\n                Connect_Retry: 60<br \/>\n              Master_Log_File: mysql-bin.000004<br \/>\n          Read_Master_Log_Pos: 535<br \/>\n               Relay_Log_File: mysql-relay-bin.000002<br \/>\n                Relay_Log_Pos: 744<br \/>\n        Relay_Master_Log_File: mysql-bin.000004<br \/>\n             Slave_IO_Running: Yes<br \/>\n            Slave_SQL_Running: Yes<br \/>\n              Replicate_Do_DB:<br \/>\n          Replicate_Ignore_DB:<br \/>\n           Replicate_Do_Table:<br \/>\n       Replicate_Ignore_Table:<br \/>\n      Replicate_Wild_Do_Table:<br \/>\n  Replicate_Wild_Ignore_Table:<br \/>\n                   Last_Errno: 0<br \/>\n                   Last_Error:<br \/>\n                 Skip_Counter: 0<br \/>\n          Exec_Master_Log_Pos: 535<br \/>\n              Relay_Log_Space: 1041<br \/>\n              Until_Condition: None<br \/>\n               Until_Log_File:<br \/>\n                Until_Log_Pos: 0<br \/>\n           Master_SSL_Allowed: No<br \/>\n           Master_SSL_CA_File:<br \/>\n           Master_SSL_CA_Path:<br \/>\n              Master_SSL_Cert:<br \/>\n            Master_SSL_Cipher:<br \/>\n               Master_SSL_Key:<br \/>\n        Seconds_Behind_Master: 0<br \/>\nMaster_SSL_Verify_Server_Cert: No<br \/>\n                Last_IO_Errno: 0<br \/>\n                Last_IO_Error:<br \/>\n               Last_SQL_Errno: 0<br \/>\n               Last_SQL_Error:<br \/>\n  Replicate_Ignore_Server_Ids:<br \/>\n             Master_Server_Id: 1<br \/>\n               Master_SSL_Crl:<br \/>\n           Master_SSL_Crlpath:<br \/>\n                   Using_Gtid: No<br \/>\n                  Gtid_IO_Pos:<br \/>\n1 row in set (0.00 sec)<br \/>\n[\/crayon]<\/p>\n<p>As you can see from the first line, slave is waiting for master actions = now we can check master status on M2 to check log position (for finishing crossing and having 2 masters):<br \/>\n[crayon lang=&#8220;shell&#8220;]<br \/>\nMariaDB [mysql]> show master status;<br \/>\n+\u2014\u2014\u2014\u2014\u2014\u2014+\u2014\u2014\u2014-+\u2014\u2014\u2014\u2014\u2013+\u2014\u2014\u2014\u2014\u2014\u2014+<br \/>\n| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |<br \/>\n+\u2014\u2014\u2014\u2014\u2014\u2014+\u2014\u2014\u2014-+\u2014\u2014\u2014\u2014\u2013+\u2014\u2014\u2014\u2014\u2014\u2014+<br \/>\n| mysql-bin.000005 |  3349558 |              |                  |<br \/>\n+\u2014\u2014\u2014\u2014\u2014\u2014+\u2014\u2014\u2014-+\u2014\u2014\u2014\u2014\u2013+\u2014\u2014\u2014\u2014\u2014\u2014+<br \/>\n1 row in set (0.00 sec)<br \/>\n[\/crayon]<br \/>\n&nbsp;<\/p>\n<p><span style=\"text-decoration: underline;\">3.2 M2(Master)-&gt;M1(Slave) setup<\/span><\/p>\n<p>Ok, now we need to tell M1 to behave as slave for M2. So in M1 environment run:<br \/>\n[crayon lang=&#8220;shell&#8220;]<br \/>\nMariaDB [mysql]> CHANGE MASTER TO master_host=&#8217;192.168.56.102&#8242;, master_port=3306, master_user=&#8217;replication&#8216;, master_password=&#8217;eagle&#8216;, master_log_file=&#8217;mysql-bin.000005&#8242;, master_log_pos=3349558;<br \/>\nQuery OK, 0 rows affected (0.26 sec)<br \/>\n[\/crayon]<br \/>\nOk, setup is done, we can start slave:<br \/>\n[crayon lang=&#8220;shell&#8220;]<br \/>\nMariaDB [mysql]> start slave;<br \/>\nQuery OK, 0 rows affected (0.08 sec)<\/p>\n<p>MariaDB [mysql]> show slave status\\G<br \/>\n*************************** 1. row ***************************<br \/>\n               Slave_IO_State: Waiting for master to send event<br \/>\n                  Master_Host: 192.168.56.102<br \/>\n                  Master_User: replication<br \/>\n                  Master_Port: 3306<br \/>\n                Connect_Retry: 60<br \/>\n              Master_Log_File: mysql-bin.000005<br \/>\n          Read_Master_Log_Pos: 3349558<br \/>\n               Relay_Log_File: mysql-relay-bin.000002<br \/>\n                Relay_Log_Pos: 535<br \/>\n        Relay_Master_Log_File: mysql-bin.000005<br \/>\n             Slave_IO_Running: Yes<br \/>\n            Slave_SQL_Running: Yes<br \/>\n              Replicate_Do_DB:<br \/>\n          Replicate_Ignore_DB:<br \/>\n           Replicate_Do_Table:<br \/>\n       Replicate_Ignore_Table:<br \/>\n      Replicate_Wild_Do_Table:<br \/>\n  Replicate_Wild_Ignore_Table:<br \/>\n                   Last_Errno: 0<br \/>\n                   Last_Error:<br \/>\n                 Skip_Counter: 0<br \/>\n          Exec_Master_Log_Pos: 3349558<br \/>\n              Relay_Log_Space: 832<br \/>\n              Until_Condition: None<br \/>\n               Until_Log_File:<br \/>\n                Until_Log_Pos: 0<br \/>\n           Master_SSL_Allowed: No<br \/>\n           Master_SSL_CA_File:<br \/>\n           Master_SSL_CA_Path:<br \/>\n              Master_SSL_Cert:<br \/>\n            Master_SSL_Cipher:<br \/>\n               Master_SSL_Key:<br \/>\n        Seconds_Behind_Master: 0<br \/>\nMaster_SSL_Verify_Server_Cert: No<br \/>\n                Last_IO_Errno: 0<br \/>\n                Last_IO_Error:<br \/>\n               Last_SQL_Errno: 0<br \/>\n               Last_SQL_Error:<br \/>\n  Replicate_Ignore_Server_Ids:<br \/>\n             Master_Server_Id: 2<br \/>\n               Master_SSL_Crl:<br \/>\n           Master_SSL_Crlpath:<br \/>\n                   Using_Gtid: No<br \/>\n                  Gtid_IO_Pos:<br \/>\n1 row in set (0.00 sec)<\/p>\n<p>MariaDB [mysql]><br \/>\n[\/crayon]<\/p>\n<p>Replication setup is done. Now we can verify our environment.<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #ff6600;\"><strong>4) Verification<\/strong><\/span><\/p>\n<p>We can reuse sakila code on M2:<br \/>\n[crayon lang=&#8220;shell&#8220;]<br \/>\n[j@manjaro002 ~]$ mysqladmin -u root -p create sakila2<br \/>\nEnter password:<br \/>\n[j@manjaro002 ~]$ pv sakila.sql | mysql -u root -p sakila2<br \/>\nEnter password:<br \/>\n 3.2MiB 0:00:13 [ 240KiB\/s] [====================>] 100%<br \/>\n[j@manjaro002 ~]$<br \/>\n[\/crayon]<br \/>\nAnd now we can query within M1 machine:<br \/>\n[crayon lang=&#8220;shell&#8220;]<br \/>\n[j@manjaro001 ~]$ mysql -u root -p<br \/>\nEnter password:<\/p>\n<p>Welcome to the MariaDB monitor.  Commands end with ; or \\g.<br \/>\nYour MariaDB connection id is 13<br \/>\nServer version: 10.0.15-MariaDB-log MariaDB Server<\/p>\n<p>Copyright (c) 2000, 2014, Oracle, SkySQL Ab and others.<\/p>\n<p>Type \u2018help;\u2019 or \u2018\\h\u2019 for help. Type \u2018\\c\u2019 to clear the current input statement.<\/p>\n<p>MariaDB [(none)]><br \/>\nMariaDB [(none)]><br \/>\nMariaDB [(none)]><br \/>\nMariaDB [(none)]> use sakila2<br \/>\nDatabase changed<br \/>\nMariaDB [sakila2]> show tables<br \/>\n    -> ;<br \/>\n+\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014-+<br \/>\n| Tables_in_sakila2          |<br \/>\n+\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014-+<br \/>\n| actor                      |<br \/>\n| actor_info                 |<br \/>\n| address                    |<br \/>\n| category                   |<br \/>\n| city                       |<br \/>\n| country                    |<br \/>\n| customer                   |<br \/>\n| customer_list              |<br \/>\n| film                       |<br \/>\n| film_actor                 |<br \/>\n| film_category              |<br \/>\n| film_list                  |<br \/>\n| film_text                  |<br \/>\n| inventory                  |<br \/>\n| language                   |<br \/>\n| nicer_but_slower_film_list |<br \/>\n| payment                    |<br \/>\n| rental                     |<br \/>\n| sales_by_film_category     |<br \/>\n| sales_by_store             |<br \/>\n| staff                      |<br \/>\n| staff_list                 |<br \/>\n| store                      |<br \/>\n+\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014-+<br \/>\n23 rows in set (0.00 sec)<\/p>\n<p>MariaDB [sakila2]><br \/>\n[\/crayon]<\/p>\n<p>You can verify that it\u00b4s working also other way = you can drop database sakila2 from M1:<br \/>\n[crayon lang=&#8220;shell&#8220;]<br \/>\nMariaDB [mysql]> drop database sakila2;<br \/>\nQuery OK, 23 rows affected (1.40 sec)<br \/>\n[\/crayon]<br \/>\nAnd now on M2 you can verify that connection is working:<br \/>\n[crayon lang=&#8220;shell&#8220;]<br \/>\n[j@manjaro002 ~]$ mysql -u root -p<br \/>\nEnter password:<br \/>\nWelcome to the MariaDB monitor.  Commands end with ; or \\g.<br \/>\nYour MariaDB connection id is 11<br \/>\nServer version: 10.0.15-MariaDB-log MariaDB Server<\/p>\n<p>Copyright (c) 2000, 2014, Oracle, SkySQL Ab and others.<\/p>\n<p>Type \u2018help;\u2019 or \u2018\\h\u2019 for help. Type \u2018\\c\u2019 to clear the current input statement.<\/p>\n<p>MariaDB [(none)]><br \/>\nMariaDB [(none)]><br \/>\nMariaDB [(none)]> use sakila2<br \/>\nERROR 1049 (42000): Unknown database \u2018sakila2\u2032<br \/>\nMariaDB [(none)]><br \/>\n[\/crayon]<br \/>\nAnd that\u00b4s all. I can recommend <a href=\"http:\/\/shop.oreilly.com\/product\/0636920026907.do\">MySQL High Availability book<\/a>, full of descripiton, recipes and very valuable information.<\/p>\n<p>-a-<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sometimes it&#8217;s very useful to skip well-known master-slave replication scenario and focus on master-master possibility \ud83d\ude42<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[13],"tags":[],"_links":{"self":[{"href":"http:\/\/it.tuxie.eu\/index.php?rest_route=\/wp\/v2\/posts\/722"}],"collection":[{"href":"http:\/\/it.tuxie.eu\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/it.tuxie.eu\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/it.tuxie.eu\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/it.tuxie.eu\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=722"}],"version-history":[{"count":0,"href":"http:\/\/it.tuxie.eu\/index.php?rest_route=\/wp\/v2\/posts\/722\/revisions"}],"wp:attachment":[{"href":"http:\/\/it.tuxie.eu\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=722"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/it.tuxie.eu\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=722"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/it.tuxie.eu\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=722"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}