MySql日志(一)二进制日志

二进制日志(Binary Log)也可叫作变更日志(Update Log),是 MySQL 中非常重要的日志。主要用于记录数据库的变化情况,即 SQL 语句的 DDL 和 DML 语句,不包含数据记录查询操作。
如果 MySQL 数据库意外停止,可以通过二进制日志文件来查看用户执行了哪些操作,对数据库服务器文件做了哪些修改,然后根据二进制日志文件中的记录来恢复数据库服务器。
二进制日志包含了引起或可能引起数据库改变(如delete语句但没有匹配行)的事件信息,但绝不会包括select和show这样的查询语句。语句以"事件"的形式保存,所以包含了时间、事件开始和结束位置等信息。

一、 启动和设置二进制日志

在/etc/my.cnf文件中
log-bin [= path / [filename]]
expire_logs_days=7 #自动清理 7 天前的log文件,可根据需要修改

参数 说明
log-bin 定义开启二进制,path表明日志文件所在的路径,filename指定了日志文件的名称,其形式为 filename.number,number 的形式为 000001、000002 等
expire_logs_days 定义了MySQL的过期时间,超过后自动水处理

每次重启 MySQL 服务后,都会生成一个新的二进制日志文件,这些日志文件的文件名中 filename 部分不会改变,number 会不断递增
默认情况下,二进制日志功能是关闭的。修改/etc/my.cnf文件,重启 MySQL 服务后可看到日志
二进制日志文件的最大值通过变量 max_binlog_size 设置(默认值为1G)。但由于二进制日志可能是基于事务来记录的(如innodb表类型),而事务是绝对不可能也不应该跨文件记录的,如果正好二进制日志文件达到了最大值但事务还没有提交则不会滚动日志,而是继续增大日志,所以 max_binlog_size 指定的值和实际的二进制日志大小不一定相等。

mysql>  SHOW VARIABLES LIKE '%log_bin%';
+---------------------------------+--------------------------------+
| Variable_name                   | Value                          |
+---------------------------------+--------------------------------+
| log_bin                         | ON                             |
| log_bin_basename                | /var/lib/mysql/mysql-bin       |
| log_bin_index                   | /var/lib/mysql/mysql-bin.index |
| log_bin_trust_function_creators | OFF                            |
| log_bin_use_v1_row_events       | OFF                            |
| sql_log_bin                     | ON                             |
+---------------------------------+--------------------------------+
6 rows in set (0.00 sec)
二、查看二进制日志
1. 查看二进制日志文件列表**

可以使用如下命令查看 MySQL 中有哪些二进制日志文件:
show binary logs 该语句用于查看当前使用了哪些二进制日志文件。
show binlog events 该语句用于查看日志中进行了哪些操作。

mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000002 |       154 |
+------------------+-----------+
1 row in set (0.00 sec)

mysql> show binlog events in 'mysql-bin.000002';
+------------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                                                                 |
+------------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------------------------+
| mysql-bin.000002 |   4 | Format_desc    |         1 |         123 | Server ver: 5.7.28-log, Binlog ver: 4                                                |
| mysql-bin.000002 | 123 | Previous_gtids |         1 |         154 |                                                                                      |
| mysql-bin.000002 | 154 | Anonymous_Gtid |         1 |         219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                                                 |
| mysql-bin.000002 | 219 | Query          |         1 |         364 | use `sys`; CREATE TABLE `aa` (
`a`  varchar(255) NULL ,
`b`  varchar(255) NULL 
) |
+------------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------------------------+
4 rows in set (0.00 sec)

2. 查看当前正在写入的二进制日志文件

可以使用以下命令查看当前 MySQL 中正在写入的二进制日志文件。
show master status 该语句用于显示主服务器中的二进制日志信息。如果是主从结构,它只会显示主从结构中主服务器的二进制日志信息。

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

3. 查看二进制日志文件内容

二进制日志使用二进制格式存储,不能直接打开查看。可以使用mysqlbinlog命令查看。
mysqlbinlog 命令的语法形式如下:

mysqlbinlog [option] log-file1 log-file2...

以下是常用的几个选项:

-d,--database=name:只查看指定数据库的日志操作
-o,--offset=#:忽略掉日志中的前n个操作命令
-r,--result-file=name:将输出的日志信息输出到指定的文件中,使用重定向也一样可以。
-s,--short-form:显示简单格式的日志,只记录一些普通的语句,会省略掉一些额外的信息如位置信息和时间信息以及基于行的日志。可以用来调试,生产环境千万不可使用
--set-charset=char_name:在输出日志信息到文件中时,在文件第一行加上set names char_name
--start-datetime,--stop-datetime:指定输出开始时间和结束时间内的所有日志信息
--start-position=#,--stop-position=#:指定输出开始位置和结束位置内的所有日志信息
-v,-vv:显示更详细信息,基于row的日志默认不会显示出来,此时使用-v或-vv可以查看

示例:

[root@VM_2_223_centos mysql]# mysqlbinlog --no-defaults  mysql-bin.000002  -d sys -s >2sys.sql
WARNING: The option --database has been used. It may filter parts of transactions, but will include the GTIDs in any case. If you want to exclude or include transactions, you should use the options --exclude-gtids or --include-gtids, respectively, instead.
[root@VM_2_223_centos mysql]# tail -10f 2sys.sql 
CREATE TABLE `aa` (
`a`  varchar(255) NULL ,
`b`  varchar(255) NULL 
)

从上图中可以看出,使用-s后,少了基于行的日志信息,也少了记录的位置和时间信息。

三、删除二进制日志

删除二进制日志有几种方法。不管哪种方法,都会将删除后的信息同步到二进制index文件中。

1. 删除所有二进制日志

使用 RESET MASTER 语句可以删除的所有二进制日志,该语句的形式如下:

mysql> reset master;

登录 MySQL 数据库后,可以执行该语句来删除所有二进制日志。删除所有二进制日志后,MySQL 将会重新创建新的二进制日志,新二进制日志的编号从 000001 开始。

2. 根据编号删除二进制日志

每个二进制日志文件后面有一个 6 位数的编号,如 000001。使用 PURGE MASTER LOGS TO 语句,可以删除指定二进制日志的编号之前的日志。该语句的基本语法形式如下:

PURGE MASTER LOGS TO 'filename.number';

该语句将删除编号小于 filename.number 的所有二进制日志。

mysql>  show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       399 |
| mysql-bin.000002 |       154 |
+------------------+-----------+
2 rows in set (0.00 sec)

mysql> purge master logs to 'mysql-bin.000002';
Query OK, 0 rows affected (0.01 sec)

mysql>  show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000002 |       154 |
+------------------+-----------+
1 row in set (0.00 sec)
3. 根据创建时间删除二进制日志

使用 PURGE MASTER LOGS TO 语句,可以删除指定时间之前创建的二进制日志,该语句的基本语法格式如下:

PURGE MASTER LOGS TO 'yyyy-mm-dd hh:MM:ss';

其中,“hh”为 24 制的小时。该语句将删除在指定时间之前创建的所有二进制日志。

4. expire_logs_days参数自动过期清空

在my.cnf中使用expire_logs_days=N选项指定过了多少天日志自动过期清空。

四、 二进制日志的记录格式

在MySQL 5.1之前,MySQL只有一种基于语句statement形式的日志记录格式。即将所有的相关操作记录为SQL语句形式。但是这样的记录方式对某些特殊信息无法同步记录,例如uuid,now()等这样动态变化的值。
从MySQL 5.1开始,MySQL支持statement、row、mixed三种形式的记录方式。row形式是基于行来记录,也就是将相关行的每一列的值都在日志中保存下来,这样的结果会导致日志文件变得非常大,但是保证了动态值的确定性。还有一种mixed形式,表示如何记录日志由MySQL自己来决定。
日志的记录格式由变量 binlog_format 来指定。其值有:row,statement,mixed。innodb引擎的创始人之一在博客上推荐使用row格式。
还有一种mixed模式。这种模式下默认会采用statement的方式记录,只有以下几种情况会采用row的形式来记录日志。
1.表的存储引擎为NDB,这时对表的DML操作都会以row的格式记录。
2.使用了uuid()、user()、current_user()、found_rows()、row_count()等不确定函数。但测试发现对now()函数仍会以statement格式记录,而sysdate()函数会以row格式记录。
3.使用了insert delay语句。
4.使用了临时表。

五、二进制日志相关的变量

注意:在配置binlog相关变量的时候,相关变量名总是搞混,因为有的是binlog,有的是log_bin,当他们分开的时候,log在前,当它们一起的时候,bin在前。在配置文件中也同样如此。

  • log_bin_trust_function_creators={on | off }#默认为OFF,这个参数开启会限制存储过程、Function、触发器的创建
  • log_bin = {on | off | base_name} #指定是否启用记录二进制日志或者指定一个日志路径(路径不能加.否则.后的被忽略)
  • sql_log_bin ={ on | off } #指定是否启用记录二进制日志,只有在log_bin开启的时候才有效
  • expire_logs_days = #指定自动删除二进制日志的时间,即日志过期时间
  • binlog_do_db = #明确指定要记录日志的数据库
  • binlog_ignore_db = #指定不记录二进制日志的数据库
  • log_bin_index = #指定mysql-bin.index文件的路径
  • binlog_format = { mixed | row | statement } #指定二进制日志基于什么模式记录
  • binlog_rows_query_log_events = { 1|0 } # MySQL5.6.2添加了该变量,当binlog format为row时,默认不会记录row对应的SQL语句,设置为1或其他true布尔值时会记录,但需要使用mysqlbinlog -v查看,这些语句是被注释的,恢复时不会被执行。
  • max_binlog_size = #指定二进制日志文件最大值,超出指定值将自动滚动。但由于事务不会跨文件,所以并不一定总是精确。
  • binlog_cache_size = 32768 #基于事务类型的日志会先记录在缓冲区,当达到该缓冲大小时这些日志会写入磁盘
  • max_binlog_cache_size = #指定二进制日志缓存最大大小,硬限制。默认4G,够大了,建议不要改
  • binlog_cache_use:使用缓存写二进制日志的次数(这是一个实时变化的统计值)
  • binlog_cache_disk_use:使用临时文件写二进制日志的次数,当日志超过了binlog_cache_size的时候会使用临时文件写日志,如果该变量值不为0,则考虑增大binlog_cache_size的值
  • binlog_stmt_cache_size = 32768 #一般等同于且决定binlog_cache_size大小,所以修改缓存大小时只需修改这个而不用修改binlog_cache_size
  • binlog_stmt_cache_use:使用缓存写二进制日志的次数
  • binlog_stmt_cache_disk_use: 使用临时文件写二进制日志的次数,当日志超过了binlog_cache_size的时候会使用临时文件写日志,如果该变量值不为0,则考虑增大binlog_cache_size的值
  • sync_binlog = { 0 | n } #这个参数直接影响mysql的性能和完整性
    • sync_binlog=0:不同步,日志何时刷到磁盘由FileSystem决定,这个性能最好。
    • sync_binlog=n:每写n次二进制日志事件(不是事务),MySQL将执行一次磁盘同步指令fdatasync()将缓存日志刷新到磁盘日志文件中。Mysql中默认的设置是sync_binlog=0,即不同步,这时性能最好,但风险最大。一旦系统奔溃,缓存中的日志都会丢失。

在innodb的主从复制结构中,如果启用了二进制日志(几乎都会启用),要保证事务的一致性和持久性的时候,必须将sync_binlog的值设置为1,因为每次事务提交都会写入二进制日志,设置为1就保证了每次事务提交时二进制日志都会写入到磁盘中,从而立即被从服务器复制过去。

六、暂时停止二进制日志

在配置文件中设置了 log_bin 选项之后,MySQL 服务器将会一直开启二进制日志功能。删除该选项后就可以停止二进制日志功能,如果需要再次启动这个功能,需要重新添加 log_bin 选项。由于这样比较麻烦,所以 MySQL 提供了暂时停止二进制日志功能的语句。
如果用户不希望自己执行的某些 SQL 语句记录在二进制日志中,可以在执行这些 SQL 语句之前暂停二进制日志功能。
使用 SET 语句来暂停/开启二进制日志功能,命令如下:
SET SQL_LOG_BIN=0/1;
以上命令中,0 表示暂停二进制日志功能,1 表示开启二进制功能。

七、二进制日志定点还原数据库

只需指定二进制日志的起始位置(可指定终止位置)并将其保存到sql文件中,由mysql命令来载入恢复即可。当然直接通过管道送给mysql命令也可。
至于是基于位置来恢复还是基于时间点来恢复,这两种行为都可以。选择时间点来恢复比较直观些,并且跨日志文件恢复时更方便。
mysqlbinlog --stop-datetime=“2014-7-2 15:27:48” /tmp/mysql-bin.000008 | mysql -u user -p password
恢复多个二进制日志文件时:
mysqlbinlog mysql-bin.[*] | mysql -uroot -p password
或者将它们导入到一个文件中后恢复。
mysqlbinlog mysql-bin.000001 > /tmp/a.sql
mysqlbinlog mysql-bin.000002 >>/tmp/a.sql
mysql -u root -p password -e “source /tmp/a.sql”

猜你喜欢

转载自blog.csdn.net/jinhf10/article/details/110224552