一、二进制日志的介绍
二进制日志的数据当然是二进制形式了,所以无法直接通过文本工具来查看,并且二进制日志也不是用来查看的而是通常给mysql使用的。它记录了对数据发生或潜在发生更改的SQL语句。
二进制日志的用途有如下几点:
Ø 可以记录对数据库所在的变更,包括DDL和DML语句。
Ø 用于数据库的增量备份,增量备份主要就是利用二进制日志实现的
但是二进制日志却可以实现完整的恢复数据到崩溃时刻的状态,前提是二进制日志需要持续记录上一次备份到崩溃时刻的所有二进制日志,即备份或增量备份+二进制日志来恢复。
Ø MySQL复制(Replication)的核心组成部分。
所以二进制日志是MySQL最重要的日志之一,其实错误日子和二进制日志都是非常重要的。
二、开启和关闭二进制日志
和通用查询日志以及慢查询日志一样,MySQL默认也是没有开启二进制日志的,如果需要则要手动开启。
1.通过set命令的方式
这种方式的好处就是不用重启mysql服务就可以生效。最主要的配置是开启和关闭以及日志大小的两个参数。
SET @@global.log_bin=1 #开启二进制日志,也可以写成 set global log_bin=1 下面也一样
单个二进制日志文件的大小,日志超出该大小则会生成笑一个文件或删除其中旧的数据,这里的单位是byte。
其它的二进制日志配置参数可以通过查看VARIABLES获取,例如: show variables like %bin%;
2.通过修改my.cnf文件的方式
修改my.cnf的方式需要重启mysql才能生效。如果要持久生效,可以先通过set来设置,然后在my.cnf中配置对应的项,这样本次由set命令生效,下次启动mysql时就由my.cnf中的生效了。
常用配置项如下:
log-bin=/usr/local/mysql/data/binlog.0001 #没有等号则就是默认,其他配置项也类似
该配置指定二进制日志的路径和文件名。默认在数据文件所在目录,名称为{hostName}-bin.xxxx,其中xxxx表示二进制日志文件的顺序编号,因为会生成多个日志文件,每个文件不超过指定的大小。
该配置非常重要,因为二进制日志文件的增长速度可能比数据库本身要块很多。例如对某个表某个一行数据更改了10次,对于数据库来数只记录最后一次更改的最终结果;而对于二进制日志文件则需要记录10次更改的所有语句。因此对二进制日志文件的位置是需要讲究的,可以单独指定到一个磁盘的某个分区上(挂载点),这样就不会与数据文件在同一个磁盘,减少了IO的负担从而可以提升数据库的性能。并且如果使用了MySQL的主动复制,那么从多个从服务器都要读取二进制日志文件,所以最好不要放在与数据文件在同一个文件系统上。
max-binlog-size=500m
设置单个二进制日志文件的最大值。默认为1GB,默认最大1GB。也就是二进制日志达到了最大值的时候就会自动创建一个新的日志文件,并且新文件的文件名的后缀数字+1,如localhost-bin.00001达到了最大大小,那么会自动生成一个 localhost-bin.00002。因为当一个文件很大是对其的读写都会变得比较慢。
binlog-do-db与binlog-ignore-db
指定二进制日志文件记录或不记录哪些数据库的操作。如果要配置多个数据库,多个数据库以逗号分割。这个配置项通常也是需要配置的!对于使用SET命令设置的时候也通常需要指定该参数。
binlog-cache-size=100m
设置二进制日志文件的缓存大小。如果对数据库的数据修改非常频繁,那么对于二进制日志文件来说将变得比数据文件的更改更加频繁!因此会导致每秒的IO次数将变得非常可观,这样直接会降低mysql的性能,并且存储设置对于每秒上千次的IO操作也无法承受,因此就需要开启二进制日志的缓存,当日志数量达到定量的时候一次性写入硬盘而不是每次都写硬盘,当然如果不设置对于操作系统而言也会有一个默认的缓存大小,但是操作系统的缓存是不确定的,通常比较小。
sync-binlog=N
每N秒将缓存中的二进制日志数据写到硬盘一次,因此是为了配合binlog-cache-size一起使用的。默认为0,也就是当缓存写满了才会写一次硬盘。
不过,你经常会陷入groupcommit函数与IO之间二选一的矛盾。如果在replication环境中,由于考虑到耐久性和一致性,需要将sync-binlog设置为1。同时还需要设置innodb_flush_log_at_trx_commit=1以及innodb-support-xa=1(默认开启)。
也就是说,一个事务的提交完毕是数据的更改完毕和二进制日志的写入完毕才是一个事务的提交完毕。由于这个问题,这样一来本来是前面并发的事务,但是由于二进制日志的写入是单个文件,也就是单线程的操作,因此对于前面对mysql的并发事务由于二进制日志的写入问题会变成多个事务串行操作。为了解决这个问题,mysql就使用了group commit来解决,也就是将前面多个事务的提交组合成一个组来一起提交给mysql,这样对二进制的记录就可将多个事务的操作当作一个事务来对待,进行统一的写入,对二进制的写入就类似了并发写入一样。
要理解这个group commit与二进制日志的记录关系,要明确二进制日志的记录过程。
如果sync-binlog设置为0,那么对数据来说是最安全的。如果非0,那么在没有将缓存写入硬盘时发生了系统崩溃,那么数据就真的丢失了,因为数据库中已经写入,但是二进制日志没有写入,在重启msyql的时候会将数据库中的数据回滚掉。但是设置为0又会遇到性能问题,以及无法使用group commit,因为没有缓存就会导致二进制日志是每个事务来说串行写入,因此事务也实际变为串行。
个人觉得,实际中为了保险起见将sync-binlog=0即可,然后将二进制日志文件设置到另一个磁盘上即可。如果是replicaton环境,官方建议将sync-binlog设置为1。
三、暂停二进制日志的记录
由于某些原因需要暂停二进制日志的记录,前提是已经配置或设置了开启二进制日志并正在记录,那么就可以通过暂停和恢复来控制二进制日志的记录。
set sql_log_bin=0 #暂停记录二进制日志,但是不是关闭二进制日志。 1为开始记录,即取消暂停。
例如要从外部导入一大批的数据到mysql中,此时对于记录二进制日志是没有太大意义的,并且如果要记录则会导致二进制日志的体积猛烈增长。因此可以先暂停二进制日志的记录,当导入完毕后再取消暂停。