mysql 主從配置詳解3 主從配置不一致問題

主從讀寫與維護

有三個待解決問題:

    1. 校驗主從數據一致性問題

    2. 數據校驗恢復

    3. 主從延遲問題

1. 校驗主從數據一致性問題

在理想情況下,備庫和主庫的數據應該是完全一樣的。但事實上備庫可能發生錯誤並導致數據不一致。即使沒有明顯的錯誤,備庫同樣可能因爲MySQL自身的特 性導致數據不一致,例如MySQL的Bug感、網絡中斷、服務器崩潰,非正常關閉或者其他一些錯誤。

按照我們的經驗來看,主備一致應該是一種規範,而不是例外,也就是說,檢查你的主備庫一致性應該是一個日常工作,特別是當使用備庫來做備份時尤爲重 要,因爲肯定不希望從一個已經損壞的備庫裏獲得備份數據。

我們可以使用percona-toolkit工具做校驗,而該工具包含

1. pt-table-checksum 負責檢測MySQL主從數據一致性

2. pt-table-sync負責擋住從數據不一致時修復數據,讓他們保存數據的一致性

3. pt-heartbeat 負責監控MySQL主從同步延遲

安裝

[root@localhost home]# wget ttps://www.percona.com/downloads/percona-toolkit/3.0.3/binary/redhat/7/x86_64/percona-toolkit-3.0.3-
1.el7.x86_64.rpm
[root@localhost home]# yum install perl-IO-Socket-SSL perl-DBD-MySQL perl-Time-HiRes perl perl-DBI -y
[root@localhost home]# rpm -ivh percona-toolkit-3.0.3-1.el6.x86_64.rpm
[root@localhost home]# yum list | grep percona-toolkit
percona-toolkit.x86_64 3.0.3-1.el6 installed
percona-toolkit.noarch 2.2.20-1 percona-release-noarch
percona-toolkit.x86_64 3.1.0-2.el7 percona-release-x86_64
percona-toolkit-debuginfo.x86_64 3.0.13-1.el7 percona-release-x86_64
[root@localhost home]# pt-table-checksum --help

使用

pt-table-checksum [options] [dsn]

        pt-table-checksum:在主(master)上通過執行校驗的查詢對複製的一致性進行檢查,對比主從的校驗值,從而產生結果。DSN指向的是主的地址,該工具的退 出狀態不爲零,如果發現有任何差別,或者如果出現任何警告或錯誤,更多信息請查看官方資料。

       現在我們可以準備一個動作:來模擬數據不一致的問題,同時需要確保主從是配置好了的 -》 思路就是創建一個test的庫隨便添加一個表,使主從庫的數據不一致

       使用工具檢測,注意常用的參數解釋:

--nocheck-replication-filters :不檢查複製過濾器,建議啓用。後面可以用--databases來指定需要檢查的數據庫。
--no-check-binlog-format : 不檢查複製的binlog模式,要是binlog模式是ROW,則會報錯。
--replicate-check-only :只顯示不同步的信息。
--replicate= :把checksum的信息寫入到指定表中,建議直接寫到被檢查的數據庫當中。
--databases= :指定需要被檢查的數據庫,多個則用逗號隔開。
--tables= :指定需要被檢查的表,多個用逗號隔開
--host | h= :Master的地址
--user | u= :用戶名
--passwork | p=:密碼
--Post | P= :端口

檢測

[root@localhost home]# pt-table-checksum --nocheck-replication-filters --replicate=check_data.checksums --databases=test --tables=t --
user=root --password=root
Replica localhost.localdomain has binlog_format MIXED which could cause pt-table-checksum to break replication. Please read "Replicas
using row-based replication" in the LIMITATIONS section of the tool's documentation. If you understand the risks, specify --no-checkbinlog-format to disable this check.

        上面的錯誤信息主要是因爲,檢測主庫與從庫的binlog日誌的模式 - 通常來說可以不用改binlog添加 --no-check-binlog-format 跳過檢測 但是可能也會出現如下的問題

[root@localhost home]# pt-table-checksum --nocheck-replication-filters --replicate=check_data.checksums --no-check-binlog-format --
databases=test --tables=t --user=root --password=root
Diffs cannot be detected because no slaves were found. Please read the —recursion-method documentation for information.

 檢測的方式:

1. 是否是指定在主庫運行進行校驗

2. 就是配置--recursion-method參數,然後在從庫中指定好對應的地址

通過在主庫中查找

mysql> show processlist \G;
*************************** 1. row ***************************
Id: 113
User: repl_127
Host: 192.168.153.131:51514
db: NULL
Command: Binlog Dump
Time: 35742
State: Master has sent all binlog to slave; waiting for more updates
Info: NULL
*************************** 2. row ***************************
Id: 120
User: root
Host: localhost
db: test
Command: Query
Time: 0
State: starting
Info: show processlist
2 rows in set (0.00 sec)
ERROR:
No query specified

可以看到當前連接從庫的ip地址是 192.168.153.131:51514 然後我們可以在從庫中配置

report_port=3306
report_host=192.168.153.131

注意!!! 不要有空格不然可能啓動不了

在主庫中檢測

mysql> show slave hosts;
+-----------+-----------------+------+-----------+--------------------------------------+
| Server_id | Host | Port | Master_id | Slave_UUID |
+-----------+-----------------+------+-----------+--------------------------------------+
| 2 | 192.168.153.131 | 3306 | 1 | 64e07acc-e16e-11e9-9285-000c29ad4fca |
+-----------+-----------------+------+-----------+--------------------------------------+
1 row in set (0.00 sec)

然後進入主庫檢測

[root@localhost home]# pt-table-checksum --nocheck-replication-filters --replicate=check_data.checksums --no-check-binlog-format --
databases=test --tables=t --user=root --password=root
TS             ERRORS DIFFS ROWS CHUNKS SKIPPED TIME T  ABLE
09-28T11:46:37  0       1    3     1     0       0.274 test.t

TS :完成檢查的時間。

ERRORS :檢查時候發生錯誤和警告的數量。

DIFFS :0表示一致,1表示不一致。當指定--no-replicate-check時,會一直爲0,當指定--replicate-check-only會顯示不同的信息。

ROWS :表的行數。

CHUNKS :被劃分到表中的塊的數目。

SKIPPED :由於錯誤或警告或過大,則跳過塊的數目。

TIME :執行的時間。 TABLE :被檢查的表名。

那些信息數據會記錄在checksums表中,查看該表數據會發生一些變化

2. 主從數據一致性-恢復

       我們可以通過使用另一個工具pt-table-sync進行數據的同步 

        手冊地址:https://www.percona.com/doc/percona-toolkit/LATEST/pt-table-sync.html

        在主庫中執行

[root@localhost home]# pt-table-sync --replicate=check_data.checksums h=127.0.0.1,u=root,p=root h=192.168.153.131,u=root,p=root --print
DELETE FROM `test`.`t` WHERE `id`='3' LIMIT 1 /*percona-toolkit src_db:test src_tbl:t src_dsn:h=127.0.0.1,p=...,u=root dst_db:test
dst_tbl:t dst_dsn:h=192.168.153.131,p=...,u=root lock:1 transaction:1 changing_src:check_data.checksums replicate:check_data.checksums
bidirectional:0 pid:14262 user:root host:localhost.localdomain*/;
[root@localhost home]# pt-table-sync --replicate=check_data.checksums h=127.0.0.1,u=root,p=root h=192.168.153.131,u=root,p=root --execute

如上的操作解釋:

pt-table-sync [options] dsn [dsn]

該工具先maseter的信息, 然後再是從庫上的信息;參數建議

--replicate= :指定通過pt-table-checksum得到的表,這2個工具差不多都會一直用。

--databases= : 指定執行同步的數據庫,多個用逗號隔開。

--tables= :指定執行同步的表,多個用逗號隔開。

--sync-to-master :指定一個DSN,即從的IP,他會通過show processlist或show slave status 去自動的找主。

h=127.0.0.1 :服務器地址,命令裏有2個ip,第一次出現的是Master的地址,第2次是Slave的地址。

u=root :帳號。

p=123456 :密碼。

--print :打印,但不執行命令。

--execute :執行命令。

建議:

1.修復數據的時候,用--print打印出來,這樣就可以知道那些數據有問題

2.修復數據之前一定要備份數據庫 ; 然後再 手動執行或者 添加 --execute 我們也可以把這個編輯成腳本,定期通過centos定時器定期檢查, 對於我們來說我們執行在意的是通過pt-table-checksums 顯示信息中的DIFFS信息

[root@localhost ~]# pt-table-checksum --nocheck-replication-filters --replicate=check_data.checksums --no-check-binlog-format --
databases=test --tables=t --user=root --password=root
     TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE
09-28T16:16:52   0     1     3       1  0 0.015 test.t

對於centos來說我們可以通過 awk 命令獲取到 DIFFS 中的值,然後判斷這個值是否不等於0;則可以判斷是否一致

[root@localhost ~]# pt-table-checksum --nocheck-replication-filters --replicate=check_data.checksums --no-check-binlog-format --
databases=test --tables=t --user=root --password=root | awk 'NR>1{sum+=$3}END{print sum}'
1

下一步要做的就是編輯shell腳本 - 額外解釋,所謂的sh腳本就是可以直接模擬centos執行我們在命令太執行的命令然後根據返回的結果進行相應的邏輯處理,我 們可以創建一個pt-table-checksums;注意!!!windows下編輯的sh腳本在linux中執行可能會存在一定的問題,推薦可以直接在xshell中編輯sh腳本這樣問題會 少很多

[root@localhost ~]# touch pt-check-sync.sh
[root@localhost ~]# vi pt-check-sync.sh
#!/usr/bin/env bash
NUM=`pt-table-checksum --nocheck-replication-filters --replicate=check_data.checksums --no-check-binlog-format --databases=test --tables=t
--user=root --password=root | awk 'NR>1{sum+=$3}END{print sum}'`
if [ $NUM -eq 0 ] ;then
echo "Data is ok!"
else
echo "Data is error!"
pt-table-sync --replicate=check_data.checksums h=127.0.0.1,u=root,p=root h=192.168.153.131,u=root,p=root --print
pt-table-sync --replicate=check_data.checksums h=127.0.0.1,u=root,p=root h=192.168.153.131,u=root,p=root --execute
fi
[root@localhost ~]# sh pt-check-sync.sh

然後可以通過編輯crontab -e 定時執行這個腳本就好

20 23 * * * /www/wwwroot/192.168.153.128/shell/pt-check-sync.sh

表示每天晚上23:20運行這個腳本

3. 主從延遲問題

3.1 主從延遲問題-原因與監控

首先需要了解爲什麼會存在延遲的問題

master 服務器和 slave 服務器連接時,創建 Binlog dump thread 以發送 bin log 數據:

1. 一個 Binlog dump thread 對應一個 slave 服務器;

2. Binlog dump thread 從 bin log 獲取數據時會加鎖,獲取到數據後,立即釋放鎖。

當 slave 服務器收到 START_SLAVE 命令時,會創建 I/O thread 和 SQL thread:

1. I/O thread 以拉的方式,從 master 讀取事件,並存儲到 slave 服務器的 relay log 中;

2. SQL thread 從 relay log 中讀取事件並執行;

3. slave 可以按照自己的節奏讀取和更新數據,也可以隨意操作複製進程(啓動和停止)。

pt-heartbeat

在percona toolkit 產品中也提供了可以對於MySQL主從延時檢查的工具pt-heartbeat, pt-heartbeat 的工作原理是通過使用時間戳方式在主庫上更新特定表,然後 再從庫上讀取唄更新的時間戳然後與本地系統時間對比來得出其延遲。

具體流程:

1. 在住上創建一張hearteat表,按照一定的時間頻率更新改表的子彈。監控操作運行後,heartbeat表能促使主從同步

2. 連接到從庫上檢查複製的時間記錄,和從庫的當前系統時間進行比較,得出時間的差異。

注意在使用的方式就是需要在主庫中創建這個表;

use test;
CREATE TABLE heartbeat (
    ts varchar(26) NOT NULL,
    server_id int unsigned NOT NULL PRIMARY KEY,
    file varchar(255) DEFAULT NULL, -- SHOW MASTER STATUS
    position bigint unsigned DEFAULT NULL, -- SHOW MASTER STATUS
    relay_master_log_file varchar(255) DEFAULT NULL, -- SHOW SLAVE STATUS
    exec_master_log_pos bigint unsigned DEFAULT NULL -- SHOW SLAVE STATUS
);

通過pt-heartbeat可以對於mysql中的heartbeat表每隔多久更新一次(注意這個啓動操作要在主庫服務器上執行)

$ pt-heartbeat --user=root --ask-pass --create-table --database test --interval=1 --interval=1 --update --replace --daemonize
$ ps -ef | grep pt-heartbeat

在主庫運行監測同步延遲

$ pt-heartbeat --database test --table=heartbeat --monitor --user=root --password=root --master-server-id=1 
0.02s [ 0.00s, 0.00s, 0.00s ]
0.00s [ 0.00s, 0.00s, 0.00s ]

這其中 0.02s 表示延遲了 ,沒有延遲是爲0 而 [ 0.00s, 0.00s, 0.00s ] 則表示1m,5m,15m的平均值, 而這期中需要注意的是 --master-server-id 爲主服務器的服務id 就是在my.cnf中配置的 server_id的值

3.2 處理延遲問題

對於從庫的延時問題最爲重要的就是主庫與從庫之間連接的網咯環境,從庫的寫入熟讀 這兩個點 - 其次就是對於主從的架構的優化; 注意:一旦使用了主從必然是會有一定的延時問題,因此我們就需要考慮程序對於延遲的容忍度。 如果是0容忍的話建議還是不用主從了

MySQL從庫產生配置

網絡環境跳過,,,從庫的寫入主要是指insert,update,delete的語句的執行速度這些語句的執行速度我們就需要考慮MySQL的執行SQL語句的一個特點 -》 對 於每一個寫的sql會默認開啓事務並提交事務 ; 而事務是會影響到io的消耗的這和innodb_flush_log_at_trx_commit參數有關係。默認爲1 我們可以嘗試設置爲0或 2可以提高效率, 另一個就是sync_binlog

sync_binlog 配置說明:

sync_binlog”:這個參數是對於MySQL系統來說是至關重要的,他不僅影響到Binlog對MySQL所帶來的性能損耗,而且還影響到MySQL中數據的完整性。對 於“sync_binlog”參數的各種設置的說明如下:

sync_binlog=0,當事務提交之後,MySQL不做fsync之類的磁盤同步指令刷新binlog_cache中的信息到磁盤,而讓Filesystem自行決定什麼時候來做同步,或者 cache滿了之後才同步到磁盤。

sync_binlog=n,當每進行n次事務提交之後,MySQL將進行一次fsync之類的磁盤同步指令來將binlog_cache中的數據強制寫入磁盤。

在MySQL中系統默認的設置是sync_binlog=0,也就是不做任何強制性的磁盤刷新指令,這時候的性能是最好的,但是風險也是最大的。因爲一旦系統Crash,在 binlog_cache中的所有binlog信息都會被丟失。而當設置爲“1”的時候,是最安全但是性能損耗最大的設置。因爲當設置爲1的時候,即使系統Crash,也最多丟失 binlog_cache中未完成的一個事務,對實際數據沒有任何實質性影響。

從以往經驗和相關測試來看,對於高併發事務的系統來說,“sync_binlog”設置爲0和設置爲1的系統寫入性能差距可能高達5倍甚至更多。

nnodb_flush_log_at_trx_commit 配置說明:

默認值1的意思是每一次事務提交或事務外的指令都需要把日誌寫入(flush)硬盤,這是很費時的。特別是使用電 池供電緩存(Battery backed up cache)時。 設成2對於很多運用,特別是從MyISAM錶轉過來的是可以的,它的意思是不寫入硬盤而是寫入系統緩存。日誌仍然會每秒flush到硬 盤,所以你一般不會丟失超 過1-2秒的更新。設成0會更快一點,但安全方面比較差,即使MySQL掛了也可能會丟失事務的數據。而值2只會在整個操作系統 掛了時纔可能丟數據。

硬件

升級電腦配置。。。

架構

1. 可以考慮對於一些庫進行單獨分離。

2. 服務的基礎架構在業務和MySQL之間加入memcache或者redis的cache層。降低MySQL的杜豔麗

3. 從庫的配置要好。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章