使用Xtrabackup對MySQL作主從複製

使用Xtrabackup對MySQL作主從複製

說明

xtrabackup

mysqldump對於導出10G如下的數據庫或幾個表,仍是適用的,並且更快捷。一旦數據量達到100-500G,不管是對原庫的壓力仍是導出的性能,mysqldump就力不從心了。Percona-Xtrabackup備份工具,是實現MySQL在線熱備工做的不二選擇,可進行全量、增量、單表備份和還原。(但當數據量更大時,可能須要考慮分庫分表,或使用 LVM 快照來加快備份速度了)。
2.2版本xtrabackup能對InnoDB和XtraDB存儲引擎的數據庫非阻塞地備份,innobackupex經過perl封裝了一層xtrabackup,對MyISAM的備份經過加表讀鎖的方式實現。2.3版本xtrabackup命令直接支持MyISAM引擎。mysql

Xtrabackup優點:

  • 無需中止數據庫進行InnoDB熱備
  • 增量備份MySQL
  • 流壓縮到傳輸到其它服務器
  • 能比較容易地建立主從同步
  • 備份MySQL時不會增大服務器負載

replication

爲何要作主從複製?

我想這是要在實施之前要想清楚的問題。是爲了實現讀寫分離,減輕主庫負載或數據分析? 爲了數據安全,作備份恢復?主從切換作高可用?
大部分場景下,以上三個問號一主一從都可以解決,並且任何生產環境都建議你至少要有一個從庫,假如你的讀操做壓力特別大,甚至要作一主多從,還能夠不一樣的slave扮演不一樣的角色,例如使用不一樣的索引,或者不一樣的存儲引擎,或使用一個小內存server作slave只用於備份。(固然slave太多也會對master的負載和網絡帶寬形成壓力,此時能夠考慮級聯複製,即 A->B->C )。
還有須要考慮的是,一主一從,一旦作了主從切換,不經過其它HA(High Available,是雙機集羣系統簡稱,指高可用性集羣,是保證業務連續性的有效解決方案,通常有兩個或兩個以上的節點,且分爲活動節點及備用節點。)手段干預的話,業務訪問的仍是原IP,並且原主庫很容易就做廢了。因而「主-主」複製就產生了,憑藉各自不一樣的server-id,能夠避免「A的變化同步到B,B應用變化又同步到A」這樣循環複製的問題。但建議是,主主複製,其中一個主庫強制設置爲只讀,主從切換後架構依然是可用的。
複製過程是slave主動向master拉取,而不是master去推的,因此理想狀況下作搭建主從時不須要master作出任何改變甚至停服,slave失敗也不影響主庫。sql

複製類型

  • 基於語句的複製:STATEMENT
    在主服務器上執行的SQL語句,在從服務器上執行一樣的語句,有可能會因爲SQL執行上下文環境不一樣而是數據不一致,例如調用NOW()函數。MySQL在5.7.7之前默認採用基於語句的複製,在 5.7.7 及之後版本默認改用 row-based(基於行的)。
  • 基於行的複製:ROW
    把改變的內容複製過去,而不是把命令在從服務器上執行一遍。從mysql5.0開始支持,可以嚴格保證數據徹底一致,但此時用mysqlbinlog去分析日誌就沒啥意義。由於任何一條update語句,都會把涉及到的行數據所有set值,因此binlog文件會比較大。(遇到的一個坑是,遷移時,從庫改正了字段默認值定義,但數據在主庫更改後,即便產生的新數據默認值是正確的,但基於行的複製依然用不正確的值字段所有更新了)
  • 混合類型的複製: MIXED
    默認採用基於語句的複製,一旦發現基於語句的沒法精確的複製時,就會採用基於行的複製。

mysql系統庫mysql庫裏面表的日誌記錄格式須要說明:在經過如INSERT、UPDATE、DELETE、TRUNCATE等方式直接修改數據的語句,使用binlog_format指定的方式記錄,但使用GRANT、ALTER、CREATE、RENAME等改動的mysql庫裏數據的,會強制使用statement-based方式記錄binlog。
能夠在線修改二進制日誌類型,如SET SESSION binlog_format=MIXED;,須要SUPER權限。數據庫

複製類型還能夠分爲:異步複製和半同步複製。
一般沒說明指的都是異步,即主庫執行完Commit後,在主庫寫入Binlog日誌後便可成功返回客戶端,無需等等Binlog日誌傳送給從庫,一旦主庫宕機,有可能會丟失日誌。而半同步複製,是等待其中一個從庫也接收到Binlog事務併成功寫入Relay Log以後,才返回Commit操做成功給客戶端;如此半同步就保證了事務成功提交後至少有兩份日誌記錄,一份在主庫Binlog上,另外一份在從庫的Relay Log上,從而進一步保證數據完整性;半同步複製很大程度取決於主從網絡RTT(往返時延),以插件 semisync_master/semisync_slave 形式存在。vim

原理

  • master將改變記錄到二進制日誌(binary log)中(這些記錄叫作二進制日誌事件,binary log events);
  • slave將master的binary log events拷貝到它的中繼日誌(relay log);
  • slave重作中繼日誌中的事件,將改變反映它本身的數據。

mark

  • 該過程的第一部分就是master記錄二進制日誌。在每一個事務更新數據完成以前,master在二進制日誌記錄這些改變。MySQL將事務串行的寫入二進制日誌,即便事務中的語句都是交叉執行的。在事件寫入二進制日誌完成後,master通知存儲引擎提交事務。
  • 下一步將master的binary log拷貝到它本身的中繼日誌。首先,slave開始一個工做線程——I/O線程。I/O線程在master上打開一個普通的鏈接,請求從指定日誌文件的指定位置以後的日誌內容,而後開始binlog dump process。Binlog dump process從master的二進制日誌中讀取事件,若是已經跟上master,它會睡眠並等待master產生新的事件。I/O線程將這些事件寫入中繼日誌。
  • SQL slave thread(SQL從線程)處理該過程的最後一步。SQL線程從中繼日誌讀取事件,並重放其中的事件而更新slave的數據,使其與master中的數據一致。只要該線程與I/O線程保持一致,中繼日誌一般會位於OS的緩存中,因此中繼日誌的開銷很小。

此外,在master中也有一個工做線程:和其它MySQL的鏈接同樣,slave在master中打開一個鏈接也會使得master開始一個線程。複製過程有一個很重要的限制——複製在slave上是串行化的,也就是說master上的並行更新操做不能在slave上並行操做。緩存

補充

  • mysql 5.7開始加入了多源複製,這個特性對同時有不少個mysql實例是頗有用的,阿里雲RDS(遷移)實現了相似的方式。
  • 從MySQL 5.6.2開始,mysql binlog支持checksum校驗,而且5.6.6默認啓用(CRC32 ),這對本身模擬實現mysql複製的場景有影響。

CRC32(Cyclic Redundancy Check)校驗實用程序庫在數據存儲和數據通信領域,爲了保證數據的正確,就不得不採用檢錯的手段。在諸多檢錯手段中,CRC是最著名的一種。CRC的全稱是循環冗餘校驗。 安全

 

主從配置 bash

步驟:主從版本一致—>主庫受權複製賬號—>確保開啓binlog及主從server_id惟一—>xtrabackup恢復到從庫—>記錄xtrabackup_binlog_info中binlog名稱及偏移量—>從庫change master to —>slave start—>檢查兩個yes。服務器

主庫配置

[root@root-01 ~]# vim /etc/my.cnf
……
server-id=179
#自定義
log_bin=root-01
#指定log前綴
[root@ root-01 ~]# /etc/init.d/mysqld restart
Shutting down MySQL...... SUCCESS! 
Starting MySQL.................. SUCCESS!

建立複製帳號

在主庫操做:網絡

mysql>  GRANT REPLICATION SLAVE ON *.* TO 'rpl'@'192.168.2.%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)

使用innobackupex備份(恢復)數據

分別在主、從服務器安裝innobackupex工具:架構

安裝innobackupex工具:
[root@root-01 ~]#  rpm -ivh  http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm
[root@root-01 ~]#   yum install -y percona-xtrabackup

全量備份

在主服務器操做!
這裏假設比較簡單的狀況:全量備份,全量恢復,不涉及增量。

建立備份用戶:
[root@root-01 ~]# mysql -uroot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 212
Server version: 5.6.35-log MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> grant RELOAD, LOCK TABLES, REPLICATION CLIENT on *.* to 'bakuser'@'localhost' identified by '123456';
Query OK, 0 rows affected (0.02 sec)


mysql> grant RELOAD, LOCK TABLES, REPLICATION CLIENT on *.* to 'bakuser'@'localhost' identified by '123456';
Query OK, 0 rows affected (0.00 sec)
#該用戶只須要有備份權限便可,因此在建立用戶時只授予其部分權限

mysql> flush privileges;
Query OK, 0 rows affected (0.04 sec)
#刷新

mysql> quit
Bye


建立備份文件存放目錄:
[root@root-01 ~]# mkdir /data/backup

備份:
[root@root-01 ~]# innobackupex --defaults-file=/etc/my.cnf --user=bakuser --password='123456' -S /tmp/mysql.sock /data/backup


打包備份文件:
[root@root-01 ~]# cd /data/backup/
[root@root-01 backup]# ls
2017-10-01_11-51-05

[root@root-01 backup]# tar -cvf 2017-10-01_11-51-05.tar 2017-10-01_11-51-05

默認會以當天 日期+時間 戳命名備份目錄(2017-10-01_11-51-05),通常會對它進行tar壓縮,因爲tar只能單進程,因此每每這個壓縮過程會比備份過程耗時2倍還多。拷貝到須要恢復(作從庫)的目錄。若是手頭有一份未壓縮的全備數據,要在另外一臺恢復,其實還不如直接 rsync 過來,將近400G的數據壓縮與解壓縮過程特別漫長

 

使用innobackupex恢復數據

在從服務器操做:

關閉Mysql:
[root@root-02 ~]# /etc/init.d/mysql stop
Shutting down MySQL.. SUCCESS! 

把/data/mysql目錄拷貝並重命名
[root@root-02 data]# cp -vrp mysql mysql.bak

把/data/mysql目錄清空
[root@root-02 data]# rm -vfr mysql/*

建立備份文件存放目錄:
[root@root-02 ~]# mkdir /data/backup

拷貝主庫中的備份數據到從服務器:
[root@root-02 ~]# scp 192.168.2.115:/data/backup/2017-10-01_11-51-05.tar /data/backup
The authenticity of host '192.168.2.115 (192.168.2.115)' can't be established.
ECDSA key fingerprint is bd:fd:56:cf:07:80:0d:a6:9c:38:00:be:33:1f:f5:7a.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.2.115' (ECDSA) to the list of known hosts.
root@192.168.2.115's password: 
2017-10-01_11-51-05.tar         

解壓備份:
[root@root-02 ~]# cd /data/backup/

[root@root-02 backup]# tar -xvf 2017-10-01_11-51-05.tar 

開始恢復:
[root@root-02 ~]# innobackupex  --apply-log /data/backup/2017-10-01_11-51-05
[root@root-02 ~]# innobackupex --defaults-file=/etc/my.cnf --copy-back /data/backup/2017-10-01_11-51-05
[root@root-02 ~]# chown -R mysql:mysql /data/mysql
說明:主庫中的數據備份到了從庫中.


配置從庫

[root@root-02 ~]# cat /etc/my.cnf

[mysqld]
datadir=/data/mysql
socket=/tmp/mysql.sock
server-id=116

注意:

  • 從庫的server-id必定不能和主庫的同樣,不然會出現以下錯誤:Slave: received end packet FROM server, apparent master shutdown.
  • 從庫通常做爲只讀庫使用,因此爲安全起見,設置只讀 set global read_only=1;能夠在從服務器的my.cnf里加入read-only參數來實現這一點,惟一須要注意的一點事read-only僅對沒有super權限的用戶有效。因此最好覈對一下鏈接從服務器的用戶,確保其沒有super權限。(本機具備super權限,因此不作該配置)。
  • 關於從庫的事件
    MYSQL Replication 能夠很好的達到你的預期:從庫的事件不會本身去執行,主庫會把event執行的結果直接同步。在statement模式下,複製的是 event BODY 裏的SQL,在row模式下是主庫事件執行完成後影響的行精確複製。
    從庫event_scheduler參數是被忽略的,而且每一個event 狀態會是SLAVESIDE_DISABLED,但CREATE/ALTER EVENT等操做語句是會複製。主從切換後,從庫事件狀態會變成ENABLE。
  • 參數調整
    從庫是不容許寫入的,不然數據就不一致了。從庫實例的配置能夠不要主庫那麼高,好比原16G的buffer pool,根據用途,從庫能夠設到4-8G(當時前提是未來你也不打算把它切換爲主庫用)。 相應的,read_buffer_size,sort_buffer_size, query_cache_size 這些讀相關參數能夠略微增大。固然我通常都懶得去改。
  • skip-slave-start
    主從建立完成後,默認狀況下次啓動從庫,會自動啓動複製進程,通常這也正是咱們須要的,但在維護階段時你可能不想從庫啓動後當即開始複製,--skip-slave-start選項能夠幫到你。
  • log-slave-updates
    正常狀況從庫是不須要寫回放日誌產生的binlog,無形中增長服務器壓力。但若是你想要實現級聯複製即A->B->C,B同時是A的從庫,也是C的主庫,就須要開啓 log-bin 和 log-slave-updates 
  • sync_binlog
    For the greatest possible durability and consistency in a replication setup using InnoDB with transactions, you should use innodb_flush_log_at_trx_commit=1 and sync_binlog=1 in the master my.cnf file.
    上面的話同時也意味着性能最低。能夠在這埋點,假如出現慢的狀況,把兩參數調成2。
  • 過濾表mysql-replica-filter

啓動從庫

[root@root-02 ~]# /etc/init.d/mysql start
Starting MySQL. SUCCESS! 


change master  (在從庫操做)

mysql> change master to master_host='192.168.2.115',master_port=3306,master_user='rpl',master_password='123456',master_log_file='root-01.000001',master_log_pos=52279;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

說明:上面的master_log_file和master_log_pos便是輸出的值,也能夠在新的數據目錄下xtrabackup_binlog_info找到信息。


開始同步 (在從庫操做)

mysql>  start slave;
Query OK, 0 rows affected (0.01 sec)

mysql> show slave status\G
.................................
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
 .................................


說明:執行show slave status\G命令,出現「Slave_IO_Running: Yes;Slave_SQL_Running: Yes」信息,說明主從同步配置完成


解釋

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.2.115
                  Master_User: rpl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: root-01.000001
          Read_Master_Log_Pos: 374291
               Relay_Log_File: root-02-relay-bin.000002
                Relay_Log_Pos: 322293
        Relay_Master_Log_File: root-01.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

Master_Log_File: I/O線程當前正在讀取的主服務器二進制日誌文件的名稱
Read_Master_Log_Pos:本機I/O線程讀取主服務器二進制日誌位置
上面2各值,與在主庫執行show master status;看到的值若是基本接近,說明從庫IO線程已經遇上了主庫的binlog

Relay_Master_Log_File: 由SQL線程執行的包含多數近期事件的主服務器二進制日誌文件的名稱
Exec_Master_Log_Pos: SQL線程執行來自master的二進制日誌最後一個事件位置
與上面的Relay_Master_Log_File一塊兒,同Master_Log_File、Read_Master_Log_Pos比較,能看到SQL線程是否已經遇上從庫本地的IO線程

Slave_IO_Running:I/O線程是否啓動併成功鏈接到主服務器上
通常和下面的Slave_IO_Running和Seconds_Behind_Master一塊兒監控主從健康狀態

Slave_SQL_Running:SQL線程是否啓動 Seconds_Behind_Master: 從屬服務器「落後」多少秒 官網的解釋是:The number of seconds that the slave SQL thread is behind processing the master binary log。可是當 SBM 爲 0 時也不表明必定沒有延遲,由於可能由於網絡慢的緣故,從庫的IO線程傳輸binlog太慢,它的SQL線程應用日誌很容易就遇上relay log,但實際主庫產生的binlog比傳輸的快,就會形成爲0的假象. 有時你反覆status會發現 Seconds_Behind_Master 的值在0與一個很大的數之間波動,有多是主庫上執行了一個很是大的event,沒執行完畢的時候從庫SBM顯示爲0,event執行完成並傳輸完binlog後,就會顯示SBM很是巨大。(我在從機房遷移mysql到阿里雲上部分庫老出現這種狀況,應該跟網絡和大event都有關係)。 另外,relay log 中event記錄的時間戳是主庫上的時間戳,而SQL thread的時間戳是從庫上的,若是主庫和從庫的時間誤差較大,那麼這個SBM的意義就基本不存在了。

相關文章
相關標籤/搜索