mysql innodb断电恢复,不支持innodb,表空间丢失
一、需求
在办公网络中有一测试pc,跑mysql服务,周末大厦停电,导致mysql 异常;
具体表象为不支持innodb
Current database: kkyoo_ucenter
ERROR 1286 (42000): Unknown table engine 'InnoDB'
二、解决
1、首先发现innodb 不支持
mysql> show variables like '%innodb%';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| have_innodb | NO |
| ignore_builtin_innodb | OFF |
+-----------------------+-------+
显示结果中会有如下3种可能的结果:
have_innodb YES
have_innodb NO
have_innodb DISABLED
这3种结果分别对应:
已经开启InnoDB引擎
未安装InnoDB引擎
未启用InnoDB引擎
针对第二种未安装,只需要安装即可;
针对第三种未启用,则打开mysql配置文件,找到 skip-innodb项,将其改成#skip-innodb,之后重启mysql服务即可。
但在此环境中不可能未安装innodb,因此有innodb的表,也有对应的ib*文件
2、删除ibdata1、ib_logfile0、ib_logfile1,让其重新生成
先关闭mysql,在删除文件,之后再重启
观察mysql err日志,未发现错误,之后再进行查看mysql innodb选项
mysql> show variables like '%innodb%';
+-----------------------------------------+------------------------+
| Variable_name | Value |
+-----------------------------------------+------------------------+
| have_innodb | YES |
| ignore_builtin_innodb | OFF |
| innodb_adaptive_hash_index | ON |
| innodb_additional_mem_pool_size | 1048576 |
| innodb_autoextend_increment | 8 |
| innodb_autoinc_lock_mode | 1 |
| innodb_buffer_pool_size | 8388608 |
| innodb_checksums | ON |
| innodb_commit_concurrency | 0 |
| innodb_concurrency_tickets | 500 |
| innodb_data_file_path | ibdata1:10M:autoextend |
| innodb_data_home_dir | |
| innodb_doublewrite | ON |
| innodb_fast_shutdown | 1 |
| innodb_file_io_threads | 4 |
| innodb_file_per_table | OFF |
| innodb_flush_log_at_trx_commit | 1 |
| innodb_flush_method | |
| innodb_force_recovery | 0 |
| innodb_lock_wait_timeout | 50 |
| innodb_locks_unsafe_for_binlog | OFF |
| innodb_log_buffer_size | 1048576 |
| innodb_log_file_size | 5242880 |
| innodb_log_files_in_group | 2 |
| innodb_log_group_home_dir | ./ |
| innodb_max_dirty_pages_pct | 90 |
| innodb_max_purge_lag | 0 |
| innodb_mirrored_log_groups | 1 |
| innodb_open_files | 300 |
| innodb_rollback_on_timeout | OFF |
| innodb_stats_method | nulls_equal |
| innodb_stats_on_metadata | ON |
| innodb_support_xa | ON |
| innodb_sync_spin_loops | 20 |
| innodb_table_locks | ON |
| innodb_thread_concurrency | 8 |
| innodb_thread_sleep_delay | 10000 |
| innodb_use_legacy_cardinality_algorithm | ON |
+-----------------------------------------+------------------------+
38 rows in set (0.00 sec)
目前mysql已经支持innodb,看来就是ibdata1、ib_logfile0、ib_logfile1相关的问题了
再次进行查询,发现表不存在
mysql> select * from kkyoo_ucenter.vip;
ERROR 1146 (42S02): Table 'kkyoo_ucenter.vip' doesn't exist
mysql> use kkyoo_ucenter;
Database changed
mysql> show tables;
+-------------------------+
| Tables_in_kkyoo_ucenter |
+-------------------------+
| access |
| access_type |
| actor |
| actor_gift_running |
| agent |
| agent_earning |
| agent_out_running |
| avatar |
| buy_log |
| menu |
| user_vip |
| vip |
| vip_price |
+-------------------------+
13 rows in set (0.00 sec)
3、疑问?
此时有个问题,通过重新生成innodb相关文件,可以恢复mysql对innodb的支持;
之后再db中可以看得到表,查询却告知找不到表,何解?
此时需要很好的理解mysql data下各文件的作用:
ibdata1:innodb的共享表空间的数据文件
ib_logfile0和ib_logfile1:innodb的日志文件,这是支持事务的关键
frm:数据库表结构的描述
idb:innodb的独享表空间的数据文件
通过查看innodb相关环境变量可以看到,独享表空间的支持是OFF
innodb_file_per_table | OFF
对比原始的ibdata1,和重新生成的ibdata1,前者有552M,后者只有10M;
因此将ibdata1移除后,带来的问题是丢失了innodb的表内容,最终使得能看到表,但查询不到内容。
4、最终解决
疑问明确后,将移除的ibdata1、ib_logfile0、ib_logfile1还原,此处可以看到在删除前的备份有多重要!
再次重启后,发现依旧提示不支持innodb,不过这时依旧不在慌张,因为已经明确了问题的所在;
通过查看启动时mysql err发现如下:
140520 8:54:20 [Warning] '--skip-locking' is deprecated and will be removed in a future release. Please use '--skip-external-locking' instead.
140520 8:54:20 InnoDB: Initializing buffer pool, size = 8.0M
140520 8:54:20 InnoDB: Completed initialization of buffer pool
InnoDB: Error: log file ./ib_logfile0 is of different size 0 524288000 bytes
InnoDB: than specified in the .cnf file 0 5242880 bytes!
140520 8:54:20 [ERROR] Plugin 'InnoDB' init function returned error.
140520 8:54:20 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
140520 8:54:20 [Note] Event Scheduler: Loaded 0 events
140520 8:54:20 [Note] /usr/local/mysql/libexec/mysqld: ready for connections.
Version: '5.1.57-log' socket: '/tmp/mysql.sock' port: 3306 Source distribution
从上述看出,./ib_logfile0的大小是524288000 bytes,而cnf中配置的为5242880 bytes,两者相差100倍;
通过查看my.cnf的配置,结果发现innodb的相关参数都被注释;
fuck,这是谁在坑我···
之后的处理很顺畅,首先将innodb_log_file_size = 500M,之后再次重启mysql,继续查看日志:
140520 09:05:57 mysqld_safe mysqld from pid file /data/mysql/localhost.localdomain.pid ended
140520 09:05:58 mysqld_safe Starting mysqld daemon with databases from /data/mysql
140520 9:05:58 [Warning] '--skip-locking' is deprecated and will be removed in a future release. Please use '--skip-external-locking' instead.
140520 9:05:58 InnoDB: Initializing buffer pool, size = 8.0M
140520 9:05:58 InnoDB: Completed initialization of buffer pool
InnoDB: Log scan progressed past the checkpoint lsn 69 2108231629
140520 9:05:58 InnoDB: Database was not shut down normally!
InnoDB: Starting crash recovery.
InnoDB: Reading tablespace information from the .ibd files...
InnoDB: Restoring possible half-written data pages from the doublewrite
InnoDB: buffer...
InnoDB: Doing recovery: scanned up to log sequence number 69 2108244519
140520 9:06:07 InnoDB: Starting an apply batch of log records to the database...
InnoDB: Progress in percents: 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
InnoDB: Apply batch completed
InnoDB: Last MySQL binlog file position 0 507849067, file name /home/mysql/data3023/mysql/mysql-bin.000414
140520 9:06:08 InnoDB: Started; log sequence number 69 2108244519
140520 9:06:08 [Note] Event Scheduler: Loaded 0 events
140520 9:06:08 [Note] /usr/local/mysql/libexec/mysqld: ready for connections.
Version: '5.1.57-log' socket: '/tmp/mysql.sock' port: 3306 Source distribution
可以看到,这次的启动没有任何error的字眼,提示:
140520 9:05:58 InnoDB: Database was not shut down normally! #innodb未正常关闭
InnoDB: Starting crash recovery. #现在进行崩溃恢复
之后将各.ibd进行读取,恢复innodb数据
三、总结
技术在于使用,长时间不做mysql,很多基础知识被短暂遗忘;
出现问题要找准err输出,避免将google有病乱投医,最终导致越弄越偏···