什么是binlog
- binlog是记录所有数据库表结构变更(例如CREATE、ALTER TABLE…)以及表数据修改(INSERT、UPDATE、DELETE…)的二进制日志。
- 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_size | Binlog最大值,最大和默认值是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
- 查看是否开启二进制日志
:::
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
:::
- Format_desc:用来描述binlog文件的格式的事件。
- "Server ver: 5.7.40-log":指明MySQL服务器的版本为5.7.40,并且带有"log"后缀,表示使用了日志版本
- "Binlog ver: 4":指明binlog文件的版本是4。
- 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工具