日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL备份恢复(十二)

發布時間:2023/12/31 数据库 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL备份恢复(十二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1. MySQL數據損壞類型
      • 1.1 物理損壞
      • 1.2 邏輯損壞
    • 2. DBA運維人員備份/恢復職責
      • 2.1 設計備份/容災策略
        • 2.1.1 備份策略
        • 2.1.2 容災策略
      • 2.2 定期的備份/容災檢查
      • 2.3 定期的故障恢復演練
      • 2.4 數據損壞時的快速準確恢復
      • 2.5 數據遷移工作
    • 3. MySQL常用備份工具
      • 3.1 邏輯備份方式
      • 3.2 物理備份方式
      • 3.3 架構備份方式
    • 4. mysqldump應用
      • 4.1 mysqldump介紹
      • 4.2 mysqldump備份方式
        • 4.2.1 InnoDB表
        • 4.2.2 非InnoDB表
      • 4.3 mysqldump核心參數
        • 4.3.1 mysqldump連接參數
        • 4.3.2 mysqldump備份參數
        • 4.3.3 mysqldump備份高級參數
          • 4.3.3.1 --master-data參數
          • 4.3.3.2 --single-transaction參數
          • 4.3.3.2 -R/-E/--triggers參數
          • 4.3.3.2 --max_allowed_packet參數
    • 5. mysqldump+binlog故障恢復案例
    • 6. mysqldump小總結

1. MySQL數據損壞類型

1.1 物理損壞

磁盤損壞:硬件,磁道壞,dd,格式化
文件損壞:數據文件損壞,redo損壞

1.2 邏輯損壞

drop、delete、truncate、update

2. DBA運維人員備份/恢復職責

2.1 設計備份/容災策略

2.1.1 備份策略

備份工具原則
備份周期設計
備份監控方法

2.1.2 容災策略

備份:用什么備份
架構: 高可用,延時從庫,災備庫

容災的好處: 在發生災難的時候,怎么能快速的恢復業務。可以用備份或高可用的架構

2.2 定期的備份/容災檢查

備份軟件 ------> 帶庫(磁帶)
每周 北京 --> 天津 貨運

一定要定時的檢查數據庫的備份情況,以防止自己寫的腳本有bug,保證正常備份。

2.3 定期的故障恢復演練

至少每年兩次的恢復演練。在測試環境進行恢復演練。

2.4 數據損壞時的快速準確恢復

每個產品數據庫出現故障,要快速的恢復數據,把相關命令寫清楚,每一種損壞的應對策略。

2.5 數據遷移工作

一般用備份的手段或者主從的手段來進行遷移

3. MySQL常用備份工具

3.1 邏輯備份方式

mysqldump(MDP) *****
replication(主從方式)
mydumper(自行擴展)
load data in file(自行擴展)

邏輯備份: 備份的是sql語句

3.2 物理備份方式

MySQL Enterprise Backup(企業版)
Percona Xtrabackup(PBK,XBK)*****

物理備份: 備份的是表空間文件(數據文件)

小提示:社區版沒有自帶的物理備份方式

3.3 架構備份方式

架構備份方式,屬于邏輯的一種,比如MySQL主從。
高可用和主從主要解決物理損壞(磁盤或主機壞了),邏輯損壞時沒辦法解決的

4. mysqldump應用

4.1 mysqldump介紹

邏輯備份工具。備份的是SQL語句。
查看mysqldump的參數幫助:mysqldump --help

4.2 mysqldump備份方式

innodb表,備份的時候不需要鎖原來的表的,原來的表該干什么干什么,不受影響。
因為這只是一個優先讀的快照,不會影響其他人操作

非innodb表在mysql中基本上都是系統相關的表,系統表要備份,元數據要備份的話,要進行
全局鎖表

做全備份的時候,有innodb和非innodb,備份時會有短暫的鎖表的情況,盡量避免非innodb鎖表的情況

mysql8.0以后,大部分的系統表都被存儲到innnodb表中,備份起來性能會更好一些

4.2.1 InnoDB表

可以采用快照備份的方式
開啟一個獨立的事務,獲取當前最新的一致性快照。
將快照數據,放在臨時表中,轉換成SQL(Create database,Create table,insert),保存到sql文件中

4.2.2 非InnoDB表

需要鎖表備份,觸發FTWRL,全局鎖表。轉化成SQL(Create database,Create table,insert),保存到sql文件中

4.3 mysqldump核心參數

4.3.1 mysqldump連接參數

-u 用戶名 -p密碼 -h IP地址 -P 端口號 -S 套接字文件

mysql也好,mysqldump也好,在你沒有指定-S或者配置文件里面也沒有-S的時候,也會自動去/tmp里面去找,-S 不指定也行,默認會去找/tmp/mysql.sock,如果mysql.sock在其他地方,那就必須要加-S或者在配置文件加上參數指定mysql.sock的具體位置

避免mysql密碼暴露問題:(一般不采用,沒有必要)

# 在配置文件中添加這些參數,登錄mysql時不需要密碼(一般不采用,沒有必要)。 vim ~/.my.cnf [mysql] user=root password=123456 [mysqldump]# 讀取mysql配置文件順序: 后面的參數覆前面的參數 [root@db01 ~]# mysql --help --verbose | grep my.cnf /etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf ~/.my.cnf

4.3.2 mysqldump備份參數

-A 全備

[root@db01 ~]# mkdir -p /data/backup [root@db01 ~]# chown -R mysql.mysql /data/* [root@db01 ~]# mysqldump -uroot -p123456 -S /tmp/mysql.sock -A > /data/backup/full.sql [root@db01 ~]# vim /data/backup/full.sql 例子1: [root@db01 ~]# mkdir -p /data/backup mysqldump -uroot -p -A >/data/backup/full.sql Enter password: mysqldump: [Warning] Using a password on the command line interface can be insecure. Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don't want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events. # 補充: # 1.常規備份是要加 --set-gtid-purged=OFF,解決備份時的警告 # [root@db01 ~]# mysqldump -uroot -p123 -A --set-gtid-purged=OFF >/backup/full.sql # 2.構建主從時,做的備份,不需要加這個參數 # [root@db01 ~]# mysqldump -uroot -p123 -A --set-gtid-purged=ON >/backup/full.sql

-B 備份單庫或多個庫(-B后面跟的都是庫名)

# 備份world庫和test庫 [root@db01 ~]# mysqldump -uroot -p123456 -B world test > /data/backup/db.sql

備份單表或多表(固定語法: 數據庫 表 表 表,不能寫多個庫名)

# 備份world庫中的city表和coutry表 [root@db01 ~]# mysqldump -uroot -p123456 -S /tmp/mysql.sock world city country > /data/backup/tab.sql

驗證一下:以下兩個命令的備份結果區別?

mysqldump -uroot -p123456 -B world > /data/backup/db1.sql # 上面的比下面多出兩條sql create database world; use world;# 這條sql備份world庫下面的所有表。應用時,world庫不存在,需要手工創建,并且use到world庫下再恢復。 mysqldump -uroot -p123456 world > /data/backup/db2.sql

對比兩個sql文件:vimdiff db1.sql db2.sql

4.3.3 mysqldump備份高級參數

4.3.3.1 --master-data參數

場景:每周日23:00全備,周1-6進行binlog備份。所有備份時完整的。
周三時,有一個核心運維人員濟寧了刪庫操作。

恢復思路:恢復全備 + 所有需要binlog恢復
痛點:binlog的截取。起點查找比較困難,有兩種方法

起點: 一定要找到備份開啟時刻準確的position號以及binlog文件名,因為對innodb來說時快照備份,對于myisam是鎖表備份,所以全備的那一刻起就必須找到準確起點position號。有兩種方法找起點。
方法一:備份開始時,自動記錄日志文件信息(有position號) --master-data=2(–master-data=2在備份開始的那個時刻,記錄一下當前日志文件的一個狀態)常用方法
方法二:備份開始時,切割日志。-F(備份一開始binlog日志就是flush一下,生成一個新的文件,切割一個新的日志出來,-F 備份起始的時候,直接刷新一個新的日志,是有多少個庫,刷新多少個。這個參數使用起來不太方便)

終點: drop之前的位置點

–master-data=2 參數詳解:

[root@db01 binlog]# mysqldump --help--master-data[=#] This causes the binary log position and filename to beappended to the output. If equal to 1, will print it as aCHANGE MASTER command; if equal to 2, that command willbe prefixed with a comment symbol. This option will turn--lock-all-tables on, unless --single-transaction isspecified too (in which case a global read lock is onlytaken a short time at the beginning of the dump; don'tforget to read about --single-transaction below). In allcases, any action on logs will happen at the exact momentof the dump. Option automatically turns --lock-tablesoff.

功能:
(1)備份時自動記錄binlog信息
(2)自動鎖表和解鎖
(3)配合single transaction 可以減少鎖表時間

開始實驗
確認起點方法一:(生產中使用–master-data=2參數)

[root@db01 backup]# mysqldump -uroot -p123456 -A --master-data=2 > /data/backup/full1.sql; [root@db01 backup]# mysqldump -uroot -p123456 -A --master-data=1 > /data/backup/full2.sql;

對比 --master-data=2和 --master-data=1備份出來的區別:
vim full1.sql full2.sql
區別:–master-data=2多了主從的命令,但是前面有注釋。 --master-data=1沒有注釋,我們不需要主從的命令,真要使用主從,手動去指定恢復的起點。

確認起點方法二:(一般不用這種方法,了解即可)

[root@db01 binlog]# ls mysql-bin.000001 mysql-bin.000003 mysql-bin.000005 mysql-bin.000007 mysql-bin.000002 mysql-bin.000004 mysql-bin.000006 mysql-bin.index # 這種方法切出來的日志文件比較多而且混亂,不好確定位置點 [root@db01 binlog]# mysqldump -uroot -p123456 -A -F > /data/backup/full3.sql [root@db01 binlog]# ls mysql-bin.000001 mysql-bin.000008 mysql-bin.000015 mysql-bin.000022 mysql-bin.000029 mysql-bin.000002 mysql-bin.000009 mysql-bin.000016 mysql-bin.000023 mysql-bin.000030 mysql-bin.000003 mysql-bin.000010 mysql-bin.000017 mysql-bin.000024 mysql-bin.000031 mysql-bin.000004 mysql-bin.000011 mysql-bin.000018 mysql-bin.000025 mysql-bin.index mysql-bin.000005 mysql-bin.000012 mysql-bin.000019 mysql-bin.000026 mysql-bin.000006 mysql-bin.000013 mysql-bin.000020 mysql-bin.000027 mysql-bin.000007 mysql-bin.000014 mysql-bin.000021 mysql-bin.000028
4.3.3.2 --single-transaction參數

對于InnoDB引擎表備份時,開啟一個獨立事務,獲取一致性快照,進行備份。

# --master-data=2 --single-transaction生產必加參數 [root@db01 backup]# mysqldump -uroot -p123456 -A --master-data=2 --single-transaction > /data/backup/full1.sql [root@db01 binlog]# mysqldump --help--single-transaction Creates a consistent snapshot by dumping all tables in asingle transaction. Works ONLY for tables stored instorage engines which support multiversioning (currentlyonly InnoDB does); the dump is NOT guaranteed to beconsistent for other storage engines. While a--single-transaction dump is in process, to ensure avalid dump file (correct table contents and binary logposition), no other connection should use the followingstatements: ALTER TABLE, DROP TABLE, RENAME TABLE,TRUNCATE TABLE, as consistent snapshot is not isolatedfrom them. Option automatically turns off --lock-tables.
4.3.3.2 -R/-E/–triggers參數

這一組參數涉及mysql高級變成部分,涉及到的一些對象,可以理解為和表有一定的關系,所以備份時也要加上。

拿Linux系統來通俗的理解這些參數:
-R 類似于自己寫的程序腳本,如果之備份linux系統,不備份自己寫的腳本程序,那就缺少了功能【備份存儲過程和函數,相當于再數據庫里開發的一些程序】
-E 類似于計劃任務,【備份事件】
–triggers類似于特殊類的腳本,【備份觸發器】

# -R -E --triggers生產環境必備的參數 [root@db01 backup]# mysqldump -uroot -p123456 -A --master-data=2 --single-transaction -R -E --triggers > /data/backup/full1.sql
4.3.3.2 --max_allowed_packet參數

傳輸包的最大傳輸大小:--max_allowed_packet=64M

# 調整客戶端--max_allowed_packet大小,如果64M還是不夠,那就調整128M [root@db01 backup]# mysqldump -uroot -p123456 -A --master-data=2 --single-transaction -R -E --triggers --max_allowed_packet=64M > /data/backup/full1.sql

深度解析:

兩種情況:(mysqldump是修改客戶端–max_allowed_packet的大小)

(1) mysql發送insert指令是客戶端向服務端發送數據,如果報錯Got a packet bigger than ‘max_allowed_packet’ bytes,那么就修改服務端–max_allowed_packet的大小。

(2)mysqldump命令指令是服務端向客戶端發送數據,如果報錯Got a packet bigger than ‘max_allowed_packet’ bytes,那么就修改客戶端–max_allowed_packet的大小。

5. mysqldump+binlog故障恢復案例

這個栗子可以用binlog也可以恢復,但是假設這個創庫創表兩年前就有了,用全備+binlog進行恢復。

注意:備份數據、mysql數據、日志要分開放,別放一個地方

案例場景: 基礎環境: Centos 7.6 + MySQL 5.7.28, LNMT網站業務, 數據量100G, 每天5-10M數據增長。備份策略: mysqldump每天全備,binlog定時備份。故障說明: 周三上午10點數據故障,例如: 核心業務庫被誤刪除。 恢復思路:1. 掛維護頁(停業務,避免數據的二次傷害)2. 找測試庫3. 恢復周二2300全備4. 根據周二全備文件找到起點的position號 --> 周三上午10點誤刪除之前的binlog,并恢復5. 測試業務功能正常6. 恢復業務(在MySQL中有邊緣數據庫,有可能其他邊緣業務使用,不敢直接進行全備恢復。從測試庫中單庫(核心庫)導出來,然后再恢復到生產庫中)方案1: 故障庫導回到原生產方案2: 直接用測試庫稱當生產,先跑著 模擬數據庫損壞及恢復:1. 模擬原始數據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;2. 模擬周二晚上全備mysql> mysqldump -uroot -p123456 -A --master-data=2 --single-transaction -R -E --triggers --max_allowed_packet=64M > /data/backup/full_`date +%F`.sql壓縮備份:mysql> mysqldump -uroot -p123 -A -R --triggers --set-gtid-purged=OFF --master-data=2 --single-transaction|gzip > /backup/full_$(date +%F).sql.gz3. 模擬周二 2300到周三 10點之間數據變化mysql> use mdp;mysql> create table t2 (id int);mysql> insert into t2 values(1),(2),(3);mysql> commit;4. 模擬故障,刪除表(只是模擬,不代表生產操作)mysql> drop database mdp;5. 開始恢復(再測試環境進行恢復,如果生產環境只是損壞了一張表,那么就在測試環境全備+binlog恢復完之后,進行導出單表,然后正在恢復到生產環境)5.1 檢查全備[root@db01 backup]# vim full_2023-02-23.sql# 備份開始時的binlog日志的起點位置-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000031', MASTER_LOG_POS=788;5.2 恢復全備# 如果開啟了GTID,在備份文件里面有SET @@SESSION.SQL_LOG_BIN=0作用是臨時取消了二進制日志記錄,但是沒有自動開啟,所以還是手動臨時開啟和關閉mysql> set sql_log_bin=0;mysql> source /data/backup/full_2023-02-23.sql驗證:(mdp數據庫已恢復,t1表和數據也已恢復)mysql> use mdp;mysql> show tables;+---------------+| Tables_in_mdp |+---------------+| t1 |+---------------+mysql> select * from t1;+------+| id |+------+| 1 || 2 || 3 |+------+用position號和GTID都可以來截取日志:(二選一) 5.3 截取binlogposition截取:起點:(788)[root@db01 backup]# grep "\-- CHANGE MASTER TO" /data/backup/full_2023-02-23.sql-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000031', MASTER_LOG_POS=788終點:(使用1210或者使用1275都可以,這里使用1210比較好)mysql> show binlog events in 'mysql-bin.000031';| mysql-bin.000031 | 1210 | Gtid | 6 | 1275 | SET @@SESSION.GTID_NEXT= '638fec45-e734-11ec-bcd2-000c29d09be0:24' || mysql-bin.000031 | 1275 | Query | 6 | 1364 | drop database mdpposition日志截取:# 雖然說時使用的position號截取的,但是因為binlog里面開啟了GTID,所以依然要加上參數--skip-gtidsmysqlbinlog --skip-gtids --start-position=788 --stop-position=1210 /data/binlog/mysql-bin.000031 > /tmp/binlog.sqlGTID截取:(備份文件中的信息)# GTID號進行恢復,在備份文件中存在GTID的信息SET @@GLOBAL.GTID_PURGED='XXX:1-21'; GLOBAL.GTID_PURGE這是一個命令,意思是全備恢復數據的時候把1-21號的GTID給刪了,刪完了之后再恢復 言外之意是,此備份中已經具備了1-21號GTID信息了,也就是說全備結束的GTID的位置是21[root@db01 backup]# vim full_2023-02-23.sqlSET @@GLOBAL.GTID_PURGED='638fec45-e734-11ec-bcd2-000c29d09be0:1-21';起點: 638fec45-e734-11ec-bcd2-000c29d09be0:22# show binlog events in 'mysql-bin.000031';查看確定終點終點: 638fec45-e734-11ec-bcd2-000c29d09be0:23(因為gtid=24為刪庫操作,所以要恢復到gtid的終點是23)| mysql-bin.000031 | 1210 | Gtid |6 |1275 | SET @@SESSION.GTID_NEXT= '638fec45-e734-11ec-bcd2-000c29d09be0:24' || mysql-bin.000031 | 1275 | Query| 6 |1364 | drop database mdp GTID日志截取:(gtid可以跨文件,position號是不可以跨文件的。這也是gtid的優勢所在)mysqlbinlog --skip-gtids --include-gtids='xxx:17-18' /data/binlog/mysql-bin.000031 > /tmp/binlog1.sql小提示:沒有開啟gitd的話也要加上--skip-gtids,因為截取出還是帶有gtid的(猜測應該是之前開過gtid,不加也成功的話,因備份文件里面有SET @@GLOBAL.GTID_PURGED='XXX:1-21',刪除了gtid) 建議加上--skip-gtids,標準用法5.4 恢復binlog# 如果開啟了GTID,在備份文件里面有SET @@SESSION.SQL_LOG_BIN=0作用是臨時取消了二進制日志記錄,但是沒有自動開啟,所以還是手動臨時開啟和關閉mysql> set sql_log_bin=0;# 使用position號或者gtid進行截取的日志,進行恢復mysql> source /tmp/binlog.sql;mysql> set sql_log_bin=1;# 驗證數據,成功恢復mysql> use mdp;mysql> show tables;+---------------+| Tables_in_mdp |+---------------+| t1 || t2 |+---------------+小練習:使用rm -rf /data/3306/* 故障模擬恢復 恢復思路:1. 需要把原來的實例給kill2. kill完之后把目錄清空,重新進行初始化,重新初始之后再按這上面的思路進行恢復

6. mysqldump小總結

參數:-u -p -S -h -P-A -B --master-data=2 --single-transaction -R -E --triggers --max_allowed_packet=64選擇場景:優點: 可讀性比較強,壓縮比,節省空間,不需要下載安裝。缺點:備份時間相對較長。恢復時間長。數據量較少,建議mysqldump 100G以內。數據量巨大: 分布式架構,數據量較大時候,可以采用分布式備份。也可以選擇mysqldump。(分布式架構(分別備份不同的分片),一個T數據,砍成十份,每份100G,并發的分布式備份。然后就沒有這么慢了 如果全備數據量大,但是只想恢復一張表,而這張表只有兩M,這時可以從全備中截取單表)mysqldump恢復是備份兩倍以上的時間mysqldump用壓縮工具壓縮備份出來的文件的壓縮比高(比物理備份要高)思考:mysql如何進行分布式備份???擴展: 從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

總結

以上是生活随笔為你收集整理的MySQL备份恢复(十二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。