MySQL Replication需要注意的問題

主庫意外宕機

如果沒有設置主庫的sync_binlog選項,就可能在奔潰前沒有將最后的幾個二進制日志事件刷新到磁盤中。備庫I/O線程因此也可一直處于讀不到尚未寫入磁盤的事件的狀態中。當主庫從新啟動時,備庫將重連到主庫并再次嘗試去讀該事件,但主庫會告訴備庫沒有這個二進制日志偏移量。解決這個問題的方法是指定備庫從下一個二進制日志的開頭讀日志。但是一些事件將永久丟失。可以使用前面文章提到的工具來檢查主從數據一致以及修復pt-table-checksum。即使開啟了sync_binlog,myisam表的數據仍然可能在奔潰的時候損壞。對于innodb表,如果innodb_flush_log_at_trx_commit沒有設置為1,也可能丟失數據,但是數據不會損壞。

因此主庫的參數建議開啟

sync_binlog=1
innodb-flush-log-at-trx-commit=1

MySQL 5.6版本之前存在一個bug,即當啟用上述兩個參數時,會使得InnoDB存儲引擎的group commit失效,從而導致在寫密集的環境中性能的急劇下降。group commit是什么?這是一個知識點,那為什么sync_binlog=1,innodb-flush-log-at-trx-commit=1

會導致組提交失敗?這又是一個知識點,大家可以查閱相關資料。

因此,我們常常在性能和數據一致性中做了妥協,通常將參數innodb-flush-log-at-trx-commit設置為2,而這就導致了master不再是crash safe的,主從數據可能會不一致。關于innodb_flush_log_at_trx_commit的有效值為0,1,2。我這里簡單提一下,因為很多知識點是有連貫性的,往往提到這個問題而又涉及到另外的問題^_^

0代表當提交事務時,并不將事務的重做日志寫入磁盤上的日志文件,而是等待主線程每秒的刷新。當宕機時,丟失1秒的事務。

1和2有點相同,但是不同的地方在于:1表示在執行commit時將重做日志緩沖同步寫到磁盤,即伴有fsync的調用。2表示將重做日志異步寫到磁盤,即寫到文件系統的緩存中。由操作系統控制刷新。因此不能完全保證在執行commit時肯定會寫入重做日志文件,只是有這個動作的發生。

因此為了保證事務的ACID中的持久性,必須將innodb_flush_log_at_trx_commit設置為1,也就是每當有事務提交時,就必須確保事務都已經寫入重做日志文件。那么當數據庫因為意外發生宕機時,可以通過重做日志文件恢復,并保證可以恢復已經提交的事務。而將該參數設置為0或者2,都有可能發生恢復時部分事務的丟失。不同之處在于,設置為2時,當mysql數據庫發生宕機而操作系統及服務器并沒有發生宕機時,由于此時未寫入磁盤的事務日志保存在文件系統緩存中,當恢復時同樣能保證數據不丟失。

對于性能與安全我們都要的情況下,我們肯定會使用RAID,并且開啟Write Back功能,而且RAID卡提供電池備份單元(BBU,Battery Backup Unit),關于這塊的知識,童鞋們可以自行查閱相關資料。

備庫意外宕機:

當備庫在一次非計劃的關閉后重啟時,會去讀master.info文件以找到上次停止復制的位置。不幸的是,該文件可能并沒有同步寫到磁盤,因為該信息是在緩存中,可能并沒有刷新到磁盤文件master.info。文件中存儲的信息可能是錯誤的,備庫可能會嘗試重新執行一些二進制日志事件,這可能導致主鍵沖突,就是我們常常看見的1062錯誤。除非能確定備庫在哪里停止(很難),否則唯一的辦法就是忽略那些錯誤。

在從庫導致復制中斷有兩方面的原因,即replication中的SQL thread和IO thread。首先來看SQL thread,其主要完成兩個操作:

1.運行relay log中對應的事務信息
2.更新relay-info.log文件

更新relay-info.log文件是為了記錄已經執行relay log中的位置,當slave重啟后可以根據這個位置繼續同步relay log。但是,這里用戶會發現這兩個操作不是在一個事務中,一個是數據庫操作,一個是文件操作,因此不能達到原子的效果。此外,MySQL數據庫默認對于文件relay-info.log是寫入到操作系統緩存,因此在發生宕機時可能導致大量的已更新位置的丟失,從而導致重復執行SQL語句,最終的現象就是主從數據不一致。MySQL 5.5新增了參數sync_relay_log_info,可以控制每次事務更新relay-info.log后就進行一次fdatasync操作,這加重了系統負擔,而且即使這樣也可能存在最后一個事務丟失的情況。

IO thread用于同步master上的二進制日志,但是其在crash時依然會導致數據不一致的情況發生。IO thread將收到的二進制日志寫入到relay log,每個二進制日志由多個log event組成,所以每接受到一個log event就需要更新master-info.log。和relay-info.log一樣,其也是寫入操作系統緩存,參數sync_master_info可以控制fdatasync的時間。由于IO thread的更新不能像SQL thread一樣進行放到一個事務進行原子操作,因此其是對數據一致性會產生影響,設想一個log event傳送到了relay log中兩次的情形。

不過好在從MySQL 5.5版本開始提供了參數relay_log_recovery,當發生crash導致重連master時,其不根據master-info.log的信息進行重連,而是根據relay-info中執行到master的位置信息重新開始拉master上的日志數據(不過需要確保日志依然存在于master上,否則就。。。)

so,mysql 5.5版本的從庫推薦配置參數:

sync_master_info = 1
sync_relay_log = 1
sync_relay_log_info = 1
read_only          #從庫只讀,但是有super權限的依然可以寫入
relay_log_recovery = 1
skip_slave_start   # 默認啟動從庫就開啟了同步,io線程和sql線程都運行了,該參數是需要手動執行start slave方可啟動同步

復制過濾選項

常常看見很多同學在主庫進行過濾選項設置,當然這也有好處,減少了帶寬,但是在主庫設置過濾選項是非常危險的操作,因為無論是顯示要過濾的或者要同步的,二進制日志只記錄你設置的,其他的是不會記錄的。當主庫有數據需要用到binlog恢復時,你就準備哭吧。所以通常在備庫進行過濾選項設置。比如忽略某個庫,同步所有庫,或者同步某一個庫,當然這會浪費帶寬,但是和安全比起來,這點浪費不算什么。有時候安全與性能往往需要我們自己平衡。

還有就是跨庫更新,如果我們在備庫是這樣設置的,比如同步yayun這個庫

replicate_do_db=yayun

主庫記錄如下:

復制代碼

mysql> select *  from t1;
+----+-------+
| id | name  |
+----+-------+
|  1 | yayun |
|  2 | atlas |
|  3 | mysql |
+----+-------+
3 rows in set (0.00 sec)mysql> 

復制代碼

備庫記錄如下:

復制代碼

mysql> select * from t1;
+----+-------+
| id | name  |
+----+-------+
|  1 | yayun |
|  2 | atlas |
|  3 | mysql |
+----+-------+
3 rows in set (0.00 sec)mysql> 

復制代碼

現在我們在主庫插入一條記錄

復制代碼

mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -ADatabase changed
mysql> insert into yayun.t1 (name) values ('good yayun');
Query OK, 1 row affected (0.01 sec)mysql> select  * from yayun.t1;  
+----+------------+
| id | name       |
+----+------------+
|  1 | yayun      |
|  2 | atlas      |
|  3 | mysql      |
|  5 | good yayun |
+----+------------+
4 rows in set (0.00 sec)mysql> 

復制代碼

查看備庫:

復制代碼

mysql> select * from t1;
+----+-------+
| id | name  |
+----+-------+
|  1 | yayun |
|  2 | atlas |
|  3 | mysql |
+----+-------+
3 rows in set (0.00 sec)mysql> 

復制代碼

怎么回事?怎么沒有同步?這就是跨庫更新帶來的問題,比如下面的更新:

use test
insert into yayun.t1 (name) values ('good yayun')

當然你會說哪個2B會這么干啊,呵呵,有時2B還是有的。所以我們還有另外2個過濾復制參數

replicate_wild_do_table
replicate_wild_ignore_table

一個是要同步的表,一個是不同步的表,通常我們可以這樣寫

replicate_wild_do_table=yayun.%

表示同步yayun庫下面的所有表,這樣就解決的跨庫更新的問題。

復制格式的問題

通常推薦使用ROW格式,為什么使用?看看我前面文章MySQL數據恢復和復制對InnoDB鎖機制的影響

不要用Seconds_Behind_Master來衡量MySQL主備的延遲時間?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/535324.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/535324.shtml
英文地址,請注明出處:http://en.pswp.cn/news/535324.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

update和delete操作忘加where條件導致全表更新的處理方法

在數據庫日常維護中,開發人員是最讓人頭痛的,很多時候都會由于SQL語句寫的有問題導致服務器出問題,導致資源耗盡。最危險的操作就是在做DML操作的時候忘加where條件,導致全表更新,這是作為運維或者DBA的我們改如何處理…

Innodb結構

從MySQL5.5版本開始默認使用InnoDB作為引擎,它擅長處理事務,具有自動崩滿恢復的特性,在日常開發中使用非常廣泛,下面是言方的InnoDB引擎美構圖,主要分為內存結構和磁盤結構兩大部分。 內存結構主要包括Buffer Pool、C…

ES備份工具elasticdump

安裝 下載node下載 | Node.js 中文網 tar xvf node-v16.5.0-linux-x64.tar.xz ln -s /app/temp/node-v16.5.0-linux-x64/bin/node /usr/bin/node ln -s /app/temp/node-v16.5.0-linux-x64/bin/npm /usr/bin/npm npm install elasticdump -g npm config get cache npm in…

innodb_flush_method理解【轉】

innodb_flush_method這個參數控制著innodb數據文件及redo log的打開、刷寫模式,對于這個參數,文檔上是這樣描述的: 有三個值:fdatasync(默認),O_DSYNC,O_DIRECT 默認是fdatasync,調用fsync()去…

linux下的/dev/shm/

首先可以看出來/dev/shm是一個設備文件, 可以把/dev/shm看作是系統內存的入口, 可以把它看做是一塊物理存儲設備,一個tmp filesystem, 你可以通過這個設備向內存中讀寫文件, 以加快某些I/O高的操作,比如對一個大型文件頻繁的open, write, read&#xff0…

2021-07-30

1.服務器級別的鎖等待 可以通過show processlist看到等待鎖的線程id,但是無法知道究竟哪個線程持有鎖 可以通過mysqladmin debug 相關等待鎖的線程以及誰持有鎖可以在錯誤日志中找到 2.存儲引擎層的鎖等待則比較麻煩,以下是innodb存儲引擎中鎖等待以及…

getopt設計shell腳本選項

寫shell腳本的時候,通過while、case、shift來設計腳本的命令行選項是一件比較麻煩的事,因為Unix命令行的選項和參數自由度很高,支持短選項和長選項,參數可能是可選的,選項順序可能是無所謂的,等等。 bash下…

percona-toolkit---pt-heartbeat

對于MySQL數據庫主從復制延遲的監控,可以借助percona的有力武器pt-heartbeat來實現。 pt-heartbeat的工作原理通過使用時間戳方式在主庫上更新特定表,然后在從庫上讀取被更新的時間戳然后與本地系統時間對比來得出其延遲。具體流程: 1&…

定時刪除腳本

#!/bin/sh backup_dir/data/xtrabackup DATEdate %Y-%m-%d #DATE_NOWdate %Y-%m-%d.%H%M DATE_NOWdate %Y-%m-%d PATH/usr/local/mysql/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin export PATHbinog保留7天 binlog/data/binlogserver binlog_Rtime7#備…

percona-toolkit--pt-table-checksum

pt-table-checksum 是 Percona-Toolkit的組件之一,用于檢測MySQL主、從庫的數據是否一致。其原理是在主庫執行基于statement的sql語句來生成主庫數據塊的checksum,把相同的sql語句傳遞到從庫執行,并在從庫上計算相同數據塊的checksum&#xf…

Docker容器間網絡通信

自從Docker容器出現以來,容器網絡通信就一直是被關注的焦點,也是生產環境的迫切需求。容器網絡通信又分為兩大方面:單主機容器上的相互通信,和跨主機的容器相互通信。 一、Docker單主機容器通信 基于對net namespace的控制&#…

Docker容器的重啟策略

1. Docker容器的重啟策略 Docker容器的重啟策略是面向生產環境的一個啟動策略,在開發過程中可以忽略該策略。 Docker容器的重啟都是由Docker守護進程完成的,因此與守護進程息息相關。 Docker容器的重啟策略如下: no,默認策略&…

innobackupex實現導出和導入單張表

默認情況下,InnoDB表不能通過直接復制表文件的方式在mysql服務器之間進行移植,即便使用了innodb_file_per_table選項。而使用Xtrabackup工具可以實現此種功能,不過只能"導出"具有.ibd文件的表,也就是說導出表的mysql服務…

xtrabackup工具

(1).備份過程 和innobackupex備份過程不同的是,xtrabackup的備份路徑是由"--target-dir"選項嚴格指定的,如果指定的目錄不存在,它備份的時候不會在target-dir目錄中再創建時間戳子目錄。 [rootxuexi data]# xtrabackup --backup …

mysql數據庫參數

注意:在配置binlog相關變量的時候,相關變量名總是搞混,因為有的是binlog,有的是log_bin,當他們分開的時候,log在前,當它們一起的時候,bin在前。在配置文件中也同樣如此。 log_bin …

oracle命令行安裝

cd /home/oracle/databases/runInstaller -silent -force -showprogress -responseFile /home/oracle/database/db_install.rsp -ignoreSysPrereqs -ignorePrereqdbca -silent -responseFile pwd/dbca.rspnetca -silent -responseFile /home/oracle/databases/netca.rsp

定期刪除數據腳本

#!/bin/sh backup_dir/data/xtrabackup DATEdate %Y-%m-%d #DATE_NOWdate %Y-%m-%d.%H%M DATE_NOWdate %Y-%m-%d PATH/usr/local/mysql/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin export PATH#binog保留7天 binlog/data/binlogserver binlog_Rtime7#備…

定期備份數據庫腳本

#!/bin/bash MasterIp* USERroot PORT3306 PASSWD000000 DATEdate %Y-%m-%d #DATE_NOWdate %Y-%m-%d.%H%M DATE_NOWdate %Y-%m-%d OLDDATEdate %Y-%m-%d -d "30 days ago"  #全表備份 BACKUPDIR/data/mysql_backup/fulltable #單表tb_trcevt備份 datapath/data/mysq…

日志清理腳本

#!/bin/bash#定義日志所在分區當前空間所占比例數(去掉%)。grep -w表示精準匹配,只匹配"/"這個分區 LOG_PARTITION$(which df -h|awk {print $5,$6}|grep -w "/"|cut -d" " -f1|awk -F"%" {print $1}) #定義一周前的日期&a…

k8s二進制安裝

1. 前言 之前文章安裝 kubernetes 集群,都是使用 kubeadm 安裝,然鵝很多公司也采用二進制方式搭建集群。這篇文章主要講解,如何采用二進制包來搭建完整的高可用集群。相比使用 kubeadm 搭建,二進制搭建要繁瑣很多,需要…