sybench壓測下模擬誤truncate數據恢復

基本環境:官方社區版MySQL 5.7.21 Row+Gtid
開啓sysbench壓測,使用mysqldump備份數據庫,執行truncate操做,恢復數據到truncate前的時間點
一、切換日誌,記錄當前位置html

# 3306切換日誌
mydba@192.168.85.132,3306 [sbtest]> flush binary logs;
Query OK, 0 rows affected (0.07 sec)
# 3306查看當前位置
mydba@192.168.85.132,3306 [sbtest]> show master status;
+------------------+----------+--------------+------------------+-----------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                             |
+------------------+----------+--------------+------------------+-----------------------------------------------+
| mysql-bin.000013 |      194 |              |                  | 60863f8d-01af-11e8-bfdf-000c29c1025c:1-185088 |
+------------------+----------+--------------+------------------+-----------------------------------------------+
row in set (0.00 sec)
View Code

二、開啓sysbench壓測mysql

[root@ZST1 ~]# sysbench --version
sysbench 1.0.10
[root@ZST1 ~]# sysbench /usr/share/sysbench/tests/include/oltp_legacy/oltp.lua \
--mysql-host=192.168.85.132 --mysql-port=3306 --mysql-user=mydba --mysql-password=mysql5721 \
--db-driver=mysql --mysql-db=sbtest --oltp-tables-count=5 --oltp-table-size=100 \
--oltp-read-only=off --oltp-test-mode=complex --rand-type=uniform --rand-init=on \
--threads=6 --time=100 --events=100000 --report-interval=10 --percentile=99 run
View Code

先prepare再run,窗口有輸出後,使用mysqldump進行備份。sysbench詳細使用參考https://github.com/akopytov/sysbench
三、使用mysqldump備份數據庫git

# 3306備份數據
[root@ZST1 ~]# mysqldump --login-path=1323306 --single-transaction --master-data=2 -A >/data/backup/all_dump_1323306_`date +%Y%m%d`.sql
View Code

sysbench建立的表爲innodb引擎,在本例中使用mysqldump能確保備份數據的一致性。詳細說明參考:MySQL備份可能遇到的坑
四、刪除數據github

# 3306刪除數據
mydba@192.168.85.132,3306 [sbtest]> truncate table sbtest1;
View Code

執行truncate操做後恍然發現數據刪除錯誤,如今須要將數據恢復到truncate前的時間點(⊙_⊙)
首先咱們使用第3步的備份恢復到較近的時間點,結合備份以後產生的binary log恢復到truncate時刻。這裏爲了方便,僅恢復sbtest數據庫到3308實例
五、單庫恢復sql

# 單庫恢復(手動將gtid_purged變量註釋)
[root@ZST1 backup]# mysql --login-path=1323308 sbtest -o </data/backup/all_dump_1323306_`date +%Y%m%d`.sql
ERROR 1049 (42000) at line 936: Unknown database 'replcrash'
View Code

爲何會報這個錯?
-o, --one-database:Ignore statements except those that occur while the default database is the one named at the command line.
指定-o參數,僅執行默認數據庫(use dbname)與命令行指定dbname相同的腳本
查看備份出來腳本數據庫

# vim打開備份腳本搜索關鍵字replcrash
[root@ZST1 backup]# vim /data/backup/all_dump_1323306_`date +%Y%m%d`.sql
..
 931 -- Current Database: `replcrash`
 932 --
 933 
 934 CREATE DATABASE /*!32312 IF NOT EXISTS*/ `replcrash` /*!40100 DEFAULT CHARACTER SET utf8 */;
 935 
 936 USE `replcrash`;
 937 
 938 --
 939 -- Table structure for table `py_user`
 940 --
 941 
 942 DROP TABLE IF EXISTS `py_user`;
...
View Code

雖然有create database replcrash語句,可是它沒在use sbtest下面,那麼它的默認數據庫與命令行中的不一樣,所以create database replcrash不會執行。緊接着後面一句use replcrash就會找不到對應db,在3308實例建立備份文件中包含的用戶數據庫vim

# 建立用戶數據庫
mydba@192.168.85.132,3308 [sbtest]> create database replcrash;
mydba@192.168.85.132,3308 [sbtest]> create database sbtest;
# 從新恢復
[root@ZST1 backup]# mysql --login-path=1323308 sbtest -o </data/backup/all_dump_1323306_`date +%Y%m%d`.sql
View Code

等待片刻,上述命令僅恢復use sbtest裏面的腳本
將恢復出來的sbtest.sbtest1拷貝一份數據到sbtest_bak.sbtest1session

# 拷貝一份全備點的數據
mydba@192.168.85.132,3308 [sbtest]> create table sbtest_bak.sbtest1 select * from sbtest1;
ERROR 1786 (HY000): Statement violates GTID consistency: CREATE TABLE ... SELECT.
mydba@192.168.85.132,3308 [sbtest]> create table sbtest_bak.sbtest1 like sbtest1;
Query OK, 0 rows affected (0.02 sec)
mydba@192.168.85.132,3308 [sbtest]> insert into sbtest_bak.sbtest1 select * from sbtest1;
Query OK, 100 rows affected (0.00 sec)
Records: 100  Duplicates: 0  Warnings: 0

# 後續能夠檢測數據的一致性 
[root@ZST1 ~]# mysqldbcompare --server1=mydba:mysql5721@192.168.85.132:3308 --server2=mydba:mysql5721@192.168.85.132:3308 --changes-for=server2 --difftype=sql sbtest:sbtest_bak --run-all-tests
View Code

六、找到truncate的位置ide

# 3306解析truncate位置
[root@ZST1 logs]# mysqlbinlog -vv --base64-output=decode-rows mysql-bin.000013
...
COMMIT/*!*/;
# at 14270546
#180202 15:05:12 server id 1323306  end_log_pos 14270611 CRC32 0x582ae6bb       GTID    last_committed=8454     sequence_number=8455    rbr_only=no
SET @@SESSION.GTID_NEXT= '60863f8d-01af-11e8-bfdf-000c29c1025c:193543'/*!*/;
# at 14270611
#180202 15:05:12 server id 1323306  end_log_pos 14270702 CRC32 0xe3231860       Query   thread_id=7     exec_time=0     error_code=0
use `sbtest`/*!*/;
SET TIMESTAMP=1517555112/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
truncate table sbtest1
/*!*/;
# at 14270702
#180202 15:05:12 server id 1323306  end_log_pos 14270767 CRC32 0xaa411397       GTID    last_committed=8455     sequence_number=8456    rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= '60863f8d-01af-11e8-bfdf-000c29c1025c:193544'/*!*/;
# at 14270767

# 3306查看備份位置
[root@ZST1 backup]# more /data/backup/all_dump_1323306_`date +%Y%m%d`.sql
...
-- GTID state at the beginning of the backup 
-- SET @@GLOBAL.GTID_PURGED='60863f8d-01af-11e8-bfdf-000c29c1025c:1-188148';

-- Position to start replication or point-in-time recovery from
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000013', MASTER_LOG_POS=5165474;
View Code

所以備份點到truncate之間需補充的數據爲60863f8d-01af-11e8-bfdf-000c29c1025c:188149-193542
mysql-bin.000013 --start-position=5165474 --stop-position=14270546
七、恢復數據到truncate前的位置lua

# 恢復數據到truncate前的位置
[root@ZST1 logs]# mysqlbinlog mysql-bin.000013 --start-position=5165474 --stop-position=14270546 |mysql --login-path=1323308
View Code

此時3308實例已恢復到truncate操做點的一致性狀態,那是否是就到此結束呢?
若是咱們只須要還原數據到truncate時間點,那差很少完成~
若是咱們須要跳過誤刪除的命令,其餘操做繼續,那就得考慮是否存在關聯誤刪除的操做,以及這些操做對線上數據的影響是否能接受~
跳過誤刪除操做,應用後續日誌

# 誤刪除對應的事務
60863f8d-01af-11e8-bfdf-000c29c1025c:193543
mysql-bin.000013 --start-position=14270546 --stop-position=14270702

# 跳過誤刪除操做,應用後續日誌
[root@ZST1 logs]# mysqlbinlog mysql-bin.000013 --start-position=14270702 |mysql --login-path=1323308
ERROR 1062 (23000) at line 34: Duplicate entry '21' for key 'PRIMARY'
[root@ZST1 logs]#
View Code

爲何會有重複條目?sysbench邏輯以下:sysbench prepare:按照指定table-size往表sbtest*寫入數據sysbench run:根據key值(key受限於table-size)執行一系列的update、delete、insert操做,而且每個delete..where key=keydel後面緊接着insert..values(keydel),每一次刪除一條記錄,立刻寫入相同鍵值的記錄sysbench cleanup:刪除sbtest*表因爲binlog_format='row',在truncate後執行的delete沒有找到對應記錄,就不會記錄binlog,但緊接着的insert卻記錄到binlog。在咱們還原數據到truncate時間點前,應用truncate後的binlog時,在執行insert前沒有delete操做時就會遇到Duplicat entry的現象。若是binlog_format='statement'就不會出現這種狀況(上述操做都能進行),但這並不影響咱們推薦使用row格式~

相關文章
相關標籤/搜索