mysql5.7.33 실수로 ibdata 파일을 삭제하여 데이터 검색

1. 장면 설명 :

대부분의 경우 MySQL 데이터베이스를 시작할 수 없기 때문에 데이터에 액세스 할 수 없지만 일반적으로 응용 프로그램 데이터는 손실되지 않지만 시스템 테이블 공간과 같은 다른 파일이 손상되거나 MySQL 버그가 발생합니다.
이때 백업이 없으면 많은 사람들이 데이터가 손실되었다고 생각하지만 실제로는 대부분의 시간 동안 데이터를 저장할 수 있습니다.
MyISAM 엔진의 테이블 스페이스의 경우 해당 데이터 파일을 새 데이터베이스에 직접 복사하기 만하면 데이터를 복원 할 수 있습니다.
InnoDB 엔진의 데이터베이스 테이블 스페이스의 경우 테이블 스페이스를 전송하여 데이터를 복구 할 수 있습니다.
전제는 MySQL이 매개 변수 innodb_file_per_table = 1 개의 독립 테이블 스페이스 파일을 활성화 한 것입니다 .

MySQL 데이터 테이블 스페이스 파일 ibdata 파일이 손상되었거나 수정 또는 삭제되지 않으면 MySQL 서비스가 다시 시작되지 않습니다. 동시에 MySQL 데이터는 제 시간에 백업되지 않습니다. 이때 가능한 한 많은 MySQL 데이터를 검색하려면 어떻게해야합니까? ?

2. 사례 데모 :

2.1. MySQL 실패를 확인하기 전에 라이브러리의 각 테이블에는 몇 개의 레코드가 있습니까?

for n in `mysql -e "use  db_bbs;show tables;"|sed '1d'`;do echo $n; mysql -e "use  db_bbs;select count(*) from $n;";done >test.txt

MySQL 실패를 확인하기 전에 라이브러리에있는 테이블 수 :

一共是39张表:
[root@10-10-127-11 ~]# mysql -e "use db_bbs;show tables;"|sed '1d'|wc -l
39

2.2. ibdata 삭제 실패 시뮬레이션 :

ibdata 파일 삭제 (프로덕션 환경에서는 금지됨)

innodb_force_recovery = 6 현재 MySQL 서비스를 시작하려면 MySQL의 필수 시작 매개 변수를 사용하지만 더 이상 도움이되지 않습니다. 데이터 테이블 스페이스 파일이므로 ibdata 파일이 삭제되어 현재 MySQL 서비스를 시작할 수 없습니다.
MySQL에서 사용하는 innodb 엔진 때문입니다. 그리고 독립 테이블 스페이스 매개 변수 innodb_file_per_table = 1이 켜집니다. 따라서 이때 전송 테이블 스페이스를 사용하여 데이터를 복구 할 수 있습니다.

2.3. 데이터 검색 방법 :

먼저 누락 된 테이블 구조를 만듭니다.

먼저 실패한 MySQL 서버에 mysql-utilities를 설치합니다.
yum -y install mysql-utilities
mysqlfrm을 사용하여 .frm 파일에서 테이블 생성 문을 검색합니다.

.frm 파일을 분석하여 테이블 작성을위한 명령문 생성

mysqlfrm --diagnostic  
[root@test02 db_bbs]# mysqlfrm --diagnostic /data/mysql/data/db_bbs/t_admin.frm  |grep -v "^#"
CREATE TABLE `db_bbs`.`t_admin` (
  `f_id` int(4) NOT NULL AUTO_INCREMENT, 
  `f_type` tinyint(1) NOT NULL, 
  `f_username` varchar(80) NOT NULL, 
  `f_password` varchar(80) NOT NULL, 
  `f_nick_name` varchar(80) NOT NULL, 
  `f_real_name` varchar(80) NOT NULL, 
  `f_create_time` bigint(4) NOT NULL, 
  `f_update_time` bigint(4) NOT NULL, 
  `f_last_login_time` bigint(4) DEFAULT NULL, 
  `f_last_login_ip` varchar(80) DEFAULT NULL, 
  `f_status` tinyint(1) NOT NULL, 
PRIMARY KEY `PRIMARY` (`f_id`) USING BTREE
) ENGINE=InnoDB ROW_FORMAT = 2;

모든 테이블 생성 문을 /tmp/create.sql 파일로 가져옵니다.

[root@test02 ~]# cd /data/mysql/data/db_bbs/
[root@test02 db_bbs]# for n in `ls -l  /data/mysql/data/db_bbs/*.frm|awk -F '/' '{print $NF}'|xargs -n 40`;do mysqlfrm --diagnostic $n|grep -v "^#" >>/tmp/create.sql;done  

프로덕션 테이블 생성 문을 새 MySQL 인스턴스 데이터베이스로 가져옵니다.

[root@10-10-127-11 ~]# mysql db_bbs < create.sql 
ERROR 1064 (42000) at line 2: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '5' at line 10
原因是获取到的建表sql中包含了ROW_FORMAT = 2 这样的参数导致的

### 테이블 작성 명령문에서 ROW_FORMAT = 2, ROW_FORMAT = 5가 포함 된 문자를 제거하고 테이블 작성 명령문을 다시 가져 오십시오. ###

일괄 교체 명령은 다음과 같습니다.

cat /tmp/create.sql|sed -e 's/ENGINE=InnoDB ROW_FORMAT = 2;/ENGINE=InnoDB ;/g'|grep ROW_FORMAT |uniq -c
cat /tmp/create.sql|sed -e 's/ENGINE=InnoDB ROW_FORMAT = 5;/ENGINE=InnoDB ;/g'|grep ROW_FORMAT |uniq -c
sed -i 's/ENGINE=InnoDB ROW_FORMAT = 2;/ENGINE=InnoDB ;/g' /tmp/create.sql
sed -i 's/ENGINE=InnoDB ROW_FORMAT = 5;/ENGINE=InnoDB ;/g' /tmp/create.sql
cat /tmp/create.sql|grep ROW_FORMAT |uniq -c 

테이블 생성 문을 새 MySQL 인스턴스 db_bbs 라이브러리로 내 보내면 오류 필드가 너무 깁니다.

[root@10-10-127-11 ~]# mysql db_bbs -f < create.sql 
ERROR 1074 (42000) at line 232: Column length too big for column 'f_content' (max = 16383); use BLOB or TEXT instead
ERROR 1074 (42000) at line 299: Column length too big for column 'f_desc' (max = 16383); use BLOB or TEXT instead
ERROR 1074 (42000) at line 365: Column length too big for column 'f_body_image' (max = 16383); use BLOB or TEXT instead
ERROR 1074 (42000) at line 406: Column length too big for column 'f_content' (max = 16383); use BLOB or TEXT instead
ERROR 1074 (42000) at line 433: Column length too big for column 'f_summary' (max = 16383); use BLOB or TEXT instead

필드 길이 유형을 수정 한 후 테이블 작성 SQL을 새 MySQL 데이터베이스로 다시 가져옵니다.

[root@10-10-127-11 ~]# mysql db_bbs -f < create.sql  
[root@10-10-127-11 ~]# 
[root@10-10-127-11 ~]# 
[root@10-10-127-11 ~]# mysql -e "use db_bbs;show tables;"|sed '1d'|wc -l
39

### 새로 생성 된 MySQL 인스턴스의 데이터가 포함되지 않은 .ibd 파일을 삭제 한 다음 실패한 데이터베이스의 .idb 파일을 가져옵니다. ###

새로 생성 된 라이브러리의 데이터 .ibd 파일을 삭제합니다.

mysql -e "show tables from db_bbs" | grep -v  Tables_in_db_bbs| while read a; do mysql -e  "ALTER TABLE db_bbs.$a DISCARD TABLESPACE" ;done
[root@10-10-127-11 db_bbs]# ll *.ibd|wc -l
39
[root@10-10-127-11 db_bbs]# mysql -e "show tables from db_bbs" | grep -v  Tables_in_db_bbs| while read a; do mysql -e  "ALTER TABLE db_bbs.$a DISCARD TABLESPACE" ;done
[root@10-10-127-11 db_bbs]# ll *.ibd|wc -l
ls: cannot access *.ibd: No such file or directory

0

* 모든 .idb 파일이 삭제되었음을 알 수 있습니다. 그런 다음 데이터가 포함 된 이전 .ibd 파일을이 새 MySQL 인스턴스의 ./data/db_bbs/ 디렉토리에 복사하고 소유자 (chown mysql.)를 변경 한 다음 이러한 데이터 파일을 데이터베이스 **로 가져옵니다.


[root@test02 db_bbs]# scp *.ibd [email protected]:/data/mysql/data/db_bbs/
[email protected]'s password: 
browse_record.ibd                                                                                                                        100%  100MB  50.0MB/s   00:02    
t_admin.ibd                  
........
........
[root@10-10-127-11 db_bbs]# ll *.ibd|wc -l
39
[root@10-10-127-11 db_bbs]# ll *.ibd
-rw-r----- 1 root root 104857600 Mar 14 21:56 browse_record.ibd
-rw-r----- 1 root root     98304 Mar 14 21:56 t_admin.ibd
-rw-r----- 1 root root     98304 Mar 14 21:56 t_anonymous_code.ibd
-rw-r----- 1 root root     98304 Mar 14 21:56 t_apply.ibd
-rw-r----- 1 root root   9437184 Mar 14 21:56 t_attach.ibd
-rw-r----- 1 root root    147456 Mar 14 21:56 t_banner.ibd
-rw-r----- 1 root root    163840 Mar 14 21:56 t_banner_log.ibd
-rw-r----- 1 root root    114688 Mar 14 21:56 t_black_ip.ibd
-rw-r----- 1 root root     98304 Mar 14 21:56 t_black_user.ibd
-rw-r----- 1 root root     98304 Mar 14 21:56 t_block_userbaseinfo.ibd
-rw-r----- 1 root root     98304 Mar 14 21:56 t_collect.ibd
-rw-r----- 1 root root     98304 Mar 14 21:56 t_country_code.ibd
-rw-r----- 1 root root    163840 Mar 14 21:56 t_ct_goods.ibd
-rw-r----- 1 root root    131072 Mar 14 21:56 t_ct_goods_record.ibd
-rw-r----- 1 root root   9437184 Mar 14 21:56 t_ct_integral.ibd
-rw-r----- 1 root root  46137344 Mar 14 21:56 t_ct_integral_record.ibd
-rw-r----- 1 root root  27262976 Mar 14 21:56 t_ct_news.ibd
-rw-r----- 1 root root   9437184 Mar 14 21:56 t_ct_order.ibd
-rw-r----- 1 root root     98304 Mar 14 21:56 t_feedback.ibd
-rw-r----- 1 root root     98304 Mar 14 21:56 t_lexicon.ibd
-rw-r----- 1 root root    327680 Mar 14 21:56 t_logs.ibd
-rw-r----- 1 root root     98304 Mar 14 21:56 t_manage.ibd
-rw-r----- 1 root root     98304 Mar 14 21:56 t_module.ibd
-rw-r----- 1 root root   9437184 Mar 14 21:56 t_post_extend.ibd
-rw-r----- 1 root root  12582912 Mar 14 21:56 t_post.ibd
-rw-r----- 1 root root     98304 Mar 14 21:56 t_post_video.ibd
-rw-r----- 1 root root     98304 Mar 14 21:56 t_realtime_message.ibd
-rw-r----- 1 root root     98304 Mar 14 21:56 t_recommend.ibd
-rw-r----- 1 root root  46137344 Mar 14 21:56 t_reply.ibd
-rw-r----- 1 root root     98304 Mar 14 21:56 t_reward.ibd
-rw-r----- 1 root root    196608 Mar 14 21:56 t_sensitive_word.ibd
-rw-r----- 1 root root     98304 Mar 14 21:56 t_system_message.ibd
-rw-r----- 1 root root   9437184 Mar 14 21:56 t_userbaseinfo.ibd
-rw-r----- 1 root root    344064 Mar 14 21:56 t_userextendinfo.ibd
-rw-r----- 1 root root  12582912 Mar 14 21:56 t_user_health.ibd
-rw-r----- 1 root root     98304 Mar 14 21:56 t_user_message.ibd
-rw-r----- 1 root root    442368 Mar 14 21:56 t_user_read_module_log.ibd
-rw-r----- 1 root root  17825792 Mar 14 21:56 t_viewpoint.ibd
-rw-r----- 1 root root    114688 Mar 14 21:56 t_white_ip.ibd

[root@10-10-127-11 db_bbs]# chown mysql.mysql *.ibd

mysql -e "show tables from db_bbs" | grep -v  Tables_in_db_bbs| while read a; do mysql -e  "ALTER TABLE db_bbs.$a import TABLESPACE" ;done

각 테이블의 테이블 스페이스를 가져올 때 개별 테이블 오류가 발생했습니다.

[root@10-10-127-11 db_bbs]# mysql -e "show tables from db_bbs" | grep -v  Tables_in_db_bbs| while read a; do mysql -e  "ALTER TABLE db_bbs.$a import TABLESPACE" ;done 
ERROR 1808 (HY000) at line 1: Schema mismatch (Table has ROW_TYPE_DYNAMIC row format, .ibd file has ROW_TYPE_COMPACT row format.)

테이블 파일을 확인하십시오. browse_record 테이블 만 독립 테이블 스페이스로 반입되고 오류가보고되어이 테이블의 데이터 복구가 실패합니다.


[root@10-10-127-11 db_bbs]# mysqlcheck -c db_bbs
db_bbs.browse_record
Warning  : InnoDB: Tablespace has been discarded for table 'browse_record'
Error    : Tablespace has been discarded for table 'browse_record'
error    : Corrupt
db_bbs.t_admin                                     OK
db_bbs.t_anonymous_code                            OK
db_bbs.t_apply                                     OK
db_bbs.t_attach                                    OK
db_bbs.t_banner                                    OK
db_bbs.t_banner_log                                OK
db_bbs.t_black_ip                                  OK
db_bbs.t_black_user                                OK
db_bbs.t_block_userbaseinfo                        OK
db_bbs.t_collect                                   OK
db_bbs.t_country_code                              OK
db_bbs.t_ct_goods                                  OK
db_bbs.t_ct_goods_record                           OK
db_bbs.t_ct_integral                               OK
db_bbs.t_ct_integral_record                        OK
db_bbs.t_ct_news                                   OK
db_bbs.t_ct_order                                  OK
db_bbs.t_feedback                                  OK
db_bbs.t_lexicon                                   OK
db_bbs.t_logs                                      OK
db_bbs.t_manage                                    OK
db_bbs.t_module                                    OK
db_bbs.t_post                                      OK
db_bbs.t_post_extend                               OK
db_bbs.t_post_video                                OK
db_bbs.t_realtime_message                          OK
db_bbs.t_recommend                                 OK
db_bbs.t_reply                                     OK
db_bbs.t_reward                                    OK
db_bbs.t_sensitive_word                            OK
db_bbs.t_system_message                            OK
db_bbs.t_user_health                               OK
db_bbs.t_user_message                              OK
db_bbs.t_user_read_module_log                      OK
db_bbs.t_userbaseinfo                              OK
db_bbs.t_userextendinfo                            OK
db_bbs.t_viewpoint                                 OK
db_bbs.t_white_ip                                  OK

위의 browse_record 테이블 복원 실패 오류 보고서 솔루션은 다음과 같습니다.
참조 : https://blog.csdn.net/weixin_30607659/article/details/94987901

새 MySQL 인스턴스로 가져온 browse_record 테이블을 삭제 한 후 다음 테이블 생성 문을 실행하여 새 browse_record 테이블을 만듭니다.

CREATE TABLE `browse_record` (
  `id` int(4) unsigned NOT NULL AUTO_INCREMENT,
  `post_id` int(4) unsigned NOT NULL,
  `user_id` int(4) unsigned NOT NULL,
  `status` tinyint(1) unsigned NOT NULL,
  `update_time` bigint(4) unsigned NOT NULL,
  `create_time` bigint(4) unsigned NOT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  KEY `browse` (`post_id`,`user_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4  row_format=compact;

팁 : 새 MySQL 인스턴스에서 browse_record 테이블을 별도로 삭제하는 경우 삭제에 실패하면 새 MySQL 인스턴스에서 db_bbs 라이브러리를 직접 삭제하고 db_bbs에있는 모든 테이블의 테이블 생성 문을 다시 가져온 후 다음 명령을 실행하십시오. :

mysql -e "show tables from db_bbs" | grep -v  Tables_in_db_bbs| while read a; do mysql -e  "ALTER TABLE db_bbs.$a DISCARD TABLESPACE" ;done

테이블 스페이스를 새 인스턴스 MySQL로 다시 가져옵니다.

[root@10-10-127-11 db_bbs]# mysql -e "show tables from db_bbs" | grep -v  Tables_in_db_bbs| while read a; do mysql -e  "ALTER TABLE db_bbs.$a import TABLESPACE" ;done
[root@10-10-127-11 db_bbs]# 

여기에서 데이터 복구가 완료되었습니다.

MySQL db_bbs 라이브러리의 테이블을 확인합니다.


[root@10-10-127-11 db_bbs]# mysqlcheck -c db_bbs
db_bbs.browse_record                               OK
db_bbs.t_admin                                     OK
db_bbs.t_anonymous_code                            OK
db_bbs.t_apply                                     OK
db_bbs.t_attach                                    OK
db_bbs.t_banner                                    OK
db_bbs.t_banner_log                                OK
db_bbs.t_black_ip                                  OK
db_bbs.t_black_user                                OK
db_bbs.t_block_userbaseinfo                        OK
db_bbs.t_collect                                   OK
db_bbs.t_country_code                              OK
db_bbs.t_ct_goods                                  OK
db_bbs.t_ct_goods_record                           OK
db_bbs.t_ct_integral                               OK
db_bbs.t_ct_integral_record                        OK
db_bbs.t_ct_news                                   OK
db_bbs.t_ct_order                                  OK
db_bbs.t_feedback                                  OK
db_bbs.t_lexicon                                   OK
db_bbs.t_logs                                      OK
db_bbs.t_manage                                    OK
db_bbs.t_module                                    OK
db_bbs.t_post                                      OK
db_bbs.t_post_extend                               OK
db_bbs.t_post_video                                OK
db_bbs.t_realtime_message                          OK
db_bbs.t_recommend                                 OK
db_bbs.t_reply                                     OK
db_bbs.t_reward                                    OK
db_bbs.t_sensitive_word                            OK
db_bbs.t_system_message                            OK
db_bbs.t_user_health                               OK
db_bbs.t_user_message                              OK
db_bbs.t_user_read_module_log                      OK
db_bbs.t_userbaseinfo                              OK
db_bbs.t_userextendinfo                            OK
db_bbs.t_viewpoint                                 OK
db_bbs.t_white_ip                                  OK

2.4. 새 MySQL 인스턴스의 db_bbs 라이브러리로 가져온 테이블 레코드를 가져 와서 원래 라이브러리 test.txt 테이블 레코드 파일과 비교합니다.

[root@10-10-127-11 ~]# for n in `mysql -e "use  db_bbs;show tables;"|sed '1d'`;do echo $n; mysql -e "use  db_bbs;select count(*) from $n;";done >test.txt11
和原来的库test.txt表记录文件对比。
[root@test02 ~]# vimdiff test.txt11 test.txt

表记录完全一致

지금까지 MySQL 데이터가 복구되었습니다.

참조 자료 :
https://mp.weixin.qq.com/s/r3KTPsFay292JnO0lgTLUg
https://www.cnblogs.com/jiangxu67/p/4744283.html
https://blog.csdn.net/Sonny_alice/article/details / 80198200
https://www.cnblogs.com/jiangxu67/p/4744283.html

추천

출처blog.51cto.com/wujianwei/2665154