Mysql數據庫的主從複製
爲何要進行mysql的主從複製
冗餘:promte(提高爲主),異地災備
擴展:轉移一部分「讀」請求;
支援安全的備份操做;
測試;
...
mysql 的主從複製
主從複製
主:可讀可寫
從:只可度
主從結構
一主多從;
一主一從;
一從多主:每一個主服務器提供不一樣的數據庫;
異步複製:
級聯複製;
循環複製;
雙主複製;
半同步複製;
單個msql的問題分析

若後端mysql數據庫只有一臺時,會有如下問題:
單點故障,服務不可用,沒法處理大量的併發數據請求,數據丟失將形成大災難。
改造辦法:
增長mysql數據庫服務器,對數據進行備份,造成主備。
確保mysql數據庫服務器是同樣的。
主服務器宕機了,備份服務器繼續工做,數據有保障。
mysql主從複製與讀寫分離是密切相關的
主從複製原理

mysql主從複製的類型:
基於語句的複製
基於行的複製
混合類型的複製
過程:
1》mysql從服務器開啓I/O(io_thread)線程,向主服務器請求數據同步(獲取二進制日誌)。
2》mysql主服務器開啓I/O(io_thread)線程迴應從服務器
3》從服務器獲得主的二進制日誌寫入中繼日誌
4》從服務器開啓sql(sql_thread)線程將日誌內容執行,實現數據同步
複製實現
清楚整個過程的全部須要注意的點兒後才能開始複製
1》複製前的配置
時間同步;
複製的開始位置:
從0開始;
從備份中恢復到從節點後啓動的複製的起始點,備份操做時主節點所處的日誌文件及其事件位置;
主從服務器mysqld程序版本不一致?
從服務器的版本號高於主服務器的版本號;
主從複製時應該注意的問題:
查看
select @@global.xxxxx;
設置
set @@global.xxxx={1|0};
一、從服務設定爲「只讀」;
在從服務器啓動read_only,但僅對非super權限的用戶有效;
阻止全部用戶:
mysql> flush tables with read lock;
二、儘可能確保複製時的事務安全,能夠在配置文件中設置
在master節點啓用參數:
sync_binlog = on
表示只要當前節點有事物提交時就當即從內存緩衝區保存到二進制日誌中,避免從服務器複製時二進制日誌中沒有這個提交操做主服務器就壞了,這樣從服務器就不知道這個事物該不應提交了。
若是用到的是innodb存儲引擎:
innodb_flush_logs_at_trx_commit=on
每當事物提交時就同步到事物日誌中
innodb_support_xa=on
讓innodb支持分佈式事物
三、從服務器意外停止時儘可能避免自動啓動複製線程
爲了不這種事情發生,咱們要把網斷掉,查看一下是否有複製到一半的事物,若是有手動刪除,而後手動加change master to 指向意外終止時主服務器二進制日誌的位置,或者從新備份恢復後啓動複製功能。
四、從節點設置參數,可在配置文件中設置
sync_master_info=on
sync_relay_log_info=on
2》主從複製實現
若是主服務器已經運行一段時間了,要想實現主從複製,先對主服務器進行一個徹底備份,而後在從服務器上進行恢復,使二者的數據達到一致後在開啓主從複製功能。
主服務器:
配置文件/etc/my.cnf
server_id=# ##任意數,不要和從相同
log_bin=log-bin
重啓服務
啓動mysql
mysql -uroot -p
mysql> grant replication slave,replication client on *.* to 'username'@'host' identified by 'your_password';
mysql> flush privileges;
mysql>show master status; ##查看正在使用二進制日誌
+----------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+----------------+----------+--------------+------------------+
| log-bin.000001 | 245 | | |
+----------------+----------+--------------+------------------+
從服務器:
配置文件/etc/my.cnf
server_id=# ##任意數,不要和其餘相同
relay_log=relay-log
read_only=on
sync_master_info=on
sync_relay_log_info=on ##這些參數能夠在數據庫中設置不過是暫時的重啓失效而已
重啓服務
啓動mysql
mysql>help change master to ##查看幫助
mysql> change master to master_host='host',master_user='username',master_password='your_password',master_log_file='log-bin.000001',master_log_pos=245;
mysql> start slave io_thread,sql_thread;
mysql> show slave status\G;
MariaDB [(none)]> show status\G; ##如下兩個出現就算主從成功。
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
若主從服務器沒有設置skip_name_resolve= on,則須要保證主機間能夠相互解析主機
主從複製centos6.9的配置及注意事項
vim /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
skip_name_resolve = on
innodb_file_per_table = on
max_connections = 20000 ##以上三行不能寫到server裏,mysql服務啓動不了
[server] ##注意在這裏要加上server這一項否則不會生效
server_id = 1
log_bin = bin-log
relay_log = relay-log
auto_increment_offset = 1
auto_increment_increment = 2
啓動slave時要用mysql> start slave io_thread,sql_thread; 不能簡寫成mysql> start slave,否則開啓不了複製操做
3》主主複製實現:
主主複製實際也是主從複製,區別在於互爲主從而已。
互爲主從的配置要求:
一、server_id必需要使用不一樣值;
二、兩個節點各自都要開啓binlog和relay log;
三、存在自動增加id的表,爲了使得id不相沖突,須要定義其自動增加方式;
定義一個節點使用奇數id
auto_increment_offset=1
auto_increment_increment=2
另外一個節點使用偶數id
auto_increment_offset=2
auto_increment_increment=2
四、服務啓動後執行以下兩步:
1都受權有複製權限的用戶帳號;
2各把對方指定爲主節點;
在A服務器上配置
配置文件my.cnf
[server]
skip_name_resolve = on
innodb_file_per_table = on
max_connections = 20000
log_bin = bin-log ##開啓二級制日誌
relay_log = relay-log ##開啓中繼日誌
server_id = 1
auto_increment_offset = 1 ##表示id號從1開始
auto_increment_increment = 2 ##表示以2爲步進,即爲奇數
登陸服務器
MariaDB [(none)]> select user,password,host from mysql.user; ##查看一下是否有受權的用戶用於主從複製
MariaDB [mydb]>grant replication slave,replication client on *.* to 'username'@'host' identified by 'your_password'; ##若無受權用戶進程主從複製則進行受權
MariaDB [mydb]> change master to master_host='host',master_user='username',master_password='your_password',master_log_file='binlog',master_log_pos=#;
MariaDB [mydb]> start slave;
MariaDB [mydb]> show slave status \G
在B服務器上配置
配置文件my.cnf
[server]
skip_name_resolve = on
innodb_file_per_table = on
max_connections = 20000
server_id = 2
relay_log = relay-log
log_bin = bin-log
auto_increment_offset = 2
auto_increment_increment = 2
登陸服務器
MariaDB [(none)]> select user,password,host from mysql.user; ##查看一下是否有受權的用戶用於主從複製
MariaDB [mydb]>grant replication client,replication slave on *.* to 'username'@'host' identified by 'your_password'; ##若無受權用戶進程主從複製則進行受權
MariaDB [mydb]> change master to master_host='host',master_user='username',master_password='your_password',master_log_file='binlog',master_log_pos=#;
MariaDB [mydb]> start slave;
MariaDB [mydb]> show slave status \G
檢查主從同步,若是您看到Slave_IO_Running和Slave_SQL_Running均爲Yes,則主從複製鏈接正常。
4)基於ssl的複製實現
查看所安裝的數據庫軟件是否支持ssl,默認yum安裝都是不支持的,須要編譯安裝的時候加上ssl功能
MariaDB [(none)]> show global variables like '%ssl%';
+---------------+----------+
| Variable_name | Value |
+---------------+----------+
| have_openssl | DISABLED |
| have_ssl | DISABLED |
| ssl_ca | |
| ssl_capath | |
| ssl_cert | |
| ssl_cipher | |
| ssl_key | |
+---------------+----------+
在主服務器上建立一個用於複製的帳號,要求從服務器使用這個帳號鏈接到主服務器時必須使用ssl鏈接
MariaDB [none]>grant replication client,replication slave on *.* to 'username'@'host' identified by 'your_password' require ssl;
在從服務器上建立證書和私鑰文件
從服務器上使用change master to命令指明本身的ssl相關選項
help change master to查看使用的選項
change master to master_host='host',master_user='username',master_password='your_password',master_log_file='binlog',master_log_pos=#,MASTER_SSL_CERT='/etc/pki/tls/certs/mysql.crt',MASTER_SSL_KEY='/etc/pki/tls/certs/mysql.key';
這裏的,MASTER_SSL_CERT='/etc/pki/tls/certs/mysql.crt',MASTER_SSL_KEY='/etc/pki/tls/certs/mysql.key'; 是從服務器上的證書和私鑰文件路徑
若是從服務器也須要主服務器提供ssl驗證,就須要在主服務器上也建立證書和私鑰文件
將證書和私鑰文件在主服務器的配置文件中指定
通常狀況下主服務器端不須要配置證書和私鑰,由於是從服務器去鏈接主服務器進行復制,因此要求從服務器提供證書和私鑰文件進行認證。
5》半同步複製
半同步複製指當一個主節點有多個從節點時,其中一個或幾個從節點使用同步複製的方式,其餘從節點使用異步複製的方式,稱爲半同步複製。
同步複製時客戶端在訪問mysql數據庫並完成一個寫操做後,從節點會當即將數據同步到本地並將結果反饋給主節點,證實本身已經同步完成,客戶端才能進行第二次寫操做。
若是主節點等待從節點反饋的時間超過了規定的超時時間,這個從節點會自動降級爲異步複製模方式。
支持多種插件:
/usr/lib64/mysql/plugins/
須要安裝纔可以使用:
mysql> install plugin plugin_name soname 'shared_library_name';
半同步複製插件:
semisync_master.so
semisync_slave.so
半同步複製的實現
在主上配置:
MariaDB [(none)]>install plugin rpl_semi_sync_master soname 'semisync_master.so';
MariaDB [(none)]>show global variables like 'rpl_semi%';
+------------------------------------+-------+
| variable_name | value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled | off |
| rpl_semi_sync_master_timeout | 10000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_no_slave | on | ##沒有從節點時是否開啓同步複製
+------------------------------------+-------+
MariaDB [(none)]> set global rpl_semi_sync_master_enabled=on;
MariaDB [(none)]> show global status like 'rpl_semi%';
在從上配置:
MariaDB [(none)]>install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
MariaDB [(none)]> show global variables like 'rpl_semi%';
+---------------------------------+-------+
| variable_name | value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | off |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------+-------+
MariaDB [(none)]> set @@global.rpl_semi_sync_slave_enabled=on;
MariaDB [(none)]> stop slave io_thread;
MariaDB [(none)]> start slave io_thread;
MariaDB [(none)]> show global variables like 'rpl_semi%';
判斷方法:
主節點:
mariadb [mydb]> select @@global.rpl_semi_sync_master_clients;
複製過濾器
僅複製有限一個或幾個數據庫相關的數據,而非全部,由複製過濾器進行;
有兩種實現思路:使用set設置
(1) 主服務器
主服務器僅向二進制日誌中記錄有關特定數據庫相關的寫操做;
問題:其它庫的time-point recovery將無從實現,由於二進制日誌不全,因此對於其餘庫沒法進行重放二級制日誌,通常這種方法不會使用。
binlog_do_db=
binlog_ignore_db=
(2) 從服務器
從服務器的sql thread僅重放關注的數據庫或表相關的事件,並將其應用於本地;
問題:網絡io和磁盤io,由於會將全部庫的數據複製到從服務器的中繼日誌中,只是從中繼日誌中重放的時候只會挑選特定的數據庫或表進行重放。
replicate_do_db=
replicate_ignore_db=
replicate_do_table=
replicate_ignore_table=
replicate_wild_do_table=
replicate_wild_ignore_table=
複製的監控和維護
(1) 清理日誌:purge
MariaDB [(none)]> purge { binary | master } logs { to 'log_name' | before datetime_expr };
使用purge刪除二進制日誌後,mysql從新啓動時不會讀取刪除的二進制日誌文件,這樣不會報錯。
(2) 複製監控
master:
show master status;查看正在使用二進制日誌
show binlog events;查看二進制日誌中的事件
show binary logs;查看二進制日誌列表
slave:
show slave status;查看從服務器的狀態
seconds_behind_master: 0 ##判斷從服務器是否落後於主服務器
(3) 如何肯定主從節點數據是否一致?
經過表的checksum檢查;
使用percona-toolkit中pt-table-checksum;
(4) 主從數據不一致時的修復方法?
備份恢復後重試設置主從複製;
maxscale配置示例:
[maxscale]
threads=auto
[server1]
type=server
address=172.18.0.67
port=3306
protocol=mysqlbackend
[server2]
type=server
address=172.18.0.68
port=3306
protocol=mysqlbackend
[server3]
type=server
address=172.18.0.69
port=3306
protocol=mysqlbackend
[mysql monitor]
type=monitor
module=mysqlmon
servers=server1,server2,server3
user=maxscale
passwd=201221dc8fc5a49ea50f417a939a1302
monitor_interval=1000
[read-only service]
type=service
router=readconnroute
servers=server2,server3
user=maxscale
passwd=201221dc8fc5a49ea50f417a939a1302
router_options=slave
[read-write service]
type=service
router=readwritesplit
servers=server1
user=maxscale
passwd=201221dc8fc5a49ea50f417a939a1302
max_slave_connections=100%
[maxadmin service]
type=service
router=cli
[read-only listener]
type=listener
service=read-only service
protocol=mysqlclient
port=4008
[read-write listener]
type=listener
service=read-write service
protocol=mysqlclient
port=4006
[maxadmin listener]
type=listener
service=maxadmin service
protocol=maxscaled
port=6602