Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


7.4.4 二进制日志

二进制日志中包含描述数据库变化的“事件”,例如表创建操作或表数据更改。它还包含可能会导致变化的语句(例如,一个DELETE 语句),除非使用行级别日志记录。二进制日志还包含每个语句更新数据所用的时间信息。二进制日志有两个重要作用:

  • 对于复制,源服务器的二进制日志提供了要发送到副本服务器的数据变化记录。源服务器将其二进制日志中的信息发送给副本服务器,副本服务器重新执行这些事务,以便在源服务器上进行相同的数据变化。见第19.2节,“复制实现”

  • 某些数据恢复操作需要使用二进制日志。在备份已经恢复后,二进制日志中记录的事件重新执行。这些事件将数据库更新到备份点。见第9.5节,“瞬时恢复(增量)”

二进制日志不用于修改数据的语句,如SELECTSHOW。要记录所有语句(例如,来标识问题查询),使用一般查询日志。见第7.4.3节,“一般查询日志”

启用二进制日志使服务器性能略微下降。然而,二进制日志在设置复制和恢复操作中的优点通常超过这个小的性能下降。

二进制日志对突然中断非常 resilient,只记录或读取完整事件或事务。

服务器将在二进制日志中写入的密码重写为不以明文形式出现。请参见第8.1.2.3节,“密码和日志记录”

MySQL 二进制日志文件和中继日志文件可以加密,帮助保护这些文件和其中包含的敏感数据免受外部攻击者和未经授权的操作系统用户查看。您可以通过将binlog_encryption系统变量设置为ON来启用加密。更多信息,请参见第19.3.2节,“加密二进制日志文件和中继日志文件”

以下讨论了服务器选项和变量,影响二进制日志操作的部分内容。完整列表,请参见第19.1.6.4节,“二进制日志选项和变量”

默认情况下,二进制日志记录是启用的(log_bin 系统变量设置为 ON)。唯一的例外是,如果您使用 mysqld 手动初始化数据目录,通过指定 --initialize--initialize-insecure 选项,二进制日志记录默认是禁用的,但可以通过指定 --log-bin 选项来启用。

要禁用二进制日志记录,可以在启动时指定 --skip-log-bin--disable-log-bin 选项。如果指定了这两个选项之一,并且同时指定 --log-bin,后指定的选项优先生效。

"--log-replica-updates" 和 "--replica-preserve-commit-order" 选项需要二进制日志记录。如果您禁用二进制日志记录,或者指定 "--log-replica-updates=OFF" 和 "--skip-replica-preserve-commit-order"。MySQL 在指定 "--skip-log-bin" 或 "--disable-log-bin" 时默认禁用这些选项。如果您同时指定 "--log-replica-updates" 和 "--replica-preserve-commit-order",或者 "--skip-log-bin" 或 "--disable-log-bin", 将发出警告或错误信息。

使用--log-bin[=base_name]选项指定二进制日志文件的基础名称。如果不提供--log-bin选项,MySQL将使用binlog作为默认的基础名称。为了与早期版本保持兼容,如果您提供了空字符串或无字符串的--log-bin选项,基础名称将默认为host_name-bin,使用主机名。建议指定基础名称,以便如果主机名发生变化,您可以轻松地继续使用相同的二进制日志文件名称(见第B.3.7节,“MySQL中的已知问题”)。如果您在log name中提供了扩展名(例如--log-bin=base_name.extension),扩展名将被忽略。

mysqld将数字扩展追加到二进制日志基础名称中,生成二进制日志文件名称。每次服务器创建新日志文件时,该数字都会增加,从而创建一个有序的文件系列。服务器在以下事件发生时创建新的文件:

  • 服务器启动或重启

  • 服务器刷新日志

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

二进制日志文件可能会因为使用大事务而超过max_binlog_size,因为事务一次写入到文件中,永不分割。

为了跟踪已经使用的二进制日志文件,mysqld还创建了一个二进制日志索引文件,该文件包含二进制日志文件的名称。默认情况下,这个索引文件的名称与二进制日志文件相同,后缀名为'.index'。你可以使用--log-bin-index[=file_name]选项来更改索引文件的名称。不要在mysqld运行时手动编辑这个文件;这样做将会混淆mysqld

术语““二进制日志文件”通常指的是单个带有编号的文件,包含数据库事件。术语““二进制日志”collectively 指的是编号二进制日志文件集和索引文件。

默认的二进制日志文件和二进制日志索引文件位置是数据目录。您可以使用--log-bin选项指定一个不同的目录,通过在基本名称前添加绝对路径名来指定。服务器读取二进制日志索引文件时,它检查该条目是否包含相对路径。如果是,则将相对部分的路径替换为使用--log-bin选项设置的绝对路径。二进制日志文件基本名称和指定的路径可作为系统变量log_bin_basename访问。

服务器可以使用默认的服务器ID启动二进制日志,但如果不显式指定服务器ID使用server_id系统变量,会发出信息性消息。对于在复制拓扑结构中使用的服务器,您必须为每个服务器指定唯一的非零服务器ID。

拥有足够权限设置受限会话系统变量(见第7.1.9.1节,“系统变量权限”)的客户端可以使用SET sql_log_bin=OFF语句来禁用自己的语句二进制日志。

默认情况下,服务器同时记录事件的长度和事件本身,并使用该信息验证事件是否正确。您也可以通过设置binlog_checksum系统变量,使服务器写入事件的校验和。从二进制日志读取时,源服务器默认使用事件长度,但可以使用可用校验和,如果启用source_verify_checksum。副本中的复制I/O线程也会验证来自源服务器的事件。您可以使复制SQL线程在读取从relay日志时使用可用校验和,启用replica_sql_verify_checksum

二进制日志中记录事件的格式取决于二进制日志格式。支持三种格式类型:行基于日志、语句基于日志和混合基于日志。使用的二进制日志格式取决于MySQL版本。关于日志格式的描述,见第7.4.4.1节,“二进制日志格式”

服务器对--binlog-do-db--binlog-ignore-db选项的评估方式与对--replicate-do-db--replicate-ignore-db选项相同。关于如何进行评估的信息,请参见第19.2.5.1节,“数据库级别复制和二进制日志选项”

副本默认情况下启用log_replica_updates第19.1.6.3节,“副本服务器选项和变量”)。该设置使副本可以作为其他副本的源服务器。

您可以使用RESET BINARY LOGS AND GTIDS语句删除所有二进制日志文件,也可以使用PURGE BINARY LOGS语句删除其中的一部分。请参阅第15.7.8.6节,“ RESET 语句”,和第15.4.1.1节,“ PURGE BINARY LOGS 语句”

如果您使用 MySQL 复制,您不应该在源服务器上删除老的二进制日志文件,直到您确定没有任何副本仍然需要它们。例如,如果您的副本从不超过三天落后一次,可以每天在源服务器上执行mysqladmin flush-logs binary,然后删除超过三天的日志文件。您可以手动删除文件,但是使用PURGE BINARY LOGS更好,因为它也会安全地更新二进制日志索引文件(并且可以带日期参数)。请参阅第15.4.1.1节,“ PURGE BINARY LOGS 语句”

您可以使用mysqlbinlog实用工具来显示二进制日志文件的内容。例如,您可以使用该工具将MySQL服务器更新到最新状态。例如,可以按照以下方式更新MySQL服务器:

$> mysqlbinlog log_file | mysql -h server_name

mysqlbinlog也可以用来显示复制服务器上的relay日志文件,因为它们使用相同的格式写入。关于mysqlbinlog实用工具和如何使用它,见第6.6.9节,“mysqlbinlog — Utility for Processing Binary Log Files”。关于二进制日志和恢复操作,见第9.5节,“点时恢复(增量)”

二进制日志在语句或事务完成后立即执行,但是在释放锁之前或提交事务之前。这样确保了日志以提交顺序写入。

非事务表的更新结果在执行完毕后立即存储到二进制日志中。

在未提交事务中,所有更新(UPDATEDELETEINSERT)都缓存在事务表中,例如InnoDB 表,直到服务器接收COMMIT 语句时,mysqld 将整个事务写入二进制日志,然后执行COMMIT

非事务表的修改不能回滚。如果一个事务回滚包括了非事务表的修改,那么整个事务在最后使用ROLLBACK 语句来确保这些表的修改被复制。

当一个处理事务的线程启动时,它分配了binlog_cache_size 缓冲区来缓存语句。如果语句大于这个缓冲区,线程就打开一个临时文件来存储事务。临时文件在线程结束时删除。如果服务器上启用了二进制日志加密,那么临时文件也会被加密。

"Binlog_cache_use" 状态变量显示了使用这个缓冲区(可能是临时文件)的事务数量。"Binlog_cache_disk_use" 状态变量显示了那些事务实际使用了临时文件的数量。这两个变量可以用于调整 "binlog_cache_size" 到足够大的值,以避免使用临时文件。

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

如果您使用二进制日志和行基于日志,CREATE ... SELECTINSERT ... SELECT 语句的并发插入将被转换为正常插入,以确保在备份操作中可以重新创建表的精确副本。如果您使用语句基于日志,原始语句将写入到日志。

二进制日志格式有一些已知的限制,可以影响从备份恢复。见第19.5.1节,“Replication Features and Issues”

存储程序的二进制日志记录按照第27.7节,“存储程序二进制日志”中描述。

注意,MySQL 8.4 中的二进制日志格式与之前的 MySQL 版本不同,因为是由于复制功能的增强。见第19.5.2节,“MySQL 版本之间的复制兼容性”

如果服务器无法写入二进制日志、刷新二进制日志文件或将二进制日志同步到磁盘,源服务器上的二进制日志可能会变得不一致,副本也可能会与源失去同步。控制遇到这种错误时的操作的是binlog_error_action系统变量。

  • 默认设置为 ABORT_SERVER,使服务器停止二进制日志记录并关闭。到这个点,你可以识别和修复错误的原因。在重启时,恢复过程与意外服务器关闭的情况相同(见第19.4.2节,“副本意外中断处理”)。

  • 设置IGNORE_ERROR提供了与老版本MySQL的向后兼容性。使用这个设置,服务器将继续进行事务,并记录错误,然后停止二进制日志,但继续执行更新。在这个点上,您可以识别并纠正错误。要恢复二进制日志,需要重新启用log_bin,这需要服务器重启。只有在您需要向后兼容且二进制日志对这个MySQL实例非必要时才使用该选项。例如,您可能只用于间歇性 auditing 或调试服务器,而不用于从服务器复制或依赖于它进行点时间恢复操作。

默认情况下,二进制日志在每次写入时同步到磁盘(sync_binlog=1)。如果sync_binlog未启用,并且操作系统或机器(不仅是MySQL服务器)崩溃,可能会丢失二进制日志的最后语句。为了防止这个问题,启用sync_binlog系统变量,使其在每个N事务组同步到磁盘。见第7.1.8节,“服务器系统变量”sync_binlog的安全值是1(默认),但这也是最慢的。

在早期MySQL版本中,如果发生崩溃,表内容和二进制日志内容可能不一致,即使设置了sync_binlog为1。例如,如果使用InnoDB表并且MySQL服务器处理COMMIT语句,它将顺序写入许多预准备事务到二进制日志,同步二进制日志,然后将事务提交到InnoDB。如果服务器在这两个操作之间意外退出,事务将在重启时由InnoDB回滚,但仍然存在于二进制日志中。这种问题在之前的版本中通过启用XA事务中的两阶段提交来解决。在MySQL 8.4中,InnoDB总是启用了XA事务中的两阶段提交。

InnoDB 对XA事务的两阶段提交支持确保了二进制日志和 InnoDB 数据文件同步。然而,MySQL 服务器也应该在提交事务前将二进制日志和 InnoDB 日志同步到磁盘。InnoDB 日志默认是同步的,sync_binlog=1 确保了二进制日志同步。两阶段提交在XA事务中的 InnoDB 支持和 sync_binlog=1 的效果是,在崩溃后重启,MySQL 服务器会扫描最新的二进制日志文件,收集事务 xid 值,并计算最后一个有效位置。然后,MySQL 服务器告诉 InnoDB 完成已经成功写入到二进制日志的预备事务,并截断二进制日志到最后一个有效位置。这确保了二进制日志反映了 InnoDB 表的exact数据,因此副本与源保持同步,因为它不会接收已经回滚的事务语句。

如果 MySQL 服务器在崩溃恢复时发现二进制日志比预期短,至少缺少一个已经提交的 InnoDB 事务。这不应该发生,如果 sync_binlog=1 并且磁盘/文件系统在被请求同步时实际同步(一些不),那么服务器打印错误消息 The binary log file_name is shorter than its expected size。在这种情况下,这个二进制日志不是正确的,复制应该从源数据的新快照重新启动。

以下系统变量的会话值被写入到二进制日志中,并且在解析二进制日志时被副本所尊重: