说明:
数据库的某个表(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/。