还原被误删的innodb表

说明:
数据库的某个表(user_money表,innodb引擎)被误删掉,因为之前有备份。想把原来备份的数据库拷到其它机子(ibdata1保存了所有innodb引擎数据库的数据,直接在本机上运行可能会覆盖掉其它innodb数据库的数据),提取出被删掉的表,再还原回去。而整个库比较大,我只需要user_money这个表,因此我只想拷user_money.frm这个表和inbata1这个数据。
innodb跟myisam不同,数据跟表是分开的。数据存储在ibdata1中。

实现:
1.拷贝ibdata1(保存了所有innodb引擎数据库的数据);user_money.frm(被误删的表,估计是表结构,没仔细看)两个文件到其它机子的mysql目录。具体位置可以查看/etc/my.cnf。
如我这里my.cnf里位置是innodb_data_home_dir = /home/mysql/data/,ibdata1就拷贝到/home/mysql/data/,覆盖原来的ibdata1。
而user_money.frm原来是在tst目录下(tst库),/etc/my.cnf中位置是datadir = /home/mysql/data,因此user_money.frm就拷贝到/home/mysql/data/tst下。tst目录没有就新建个。

2.修改/home/mysql/data/tst,/home/mysql/data/ibdata1用户,权限

# chown -R mysql.mysql /home/mysql/data/tst
# chown -R mysql.mysql /home/mysql/data/ibadta1
# chmod 660 /home/mysql/data/tst -R

 
3.修改my.cnf,在innodb段最后添加innodb_force_recovery = 1

# Uncomment the following if you are using InnoDB tables
innodb_data_home_dir = /home/mysql/data/
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = /home/mysql/data/
# You can set .._buffer_pool_size up to 50 - 80 %
# of RAM but beware of setting memory usage too high
innodb_buffer_pool_size = 16M
innodb_additional_mem_pool_size = 2M
# Set .._log_file_size to 25 % of buffer pool size
innodb_log_file_size = 5M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50
innodb_force_recovery = 1

 
4.重启mysql

# /etc/init.d/mysqld restart
# /usr/local/mysql/bin/mysql -uroot -p -S /tmp/mysql.sock  //可以看到多了个tst库
# use tst;
# show tables;
# select * from user_money;  //这时,可以看到能查得到数据。

 
5.新建个表user_money_2,跟user_money结构相同,将user_money数据导出到新表user_money_2

> CREATE TABLE `test` (   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,   `leng_money` decimal(10,0) NOT NULL DEFAULT '0',   `update_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',   PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=651721 DEFAULT CHARSET=latin1;

> INSERT INTO test SELECT * FROM user_money;
Query OK, 651717 rows affected (12.42 sec)
Records: 651717  Duplicates: 0  Warnings: 0

 
当然也可以使用mysqldump将表导出,然后再导回到InnoDB表中。不过,这里需要先将步骤3中往my.cnf innodb段最后添加innodb_force_recovery = 1注释掉。然后重启mysqld,然后再进行下面的操作

# /usr/local/mysql/bin/mysqldump -uroot -p tst user_money > /tmp/user_money.sql //导出tst库的user_money表
# /usr/local/mysql/bin/mysql -uroot -p -S /tmp/mysql.sock
> use tst;
> source /tmp/mysql.sock  //还原回去

 
附录:
1.ERROR 1030 (HY000): Got error 28 from storage engine
出现此问题的原因:临时空间不够,无法执行此SQL语句。解决方法就是将tmpdir指向一个硬盘空间很大的目录。可以修改/et/my.cnf中的tmpdir = /home/mysql/tmp/。

发表评论

邮箱地址不会被公开。 必填项已用*标注