專職DBA-MySQL備份恢復 DBA在數據庫備份恢復工做職責:設計備份策略 (1).數據量:小於100G、100G-1TB、大於1TB (2).備份工具 mysqldump (MDP) xtrabackup(XBK) MEB select ... from ... into outfile ... (3).備份時間:23:00 23:59 (4).週期頻率:天天、每週、每個月 (5).備份方式 全備 (full) : 某個時刻總的數據量。 增量 (inc) : 老是針對前一天的變化備份。 差別 (dif) : 老是針對最近一次全備變化備份 inc和dif的優缺點: inc 優勢:備份數據量少,快。 缺點:恢復時,須要依賴全部過程備份。 dif 優勢:恢復時,全備+1個差別。 缺點:備份數據量較大,較慢。 (6).備份對象:數據庫、表、binlog日誌 (7).備份腳本 (8).備份檢查 備份存在性:日誌,文件,備份集 備份空間夠用否 備份可用性:文件內容,備份集完整性。 (9).按期在測試庫恢復演練:一季度、半年。 (10).數據故障恢復 物理故障:磁盤,raid,FS,數據文件,rm,dd等等。 邏輯故障:drop,delete,truncate,update等等。 經過現有備份,可以將數據庫恢復到故障以前的時間點。 (11).遷移:停機時間、回退方案 同構:低版本-->高版本 異構: windows ----> Linux Oracle ----> MySQL MySQL ----> MongoDB MySQL 上雲 Oracle 自愈,自治 備份類型 1.熱備:InnoDB支持,在業務不中止的時候備份,幾乎不鎖表,對業務影響較小。 2.溫備:鎖表備份,只能查詢不能作變動(MyISAM),影響到寫入操做。 3.冷備:停業務備份,全部查詢變動都作不了。 備份方式及工具介紹 1.邏輯備份工具 mysqldump(MDP) : full+binlog mysqlbinlog mydumper 2.物理備份工具 基於磁盤數據文件備份 xtrabackup(XBK) : Percona第三方 : full+inc+binlog,full+binlog MySQL Enterprise Backup(MEB) : MySQL官方 邏輯備份和物理備份的比較 mysqldump 優勢: 1.不須要下載安裝。 2.備份出來的是SQL,文本格式,可讀性高,便於備份處理。 3.壓縮比較高,節省備份的磁盤空間。 缺點: 1.依賴於數據庫引擎,須要從磁盤把數據讀出。而後轉換成SQL進行轉儲,比較耗費資源,數據量大的話效率極低。 建議:100G之內的數據量級,可使用mysqldump 超過TB以上,咱們也可能選擇的是mysqldump,配合分佈式的系統 1EB=1024PB=1000000TB xtrabackup 優勢: 1.相似於直接cp數據文件,不須要管邏輯結構,相對來講性能較高。 缺點: 1.可讀性差. 2.壓縮比低,須要更多磁盤空間。 建議:>100G<TB 備份策略 備份方式: 全備:全庫備份,備份全部數據。 增量:備份變化的數據。 邏輯備份:mysqldump+mysqlbinlog 物理備份:xtrabackup_full+xtrabackup_incr+binlog 或者xtrabackup_full+binlog 備份週期:根據數據量設計備份週期。好比:週日全備,周1-周6增量。 [root@db01 ~]# mysqld --defaults-file=/data/mysql/3306/my.cnf & [root@db01 ~]# ps -ef | grep mysql [root@db01 ~]# netstat -lnp | grep mysql [root@db01 ~]# mkdir -p /backup 備份工具使用-mysqldump mysqldump邏輯備份的客戶端工具,備份的是SQL語句。 備份過程:將數據--調取到臨時表--轉換--SQL語句--轉存到bak.sql文件。 客戶端通用鏈接參數:-u -p -S -h -P 本地備份:mysqldump -uroot -p -S /data/mysql/3306/mysql.sock 遠程備份:mysqldump -uroot -p -h10.0.0.11 -P3306 備份專用基本參數 (1).-A --all-databases 全備參數 [root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p -A >/backup/full.sql 補充: 1.常規備份是要加--set-gtid-purged=OFF解決備份時的警告 [root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p -A --set-gtid-purged=OFF >/backup/full.sql 2.構建主從時,作的備份,不須要加這個參數。 [root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p -A --set-gtid-purged=ON >/backup/full.sql 在構建主從複製是,千萬不要OFF。在平常備份時,能夠OFF。 --set-gtid-purged=AUTO,ON,OFF 1.--set-gtid-purged=OFF可使用在平常備份參數中。 2.--set-gtid-purged=ON在構建主從複製環境時須要的參數配置。 (2)-B備份多個單庫db1 db2 db3,增長建立數據庫語句 和 use鏈接數據庫的語句。 說明:生產中須要備份業務相關的庫和MySQL庫。 [root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p -B world school --set-gtid-purged=OFF >/backup/a.sql 備份單個或多個表 world數據庫下的city,country表 [root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p world city country --set-gtid-purged=OFF >/backup/a.sql 以上備份恢復時,必須庫事先存在。而且ues才能source恢復。 (3).高級參數應用 -R --routines 備份存儲過程及函數 --triggers 備份觸發器 -E --events 備份事件 [root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p -A --master-data=2 --single-transaction --routines --events --triggers --set-gtid-purged=OFF >/backup/a.sql -F 在備份開始時,刷新一個新binlog日誌 [root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p -F -A --master-data=2 --single-transaction --routines --events --triggers --set-gtid-purged=OFF >/backup/a.sql --master-data=2 在備份時,自動記錄二進制日誌的文件和位置號。能夠自動加鎖和解鎖。 以註釋的形式,保存備份開始時間點的binlog的狀態信息。 加了--single-transaction能夠減小鎖表時間。 -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000008', MASTER_LOG_POS=194; 功能: (1).在備份時,會自動記錄,二進制日誌文件名和位置號。 0 默認值 1 以change master to命令形式,能夠用做主從複製 2 以註釋的形式記錄,備份時刻的文件名+postion號 (1).自動鎖表 (3).若是配合--single-transaction,只對非InnoDB表進行鎖表備份,InnoDB表進行熱備,其實是實現快照備份。 --single-transaction innodb 存儲引擎開啓熱備(快照備份)功能。 在對於InnoDB表備份時,開啓一個單獨事務,備份全部表的一致性快照數據。 --master-data能夠自動加鎖。 (1).在不加--single-transaction ,啓動全部表的溫備份,全部表都鎖定。 (2).加上--single-transaction,對innodb進行快照備份,對非innodb表能夠實現自動鎖表功能。 (1)開啓單獨事務備份 (2)對於InnoDB表一致性快照備份 (3)減小總體鎖表的時間 備份必加參數 [root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p -F -A --master-data=2 --single-transaction --routines --events --triggers --set-gtid-purged=OFF >/backup/full.sql --max-allowed-packet 最大的數據包大小 1153 - Got a packet bigger than 'max_allowed_packet' bytes The maximum packet length to send to or receive from server. [root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p -F -A --master-data=2 --single-transaction --routines --events --triggers --set-gtid-purged=OFF --max-allowed-packet=128M >/backup/full.sql 壓縮備份並添加時間戳 mysqldump -S /data/mysql/3306/mysql.sock -p -F -A --master-data=2 --single-transaction --routines --events --triggers --set-gtid-purged=OFF|gzip >/backup/full_$(date +"%F_%T").sql.gz 實現全部表的單獨備份 提示: information_schema.tables SELECT CONCAT("mysqldump -S /data/mysql/3306/mysql.sock -p123 ",table_schema," ",table_name," -F --master-data=2 --single-transaction --routines --events --triggers --set-gtid-purged=OFF >/backup/",table_schema,"_",table_name,".sql") FROM information_schema.tables WHERE table_schema NOT IN('mysql','sys','information_schema','performance_schema'); 模擬故障案例並恢復 (1).天天全備 (2).binlog日誌是完整 (3).模擬白天的數據變化 (4).模擬下午兩點誤刪除數據庫 需求:利用全備+binlog恢復數據庫誤刪除以前。 故障模擬及恢復: 1.模擬週一23:00的全備 [root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p -F -A --master-data=2 --single-transaction --routines --events --triggers --set-gtid-purged=OFF >/backup/full.sql 2.模擬白天的數據變化 [root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p mysql> set global read_only=off; mysql> set global supper_read_only=off; mysql> create database day01 charset=utf8mb4; mysql> use day01; mysql> create table t1(id int); mysql> insert into t1 values(1),(2),(3); mysql> commit; mysql> insert into t1 values(4),(5),(6); mysql> commit; mysql> shutdown; 模擬磁盤損壞: [root@db01 ~]# cd /data/mysql/3306/ [root@db01 /data/mysql/3306]# mv data data_rm1 [root@db01 ~]# mv /data/mysql/3306/logs/* /backup/binlog/ [root@db01 /data/mysql/3306]# mkdir data [root@db01 /data/mysql/3306]# chown mysql.mysql data 恢復故障思路 (1).檢查備份可用性 (2).從備份中獲取二進制日誌位置 (3).根據日誌位置截取須要的二進制日誌 (4).初始化數據庫並啓動 (5).恢復全備 (6).恢復二進制日誌 [root@db01 ~]# cd /data/mysql/3306/ [root@db01 /data/mysql/3306]# rm -rf data/* error.log logs/* slow.log tmp/* [root@db01 /data/mysql/3306]# mysqld --defaults-file=/data/mysql/3306/my.cnf --initialize-insecure [root@db01 ~]# mysqld --defaults-file=/data/mysql/3306/my.cnf & [root@db01 ~]# ps -ef | grep mysql [root@db01 ~]# netstat -lnp | grep mysql [root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock mysql> set global read_only=off; mysql> set global super_read_only=off; mysql> set sql_log_bin=off; mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000002 | 154 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec) mysql> source /backup/full.sql; mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | binlog | | mysql | | performance_schema | | school | | sys | | world | +--------------------+ 7 rows in set (0.00 sec) 全備的數據已將回來,先不要退出會話。 [root@db01 ~]# cd /backup/ [root@db01 /backup]# sed -n '22p' full.sql -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000007', MASTER_LOG_POS=194; [root@db01 /backup]# cd /backup/binlog/ [root@db01 /backup/binlog]# mysqlbinlog --skip-gtids --start-position=194 mysql-bin.000007 >/tmp/bin.sql mysql> source /tmp/bin.sql; mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | binlog | | day01 | | mysql | | performance_schema | | school | | sys | | world | +--------------------+ 8 rows in set (0.00 sec) mysql> select * from day01.t1; +------+ | id | +------+ | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | +------+ 6 rows in set (0.00 sec) mysql> set sql_log_bin=on; 數據已經恢復完成 mysqldump備份的恢復方式(在生產中恢復要謹慎,恢復會刪除重複的表) 注意: mysqldump在備份和恢復時都須要mysql實例啓動爲前提。 通常數據量級100G之內,大約15-45分鐘能夠恢復。 mysqldump是覆蓋形式恢復的方法。 通常咱們認爲,在同數據量級,物理備份要比邏輯備份速度快。 邏輯備份的優點: 1.可讀性強 2.壓縮比很高 企業故障恢復案例 背景環境:中小型網站架構,MySQL5.7.20,數據量200G,日業務增量10-15M。 備份策略:每週mysqldump全備,天天binlog增量,binlog15天過時。 年末故障演練:週三上午10點,模擬誤刪數據庫,並進行恢復。 恢復方案: (1).停業務,掛維護頁,避免數據的二次傷害。 (2).找一個臨時庫,恢復上一次全備。 (3).截取上一次全備到週三上午10點誤刪除之間的全部binlog (4).恢復binlog到臨時庫,導出故障表,恢復至生產。 (5).測試可用性和完整性。 方法一:直接使用臨時庫頂替原生產庫,前端應用割接到新庫。 方法二:將誤刪除的表導出,導入到原生產庫。 (6).開啓業務 處理結果:通過20分鐘的處理,最終業務恢復正常。 故障模擬演練 準備數據 [root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock mysql> create database mdp charset=utf8mb4; mysql> use mdp; mysql> create table t1(id int); mysql> insert into t1 values(1),(2),(3); mysql> commit; [root@db01 ~]# rm -rf /backup/* 週二23:00全備 [root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p -F -A --master-data=2 --single-transaction --routines --events --triggers --set-gtid-purged=OFF|gzip >/backup/full_$(date +"%F_%T").sql.gz 模擬週二23:00到週三10點之間數據變化 mysql> use mdp; mysql> insert into t1 values(4),(5),(6); mysql> commit; 模擬故障,刪除表(只是模擬,不表明生產操做) mysql> drop database mdp; 恢復過程 準備臨時數據庫(多實例3307) mkdir -p /data/mysql/3307/{data,logs,tmp} cp /data/mysql/3306/my.cnf /data/mysql/3307/ tree /data/mysql/3307/ sed -i 's/3306/3307/g' /data/mysql/3307/my.cnf chown -R mysql:mysql /data/mysql/3307 mysqld --defaults-file=/data/mysql/3307/my.cnf --initialize-insecure cat /data/mysql/3307/error.log mysqld --defaults-file=/data/mysql/3307/my.cnf & ps -ef | grep mysql netstat -lnp | grep mysql mysql -S /data/mysql/3307/mysql.sock 準備備份 [root@db01 /backup]# gunzip -d full_2019-09-15_01\:59\:21.sql.gz mysql> show master status; mysql> show binlog events in 'mysql-bin.000005'; [root@db01 ~]# mysqlbinlog --skip-gtids --include-gtids='0cfb4a27-d714-11e9-9150-000c29ca1344:1-5' --exclude-gtids='0cfb4a27-d714-11e9-9150-000c29ca1344:5' /data/mysql/3306/logs/mysql-bin.000005 >/tmp/bin.sql 恢復備份到臨時庫 [root@db01 ~]# mysql -S /data/mysql/3307/mysql.sock mysql> set global read_only=off; mysql> set global super_read_only=off; mysql> set sql_log_bin=off; mysql> source /backup/full_2019-09-15_01:59:21.sql; mysql> source /tmp/bin.sql; mysql> select * from mdp.t1; +------+ | id | +------+ | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | +------+ 6 rows in set (0.00 sec) mysql> set sql_log_bin=on; 將故障表導出並恢復到生產 [root@db01 ~]# mysqldump -S /data/mysql/3307/mysql.sock -B mdp --set-gtid-purged=OFF >/backup/mdp.sql [root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock mysql> set sql_log_bin=off; mysql> source /backup/mdp.sql; mysql> select * from mdp.t1; +------+ | id | +------+ | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | +------+ 6 rows in set (0.00 sec) mysql> set sql_log_bin=on; 課下做業: 練習: 1.建立一個數據庫app01 2.在app01下建立一張表t1 3.插入5行任意數據 4.全備 5.插入兩行數據,任意修改3行數據,刪除1行數據。 6.刪除全部數據 7.再t1中又插入5行新數據,修改3行數據。 需求,跳過第六步恢復表數據。 寫備份腳本和策略 2.分庫分表併發備份 備份時優化參數: (1).max_allowed_packet 最大的數據包大小 mysql> select @@max_allowed_packet; (2).增長key_buffer_size (臨時表有關) mysql> select @@key_buffer_size; MySQL物理備份工具-xtrabackup(XBK、PBK、Xbackup) Percona 公司的產品,Perl語言開發。 安裝依賴包: yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL libev perl-Digest perl-Digest-MD5 能夠一直yum -y,用騰訊鏡像站。。。 [root@db01 ~]# yum -y install https://mirrors.cloud.tencent.com/percona/centos/7Server/RPMS/x86_64/percona-xtrabackup-24-2.4.15-1.el7.x86_64.rpm [root@db01 ~]# rm -rf /etc/my.cnf.rpmnew [root@db01 ~]# rm -rf /etc/my.cnf.d [root@db01 ~]# ls -l `which innobackupex` lrwxrwxrwx 1 root root 10 Sep 17 04:54 /usr/bin/innobackupex -> xtrabackup 備份方式:物理備份 (1).自動判斷表的類型。 (2).flush table with read lock; (FTWRL) (2).對於非InnoDB表(不支持事務的),進行鎖表,而後cp數據文件,屬於一種溫備份。 (3).對於InnoDB的表(支持事務的),當即CKPT,不鎖表,將提交的髒頁進行刷新到磁盤,進行cp數據頁,最終以數據文件的方式保存下來,cp同時將過程當中產生的redo和undo一塊備份走。屬於熱備方式。 恢復: 1.非InnoDB,直接恢復便可。 2.InnoDB表,須要XBK處理備份後,再進行恢復。 處理備份(Prepare)? 模仿了,自動故障恢復的流程:先redo前滾,再undo回滾。 面試題:XBK在innodb表備份恢復的流程。 (1).XBK備份執行的瞬間,當即觸發ckpt,已提交的數據髒頁,從內存刷寫到磁盤,並記錄此時的LSN號。 (2).備份時,拷貝磁盤數據頁,而且記錄備份過程當中產生的redo和undo一塊兒拷貝走,也就是checkpoint LSN以後的日誌。 (3).在恢復以前,模擬Innodb「自動故障恢復」的過程,將redo(前滾)與undo(回滾)進行應用。 (4).恢復過程是cp備份到原來數據目錄下。 innobackupex使用 全備 [root@db01 ~]# innobackupex --defaults-file=/data/mysql/3306/my.cnf -uroot -p123 -S /data/mysql/3306/mysql.sock /backup/full [root@db01 ~]# ls -l /backup/full/ total 0 drwxr-x--- 11 root root 304 Sep 17 06:14 2019-09-17_06-14-16 [root@db01 ~]# du -sh /backup/full/2019-09-17_06-14-16 179M /backup/full/2019-09-17_06-14-16 [root@db01 ~]# rm -rf /backup/* 自主定製備份路徑名 [root@db01 ~]# innobackupex --defaults-file=/data/mysql/3306/my.cnf -uroot -p123 -S /data/mysql/3306/mysql.sock --no-timestamp /backup/full [root@db01 ~]# ls -l /backup/full/ total 102456 -rw-r----- 1 root root 537 Sep 17 06:20 backup-my.cnf drwxr-x--- 2 root root 48 Sep 17 06:20 binlog drwxr-x--- 2 root root 48 Sep 17 06:20 day01 -rw-r----- 1 root root 7050 Sep 17 06:20 ib_buffer_pool -rw-r----- 1 root root 104857600 Sep 17 06:20 ibdata1 drwxr-x--- 2 root root 48 Sep 17 06:20 mdp drwxr-x--- 2 root root 4096 Sep 17 06:20 mysql drwxr-x--- 2 root root 8192 Sep 17 06:20 performance_schema drwxr-x--- 2 root root 176 Sep 17 06:20 school drwxr-x--- 2 root root 54 Sep 17 06:20 shenzhen drwxr-x--- 2 root root 8192 Sep 17 06:20 sys drwxr-x--- 2 root root 144 Sep 17 06:20 world -rw-r----- 1 root root 68 Sep 17 06:20 xtrabackup_binlog_info -rw-r----- 1 root root 141 Sep 17 06:20 xtrabackup_checkpoints -rw-r----- 1 root root 618 Sep 17 06:20 xtrabackup_info -rw-r----- 1 root root 2560 Sep 17 06:20 xtrabackup_logfile 備份集中多出來的文件: xtrabackup_binlog_info:備份時的binlog的位置點信息,截取binlog的起點信息。 [root@db01 ~]# cat /backup/full/xtrabackup_binlog_info mysql-bin.000007 194 0cfb4a27-d714-11e9-9150-000c29ca1344:1-1000021 記錄的是備份時刻,binlog的文件名字和當時的結束的position,能夠用來做爲截取binlog時的起點。 xtrabackup_checkpoints: [root@db01 ~]# cat /backup/full/xtrabackup_checkpoints backup_type = full-backuped #備份類型和狀態 from_lsn = 0 #整個備份,起始的LSN(上次所到達的LSN號,對於全備就是從0開始,對於增量有別的顯示方法) to_lsn = 313412276 #CKPT的LSN(備份開始時間ckpt點數據頁的LSN) last_lsn = 313412285 #備份結束的LSN(備份結束後,redo日誌最終的LSN) compact = 0 recover_binlog_info = 0 flushed_lsn = 313412285 (1).備份時刻,當即將已經commit過的,內存中的數據頁刷新到磁盤(CKPT),開始備份數據,數據文件的LSN會停留在to_lsn位置。 (2).備份時刻有可能會有其餘的數據寫入,已備走的數據文件就不會再發生變化了。 (3).在備份過程當中,備份軟件會一直監控着redo的undo,若是一旦有變化會將日誌也一併備走,並記錄LSN到last_lsn。 從to_lsn---》last_lsn 就是,備份過程當中產生的數據變化。 xtrabackup_info:備份信息的總覽 [root@db01 ~]# cat /backup/full/xtrabackup_info uuid = 392658e9-d8d0-11e9-bde5-000c29ca1344 name = tool_name = innobackupex tool_command = --defaults-file=/data/mysql/3306/my.cnf -uroot -p123 -S /data/mysql/3306/mysql.sock --no-timestamp /backup/full tool_version = 2.4.15 ibbackup_version = 2.4.15 server_version = 5.7.26-log start_time = 2019-09-17 06:20:41 end_time = 2019-09-17 06:20:43 lock_time = 0 binlog_pos = filename 'mysql-bin.000007', position '194', GTID of the last change '0cfb4a27-d714-11e9-9150-000c29ca1344:1-1000021' innodb_from_lsn = 0 innodb_to_lsn = 313412276 partial = N incremental = N format = file compact = N compressed = N encrypted = N xtrabackup_logfile:記錄備份過程當中產生的redo [root@db01 ~]# cat /backup/full/xtrabackup_logfile 搞破壞 [root@db01 ~]# mysqladmin -S /data/mysql/3306/mysql.sock -p shutdown [root@db01 ~]# cd /data/mysql/3306/ [root@db01 /data/mysql/3306]# mv data data_rm2 重作回滾準備的備份 將redo進行重作,已提交的寫到數據文件,未提交的使用undo回滾掉。模擬了CSR的過程。 [root@db01 ~]# innobackupex --apply-log /backup/full/ 開始恢復 (1).被恢復的目錄是空。 (2).被恢復的數據庫的實例是關閉。 [root@db01 ~]# mkdir -p /data/mysql/3306/data [root@db01 ~]# cp -a /backup/full/* /data/mysql/3306/data/ [root@db01 ~]# chown -R mysql:mysql /data/mysql/3306/data [root@db01 ~]# tail -f /data/mysql/3306/error.log [root@db01 ~]# mysqld --defaults-file=/data/mysql/3306/my.cnf & [root@db01 ~]# ps -ef | grep mysql [root@db01 ~]# netstat -lnp | grep mysql 若是你不想cp也能夠用 innobackupex --defaults-file=/data/mysql/3306/my.cnf --copy-back --rsync /backup/full/ innobackupex 增量備份(incremental) (1).增量備份的方式,是基於上一次備份進行增量。 (2).增量備份沒法單獨恢復。必須基於全備進行恢復。 (3).全部增量必需要按順序合併到全備中。 全備+增量備份 故障案例說明: 1.背景:某大型網站,MySQL 5.7.20,數據量800G 2.備份策略:Xtrabackup,full(週日23:30)+incN(週一到週六23:30)+binlog(天天中午12:30) 3.故障:週三上午10點,數據庫"癱了"。 故障案例模擬: [root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p mysql [(none)]> set global read_only=off; mysql [(none)]> set global super_read_only=off; 1.模擬初始數據 mysql [(none)]> create database xbk charset=utf8mb4; mysql [(none)]> use xbk; mysql [xbk]> create table t1(id int) engine=innodb charset=utf8mb4; mysql [xbk]> insert into t1 values(1),(2),(3); mysql [xbk]> commit; 2.模擬週日的全備 [root@db01 ~]# rm -rf /backup/* [root@db01 ~]# innobackupex --defaults-file=/data/mysql/3306/my.cnf -uroot -p123 -S /data/mysql/3306/mysql.sock --no-timestamp /backup/full 3.模擬週一白天數據變化 mysql [xbk]> insert into t1 values(11),(22),(33); mysql [xbk]> commit; 4.模擬週一夜增量備份 [root@db01 ~]# innobackupex --defaults-file=/data/mysql/3306/my.cnf -uroot -p123 -S /data/mysql/3306/mysql.sock --no-timestamp --incremental --incremental-basedir=/backup/full /backup/inc1 5.模擬週二白天數據變化 mysql [xbk]> insert into t1 values(111),(222),(333); mysql [xbk]> commit; 6.模擬週二晚上增量備份 [root@db01 ~]# innobackupex --defaults-file=/data/mysql/3306/my.cnf -uroot -p123 -S /data/mysql/3306/mysql.sock --no-timestamp --incremental --incremental-basedir=/backup/inc1 /backup/inc2 7.模擬週三白天的數據變化 mysql [xbk]> insert into t1 values(1111),(2222),(3333); mysql [xbk]> commit; 8.搞破壞 mysql [xbk]> shutdown; [root@db01 ~]# cd /data/mysql/3306/ [root@db01 /data/mysql/3306]# mv data data_rm3 9.恢復模擬 檢查備份 full+inc1+inc2+binlog full進行處理備份 [root@db01 ~]# innobackupex --apply-log --redo-only /backup/full/ 合併inc1到full中,處理備份 [root@db01 ~]# innobackupex --apply-log --redo-only --incremental-dir=/backup/inc1 /backup/full/ 合併inc2到full中,處理備份 [root@db01 ~]# innobackupex --apply-log --incremental-dir=/backup/inc2 /backup/full/ 最後一次整理備份 [root@db01 ~]# innobackupex --apply-log /backup/full/ 開始恢復 [root@db01 ~]# mkdir -p /data/mysql/3306/data [root@db01 ~]# cp -a /backup/full/* /data/mysql/3306/data/ [root@db01 ~]# chown -R mysql:mysql /data/mysql/3306/data [root@db01 ~]# tail -f /data/mysql/3306/error.log [root@db01 ~]# mysqld --defaults-file=/data/mysql/3306/my.cnf & [root@db01 ~]# ps -ef | grep mysql [root@db01 ~]# netstat -lnp | grep mysql [root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p mysql [xbk]> set global read_only=off; mysql [xbk]> set global super_read_only=off; mysql [(none)]> use xbk; mysql [xbk]> select * from t1; +------+ | id | +------+ | 1 | | 2 | | 3 | | 11 | | 22 | | 33 | | 111 | | 222 | | 333 | +------+ 9 rows in set (0.00 sec) [root@db01 ~]# cat /backup/inc2/xtrabackup_binlog_info mysql-bin.000008 2156 0cfb4a27-d714-11e9-9150-000c29ca1344:1-1000021, ccd8a5da-d8d2-11e9-8419-000c29ca1344:1-9 截取binlog和安裝傳統方式或gtid [root@db01 ~]# mysqlbinlog --skip-gtids --start-position=2156 /data/mysql/3306/logs/mysql-bin.000008 > /tmp/bin.sql mysql [xbk]> set sql_log_bin=off; mysql [xbk]> source /tmp/bin.sql; mysql [xbk]> select * from t1; +------+ | id | +------+ | 1 | | 2 | | 3 | | 11 | | 22 | | 33 | | 111 | | 222 | | 333 | | 1111 | | 2222 | | 3333 | +------+ 12 rows in set (0.00 sec) 恢復到週三誤drop以前的數據狀態 恢復思路: (1).掛出維護頁,中止當天的自動備份腳本。 (2).檢查備份:週日full+週一inc1+週二inc2,週三的完整二進制日誌。 (3).進行備份整理(細節),截取關鍵的二進制日誌(從備份--誤刪除以前)。 (4).測試庫進行備份恢復及日誌恢復。 (5).應用進行測試無誤,開啓業務。 (6).這次工做的總結。 本身擴展 (1).MySQL8.0的XBK (2).從全備中恢復單表。 (3).遠程備份 innobackupex --defaults-file=/etc/my.cnf --no-lock --user 'root' --password 'password123' --stream=tar ./ | ssh root@192.168.2.100 \ "cat - > /home/backup/database/`date +%Y%m%d`/`date +%H-%M`-backup.tar" echo `date +%Y%m%d-%H%M`:備份結束 >> backup_db.log 做業1 Xtrabackup企業級增量恢復實戰 背景: 某大型網站,mysql數據庫,數據量500G,每日更新量20M-30M 備份策略: xtrabackup,每週日0:00進行全備,週一到週六00:00進行增量備份。 故障場景: 週三下午2點出現數據庫意外刪除表操做。 如何恢復? 做業2 練習:mysqldump備份恢復例子。 1.建立一個數據庫 oldboy 2.在oldboy下建立一張表t1 3.插入5行任意數據。 4.全備。 5.插入兩行數據,任意修改3行數據,刪除1行數據。 6.刪除全部數據。 7.再t1中又插入5行新數據,修改3行數據。 需求,跳過第六步恢復表數據。 做業3 分別寫備份腳本和策略。 做業4:備份集中單獨恢復表。 思考:在以前的項目案例中,若是誤刪除的表只有10M,而備份有500G,該如何快速恢復誤刪除表? 提示: drop table city; create table city like city_bak; alter table city discard tablespace; cp /backup/full/world/city.ibd /application/mysql/data/world/ chown -R mysql.mysql /application/mysql/data/world/city.ibd alter table city import tablespace; 做業5:從mysqldump全備中獲取庫和表的備份。 1.得到表結構。 # sed -e'/./{H;$!d;}' -e 'x;/CREATE TABLE `city`/!d;q' full.sql>createtable.sql 2.得到INSERT INTO 語句,用於數據的恢復。 # grep -i 'INSERT INTO `city`' full.sqll >data.sql & 3.獲取單庫的備份。 # sed -n '/^-- Current Database: `world`/,/^-- Current Database: `/p' all.sql >world.sql 批量的分庫分表備份 (1).shell腳本for循環 (2).用元數據查詢拼接concat() information_schema.tables