mysql数据库恢复---mysql二进制文件(binlog)的应用

mysql二进制文件(binlog)的应用

mysql二进制文件(binlog)的使用说明:
在MYSQL中有不同类型的日志文件(各自存储了不同类型的日志),从它们当中可以查询到MYSQL里都做了些什么,对于MYSQL的管理工作,这些日志文件是不可缺少的。
下面是日志文件的一些类型:
1.二进制日志(The binary log):记录了所有对数据库数据的修改语句;
2.错误日志(The error log):记录了数据库启动、运行以及停止过程中错误信息;
3.ISAM操作日志(The isam log):记录了所有对ISAM表的修改,该日志仅仅用于调试ISAM模式;
4.SQL执行日志(The query log):记录了客户端的连接以及所执行的SQL语句;
5.更新日志(The update log):记录了改变数据的语句,已经不建议使用,由二进制日志替代;
6.超时日志(The slow log):记录所有执行时间超过最大SQL执行时间(long_query_time)或未使用索引的语句;
如果你是在用mysql的复制、备份功能,那么从服务器还提供了一种叫做relay log的日志文件。
默认情况下所有日志文件会记录在MYSQL的数据目录下,你可以通过强制mysql去关闭并重新打开一个文件进行日志记录,当然系统会自动加后缀 (如.00001, .00002),方式有在mysql环境下执行语句 mysql>flush logs; 或者通过mysqladmin管理程序执行 #mysqladmin flush-logs 或 #mysqladmin refresh
这些日志的启动方式可以在mysqld_safe方式启动数据库的时候,后面跟选项参数,也可以在配置文件里配置,推荐采用第二种方式,配置方法很简单,我只配置了三种日志:
[mysqld]
log=/var/log/mysqld_common.log
log-error=/var/log/mysqld_err.log
log-bin=/var/log/mysqld_bin.bin
日志的查看很简单,大部分都是文本,直接用vim、less、more之类的工具看就可以了,值得说明的是二进制文件的查看:
1). 首先确定是否开启了二进制文件记录功能
mysql>show variables like 'log_bin';
2). 如果你想知道现在记录二进制数据的文件具体信息,你可以通过下列语句看到现在正在记录哪个文件,以及记录的当前位置:
mysql>show master status;
3). 查看二进制数据需要借助程序mysqlbinlog,看看它支持哪些选项,根据自己需要来使用。
mysql>mysqlbinlog /var/log/mysql/mysql-bin.000040;
查询某个时间范围的可以执行如下语句,如果记录很多,可以将结果定向到一个文件里自己慢慢看:-) :
mysql>mysqlbinlog --start-datetime='2010-01-01 00:00:00' --stop-datetime='2010-01-25 00:00:00' /var/log/mysql/mysql-bin.000040 > ./tmp.log

==========================================================================================================

下面先介绍二进制日志的作用和使用方法,并利用二进制日志对数据库进行各种维护和优化

二进制日志的文件的作用

    mysql二进制日志文件用来记录所有用户对数据库操作,即记录用户对数据库操作的sql语句。如果有此文件,当数据库发生意外时,可以通过此文件查看到用户在此文件记录的时间段内用户所做的操作,再和数据库备份配合使用,即可再现用户操作,使数据库恢复。

  1. 作用:   
  2.     1。二进制日志的主要目的是在恢复使能够最大可能地更新数据库,因为二进制日志包含备份后进行的所有更新。   
  3.     2。二进制日志还用于在主复制服务器上记录所有将发送给从服务器的语句。   

二进制日志文件的弊端

二进制日志文件开启后,所有对数据库操作的记录均会被记录到此文件,

所以,当长时间开启之后,日志文件会变得很大,占用磁盘空间。

运行服务器时若启用二进制日志则性能大约慢1%。

 

如何启动:   

  1.     通过 --log-bin=file选项可以启用     (更改my.ini文件)   

日志位置:  

  1.     >>如果没有指定文件名,则Mysql使用hostname-bin文件.   
  2.     >>如果指定了相对路径,则假定该路径相对于数据目录   
  3.     >>Mysql在文件名后添加了数字索引.所以该文件最后的形式为filename.number   
  4.     如果你在日志名中提供了扩展名(例如,--log-bin=file_name.extension),则扩展名被悄悄除掉并忽略。   

更换策略:  

 使用索引来循环文件,在以下条件将循环至下一个索引   

 1。服务器重启   

2。服务器被更新   

3。日志到达了最大日志长度 max_binlog_size   

4。日志被刷新 mysql> flush logs;   

 

工具介绍:  

  1.     shell>>mysqlbinlog [option] binlogFile> newfile   
  2.     如: D:\mysql\log>mysqlbinlog  binlog.000001 > 1.txt   
  3. 一个例子:   
  4.     log-bin="D:/mysql/log/binlog"  那么,在该文件夹下就会有文件D:/mysql/log/binlog.000001

二进制文件的查看:

由于日志是以二进制方式存储的,不能直接读取,需要使用mysql自带的mysqlbinlog工具来进行查看
语法如下:

#mysqlbinlog mysql-bin.000002
现在我们尝试向test1表插入数据

然后使用mysqlbinlog工具进行日志查看
#mysqlbinlog mysql-bin.000002 -d test

=============================================================================

常见问题:

1.如何清除binlog     

>>>使用下面的两个命令   

  1. PURGE {MASTER | BINARY} LOGS TO 'log_name' //log_name不会被清除   
  2. PURGE {MASTER | BINARY} LOGS BEFORE 'date' //date不会被清除   

实例如下:   

  1. mysql> purge master logs to 'binlog.000004';   
  2. Query OK, 0 rows affected (0.01 sec)   
  3. mysql> purge master logs before '2009-09-22 00:00:00';   
  4. Query OK, 0 rows affected (0.05 sec)   

>>>或使用命令   

  1. RESET MASTER   
  2. 删除之前所有的binlog,并重新生成新的binlog   
  3. 后缀从000001开始   

   注:如果您有一个活性的从属服务器,该服务器当前正在读取您正在试图删除的日志之一,   

  1. 则本语句不会起作用,而是会失败,并伴随一个错误。   
  2. 不过,如果从属服务器是休止的,并且您碰巧清理了其想要读取的日志之一,则从属服务器启动后不能复制。   
  3. 当从属服务器正在复制时,本语句可以安全运行。您不需要停止它们。   

2.记录到二进制日志知的内容配置  

  1. binlog-do-db=sales 只记录sales库   
  2. binlog-ignore-db=sales 除sales库不记录,其他都记录   

但是如果在操作数据库之前,不使用use $dbname 那么所有的SQL都不会记录   

如果使用了use $dbname,那么判断规则取决于这里的$dbname,而不是SQL中操作的库   

 

3.二进制日志不准确的处理   

  1. 默认情况下,并不是每次写入时都将二进制日志与硬盘同步。因此如果操作系统或机器(不仅仅是MySQL服务器)崩溃,有可能二进制日志中最后的语句丢失。   
  2. 要想防止这种情况,你可以使用sync_binlog全局变量(1是最安全的值,但也是最慢的),使二进制日志在每N次二进制日志写入后与硬盘同步。   
  3. 即使sync_binlog设置为1,出现崩溃时,也有可能表内容和二进制日志内容之间存在不一致性。   
  4.   
  5. 如果崩溃恢复时MySQL服务器发现二进制日志变短了(即至少缺少一个成功提交的InnoDB事务),   
  6. 如果sync_binlog =1并且硬盘/文件系统的确能根据需要进行同步(有些不需要)则不会发生,则输出错误消息 ("二进制日志<名>比期望的要小")。   
  7. 在这种情况下,二进制日志不准确,复制应从主服务器的数据快照开始。 

=============================================================================

常用的专门针对binary logs的mysql命令: 

1. Binary logs 位置:

1)查看/etc/my.cnf (Windows下为my.ini), 例如:

log_bin=/var/mydb/bin-log

如果该设置没带路径,就放在datadir=/var/lib/mysql 下

2) 到数据库查看是否开启binary log 功能:

mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin            | ON    |
+---------------+-------+
1 row in set (0.00 sec)

mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin             | OFF   |
+---------------+-------+
1 row in set (0.01 sec)

如果是OFF就没有以下工作了:)

2. 查看当前工作的logfile名及大小: show binary logs /show master logs;

mysql> show binary logs;
+-----------------+-----------+
| Log_name           | File_size |
+-----------------+-----------+
| bin-log.000011 |    148329 |
+-----------------+-----------+

mysql> show master logs;
+-----------------+-----------+
| Log_name           | File_size |
+-----------------+-----------+
| bin-log.000011 |    148329 |
+-----------------+-----------+

mysql> show binary logs;
ERROR 1381 (HY000): You are not using binary logging ###没有开启binary logs

3. 清除所有binary logs;

1)

mysql> show master logs;
+-----------------+-----------+
| Log_name        | File_size |
+-----------------+-----------+
| log-bin.000001 |    259548 |
| log-bin.000002 |     37200 |
| log-bin.000003 |     74219 |
+-----------------+-----------+
3 rows in set (0.00 sec)

mysql> reset master; (在slave上,用reset slave,之前应stop slave,之后再start slave)
Query OK, 0 rows affected (0.00 sec)

mysql> show master logs;
+-----------------+-----------+
| Log_name        | File_size |
+-----------------+-----------+
| log-bin.000001 |        98 |
+-----------------+-----------+
1 row in set (0.00 sec)

4. 清除指定部分logs:

mysql>purge binary logs to 'log-bin.000012';

将log-bin.000012之前的binary logs清掉;

mysql>purge binary logs before '2011-05-28 12:05:38';

将指定时间之前的binary logs清掉;

5.查看当前binary log的情况:

mysql>show master status;

6. 查看binary logs的内容:

mysql>show binlog events;

命令行下:

#mysqlbinlog /var/log/mysql/log-bin.000140; 或者

#mysqlbinlog --start-datetime='2011-07-01 00:00:00' --stop-datetime='2010-07-15 00:00:00' /var/log/mysql/log-bin.000020 > ./tmp.log

7. 在my.cnf/my.ini中设定binary logs回滚天数:

expire_logs_days = 7  //这里我们设定保存日志为7天,7天之后过期的日志将被自动删除 

 

===========================================================================================================

恢复数据库

使用日志文件恢复数据库必须要有一个数据库备份(只要是在二进制日志文件功能开启之后备份的就行)。恢复数据库时,可以通过时间恢复,也可以通过操作点恢复。

bin-log是记录着mysql所有事件的操作,当mysql发生灾难性错误时,可以通过bin-log做完整恢复,基于时间点的恢复,和基于位置的恢复

完整恢复,假定我们每天凌晨2点都会使用mysqldump备份数据库,但在第二天早上9点由于数据库出现了故障,数据无法访问,需要恢复数据,先使用昨天凌晨备份的文件进行恢复到凌晨2点的状态,在使用mysqlbinlog恢复自mysqldump备份以来的binlog
mysql localhost mysql-bin.000001 | mysql -uroot -p
这样数据库就可以完全的恢复到崩溃前的完全状态

基于时间点的恢复,由于误操作,比如说删除了一张表,这时使用上面讲的完全恢复是没有用的,因为日志里面还存在误操作的语句,,我们需要的是恢复到误操作前的状态,然后跳过误操作的语句,再恢复后面操作的语句,假定我们删除了一张表的误操作发生在10:00这个时间点,我们可以使用下面的语句用备份和binlog将数据恢复到故障前

mysqlbinlog –stop-date=’2010-09-04 9:59:59′ /var/log/mysql-bin.000001 | mysql -uroot -p

然后跳过误操作的时间点,继续执行后面的binlog

mysqlbinlog –start-date=’2010-09-04 10:01:00′ /var/log/mysql-bin.000001 | mysql -uroot -p

其中–stop-date=’2010-09-04 9:59:59′ 和 –start-date=’2010-09-04 10:01:00′ 其中的时间是你误操作的时间点,当然了,这个时间点你需要你自己计算的,而且这个时间点还可以涉及到的不只是误操作,还可以有正确的操作也被跳过去了。

基于位置恢复,由于上面提到的,使用基于时间点的恢复可能出现,在一个时间点里面可能存在误操作和其他正确的操作,所以我们需要一种更为精确的恢复方式
使用mysqlbinlog查看二进制,可看到

其中drop tables test1这个误操作的end_log_pos为8879917,几下这个id,得出它前后操作的id分别为8879916,8879918
我们将进行位置恢复操作

mysqlbinlog –stop-position=’8879916′ /var/log/mysql-bin.000001 | mysql -uroot -p

mysqlbinlog –start-position=’8879918′ /var/log/mysql-bin.000001 | mysql -uroot -p

第一行是恢复到停止位置位置的所以事务,第二性是恢复从给定的起始位置知道二进制日志结束所有事物。

===========================================================================================================

附:

1.0       如果直接打开log文件 可能会是乱码,所以我们一般会:

      ~]$ mysqlbinlog logbin_ouyang.000003 >log_3.txt  复制下 然后用记事本打开!

   就可以清楚的看到 操作的编号了 或者说(行号)

2.0       如果发生了错误的操作!如果可以的话!你应该立马停止数据库!然后恢复数据!

3.0       如果只是去掉某一个语句,你可以选择恢复两次 

      ~]$ mysqlbinlog logbin_ouyang.000009 --stop-position=10625|mysql -uroot         -proot

      ~]$ mysqlbinlog logbin_ouyang.000009 --start-position=10843|mysql -uroot –proot

4.0 如果发生Could not read entry at offset 1478: Error in log format or read error. 类似的错误!

   请检查你的编号是否正确!注意这个编号 不是一些编辑器显示的那个行号!

此文,部分摘自该链接:http://www.uini.net/


你可能感兴趣的:(mysql)