久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

MySQL數據怎么恢復

170次閱讀
沒有評論

共計 10685 個字符,預計需要花費 27 分鐘才能閱讀完成。

這篇文章主要講解了“MySQL 數據怎么恢復”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著丸趣 TV 小編的思路慢慢深入,一起來研究和學習“MySQL 數據怎么恢復”吧!

1、前言

數據恢復的前提的做好備份,且開啟 binlog,格式為 row。如果沒有備份文件,那么刪掉庫表后就真的刪掉了,lsof 中還有記錄的話,有可能恢復一部分文件。但若剛好數據庫沒有打開這個表文件,那就只能跑路了。如果沒有開啟 binlog,那么恢復數據后,從備份時間點開始的數據都沒了。如果 binlog 格式不為 row,那么在誤操作數據后就沒有辦法做閃回操作,只能老老實實地走備份恢復流程。

2、直接恢復

直接恢復是使用備份文件做全量恢復,這是最常見的場景。

2.1 mysqldump 備份全量恢復

使用 mysqldump 文件恢復數據非常簡單,直接解壓了執行:

gzip -d backup.sql.gz | mysql -u user  -h host  -P port  -p

2.2 xtrabackup 備份全量恢復

恢復過程:

#  步驟一:解壓(如果沒有壓縮可以忽略這一步) innobackupex --decompress  備份文件所在目錄  #  步驟二:應用日志  innobackupex --apply-log  備份文件所在目錄  #  步驟三:復制備份文件到數據目錄  innobackupex --datadir= MySQL 數據目錄  --copy-back  備份文件所在目錄 

2.3 基于時間點恢復

基于時間點的恢復依賴的是 binlog 日志,需要從 binlog 中找過從備份點到恢復點的所有日志,然后應用。我們測試一下。

新建測試表:

chengqm-3306 show create table mytest.mytest \G; *************************** 1. row *************************** Table: mytest Create Table: CREATE TABLE `mytest` ( `id` int(11) NOT NULL AUTO_INCREMENT, `ctime` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8

每秒插入一條數據:

[mysql@mysql-test ~]$ while true; do mysql -S /tmp/mysql.sock -e  insert into mytest.mytest(ctime)values(now()) date;sleep 1;done

備份:

[mysql@mysql-test ~]$ mysqldump --opt --single-transaction --master-data=2 --default-character-set=utf8 -S /tmp/mysql.sock -A   backup.sql

找出備份時的日志位置:

[mysql@mysql-test ~]$ head -n 25 backup.sql | grep  CHANGE MASTER TO MASTER_LOG_FILE  -- CHANGE MASTER TO MASTER_LOG_FILE= mysql-bin.000032 , MASTER_LOG_POS=39654;

假設要恢復到 2019-08-09 11:01:54 這個時間點,我們從 binlog 中查找從 39654 到 019-08-09 11:01:54 的日志。

[mysql@mysql-test ~]$ mysqlbinlog --start-position=39654 --stop-datetime= 2019-08-09 11:01:54  /data/mysql_log/mysql_test/mysql-bin.000032   backup_inc.sql [mysql@mysql-test-83 ~]$ tail -n 20 backup_inc.sql ...... ### INSERT INTO `mytest`.`mytest` ### SET ### @1=161 /* INT meta=0 nullable=0 is_null=0 */ ### @2= 2019-08-09 11:01:53  /* DATETIME(0) meta=0 nullable=1 is_null=0 */ ......

當前數據條目數:

-- 2019-08-09 11:01:54 之前的數據條數  chengqm-3306 select count(*) from mytest.mytest where ctime    2019-08-09 11:01:54  +----------+ | count(*) | +----------+ | 161 | +----------+ 1 row in set (0.00 sec)

所有數據條數

chengqm-3306 select count(*) from mytest.mytest; +----------+ | count(*) | +----------+ | 180 | +----------+ 1 row in set (0.00 sec)

然后執行恢復:

#  全量恢復  [mysql@mysql-test ~]$ mysql -S /tmp/mysql.sock   backup.sql #  應用增量日志  [mysql@mysql-test ~]$ mysql -S /tmp/mysql.sock   backup_inc.sql

檢查數據:

chengqm-3306 select count(*) from mytest.mytest; +----------+ | count(*) | +----------+ | 161 | +----------+ 1 row in set (0.00 sec) chengqm-3306 select * from mytest.mytest order by id desc limit 5; +-----+---------------------+ | id | ctime | +-----+---------------------+ | 161 | 2019-08-09 11:01:53 | | 160 | 2019-08-09 11:01:52 | | 159 | 2019-08-09 11:01:51 | | 158 | 2019-08-09 11:01:50 | | 157 | 2019-08-09 11:01:49 | +-----+---------------------+ 5 rows in set (0.00 sec)

已經恢復到 2019-08-09 11:01:54 這個時間點。

3、恢復一個表

3.1 從 mysqldump 備份恢復一個表

假設要恢復的表是 mytest.mytest:

#  提取某個庫的所有數據  sed -n  /^-- Current Database: `mytest`/,/^-- Current Database:/p  backup.sql   backup_mytest.sql #  從庫備份文件中提取建表語句  sed -e /./{H;$!d;}  -e  /CREATE TABLE `mytest`/!d;q  backup_mytest.sql   mytest_table_create.sql #  從庫備份文件中提取插入數據語句  grep -i  INSERT INTO `mytest`  backup_mytest.sql   mytest_table_insert.sql #  恢復表結構到  mytest  庫  mysql -u user  -p mytest   mytest_table_create.sql #  恢復表數據到  mytest.mytest  表  mysql -u user  -p mytest   mytest_table_insert.sql

3.2 從 xtrabackup 備份恢復一個表

假設 ./backup_xtra_full 目錄為解壓后應用過日志的備份文件。

3.2.1 MyISAM 表

假設從備份文件中恢復表 mytest.t_myisam。從備份文件中找到 t_myisam.frm, t_myisam.MYD, t_myisam.MYI 這 3 個文件,復制到對應的數據目錄中,并授權

進入 MySQL。檢查表情況:

chengqm-3306 show tables; +------------------+ | Tables_in_mytest | +------------------+ | mytest | | t_myisam | +------------------+ 2 rows in set (0.00 sec) chengqm-3306 check table t_myisam; +-----------------+-------+----------+----------+ | Table | Op | Msg_type | Msg_text | +-----------------+-------+----------+----------+ | mytest.t_myisam | check | status | OK | +-----------------+-------+----------+----------+ 1 row in set (0.00 sec)

3.2.2 Innodb 表

假設從備份文件中恢復表 mytest.t_innodb,恢復前提是設置了 innodb_file_per_table = on:

  起一個新實例;

  在實例上建一個和原來一模一樣的表;

  執行 alter table t_innodb discard tablespace; 刪除表空間,這個操作會把 t_innodb.ibd 刪除;

  從備份文件中找到 t_innodb.ibd 這個文件,復制到對應的數據目錄,并授權;

  執行 alter table t_innodb IMPORT tablespace; 加載表空間;

  執行 flush table t_innodb;check table t_innodb; 檢查表;

  使用 mysqldump 導出數據,然后再導入到要恢復的數據庫。

注意:

  在新實例上恢復再 dump 出來是為了避免風險,如果是測試,可以直接在原庫上操作步驟 2-6;

  只在 8.0 以前的版本有效。

4、跳過誤操作 SQL

跳過誤操作 SQL 一般用于執行了無法閃回的操作比如 drop table\database。

4.1 使用備份文件恢復跳過

4.1.1 不開啟 GTID

使用備份文件恢復的步驟和基于時間點恢復的操作差不多,區別在于多一個查找 binlog 操作。舉個例子,我這里建立了兩個表 a 和 b,每分鐘插入一條數據,然后做全量備份,再刪除表 b,現在要跳過這條 SQL。

刪除表 b 后的數據庫狀態:

chgnqm-3306 show tables; +------------------+ | Tables_in_mytest | +------------------+ | a | +------------------+ 1 row in set (0.00 sec)

鴻蒙官方戰略合作共建——HarmonyOS 技術社區

  找出備份時的日志位置  

[mysql@mysql-test ~]$ head -n 25 backup.sql | grep  CHANGE MASTER TO MASTER_LOG_FILE  -- CHANGE MASTER TO MASTER_LOG_FILE= mysql-bin.000034 , MASTER_LOG_POS=38414;

    2.  找出執行了 drop table 語句的 pos 位置

[mysql@mysql-test mysql_test]$ mysqlbinlog -vv /data/mysql_log/mysql_test/mysql-bin.000034 | grep -i -B 3  drop table `b`  # at 120629 #190818 19:48:30 server id 83 end_log_pos 120747 CRC32 0x6dd6ab2a Query thread_id=29488 exec_time=0 error_code=0 SET TIMESTAMP=1566128910/*!*/; DROP TABLE `b` /* generated by server */

從結果中我們可以看到 drop 所在語句的開始位置是 120629,結束位置是 120747。

    3.  從 binglog 中提取跳過這條語句的其他記錄

#  第一條的  start-position  為備份文件的  pos  位置,stop-position  為  drop  語句的開始位置  mysqlbinlog -vv --start-position=38414 --stop-position=120629 /data/mysql_log/mysql_test/mysql-bin.000034   backup_inc_1.sql #  第二條的  start-position  為  drop  語句的結束位置  mysqlbinlog -vv --start-position=120747 /data/mysql_log/mysql_test/mysql-bin.000034   backup_inc_2.sql

    4.  恢復備份文件

[mysql@mysql-test ~]$ mysql -S /tmp/mysql.sock   backup.sql

全量恢復后狀態:

chgnqm-3306 show tables; +------------------+ | Tables_in_mytest | +------------------+ | a | | b | +------------------+ 2 rows in set (0.00 sec) chgnqm-3306 select count(*) from a; +----------+ | count(*) | +----------+ | 71 | +----------+ 1 row in set (0.00 sec)

   5.    恢復增量數據

[mysql@mysql-test ~]$ mysql -S /tmp/mysql.sock   backup_inc_1.sql [mysql@mysql-test ~]$ mysql -S /tmp/mysql.sock   backup_inc_2.sql

恢復后狀態,可以看到已經跳過了 drop 語句:

chgnqm-3306 show tables; +------------------+ | Tables_in_mytest | +------------------+ | a | | b | +------------------+ 2 rows in set (0.00 sec) chgnqm-3306 select count(*) from a; +----------+ | count(*) | +----------+ | 274 | +----------+ 1 row in set (0.00 sec)

4.1.2 開啟 GTID

使用 GTID 可以直接跳過錯誤的 SQL:

  找出備份時的日志位置;

  找出執行了 drop table 語句的 GTID 值;

  導出備份時日志位置到最新的 binglog 日志;

  恢復備份文件;

  跳過這個 GTID; 

SET SESSION GTID_NEXT= 對應的  GTID  值  BEGIN; COMMIT; SET SESSION GTID_NEXT = AUTOMATIC;

  應用步驟 3 得到的增量 binlog 日志。

4.2 使用延遲庫跳過

4.2.1 不開啟 GTID

使用延遲庫恢復的關鍵操作在于 start slave until。我在測試環境搭建了兩個 MySQL 節點,節點二延遲 600 秒,新建 a,b 兩個表,每秒插入一條數據模擬業務數據插入。

localhost:3306 -  localhost:3307(delay 600)

當前節點二狀態:

chengqm-3307 show slave status \G; ... Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000039 Read_Master_Log_Pos: 15524 Relay_Log_File: mysql-relay-bin.000002 Relay_Log_Pos: 22845 Relay_Master_Log_File: mysql-bin.000038 Slave_IO_Running: Yes Slave_SQL_Running: Yes ... Seconds_Behind_Master: 600 ...

當前節點二表:

chengqm-3307 show tables; +------------------+ | Tables_in_mytest | +------------------+ | a | | b | +------------------+

在節點一刪除表 b:

chengqm-3306 drop table b; Query OK, 0 rows affected (0.00 sec) chengqm-3306 show tables; +------------------+ | Tables_in_mytest | +------------------+ | a | +------------------+ 1 row in set (0.00 sec)

接下來就是跳過這條 SQL 的操作步驟。

鴻蒙官方戰略合作共建——HarmonyOS 技術社區

  延遲庫停止同步

stop slave;

    2.  找出執行了 drop table 語句的前一句的 pos 位置

[mysql@mysql-test ~]$ mysqlbinlog -vv /data/mysql_log/mysql_test/mysql-bin.000039 | grep -i -B 10  drop table `b`  ... # at 35134 #190819 11:40:25 server id 83 end_log_pos 35199 CRC32 0x02771167 Anonymous_GTID last_committed=132 sequence_number=133 rbr_only=no SET @@SESSION.GTID_NEXT=  ANONYMOUS /*!*/; # at 35199 #190819 11:40:25 server id 83 end_log_pos 35317 CRC32 0x50a018aa Query thread_id=37155 exec_time=0 error_code=0 use `mytest`/*!*/; SET TIMESTAMP=1566186025/*!*/; DROP TABLE `b` /* generated by server */

從結果中我們可以看到 drop 所在語句的前一句開始位置是 35134,所以我們同步到 35134(這個可別選錯了)。

    3.  延遲庫同步到要跳過的 SQL 前一條

change master to master_delay=0; start slave until master_log_file= mysql-bin.000039 ,master_log_pos=35134;

查看狀態看到已經同步到對應節點:

chengqm-3307 show slave status \G; ... Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000039 Read_Master_Log_Pos: 65792 ... Slave_IO_Running: Yes Slave_SQL_Running: No Exec_Master_Log_Pos: 35134 ... Until_Log_File: mysql-bin.000039 Until_Log_Pos: 35134

    4.  跳過一條 SQL 后開始同步

set global sql_slave_skip_counter=1; start slave;

查看同步狀態,刪除表 b 的語句已經被跳過:

chengqm-3307 show slave status \G; ... Slave_IO_Running: Yes Slave_SQL_Running: Yes ... 1 row in set (0.00 sec) chengqm-3307 show tables; +------------------+ | Tables_in_mytest | +------------------+ | a | | b | +------------------+ 2 rows in set (0.00 sec)

4.2.2 開啟 GTID

使用 GTID 跳過的步驟會簡單很多,只要執行一條和要跳過的 SQL 的 GTID 相同的事務就可以跳過了。

  停止同步;

  找出執行了 drop table 語句的 GTID;

  執行這個 GTID 的事務; 

SET SESSION GTID_NEXT= 對應的  GTID  值  BEGIN; COMMIT; SET SESSION GTID_NEXT = AUTOMATIC;

  繼續同步;

5. 閃回。

閃回操作就是反向操作,比如執行了 delete from a where id=1,閃回就會執行對應的插入操作 insert into a (id,…) values(1,…),用于誤操作數據,只對 DML 語句有效,且要求 binlog 格式設為 ROW。本章介紹兩個比較好用的開源工具。

5.1 binlog2sql

binlog2sql 是大眾點評開源的一款用于解析 binlog 的工具,可以用于生成閃回語句,項目地址 binlog2sql。

5.1.1 安裝

wget https://github.com/danfengcao/binlog2sql/archive/master.zip -O binlog2sql.zip unzip binlog2sql.zip cd binlog2sql-master/ #  安裝依賴  pip install -r requirements.txt

5.1.2 生成回滾 SQL

python binlog2sql/binlog2sql.py --flashback \ -h host  -P port  -u user  -p password  -d dbname  -t table_name \ --start-file= binlog_file  \ --start-datetime= start_time  \ --stop-datetime= stop_time    ./flashback.sql python binlog2sql/binlog2sql.py --flashback \ -h host  -P port  -u user  -p password  -d dbname  -t table_name  \ --start-file= binlog_file  \ --start-position= start_pos  \ --stop-position= stop_pos    ./flashback.sql

5.2 MyFlash

MyFlash 是由美團點評公司技術工程部開發維護的一個回滾 DML 操作的工具,項目鏈接 MyFlash。

限制:

 binlog 格式必須為 row,且 binlog_row_image=full;

  僅支持 5.6 與 5.7;

  只能回滾 DML(增、刪、改)。

5.2.1 安裝

#  依賴 (centos) yum install gcc* pkg-config glib2 libgnomeui-devel -y #  下載文件  wget https://github.com/Meituan-Dianping/MyFlash/archive/master.zip -O MyFlash.zip unzip MyFlash.zip cd MyFlash-master #  編譯安裝  gcc -w `pkg-config --cflags --libs glib-2.0` source/binlogParseGlib.c -o binary/flashback mv binary /usr/local/MyFlash ln -s /usr/local/MyFlash/flashback /usr/bin/flashback

5.2.2 使用

生成回滾語句:

flashback --databaseNames= dbname  --binlogFileNames= binlog_file  --start-position= start_pos  --stop-position= stop_pos

執行后會生成 binlog_output_base.flashback 文件,需要用 mysqlbinlog 解析出來再使用:

mysqlbinlog -vv binlog_output_base.flashback | mysql -u user  -p

感謝各位的閱讀,以上就是“MySQL 數據怎么恢復”的內容了,經過本文的學習后,相信大家對 MySQL 數據怎么恢復這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是丸趣 TV,丸趣 TV 小編將為大家推送更多相關知識點的文章,歡迎關注!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-28發表,共計10685字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 电白县| 安顺市| 武乡县| 隆昌县| 栾城县| 姚安县| 昭苏县| 汝城县| 柳林县| 永修县| 青龙| 收藏| 花莲县| 加查县| 都江堰市| 平定县| 杭锦后旗| 句容市| 防城港市| 西青区| 屏山县| 鞍山市| 清水河县| 洪湖市| 泾川县| 孟连| 乌鲁木齐县| 通海县| 遂川县| 天峻县| 岳普湖县| 龙口市| 东海县| 盐城市| 澄城县| 红河县| 资兴市| 永州市| 武宁县| 勃利县| 德钦县|