binlog

305 阅读8分钟

什么是binlog

  1. binlog是记录所有数据库表结构变更(例如CREATE、ALTER TABLE…)以及表数据修改(INSERT、UPDATE、DELETE…)的二进制日志
  2. binlog不会记录SELECT和SHOW这类操作,因为这类操作对数据本身并没有修改,但你可以通过查询通用日志来查看MySQL执行过的所有语句。

binlog作用

因为Binlog日志主要就是记录数据库表结构变更和数据修改的,所以主要有两个用途:\ (1)数据库表备份\ (2)数据库主从复制

binlog相关参数

参数详解
log_bin设置此参数表示启用binlog功能,并指定路径名称
log_bin_index设置此参数是指定二进制索引文件的路径与名称
binlog_do_db此参数表示只记录指定数据库的二进制日志
binlog_ignore_db此参数表示不记录指定的数据库的二进制日志
max_binlog_cache_size此参数表示binlog使用的内存最大的尺寸
binlog_cache_size此参数表示binlog使用的内存大小,可以通过状态变量binlog_cache_use和binlog_cache_disk_use来帮助测试。
binlog_cache_use使用二进制日志缓存的事务数量
binlog_cache_disk_use使用二进制日志缓存但超过binlog_cache_size值并使用临时文件来保存事务中的语句的事务数量
max_binlog_sizeBinlog最大值,最大和默认值是1GB,该设置并不能严格控制Binlog的大小,尤其是Binlog比较靠近最大值而又遇到一个比较大事务时,为了保证事务的完整性,不可能做切换日志的动作,只能将该事务的所有SQL都记录进当前日志,直到事务结束
sync_binlog这个参数直接影响mysql的性能和完整性。sync_binlog=0:当事务提交后,Mysql仅仅是将binlog_cache中的数据写入Binlog文件,但不执行fsync之类的磁盘 同步指令通知文件系统将缓存刷新到磁盘,而让Filesystem自行决定什么时候来做同步,这个是性能最好的。sync_binlog=n,在进行n次事务提交以后,Mysql将执行一次fsync之类的磁盘同步指令,同志文件系统将Binlog文件缓存刷新到磁盘。Mysql中默认的设置是sync_binlog=0,即不作任何强制性的磁盘刷新指令,这时性能是最好的,但风险也是最大的。一旦系统绷Crash,在文件系统缓存中的所有Binlog信息都会丢失

查看binglog

:::info

  1. 查看是否开启二进制日志

:::

SHOW VARIABLES LIKE 'log_bin';-- ON代表开启 OFF代表关闭

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

:::

show master status;

:::info 3. 在MySQL客户端中,执行以下命令以显示可用的二进制日志文件列表

:::

<font style="color:rgb(0, 119, 170);background-color:rgb(245, 242, 240);">SHOW BINARY</font><font style="color:rgb(0, 0, 0);background-color:rgb(245, 242, 240);"> LOGS</font><font style="color:rgb(153, 153, 153);background-color:rgb(245, 242, 240);">;</font>

显示所有未过期的二进制日志文件的名称和大小。

:::info 四、删除binlog文件

:::

mysql> reset master;reset master将会删除所有日志,并让日志文件重新从000001开始。

<font style="color:rgb(0, 0, 0);background-color:rgb(239, 239, 239);">purge master logs </font><font style="color:rgb(0, 0, 255);">to</font><font style="color:rgb(0, 0, 0);background-color:rgb(239, 239, 239);"> "binlog_name.00000X"</font>将会清空00000X之前的所有日志文件。例如删除000006之前的日志文件。

:::info 五、选择要查看的二进制日志文件,并使用以下命令查看该文件的详细内容:

:::

<font style="color:rgb(0, 119, 170);background-color:rgb(245, 242, 240);">SHOW</font><font style="color:rgb(0, 0, 0);background-color:rgb(245, 242, 240);"> BINLOG EVENTS </font><font style="color:rgb(154, 110, 58);">IN </font><font style="color:rgb(102, 153, 0);background-color:rgb(245, 242, 240);">'filename'</font><font style="color:rgb(153, 153, 153);background-color:rgb(245, 242, 240);">;</font>

将 'filename' 替换为要查看的二进制日志文件的名称。这将显示指定二进制日志文件中所有事件的详细信息,包括事件的时间戳、类型、位置等。

:::info 二进制日志文件查询结果列说明

:::

  • Log_name:二进制日志文件的名称。
  • Pos:该事件在二进制日志文件中的位置。
  • Event_type:事件的类型,如 Query、Table_map、Write_rows、Update_rows、Delete_rows等。
  • Server_id:生成该事件的服务器ID。
  • End_log_pos:事件结束时的位置。
  • Info:事件的附加信息,具体内容会根据事件类型而有所不同。

以下是一些常见事件类型的说明:

  • Query:记录执行的SQL语句。
  • Table_map:映射逻辑表和物理表之间的关系。
  • Write_rows:记录插入新行的事件。
  • Update_rows:记录更新现有行的事件。
  • Delete_rows:记录删除现有行的事件。
  • Format_desc:用来描述binlog文件的格式的事件

你可以根据这些字段来分析和理解二进制日志中的事件。例如,可以根据Event_type字段判断事件的类型,根据Log_name和Pos字段确定事件在二进制日志文件中的位置,根据Info字段查看事件的具体内容等。

:::info 六、mysqlbinlog 命令

:::

要想使用mysqlbinlog命令,不能直接在客户端使用,需要在mysqlbinlog所在的目录下执行

这里以Windows环境下mysql为例

来到bin目录下,通过cmd命令行进入

原因是mysql自带的 mysqlbinlog工具无法识别binlog配置中的default-character-set=utf8这个指令。

解决办法 一

修改mysql配置文件

将配置 <font style="color:rgb(77, 77, 77);">default-character-set=utf8mb4</font> 修改为 <font style="color:rgb(77, 77, 77);">character-set-server = utf8mb4</font>

注意:此操作需要重启MySQL服务 线上不建议操作

(Windows下亲测不好使)

解决办法二

更换打开的命令 使用如下命令打开

../bin/mysqlbinlog --no-defaults mysql-bin.000001

发现是乱码的,

解决方法mysqlbinlog --no-defaults --base64-output=decode-rows -v mysql-bin.000001

以下是常用的几个选项:

-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可以查看

binlog真正的大用处

记录格式

Mysql提供了三种记录Binlog的格式:基于语句的(statement-based logging),基于行的(row-based logging)和混合的(mixed logging)。可以通过binlog-format指定。

非确定性的语句

即同一条语句多次执行的结果不同,举个例子:UUID(),如果在某个修改操作的SQL中使用了这个语句,那么多次执行的效果是不同的。再例如:now(),每次执行时的当前时间都会发生变化。

statement格式(基于语句)

基于语句的方式会直接记录SQL语句,这种方式产生的Binlog少,占用磁盘空间和I/O也最少,缺点是无法用于非确定性的语句。

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.使用了临时表。

innodb作者推荐使用基于行的格式

详细解读binlog内容

SHOW BINLOG EVENTS IN 'binlog.000001'通过此命令查看binlog事件信息

:::info 清空下binglog文件,重新生成binlog

:::

  1. Format_desc:用来描述binlog文件的格式的事件。
  • "Server ver: 5.7.40-log":指明MySQL服务器的版本为5.7.40,并且带有"log"后缀,表示使用了日志版本
  • "Binlog ver: 4":指明binlog文件的版本是4。
  1. previous_gtids:GTID-全局事务ID。当MySQL启用了GTID复制功能时,每个binlog事件都会包含一个GTID信息,用于标识该事件所属的事务。previous_gtids字段表示在当前binlog事件之前已经提交的事务的GTID集合。

:::info 执行创表语句创建student表,再次查看binlog

:::

CREATE TABLE student (
  studentid INT NOT NULL PRIMARY KEY,
  NAME VARCHAR ( 30 ) NOT NULL,
  gender enum ( 'female', 'mail' )
);

Anonymous_Gtid:用于记录在从服务器上尚未成功复制的匿名事务的GTID信息。它帮助从服务器在后续的复制过程中追踪和处理这些未复制的事务。

Query:代表执行的SQL语句

:::info 执行修改列类型的语句alter table student change gender gender enum('female','male');

:::

:::info 执行插入语句 insert into student values(1,'malongshuai','male'),(2,'gaoxiaofang','female');

:::

并没有展示出具体执行的SQL语句,说明SHOW BINLOG EVENTS IN 'binlog.000001';显示了每个事件的一些摘要信息,并不能展示详细的binlog内容。如果想查看二进制日志文件的详细内容,还是得使用mysqlbinlog工具