5.4.4 二进制日志

二进制日志包含描述数据库更改(例如 table 创建操作或 table 数据更改)的“事件”。它还包含针对可能进行了更改的语句的事件(例如,没有行匹配的DELETE),除非使用基于行的日志记录。二进制日志还包含有关每个语句花费该更新数据多长时间的信息。二进制日志有两个重要目的:

  • 对于复制,复制源服务器上的二进制日志提供了要发送到副本的数据更改的记录。源将其二进制日志中包含的事件发送到其副本,副本将执行这些事件以对源进行相同的数据更改。参见第 16.2 节“复制实现”

  • 某些数据恢复操作需要使用二进制日志。还原备份后,将重新执行在执行备份后记录的二进制日志中的事件。这些事件使数据库从备份开始就保持最新状态。参见第 7.5 节“时间点(增量)恢复”

二进制日志不用于诸如SELECTSHOW之类的不修改数据的语句。要记录所有语句(例如,确定问题查询),请使用常规查询日志。参见第 5.4.3 节“常规查询日志”

运行启用了二进制日志记录的服务器会使性能稍微降低。但是,二进制日志在使您能够设置复制和进行还原操作方面的好处通常超过了这种较小的性能下降。

二进制日志通常可以抵御意外的暂停,因为仅记录或读取完整的事务。有关更多信息,请参见第 16.3.2 节“处理副本意外停止”

服务器将重写写在二进制日志中的语句中的密码,以使它们不会 true 以纯文本形式出现。另请参见第 6.1.2.3 节“密码和日志记录”

以下讨论描述了一些影响二进制日志记录操作的服务器选项和变量。有关完整列 table,请参见第 16.1.6.4 节“二进制日志记录选项和变量”

要启用二进制日志,请使用--log-bin[=base_name]选项启动服务器。如果没有给出* base_name *值,则默认名称是--pid-file选项的值(默认情况下是主机名),后跟-bin。如果指定了基本名称,则服务器将文件写入数据目录中,除非使用基本开头的绝对路径名指定基本名称,以指定其他目录。建议您显式指定基本名称,而不要使用主机名的默认名称。参见第 B.4.7 节“ MySQL 中的已知问题”,原因。

如果您在日志名称中提供 extensions(例如--log-bin=base_name.extension),则该 extensions 将被静默删除并忽略。

mysqld在二进制日志基本名称后附加数字 extensions 以生成二进制日志文件名。每次服务器创建新的日志文件时,该数目都会增加,从而创建了有序的文件系列。每次发生以下任何事件,服务器都会在系列中创建一个新文件:

  • 服务器已启动或重新启动

  • 服务器刷新日志。

  • 当前日志文件的大小达到max_binlog_size

如果您使用的是大型事务,则二进制日志文件可能会大于max_binlog_size,这是因为将事务以一件的形式写入文件中,切勿在文件之间分割。

为了跟踪使用了哪些二进制日志文件,mysqld还创建了一个二进制日志索引文件,其中包含二进制日志文件的名称。默认情况下,该名称与二进制日志文件具有相同的基本名称,extensions 为'.index'。您可以使用--log-bin-index[=file_name]选项更改二进制日志索引文件的名称。 mysqld运行时,您不应该手动编辑此文件。这样做会混淆mysqld

术语“二进制日志文件”通常 table 示包含数据库事件的单独编号文件。术语“二进制日志”统称为带编号的二进制日志文件加上索引文件的集合。

具有足以设置受限制的会话系统变量(请参见第 5.1.8.1 节“系统变量特权”)的特权的 Client 端可以使用SET sql_log_bin=OFF语句来禁用其自身语句的二进制记录。

默认情况下,服务器记录事件的长度以及事件本身,并使用它来验证事件是否被正确写入。您还可以通过设置binlog_checksum系统变量来使服务器编写事件的校验和。从二进制日志中读回时,默认情况下,源使用事件长度,但可以通过启用master_verify_checksum系统变量使源使用校验和。复制 I/O 线程还将验证从源接收到的事件。通过启用slave_sql_verify_checksum系统变量,可以在从中继日志中读取时使复制 SQL 线程使用校验和(如果可用)。

二进制日志中记录的事件的格式取决于二进制日志格式。支持三种格式类型:基于行的日志,基于语句的日志和基于混合的日志。使用的二进制日志记录格式取决于 MySQL 版本。有关日志记录格式的一般说明,请参见第 5.4.4.1 节“二进制日志记录格式”。有关二进制日志格式的详细信息,请参见MySQL 内部:二进制日志

服务器以与--replicate-do-db--replicate-ignore-db选项相同的方式评估--binlog-do-db--binlog-ignore-db选项。有关如何完成此操作的信息,请参见第 16.2.5.1 节“数据库级复制和二进制日志记录选项的评估”

默认情况下,副本不会将从源接收到的任何数据修 Rewrite 入其自己的二进制日志中。要记录这些修改,除了--log-bin选项(请参阅第 16.1.6.3 节“ Replica 服务器选项和变量”)之外,还使用--log-slave-updates选项启动副本。当副本还充当链接复制中其他副本的源时,就可以完成此操作。

您可以使用RESET MASTER语句删除所有二进制日志文件,或者使用清除二进制日志删除它们的一部分。参见第 13.7.6.6 节“ RESET 语句”第 13.4.1.1 节“ PURGE BINARY LOGS 语句”

如果使用复制,则在确定没有副本仍需要使用它们之前,不应删除源上的旧二进制日志文件。例如,如果您的副本从未运行超过三天,则可以每天一次在源上执行mysqladmin flush-logs,然后删除任何已存在三天以上的日志。您可以手动删除文件,但是最好使用清除二进制日志,它也可以安全地为您更新二进制日志索引文件(并且可以使用 date 参数)。参见第 13.4.1.1 节“ PURGE BINARY LOGS 语句”

您可以使用mysqlbinlogUtil 显示二进制日志文件的内容。当您要重新处理日志中的语句以进行恢复操作时,此功能很有用。例如,您可以从二进制日志中更新 MySQL 服务器,如下所示:

shell> mysqlbinlog log_file | mysql -h server_name

mysqlbinlog也可以用于显示中继日志文件的内容,因为它们的写入格式与二进制日志文件的格式相同。有关mysqlbinlogUtil 及其使用方式的更多信息,请参见第 4.6.7 节“ mysqlbinlog-处理二进制日志文件的 Util”。有关二进制日志和恢复操作的更多信息,请参见第 7.5 节“时间点(增量)恢复”

在语句或事务完成之后但在释放任何锁或完成任何提交之前,立即执行二进制日志记录。这样可以确保日志以提交 Sequences 记录。

非事务 table 的更新在执行后立即存储在二进制日志中。

在未提交的事务中,更改事务 table(例如InnoDBtable)的所有更新(UPDATEDELETEINSERT)都会被缓存,直到服务器收到COMMIT语句。那时,mysqld在执行COMMIT之前将整个事务写入二进制日志。

对非事务 table 的修改不能回滚。如果回滚的事务包括对非事务 table 的修改,则整个事务的末尾将使用ROLLBACK语句记录下来,以确保复制对这些 table 的修改。

当处理事务的线程启动时,它将为缓冲区语句分配binlog_cache_size的缓冲区。如果语句大于此值,则线程将打开一个临时文件来存储事务。当线程结束时,将删除临时文件。

Binlog_cache_use状态变量显示使用此缓冲区(可能还有一个临时文件)存储语句的事务数。状态Binlog_cache_disk_use状态变量显示实际上有多少个事务必须使用临时文件。这两个变量可用于将binlog_cache_size调整为足够大的值,从而避免使用临时文件。

max_binlog_cache_size系统变量(默认为 4GB,也是最大值)可用于限制用于缓存多语句事务的总大小。如果事务大于此多个字节,它将失败并回滚。最小值是 4096.

如果使用二进制日志和基于行的日志记录,则并发插入将转换为CREATE ... SELECT插入...选择语句的普通插入。这样做是为了确保您可以通过在备份操作期间应用日志来重新创建 table 的精确副本。如果使用的是基于语句的日志记录,则原始语句将写入日志。

二进制日志格式具有一些已知的限制,可能会影响从备份的恢复。参见第 16.4.1 节“复制功能和问题”

第 23.7 节“存储的程序二进制日志”中所述完成存储程序的二进制日志记录。

请注意,由于复制功能的增强,MySQL 5.7 中的二进制日志格式与以前的 MySQL 版本不同。参见第 16.4.2 节“ MySQL 版本之间的复制兼容性”

如果服务器无法写入二进制日志,刷新二进制日志文件或将二进制日志同步到磁盘,则源上的二进制日志可能会变得不一致,并且副本可能会与源失去同步。 binlog_error_action系统变量控制在二进制日志中遇到此类错误时采取的措施。

  • 默认设置ABORT_SERVER使服务器停止二进制日志记录并关闭。此时,您可以确定并纠正错误原因。重新启动后,恢复将 continue 进行,就像服务器意外停止一样(请参见第 16.3.2 节“处理副本意外停止”)。

  • 设置IGNORE_ERROR提供与旧版 MySQL 的向后兼容性。使用此设置,服务器将 continue 进行中的事务并记录错误,然后停止二进制日志记录,但 continue 执行更新。此时,您可以确定并纠正错误原因。要恢复二进制日志记录,必须再次启用log_bin,这需要重新启动服务器。仅在需要向后兼容性且二进制日志在此 MySQL 服务器实例上为非必需时才使用此选项。例如,您可能只将二进制日志用于服务器的间歇审核或调试,而不将其用于从服务器复制或将其用于时间点还原操作。

默认情况下,二进制日志在每次写入(sync_binlog=1)时都会同步到磁盘。如果未启用sync_binlog,并且 os 或计算机(不仅是 MySQL 服务器)崩溃,则二进制日志的最后一条语句可能会丢失。为防止这种情况,请在每个N *提交组之后,启用sync_binlog系统变量以将二进制日志同步到磁盘。参见第 5.1.7 节“服务器系统变量”sync_binlog的最安全值为 1(默认值),但这也是最慢的。

例如,如果您使用InnoDBtable,并且 MySQL 服务器处理COMMIT语句,它将按 Sequences 将许多准备好的事务写入二进制日志,同步二进制日志,然后将此事务提交到InnoDB中。如果服务器在这两个操作之间崩溃,则事务将在重新启动时由InnoDB回滚,但仍存在于二进制日志中。假设--innodb_support_xa设置为默认值 1,则可以解决此问题。尽管此选项与InnoDB中对 XA 事务的支持有关,但它还可以确保二进制日志和 InnoDB 数据文件同步。为了使此选项提供更高的安全性,还应将 MySQL 服务器配置为在提交事务之前将二进制日志和InnoDB日志同步到磁盘。 InnoDB日志默认情况下是同步的,而sync_binlog=1可用于同步二进制日志。此选项的作用是,崩溃后重新启动时,在回滚事务之后,MySQL 服务器将扫描最新的二进制日志文件以收集事务* xid *值并计算二进制日志文件中的最后一个有效位置。然后,MySQL 服务器告诉InnoDB完成已成功写入二进制日志的所有准备好的事务,并将二进制日志截断到最后一个有效位置。这样可以确保二进制日志反映了InnoDBtable 的确切数据,因此该副本与源保持同步,因为它没有收到已回滚的语句。

Note

innodb_support_xa已过时,将在以后的版本中删除。自 MySQL 5.7.10 起,始终启用对 XA 事务中的两阶段提交的InnoDB支持。

如果 MySQL 服务器在崩溃恢复时发现二进制日志短于其应有的时间,则它至少缺少一个成功提交的InnoDB事务。如果sync_binlog=1和磁盘/文件系统在请求时进行实际同步(某些情况下不这样做),则应该不会发生这种情况,因此服务器将输出一条错误消息The binary log file_name is shorter than its expected size。在这种情况下,此二进制日志不正确,应从源数据的新快照重新开始复制。

以下系统变量的会话值将写入二进制日志,并在解析二进制日志时由副本服务器遵循: