mysql半主從複製
在聊主從半同步前我們先聊一下mysql主從同步的原理
一、mysql的複製原理
至少需要兩個節點,一主(master)一從(slave)
那麼從節點如何從主節點獲得數據呢?
1、主節點開啓二進制日誌,記錄了修改數據的所有語句
2、從節點扮演mysql客戶端請求主節點的二進制日誌,默認是第一個文件的最開始位置,通常要指定二進制文件的指定位置。從節點收到二進制日誌後保存在本地的中繼日誌中,並且會記錄已經讀取到哪個二進制日誌的哪個位置,用作再次請求二進制日誌的起始位置。從節點會讀取中繼日誌中的事件完成重放後從而形成一模一樣的數據保存在數據庫中。
3、slave節點上負責從master節點上請求二進制日誌的線程叫做IO_THREAD,從節點收到二進制日誌後,保存在本地中繼日誌中並由SQL_THREAD做重放後將數據保存在數據庫中。
4、主節點會爲每個請求二進制日誌的從服務器線程IO_THREAD啓動一個響應線程dump_thread,該線程負責讀取主服務器上的二進制日誌併發送給從服務器。
在傳統的mysql主從同步中,當mysql主服務器寫入數據、記入二進制日誌後就直接回復客戶端寫入完成了,是不會等待從服務器寫入後再回復確認給客戶端。換而言之,如果從服務器沒有收到二進制日誌而主服務器宕機,那麼新寫入的數據會來不及同步給從服務器而造成丟失的。因此,比較穩妥的做法是,當主服務器寫入數據後還應該等待至少一臺從服務器也寫入完成後纔回復客戶端寫入完成,也就是說,主、從服務器寫入是同步進行而非異步。多臺從服務器時,通常僅指定一臺從服務器爲同步模式,其餘從服務器爲異步模式——這種mysql主從同步模式成爲mysql主從半同步複製。
實現mysql主從半同步複製模式是由google開發的插件完成的,它們是semisync_master.so和semisync_slave.so,前者工作在mysql主服務器,後者工作在mysql從服務器。這對插件在安裝mariadb-server的rpm包時默認提供。在配置mysql主從時,安裝啓用此插件再啓動slave複製線程即可完成主從半同步複製。
二、mysql半主從複製配置演示
node3: 172.16.92.3/16 mariadb主服務器
node4: 172.16.92.4/16 mariadb從服務器
以上節點均爲CentOS 7.1
配置環境
1. 配置好光盤yum源
2. 關閉selinux和iptables
node3: mariadb主服務器 [root@node3 ~]# yum -y install mariadb-server [root@node3 ~]# vim /etc/my.cnf [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 # Settings user and group are ignored when systemd is used. # If you need to run mysqld under a different user or group, # customize your systemd unit file for mariadb according to the # instructions in http://fedoraproject.org/wiki/Systemd #######以下的內容爲添加######## #二進制變更日誌 log-bin=mysql-bin #二進制日誌格式爲混合模式 binlog_format=mixed #爲主服務器node3的ID值 server-id = 1 port = 3306 skip-external-locking key_buffer_size = 256M max_allowed_packet = 1M table_open_cache = 256 sort_buffer_size = 1M read_buffer_size = 1M read_rnd_buffer_size = 4M myisam_sort_buffer_size = 64M thread_cache_size = 8 query_cache_size= 16M thread_concurrency = 4 innodb_file_per_table = on skip_name_resolve = on ############################### ###### 以下的內容可選 ######## [mysqldump] quick max_allowed_packet = 16M [mysql] no-auto-rehash [myisamchk] key_buffer_size = 128M sort_buffer_size = 128M read_buffer = 2M write_buffer = 2M [mysqlhotcopy] interactive-timeout ############################# [mysqld_safe] log-error=/var/log/mariadb/mariadb.log pid-file=/var/run/mariadb/mariadb.pid # # include all files from the config directory # !includedir /etc/my.cnf.d ############### End for my.cnf ################# [root@node3 ~]# rpm -ql mariadb-server | grep 'semisync' /usr/lib64/mysql/plugin/semisync_master.so #用於Master服務器安裝的半同步插件 /usr/lib64/mysql/plugin/semisync_slave.so #用於Slave服務器安裝的半同步插件 [root@node3 ~]# systemctl start mariadb [root@node3 ~]# mysql MariaDB [(none)]> install plugin rpl_semi_sync_master soname 'semisync_master.so'; #安裝Master半同步插件 MariaDB [(none)]> set global rpl_semi_sync_master_enabled = 1; #開啓Master半同步功能 MariaDB [(none)]> set global rpl_semi_sync_master_timeout = 2000; #超時時間毫秒級 MariaDB [(none)]> grant replication client,replication slave on *.* to 'repluser'@'172.16.92.4' identified by 'replpass'; MariaDB [(none)]> flush privileges; MariaDB [(none)]> show master status\G *************************** 1. row *************************** File: mysql-bin.000003 Position: 497 Binlog_Do_DB: Binlog_Ignore_DB: ##### 記下mysql-bin.000003 和 497 , 設置從服務器中繼日誌時有用 #### node4: mariadb從服務器 [root@node4 ~]# yum -y install mariadb-server [root@node4 ~]# vim /etc/my.cnf [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 # Settings user and group are ignored when systemd is used. # If you need to run mysqld under a different user or group, # customize your systemd unit file for mariadb according to the # instructions in http://fedoraproject.org/wiki/Systemd ########## 添加以下內容 ########## log-bin=mysql-bin binlog_format=mixed server-id = 2 relay-log = relay-bin log_slave_updates = 1 read_only = on port = 3306 skip-external-locking key_buffer_size = 256M max_allowed_packet = 1M table_open_cache = 256 sort_buffer_size = 1M read_buffer_size = 1M read_rnd_buffer_size = 4M myisam_sort_buffer_size = 64M thread_cache_size = 8 query_cache_size= 16M thread_concurrency = 4 innodb_file_per_table = on skip_name_resolve = on ################################### ######### 以下內容可選 ############ [mysqldump] quick max_allowed_packet = 16M [mysql] no-auto-rehash [myisamchk] key_buffer_size = 128M sort_buffer_size = 128M read_buffer = 2M write_buffer = 2M [mysqlhotcopy] interactive-timeout #################################### [mysqld_safe] log-error=/var/log/mariadb/mariadb.log pid-file=/var/run/mariadb/mariadb.pid # # include all files from the config directory # !includedir /etc/my.cnf.d ############# End of my.cnf ############### [root@node4 ~]# systemctl start mariadb [root@node4 ~]# mysql MariaDB [(none)]> show global variables like '%read_only%'\G *************************** 1. row *************************** Variable_name: read_only Value: ON MariaDB [(none)]> change master to master_host='172.16.92.3',master_user='repluser',master_password='replpass',master_log_file='mysql-bin.000003',master_log_pos=497,master_connect_retry=5,master_heartbeat_period=2; MariaDB [(none)]> install plugin rpl_semi_sync_slave soname 'semisync_slave.so'; #安裝Slave半同步插件 MariaDB [(none)]> set global rpl_semi_sync_slave_enabled = 1; #開啓Slave半同步功能 MariaDB [(none)]> start slave; #重啓IO線程生效 MariaDB [(none)]> show slave status\G *************************** 1. row *************************** Slave_IO_Running: Yes Slave_SQL_Running: Yes ........ 其餘信息略 ........ MariaDB [(none)]> show processlist\G *************************** 3. row *************************** State: Slave has read all relay log; waiting for the slave I/O thread to update it ........ 其餘信息略 ........說明: 從節點已經接收到所有的中繼日誌 MariaDB [(none)]> show global status like '%semi%'; | Rpl_semi_sync_slave_status | ON |#半同步狀態已經開啓了; MariaDB [(none)]> show global variables like '%rpl%'; | rpl_semi_sync_slave_enabled | ON |#從服務器節點的半同步已經開啓; node3 主節點上可查看到此進程 MariaDB [(none)]> show processlist\G *************************** 2. row *************************** State: Master has sent all binlog to slave; waiting for binlog to be updated ........ 其餘信息略 ........ MariaDB [(none)]> show global status like 'rpl_semi%'; | Rpl_semi_sync_master_clients | 1 | #可以看出有一個半同步客戶端了; ........ 其餘信息略 ........ 在主節點上創建數據庫測試是否能主從半同步 MariaDB [(none)]> create database testdb; 在從節點上可看到testdb數據庫, 說明主從同步成功! MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | | testdb | +--------------------+ 再來看一下 從節點 的狀態 MariaDB [(none)]> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 172.16.92.3 Master_User: repluser Master_Port: 3306 Connect_Retry: 5 Master_Log_File: mysql-bin.000003 Read_Master_Log_Pos: 584 #497->584 Relay_Log_File: relay-bin.000002 Relay_Log_Pos: 616 #529->616 Relay_Master_Log_File: mysql-bin.000003 Slave_IO_Running: Yes Slave_SQL_Running: Yes ############# mysql半主從複製結束 ##############