Que faire si le fichier ibd de la table de base de données MySQL est supprimé par erreur

Il y a de nombreuses années, lors de l'apprentissage de la technologie oracle10g, j'ai lu un article écrit par le professeur Gai Guoqiang. Dans le système Linux, lorsque la base de données oracle est active, utilisez la commande système rm pour supprimer un fichier de données. À ce stade, recherchez le fd du fichier supprimé. Vous pouvez récupérer les fichiers supprimés en utilisant le handle. Cela semblait tellement magique à l'époque, et il y avait même ce genre d'opération de tristesse.

Étant donné que la base de données oracle peut restaurer des fichiers de données supprimés, pouvez-vous jouer une telle opération show dans la base de données MySQL? Voici le test de simulation que j'ai effectué, jetons un coup d'œil.

Table de test simulée


[root@localhost] 10:18:14 [(none)]>use testdb;
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
[root@localhost] 10:18:19 [testdb]>
[root@localhost] 10:18:20 [testdb]>show tables;
+------------------+
| Tables_in_testdb |
+------------------+
| t_test           |
| test1            |
+------------------+
2 rows in set (0.00 sec)

[root@localhost] 10:18:24 [testdb]>select * from test1;
+----+-------+-------+
| id | name | name2 |
+----+-------+-------+
|  1 | test1 | test1 |
|  2 | test  | test  |
+----+-------+-------+
2 rows in set (0.01 sec)

Trouvez l'adresse IP du processus de base de données Mysql


[root@mysql ~]# ps -ef|grep -i mysqld|grep -i basedir|grep -v grep
mysql      7988   7159  1 10:17 pts/0    00:00:02 /data/mysql-5.7.26/bin/mysqld --defaults-file=/data/mysql/conf/3306/my.cnf --basedir=/data/mysql-5.7.26 --datadir=/data/mysql/data/3306 --plugin-dir=/data/mysql-5.7.26/lib/plugin --log-error=/data/mysql/log/3306/error.log --open-files-limit=65535 --pid-file=/data/mysql/run/3306/mysql.pid --socket=/data/mysql/run/3306/mysql.sock --port=3306

Afficher le descripteur de fichier utilisé par le processus de base de données Mysql


[root@mysql ~]# cd /proc/7988/fd
[root@mysql fd]# ll
总用量 0
lr-x------ 1 mysql mysql 64 9月  18 10:18 0 -> /dev/null
lrwx------ 1 mysql mysql 64 9月  18 10:18 42 -> /data/mysql/data/3306/mysql/tables_priv.MYD
lrwx------ 1 mysql mysql 64 9月  18 10:18 43 -> /data/mysql/data/3306/mysql/columns_priv.MYI
lrwx------ 1 mysql mysql 64 9月  18 10:18 44 -> /data/mysql/data/3306/mysql/columns_priv.MYD
lrwx------ 1 mysql mysql 64 9月  18 10:18 45 -> /data/mysql/data/3306/mysql/procs_priv.MYI
lrwx------ 1 mysql mysql 64 9月  18 10:18 46 -> /data/mysql/data/3306/mysql/procs_priv.MYD
lrwx------ 1 mysql mysql 64 9月  18 10:18 47 -> /data/mysql/data/3306/mysql/servers.ibd
lrwx------ 1 mysql mysql 64 9月  18 10:18 48 -> /data/mysql/data/3306/mysql/slave_master_info.ibd
lrwx------ 1 mysql mysql 64 9月  18 10:18 49 -> /data/mysql/data/3306/mysql/slave_relay_log_info.ibd
lrwx------ 1 mysql mysql 64 9月  18 10:18 5 -> /tmp/ibTITlZK (deleted)
lrwx------ 1 mysql mysql 64 9月  18 10:18 50 -> /data/mysql/data/3306/mysql/slave_worker_info.ibd
lrwx------ 1 mysql mysql 64 9月  18 10:18 51 -> /data/mysql/data/3306/mysql/event.MYI
lrwx------ 1 mysql mysql 64 9月  18 10:18 52 -> /data/mysql/data/3306/mysql/event.MYD
lrwx------ 1 mysql mysql 64 9月  18 10:21 53 -> socket:[39748]
lrwx------ 1 mysql mysql 64 9月  18 10:21 54 -> /data/mysql/data/3306/query_rewrite/rewrite_rules.ibd
lrwx------ 1 mysql mysql 64 9月  18 10:21 55 -> /data/mysql/data/3306/testdb/test1.ibd
lrwx------ 1 mysql mysql 64 9月  18 10:18 6 -> /tmp/ib3ojR5h (deleted)
lrwx------ 1 mysql mysql 64 9月  18 10:18 7 -> /tmp/ib9mkncP (deleted)
lrwx------ 1 mysql mysql 64 9月  18 10:18 8 -> /tmp/ibrfgk1T (deleted)
lrwx------ 1 mysql mysql 64 9月  18 10:18 9 -> /data/mysql/log/3306/redo/ib_logfile1

Simuler la suppression du fichier ibd de la table métier


[mysql@mysql testdb]$ ls -l
total 728
-rw-rw-r--. 1 mysql mysql 485385 Jul 14 11:11 a.log
-rw-r-----. 1 mysql mysql     67 Jul 13 17:20 db.opt
-rw-r-----  1 mysql mysql   8618 Sep 18 10:31 test1.frm
-rw-r-----  1 mysql mysql  98304 Sep 18 10:32 test1.ibd
-rw-r-----. 1 mysql mysql   8618 Sep  9 15:23 t_test.frm
-rw-r-----. 1 mysql mysql 131072 Sep  9 15:25 t_test.ibd
[mysql@mysql testdb]$
[mysql@mysql testdb]$ rm test1.ibd
[mysql@mysql testdb]$ ls -l
total 632
-rw-rw-r--. 1 mysql mysql 485385 Jul 14 11:11 a.log
-rw-r-----. 1 mysql mysql     67 Jul 13 17:20 db.opt
-rw-r-----  1 mysql mysql   8618 Sep 18 10:31 test1.frm
-rw-r-----. 1 mysql mysql   8618 Sep  9 15:23 t_test.frm
-rw-r-----. 1 mysql mysql 131072 Sep  9 15:25 t_test.ibd

Si vous effectuez accidentellement cette opération dans un environnement de production, on estime que vous êtes déjà en sueur froide derrière le dos à ce moment.


Vérifiez à nouveau le descripteur de fichier utilisé par le processus de base de données Mysql


[root@mysql fd]# ls -l
lrwx------ 1 mysql mysql 64 9月  18 10:18 46 -> /data/mysql/data/3306/mysql/procs_priv.MYD
lrwx------ 1 mysql mysql 64 9月  18 10:18 47 -> /data/mysql/data/3306/mysql/servers.ibd
lrwx------ 1 mysql mysql 64 9月  18 10:18 48 -> /data/mysql/data/3306/mysql/slave_master_info.ibd
lrwx------ 1 mysql mysql 64 9月  18 10:18 49 -> /data/mysql/data/3306/mysql/slave_relay_log_info.ibd
lrwx------ 1 mysql mysql 64 9月  18 10:18 5 -> /tmp/ibTITlZK (deleted)
lrwx------ 1 mysql mysql 64 9月  18 10:18 50 -> /data/mysql/data/3306/mysql/slave_worker_info.ibd
lrwx------ 1 mysql mysql 64 9月  18 10:18 51 -> /data/mysql/data/3306/mysql/event.MYI
lrwx------ 1 mysql mysql 64 9月  18 10:18 52 -> /data/mysql/data/3306/mysql/event.MYD
lrwx------ 1 mysql mysql 64 9月  18 10:21 53 -> socket:[39748]
lrwx------ 1 mysql mysql 64 9月  18 10:21 54 -> /data/mysql/data/3306/query_rewrite/rewrite_rules.ibd
lrwx------ 1 mysql mysql 64 9月  18 10:21 55 -> /data/mysql/data/3306/testdb/test1.ibd (deleted)
lrwx------ 1 mysql mysql 64 9月  18 10:18 6 -> /tmp/ib3ojR5h (deleted)
lrwx------ 1 mysql mysql 64 9月  18 10:18 7 -> /tmp/ib9mkncP (deleted)
lrwx------ 1 mysql mysql 64 9月  18 10:18 8 -> /tmp/ibrfgk1T (deleted)
lrwx------ 1 mysql mysql 64 9月  18 10:18 9 -> /data/mysql/log/3306/redo/ib_logfile1
[root@mysql fd]# 

Cette table peut toujours effectuer des opérations DML dans une certaine plage de temps

[root@localhost] 10:49:54 [testdb]>update test1 set name2='dsljfld' where id=2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0
[root@localhost] 10:50:12 [testdb]>select * from test1;
+----+-------+---------+
| id | name  | name2   |
+----+-------+---------+
|  1 | test1 | test1   |
|  2 | test  | dsljfld |
+----+-------+---------+
2 rows in set (0.00 sec)
[root@localhost] 10:50:36 [testdb]>insert into test1 values(3,'dsf','sfsf');
Query OK, 1 row affected (0.01 sec)
[root@localhost] 10:50:45 [testdb]>select * from test1;
+----+-------+---------+
| id | name  | name2   |
+----+-------+---------+
|  1 | test1 | test1   |
|  2 | test  | dsljfld |
|  3 | dsf   | sfsf    |
+----+-------+---------+

Par mesure de sécurité, il est recommandé de verrouiller cette table, lire uniquement l'opération


[root@localhost] 10:58:17 [testdb]>lock tables test1 read;
Query OK, 0 rows affected (0.00 sec)

[root@localhost] 10:59:07 [testdb]>
[root@localhost] 10:59:09 [testdb]>insert into test1 values(4,'esdsf','dfesfsf');
ERROR 1099 (HY000): Table 'test1' was locked with a READ lock and can't be updated

Vous constaterez que le fichier rm test1.ibd vient d'être vu ici. À ce stade, ce que nous devons faire est de recopier rapidement ce fichier.


[mysql@mysql fd]$ cp /proc/9015/fd/54 /data/mysql/data/3306/testdb/test1.ibd

[mysql@mysql testdb]$ ls -l
total 728
-rw-rw-r--. 1 mysql mysql 485385 Jul 14 11:11 a.log
-rw-r-----. 1 mysql mysql     67 Jul 13 17:20 db.opt
-rw-r-----  1 mysql mysql   8618 Sep 18 10:31 test1.frm
-rw-r-----  1 mysql mysql  98304 Sep 18 11:01 test1.ibd
-rw-r-----. 1 mysql mysql   8618 Sep  9 15:23 t_test.frm
-rw-r-----. 1 mysql mysql 131072 Sep  9 15:25 t_test.ibd

Vous pouvez voir que le fichier a été complètement récupéré. À ce stade, vous pouvez libérer le verrou de lecture de la table


[root@localhost] 11:02:56 [testdb]>unlock tables;Query OK, 0 rows affected (0.00 sec)

[root@localhost] 11:03:25 [testdb]>insert into test1 values(4,'esdsf','dfesfsf');
Query OK, 1 row affected (0.00 sec)

À ce stade, vous pouvez redémarrer la base de données MySQL sans aucun problème.

Résumez
pourquoi nous pouvons restaurer le fichier ibd qui a été déposé par rm de cette manière, principalement parce que lorsque nous le supprimons avec la commande rm, le processus de base de données Mysql détient toujours le handle du fichier ibd supprimé, qui se trouve dans / proc / {It se trouve dans le répertoire mysql_pid} / pd. Si vous redémarrez l'instance de base de données Mysql à ce moment, le processus Mysql libérera le handle du fichier supprimé et vous ne pourrez vraiment pas accéder au fichier supprimé. Dans ce cas , vous devez restaurer la table supprimée sera longue et laborieuse.

Je suppose que tu aimes

Origine blog.51cto.com/15061930/2642068
conseillé
Classement