分类: Mysql/postgreSQL
2014-01-16 17:01:13
from:
近段时间一直在研究mysql的日志系统,在网上看了N多mysql日志操作的文章,但都过于零乱,为了让自己以后不再搞忘,特作出以下总结:
1. 以前我错误的认为mysql的日志可以恢复到任何时间的状态,其实并不是这样,这个恢复是有前提的,就是你至少得有一个从日志记录开始后的数据库备份,通过日志恢复数据库实际上只是一个对以前操作的回放过程而已,不用想得太复杂,既然是回放你就得注意了,如果你执行了两次恢复那么就相当于是回放了两次,后果如何你自己应该清楚了吧。
2. 要想通过日志恢复数据库,在你的my.cnf文件里应该有如下的定义,log-bin=mysql-bin,这个是必须的.binlog-do-db=db_test,这个是指定哪些数据库需要日志,如果有多个数据库就每行一个,如果不指定的话默认就是所有数据库.
[mysqld]
log-bin=mysql-bin
binlog-do-db=db_test
binlog-do-db=db_test2
3.删除二进制日志:
a.mysql> system ls -ltr /var/lib/mysql/bintest*;
mysql>reset master(清空所有的二进制日志文件)
b.purge master logs to ‘bintest.000006′;(删除bintest.000006之前的二进制日志文件)
c.purge master logs before ’2007-08-10 04:07:00′(删除该日期之前的日志)
d.在my.cnf 配置文件中[mysqld]中添加:
expire_logs_day=3设置日志的过期天数,过了指定的天数,会自动删除
4.下面就是恢复操作了
特别提示,mysql每次启动都会重新生成一个类似mysql-bin.000003的文件,如果你的mysql每天都要重新启动一次的话,这时候你就要特别注意不要选错日志文件了。
(注意:下面有一些技巧,这些东西才是最宝贵的哟,普通的东东手册上都有,这可是我摸索出来的哟,别人我都不告诉他。
技巧1 :
在下面你将看到 mysqlbinlog –stop-date=”2005-04-20 9:59:59″ /var/log/mysql/mysql-bin.000001 | mysql -u root -pmypwd 类似的语句,但是它一次只能操作一个日志文件,如果你变通一下变成这样 mysqlbinlog –stop-date=”2005-04-20 9:59:59″ /var/log/mysql/mysql-bin.0* | mysql -u root -pmypwd 那么它基本上就会表示出的所有的日志文件了,这样可解决你忘记在哪一个日志文件中的问题,当然你也可以用这种写法更完美,mysqlbinlog –stop-date=”2005-04-20 9:59:59″ /var/log/mysql/mysql-bin.[0-9]* | mysql -u root -pmypwd ,看到[0-9]*这个东东了吧,它表示以数字开头的任何字符,方便吧!
技巧2:
你可以通过–one-database 参数选择性的恢复单个数据库,example在下面,爽吧。
mysqlbinlog –stop-date=”2005-04-20 9:59:59″ /var/log/mysql/mysql-bin.000001 | mysql -u root -pmypwd –one-database db_test
技巧3:
如果你老人家已经使用过 /usr/local/mysql5/bin/mysqlbinlog –start-date=”2005-04-20 9:55:00″ /var/data/mysql5/mysql-bin.0* > /home/db/tt.sql 类似的语句将日志导成了ASCII文本文件,那么你就可以直接在phpmyadmin或者其它什么乱七糟八的的客户端里执行这个文件文件就行了,因为它本身就是一个标准的sql文件,比如想让文件里面的某些语句不执行,OK,it’s easy,找到它们删除即可,然后再放进去执行就OK滴啦!这个可是灰常灰常的爽哟。。。。。。
技巧4:
我来给大家讲一下,下面这条语句都做了什么
mysqlbinlog –stop-date=”2005-04-20 9:59:59″ /var/log/mysql/mysql-bin.000001 | mysql -u root -pmypwd –one-database db_test
这是把mysql-bin.000001这个二进制文件里的内容转换成ASCII文件(也就是sql语句),直接通过管道操作符”|”传输给 mysql这个程序,然后过滤掉其它数据库的语句,只在db_test里执行。
技巧5:
着了,多打了一个技巧,现在暂时没内容,等以后再加吧!!!
)
下面部份摘录自网上。
如果MySQL服务器启用了二进制日志,你可以使用mysqlbinlog工具来恢复从指定的时间点开始 (例如,从你最后一次备份)直到现在或另一个指定的时间点的数据。关于启用二进制日志的信息,参见5.11.3节,“二进制日志”。对于 mysqlbinlog的详细信息,参见mysql手册8.6节,“mysqlbinlog:用于处理二进制日志文件的实用工具”。
要想从二进制日志恢复数据,你需要知道当前二进制日志文件的路径和文件名。一般可以从选项文件(即my.cnf or my.ini,取决于你的系统)中找到路径。如果未包含在选项文件中,当服务器启动时,可以在命令行中以选项的形式给出。启用二进制日志的选项为– log-bin。要想确定当前的二进制日志文件的文件名,输入下面的MySQL语句:
SHOW BINLOG EVENTS G
你还可以从命令行输入下面的内容:
mysql –user=root -pmy_pwd -e ‘SHOW BINLOG EVENTS G’
将密码my_pwd替换为服务器的root密码。
1. 指定恢复时间
对于MySQL 4.1.4,可以在mysqlbinlog语句中通过–start-date和–stop-date选项指定DATETIME格式的起止时间。举例说明,假设在今天上午10:00(今天是2005年4月20日),执行SQL语句来删除一个大表。要想恢复表和数据,你可以恢复前晚上的备份,并输入:
mysqlbinlog –stop-date=”2005-04-20 9:59:59″ /var/log/mysql/mysql-bin.000001 | mysql -u root -pmypwd
该命令将恢复截止到在–stop-date选项中以DATETIME格式给出的日期和时间的所有数据。如果你没有检测到几个小时后输入的错误的SQL语句,可能你想要恢复后面发生的活动。根据这些,你可以用起使日期和时间再次运行mysqlbinlog:
mysqlbinlog –start-date=”2005-04-20 10:01:00″ /var/log/mysql/mysql-bin.000001 | mysql -u root -pmypwd
在该行中,从上午10:01登录的SQL语句将运行。组合执行前夜的转储文件和mysqlbinlog的两行可以将所有数据恢复到上午10:00前一秒钟。你应检查日志以确保时间确切。下一节介绍如何实现。
2. 指定恢复位置
也可以不指定日期和时间,而使用mysqlbinlog的选项–start-position和–stop-position来指定日志位置。它们的作用与起止日选项相同,不同的是给出了从日志起的位置号。使用日志位置是更准确的恢复方法,特别是当由于破坏性SQL语句同时发生许多事务的时候。要想确定位置号,可以运行mysqlbinlog寻找执行了不期望的事务的时间范围,但应将结果重新指向文本文件以便进行检查。操作方法为:
mysqlbinlog –start-date=”2005-04-20 9:55:00″ –stop-date=”2005-04-20 10:05:00″
/var/log/mysql/mysql-bin.000001 > /tmp/mysql_restore.sql
该命令将在/tmp目录创建小的文本文件,将显示执行了错误的SQL语句时的SQL语句。你可以用文本编辑器打开该文件,寻找你不要想重复的语句。如果二进制日志中的位置号用于停止和继续恢复操作,应进行注释。用log_pos加一个数字来标记位置。使用位置号恢复了以前的备份文件后,你应从命令行输入下面内容:
mysqlbinlog –stop-position=”368312″ /var/log/mysql/mysql-bin.000001 | mysql -u root -pmypwd
mysqlbinlog –start-position=”368315″ /var/log/mysql/mysql-bin.000001 | mysql -u root -pmypwd
上面的第1行将恢复到停止位置为止的所有事务。下一行将恢复从给定的起始位置直到二进制日志结束的所有事务。因为mysqlbinlog的输出包括每个SQL语句记录之前的SET TIMESTAMP语句,恢复的数据和相关MySQL日志将反应事务执行的原时间。
一,什么是增量备份
增量备份,就是将新增加的数据进行备份。假如你一个数据库,有10G的数据,每天会增加10M的数据,数据库每天都要备份一次,这么多数据是不是都要备份呢?还是只要备份增加的数据呢,很显然,我只要备份增加的数据。这样减少服务器的负担。
二,启用binlog
vi my.cnf
log-bin=/var/lib/mysql/mysql-bin.log,如果是这样的话log-bin=mysql-bin.log默认在datadir目录下面
[root@BlackGhost mysql]# ls |grep mysql-bin
mysql-bin.000001
mysql-bin.000002
mysql-bin.000003
mysql-bin.000004
mysql-bin.000005
mysql-bin.000006
mysql-bin.index
启动后会产生mysql-bin这样的文件,每启动一次,就会增加一个或者多个。
mysql-bin.000002这样文件存放的是数据库每天增加的数据,所有数据库的数据增量都在这里面。
三,查看mysql-bin.000002这样的文件里面到底是什么东西
[root@BlackGhost mysql]# mysqlbinlog /var/lib/mysql/mysql-bin.000002 > /tmp/add.sql
下面还有一个重要索引文件就是mysql-bin.index
四,增量备份和增量还原
1,增量备份
既然我们知道了,mysql里面新增加的数据在mysql-bin这样的文件里面,我们只要把mysql-bin这样的文件进行备份就可以了。
cp /var/lib/mysql/mysql-bin* /data/mysql_newbak/
2,增量还原,讲几个常用的,比较有用的
a),根据时间来还原 –start-date,–stop-date
[root@BlackGhost mysql]# /usr/local/mysql/bin/mysqlbinlog –start-date=”2010-09-29 18:00:00″ –stop-date=”2010-09-29 23:00:00″ /var/lib/mysql/mysql-bin.000002 |mysql -u root -p
根据条件看一下数据
b),根据起始位置来还原,–start-position,–stop-position
[root@BlackGhost mysql]# /usr/local/mysql/bin/mysqlbinlog –start-position=370 –stop-position=440 /var/lib/mysql/mysql-bin.000002 |mysql -u root -p
//查看插入的内容,根a)中是一样的
[root@BlackGhost mysql]# /usr/local/mysql/bin/mysqlbinlog –start-position=370 –stop-position=440 /var/lib/mysql/mysql-bin.000002
–start-position=370 –stop-position=440 这里面数字从哪儿来的呢?
# at 370
#100929 21:35:25 server id 1 end_log_pos 440 Query thread_id=1 exec_time=0 error_code=0
SET TIMESTAMP=1285767325/*!*/;
上面的红色加粗的就是,一个是start-position,一个是stop-position
c),根据数据库名来进行还原 -d
在这里是小写的d,请不要把它和mysqldump中的-D搞混了。哈哈。
[root@BlackGhost mysql]# /usr/local/mysql/bin/mysqlbinlog -d test /var/lib/mysql/mysql-bin.000002
查看内容,请参考a)
d),根据数据库所在IP来分-h
[root@BlackGhost mysql]# /usr/local/mysql/bin/mysqlbinlog -h 192.1681.102 /var/lib/mysql/mysql-bin.000002
查看内容,请参考a)
e),根据数据库所占用的端口来分-P
有的时候,我们的mysql用的不一定是3306端口,注意是大写的P
[root@BlackGhost mysql]# /usr/local/mysql/bin/mysqlbinlog -p 13306 /var/lib/mysql/mysql-bin.000002
查看内容,请参考a)
f),根据数据库serverid来还原–server-id
在数据库的配置文件中,都有一个serverid并且同一集群中serverid是不能相同的。
[root@BlackGhost mysql]# /usr/local/mysql/bin/mysqlbinlog –server-id=1 /var/lib/mysql/mysql-bin.000002
查看内容,请参考a)
注意:上面的几个例子,我都是一个一个说的,其实可以排列组合的。例如
[root@BlackGhost mysql]# /usr/local/mysql/bin/mysqlbinlog –start-position=”2010-09-29 18:00:00″ -d test -h 127.0.0.1 /var/lib/mysql/mysql-bin.000002 |mysql -u root -p
五,后续
增量备份的时候,有一点让人不爽,就是mysql-bin这样的文件,每启动一次mysql就会增加一些,如果你不去管他的话,时间长了,他会把你的磁盘占满。
./mysqldump –flush-logs -u root myblog > /tmp/myblog.sql
备份myblog数据库,清除增量备份里面的有关myblog的数据
./mysqldump –flush-logs -u root –all-databases > /tmp/alldatabase.sql
备份所有数据库,清除增量备份
mysql-bin.index的起索引作用,因为增量的数据不一定在一个mysql-bin000这样的文件里面,这个时候,我们就要根据mysql-bin.index来找mysql-bin这样的增量文件了。
如果mysql里面做了这样的配置binlog-do-db=test1,增量备份里面只会有test1这个数据库的数据
mysqlbinlog确实是个强大的mysql数据库辅助工具。 1.首先将数据存到my.sql C:\wamp\bin\mysql\mysql5.5.8\bin\mysqlbinlog.exe --stop-date="2011-10-30 23:30:00" --result-file="c:\my.sql" ../data/mysql-bin.000025 | mysql -uroot 2.然后开始还原数据 C:\wamp\bin\mysql\mysql5.5.8\bin\mysql.exe source c:\my.sql
做了my主 从也有一段时间了,这两天检查磁盘空间情况,发现放数据库的分区磁盘激增了40多G,一路查看下来,发现配置好主从复制以来到现在的binlog就有40 多G,原来根源出在这里,查看了一下my.cnf,看到binlog的size是1G就做分割,但没有看到删除的配置,在mysql里查看了一下 variables
mysql>show variables like ‘%log%’;
查到了
| expire_logs_days | 0 |
这个默认是0,也就是logs不过期,这个是一个global的参数,所以需要执行
set global expire_logs_days=8;
这样8天前的log就会被删除了,如果有回复的需要,请做好备份工作,但这样设置还不行,下次重启mysql了,配置又恢复默认了,所以需在my.cnf中设置
expire_logs_days = 8
这样重启也不怕了
想要恢愎数据库以前的资料,执行mysql>show binlog events;
由于数据量很多,查看起来很麻烦,光打开个文件就要闪半天,所以应该适当删除部分可不用的日志。
并且如果使用的时间足够长的话,会把我的硬盘空间都给吃掉
1、登录系统,/usr/bin/mysql
使用mysql查看日志
mysql>show binary logs;
+&mdh;————-+———–+
| Log_name | File_size |
+—————-+———–+
| ablelee.000001 | 150462942 |
| ablelee.000002 | 120332942 |
| ablelee.000003 | 141462942 |
+—————-+———–+
2、删除bin-log(删除ablelee.000003之前的而没有包含ablelee.000003)
mysql> purge binary logs to ′ablelee.000003′;
Query OK, 0 rows affected (0.16 sec)
3、查询结果(现在只有一条记录了)
mysql> show binlog events\G
*************************** 1. row ***************************
Log_name: ablelee.000003
Pos: 4
Event_type: Format_desc
_id: 1
End_log_pos: 106
Info: Server ver: 5.1.26-rc-log, Binlog ver: 4
1 row in set (0.01 sec)
(ablelee.000001和ablelee.000002已被删除)
mysql> show binary logs;
+—————-+———–+
| Log_name | File_size |
+—————-+———–+
| ablelee.000003 | 106 |
+—————-+———–+
1 row in set (0.00 sec)
(删除的其它格式运用!)
PURGE {MASTER | BINARY} LOGS TO ‘log_name’
PURGE {MASTER | BINARY} LOGS BEFORE ‘date’
用于删除列于在指定的日志或日期之前的日志中的所有二进制日志。这些日志也会从记录在日志索引文件
中的清单中被删除,这样被给定的日志成为第一个。
例如:
PURGE MASTER LOGS TO ‘mysql-bin.010′;
PURGE MASTER LOGS BEFORE ‘2008-06-22 13:00:00′;
清除3天前的 binlog
PURGE MASTER LOGS BEFORE DATE_SUB( NOW( ), INTERVAL 3 DAY);
BEFORE变量的date自变量可以为’YYYY-MM-DD hh:mm:ss’格式。MASTER和BINARY是同义词。
如果您有一个活性的从属,该服务器当前正在读取您正在试图删除的日志之一,则本语句不会起作用,
而是会失败,并伴随一个错误。不过,如果从属服务器是休止的,并且您碰巧清理了其想要读取的日志之一,则从
属服务器启动后不能复制。当从属服务器正在复制时,本语句可以安全运行。您不需要停止它们。
要清理日志,需按照以下步骤:
1. 在每个从属服务器上,使用SHOW SLAVE STATUS来检查它正在读取哪个日志。
2. 使用SHOW MASTER LOGS获得主服务器上的一系列日志。
3. 在所有的从属服务器中判定最早的日志。这个是目标日志。如果所有的从属服务器是更新的,这是清单上的
最后一个日志。
4. 制作您将要删除的所有日志的备份(这个步骤是自选的,但是建议采用)。
5. 清理所有的日志,但是不包括目标日志。
下面讲一下怎么从二进制文件恢复数据, 假如不小心执行了drop table xxx_db, 假如你保留了完整的二进制日志的话, 先不要冒汗, 这是可以恢复的.
先看看日志
#mysqlbinlog /diskb/bin-logs/xxx_db-bin.000001
找到执行create table xxx_db之后和drop table xxx_db之前的position, 假如是20, 1000
#mysqlbinlog –start-position=”4″ –stop-position=”1000″ /diskb/bin-logs/xxx_db-bin.000001 | mysql -u root
伴 随着一大堆的ERROR 1062 (23000) at line 12355: Duplicate entry ’139′ for key 1, 数据库就这样恢复了, 不过–start-position=”20″是不行的, 必须从–start-position=”4″开始, 为什么要强制从4开始, 这个问题我也暂时没有搞清楚.
还有一种办法是根据日期来恢复
#mysqlbinlog –start-datetime=”2009-09-14 0:20:00″ –stop-datetim=”2009-09-15 01:25:00″ /diskb/bin-logs/xxx_db-bin.000001 | mysql -u root
如果create table xxx_db和drop table xxx_db之间的时间相距是一年, 或者在不同的二进制日志中, 且位置相距好远, 就等着失眠吧! 做好备份, 小心操作才是正路啊!