一啦租、上節(jié)回顧
1哗伯、mysqldump
-u -p -S -h -P -A -B 庫 表
-R --triggers -E
--master-data=2
--single-transaction
--set-gtid-purged=OFF 構(gòu)建主從的備份千萬不能加OFF,可以是ON或者AUTO
--max-allowed-packet
- 2篷角、xtrabackup
innobackupex
全備:
innobackupex --user --password --no-timestamp /data/backup/full
增量:
innobackupex --user --password --no-timestamp --incremental --incremental-basedir=/data/backup/full/ /data/backup/incl
整理備份:
全備:
innobackupex --apply-log /data/backup/full
增量:
只有最后一次合并的增量不需要--redo-only焊刹,過程中所有備份整理都要加--redo-only。
innobackupex --apply-log --redo-only --incremental-dir=/data/backup/incl /data/backup/full
恢復備份:
innobackupex --copy-back /data/backup/full
- 3恳蹲、備份工具如何配合binlog應用
binlog截取最重要的是找 起點和終點
周三下午兩點虐块,數(shù)據(jù)損壞,截取日志的思路
mysqldump:
起點:找到周二晚上全備腳本嘉蕾,找到change master to
終點:通過看events 或者 文件內(nèi)容 找到故障點的位置
- 4贺奠、異構(gòu)
操作系統(tǒng)版本不一樣
邏輯備份
數(shù)據(jù)庫軟件不一樣
MySQL ---CSV-> MongoDB ,ES
MySQL ---JSON-> MongoDB ,ES
二、主從復制(重點)
1荆针、介紹
依賴于二進制日志的敞嗡,“實時”備份的一個多節(jié)點架構(gòu)
2、搭建主從復制的前提(搭建主從復制)
2.1 至少2個實例
2.2 不同server_id
2.3 主庫需要開啟二進制日志
2.4 主庫需要授權(quán)一個專用復制用戶
2.5 主庫數(shù)據(jù)備份
2.6 開專用復制線程
3航背、搭建主從復制
3.1 準備多實例
啟動多實例
[root@mysql ~]# systemctl start mysqld3307.service
[root@mysql ~]# systemctl start mysqld3308.service
[root@mysql ~]# systemctl start mysqld3309.service
[root@mysql ~]# netstat -luntp |egrep 330*
3.2喉悴、檢查server ID
[root@mysql ~]# mysql -S /data/3307/mysql.sock -e "select @@server_id"
[root@mysql ~]# mysql -S /data/3308/mysql.sock -e "select @@server_id"
[root@mysql ~]# mysql -S /data/3309/mysql.sock -e "select @@server_id"
3.3、檢查3307(主庫)的二進制日志情況
[root@mysql /data/3307]# mysql -S /data/3307/mysql.sock -e "show variables like '%log_bin%'"
3.4玖媚、創(chuàng)建主庫復制用戶
[root@mysql /data/3307]# mysql -S /data/3307/mysql.sock
mysql> grant replication slave on *.* to repl@'10.0.0.%' identified by '123';
3.5箕肃、進行主庫數(shù)據(jù)庫備份
[root@mysql /data/3307]# mysqldump -S /data/3307/mysql.sock -A --master-data=2 -R -E --triggers --single-transaction >/tmp/full.sql
3.6、恢復數(shù)據(jù)到從庫
[root@mysql /data/3308]# mysql -S /data/3308/mysql.sock
mysql> set sql_log_bin=0;
mysql> source /tmp/full.sql;
3.7今魔、告訴從庫復制的信息
[root@mysql /data/3307]# mysql -S /data/3307/mysql.sock
mysql> help change master to
[root@mysql /data/3307]# vim /tmp/full.sql #查看備份日志獲得二進制號勺像,pos號
22 -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000004', MASTER_LOG_POS=444;
[root@mysql /data/3308]# mysql -S /data/3308/mysql.sock
mysql> CHANGE MASTER TO
MASTER_HOST='10.0.0.51', #主庫IP
MASTER_USER='repl', #授權(quán)的用戶
MASTER_PASSWORD='123456', #授權(quán)的密碼
MASTER_PORT=3307, #主庫端口
MASTER_LOG_FILE='mysql-bin.000004', #備份日志的二進制號
MASTER_LOG_POS=444, #pos號
MASTER_CONNECT_RETRY=10;
###如果 change master to 信息輸入錯誤,咋辦错森?
[root@mysql /data/3308]# mysql -S /data/3308/mysql.sock
mysql> stop slave;
mysql> reset slave all;
CHANGE MASTER TO
MASTER_HOST='10.0.0.51',
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_PORT=3307,
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=444,
MASTER_CONNECT_RETRY=10;
mysql> start slave;
3.8吟宦、啟動復制線程(從庫操作)
[root@mysql /data/3308]# mysql -S /data/3308/mysql.sock
mysql> start slave;
3.9、查看主從是否連接成功
mysql -S /data/3308/mysql.sock
mysql> show slave status\G
#查看這兩行
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
3.10涩维、測試(主庫創(chuàng)建一個庫殃姓,從庫查看)
#主庫創(chuàng)建庫
mysql> create database zhucong;
#從庫查看
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| wordpress |
| zhucong |
+--------------------+
6 rows in set (0.00 sec)
4、主從復制工作過程
- 4.1瓦阐、名詞認識
文件:
主庫:binlog
從庫:
relay-log 中繼日志
master.info 主庫信息文件
relay-log.info 中繼日志應用信息
線程:
主庫:Binlog_Dump_thread 二進制日志投遞線程
查看二進制日志投遞線程
[root@db01 /data/3307/data]# mysql -S /data/3307/mysql.sock -e "show processlist"
從庫:
IO_Thread : 從庫IO線程 : 請求和接收binlog
SQL_Thread: 從庫的SQL線程 : 回放日志
- 4.2蜗侈、主從復制工作原理
工作原理:
(1) 從庫執(zhí)行 change master to 語句,會立即將主庫信息記錄到master.info中
(2) 從庫執(zhí)行 start slave語句睡蟋,會立即生成IO_T和SQL_T
(3) IO_T 讀取master.info文件踏幻,獲取主庫信息
(4) IO_T 連接主庫,主庫會立即分配一個DUMP_T,進行交互
(5) IO_T 根據(jù)master.info binlog信息戳杀,向DUMP_T請求最新的binlog
(6) 主庫DUMP_T,經(jīng)過查詢该面,如果發(fā)現(xiàn)有新的夭苗,截取并返回給從庫IO_T
(7) 從庫IO_T會收到binlog,存儲在TCP/IP緩存中吆倦,在網(wǎng)絡(luò)底層返回ACK
(8) 從庫IO_T會更新master.info听诸,重置binlog位置點信息
(9) 從庫IO_T會將binlog,寫入到relay-log中
(10) 從庫SQL_T 讀取relay-log.info 文件晌梨,獲取上次執(zhí)行過的位置點
(11) SQL_T按照位置點往下執(zhí)行relay-log日志
(12) SQL_T執(zhí)行完成之后须妻,重新更新relay-log.info
(13) relaylog定期自動清理的功能
細節(jié):
主庫發(fā)生了信息的修改,更新二進制日志完成后荒吏,會發(fā)送一個信號DUMP_T,DIPM_T通知給IO_T線程
5、主從復制監(jiān)控及分析故障處理
- 5.1 主從監(jiān)控
主庫:
show processlist;
Master has sent all binlog to slave; waiting for more updates #正常狀態(tài)
從庫:
show slave status \G
主庫的信息(master.info):
Master_Host: 10.0.0.51 主庫的IP
Master_User: repl 復制用戶名
Master_Port: 3307 主庫的端口
Connect_Retry: 10 斷連之后重試次數(shù)
Master_Log_File: mysql-bin.000001 已經(jīng)獲取得到binlog的文件名
Read_Master_Log_Pos: 444 已經(jīng)獲取得到binlog的位置號
從庫的relaylog的信息(relay-log.info):
Relay_Log_File: db01-relay-bin.000002 從庫已經(jīng)運行過的relaylog的文件名
Relay_Log_Pos: 320 從庫已經(jīng)運行過的relaylog的位置點
從庫復制線程工作狀態(tài):
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
過濾復制相關(guān)的狀態(tài):
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
從庫延時主庫的時間:
Seconds_Behind_Master: 0 從庫延時主庫的時間(秒為單位)
從庫線程報錯詳細信息:
Last_IO_Errno: 0 IO報錯的號碼
Last_IO_Error: IO報錯的具體信息
Last_SQL_Errno: 0 SQL報錯的號碼
Last_SQL_Error: SQL線程報錯的具體原因
延時從庫:
SQL_Delay: 0 延時從庫設(shè)定的時間
SQL_Remaining_Delay: NULL 延時操作剩余時間
GTID復制信息:
Retrieved_Gtid_Set: 接收到的GTID的個數(shù)
Executed_Gtid_Set: 執(zhí)行了的GTID的個數(shù)
- 5.2 主從故障的分析及處理
從庫復制線程工作狀態(tài):
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
從庫線程報錯詳細信息:
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
- 5.2.1 IO線程故障
(1) 連接主庫連接不上
connecting
原因:
網(wǎng)絡(luò)不通
防火墻
IP不對
port不對
用戶,密碼不對
skip_name_resolve
連接數(shù)上限
處理思路:
[root@mysql /data/3308]# mysql -urepl -p123 -h 10.0.0.51 -P 3307 ----> 密碼錯誤
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'repl'@'mysql' (using password: YES)
[root@mysql /data/3308]# mysql -ureplo -p123456 -h 10.0.0.51 -P 3307 ----> 用戶名錯誤
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'replo'@'mysql' (using password: YES)
[root@mysql /data/3308]# mysql -urepl -p123 -h 10.0.0.51 -P 3308 ----> 端口錯誤
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1130 (HY000): Host 'mysql' is not allowed to connect to this MySQL server
[root@mysql /data/3308]# mysql -urepl -p123 -h 10.0.0.52 -P 3307 ----> IP錯誤
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 2003 (HY000): Can't connect to MySQL server on '10.0.0.52' (110)
[root@mysql /data/3308]# mysql -urepl -123 -h 10.0.0.52 -P 3307 ----> 參數(shù)錯誤
mysql: [ERROR] mysql: unknown option '-1'
如何處理?
[root@mysql /data/3308]# mysql -S /data/3308/mysql.sock
mysql> stop slave;
mysql> reset slave all;
mysql> change master to
mysql> CHANGE MASTER TO #修改數(shù)據(jù)
MASTER_HOST='10.0.0.51',
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_PORT=3307,
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=444,
MASTER_CONNECT_RETRY=10;
mysql> start slave;
(2) 請求新的binlog
IO線程NO的狀態(tài)分析:
原因1:日志名不對
從庫信息:
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 444
對比備份的位置號
原因2:日志損壞原特恬、日志不連續(xù)
演示損壞步驟:
主庫:
[root@mysql /data/3307]# mysql -S /data/3307/mysql.sock
mysql> flush logs;
mysql> flush logs;
mysql> flush logs;
mysql> flush logs;
mysql> flush logs;
mysql> reset master;
mysql> create database dd;
mysql> create database dd1;
mysql> create database dd2;
從庫:
[root@mysql /data/3308]# mysql -S /data/3308/mysql.sock
mysql> show slave status\G
Slave_IO_Running: No
Slave_SQL_Running: Yes
報錯信息:
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'could not find next log; the first event 'mysql-bin.000004' at 444, the last event read from '/data/3307/mysql-bin.000010' at 154, the last byte read from '/data/3307/mysql-bin.000010' at 154.'
恢復:
[root@mysql /data/3307]# mysql -S /data/3307/mysql.sock
[root@mysql /data/3307]# mysql> show master status\G; #在主庫上查看二進制號
File: mysql-bin.000001
[root@mysql /data/3308]# mysql -S /data/3308/mysql.sock
mysql> stop slave;
mysql> reset slave all ;
mysql> CHANGE MASTER TO
MASTER_HOST='10.0.0.51',
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_PORT=3307,
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154,
MASTER_CONNECT_RETRY=10;
mysql> start slave;
查看結(jié)果:
mysql> show slave status\G
Slave_IO_Running: yes
Slave_SQL_Running: Yes
(3) 寫relaylog
(4) 更新master.info
(5) server_id重復
- 5.2.2 SQL線程故障
原因1:
讀relay-log.info
讀relay-log癌刽,并執(zhí)行日志
更新relay-log.info
以上文件損壞尝丐,最好是重新構(gòu)建主從
原因2:
為什么一條SQL語句執(zhí)行不成功
1显拜、主從數(shù)據(jù)庫版本差異較大
2、主從數(shù)據(jù)庫配置參數(shù)不一致(例如:sql_mode等)
3远荠、想要創(chuàng)建的對象已經(jīng)存在
4失息、想要刪除或修改對象不存在
5、主鍵沖突
6根时、DML語句不符合表定義及約束時
7辰晕、歸根結(jié)底是從庫寫入了
從庫出現(xiàn)通過錯誤跳過錯誤:
方法一:
mysql> stop slave; #停止從庫
mysql> set global sql_slave_skip_counter = 1; #從庫跳過主庫過來錯誤語句
mysql> start slave; #重新啟動從庫
方法二:
[root@mysql /data/3308]# vim /etc/my.cnf
slave-skip-errors = 1032,1062,1007 #只要一遇到1032,1062,1007褒链,直接跳過
方法三:萬全的解決
設(shè)置從庫只讀卡骂,防止寫入
使用中間件做成讀寫分離的架構(gòu)
設(shè)置只讀查看方法,一般不推薦,可以使用中間件來實現(xiàn):
mysql> show variables like '%read_only%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_read_only | OFF |
| read_only | OFF | #設(shè)置為0抒痒,能對普通用戶有效
| super_read_only | OFF | #設(shè)置為0,能對root用戶有效
| transaction_read_only | OFF |
| tx_read_only | OFF |
+-----------------------+-------+
5 rows in set (0.02 sec)
6故黑、主從延時原因分析
從庫延時主庫的時間(以秒為單位):
Seconds_Behind_Master: 0
- 6.1 主庫方面
日志寫入不及時:
mysql> select @@sync_binlog;
+---------------+
| @@sync_binlog |
+---------------+
| 1 | #等于1立刻刷新
+---------------+
1 row in set (0.00 sec)
主庫并發(fā)業(yè)務較高:
采用'分布式架構(gòu)'
從庫太多:
級聯(lián)主從
對于Classic Replication:
主庫是有能力并發(fā)運動事務的庭砍,但是在Dump_T再傳輸日志的數(shù)據(jù)時候,是以事件為單元傳輸日志的怠缸,
所以導致事務的傳輸工作是串行方式的,這時在主庫TPS很高時扳炬,會產(chǎn)生比較大的主從延時。
怎么處理:
group commit
從5.6開始加入了GTID搔体,在復制時,可以將原來串行的傳輸模式變成并行的厌杜。
除了GTID支持计螺,還需要雙一保證。
- 6.2 從庫方面
Classic Replication
SQL 線程只有一個登馒,所以說只能串行執(zhí)行relay的事務。
怎么解決圈纺?
多加幾個SQL線程
在5.6中出現(xiàn)了database級別多線程SQL
只能針對不同庫下的事務,才能并發(fā)
到5.7版本加入了MTS蛾娶,真正實現(xiàn)了事務級別的并發(fā)SQL
7潜秋、延時從庫
- 7.1、數(shù)據(jù)損壞
數(shù)據(jù)損壞
邏輯損壞
對于傳統(tǒng)的主從復制峻呛,比較擅長處理物理損壞辜窑。
- 7.2寨躁、延時從庫設(shè)置理念
對SQL線程進行延時設(shè)置
- 7.3、延時從庫設(shè)置多久合適
一般企業(yè)职恳,延時3-6小時
- 7.4、如何設(shè)置延時從庫(秒為單位)
[root@mysql /data/3308]# mysql -S /data/3308/mysql.sock
mysql> stop slave;
mysql> CHANGE MASTER TO MASTER_DELAY = 300;
mysql> start slave;
#查看設(shè)置結(jié)果
mysql> show slave status \G
SQL_Delay: 300
SQL_Remaining_Delay: NULL
7.5话肖、如何使用延時從庫
7.5.1 思路
模擬故障:
[root@mysql /data/3307]# mysql -S /data/3307/mysql.sock
create database delay charset utf8mb4;
use delay;
create table t1(id int);
insert into t1 values(1),(2),(3);
commit;
drop database delay;
發(fā)現(xiàn)問題了:
1、停止SQL線程贺氓,停止主庫業(yè)務
2床蜘、模擬SQL線程辙培,手工恢復relaylog到drop之前的位置點
3邢锯、截取relaylog日志,找到起點(relay-log.info)和終點(drop 操作)
4丹擎、恢復截取日志蒂培,驗證數(shù)據(jù)可用性
開始處理:
1再愈、停止從庫的SQL線程
[root@mysql /data/3308]# mysql -S /data/3308/mysql.sock
mysql> stop slave sql_thread;
2护戳、找到起始點
show slave status \G
Relay_Log_Pos: 473
3、找到終點媳荒,找到drop之前操作即可,只看左邊pos號
show relaylog events in 'mysql-relay-bin.000002';
1080
4缴渊、備份
mysqlbinlog --start-position=473 --stop-position=1080 /data/3308/data/mysql-relay-bin.000002 >/tmp/relay.sql
5鱼炒、恢復
mysql -S /data/3308/mysql.sock
set sql_log_bin=0;
source /tmp/relay.sql
8、過濾復制
9、半同步復制
CHANGE MASTER TO
MASTER_HOST='10.0.0.51',
MASTER_USER='repl',
MASTER_PASSWORD='123',
MASTER_PORT=3307,
MASTER_LOG_FILE='mysql-bin.000004',
MASTER_LOG_POS=154,
MASTER_CONNECT_RETRY=10;