情况:
一台服务器,mysql 的数库里面跑了很多网站的数据,其中一个myisam引擎的gbk编码数据库,误删了一张表。最近的完整备份只有一个月前的,要保证当前各数据库正常运转情况下对那张表恢复,由于服务器托管在机房,也不可能将相关文件导入其它服务器恢复。
方案:
1.在数据库中新建一新的空白数据库loupanbbs,导入之前备份的数据库;不知道那边那位朋友是不是没有听懂我意思,结果数据是与现在跑的loupanjiaju一样,我们要恢复的表bbs_posts存在,为7.23日当天备份时的数据,但其它表已经是最新的8.23号的数据了。不管那么多了,现在只有将binlog完全恢复,再单独导出那张需要的表即可
2. 恢复时发现mysqlbinlog导出时只能指定数据库,不能指定到具体的某个表;在得到的mysql语句里有些语句指定了插入到原来的loupanjiaju数据库中,需要全部改成将要导入的测试数据库名
具体操作;
1. 使用mysqlbinlog命令,确定恢复的起始点,和结束点。
Mysqlbinlog �Cstart-datetime=”2011-07-23 04:50:00” �Cd loupanjiaju mysql-bin.000245 | sed ‘s/loupanjiaju/loupanbbs/g’ > /tmp/restore/mysql-bin.000245
Mysqlbinlog �Cstop-position=” 862820986” �Cd loupanjiaju mysql-bin.000346 | sed ‘s/loupanjiaju/loupanbbs/g’> /tmp/restore/mysql-bin.000346
这样得到了开头,和结尾两个binlog的sql语句。中间的binlog使用脚本完成
2. 创建如下脚本,与mysql-bin.log放在同一目录内
#!/bin/sh
for i in $(cat binlog.index)
do
mysqlbinlog -d loupanjiaju $i | sed 's/loupanjiaju/loupanbbs/g' > /tmp/restore/$i
done
binlog.index为你要恢复的binlog文件名称,可用如下命令得到
ls �Cl mysql-bin.000* | awk ‘{print $9}’ > binlog.index 再手工去掉多余的即可,注意要保证顺序,因为恢复时数据插入顺序不对可能会产生很大问题。
3. 恢复,创建如下脚本,在/tmp/restore目录内
#!/bin/sh
for i in $(cat binlog.index)
do
echo “now process $i” >> /var/log/binlog.log
# mysqlbinlog -d loupanjiaju $i | sed 's/loupanjiaju/loupanbbs/g' > /tmp/restore/$i
cat $i | mysql -f -u restore --password=taoxin loupanbbs 2>/dev/null
done
这样,将此脚本放在后台运行,防止连线中断造成恢复前功尽弃。。保存为binlog.sh
nohup ./binlog.sh &
4. 连接数据库的用户只给你要操作的数据库权限,防止binlog中语句出错时可能对其它数据库造成伤害;实际运行时先测试跑一个日记,看有没有问题,再运行脚本。实际在运行时就有报字符集不同问题,数据库用的是gbk,但我的终端连接用的是lanting1,这里只要让他们保持一样即可。可以修改数据库配置文件,或者指定连接使用字符集。。
Vi /etc/my.cnf 在[mysql] 增加: default_character_set = gbk 就可以了。其它数据重复这类问题,我加了参数-f 全部忽略直接运行了。
5. 进入数据库,查看恢复数据
Mysql> select count(*) from bbs_posts;
或者看日记 tail /var/log/binlog.log 看当前在跑哪一个日记。。