What to do if the MySQL database page is damaged, the innodb_force_recovery parameter can help you solve the problem

What to do if the MySQL database page is damaged, the innodb_force_recovery parameter can help you solve the problem

Sometimes, your MySQL database is a stand-alone machine with no master-slave and high availability. If there is a downtime or other abnormal conditions, your ibd file will be damaged. At this time, your MySQL database instance cannot be started, and you need to export it. The key data in the MySQL database, at this time the innodb_force_recovery parameter can save your life, first you need to understand the role of innodb_force_recovery.

innodb_force_recovery defaults to 0, innodb_force_recovery can be set from 1 to 6. The larger value includes all functions of the smaller value. For example, 3 contains all the functions of 1 and 2.

Set the innodb_force_recovery value to be equal to or less than 3. The MySQL database table is relatively safe. At this time, only some data on the damaged single page is lost. Setting a value of 4 or greater is very dangerous, and it may cause permanent damage to the page data.

To protect data, InnoDB will block INSERT, UPDATE or DELETE operations when innodb_force_recovery is greater than 0. Setting innodb_force_recovery to 4 or greater will put InnoDB in read-only mode.

Let's introduce the role of innodb_force_recovery setting various values
innodb_force_recovery=1 (SRV_FORCE_IGNORE_CORRUPT)
At this time, the MySQL database can run even if a damaged page is detected. You can try to make the SELECT * FROM tab skip the damaged index records and pages, and you can restore the undamaged business data.

innodb_force_recovery=2 (SRV_FORCE_NO_BACKGROUND)
prevents the master thread and any purge threads from running. If a crash occurs during a purge operation, this recovery value will prevent it.

innodb_force_recovery=3 (SRV_FORCE_NO_TRX_UNDO)
Do not perform transaction rollbacks after crash recovery.

innodb_force_recovery=4 (SRV_FORCE_NO_IBUF_MERGE)
prevents the insert buffer merge operation and does not calculate tablestatistics. At this time, the data file may be permanently damaged, and all secondary indexes need to be deleted and recreated.

innodb_force_recovery=5 (SRV_FORCE_NO_UNDO_LOG_SCAN)
Do not check undo logs when starting the database: InnoDB even treats unfinished transactions as committed. This value may permanently damage the data file. Set InnoDB to read-only.

innodb_force_recovery=6 (SRV_FORCE_NO_LOG_REDO)
does not perform redo log roll forward related to recovery. This value may permanently damage the data file. Make database pages out of date, which may cause more damage to B-trees and other database structures. Set InnoDB to read-only.

Create a simulation table

mysql> show create table t_test\G;
*************************** 1. row ***************************
       Table: t_test
Create Table: CREATE TABLE `t_test` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `k` int(12) unsigned NOT NULL DEFAULT '0',
  `c` char(120) NOT NULL DEFAULT '',
  `pad` char(60) NOT NULL DEFAULT '',
  `paymont` double(10,2) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `k_1` (`k`)
) ENGINE=InnoDB AUTO_INCREMENT=10002 DEFAULT CHARSET=utf8 MAX_ROWS=1000000
1 row in set (0.00 sec)

mysql> select * from t_test;
+----+---------+-------------+-------------+-----------+
| id | k       | c           | pad         | paymont   |
+----+---------+-------------+-------------+-----------+
|  1 | 4992833 | 83868641912 | 67847967377 | 200000.00 |
|  2 | 5019684 | 38014276128 | 23183251411 |      NULL |
|  3 | 5042604 | 33973744704 | 38615512647 |      NULL |
|  4 | 5020133 | 37002370280 | 63947013338 |      NULL |
|  5 | 4998122 | 44257470806 | 34551750492 |      NULL |
|  6 | 5005844 | 37216201353 | 05161542529 |      NULL |
|  7 | 5013709 | 33071042495 | 91798303270 |      NULL |
|  8 | 4999376 | 73754818686 | 76460662325 |      NULL |
|  9 | 5272683 | 26482547570 | 30508501104 |      NULL |
| 10 | 5033749 | 05677017559 | 29489382504 |      NULL |
| 11 | 5495590 | 69916792160 | 87387995487 |      NULL |
| 12 | 4877585 | 06636928111 | 89292458800 |      NULL |
+----+---------+-------------+-------------+-----------+
12 rows in set (0.00 sec)

Simulating table page damage
To simulate the t_test table page damage, it is actually very simple. You can use the vi tool to add N at the beginning of the t_test.ibd file! can

Restart the MySQL service After
simulating the damage, restart the MySQL database instance and watch the MySQL database error log at the same time

2020-09-01T12:58:25.207448Z 0 [Note] InnoDB: Loading buffer pool(s) from /u02/log/3308/iblog/ib_buffer_pool
2020-09-01T12:58:25.209575Z 0 [ERROR] InnoDB: Space ID in fsp header is 134217728, but in the page header it is 660067840.
2020-09-01T12:58:25.331762Z 0 [ERROR] [FATAL] InnoDB: Tablespace id is 48 in the data dictionary but in file ./sbtest/t_test.ibd it is 18446744073709551615!
2020-09-01 20:58:25 0x7ffb8d022700  InnoDB: Assertion failure in thread 140718379247360 in file ut0ut.cc line 942
InnoDB: We intentionally generate a memory trap.
InnoDB: Submit a detailed bug report to http://bugs.mysql.com.
InnoDB: If you get repeated assertion failures or crashes, even
InnoDB: immediately after the mysqld startup, there may be
InnoDB: corruption in the InnoDB tablespace. Please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.7/en/forcing-innodb-recovery.html

InnoDB: about forcing recovery.

Did you see it? At this time, the database instance cannot be started normally because the Tablespace id recorded in the header of the t_test.ibd file is inconsistent with the data dictionary. How to do

Set innodb_force_recovery
because at this time the Tablespace id recorded in the header of the t_test.ibd file is inconsistent with the data dictionary, you can only add innodb_force_recovery=4 to the my.cnf file, and then start the MySQL database instance

mysql> show tables;
+------------------+
| Tables_in_sbtest |
+------------------+
| sbtest1          |
| t_pay_test       |
| t_test           |
+------------------+
3 rows in set (0.00 sec)

mysql> select * from t_test;
ERROR 1812 (HY000): Tablespace is missing for table `sbtest`.`t_test`.
mysql>
mysql> drop table t_test;

Query OK, 0 rows affected (0.02 sec)

Since the t_test.ibd file cannot be recognized at this time, the t_test table can only be dropped at this time.
If you just damage the page data, you can use the following SQL statement to restore business data

insert ignore into t_test_recovery select * from t_test limit 5;
insert ignore into t_test_recovery select * from t_test limit 10;

What to do if the MySQL database page is damaged? The innodb_force_recovery parameter can help you solve the problem
https://mp.weixin.qq.com/s/l6KZP4glnwwuDQxU98A0Mw

Guess you like

Origin blog.csdn.net/qq_40907977/article/details/114842270