Qué hacer si el archivo ibd de la tabla de la base de datos MySQL se elimina por error

Hace muchos años, cuando estaba aprendiendo la tecnología de oracle10g, leí un artículo escrito por el maestro Gai Guoqiang. En el sistema Linux, cuando la base de datos de Oracle está viva, use el comando del sistema rm para eliminar un archivo de datos. En este momento, busque el fd del archivo eliminado. Puedes recuperar los archivos eliminados usando el identificador. Se sintió tan mágico en ese momento, e incluso hubo este tipo de operación de dolor.

Dado que la base de datos de Oracle puede restaurar archivos de datos eliminados, ¿puede reproducir una operación de espectáculo en la base de datos MySQL? La siguiente es la prueba de simulación que hice, echemos un vistazo.

Mesa de prueba simulada


[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)

Encuentre la IP del proceso de la base de datos 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

Ver el identificador de archivo utilizado por el proceso de la base de datos 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

Simular la eliminación del archivo ibd de la tabla de negocios


[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 accidentalmente realiza esta operación en un entorno de producción, se estima que ya está sudando frío a sus espaldas en este momento.


Verifique nuevamente el identificador de archivo utilizado por el proceso de la base de datos 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]# 

Esta tabla aún puede realizar operaciones DML dentro de un cierto rango de tiempo

[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    |
+----+-------+---------+

Para estar seguro, se recomienda bloquear esta mesa, solo leer la operación


[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

Encontrará que el archivo rm test1.ibd ahora se puede ver aquí. En este momento, lo que tenemos que hacer es copiar rápidamente este archivo.


[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

Puede ver que el archivo se ha recuperado por completo. En este momento, puede liberar el bloqueo de lectura de la tabla.


[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)

En este punto, puede reiniciar la base de datos MySQL sin ningún problema.

Resuma
por qué podemos restaurar el archivo ibd que rm eliminó de esta manera, principalmente porque cuando lo eliminamos con el comando rm, el proceso de la base de datos Mysql aún conserva el identificador del archivo ibd eliminado, que está en / proc / {It se puede encontrar en el directorio mysql_pid} / pd. Si reinicia la instancia de la base de datos Mysql en este momento, el proceso Mysql liberará el identificador del archivo eliminado y realmente no podrá acceder al archivo eliminado. En este caso , debe restaurar la tabla eliminada llevará mucho tiempo y será laborioso.

Supongo que te gusta

Origin blog.51cto.com/15061930/2642068
Recomendado
Clasificación