MySQL uses ibd files to restore data skills?

Accidents such as hard disk bad sectors and power outages are not normal, but it is enough for you to be "thrilling" if you encounter them! What should I do if the data is lost due to database corruption and Binlog is no longer available? In order to restore data without loss in a short period of time to ensure business stability, in addition to using binlog, we also practiced a new recovery skill!

Remember what we wrote before, "Just One Trick, Let Out-of-Control R&D Fall in Love with You"? As mentioned earlier, the two database recovery methods we use more frequently are:

MySQL uses ibd files to restore data skills?  MySQL uses ibd files to restore data skills?

Both of the above two methods can achieve real-time rollback, but do you think that these two skills are enough?

No….!

In this intricate online structure, there are actually many unknown reasons that we cannot predict. For example, the following situation:

The disk that has lost its life due to hard work has grown bad sectors, resulting in database corruption. And just damaged the ibdata file and binlog file. Then if you still think about the plan of timing backup + binlog recovery, it is impossible. Can you only use fixed-point backup to restore files? After careful consideration, as an operation and maintenance personnel, we will never implement a lossy rollback as a last resort, because it will have too much impact on the business, but what else can we do? Next we will put a big move! ! !

First check the database environment, whether the independent table space is enabled, if it is enabled, then congratulations, there is a great chance that all data can be recovered. We can rely on the frm and ibd files in each database directory to achieve data recovery. Generally speaking, if InnoDB is used but the independent table space is not enabled, all database table information and metadata will be written into the ibdata file, which lasts for a long time. If it is running, the ibdata file will become larger and larger, and the performance of the database will decrease. InnoDB provides a parameter to enable the independent table space, which allows the data to be stored independently. In this way, the ibdata file is only used to store some engine-related index information, and the actual data is written into the independent frm and ibd files.

Well, with the frm and ibd files, we can start to try data recovery. His process is more thrilling and interesting than binlog recovery! First, let's take a look at the description of ibd and frm:

.frm file: saves the metadata of each table, including the definition of the table structure, etc. This file has nothing to do with the database engine.

.ibd file: The InnoDB engine opens the independent table space (configure innodb_file_per_table = 1 in my.ini) to store the data and index files of the table.

We all know that for the InnoDB database, if you do not copy the entire data directory, but only copy the specified database directory to the new instance, the database will not be recognized. So how to restore the database based on these two files?

Recovery ideas:

Since some index information about the engine is stored in the ibdata file, if the ibdata file is damaged, the table name index is lost and cannot be started. Then we can first rename the original old entire data directory for backup, then reinitialize the database to generate a new ibdata file, then recreate the original database and corresponding tables, and finally change the backup tablespace id number to the newly created tablespace id number (the ibdata file has a unique table space index id for each table, and the id is incremented by the number of new tables created), so that the original database can be restored.
For example:
library name: test_restore
table structure: db_struc.sql
table file: G_RESTORE.ibd, G_RESTORE.frm

1. Create a new library and import the table structure

#mysql -uroot –p****  -e “create database test_restore”

#mysql -uroot –p****  test_restore < db_struc.sql

2. View and modify the id of the table in the test_restore library in the new instance

#vim -b /data/database/mysql/test_restore/G_RESTORE.ibd

Open it directly as garbled characters, and convert it to hexadecimal for viewing. Execute in Vi:%!xxd to convert to hexadecimal. The result is:

MySQL uses ibd files to restore data skills?  MySQL uses ibd files to restore data skills?

as the picture shows. The id of the G_RESTORE table in the mysql database is 00fe.

Modify the backup G_RESTORE.ibd file. The operation is the same as above, but please make a backup first.

#cp G_RESTORE.ibd{,_back}

#vim -v G_RESTORE.ibd

MySQL uses ibd files to restore data skills?  MySQL uses ibd files to restore data skills?

Change 011b to 00fe. Notice. After the modification is completed, it needs to be executed in vim first: %!xxd -r

Then wq to save and exit the file. Otherwise, what is saved is the result of the hexadecimal view.

Save the result as follows:

MySQL uses ibd files to restore data skills?  MySQL uses ibd files to restore data skills?

Replace the modified G_RESTORE.ibd with the G_RESTORE.ibd file in the new database.

Explanation about ibdata table id:

MySQL uses ibd files to restore data skills?  MySQL uses ibd files to restore data skills?

Refer to the official documentation to explain that each table space is allocated 4 bytes to store the table space id information, and the final offset address is 38. There is also a set of reserved table space ids, which are also 4 bytes, and the final offset address is 42.

3. Verify and restore mysql data

close mysql. Modify my.conf.
innodb_force_recovery=6 innodb_purge_threads=0

Start the database. If not modified. The database will think G_RESTORE has been corrupted.

Click Select to view the restoration result, but an error will be reported when inserting data at this time. You should dump the data as soon as possible and import it back to the original instance.

Export the data, then import the data, and the recovery is complete!

#mysqldump -uroot –p****** test_restore > test_restore.sql

#mysql -uroot –p****** test_restore < test_restore.sql

Explanation: After the new space id is changed, the .ibd table file can only recognize the data after starting the database, but cannot write in. This is because the original ibdata file not only saves the space id index, but also saves some other elements at the same time. data. In order to complete the metadata, the operation of export and import is adopted.

The above example is the recovery process of a single database table. You will definitely have another question when you see this, right? It is impossible to have only one table in the online scene. In the case of many database tables, the speed of modifying each table is undoubtedly too slow. So how to recover when there are a large number of tables? The idea is to obtain the id values ​​of the backed up ibd files, build tables in the order of id values, and use random table creation statements in the middle span to make up enough numbers (the index id of each table space is incremented by the number of new tables created). The implementation is as follows:

1. Obtain the space id numbers of the backup database ibd files and sort them.

for ibd in `find test_restore/ -name “*.ibd”` ; do  echo -e “${ibd/ }   /c” ;hexdump -C ${ibd} |head -n 3 |tail -n 1|awk ‘{print  strtonum(“0x”$6$7)}’ ;done | sort -n  -k 3 | column -t > /tmp/

The generated ibd.txt file has the following format: (library name-table name-SpaceId)

MySQL uses ibd files to restore data skills?  MySQL uses ibd files to restore data skills?


2. Create a new table and view the current tablespace id (assuming the space id is 10)

#mysql -uroot –p****** -e”create table test.tt(a bool)”

#hexdump -C mysql/test/tt.ibd |head -n 3 |tail -n 1|awk ‘{print  strtonum(“0x”$6$7)}’

3. First create all libraries, prepare all table structures, write scripts , and automatically create new tables based on the space id number

Prepare the database table structure, which can be taken from the backup file (our backup method is to back up the structure and data separately), or backed up and copied from other servers with the same table structure.

Refer to the backup statement:

mysqldump -uroot –p****** -d ${db} –T /data/backup/${db}/

Create the original database:

mysql -uroot –p****** -e “create database ${db}”

Restoring the table id to create a table script :

#!/bin/bash #Because the previous assumption is 10, so create 
oid=11 
from 11 
#Open the ibd.txt file generated earlier, read "library name-table name-SpaceId" by line 
cat /tmp/ibd. txt | while read db tb id ;do 
#If we need to restore the category table, its id is 415, based on the principle that the id is the self-increment of the table, that is, 415-11=404, #We also need to create 
404 tables in a loop , before actually importing the category table structure. 
for ((oid;oid<id;oid++)); do 
mysql -uroot –p****** -e “create table test.t(a bool);drop table test.t;” && echo “${ oid} ok” 
done 
#Create 404 tables in a loop, the id is 415, which is consistent with the number of the original backup .ibd file, import the table structure 
mysql -uroot –p****** ${db} < /data/backup /${db}/${tb%%.ibd}.sql && echo “${oid} ${db}/${tb%%.ibd}.sql ok” 
let oid=oid+1 
done


4. Check whether the tablespace id is consistent with the backup

for ibd in `find test_restore/ -name “*.ibd”` ; do  echo -e “${ibd/ }   /c” ;hexdump -C ${ibd} |head -n 3 |tail -n 1|awk ‘{print  strtonum(“0x”$6$7)}’ ;done | sort -n  -k 3 | column -t > /tmp/ibd2.txt

After confirming the consistency, copy the backup .ibd file to the new database instance directory and modify my.cnf

innodb_force_recovery=6

innodb_purge_threads=0

Start the database. The follow-up steps are similar to single table recovery, just export and restore to the original instance.

Of course, this method is a method that has to be adopted in the extreme situation of the database. The most important thing online is to do master-slave synchronization and regular backup to avoid such risks.

About InnoDB engine independent table space description:

For students who have used MySQL, the MyISAM table engine is the most in contact with at the beginning. The database of this engine will create three files: table structure, table index, and table data space. We can migrate a database directory directly to other databases and it will work fine. However, when you use InnoDB, everything changes.

By default, InnoDB will store all database InnoDB engine table data in a shared space: ibdata1, which feels uncomfortable. When adding or deleting databases, the ibdata1 file will not automatically shrink, and the backup of a single database will also become a problem. Usually, the data can only be exported using mysqldump, and then imported to solve this problem.

However, the independent table space mode can be enabled by modifying the innodb_file_per_table parameter in the [mysqld] section of the MySQL configuration file, and each table of each database will generate a data space.

advantage:

1. Each table has its own independent table space.

2. The data and indexes of each table will exist in its own table space.

3. A single table can be moved between different databases.

4. The space can be reclaimed (except for the drop table operation, the empty table cannot be reclaimed by itself)

a) The Drop table operation automatically reclaims the table space. For statistical analysis or daily value tables, after deleting a large amount of data, you can use: alter table TableName engine=innodb; to retract the unused space.

b) Using turncate table for Innodb that uses innodb-plugin will also shrink the space.

c) For a table that uses an independent table space, no matter how it is deleted, the fragmentation of the table space will not seriously affect the performance, and there is still a chance to deal with it.

shortcoming:

The increase of a single table is too large, such as more than 100 G.

in conclusion:

Shared table space has few advantages in Insert operation. No other independent table space performs well. When enabling the independent table space, please adjust it reasonably: innodb_open_files.

Configuration method:
1. innodb_file_per_table setting. Opening method:

Set under [mysqld] in my.cnf

innodb_file_per_table=1
2. Check whether it is enabled:
mysql> show variables like '%per_table%';

3. Close the exclusive table space
innodb_file_per_table=0 close the independent table space

mysql> show variables like ‘%per_table%’;

Guess you like

Origin blog.csdn.net/yaxuan88521/article/details/132555207