MySQL-日志&二进制日志binlog初探

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: MySQL-日志&二进制日志binlog初探

生猛干货

带你搞定MySQL实战,轻松对应海量业务处理及高并发需求,从容应对大场面试


官方文档

https://dev.mysql.com/doc/

如果英文不好的话,可以参考 searchdoc 翻译的中文版本

http://www.searchdoc.cn/rdbms/mysql/dev.mysql.com/doc/refman/5.7/en/index.com.coder114.cn.html


二进制日志 : http://www.searchdoc.cn/rdbms/mysql/dev.mysql.com/doc/refman/5.7/en/binary-log.com.coder114.cn.html


MySQL日志分类

MySQL服务层日志

  • 二进制日志: 记录更改数据的语句
  • 慢查询日志:记录所有执行时间超过 long_query_time 秒的所有查询或不使用索引的查询
    MySQL默认不开启慢查询日志。
mysql> show variables like '%slow_query%';  # 我这里设置打开了,默认关闭
+---------------------+---------------------------------+
| Variable_name       | Value                           |
+---------------------+---------------------------------+
| slow_query_log      | ON                              |
| slow_query_log_file | /var/lib/mysql/artisan-slow.log |
+---------------------+---------------------------------+
2 rows in set (0.00 sec)
mysql> 
mysql> show variables like 'long_query_time';  # 默认10秒
+-----------------+-----------+
| Variable_name   | Value     |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
1 row in set (0.00 sec)
mysql> 
  • long_query_time,超过这个阈值,MySQL会记录超过该值的所有SQL,必须大于, 等于改值的不会被记录。
    另外一个和慢查询相关的参数 log_queries_not_using_indexes
mysql> show variables like 'log_queries_not_using_indexes';
+-------------------------------+-------+
| Variable_name                 | Value |
+-------------------------------+-------+
| log_queries_not_using_indexes | OFF   |
+-------------------------------+-------+
1 row in set (0.00 sec)
mysql>
  • 如果SQL没有使用索引,则会被记录到慢日志查询中。

  • 通用日志 :记录建立的客户端连接和执行的语句
  • 中继(relay)日志:从节点复制主服务器接收的数据更改
  • DDL日志(元数据日志):元数据操作由DDL语句执行
  • 错误日志
mysql> show variables like 'log_error';
+---------------+---------------------+
| Variable_name | Value               |
+---------------+---------------------+
| log_error     | /var/log/mysqld.log |
+---------------+---------------------+
1 row in set (0.01 sec)
mysql> 
  • 错误日志记录了MySQL的启动、运行、关闭过程进行了记录。 方便定位问题,如果mysql起不来,首先就应该去这个日志文件来看。

存储引擎层日志

以Innodb存储引擎来讲,主要由 Redo log 和 Undo log , 为了支持事务。


binlog

这里我们重点来了解下 binlog的主要功能


binlog都记录了哪些内容

binlog中主要记录了所有对MySQL数据库的修改事件,包括增删改事件以及对表结构的修改事件,不包括 select 和 show 之类的操作(这部分会记到查询日志中) 。 需要注意的一点: 只有成功执行的才回被记录到binlog中,那些执行出错或者已经回滚的数据,是不会被记录到binlog中的。

binlog 的主要目的是主从复制和数据恢复

  • 在Master端开启binlog,Master把它的二进制日志传递给slaves来达到master-slave数据一致的目的
  • 数据恢复:通过使用 mysqlbinlog工具来使恢复数据

什么时候写binlog

InnoDB (支持事务的存储引擎),必须要提交了事务才会记录binlog。binlog 什么时候刷新到磁盘取决于参数 sync_binlog

  • 如果设置为0,则表示MySQL不控制binlog的刷新,由文件系统去控制它缓存的刷新;
  • 如果设置为不为0的值,则表示每 sync_binlog 次事务,MySQL调用文件系统的刷新操作刷新binlog到磁盘中。

如果 sync_binlog=0 或 sync_binlog大于1,当发生电源故障或操作系统崩溃时,可能有一部分已提交但其binlog未被同步到磁盘的事务会被丢失,恢复程序将无法恢复这部分事务。

建议设置为1是最安全的,在系统故障时最多丢失一个事务的更新,但是会对性能有所影响。


binlog 文件以及扩展

binlog日志包括两类文件:

  • 二进制日志索引文件(文件名后缀为.index)用于记录所有有效的的二进制文件
  • 二进制日志文件(文件名后缀为.00000*)记录数据库所有的DDL和DML语句事件

何时会生成新的binlog

  • MySQL服务器停止或重启时
  • 使用 flush logs 命令;
  • 当 binlog 文件大小超过 max_binlog_size 变量的值

以上三种情况,MySQL会重新生成一个新的日志文件,文件序号递增。

注: max_binlog_size 的最小值是4096字节,最大值和默认值是 1GB (1073741824字节)。

事务被写入到binlog的一个块中,所以它不会在几个二进制日志之间被拆分。因此,如果你有很大的事务,为了保证事务的完整性,不可能做切换日志的动作,只能将该事务的日志都记录到当前日志文件中,直到事务结束,所以有的时候我们会看到binlog文件大于 max_binlog_size 的情况。


binlog的格式

二进制日志中的事件的格式取决于二进制记录格式。支持三种格式类型:

  • STATEMENT:基于SQL语句的复制(statement-based replication, SBR)
  • ROW:基于行的复制(row-based replication, RBR)
  • MIXED:混合模式复制(mixed-based replication, MBR)

Version < MySQL 5.7.7 ,默认的格式是 STATEMENT,

Version >= MySQL 5.7.7 + ,默认值是 ROW。

日志格式通过 binlog-format 指定 —> binlog-format=STATEMENT、binlog-format=ROW、binlog-format=MIXED


基于段的格式-STATEMENT

基于段的格式 binlog_format=STATEMENT

STATEMENT 的优缺点
  • 优点:日志记录量相对较小,节省磁盘及网络I/O ,只对一条删记录进行修改或者插入,row格式所产生的日质量小于段产生的日志量
  • 缺点: 必须要记录上下文的信息,以确保在从服务器上能够正确执行。但是有些特定函数比如UUID(),user() ,now()这样非确定性函数还是无法复制,有可能造成主备服务器数据不一致。

使用mysqlbinlog查看binlog
[root@artisan ~]# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 44
Server version: 5.7.29-log MySQL Community Server (GPL)
.....
.....
mysql> show variables like 'binlog_format'; # 查看当前binlog的格式
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |
+---------------+-------+
1 row in set (0.00 sec)
mysql> set session binlog_formate=statement; # 修改session级别的binlog格式为statement
mysql> set session binlog_format=statement;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like 'binlog_format';  #确认下当前binlog的格式
+---------------+-----------+
| Variable_name | Value     |
+---------------+-----------+
| binlog_format | STATEMENT |
+---------------+-----------+
1 row in set (0.00 sec)
mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       177 |
| mysql-bin.000002 |       177 |
....
....
| mysql-bin.000049 |      177 |
+------------------+-----------+
45 rows in set (0.00 sec)
mysql> flush logs; #  刷新log ,会产生一个新的binlog
Query OK, 0 rows affected (0.05 sec)
mysql> show binary logs;
+------------------+-----------+
| Log_name         | File_size |
+------------------+-----------+
| mysql-bin.000001 |       177 |
....
....
| mysql-bin.000049 |      177 |
| mysql-bin.000050 |      154 |
+------------------+-----------+
46 rows in set (0.00 sec)
mysql> 下面随便搞点操作,方便观察binlog
mysql> create database artisan2;
Query OK, 1 row affected (0.00 sec)
mysql> use artisan2;
Database changed
mysql> create table t(id int , c1 varchar(10));
Query OK, 0 rows affected (0.30 sec)
mysql> insert into t values(1,'a'),(2,'b');
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0
mysql> 

切到binlog的目录下 (/etc/my.cnf中配置的log-bin项)

[root@artisan binlog]# pwd
/var/lib/mysql/data/binlog
[root@artisan binlog]# mysqlbinlog  mysql-bin.000050 
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#200131 16:15:14 server id 1  end_log_pos 123 CRC32 0xf1d6a9f8  Start: binlog v 4, server v 5.7.29-log created 200131 16:15:14
# Warning: this binlog is either in use or was not closed properly.
BINLOG '
EuIzXg8BAAAAdwAAAHsAAAABAAQANS43LjI5LWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
Afip1vE=
'/*!*/;
# at 123
#200131 16:15:14 server id 1  end_log_pos 154 CRC32 0x19c20618  Previous-GTIDs
# [empty]
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@artisan binlog]# 

5.7.29版本的这个statement格式的binlog ,居然没法直接看内容了 ,先记录下。

5.7.9中 还能看到具体的SQL


基于行的格式-Row

基于行的日志格式 binlog_format=ROW

举个例子,假设有一个SQL修改了1万条数据, 基于段Statement的日志格式仅仅会记录这个SQL, 而基于Row的日志会有1万条记录分别记录每一行的数据修改。


优缺点
  • 优点: 记录每一条数据的变更,因此使得MySQL主从复制更加安全。 对每一行数据的修改比基于段的复制高效 。 还可以用来数据恢复(比对数据的变更)
  • 缺点: 因为要记录每一条的变更,因此记录日志量较大

日志内容的控制参数 binlog_row_image
binlog_row_image = FULL | MINIMAL | NOBLOB  (3个选项,默认FULL)

举个例子 一个表中 有 20 列(20个字段) ,3个参数的区别如下

  • FULL 全部字段都记录
  • MINIMAL 仅记录变更的字段数据
  • NOBLOB : 和full类似,只是不记录BLOB类型的字段,其他全记录
mysql> show variables like 'binlog_row_image';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| binlog_row_image | FULL  |
+------------------+-------+
1 row in set (0.00 sec)
mysql> set session binlog_row_image=minimal;  # 修改 
Query OK, 0 rows affected (0.00 sec)

增加c2字段 ,text类型


full

默认 FULL的情况

mysqlbinlog -vv 命令查看ROW格式的日志


minimal

修改为 minimal

mysqlbinlog -vv 命令查看ROW格式的日志

可以看到

仅记录了 变化的 字段的内容。


noblob

设置参数为 noblob

将非 blob字段 更新下,看看是否记录blob字段的信息

mysqlbinlog -vv 命令查看ROW格式的日志

可以看到

第三列,text类型的,并没有在binLog中。


查看Row格式的binglog

Row格式的 增加 -vv 查看

[root@artisan binlog]# mysqlbinlog -vv  mysql-bin.000050

我这个5.7.29的版本 看不到。。。有可能是打开方式不对,待确认 。

5.7.9版本可以


混合日志格式-mixed

binlog_format=MIXED

特点
  • 根据SQL语句由系统决定在基于段和基于行的日志格式中进行选择
  • 数据量的大小由所执行的SQL决定

不展开了,并不是一种新的格式


常用binlog操作

## binlog相关的命令 
```sql
# 查看是否开启binlog
mysql>show binary logs;
#查看binlog格式:
mysql>show variables like 'binlog_format';
#获取binlog文件列表:
mysql>show binary logs;
#查看当前正在写入的binlog文件:
mysql>show master status;
#查看master上的binlog:
mysql>show master logs;
#只查看第一个binlog文件的内容:
mysql>show binlog events;
#查看指定binlog文件的内容:
mysql>show binlog events in 'mysql-bin.000045';
#清空所有的bin-log:
mysql>reset master;
#生成一个新的binlog:
mysql>flush logs;

binlog相关的参数


小结

建议 binlog_format=mixed 或者 row, 如果用row的话,最好binlog_row_image=minimal ,减少binlog的大小,占用更少的网络I/O 和 磁盘I/O


搞定MySQL


相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
22天前
|
存储 SQL 关系型数据库
mysql 的ReLog和BinLog区别
MySQL中的重做日志和二进制日志是确保数据库稳定性和可靠性的关键组件。重做日志主要用于事务的持久性和原子性,通过记录数据页的物理修改信息来恢复未提交的事务;而二进制日志记录SQL语句的逻辑变化,支持数据复制、恢复和审计。两者在写入时机、存储方式及配置参数等方面存在显著差异。
|
5天前
|
SQL 关系型数据库 MySQL
数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog
《数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog》介绍了如何利用MySQL的二进制日志(Binlog)恢复误删除的数据。主要内容包括: 1. **启用二进制日志**:在`my.cnf`中配置`log-bin`并重启MySQL服务。 2. **查看二进制日志文件**:使用`SHOW VARIABLES LIKE &#39;log_%&#39;;`和`SHOW MASTER STATUS;`命令获取当前日志文件及位置。 3. **创建数据备份**:确保在恢复前已有备份,以防意外。 4. **导出二进制日志为SQL语句**:使用`mysqlbinlog`
33 2
|
22天前
|
SQL 存储 缓存
MySQL进阶突击系列(02)一条更新SQL执行过程 | 讲透undoLog、redoLog、binLog日志三宝
本文详细介绍了MySQL中update SQL执行过程涉及的undoLog、redoLog和binLog三种日志的作用及其工作原理,包括它们如何确保数据的一致性和完整性,以及在事务提交过程中各自的角色。同时,文章还探讨了这些日志在故障恢复中的重要性,强调了合理配置相关参数对于提高系统稳定性的必要性。
|
1月前
|
关系型数据库 MySQL 数据库
【赵渝强老师】MySQL的binlog日志文件
MySQL的binlog日志记录了所有对数据库的更改操作(不包括SELECT和SHOW),主要用于主从复制和数据恢复。binlog有三种模式,可通过设置binlog_format参数选择。示例展示了如何启用binlog、设置格式、查看日志文件及记录的信息。
134 6
|
1月前
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
363 30
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
16天前
|
监控 安全 Apache
什么是Apache日志?为什么Apache日志分析很重要?
Apache是全球广泛使用的Web服务器软件,支持超过30%的活跃网站。它通过接收和处理HTTP请求,与后端服务器通信,返回响应并记录日志,确保网页请求的快速准确处理。Apache日志分为访问日志和错误日志,对提升用户体验、保障安全及优化性能至关重要。EventLog Analyzer等工具可有效管理和分析这些日志,增强Web服务的安全性和可靠性。
|
2月前
|
XML JSON Java
Logback 与 log4j2 性能对比:谁才是日志框架的性能王者?
【10月更文挑战第5天】在Java开发中,日志框架是不可或缺的工具,它们帮助我们记录系统运行时的信息、警告和错误,对于开发人员来说至关重要。在众多日志框架中,Logback和log4j2以其卓越的性能和丰富的功能脱颖而出,成为开发者们的首选。本文将深入探讨Logback与log4j2在性能方面的对比,通过详细的分析和实例,帮助大家理解两者之间的性能差异,以便在实际项目中做出更明智的选择。
336 3
|
26天前
|
存储 监控 安全
什么是事件日志管理系统?事件日志管理系统有哪些用处?
事件日志管理系统是IT安全的重要工具,用于集中收集、分析和解释来自组织IT基础设施各组件的事件日志,如防火墙、路由器、交换机等,帮助提升网络安全、实现主动威胁检测和促进合规性。系统支持多种日志类型,包括Windows事件日志、Syslog日志和应用程序日志,通过实时监测、告警及可视化分析,为企业提供强大的安全保障。然而,实施过程中也面临数据量大、日志管理和分析复杂等挑战。EventLog Analyzer作为一款高效工具,不仅提供实时监测与告警、可视化分析和报告功能,还支持多种合规性报告,帮助企业克服挑战,提升网络安全水平。
|
2月前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1712 14
|
1月前
|
存储 监控 安全
什么是日志管理,如何进行日志管理?
日志管理是对IT系统生成的日志数据进行收集、存储、分析和处理的实践,对维护系统健康、确保安全及获取运营智能至关重要。本文介绍了日志管理的基本概念、常见挑战、工具的主要功能及选择解决方案的方法,强调了定义管理目标、日志收集与分析、警报和报告、持续改进等关键步骤,以及如何应对数据量大、安全问题、警报疲劳等挑战,最终实现日志数据的有效管理和利用。
113 0