數據庫學習之十二:mysql主從複製

12、mysql主從複製

一、主從複製原理

1.主從複製的前提:mysql

1.1兩臺mysql實例(多臺物理機,或者多實例)sql

1.2主庫要開啓二進制日誌數據庫

1.3主庫要提供複製相關用戶,replication slave,一個比較特殊的權限。vim

grant replication slave on * . * to repl@'10.0.0.%' identified by '123';

1.4從庫須要將和主庫相差的數據,進行追加緩存

通常狀況下能夠人爲備份主庫數據,恢復到從庫上。安全

1.5應該從恢復以後的時間點,開始自動從主庫獲取二進制日誌開始應用網絡

須要人爲告訴從庫,從哪裏開始自動開始複製二進制日誌(file+position),另外還須要告訴從庫user,password,ip,port架構

2.複製中的線程及文件

2.1主庫app

dump(IO) thread:在複製過程當中,主庫發送二進制日誌的線程。less

2.2從庫

IO thread:向主庫請求二進制日誌,而且接受二進制日誌的線程。

SQL thread:執行請求過來的二進制的線程

2.3在主庫的文件

binlog文件,主庫的二進制日誌

2.4從庫文件

relaylog:中繼日誌,存儲請求過來的二進制日誌。

master.info:

​ 1.從庫鏈接主庫的重要參數(user,password,ip,port)

​ 2.上次獲取過的主庫二進制日誌的位置

relay-log.info

​ 存儲從庫SQL線程已經執行過的relaylog日誌位置。

3.主從複製的工做原理

3.1從庫,IO線程,讀取master.info中的信息,獲取到鏈接參數(user,password,ip,port),和上次用過的主庫的binlog的位置(mysqlbin-0000,position)。

3.2IO線程使用鏈接到主庫,拿着上次從主庫獲取到的binlog的位置,問主庫有沒有比這個更新的二進制日誌。

3.3主庫查詢二進制日誌,並對比從庫發送過來的位置信息,若是有新的二進制日子,就經過dump thread發送給我從庫。

3.4從庫經過IO線程,接受主庫發來的二進制日誌,存儲到TCP/IP緩存中,而且返回ACK確認給主庫,這時主庫認爲複製完成了,能夠繼續其餘工做了。

3.5從庫更新master.info,二進制日誌的爲新的位置信息。

3.6從庫IO線程會將TCP/IP緩存中的日誌,存儲到relay-log中繼日誌文件中。

3.7從庫SQL線程,讀取relay-log.info,獲取到上次執行到的relay-log日誌位置,以這個位置爲起點,日後繼續執行中繼日誌。

3.8SQL線程執行完成全部relay以後,會更新relay-log.info信息爲新位置信息。

到此位置,一次完成的複製過程完成。

四、搭建主從複製

一、準備環境
思路:
一、兩個以上節點(多實例)
3307:master
3308:slave1
3309:slave2
二、主庫binlog開啓,從庫開啓relay-log(默認在數據目錄下生成)
vim /data/3307/my.cnf
log-bin=/data/3307/mysql-bin
binlog_format=row

三、server-id不一樣
[root@db02 data]# cat /data/3307/my.cnf |grep server-id
server-id=3307
[root@db02 data]# cat /data/3308/my.cnf |grep server-id
server-id=3308
[root@db02 data]# cat /data/3309/my.cnf |grep server-id
server-id=3309
四、關閉數據庫的自動域名解析
每一個節點都加入如下配置:
skip-name-resolve
五、啓動多實例
mysqld_safe --defaults-file=/data/3307/my.cnf &
mysqld_safe --defaults-file=/data/3308/my.cnf &
mysqld_safe --defaults-file=/data/3309/my.cnf &

六、主庫建立複製帳戶
鏈接到主庫:
mysql -S /data/3307/mysql.sock
grant replication slave on *.* to repl@'10.0.0.%' identified by '123';

七、從庫數據的追加
	(1)不須要追加的狀況
	 主和從同時搭建的新環境,就不須要備份主庫數據,恢復到從庫了,直接從第一個binlog(mysql-bin.000001)的開頭位置(120)。
	(2)若是主庫已經工做了很長時間了,咱們通常須要備份主庫數據,恢復到從庫,而後從庫從備份的時間點起自動進行復制。
重點針對第二種狀況進行演示:
備份主庫:
mysqldump -S /data/3307/mysql.sock -A -R  --triggers --master-data=2 --single-transaction >/tmp/full.sql
sed -n '22p' /tmp/full.sql 
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=325;
恢復到從庫:
mysql -S /data/3308/mysql.sock 
mysql> set sql_log_bin=0;
mysql> source /tmp/full.sql

八、從庫開啓主庫:
mysql -S /data/3308/mysql.sock
help change master to

CHANGE MASTER TO
  MASTER_HOST='10.0.0.203',
  MASTER_USER='repl',
  MASTER_PASSWORD='123',
  MASTER_PORT=3307,
  MASTER_LOG_FILE='mysql-bin.000003',
  MASTER_LOG_POS=325;
開啓主從(開啓IO和SQL線程):
start slave;
九、查看主從狀態:
show slave status\G
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
十、主從重要狀態信息介紹
show slave status\G
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Last_IO_Errno: 0
Last_IO_Error: 
Last_SQL_Errno: 0
Last_SQL_Error: 


IO線程故障:
    一、主庫鏈接不上
       user、password、port、ip 錯誤
	   解決方案:
		stop  slave;	
		reset slave all;  
		change master to	
		start slave;
       防火牆
       網絡不通
       skip-name-resolve
	   stop  slave;
	   start slave;
	   
    二、主庫二進制日誌丟失或損壞
		解決方案:
		stop  slave;	
		reset slave all;  
		從新備份恢復
		change master to	
		start slave;

五、SQL線程故障

SQL線程故障:
   執行relaylog日誌新事件
    一、刪除、修改對象的操做時,沒有這個對象
    二、建立對象時,對象已存在
    三、主鍵衝突
從庫作寫入操做,會致使以上問題出現
處理方法:
stop slave; 
set global sql_slave_skip_counter = 1; 
start slave;
/etc/my.cnf
slave-skip-errors = 1032,1062,1007
可是,以上操做有時是有風險的,最安全的作法就是從新構建主從。
怎麼預防以上問題?
從庫加入配置文件
set global read_only=1;
vim /etc/my.cnf
read_only=1           ---->只能控制普通用戶

六、主從異常--主從延時過長

show slave status \G
Seconds_Behind_Master:0

默認的主從複製機制是異步的一個過程。

主庫緣由:
一、主庫作修改操做以後,纔會記錄二進制日誌。
sync_binlog=0/1

If the value of this variable is greater than 0, 
the MySQL server synchronizes its binary log to disk (using fdatasync()) 
after sync_binlog commit groups are written to the binary log. 
The default value of sync_binlog is 0, which does no synchronizing to disk—in this case,
the server relies on the operating system to flush the binary log's contents from time to time as for any other file. 
A value of 1 is the safest choice because in the event of a crash you lose at most one commit group from the binary log. 
However, it is also the slowest choice (unless the disk has a battery-backed cache, which makes synchronization very fast)
---------------------
    1:表示:每次事務commit,刷新binlog到磁盤
    0:系統決定binlog什時候刷新到磁盤
二、主庫的壓力特別大(大事務、多事務)
三、從庫數量多,致使dump線程繁忙
-------------------
從庫緣由:
一、relay-log寫入慢
二、SQL線程慢(主從硬件差別比較大)
-----------------------------
儘量的避免主從延時
一、sync_binlog=1
二、大事務拆成小事務,多事務進行分離
三、使用多級主從,分庫分表架構
四、將binlog放到ssd或者flash上,高性能存儲
五、將relay放到ssd或者flash上
六、儘可能選擇和主庫一致硬件和配置

七、主從複製高級功能--半同步複製

出發點:保證主從數據一致性的問題,安全的考慮

5.5 出現的概念,可是不建議使用,性能太差

5.6之後出現group commit 組提交功能,來提高開啓版同步複製的性能

5.7 加強半同步複製的新特性:after sync;

------
加載插件

主:
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';

從:
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
查看是否加載成功:
show plugins;

啓動:
主:
SET GLOBAL rpl_semi_sync_master_enabled = 1;

從:
SET GLOBAL rpl_semi_sync_slave_enabled = 1;

重啓從庫上的IO線程
STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;
查看是否在運行
主:
show status like 'Rpl_semi_sync_master_status';
從:
show status like 'Rpl_semi_sync_slave_status';
-----
補充:
rpl_semi_sync_master_timeout       | 10000
默認狀況先,到達10秒鐘尚未ack,主從關係自動切換爲普通複製
若是是1主多從的半同步複製,只要有一臺落地relaylog,返回ack,此次半同步就完成了。

八、主從複製高級特性--延時從庫

會專門找一個節點,配置成延時節點,儘量防止邏輯損壞,通常狀況下這個節點會被用備份
	
咱們配置的是SQL_thread的延時

mysql>stop slave;

mysql>CHANGE MASTER TO MASTER_DELAY = 60;

mysql>start slave;

mysql> show slave status \G
SQL_Delay: 300

取消延時:
mysql> stop slave;
mysql> CHANGE MASTER TO MASTER_DELAY = 0;
mysql> start slave;

九、主從複製高級功能--複製過濾

主庫方面控制(不建議使用):
    白名單:只記錄白名單中列出的庫的二進制日誌
     binlog-do-db
    黑名單:不記錄黑名單列出的庫的二進制日誌
     binlog-ignore-db
	  
從庫方面控制:
show slave status\G;查看相關參數。
白名單:只執行白名單中列出的庫或者表的中繼日誌   

--replicate-do-db=test
--replicate-do-table=test.t1
--replicate-wild-do-table=test.x*
   
黑名單:不執行黑名單中列出的庫或者表的中繼日誌
--replicate-ignore-db
--replicate-ignore-table
--replicate-wild-ignore-table
只複製world數據庫的數據

十、主從複製新特性--GTID複製

GTID
5.6新特性
GTID(Global Transaction ID)是對於一個已提交事務的編號,而且是一個全局惟一的編號。
它的官方定義以下:
GTID = source_id :transaction_id
7E11FA47-31CA-19E1-9E56-C43AA21293967:29
每一臺mysql實例中,都會有一個惟一的uuid,標識實例的惟一性
auto.cnf,存放在數據目錄下

重要參數:
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1


gtid-mode=on			            --啓用gtid類型,不然就是普通的複製架構
enforce-gtid-consistency=true		 --強制GTID的一致性
log-slave-updates=1					--slave更新是否記入日誌

-----------------
構建1主2從的GTID複製環境:

3臺虛擬機,
db02 克隆兩臺虛擬機環境,分別命名爲db0一、db03,在生產中準備3臺真實的物理機,不用多實例

要求:

一、IP地址、主機名
	 db01:10.0.0.51/24   
	 db03:10.0.0.53/24
二、清理全部以前3306的相關數據,只留軟件

db01:
cd /application/mysql/data/
\rm -rf *
cd /data/binlog/
\rm -rf *

db02:
cd /application/mysql/data/
\rm -rf *
cd /data/binlog/
\rm -rf *

db03:
cd /application/mysql/data/
\rm -rf *
cd /data/binlog/
\rm -rf *

三、準備配置文件
規劃:
	主庫: 10.0.0.51/24
	從庫1: 10.0.0.52/24
	從庫2:10.0.0.53/24
主庫:
加入如下配置信息
db01:10.0.0.51/24
vim /etc/my.cnf
[mysqld]
basedir=/application/mysql
datadir=/application/mysql/data
socket=/tmp/mysql.sock
log-error=/var/log/mysql.log
log_bin=/data/binlog/mysql-bin
binlog_format=row
skip-name-resolve
server-id=51
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[client]
socket=/tmp/mysql.sock

slave1:
db02:10.0.0.52/24

vim /etc/my.cnf
[mysqld]
basedir=/application/mysql
datadir=/application/mysql/data
socket=/tmp/mysql.sock
log-error=/var/log/mysql.log
log_bin=/data/binlog/mysql-bin
binlog_format=row
skip-name-resolve
server-id=52
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[client]
socket=/tmp/mysql.sock

slave2:
db02:10.0.0.53/24

vim /etc/my.cnf
[mysqld]
basedir=/application/mysql
datadir=/application/mysql/data
socket=/tmp/mysql.sock
log-error=/var/log/mysql.log
log_bin=/data/binlog/mysql-bin
binlog_format=row
skip-name-resolve
server-id=53
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[client]
socket=/tmp/mysql.sock

-----------------
三臺節點分別初始化數據:

/application/mysql/scripts/mysql_install_db --user=mysql  --basedir=/application/mysql --datadir=/application/mysql/data/ 

分別啓動三個節點mysql:
/etc/init.d/mysqld start

測試啓動狀況:
mysql -e "show variables like 'server_id'"

master:51
slave:52,53

51:
grant replication slave  on *.* to repl@'10.0.0.%' identified by '123';
52\53:
change master to master_host='10.0.0.51',master_user='repl',master_password='123' ,MASTER_AUTO_POSITION=1;
start slave;
相關文章
相關標籤/搜索