十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團隊
量身定制 + 運營維護+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
數(shù)據(jù)備份是數(shù)據(jù)容災的最后一道防線,即便有著兩地三中心的架構,備份也依然重要。如果備份出問題,備份時影響了交易業(yè)務,備份數(shù)據(jù)無法恢復,這些也是企業(yè)難以承受的。所以選擇合適的備份工具尤為重要。
成都創(chuàng)新互聯(lián)公司堅持“要么做到,要么別承諾”的工作理念,服務領域包括:網(wǎng)站設計、成都做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務,滿足客戶于互聯(lián)網(wǎng)時代的貴南網(wǎng)站設計、移動媒體設計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡建設合作伙伴!
每個企業(yè)級數(shù)據(jù)庫都會有配套的備份工具,MEB(MySQL Enterprise Backup)就是MySQL企業(yè)版中非常重要的工具之一,是為企業(yè)級客戶提供的數(shù)據(jù)備份方案。
Xtrabackup一直作為MEB 開源版?zhèn)涮ザ嬖冢瑥腗ySQL 8.0開始情況可能會變得有所不同。
在 MySQL 8.0的Backup Lock、Redo Log Archiving、Page Tracking等新特性的加持下,MEB備份/恢復體驗會更好,目前xtrabackup還不支持這些特性。
MySQL 企業(yè)版還有哪些功能?
特性1:Backup Lock
8.0之前使用xtrabackup或MEB做物理備份,為了保證備份時InnoDB引擎表與其他引擎數(shù)據(jù)文件、及binlog日志的一致性會上全局讀鎖,再拷貝非InnoDB文件,這期間MySQL會變成只讀,數(shù)據(jù)無法寫入。表數(shù)量越多,可能加上時間越長,如果使用的xtrabackup 不小心沒加rsync參數(shù),逐個拷貝frm文件,鎖定時間會更長,對業(yè)務影響較大。
我曾遇到過部署在虛擬機的實例有12000多張表,當時使用的xtrabackup,備份腳本中沒加rsync參數(shù),結果鎖了十幾分鐘,而MEB就沒有這樣的問題。
MySQL 8.0支持輕量級備份鎖 LOCK INSTANCE FOR BACKUP,數(shù)據(jù)字典也重構了由InnoDB存儲。若不創(chuàng)建非InnoDB表,MEB默認使用備份鎖獲取binlog日志一致性位置,并阻止DDL操作,但不影響DML操作。
只有InnoDB表,僅上備份鎖
請點擊輸入圖片描述
若有非InnoDB表,上全局鎖
請點擊輸入圖片描述
特性2:Redo Log Archiving
MEB能做到在線熱備,備份時不影響數(shù)據(jù)庫讀寫,這是利用了InnoDB事務日志,在備份期間持續(xù)監(jiān)視redo log的變化,讀取增量變化,寫入到ibbackup_logfile,也就不需要上鎖來保障備份一致性。(對非InnoDB的文件需要上讀鎖拷貝)
如果備份期間數(shù)據(jù)庫寫入負載特別大,而寫入ibbackup_logfile速度較慢,redo log size也不大,很可能會出現(xiàn)ibbackup_logfile的寫入速度跟不上redo log記錄生成速度,redo log 空間不夠時需要覆寫日志文件,那么來不及寫入ibbackup_logfile的記錄會丟失,導致備份失敗。
MEB 4.1對此做了優(yōu)化,將redo log處理線程拆分成多線程分工合作,提高處理redo log的效率,降低了redo log覆寫造成備份失敗的概率,但redo log新增速度和ibbackup_logfile寫入速度懸殊太大,問題依然會發(fā)生。
MySQL 8.0.17支持了redo log archiving 徹底解決了此問題,備份前設置innodb_redo_log_archive_dirs,指定redo log歸檔目錄。MEB備份時自動開啟日志歸檔,當checkpoint時會將舊記錄歸檔到此目錄,后續(xù)從歸檔文件中讀取redo日志記錄,避免了覆寫可能導致的redo記錄丟失。
請點擊輸入圖片描述
注意:innodb_redo_log_archive_dirs 不能在數(shù)據(jù)目錄下,目錄權限要求是700
特性3:Page Tracking
Page Tracking 是為優(yōu)化增量備份效率,減少不必要的數(shù)據(jù)頁掃描。
增量備份當前有3種掃描模式:
page-track:利用LSN精確跟蹤上次備份之后被修改頁面,僅復制這些頁面,效率最快。
optimistic:掃描上次備份之后被修改的InnoDB 數(shù)據(jù)文件中,找出并拷貝修改的頁面。依賴系統(tǒng)時間,使用存在限制。
full-scan:掃描所有InnoDB數(shù)據(jù)文件,找出并拷貝自上次備份之后修改的頁面,效率最慢
1、利用page-track增量備份,需先安裝備份組件
mysql INSTALL COMPONENT "";
2、在全備前開啟page-track
SELECT mysqlbackup_page_track_set(true);
3、全備之后,做增量備份時指定若滿足page tracking條件,默認會使用page-track模式,否則會使用full-scan模式,也可以指定--incremental=page-track。
mysqlbackup --incremental-backup-dir=backup_incr --trace=3 --incremental=page-track --incremental-base=history:last_full_backup backup
incremental-base有3種選擇
last_backup:基于前一次備份做增備,前一次備份可能是增備,也可能是全備。這種方式全備之間可能會有多個增備,每次增量可能比較小,但恢復時需要逐個合并。
last_full_backup:基于前一次全備做增備。這種方式增備會越往后體積可能越大,但恢復時只需要合并最后一次增量備份。
dir:基于前一次的備份目錄,前一次備份可能是增備,也可能是全備。
測試對比full-scan 和page-track ,在變更頁小于總體50%的情況下 ,備份效率至少能有1倍的速度提升。
page-track 模式 磁盤讀寫均衡,說明讀寫的都是修改頁面。
請點擊輸入圖片描述
full-scan模式 磁盤讀寫差別很大,說明讀了很多未修改的頁面。
請點擊輸入圖片描述
常規(guī)的mysql備份使用命令是 mysqldump命令用法如下,
mysqldump [選項] 數(shù)據(jù)庫名 [表名] 腳本名
或mysqldump [選項] --數(shù)據(jù)庫名 [選項 表名] 腳本名
或mysqldump [選項] --all-databases [選項] 腳本名
例如:
備份所有數(shù)據(jù)庫:
mysqldump -uroot -p --all-databases /backup/mysqldump/all.db
備份指定數(shù)據(jù)庫:
mysqldump -uroot -p test /backup/mysqldump/test.db
備份指定數(shù)據(jù)庫指定表(多個表以空格間隔)
mysqldump -uroot -p mysql db event /backup/mysqldump/2table.db
備份指定數(shù)據(jù)庫排除某些表
mysqldump -uroot -p test --ignore-table=test.t1 --ignore-table=test.t2 /backup/mysqldump/test2.db
還原命令例如:
mysqladmin -uroot -p create db_name
mysql -uroot -p db_name /backup/mysqldump/db_name.db
注:在導入備份數(shù)據(jù)庫前,db_name如果沒有,是需要創(chuàng)建的; 而且與db_name.db中數(shù)據(jù)庫名是一樣的才可以導入。
Mysql數(shù)據(jù)庫的常用備份方法是使用使用實用程序mysqldump, 其命令格式如下
# mysqldump [options] database [tables]
其參數(shù)的含義為:
options:代表mysqldump的選項,通過mysqldump –help可以查到。
database: 代表將要備份的數(shù)據(jù)庫
tables: 代表將要備份的表,如果不指定任何表,則備份整個數(shù)據(jù)庫。
使用 mysqldump進行備份非常簡單,如果要備份數(shù)據(jù)庫” phpbb_db_backup ”,使用命令:
#mysqldump –u -p phpbb_db_backup /usr/backups/mysql/ phpbb_db_backup.2005.5.6
還可以使用gzip命令對備份文件進行壓縮:
#mysqldump phpbb_db_backup | gzip /usr/backups/mysql/ phpbb_db_backup.2005.5.6。gz
恢復數(shù)據(jù)使用命令:
#mysql –u -p phpbb_db_backup /usr/backups/mysql/phpbb_db_backup.2005
MySQL 主從一直是面試???,里面的知識點雖然基礎,但是能回答全的同學不多。
比如樓哥之前面試小米,就被問到過主從復制的原理,以及主從延遲的解決方案,因為回答的非常不錯,給面試官留下非常好的印象。你之前面試,有遇到過哪些 MySQL 主從的問題呢?
所謂 MySQL 主從,就是建立兩個完全一樣的數(shù)據(jù)庫,一個是主庫,一個是從庫, 主庫對外提供讀寫的操作,從庫對外提供讀的操作 ,下面是一主一從模式:
對于數(shù)據(jù)庫單機部署,在 4 核 8G 的機器上運行 MySQL 5.7 時,大概可以支撐 500 的 TPS 和 10000 的 QPS, 當遇到一些活動時,查詢流量驟然,就需要進行主從分離。
大部分系統(tǒng)的訪問模型是讀多寫少,讀寫請求量的差距可能達到幾個數(shù)量級,所以我們可以通過一主多從的方式, 主庫只負責寫入和部分核心邏輯的查詢,多個從庫只負責查詢,提升查詢性能,降低主庫壓力。
MySQL 主從還能做到服務高可用,當主庫宕機時,從庫可以切成主庫,保證服務的高可用,然后主庫也可以做數(shù)據(jù)的容災備份。
整體場景總結如下:
MySQL 的主從復制是依賴于 binlog 的,也就是記錄 MySQL 上的所有變化并以二進制形式保存在磁盤上二進制日志文件。
主從復制就是將 binlog 中的數(shù)據(jù)從主庫傳輸?shù)綇膸焐?,一般這個過程是異步的,即主庫上的操作不會等待 binlog 同步的完成。
詳細流程如下:
當主庫和從庫數(shù)據(jù)同步時,突然中斷怎么辦?因為主庫與從庫之間維持了一個長鏈接,主庫內(nèi)部有一個線程,專門服務于從庫的這個長鏈接的。
對于下面的情況,假如主庫執(zhí)行如下 SQL,其中 a 和 create_time 都是索引:
我們知道,數(shù)據(jù)選擇了 a 索引和選擇 create_time 索引,最后 limit 1 出來的數(shù)據(jù)一般是不一樣的。
所以就會存在這種情況:在 binlog = statement 格式時,主庫在執(zhí)行這條 SQL 時,使用的是索引 a,而從庫在執(zhí)行這條 SQL 時,使用了索引 create_time,最后主從數(shù)據(jù)不一致了。
那么我們改如何解決呢?
可以把 binlog 格式修改為 row,row 格式的 binlog 日志記錄的不是 SQL 原文,而是兩個 event:Table_map 和 Delete_rows。
Table_map event 說明要操作的表,Delete_rows event用于定義要刪除的行為,記錄刪除的具體行數(shù)。 row 格式的 binlog 記錄的就是要刪除的主鍵 ID 信息,因此不會出現(xiàn)主從不一致的問題。
但是如果 SQL 刪除 10 萬行數(shù)據(jù),使用 row 格式就會很占空間的,10 萬條數(shù)據(jù)都在 binlog 里面,寫 binlog 的時候也很耗 IO。但是 statement 格式的 binlog 可能會導致數(shù)據(jù)不一致。
設計 MySQL 的大叔想了一個折中的方案,mixed 格式的 binlog,其實就是 row 和 statement 格式混合使用, 當 MySQL 判斷可能數(shù)據(jù)不一致時,就用 row 格式,否則使用就用 statement 格式。
有時候我們遇到從數(shù)據(jù)庫中獲取不到信息的詭異問題時,會糾結于代碼中是否有一些邏輯會把之前寫入的內(nèi)容刪除,但是你又會發(fā)現(xiàn),過了一段時間再去查詢時又可以讀到數(shù)據(jù)了,這基本上就是主從延遲在作怪。
主從延遲,其實就是“從庫回放” 完成的時間,與 “主庫寫 binlog” 完成時間的差值, 會導致從庫查詢的數(shù)據(jù),和主庫的不一致 。
談到 MySQL 數(shù)據(jù)庫主從同步延遲原理,得從 MySQL 的主從復制原理說起:
總結一下主從延遲的主要原因 :主從延遲主要是出現(xiàn)在 “relay log 回放” 這一步,當主庫的 TPS 并發(fā)較高,產(chǎn)生的 DDL 數(shù)量超過從庫一個 SQL 線程所能承受的范圍,那么延時就產(chǎn)生了,當然還有就是可能與從庫的大型 query 語句產(chǎn)生了鎖等待。
我們一般會把從庫落后的時間作為一個重點的數(shù)據(jù)庫指標做監(jiān)控和報警,正常的時間是在毫秒級別,一旦落后的時間達到了秒級別就需要告警了。
解決該問題的方法,除了縮短主從延遲的時間,還有一些其它的方法,基本原理都是盡量不查詢從庫。
具體解決方案如下:
在實際應用場景中,對于一些非常核心的場景,比如庫存,支付訂單等,需要直接查詢從庫,其它非核心場景,就不要去查主庫了。
兩臺機器 A 和 B,A 為主庫,負責讀寫,B 為從庫,負責讀數(shù)據(jù)。
如果 A 庫發(fā)生故障,B 庫成為主庫負責讀寫,修復故障后,A 成為從庫,主庫 B 同步數(shù)據(jù)到從庫 A。
一臺主庫多臺從庫,A 為主庫,負責讀寫,B、C、D為從庫,負責讀數(shù)據(jù)。
如果 A 庫發(fā)生故障,B 庫成為主庫負責讀寫,C、D負責讀,修復故障后,A 也成為從庫,主庫 B 同步數(shù)據(jù)到從庫 A。
目前mysql5.6版本也未能支持CHANGE MASTER TO 多用戶;而且只基于數(shù)據(jù)庫同步,不支持單個實例多線程同步