1、二進制日志
二進制日志記錄了數據庫的所有改變,使得任何slave都可以執行相同的更新。一般來說,開啟二進制日志大概會有1%的性能損耗,它有兩個重要的使用場景:
(1)備份:在某個時間點t作了一次備份,然后利用binary log記錄從這個時間點t后的所有對數據庫的改動,然后下一次還原的時候,利用時間點t的備份文件和這個binary log文件,就可以將數據還原至最新時點。
(2)復制:在master端開啟binary log后,binary log記錄所有數據庫的改動,然后slave端獲得這個binary log文件內容,就可以在slave端進行同樣的操作,使master和slave保持一致。
Tips:
(1) 二進制日志按master上的提交順序記錄事務;
(2) select語句一般不會被記錄,因為它對數據庫不產生變動;
(3)那些尚沒有但是可能改變數據庫的語句也會記錄下來,如drop table if exists 或create table if not exists,以及那些不匹配任何行的語句,如帶有where條件的delete和update語句。
2、MySQL 備份
2.1 備份類型
(1)按備份操作方式:
備份方式 |
優點 | 缺點 |
邏輯備份 | 1. 邏輯備份是可以用編譯器或像grep和sed之類的命令查看和操作的普通文件; 2. 恢復簡單,非常靈活; 3. 與存儲引擎無關。 |
1. 還原時需要mysql加載和解釋語句,轉化為存儲格式,並重建索引,所以會比較慢; 2. 無法保證導出后再還原出來的一定是同樣的數據。浮點數、軟件BUG等都會導致問題; 3. 必須由數據庫服務器完成生成邏輯備份的工作,因此要使用更多的CPU周期。 |
物理備份 |
1. 基於文件的物理備份,只需要將需要的文件復制到其他地方即可完成備份; 2. 恢復更簡單; 3. 恢復快,因為MySQL服務器不需要執行任何SQL或構建索引。 |
1. InnoDB的原始文件通常比相應的邏輯備份要大得多; 2. 物理備份不總是可以跨平台、操作系統及MySQL版本。文件名大小寫敏感和浮點格式可能會遇到麻煩。 |
(2)按是否備份全部數據:
完全備份
增量備份
差異備份
一般情況下,根據備份策略組合使用:完全+增量;完全+差異
2.2 常用備份工具
2.2.1 mysqldump
mysqldump作為重要的MySQL備份工具,功能相當強大。備份參數、恢復策略,需要仔細研究。
(1)基本語法
備份單個數據庫或單個數據庫中的指定表:
mysqldump [OPTIONS] database [tb1] [tb2]…
備份多個數據庫:
mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
備份所有數據庫:
mysqldump [OPTIONS] --all-databases [OPTIONS]
(2)選項[OPTIONS]說明
--default-character-set=charset
指定導出數據時采用何種字符集,如果數據表不是采用默認的 latin1 字符集的話,那么導出時必須指定該選項,否則再次導入數據后將產生亂碼問題。
--lock-all-tables,-x
在開始導出之前,提交請求鎖定所有數據庫中的所有表,以保證數據的一致性。這是一個全局讀鎖,並且自動關閉 --single-transaction 和 --lock-tables 選項。
--lock-tables
和 --lock-all-tables 類似,不過是鎖定當前導出的數據表,而不是鎖定全部庫下的表。本選項只適用於 MyISAM 表,如果是 Innodb 表可以用 --single-transaction 選項。
--no-create-info,-t
只導出數據,而不添加 CREATE TABLE 語句。
--no-data, -d
只導出數據庫表結構,不導出任何數據。
--opt
這只是一個快捷選項,等同於同時添加 --add-drop-tables --add-locking --create-option --disable-keys --extended-insert --lock-tables --quick --set-charset 選項。本選項能讓 mysqldump 很快的導出數據,並且導出的數據能很快導回。該選項默認開啟,但可以用 --skip-opt 禁用。注意,如果運行 mysqldump 沒有指定 --quick 或 --opt 選項,則會將整個結果集放在內存中。如果導出大數據庫的話可能會出現問題。
--quick,-q
該選項在導出大表時很有用,它強制 mysqldump 從服務器查詢取得記錄直接輸出而不是取得所有記錄后將它們緩存到內存中。
--routines,-R
導出存儲過程以及自定義函數。
--single-transaction
該選項在導出數據之前提交一個 BEGIN SQL語句,BEGIN 不會阻塞任何應用程序且能保證導出時數據庫的一致性狀態。它只適用於事務表,例如 InnoDB 和 BDB。
本選項和 --lock-tables 選項是互斥的,因為 LOCK TABLES 會使任何掛起的事務隱含提交。
要想導出大表的話,應結合使用 --quick 選項。
--triggers
同時導出觸發器。該選項默認啟用,用 --skip-triggers 禁用它。
(3)注意事項:
以下是使用mysqldump進行數據遷移時,需要注意的一些事項:
a. 表結構備份和數據備份最好分開來做
b. 在進行表結構備份的時候,記得加上--add-drop-database=false和--add-drop-table=false,以免在進行增量恢復時,覆蓋已經存在的數據;如若需要全量恢復,可以先手工drop database或者drop table,再使用表結構備份腳本來恢復表結構
c. innodb要想維持數據一致性,加上--single-transaction,這個參數不會阻塞讀寫
d. 備份blob數據,需要加上--hex-blob,否則恢復的時候可能會報錯
e. 如果想要進行增量數據恢復,那么備份的時候最好加上--add-locks。否則在恢復過程中,表將無法進行讀寫。
f. 備份完成之后,tail -n 1 backup_file。成功的備份會顯示如下信息“-- Dump completed on 2014-04-06 10:40:32”
2.2.2 mysqlbinlog
(1)基本語法
mysqlbinlog [options] log-files
(2)常用[OPTIONS]說明
--start-position:開始位置
--stop-position:結束位置
--start-date 'yyyy-mm-dd hh:mm:ss':開始時間
--stop-date 'yyyy-mm-dd hh:mm:ss' :結束時間
在時間點17:17:24,刪除了數據庫中的幾條記錄,可以通過mysqlbinlog進行恢復。
基於時間點的恢復:
mysqlbinlog --stop-date="2014-04-07 17:17:24" mysql-bin.000001|mysql -uroot -h127.0.0.1
基於位置的恢復:
mysqlbinlog --stop-position="793" mysql-bin.000001|mysql -uroot -h127.0.0.1
2.2.3 Xtrabackup
Xtrabackup是由percona提供的mysql數據庫備份工具,據官方介紹,這也是世界上惟一一款開源的能夠對innodb和xtradb數據庫進行熱備的工具。特點:
(1)備份過程快速、可靠;
(2)備份過程不會打斷正在執行的事務;
(3)能夠基於壓縮等功能節約磁盤空間和流量;
(4)自動實現備份檢驗;
(5)還原速度快;
3、MySQL復制
3.1 復制過程
總的來說,復制有三個步驟:
(1)在主庫上把數據更改記錄到二進制日志中;
(2)備庫將主庫的二進制日志復制到其本地的中繼日志中;
首先,備庫會啟動一個工作線程,稱為I/O線程,I/O線程會建立一個到主庫的TCP/IP連接;然后在主庫上啟動一個特殊的二進制轉儲線程(binlog dump,該線程沒有對應的SQL語句),這個二進制轉儲線程會讀取主庫上二進制日志中的事件。如果該線程追趕上了主庫,它將進入睡眠狀態,直到主庫發送信號量通知有新的事件產生時才會被喚醒,備庫I/O線程會將接收到的事件記錄到中繼日志中。
(3)備庫讀取中繼日志中的事件,將其重放到備庫數據之上。
當SQL線程追趕上I/O線程時,中繼日志通常已經在系統緩存中,所以中繼日志開銷很低。SQL線程執行的事件也可以通過配置選項來決定是否寫入其自己的二進制日志中。
架構的優點:實現了獲取事件和重發事件的解耦,允許這兩個過程異步進行。I/O線程能夠獨立於SQL線程之外工作。
缺點:主庫上並發運行的查詢在備庫上只能串行化執行,因為只有一個SQL線程來重放中繼日志的事件。這是很多工作負載的瓶頸所在。
3.2 配置復制
創建復制賬號
GRANT REPLICATION SLAVE ON *.* TO 'rep'@'10.250.7.50' IDENTIFIED BY'rep123';
配置主庫
對master進行配置,包括打開二進制日志,指定唯一的servr ID。例如,在配置文件加入如下值:
重啟master,運行SHOW MASTER STATUS
配置備庫
備庫在my.cnf中增加類似的配置,如下:
server_id是必須且唯一的。slave沒有必要開啟二進制日志,但是在一些情況下,必須設置,例如,如果slave為其它slave的master,必須設置bin_log;
relay_log指定中繼日志的位置和命名;
log_slave_updates表示允許備庫將其重放的事件也記錄到自身的二進制日志中。
啟動復制
告訴備庫如何連接到主庫並重放其二進制日志。
mysql> change master to master_host='10.250.7.60',master_user='rep',master_password='rep123',master_log_file='mysql-bin.000001',master_log_pos=107;
mysql> start salve;
運行SHOW SLAVE STATUS查看輸出結果:
3.3 復制模式
復制模式 |
優點 |
缺點 |
Statement |
1. 語句的方式執行復制過程基本就是執行SQL語句,這意味着所有在服務器上發生的變更都以一種容易理解的方式運行,出問題時可以很好的定位; 2. 不需要記錄每一行數據的變化,減少了 binlog 日志量,節省 I/O 以及存儲資源,提高性能。 |
1. 對於觸發器或者存儲過程,存在大量bug; 2. 很多情況下無法正確復制 |
Row |
1. binlog會非常清楚的記錄下每一行數據修改的細節,非常容易理解; 2. 幾乎沒有基於行的復制模式無法處理的場景,對於所有的SQL構造、觸發器、存儲過程都能正確執行。 |
1. 會產生大量的日志內容 2. 難以定位問題 3. 難以進行時間點恢復 |
Mixed |
默認情況下使用基於語句的復制方式,如果發現語句無法被正確的復制,就切換成基於行的復制模式。 |
3.4 復制過濾
復制過濾可以讓你只復制服務器中的一部分數據,有兩種復制過濾:在master上過濾二進制日志中的事件;在slave上過濾中繼日志中的事件。如下:
3.5 發送復制事件到其它slave
當設置log_slave_updates時,你可以讓slave扮演其它slave的master。此時,slave把SQL線程執行的事件寫進行自己的二進制日志(binary log),然后,它的slave可以獲取這些事件並執行它。