数据库最好定期使用mysqldump 进行备份,纯文本的备份不易损坏,另外数据库要启用binlog,用来弥补dump备份不包含的数据,
例如使用 dump备份导入了 3月27日 凌晨3点的备份,剩余的数据可以通过binlog找回,对于失误使用了 delete或truncate语句删除的数据,需要先根据binlog 导出这段时间执行的所有sql
mysqlbinlog --start-datetime='2013-03-27 03:00:00' --stop-datetime='2013-03-27 12:00:00' mysqlbin-log.000001 > sql.txt
mysqlbin-log.000001文件可以根据文件修改时间判断出来,导出的sql.txt包含指定时间段内所有执行过的sql语句, 找到错误执行的语句,选择这条语句之上的一个时间点,通过mysqlbinlog 导入这个时间点之前的数据
mysqlbinlog --start-datetime='20130-3-27 03:00:00' --stop-datetime='2013-03-27 10:00:00' mysqlbin-log.000001 | mysql -uroot -p
排除掉错误语句时间,执行剩余语句
mysqlbinlog --start-datetime='20130-3-27 10:01:00' mysqlbin-log.000001 | mysql -uroot -p
通过以上方法可以找回数据表的所有数据。
如果备份方式为tar压缩备份,且数据库中包含innodb表,且my.cnf中 设置了innodb_file_per_table,那么恭喜你,通过上面的方法你所有的数据都已经找回了, 如果没有设置 Innodb_file_per_table,那么所有innodb表的数据都存储在 ibdata1文件中,没有办法直接通过覆盖的方式找回数据, 这时候就要用到 innodb-tools这个工具了
tar -zxvf percona-data-recovery-tool-for-innodb-0.5.tar.gz
cd percona-data-recovery-tool-for-innodb-0.5/mysql-source
./configure (apt-get install libncurses5-dev)
cd ..
make
(不需要 install)
之后我们就可以使用这个工具的一些命令了, 首先我们需要把ibdata1内的数据根据索引拆分页
./page_parse -5 -f /path/to/ibdata1 ## -5表示mysql版本为5.0以上
这个命令会创建一个 pages-<timestamp>的目录, 里边有所有的索引页,下一步需要做的是查找到要恢复的表所在的索引页,我们需要先启动 innodb_tablespace_monitor,用来查看表的索引ID
mysql> CREATE TABLE innodb_table_monitor (x int) ENGINE=InnoDB;
这个表不会有任何记录,innodb_tablespace_monitor会输出到mysql的错误文件中,例如我的服务器是debian,默认的错误日志是/var/log/daemon.err, 要恢复的表名是 exam_scores, 使用命令
cat /var/log/daemon.err|grep exam_scores
根据这条命令可以查看到exam_scores这个表对应的索引Id, 比如 id:0 189,那么我们的索引页在目录 0-189内,这里要说明一点,我的数据丢失原因是因为误操作,使用了truncate table命令,清空了所有表, truncate会 先执行 drop table之后create table, 索引id目录(0-189)并没有在page_parser产生的目录中找到, 但是存在另外一个目录 0-589,不知道这个400是不是truncate创建新索引id的规律,找到了索引页后,就是要从页中提取记录,首先合并一下所有的page 页
find pages-<timestamp>/0-589/ -type f -name '*.page' | sort -n | xargs cat > pages-
<timestamp>
/0-589/exam_scores_data
接下来需要让innodb-tools来根据这个合并后的数据来提取记录,这里需要用到constraints_parser这个工具,constraints_parser默认包含的是SYS_TABLES这个表的结构信息,这样是没有办法提取记录的,需要根据exam_scores这个表结构重新编译 constraints_parser,先生成表结构的定义文件
./create_defs.pl --host=localhost --user=root --password=123456 --db=dbname --table=exam_score > include/table_defs.h
make
mkdir ./dumps/default -p
./constraints_parser -5 -f pages-<timestamp>
/0-589/exam_scores_data > ./dumps/default/exam_scores
命令执行成功后会输出一条LOAD DATA INFILE的SQL语句, 拿这条语句到MYSQL中执行吧,成功后,你的数据就恢复了