百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

MySQL Binlog 初识

bigegpt 2024-08-18 13:59 6 浏览

Mysql日志

MySQL 的日志包括错误日志(ErrorLog),更新日志(Update Log),二进制日志(Binlog),查询日志(Query Log),慢查询日志(Slow Query Log)等;

更新日志是老版本的MySQL 才有的,目前已经被二进制日志替代;在默认情况下,系统仅仅打开错误日志,关闭了其他所有日志,以达到尽可能减少IO损耗提高系统性能的目的,但是在一般稍微重要一点的实际应用场景中,都至少需要打开二进制日志,因为这是MySQL很多存储引擎进行增量备份的基础,也是MySQL实现复制的基本条件;

下面介绍的就是二进制日志–Binlog

Binlog开启

默认Binlog是关闭的,首先要开启才能记录日志;

1.查看是否开启log_bin

mysql> show variables like'log_bin';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| log_bin | OFF |

+---------------+-------+

2.开启log_bin

在my.ini中添加配置:

log_bin=D:/mysql/bin-log.log

3.重启mysql,再次查看

mysql> show variables like'log_bin';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| log_bin | ON |

+---------------+-------+

4.查看Binlog

4.1显示binlog的名称和大小

mysql> show binary logs;

+----------------+-----------+

| Log_name | File_size |

+----------------+-----------+

| bin-log.000001 | 107 |

+----------------+-----------+

4.2查看生成的binlog

想用查看到binlog可以往数据库中更新数据库(包括:插入,更新和删除操作),查询sql是无法生成binlog的

mysql> show binlog events;

+----------------+------+-------------+-----------+-------------+---------------

------------------------------------------------+

| Log_name | Pos | Event_type | Server_id | End_log_pos | Info

|

+----------------+------+-------------+-----------+-------------+---------------

------------------------------------------------+

| bin-log.000001 | 4 | Format_desc | 1 | 107 | Server ver: 5.

5.29-log,Binlog ver: 4 |

| bin-log.000001 | 107 | Query | 1 | 175 | BEGIN

|

| bin-log.000001 | 175 | Intvar | 1 | 203 | INSERT_ID=9

|

| bin-log.000001 | 203 | Query | 1 | 315 | use`test`;in

sert into user(age,name)values(100,"zhaohui") |

| bin-log.000001 | 315 | Xid | 1 | 342 | COMMIT/* xid=

41 */ |

+----------------+------+-------------+-----------+-------------+---------------

------------------------------------------------+

Binlog相关参数

通过执行如下命令可以获得关于Binlog 的相关参数:

1.binlog_cache_size

在事务过程中容纳binlog SQL语句的缓存大小;binlog缓存是服务器支持事务存储引擎并且服务器启用了二进制日志(—log-bin选项)的前提下为每个Session分配的内存;

主要是用来提高binlog的写速度;可以通过MySQL的以下个状态变量来判断当前的binlog_cache_size的状况:Binlog_cache_use和Binlog_cache_disk_use

Binlog_cache_use:使用缓冲区存放binlog的次数

Binlog_cache_disk_use:使用临时文件存放binlog的次数

2.binlog_stmt_cache_size

发生事务时非事务语句的缓存的大小,可以通过MySQL 的以下个状态变量来判断当前的binlog_stmt_cache_size的状况:Binlog_stmt_cache_use和Binlog_stmt_cache_disk_use

Binlog_stmt_cache_use:缓冲区存放binlog的次数

Binlog_stmt_cache_disk_use:临时文件存放binlog的次数

3.max_binlog_cache_size

和binlog_cache_size相对应,但是所代表的是binlog能够使用的最大cache内存大小;binlog_cache_size对应的每个Session,max_binlog_cache_size对应所有Session;

当我们执行多语句事务的时候,所有Session的使用的内存超过max_binlog_cache_size的值时,系统可能会报出”Multi-statement transaction required more than ‘max_binlog_cache_size’ bytes of storage”的错误。

4.max_binlog_stmt_cache_size

同max_binlog_cache_size类似,非事务语句binlog能够使用的最大cache内存大小。

5.max_binlog_size

Binlog日志最大值,默认1G,。该大小并不能非常严格控制Binlog大小,尤其是当到达Binlog比较靠近尾部而又遇到一个较大事务的时候,系统为了保证事务的完整性,不可能做切换日志的动作,只能将该事务的所有SQL都记录进入当前日志,直到该事务结束。

6.sync_binlog

同步binlog缓存中数据到磁盘的方式:

sync_binlog=0

当事务提交之后,MySQL不做fsync之类的磁盘同步指令刷新binlog_cache中的信息到磁盘,而让Filesystem自行决定什么时候来做同步,或者cache满了之后才同步到磁盘;

sync_binlog=n(区间0-4294967295)

当每进行n次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘;

系统默认设置为0,这种情况下性能最好,风险最大,可能导致binlog_cache中的数据丢失;sync_binlog=1性能最差,风险最小。

7.binlog_format

设置binlog的格式,可选值:STATEMENT, ROW, or MIXED;默认是:STATEMENT

7.1 ROW模式

日志中记录成每一行数据被修改的形式,然后在slave端再对相同的数据进行修改;

在ROW模式下bin-log中可以不记录执行的SQL语句的上下文相关的信息,只需要记录哪条数据被修改成什么样了,不会因为某些语法复制出现问题(比如function,trigger等);

缺点是每行数据的修改都会记录,最明显的就是update语句,导致更新多少条数据就会产生多少事件,使bin-log文件很大,而复制要网络传输,影响性能。

7.2 STATEMENT模式

每一条修改数据的sql都会被记录到bin-log中,slave端再根据sql语句重现,解决了ROW模式的缺点,不会产生大量是bin-log数据;

缺点是为了让sql能在slave端正确重现,需要记录sql在执行的上下文信息,另外一个问题就是在复制某些特殊的函数或者功能的时候会出现问题,比如sleep()函数。

7.3 MIXED模式

前面两种模式的结合,根据不同的情况分别使用ROW模式和STATEMENT模式。

更多参数详见:https://dev.mysql.com/doc/refman/5.7/en/replication-options-binary-log.html

Binlog结构和内容

日志由一组二进制日志文件(Binlog),加上一个索引文件(index);Binlog是一个二进制文件集合,每个Binlog以一个4字节的魔数开头,接着是一组Events;

1.魔数:0xfe62696e对应的是0xfebin;

2.Event:每个Event包含header和data两个部分;header提供了Event的创建时间,哪个服务器等信息,data部分提供的是针对该Event的具体信息,如具体数据的修改;

3.第一个Event用于描述binlog文件的格式版本,这个格式就是event写入binlog文件的格式;

4.其余的Event按照第一个Event的格式版本写入;

5.最后一个Event用于说明下一个binlog文件;

6.Binlog的索引文件是一个文本文件,其中内容为当前的binlog文件列表,比如:

D:\mysql\bin-log.000001

参考:https://dev.mysql.com/doc/internals/en/binary-log-structure-and-contents.html

Binlog的Event类型

官方提供的可能Event类型有36种,具体看下面的枚举:

enumLog_event_type{

UNKNOWN_EVENT= 0,

START_EVENT_V3= 1,

QUERY_EVENT= 2,

STOP_EVENT= 3,

ROTATE_EVENT= 4,

INTVAR_EVENT= 5,

LOAD_EVENT= 6,

SLAVE_EVENT= 7,

CREATE_FILE_EVENT= 8,

APPEND_BLOCK_EVENT= 9,

EXEC_LOAD_EVENT= 10,

DELETE_FILE_EVENT= 11,

NEW_LOAD_EVENT= 12,

RAND_EVENT= 13,

USER_VAR_EVENT= 14,

FORMAT_DESCRIPTION_EVENT= 15,

XID_EVENT= 16,

BEGIN_LOAD_QUERY_EVENT= 17,

EXECUTE_LOAD_QUERY_EVENT= 18,

TABLE_MAP_EVENT = 19,

PRE_GA_WRITE_ROWS_EVENT = 20,

PRE_GA_UPDATE_ROWS_EVENT = 21,

PRE_GA_DELETE_ROWS_EVENT = 22,

WRITE_ROWS_EVENT = 23,

UPDATE_ROWS_EVENT = 24,

DELETE_ROWS_EVENT = 25,

INCIDENT_EVENT= 26,

HEARTBEAT_LOG_EVENT= 27,

IGNORABLE_LOG_EVENT= 28,

ROWS_QUERY_LOG_EVENT= 29,

WRITE_ROWS_EVENT = 30,

UPDATE_ROWS_EVENT = 31,

DELETE_ROWS_EVENT = 32,

GTID_LOG_EVENT= 33,

ANONYMOUS_GTID_LOG_EVENT= 34,

PREVIOUS_GTIDS_LOG_EVENT= 35,

ENUM_END_EVENT

/* end marker */

};

参考:https://dev.mysql.com/doc/internals/en/event-classes-and-types.html

Event结构官网提供了3个版本,分别是v1,v3,v4:

v1:用在MySQL 3.23

v3:用在MySQL 4.0.2-4.1

v4:用在MySQL 5.0之后

现在MySQL的版本基本都使用5.0之后的版本,可以直接看v4,具体如下:

名字后面的两个数字表示:offset : length即从第几个字节开始,后面多少个字节用来存放数据

比如:timestamp(0 : 4)表示从第0个字节开始,往后四个字节用来存放timestamp

目前来说x=19,所有extra_headers是空的,y是fixed part的长度,不同的Event长度不一样。

参考:https://dev.mysql.com/doc/internals/en/event-structure.html

Event简要分析

1.从一个最简单的实例来分析其中的Event,包括创建表,插入数据,更新数据,删除数据;binlog_format使用的是默认的STATEMENT;

CREATE TABLE`btest`(

`id`bigint(20)NOTNULLAUTO_INCREMENT,

`age`int(11)DEFAULTNULL,

`name`varchar(255)DEFAULTNULL,

PRIMARY KEY(`id`)

)ENGINE=InnoDB DEFAULTCHARSET=utf8

insert into btest values(1,100,'zhaohui');

update btest set name='zhaohui_new'where id=1;

delete from btest where id=1;

2.查看所有的Events

show binlog events;

上图中一共出现了3中类型的Event,分别是Format_desc,Query和Xid,下面进行简单的分析

2.1Format_desc_Event

官网格式如下:

使用十六进制方式打开文件bin-log.000001,以下是Format_desc_Event的十六进制代码:

可以先看前面的4+103=107个字节,4字节是binlog的魔数,103字节是Format_desc_Event,其中有19字节是header;

注:Binlog日志是小端字节顺序

0x5A0504AA四个字节是timestamp;0x0F一个字节表示type_code;0x00000001四个字节为server_id;0x00000067四个字节是event_length,对应的十进制就是103;

0x0000006b四个字节是next_position,即下一个Event的开始位置为107;ox0001两个字节是flags;header总计19字节。

data总字节数=103-19即84字节,排除掉前面的57个字节,剩余27字节表示post-header lengths for all event types;

post-header lengths:从START_EVENT_V3开始到第27个Event,每个Event的fixed part lengths;

Format_desc_Event位置是15,可以在图中找到15的位置是0x54,对应十进制是84,即fixed part lengths=84,而这个值刚好是57+27=84,所以Format_desc_Event不存在variable part;

参考:https://dev.mysql.com/doc/internals/en/binary-log-versions.html

2.2Query_Event

以下的create table产生的Query_Event的十六进制代码:

header共19字节,0x02一个字节表示type_code(Query_Event=2);0x00000101四个字节是event_length,对应的十进制就是257(pos=107,End_log_pos=364);

Query_Event在post-header的第二个位置0x0d,所有fix part lengths=13;

variable part=257-19-13=225字节

具体fix data和variable data:

在创建表产生一个Query_Event,insert、update以及delete执行之后分别产生了2个Query_Event和一个Xid_Event。

更多详细:https://dev.mysql.com/doc/internals/en/event-data-for-specific-event-types.html

2.3Xid_Event

以下的更新数据产生的Xid_Event的十六进制代码:

header共19字节,0x10一个字节表示type_code(XID_EVENT=16);0x0000001b四个字节是event_length,对应的十进制就是27(pos=536,End_log_pos=563);

2Xid_Event在post-header的第十六个位置0x00,所有fix part lengths=0;

variable part=27-19=8字节

8字节:The XID transaction number。

insert、update以及delete执行之后分别产生了Xid_Event,事务提交产生的事件。

更多详细:https://dev.mysql.com/doc/internals/en/event-data-for-specific-event-types.html

总结

本文主要对Mysql Binlog做了一个大体的介绍,包括:Binlog的参数,格式以及最重要的事件;事件数量比较多,从最简单的增删改查入手,介绍了几个比较常见的事件;

后续会继续学习其他事件,对Binlog有更加详细的了解。

相关推荐

悠悠万事,吃饭为大(悠悠万事吃饭为大,什么意思)

新媒体编辑:杜岷赵蕾初审:程秀娟审核:汤小俊审签:周星...

高铁扒门事件升级版!婚宴上‘冲喜’老人团:我们抢的是社会资源

凌晨两点改方案时,突然收到婚庆团队发来的视频——胶东某酒店宴会厅,三个穿大红棉袄的中年妇女跟敢死队似的往前冲,眼瞅着就要扑到新娘的高额钻石项链上。要不是门口小伙及时阻拦,这婚礼造型团队熬了三个月的方案...

微服务架构实战:商家管理后台与sso设计,SSO客户端设计

SSO客户端设计下面通过模块merchant-security对SSO客户端安全认证部分的实现进行封装,以便各个接入SSO的客户端应用进行引用。安全认证的项目管理配置SSO客户端安全认证的项目管理使...

还在为 Spring Boot 配置类加载机制困惑?一文为你彻底解惑

在当今微服务架构盛行、项目复杂度不断攀升的开发环境下,SpringBoot作为Java后端开发的主流框架,无疑是我们手中的得力武器。然而,当我们在享受其自动配置带来的便捷时,是否曾被配置类加载...

Seata源码—6.Seata AT模式的数据源代理二

大纲1.Seata的Resource资源接口源码2.Seata数据源连接池代理的实现源码3.Client向Server发起注册RM的源码4.Client向Server注册RM时的交互源码5.数据源连接...

30分钟了解K8S(30分钟了解微积分)

微服务演进方向o面向分布式设计(Distribution):容器、微服务、API驱动的开发;o面向配置设计(Configuration):一个镜像,多个环境配置;o面向韧性设计(Resista...

SpringBoot条件化配置(@Conditional)全面解析与实战指南

一、条件化配置基础概念1.1什么是条件化配置条件化配置是Spring框架提供的一种基于特定条件来决定是否注册Bean或加载配置的机制。在SpringBoot中,这一机制通过@Conditional...

一招解决所有依赖冲突(克服依赖)

背景介绍最近遇到了这样一个问题,我们有一个jar包common-tool,作为基础工具包,被各个项目在引用。突然某一天发现日志很多报错。一看是NoSuchMethodError,意思是Dis...

你读过Mybatis的源码?说说它用到了几种设计模式

学习设计模式时,很多人都有类似的困扰——明明概念背得滚瓜烂熟,一到写代码就完全想不起来怎么用。就像学了一堆游泳技巧,却从没下过水实践,很难真正掌握。其实理解一个知识点,就像看立体模型,单角度观察总...

golang对接阿里云私有Bucket上传图片、授权访问图片

1、为什么要设置私有bucket公共读写:互联网上任何用户都可以对该Bucket内的文件进行访问,并且向该Bucket写入数据。这有可能造成您数据的外泄以及费用激增,若被人恶意写入违法信息还可...

spring中的资源的加载(spring加载原理)

最近在网上看到有人问@ContextConfiguration("classpath:/bean.xml")中除了classpath这种还有其他的写法么,看他的意思是想从本地文件...

Android资源使用(android资源文件)

Android资源管理机制在Android的开发中,需要使用到各式各样的资源,这些资源往往是一些静态资源,比如位图,颜色,布局定义,用户界面使用到的字符串,动画等。这些资源统统放在项目的res/独立子...

如何深度理解mybatis?(如何深度理解康乐服务质量管理的5个维度)

深度自定义mybatis回顾mybatis的操作的核心步骤编写核心类SqlSessionFacotryBuild进行解析配置文件深度分析解析SqlSessionFacotryBuild干的核心工作编写...

@Autowired与@Resource原理知识点详解

springIOCAOP的不多做赘述了,说下IOC:SpringIOC解决的是对象管理和对象依赖的问题,IOC容器可以理解为一个对象工厂,我们都把该对象交给工厂,工厂管理这些对象的创建以及依赖关系...

java的redis连接工具篇(java redis client)

在Java里,有不少用于连接Redis的工具,下面为你介绍一些主流的工具及其特点:JedisJedis是Redis官方推荐的Java连接工具,它提供了全面的Redis命令支持,且...