Binlog概念
Binlog其实是(binary log)MySQL的二进制日志,以二进制的形式记录了对于数据库的变更操作,不包括select和show操作。
- 用来查看MySQL变更
- MySQL的备份恢复
- MySQL的主从复制
文件位置
Binlog默认放置在数据目录下
Binlog的命名方式
mysql-bin.000001
binlog文件的生成方式
- MySQL启动的时候会产生binlog
- MySQL服务器在执行flush logs;可以产生新的binlog文件
关于binlog的参数
总体的关于binlog的参数如下:
sync_binlog = 1
log_bin = mysql-bin
binlog_format = row
expire_logs_days = 10
binlog_cache_size = 4M
max_ binlog_cache_size = 8M
max_binlog_size = 1024M
相关参数讲解
Log_bin:决定了MySQL的binlog的名字,生成的binlog名字为mysql-bin.000001
Binlog_format:规定binlog的格式,binlog有三种格式statement、row、mixad,默认使用statement,建议使用row格式
Expire_logs_days:过期时间
Binlog_do_db:此参数表示只记录指定数据库的二进制日志
Binlog_ignore_db:此参数表示不记录指定的数据库的二进制日志
Sync_binlog:在提交n次事务后,进行binlog的落盘,0为不进行强行的刷新操作,而是由文件系统控制刷新日志文件,如果是在线交易和账有关的数据建议设置成1,如果是其他数据可以保持为0即可
Max_binlog_size:binlog文件的最大值,默认和最大是1G,并不能严格限定二进制文件的大小
Max_binlog_cache_size:表示binlog能够使用的最大cache内存大小
当我们执行多语句事务的时候,所有session的使用的内存超过max_binlog_cache_size的值时就会报错:”Multi-statement transaction required more than ‘max_binlog_cache_size’ bytes ofstorage”
MySQL binlog格式
Statement格式
特点:记录每一条数据的sql,将执行的每一条sql记录在binlog中,减少日志量,节省IO,提高行能。
缺点:某些sql中的函数无法使用,比如sysdate(),在同步过程中会出现无法同步到问题。
Mixed格式
特点:一般的语句使用sql语句记录,遇到特殊的语句使用row格式记录,保证数据的一致性和复制的准确性
Row格式
特点:binlog中仅仅记录哪一条记录被修改,不记录dml的sql语句,会详细记录每一row的更改细节,不会出现无法复制的问题。
缺点:因为要记录每一条修改记录的日志,所有大量占用磁盘IO和大量使用磁盘空间。
清理过期的binlog日志
在开启MySQL的主从后,会产生大量的binlog日志文件,可能产生大量的磁盘空间
手工删除binlog
Mysql>reset master; //删除master的binlog,慎用!!!
Mysql>reset slave; //删除slave的中继日志
Mysql>purge master logs before ‘2019-11-22 16:39:01’; //删除指定日期以前的日志索引中binlog日志文件
Mysql>purge master logs to ‘binlog.000002’; //删除指定日志文件的日志索引中binlog日志文件
或者直接使用操作系统命令直接删除
自动删除binlog
通过binlog参数(expire_logs_days)来实现MySQL自动删除binlog
Mysql>show binary logs;
Mysql>show variables like ‘expire_logs_days’;
Mysql>set global expire_logs_days=3;
手工清除binlog文件
1. 可以通过MySQL命令清除binlog
使用reset master重置binlog文件
Mysql>reset master; //删除master所有的binlog文件,并且重置为1个,慎用!!!
Mysql>show master logs;
Log_name file_size
Mysql-bin.000001 151
####reset master后,会造成slave无法找到master的严重后果
2. 直接rm本地删除binlog
查看正在使用的binlog
Mysql>show master status;
Fiel position binlog_do_db binlog_ignore_db executd_gtid_set
Mysql-bin.000001 151
直接使用rm命令删除不是当前使用的binlog
rm –rf mysql-bin.000002
###切记不要删除正在使用的binlog
-----------------------------------------------------------------------------------------------------------------
登录mysql之后使用下面的命令查看是否开启binlog
show variables like 'log_%';
开启binlog
编辑配置文件
vi /etc/my.cnf
添加如下内容:
server_id=2
log_bin = mysql-bin
binlog_format = ROW
expire_logs_days = 30
重启mysql服务
systemctl restart mysqld
1.错误日志(log_error)
1.1 作用
记录启动\关闭\日常运行过程中,状态信息,警告,错误
1.2 错误日志配置
默认就是开启的: /数据路径下/hostname.err
手工设定:
mysql>select @@log_error;
vim /etc/my.cnf
log_error=/var/log/mysql.log
log_timestamps=system
重启生效
show variables like 'log_error';
1.3 日志内容查看
主要关注[ERROR],看上下文
2. binlog(binary logs):二进制日志 *****
2.1作用:
- 备份恢复必须依赖二进制日志
- 主从环境必须依赖二进制日志
2.2Binlog配置(5.7必须加server_id):
注意:MySQL默认是没有开启二进制日志的。
基础参数查看:
mysql> select @@log_bin; --日志的开关
mysql> select @@log_bin_basename; --日志存放路径及名字
mysql> select @@server_id; --服务id号
mysql> select @@binlog_format; --二进制日志模式
mysql> select @@sync_binlog;
Mysql配置参数sync_binlog说明
MySQL提供一个sync_binlog参数来控制数据库的binlog刷到磁盘上去。
默认,sync_binlog=0,表示MySQL不控制binlog的刷新,由文件系统自己控制它的缓存的刷新。这时候的性能是最好的,但是风险也是最大的。因为一旦系统Crash,在binlog_cache中的所有binlog信息都会被丢失。
如果sync_binlog>0,表示每sync_binlog次事务提交,MySQL调用文件系统的刷新操作将缓存刷下去。最安全的就是sync_binlog=1了,表示每次事务提交,MySQL都会把binlog刷下去,是最安全但是性能损耗最大的设置。这样的话,在数据库所在的主机操作系统损坏或者突然掉电的情况下,系统才有可能丢失1个事务的数据。但是binlog虽然是顺序IO,但是设置sync_binlog=1,多个事务同时提交,同样很大的影响MySQL和IO性能。虽然可以通过group commit的补丁缓解,但是刷新的频率过高对IO的影响也非常大。对于高并发事务的系统来说,“sync_binlog”设置为0和设置为1的系统写入性能差距可能高达5倍甚至更多。
所以很多MySQL DBA设置的sync_binlog并不是最安全的1,而是100或者是0。这样牺牲一定的一致性,可以获得更高的并发和性能。
2.3binlog记录了什么?
Binlog是sql层的功能,记录的是变更sql语句,不记录查询语句。
2.3.1记录sql语句种类
DDL:原封不动的记录当前DDL(statement)。
DCL:原封不动的记录当前DCL(statement)。
DML:只记录已经提交的事务DML。
2.3.2DML三种记录方式:
Binlog_format(binlog的记录格式)参数影响
- statement(5.6默认)SBR(statement based replication):语句模式原封不动的记录当前DML
- ROW(5.7默认)RBR(row based replication):记录数据行的变化(用户看不懂,需要工具分析)。
- Mixed(混合模式)MBR(mixed based replication):以上两种模式的混合,一般不用这种模式
2.3.3 SBR和RBR模式的对比:(面试点)
Statement:可读性较高,日志量少,但是不够严谨
ROW:可读性低,日志量大,足够严谨
例如:
Update t1 set xxx=xxx where id > 1000;--->假如更新了500w行
如果是statement模式的话,只是记录这条sql语句,而row模式记录了这500w行数据变化。所以row模式日志量较大。
再例如:
Insert into t1 values (1,’zyg’,now());假如这条语句是2020/05/30,17:04:30执行的。
如果是statement模式的话,你在2020/05/31日查看的话,你会误以为是今天插进去,而row模式会记录具体的时间2020/05/30,17:04:30,所以row模式更加严谨。
所以我们建议使用:row记录模式。
2.4 Event(事件)是什么?
2.4.1 简介:
二进制日志的最小记录单元
对于DDL、DCL,一个语句就是一个event;对于DML语句来讲:只记录已提交的事务。
例如以下例子,就被分为了4个event
Begin; 120 - 240
DML1 240 - 360
DML2 360 - 480
Commit; 480 - 600
2.4.2 Event的组成
三部分构成
- 事件的开始标识
- 事件内容
- 事件的结束标识
2.5 日志文件查看
2.5.1 查看日志的开启情况
log_bin参数设置的路径,可以找到二进制日志
mysql> show variables like '%log_bin%';
2.5.2查看binlog日志文件有哪些:
mysql>show binary logs;
2.5.3 查看mysql正在使用的日志文件
mysql>show master status;
file:当前MySQL正在使用的文件名
Position:最后一个事件的结束位置号
2.6 日志内容查看
2.6.1 event查看
mysql>show binlog events in ‘master.000028’;
注释:
Log_name:binlog文件名
Pos:开始的position *****
Event_type:事件类型
Format_desc:格式描述,每一个日志文件的第一个事件,多用户没有意义,MySQL识别binlog必要信息
Server_id:MySQL服务号标识
End_log_pos:事件结束位置号 *****
Info:事件内容 *****
2.6.2更多参数
mysql> help show binlog events;
2.6.3定位到具体sql语句:
[root@node4 mysql]# mysql -uroot -p -e "show binlog events in 'master.000024'" | grep create
2.6.4Binlog文件内容详细查看:
[root@node4 mysql]# mysqlbinlog /var/lib/mysql/master.000024
例如:
Position(位置号):
开始标识:at 200
结束标识:end_log_pos 250(下一个开始标识不是251,而是250,上一个结束就是下一个的开始)
位置号的作用:为了方便我们截取事件
2.6.5转换成能看的懂的binlog文件内容查看:
[root@node4 mysql]# mysqlbinlog --base64-output=decode-rows -vvvvvv /var/lib/mysql/master.000024
注释:@1:代表第一列;@2代表第二列。。。以此类推
2.6.6只看某一个数据库的操作:
[root@node4 mysql]# mysqlbinlog --base64-output=decode-rows -vvvvvv /var/lib/mysql/master.000024 -d kettle
2.6.7日志截取查看:
1.查看某段时间日志
[root@node4 mysql]# mysqlbinlog --base64-output=decode-rows -vvvvvv --start-datetime="2020-05-22 15:01:53" --stop-datetime="2020-05-22 15:02:00" /var/lib/mysql/master.000024 -d kettle
注意:”=”两边不要有空格,不然会报错
2.查看某段position日志:
[root@node4 mysql]# mysqlbinlog --start-position=889 --stop-position=1003 /var/lib/mysql/master.000024 -d kettle
mysqlbinlog更多参数:
[root@node4 mysql]# mysqlbinlog –help
或者
[root@node4 mysql]# man mysqlbinlog
查看更多的参数,这里就不一一介绍了。
3案例:使用binlog日志进行数据恢复
1. mysql> create database binlog charset utf8; Query OK, 1 row affected (0.00 sec) 2. mysql> use binlog; Database changed mysql> create table test(id int); Query OK, 0 rows affected (0.33 sec) 3. mysql> insert into test values (1); Query OK, 1 row affected (0.01 sec) mysql> commit; Query OK, 0 rows affected (0.00 sec) mysql> insert into test values (2); Query OK, 1 row affected (0.00 sec) mysql> commit; Query OK, 0 rows affected (0.00 sec) mysql> insert into test values (3); Query OK, 1 row affected (0.00 sec) mysql> commit; Query OK, 0 rows affected (0.00 sec) 4. mysql> drop database binlog; Query OK, 1 row affected (0.35 sec) 5.查看当前用的日志事件 mysql> show master status; 6. mysql> show binlog events in 'master.000028'; [root@node4 mysql]# mysqlbinlog --start-position=1492 --stop-position=2615 /var/lib/mysql/master.000028 > /tmp/bin.sql mysql> show databases; mysql> select @@sql_log_bin; mysql> set sql_log_bin=0; 插一脚: sql_log_bin用处: 1.当还原数据库的时候,如果不关闭二进制日志,那么你还原的过程仍然会记录在二进制日志里面,不仅浪费资源,那么增加了磁盘的容量,还没有必要(特别是利用二进制还原数据库的时候)所以一般还原的时候会选择关闭二进制日志,可以通过修改配置文件,重启关闭二进制日志。 也可以动态命令关闭sql_log_bin,然后导入数据库。 2. 如果想在主库上执行一些操作,但不复制到slave库上,可以通过修改参数sql_log_bin来实现。设为0后,在Master数据库上执行的语句都不记录binlog。要慎重使用global修饰符(set global sql_log_bin=0),这样会导致所有在Master数据库上执行的语句都不记录到binlog,这肯定不是你想要的结果。 mysql> select @@sql_log_bin; mysql> source /tmp/bin.sql |