本站文章除注明转载外,均为本站原创: 转载自love wife & love life —Roger的Oracle&MySQL技术博客
本文链接地址: 无备份情况下恢复MySQL truncate table
近期陆续有客户遇到MySQL的数据库问题,最近正好开始研究MySQL的一些技术。大家都知道我之前是擅长Oracle恢复,如果不会MySQL 数据库恢复,总感觉却少一点什么。既然如此,就顺道研究一下吧。幸运的是,Google能够发现一些针对MySQL的恢复文章以及一些工具。
我们都知道,MySQL Server都很多存储引擎,并不是每种都可以进行异常情况之下都恢复,比如drop table/tuncate table/delete table/update table /drop database /又或者是ibdata文件损坏之类的。用的最多的就是Myisam和innodb存储引擎。目前基本上都是5.5+版本了,我想几乎没有人再去使用Myisam了吧。我这里所测试都5.6,5.7版本中默认都存储引擎已经是Innodb了。因此这里我以Innodb引擎为例子进行说明。
首先这里我要利用undrop_for_innodb 这个开源工具包(当然需要编译),目前该工具已经在2017年1月宣布闭源了,而且开始收费。但是我们仍然开源使用之前都开源工具包。另外这里可以告诉大家,不久的将来,odu 也会支持MySQL.
如下是我的truncate table 测试过程:
mysql> set global innodb_file_per_table=on; Query OK, 0 rows affected (0.00 sec) mysql> show global variables like '%file_per%'; +-----------------------+-------+ | Variable_name | Value | +-----------------------+-------+ | innodb_file_per_table | ON | +-----------------------+-------+ 1 row in set (0.00 sec) mysql> use recover; Database changed mysql> create table t_enmotech(a int); Query OK, 0 rows affected (0.01 sec) mysql> insert into t_enmotech values('9999'); Query OK, 1 row affected (0.00 sec) mysql> alter table t_enmotech add primary key(a); Query OK, 1 row affected (0.01 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> explain select * from t_enmotech where a=9999 ; +----+-------------+------------+-------+---------------+---------+---------+-------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------+---------------+---------+---------+-------+------+-------------+ | 1 | SIMPLE | t_enmotech | const | PRIMARY | PRIMARY | 4 | const | 1 | Using index | +----+-------------+------------+-------+---------------+---------+---------+-------+------+-------------+ 1 row in set (0.00 sec)
[root@killdb innodb_recovery]# mysqldump --opt -d -uroot -proger recover t_enmotech > /tmp/innodb_recovery/recover/t_enmotech.sql [root@killdb innodb_recovery]#
mysql> truncate table t_enmotech; Query OK, 0 rows affected (0.00 sec)
[root@killdb innodb_recovery]# ./stream_parser -f /var/lib/mysql/ibdata1 Opening file: /var/lib/mysql/ibdata1 File information: ID of device containing file: 64768 inode number: 924765 protection: 100660 (regular file) number of hard links: 1 user ID of owner: 496 group ID of owner: 491 device ID (if special file): 0 blocksize for filesystem I/O: 4096 number of blocks allocated: 69632 time of last access: 1496412155 Fri Jun 2 22:02:35 2017 time of last modification: 1496416863 Fri Jun 2 23:21:03 2017 time of last status change: 1496416863 Fri Jun 2 23:21:03 2017 total size, in bytes: 35651584 (34.000 MiB) Size to process: 35651584 (34.000 MiB) All workers finished in 0 sec
[root@killdb innodb_recovery]# ./stream_parser -f /dev/mapper/vg_oel6-lv_root -t 36000000k Opening file: /dev/mapper/vg_oel6-lv_root File information: ID of device containing file: 5 inode number: 6307 protection: 60660 (block device) number of hard links: 1 user ID of owner: 0 group ID of owner: 6 device ID (if special file): 64768 blocksize for filesystem I/O: 4096 number of blocks allocated: 0 time of last access: 1496411556 Fri Jun 2 21:52:36 2017 time of last modification: 1496113795 Tue May 30 11:09:55 2017 time of last status change: 1496113795 Tue May 30 11:09:55 2017 total size, in bytes: 0 (0.000 exp(+0)) Size to process: 36864000000 (34.332 GiB) Worker(0): 1.04% done. 2017-06-02 23:26:25 ETA(in 00:04:50). Processing speed: 119.792 MiB/sec Worker(0): 2.07% done. 2017-06-02 23:26:25 ETA(in 00:04:47). Processing speed: 119.767 MiB/sec Worker(0): 3.09% done. 2017-06-02 23:26:25 ETA(in 00:04:44). Processing speed: 119.767 MiB/sec Worker(0): 4.11% done. 2017-06-02 23:26:25 ETA(in 00:04:41). Processing speed: 119.773 MiB/sec Worker(0): 5.13% done. 2017-06-02 23:26:25 ETA(in 00:04:38). Processing speed: 119.773 MiB/sec Worker(0): 6.16% done. 2017-06-02 23:26:25 ETA(in 00:04:35). Processing speed: 119.787 MiB/sec Worker(0): 7.18% done. 2017-06-02 23:26:25 ETA(in 00:04:32). Processing speed: 119.767 MiB/sec Worker(0): 8.20% done. 2017-06-02 23:27:56 ETA(in 00:05:59). Processing speed: 89.829 MiB/sec Worker(0): 9.22% done. 2017-06-02 23:26:26 ETA(in 00:04:26). Processing speed: 119.776 MiB/sec Worker(0): 10.24% done. 2017-06-02 23:26:26 ETA(in 00:04:23). Processing speed: 119.773 MiB/sec ...... Worker(0): 96.10% done. 2017-06-02 23:26:36 ETA(in 00:00:11). Processing speed: 119.768 MiB/sec Worker(0): 97.12% done. 2017-06-02 23:26:36 ETA(in 00:00:08). Processing speed: 119.771 MiB/sec Worker(0): 98.14% done. 2017-06-02 23:26:36 ETA(in 00:00:05). Processing speed: 119.771 MiB/sec Worker(0): 99.17% done. 2017-06-02 23:26:36 ETA(in 00:00:02). Processing speed: 119.784 MiB/sec All workers finished in 306 sec [root@killdb innodb_recovery]#
[root@killdb innodb_recovery]# ./recover_dictionary.sh Generating dictionary tables dumps... OK Creating test database ... OK Creating dictionary tables in database test: SYS_TABLES ... OK SYS_COLUMNS ... OK SYS_INDEXES ... OK SYS_FIELDS ... OK All OK Loading dictionary tables data: SYS_TABLES ... 150 recs OK SYS_COLUMNS ... 243 recs OK SYS_INDEXES ... 120 recs OK SYS_FIELDS ... 122 recs OK All OK
mysql> use test; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select * from SYS_TABLES where name like 'recover/t_enmotech%'; +--------------------+-----+--------+------+--------+---------+--------------+-------+ | NAME | ID | N_COLS | TYPE | MIX_ID | MIX_LEN | CLUSTER_NAME | SPACE | +--------------------+-----+--------+------+--------+---------+--------------+-------+ | recover/t_enmotech | 181 | 1 | 1 | 0 | 0 | | 0 | +--------------------+-----+--------+------+--------+---------+--------------+-------+ 1 row in set (0.00 sec) mysql> select * from SYS_INDEXES where table_id=181; +----------+-----+---------+----------+------+-------+---------+ | TABLE_ID | ID | NAME | N_FIELDS | TYPE | SPACE | PAGE_NO | +----------+-----+---------+----------+------+-------+---------+ | 181 | 178 | PRIMARY | 1 | 3 | 0 | 552 | +----------+-----+---------+----------+------+-------+---------+ 1 row in set (0.00 sec)
[root@killdb innodb_recovery]# ./c_parser -6f pages-vg_oel6-lv_root/FIL_PAGE_INDEX/0000000000000178.page -t recover/t_enmotech.sql |head -10 -- Page id: 552, Format: COMPACT, Records list: Valid, Expected records: (0 0) -- Page id: 552, Found records: 0, Lost records: NO, Leaf page: YES -- Page id: 552, Format: COMPACT, Records list: Valid, Expected records: (0 0) -- Page id: 552, Found records: 0, Lost records: NO, Leaf page: YES -- Page id: 557, Format: COMPACT, Records list: Valid, Expected records: (1 1) 000000001306 870000013F0110t_enmotech 9999 -- Page id: 557, Found records: 1, Lost records: NO, Leaf page: YES -- Page id: 552, Format: COMPACT, Records list: Valid, Expected records: (0 0) -- Page id: 552, Found records: 0, Lost records: NO, Leaf page: YES -- Page id: 552, Format: COMPACT, Records list: Valid, Expected records: (0 0) [root@killdb innodb_recovery]#
[root@killdb innodb_recovery]# ./c_parser -6f pages-vg_oel6-lv_root/FIL_PAGE_INDEX/0000000000000178.page -t recover/t_enmotech.sql > dumps/default/t_enmotech 2> dumps/default/t_enmotech.sql [root@killdb innodb_recovery]# [root@killdb innodb_recovery]# ls -ltr dumps/default/t_enmotech* -rw-r--r--. 1 root root 222 Jun 3 06:04 dumps/default/t_enmotech.sql -rw-r--r--. 1 root root 1455 Jun 3 06:04 dumps/default/t_enmotech
mysql> use recover; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +-------------------+ | Tables_in_recover | +-------------------+ | t_enmotech | | t_recover | | test_0731 | | test_drop | +-------------------+ 4 rows in set (0.00 sec) mysql> source dumps/default/t_enmotech.sql Query OK, 0 rows affected (0.00 sec) Query OK, 3 rows affected (0.00 sec) Records: 3 Deleted: 0 Skipped: 0 Warnings: 0
mysql> select * from t_enmotech; +------+ | a | +------+ | 9999 | +------+ 1 row in set (0.00 sec)
mysql> show global variables like '%purge%'; +-------------------------+-------+ | Variable_name | Value | +-------------------------+-------+ | innodb_max_purge_lag | 0 | | innodb_purge_batch_size | 20 | | innodb_purge_threads | 0 | | relay_log_purge | ON | +-------------------------+-------+ 4 rows in set (0.00 sec)
mysql> show global variables like '%purge%'; +--------------------------------------+-------+ | Variable_name | Value | +--------------------------------------+-------+ | gtid_purged | | | innodb_max_purge_lag | 0 | | innodb_max_purge_lag_delay | 0 | | innodb_purge_batch_size | 300 | | innodb_purge_rseg_truncate_frequency | 128 | | innodb_purge_threads | 4 | | relay_log_purge | ON | +--------------------------------------+-------+ 7 rows in set (0.01 sec)