MySQL複製主要是把寫操作發送給主節點、讀操作發送給從節點,每個節點都有相關的數據集;從服務專門啓動一個線程,把自己扮演成爲客戶端,通過MySQL協議向MySQL主節點請求讀取二進制日誌文件中的事件,隨後主節點將會檢查自己二進制日誌中的事件併發送給從節點,從節點收到後先保存在自己的中繼日誌中,每讀取到一個事件都會在中繼中保存下來
複製中用到的線程名稱:
從節點:
I/O Thread:從主節點請求二進制事件,並保存於中繼日誌中
SQL Thread:從中繼日誌中讀取二進制日誌事件,在本地完成重放
主節點:
dump Thread:爲每個從節點的I/O Thread啓動一個dump Thread,用於向其發送二進制日誌事件
複製的功用:
1、實現數據分佈的目的
2、主要能夠完成寫操作的負載均衡效果
3、能夠實現備份的效果(當主服務器掛了,備節點可以當主節點)
4、可以實現高可用和故障切換
5、可以在從節點上爲Mysql做升級測試
MySQL複製的方式:主從複製、主主複製、半同步複製、過濾複製、SSL複製
一、實現主從複製:
準備環境
虛擬機1:Master節點(主節點) | IP:192.168.1.108 |
虛擬機2:Slave節點(從節點) | IP:192.168.1.109 |
1、部署Master節點
(1)、安裝mariadb服務
[root@node0 ~]# yum install mariadb-server -y
(2)編輯其配置文件
[root@node0 ~]# vim /etc/my.cnf ##mariadb配置文件路徑 [mysqld] log_bin=mysql-bin ##開啓二進制日誌功能 server-id=1 ##定義唯一Server-id innodb_file_per_table = ON skip_name_resolve = ON ##禁止反解主機名 [root@node0 ~]# systemctl start mariadb.service ##啓動mariadb服務 MariaDB [(none)]> show global variables like "server_id"; ##查看其server-id server_id 1 MariaDB [(none)]> show global variables like "log_bin"; ##查看其二進制日誌是否開啓 log_bin ON MariaDB [(none)]> show master status; ##查看正在使用的二進制日誌文件 mysql-bin.000002 245 | MariaDB [(none)]> grant replication slave,replication client on *.* to 'repluser'@'192.168.%.%' identified by 'replpass'; ##創建具有複製權限的用戶 MariaDB [(none)]> flush privileges;
2、部署Slave節點
(1)安裝mariadb服務
[root@node1 ~]# yum install mariadb-server -y
(2)編輯其配置文件
[root@node1 ~]# vim /etc/my.cnf [mysqld] relay-log=relay-log ##啓用中繼日誌 server-id=2 ##定義唯一Server-id;此Server-id一定不能和Master的上的Server-id相同 innodb_file_per_table = ON skip_name_resolve = ON [root@node1 ~]# systemctl start mariadb.service MariaDB [(none)]> show global variables like "relay_log"; ##查看中繼日誌是否啓用 relay_log relay-log MariaDB [(none)]> show global variables like "server_id"; ##查看其server-i server_id 2
(3)使用具有複製權限的用戶賬號連接至主服務器上,並啓動複製線程
MariaDB [(none)]> change master to master_host='192.168.1.108',master_user='repluser',master_password='replpass',master_log_file='mysql-bin.000002',master_log_pos=245; ## master_host:指明主節點的IP地址 ## master_user、master_password:指明具有複製權限的用戶賬號 ## master_log_file:指明主節點正在使用的二進制日誌; ## master_log_pos:指明二進制日誌的position MariaDB [(none)]> start slave; ##啓動複製線程 MariaDB [(none)]> show slave status\G; ##查看複製線程的狀態信息 Slave_IO_Running: Yes Slave_SQL_Running: Yes
3、測試主從服務器是否實現複製功能
(1)在Master節點上查看一次數據庫
MariaDB [(none)]> show databases; +--------------------+ | Database +--------------------+ | information_schema | lweim | mysql | performance_schema | test +--------------------+
(2)在Slave上查看一次數據庫
MariaDB [(none)]> show databases; +--------------------+ | Database +--------------------+ | information_schema | mysql | performance_schema | testdb +--------------------+
(3)在Master節點上創建一個名爲“MaGeRepo”的數據庫,並在Slave節點上查看
MariaDB [(none)]> create database MaGeRepo; ##在主節點上創建數據庫“MaGeRepo” Query OK, 1 row affected (0.00 sec) MariaDB [(none)]> show databases; ##在從節點上查看數據庫 +--------------------+ | Database +--------------------+ | information_schema | MaGeRepo | mysql | performance_schema | testdb +--------------------
在主從複製架構中應該注意的問題:
1、在Master節點上的參數
sync_binlog=ON sync_master_info=ON 如果用的是InnoDB存儲引擎,以下兩項也要開啓 innodb_flush_log_at_tx_commit = ON ##刷寫日誌 innodb_support_xa = ON ##是否讓innodb支持分佈式事務
2、在Slave節點上的參數
skip_slave_start = OFF ##是否自動啓動事務線程 sync_relay_log = ON sync_relay_log_info = ON
二、實現主主複製
準備環境
虛擬機1:Master節點(主節點) | IP:192.168.1.108 |
虛擬機2:Master節點(主節點) | IP:192.168.1.109 |
1、部署虛擬機1
(1)安裝mariadb服務
[root@node0 ~]# yum install mariadb-server -y
(2)編輯其配置文件
[root@node0 ~]# vim /etc/my.cnf log_bin=mysql-bin relay-log=relay-log ##啓用中繼日誌 server-id=1 innodb_file_per_table = ON [root@node0 ~]# systemctl start mariadb.service MariaDB [(none)]> show global variables like "%log%"; relay_log relay-log log_bin ON MariaDB [(none)]> show master status; mysql-bin.000003 245 MariaDB [(none)]> grant replication slave,replication client on *.* to 'repluser'@'192.168.%.%' identified by 'replpass';
2、部署虛擬機2
(1)安裝mariadb服務
[root@node1 ~]# yum install mariadb-server -y
(2)編輯配置文件
[root@node1 ~]# vim /etc/my.cnf [mysqld] relay-log=relay-log log_bin=mysql-bin ##啓用二進制日誌 server-id=2 innodb_file_per_table = ON skip_name_resolve = ON [root@node1 ~]# systemctl start mariadb.service MariaDB [(none)]> show master status; mysql-bin.000003 245 MariaDB [(none)]> grant replication slave,replication client on *.* to 'repluser'@'192.168.%.%' identified by 'replpass'; ##創建具有複製權限的用戶賬號
3、兩個節點分別使用雙方創建的用戶連到對方的服務器上,並啓動複製線程
(1)讓虛擬機1連接至虛擬機2
MariaDB [(none)]> change master to master_host='192.168.1.109',master_user='repluser',master_password='replpass',master_log_file='mysql-bin.000003',master_log_pos=245; MariaDB [(none)]> flush privileges; MariaDB [(none)]> start slave;
(2)讓虛擬機2連接至虛擬機1
MariaDB [(none)]> change master to master_host='192.168.1.108',master_user='repluser',master_password='replpass',master_log_file='mysql-bin.000003',master_log_pos=245; MariaDB [(none)]> flush privileges; MariaDB [(none)]> start slave;
4、測試主主複製模型
(1)在分別查看虛擬機1和虛擬機2的數據庫
MariaDB [(none)]> show databases; ##查看虛擬機1的數據庫 +-------------------- | Database +--------------------+ | information_schema | mysql | performance_schema | test +--------------------+ MariaDB [(none)]> show databases; ##查看虛擬機2的數據庫 +--------------------+ | Database +--------------------+ | information_schema | mysql | performance_schema | testdb +--------------------+
(2)在虛擬機1上添加“LweimRepo"數據庫,在虛擬機2上添加“WzxRepo”數據庫
MariaDB [(none)]> create database LweimRepo; ##虛擬機1 Query OK, 1 row affected (0.00 sec) MariaDB [(none)]> flush privileges; MariaDB [(none)]> create database WzxRepo; ##虛擬機2 Query OK, 1 row affected (0.00 sec) MariaDB [(none)]> flush privileges;
(3)再次查看兩個節點的數據庫
MariaDB [(none)]> show databases; ##查看虛擬機1 +--------------------+ | Database +--------------------+ | information_schema | LweimRepo | WzxRepo | mysql | performance_schema | test +--------------------+ MariaDB [(none)]> show databases; ##查看虛擬機2 +--------------------+ | Database +--------------------+ | information_schema | LweimRepo | WzxRepo | mysql | performance_schema | testdb +--------------------+
三、實現半同步複製:當master節點有多個slave節點時,只需要有一個slave節點複製完成之後並響應給master節點,隨後master節點響應客戶端
準備環境
虛擬機1:Master節點(主節點) | IP:192.168.1.108 |
虛擬機2:Slave節點(從節點) | IP:192.168.1.109 |
1、給master節點安裝插件“semisync_master.so”
MariaDB [(none)]> install plugin rpl_semi_sync_master soname 'semisync_master.so'; MariaDB [(none)]> show global variables like "%semi%"; +------------------------------------+-------+ | Variable_name Value +------------------------------------+-------+ | rpl_semi_sync_master_enabled OFF ##是否啓用半同步複製的主節點,需把它設置爲ON | rpl_semi_sync_master_timeout 10000 ##等待slave的響應時長,單位爲毫秒,默認爲10s | rpl_semi_sync_master_trace_level 32 ##跟蹤節點32,默認值就好,不建議更改 | rpl_semi_sync_master_wait_no_slave ON ##當沒有slave節點時是否等待 +------------------------------------+-------+ MariaDB [(none)]> set global rpl_semi_sync_master_enabled=1; ##“rpl_semi_sync_master_enabled”更改爲“ON”
2、在Slave節點上安裝“semisync_slave.so”
MariaDB [(none)]> install plugin rpl_semi_sync_slave soname 'semisync_slave.so'; MariaDB [(none)]> set global rpl_semi_sync_slave_enabled=1; ##啓用半同步複製的slave節點 MariaDB [(none)]> show global variables like "%semi%"; +---------------------------------+-------+ | Variable_name Value +---------------------------------+-------+ | rpl_semi_sync_slave_enabled ON ##是否啓用半同步複製的slav節點 | rpl_semi_sync_slave_trace_level 32 +---------------------------------+-------+
3、實現主從複製
4、在Master節點上查看是否增加slave節點
MariaDB [(none)]> show global status like "%semi%"; +--------------------------------------------+-------+ | Variable_name Value +--------------------------------------------+-------+ | Rpl_semi_sync_master_clients 1 ##已經連接Slave節點的個數 | Rpl_semi_sync_master_net_avg_wait_time 0 | Rpl_semi_sync_master_net_wait_time 0 | Rpl_semi_sync_master_net_waits 0 | Rpl_semi_sync_master_no_times 1 | Rpl_semi_sync_master_no_tx 2 | Rpl_semi_sync_master_status ON | Rpl_semi_sync_master_timefunc_failures 0 | Rpl_semi_sync_master_tx_avg_wait_time 0 | Rpl_semi_sync_master_tx_wait_time 0 | Rpl_semi_sync_master_tx_waits 0 | Rpl_semi_sync_master_wait_pos_backtraverse 0 | Rpl_semi_sync_master_wait_sessions 0 | Rpl_semi_sync_master_yes_tx 0 +--------------------------------------------+--- ----
5、在Master節點上創建數據庫“GunDuZi,並在Slave節點上查看
MariaDB [(none)]> create database GunDuZi; MariaDB [(none)]> show global status like "%semi%"; +--------------------------------------------+-------+ | Variable_name Value +--------------------------------------------+-------+ | Rpl_semi_sync_master_clients 1 | Rpl_semi_sync_master_net_avg_wait_time 8147 | Rpl_semi_sync_master_net_wait_time 8147 | Rpl_semi_sync_master_net_waits 1 | Rpl_semi_sync_master_no_times 1 | Rpl_semi_sync_master_no_tx 2 | Rpl_semi_sync_master_status ON | Rpl_semi_sync_master_timefunc_failures 0 | Rpl_semi_sync_master_tx_avg_wait_time 9388 | Rpl_semi_sync_master_tx_wait_time 9388 | Rpl_semi_sync_master_tx_waits 1 | Rpl_semi_sync_master_wait_pos_backtraverse 0 | Rpl_semi_sync_master_wait_sessions 0 | Rpl_semi_sync_master_yes_tx 1 +--------------------------------------------+------- MariaDB [(none)]> show databases; +--------------------+ | Database +--------------------+ | information_schema | GunDuZi | mysql | performance_schema | test +--------------------+ ##注意:一定要先安裝插件,在實現主從複製
四、實現過濾複製:讓從節點指定複製數據庫或複製數據庫中指定的表
準備環境
虛擬機1:Master節點(主節點) | IP:192.168.1.108 |
虛擬機2:Slave節點(從節點) | IP:192.168.1.109 |
1、實現主從複製
2、指定Slave節點需要複製的數據庫爲“wtcdb”
MariaDB [wxpp]> set global replicate_do_db=wtcdb; MariaDB [wxpp]> show global variables like "replicate%"; +----------------------------------+-----------+ | Variable_name Value +----------------------------------+-----------+ | replicate_annotate_row_events OFF | replicate_do_db wtcdb ##僅複製那些數據庫 | replicate_do_table ##僅複製那些數據庫中的表 | replicate_events_marked_for_skip replicate | replicate_ignore_db ##忽略的數據庫(不復制的數據庫) | replicate_ignore_table ##忽略的表(不復制的表) | replicate_wild_do_table ##可以使用通配符來指定需要複製的數據庫 | replicate_wild_ignore_table +----------------------------------+-----------+
3、查看Slave節點上的數據庫
MariaDB [(none)]> show databases; +--------------------+ | Database +--------------------+ | information_schema | mysql | performance_schema | test | wxpp +--------------------+
4、在Master節點上創建“lweimdb”、“wzxdb”、“wtcdb”三個數據庫
MariaDB [(none)]> create database lweimdb; Query OK, 1 row affected (0.01 sec) MariaDB [(none)]> create database wzxdb; Query OK, 1 row affected (0.00 sec) MariaDB [(none)]> create database wtcdb; Query OK, 1 row affected (0.00 sec) MariaDB [(none)]> flush privileges; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]> show databases; +--------------------+ | Database +--------------------+ | information_schema | lweimdb | mysql | performance_schema | test | wtcdb | wxpp | wzxdb +--------------------+
5、再一次查看Slave節點上的數據庫,是否只複製了“wtcdb”數據庫
MariaDB [(none)]> show databases; +--------------------+ | Database +--------------------+ | information_schema | mysql | performance_schema | test | wtcdb | wxpp +--------------------+
五、實現SSL複製
準備環境
虛擬機1:Master節點(主節點) | IP:192.168.1.108 |
虛擬機2:Slave節點(從節點) | IP:192.168.1.109 |
虛擬機3:CA機構(簽署主從節點證書) | IP:192.168.1.110 |
1、部署虛擬機3
(1)創建CA證書祕鑰
[root@localhost CA]# (umask 077;openssl genrsa -out ./private/cakey.pem 1024)
(2)讓CA自簽證書
[root@localhost CA]# openssl req -new -x509 -key ./private/cakey.pem -out cacert.pem -days 365 [root@localhost CA]# touch serial index.txt ##創建所需要的文件 [root@localhost CA]# echo 01 > serial ##生成證書序列號
2、Master節點創建證書,並讓CA機構簽署
[root@node0 ssl]# (umask 077; openssl genrsa -out master.key 1024) ##Master節點生成祕鑰 [root@node0 ssl]# openssl req -new -key master.key -out master.csr -days 365 ##生成需要簽署的證書 [root@localhost CA]# openssl ca -in /tmp/master.csr -out master.crt -days 365 ##讓CA簽署證書 [root@node0 ssl]# chmod 600 * ##更改權限爲600 [root@node0 ssl]# chown mysql.mysql -R ssl/* ##更改文件屬主屬組爲mysql [root@node0 ssl]# ll total 12 -rw------- 1 mysql mysql 1046 Jun 9 20:49 cacert.pem -rw------- 1 mysql mysql 3202 Jun 9 20:43 master.crt -rw------- 1 mysql mysql 887 Jun 9 20:35 master.key
3、配置Master節點的配置文件,並創建具有複製權限的用戶
[root@node0 ~]# vim /etc/my.cnf ssl ##開啓sll功能 ssl_ca=/var/lib/mysql/ssl/cacert.pem ##指明CA機構證書路徑 ssl_cert=/var/lib/mysql/ssl/master.crt ##指明Master節點的證書路徑 ssl_key=/var/lib/mysql/ssl/master.key ##指明Master節點的祕鑰路徑 [root@node0 ~]# systemctl start mariadb.service MariaDB [(none)]> show global variables like "%ssl%"; ##查看是否啓用ssl +---------------+-------------------------------+ | Variable_name | Value +---------------+-------------------------------+ | have_openssl | YES | have_ssl | YES | ssl_ca | /var/lib/mysql/ssl/cacert.pem | ssl_capath | ssl_cert | /var/lib/mysql/ssl/master.crt | ssl_cipher | ssl_key | /var/lib/mysql/ssl/master.key +---------------+-------------------------------+ MariaDB [(none)]> grant replication slave,replication client on *.* to 'repluser'@'192.168.%.%' identified by 'replpass' require ssl;
4、將Master節點上的證書發送給Slave,修改其配置文件,連接至Master節點並啓動複製線程
[root@node0 ~]# scp ssl/* [email protected]:/var/lib/mysql/ ##要確保發送的文件屬組屬主爲“mysql” [email protected]'s password: cacert.pem 100% 1046 1.0KB/s 00:00 master.crt 100% 3206 3.1KB/s 00:00 master.key 100% 887 0.9KB/s 00:00 [root@node1 ~]# vim /etc/my.cnf ssl ssl_ca=/var/lib/mysql/cacert.pem ssl_cert=/var/lib/mysql/master.crt ssl_key=/var/lib/mysql/master.key [root@node1 ~]# systemctl start mariadb.service MariaDB [(none)]> show global variables like '%ssl%'; ##從節點上的SSL的功能已經開啓 +---------------+---------------------------+ | Variable_name | Value +---------------+---------------------------+ | have_openssl | YES | have_ssl | YES | ssl_ca | /var/lib/mysql/cacert.pem | ssl_capath | | ssl_cert | /var/lib/mysql/master.crt | ssl_cipher | | ssl_key | /var/lib/mysql/master.key +---------------+---------------------------+ MariaDB [(none)]> change master to master_host='192.168.1.108',master_user='repluser',master_password='replpass',master_log_file='mysql-bin.000003',master_log_pos=245,master_ssl=1,master_ssl_ca='/var/lib/mysql/cacert.pem',master_ssl_cert='/var/lib/mysql/master.crt',master_ssl_key='/var/lib/mysql/master.key'; ## master_ssl:啓用ssl功能 ## master_ssl_ca:指明CA證書路徑 ## master_ssl_cert:指明Master節點證書路徑 ## master_ssl_key:指明Master節點祕鑰路徑 MariaDB [(none)]> start slave; ##啓動複製線程 MariaDB [(none)]> show slave status\G; ##查看複製線程相關信息 Slave_IO_Running: Yes Slave_SQL_Running: Yes Master_SSL_Allowed: Yes ##要確保這三項都爲“YES” Master_SSL_CA_File: /var/lib/mysql/cacert.pem Master_SSL_Cert: /var/lib/mysql/master.crt Master_SSL_Key: /var/lib/mysql/master.key
5、分別查看Master節點和Slave節點上的數據庫
MariaDB [(none)]> show databases; ##查看Master節點 +--------------------+ | Database +--------------------+ | information_schema | mysql | performance_schema | ssl | test +--------------------+ MariaDB [(none)]> show databases; ##查看Slave節點 +--------------------+ | Database +--------------------+ | information_schema | mysql | performance_schema | test +--------------------+
6、在Master節點上創建"LweimRepo”、“HjRepo”、“WzxRepo”,隨後再到Slave節點上查看
MariaDB [(none)]> create database LweimRepo; Query OK, 1 row affected (0.00 sec) MariaDB [(none)]> create database HjRepo; Query OK, 1 row affected (0.00 sec) MariaDB [(none)]> create database WzxRepo; Query OK, 1 row affected (0.04 sec) MariaDB [(none)]> show databases; ##在Slave節點上查看 +--------------------+ | Database +--------------------+ | information_schema | HjRepo | LweimRepo | WzxRepo | mysql | performance_schema | test +--------------------+
問題小結:
1、當Slave節點連接至Master節點時,一定要指明Master節點當前使用的二進制日誌以及pos
2、在使用SSL複製時,要確保祕鑰、證書文件的權限以及屬主屬組
3、當生成證書時,三臺虛擬機的國家、省份、公司名稱必須要一樣