mysql的备份与恢复的再探讨
首先参考两篇文章:
1, http://www.21andy.com/blog/20090610/1323.html
2, http://blog.51yip.com/mysql/1042.html
这两篇文章主要是针对增量备份与恢复做了详细的探讨,没有时间,没有兴趣的同学就别点进去了。
1,我现在的备份方案为:
A(master)----->B(slave)进行实时同步,在B(slave)上每周日凌晨3点做一次全备份,周一至周六做
增量备份,增量备份的时刻选择,根据业务需求灵活修改。当DB出现故障时,或是服务器业务逻辑出现
重大bug,玩家投诉较为严重时,这时我们需要对数据进行恢复。
2,我现在的恢复方案为:
首先停掉所有服务器,在B(slave)上首先进行一次全备份恢复:
mysql -uroot -p**** < allbackup.sql
然后选择时间点进行增量恢复:
mysqlbinlog --start-date="2011-06-15 14:00:00" --stop-date="2011-06-15 17:30:00" mysql-bin.[0-9]* |mysql -uroot -p****
这样所有的数据库,所有的表单都恢复到了正常状态。
3,这样做的问题是:
相当麻烦,很痛苦。如果只是db_account中的一个表单 tb_account出现了问题,其他的数据库均正常。那么这样做就太折腾了,
因为全备份对所有的数据库都生效,这样的恢复当然也是对所有的数据库生效。那么恢复之后,要在B(slave)上找到想要的恢复后的数据,
导入到A(master)中,而其他的数据都不能保持不动。痛苦!!!
4,改进后的方案为:
对每个数据库进行全备份,不用原来的对所有的数据库备份的做法(即下面的做法):
mysqldump -h $HOST -u $USER -p$PASSWORD --opt --all-databases --flush-logs > $BAKDIR/$DATESTR.sql
这样的话,每个数据库的备份数据都会相应的生成在一个sql文件中,也就是说原来的备份目录下的sql文件由一个增加到了N个,这样就
可以去恢复具体的数据库了,哪个数据库出问题就去恢复哪个数据库,哪里不会点哪里,妈妈再也不用担心我的学习了。
省去了很多麻烦。即你可以这样写:
mysqldump -h $HOST -u $USER -p$PASSWORD --flush-logs db_account > account.sql
mysqldump -h $HOST -u $USER -p$PASSWORD --flush-logs db_test1 > test1.sql
mysqldump -h $HOST -u $USER -p$PASSWORD --flush-logs db_test2 > test2.sql
mysqldump -h $HOST -u $USER -p$PASSWORD --flush-logs db_test3 > test3.sql
那么增量备份怎么办?
如果基于时间点的增量恢复db_account,该怎么办?有办法
mysqlbinlog --start-date="2011-06-15 14:00:00" --stop-date="2011-06-15 17:30:00" -d db_account mysql-bin.[0-9]*
可以用-d指定数据库进行增量恢复,这样就可以对指定的数据库进行全备份恢复和增量备份恢复了,一切是多么的和谐。
5,一点点的小担心:
就是在对具体的一个数据库db_account进行全备份,flush-logs的时候,会删除db_account的增量数据。那么有没有以下的可能:
5.1,两个数据库中的增量数据在一个mysql-bin文件中
5.2,一个数据库的增量数据在两个mysql-bin文件中
如果有以上的可能,那么在flush-logs的时候会不会出现什么隐患或是问题呢?如db_account在flush-logs的时候删除了
一个文件,但这个文件中还有其他数据库的增量数据。或是说flush-logs不是基于文件删除,而是基于数据删除,在所有的
文件中找到db_account的增量数据,然后做删除,当发现一个文件没有数据的时候,再删除该文件。大家都知道的,
mysql-bin的文件是相当多的,如果不做删除清理的话,总有一天硬盘会爆炸的。
===============================华丽的分割线==========================
2012.11.15补增:
1,上面的方案基本上是没什么问题的,担心的情况也是基本不成立的,可能是原来对mysql的增量不理解造成的。
2,mysql的--flush-log会触发增量事件:即本次较上次flush之后的增量,(而且每次flush之后会把新的增量生成在新的二进制文件中,即使没有增量也会生成新的二进制文件)
并不会删除文件,如果需要删除多余的增量备份文件,需要手动delete。
3,大概的原理是:新一天在全备份之前flush一次log,生成的log是前一天的增量,备份完成后,把前一天的所有增量文件删除,并备份到远程服务器。
之后每次增量备份通过flush-log生成即可,并不需要删除旧的log,该天的log由全备份时统一删除管理。
4,每个增量备份文件内部,不会按照数据库或其他的方式归类管理,在flush的时候,会根据index一次性生成,所以在恢复的时候,要在当天的所有增量文件
中做选择。
5,假设0点做全备份,每3小时做一次增量备份,那么在5点的时候做恢复,只能恢复到3点,4点和5点的时候数据将丢失。
==============================第二次割=============================
2013.1.9补增;
1,感谢王亮同学终于把增量备份的bug解决了,这次对日志备份的理解更深刻一层。
2,mysql在flush之后新生成的bin是空的,下次新增的数据,将写在该bin中,所以本次无需拷贝该文件。
3,为什么我们的脚本拷贝该文件了呢?因为咱们的shell脚本写错了,对空格的理解不深刻啊!!寒
4,要保证logbinback中的Bin和/var/log/mysql中的bin保持一致,至少logbinback中的日期要比var中多0天或1天。
如果主数据库的bin保留10天,那么备份数据库中的bin保留20天即可,没有必要全部保留。
1, http://www.21andy.com/blog/20090610/1323.html
2, http://blog.51yip.com/mysql/1042.html
这两篇文章主要是针对增量备份与恢复做了详细的探讨,没有时间,没有兴趣的同学就别点进去了。
1,我现在的备份方案为:
A(master)----->B(slave)进行实时同步,在B(slave)上每周日凌晨3点做一次全备份,周一至周六做
增量备份,增量备份的时刻选择,根据业务需求灵活修改。当DB出现故障时,或是服务器业务逻辑出现
重大bug,玩家投诉较为严重时,这时我们需要对数据进行恢复。
2,我现在的恢复方案为:
首先停掉所有服务器,在B(slave)上首先进行一次全备份恢复:
mysql -uroot -p**** < allbackup.sql
然后选择时间点进行增量恢复:
mysqlbinlog --start-date="2011-06-15 14:00:00" --stop-date="2011-06-15 17:30:00" mysql-bin.[0-9]* |mysql -uroot -p****
这样所有的数据库,所有的表单都恢复到了正常状态。
3,这样做的问题是:
相当麻烦,很痛苦。如果只是db_account中的一个表单 tb_account出现了问题,其他的数据库均正常。那么这样做就太折腾了,
因为全备份对所有的数据库都生效,这样的恢复当然也是对所有的数据库生效。那么恢复之后,要在B(slave)上找到想要的恢复后的数据,
导入到A(master)中,而其他的数据都不能保持不动。痛苦!!!
4,改进后的方案为:
对每个数据库进行全备份,不用原来的对所有的数据库备份的做法(即下面的做法):
mysqldump -h $HOST -u $USER -p$PASSWORD --opt --all-databases --flush-logs > $BAKDIR/$DATESTR.sql
这样的话,每个数据库的备份数据都会相应的生成在一个sql文件中,也就是说原来的备份目录下的sql文件由一个增加到了N个,这样就
可以去恢复具体的数据库了,哪个数据库出问题就去恢复哪个数据库,哪里不会点哪里,妈妈再也不用担心我的学习了。
省去了很多麻烦。即你可以这样写:
mysqldump -h $HOST -u $USER -p$PASSWORD --flush-logs db_account > account.sql
mysqldump -h $HOST -u $USER -p$PASSWORD --flush-logs db_test1 > test1.sql
mysqldump -h $HOST -u $USER -p$PASSWORD --flush-logs db_test2 > test2.sql
mysqldump -h $HOST -u $USER -p$PASSWORD --flush-logs db_test3 > test3.sql
那么增量备份怎么办?
如果基于时间点的增量恢复db_account,该怎么办?有办法
mysqlbinlog --start-date="2011-06-15 14:00:00" --stop-date="2011-06-15 17:30:00" -d db_account mysql-bin.[0-9]*
可以用-d指定数据库进行增量恢复,这样就可以对指定的数据库进行全备份恢复和增量备份恢复了,一切是多么的和谐。
5,一点点的小担心:
就是在对具体的一个数据库db_account进行全备份,flush-logs的时候,会删除db_account的增量数据。那么有没有以下的可能:
5.1,两个数据库中的增量数据在一个mysql-bin文件中
5.2,一个数据库的增量数据在两个mysql-bin文件中
如果有以上的可能,那么在flush-logs的时候会不会出现什么隐患或是问题呢?如db_account在flush-logs的时候删除了
一个文件,但这个文件中还有其他数据库的增量数据。或是说flush-logs不是基于文件删除,而是基于数据删除,在所有的
文件中找到db_account的增量数据,然后做删除,当发现一个文件没有数据的时候,再删除该文件。大家都知道的,
mysql-bin的文件是相当多的,如果不做删除清理的话,总有一天硬盘会爆炸的。
===============================华丽的分割线==========================
2012.11.15补增:
1,上面的方案基本上是没什么问题的,担心的情况也是基本不成立的,可能是原来对mysql的增量不理解造成的。
2,mysql的--flush-log会触发增量事件:即本次较上次flush之后的增量,(而且每次flush之后会把新的增量生成在新的二进制文件中,即使没有增量也会生成新的二进制文件)
并不会删除文件,如果需要删除多余的增量备份文件,需要手动delete。
3,大概的原理是:新一天在全备份之前flush一次log,生成的log是前一天的增量,备份完成后,把前一天的所有增量文件删除,并备份到远程服务器。
之后每次增量备份通过flush-log生成即可,并不需要删除旧的log,该天的log由全备份时统一删除管理。
4,每个增量备份文件内部,不会按照数据库或其他的方式归类管理,在flush的时候,会根据index一次性生成,所以在恢复的时候,要在当天的所有增量文件
中做选择。
5,假设0点做全备份,每3小时做一次增量备份,那么在5点的时候做恢复,只能恢复到3点,4点和5点的时候数据将丢失。
==============================第二次割=============================
2013.1.9补增;
1,感谢王亮同学终于把增量备份的bug解决了,这次对日志备份的理解更深刻一层。
2,mysql在flush之后新生成的bin是空的,下次新增的数据,将写在该bin中,所以本次无需拷贝该文件。
3,为什么我们的脚本拷贝该文件了呢?因为咱们的shell脚本写错了,对空格的理解不深刻啊!!寒
4,要保证logbinback中的Bin和/var/log/mysql中的bin保持一致,至少logbinback中的日期要比var中多0天或1天。
如果主数据库的bin保留10天,那么备份数据库中的bin保留20天即可,没有必要全部保留。