Mysqlbinlog - 用于处理二进制日志文件的工具
服务器的二进制日志包含描述对数据库内容修改的事件的文件。服务器以二进制格式写入这些文件。要以文本格式显示它们的内容,请使用mysqlbinlog实用程序。您还可以使用mysqlbinlog在复制设置中显示副本服务器编写的中继日志文件的内容,因为中继日志与二进制日志具有相同的格式。
调用mysqlbinlog如下:
mysqlbinlog [options] log_file ...
例如,要显示名为binlog.000003的二进制日志文件的内容,请使用以下命令:
mysqlbinlog binlog.000003
输出包括binlog.000003中的事件。对于基于语句的记录,事件信息包括SQL语句、执行该语句的服务器的ID、语句执行的时间戳以及执行所需的时间等。对于基于行的记录,事件指示行更改而不是SQL语句。
事件前面有头注释,提供附加信息。例如:
# at 141 #100309 9:28:36 server id 123 end_log_pos 245 Query thread_id=3350 exec_time=11 error_code=0
在第一行,表示事件在二进制日志文件中的偏移量(或起始位置)的数字后面。
第二行以日期和时间开头,表示事件发生在原始服务器上的时间。对于复制,此时间戳将传播到副本服务器。server id是事件发生的服务器的server_id值。end_log_pos表示下一个事件开始的位置(即当前事件的结束位置+1)。thread_id表示执行事件的线程。exec_time是在复制源服务器上执行事件所花费的时间。在副本上,它是从副本上的结束执行时间减去源上的开始执行时间的差异。差异用作指示复制相对于源落后多少的指示器。error_code表示执行事件的结果。零表示没有发生错误。
注意
在使用事件组时,事件的偏移量可能分组在一起,事件的注释也可能分组在一起。不要将这些分组事件误认为是空白文件偏移量。
mysqlbinlog的输出可以重新执行(例如,将其作为输入提供给mysql),以便重新执行日志中的语句。这对于意外服务器退出后的恢复操作很有用。要执行由mysqlbinlog使用的内部使用的BINLOG语句,用户需要BINLOG_ADMIN特权(或已弃用的SUPER特权),或者具有执行每个日志事件的适当权限的REPLICATION_APPLIER特权。
您可以使用mysqlbinlog直接读取二进制日志文件并将其应用于本地MySQL服务器。您还可以从远程服务器读取二进制日志,方法是使用–read-from-remote-server选项。要读取远程二进制日志,可以使用连接参数选项指示如何连接到服务器。这些选项是–host、–password、–port、–protocol、–socket和–user。
当二进制日志文件被加密时,从MySQL 8.0.14开始,mysqlbinlog无法直接读取它们,但可以使用–read-from-remote-server选项从服务器读取。当服务器的binlog_encryption系统变量设置为ON时,二进制日志文件被加密。SHOW BINARY LOGS语句显示特定二进制日志文件是否加密或未加密。加密和未加密的二进制日志文件还可以通过加密日志文件(0xFD62696E)开头的文件头中的魔术数字进行区分。请注意,从MySQL 8.0.14起,如果尝试直接读取加密的二进制日志文件,mysqlbinlog将返回适当的错误,而较旧版本的mysqlbinlog根本不识别该文件为二进制日志文件。
当二进制日志事务负载已压缩时,从MySQL 8.0.20开始,mysqlbinlog版本自该版本起自动解压缩并解码事务负载,并将它们作为未经压缩事件打印出来。较旧版本的mysqlbinlog无法读取压缩的事务负载。当服务器的binlog_transaction_compression系统变量设置为ON时,事务负载被压缩,然后作为单个事件(Transaction_payload_event)写入服务器的二进制日志文件中。使用–verbose选项,mysqlbinlog添加注释,说明使用的压缩算法、最初接收到的压缩负载大小以及解压缩后的结果负载大小。
注意
mysqlbinlog为单个事件(作为压缩事务负载的一部分)指出的结束位置与原始压缩负载的结束位置相同。因此,可以有多个解压缩事件具有相同的结束位置。
mysqlbinlog自己的连接压缩较少,但如果事务负载已经压缩,则仍然对未压缩事务和头部进行操作。
当运行mysqlbinlog针对大型二进制日志时,请小心确保文件系统有足够的空间来生成结果文件。要配置mysqlbinlog用于临时文件的目录,请使用TMPDIR环境变量。 mysqlbinlog在执行任何SQL语句之前将pseudo_replica_mode或pseudo_slave_mode的值设置为true。此系统变量影响XA事务的处理、original_commit_timestamp复制延迟时间戳和original_server_version系统变量以及不支持的SQL模式。
你可以将mysqlbinlog的输出重定向到mysql客户端来执行二进制日志中包含的事件。这种方法用于在意外退出时从旧备份恢复。例如:
mysqlbinlog binlog.000001 | mysql -u root -p
或者:
mysqlbinlog binlog.[0-9]* | mysql -u root -p
如果mysqlbinlog生成的语句可能包含BLOB值,这些值可能在mysql处理它们时造成问题。在这种情况下,使用带有–binary-mode选项的mysql。
你也可以将mysqlbinlog的输出重定向到一个文本文件,如果你需要先修改语句日志(例如,出于某种原因不想执行某些语句),可以这样做:
mysqlbinlog binlog.000001 > tmpfile
...编辑tmpfile...
mysql -u root -p < tmpfile
当使用带有–start-position选项调用mysqlbinlog时,它将仅显示偏移量大于或等于给定位置(给定位置必须与一个事件的开始匹配)的二进制日志中的事件。它还具有在看到具有给定日期和时间的事件的选项来停止和开始。这使您可以使用–stop-datetime选项(例如,可以说,“向前推进我的数据库到今天上午10:30。”)执行点时间恢复。
处理多个文件。 如果你需要在MySQL服务器上执行多个二进制日志,安全的方法是用单个连接来处理它们。这里是一个演示可能不安全的例子:
mysqlbinlog binlog.000001 | mysql -u root -p # 危险!
mysqlbinlog binlog.000002 | mysql -u root -p # 危险!
使用多个连接到服务器处理二进制日志会导致问题,如果第一个日志文件包含CREATE TEMPORARY TABLE语句,而第二个日志包含使用临时表的语句。当第一个mysql进程终止时,服务器删除临时表。当第二个mysql进程尝试使用表时,服务器报告“未知表”。
为了避免这样的问题,使用单个mysql进程来执行要处理的所有二进制日志的内容。这是一个方法:
mysqlbinlog binlog.000001 binlog.000002 | mysql -u root -p
另一个方法是将所有日志写入一个文件,然后处理该文件:
mysqlbinlog binlog.000001 > /tmp/statements.sql
mysqlbinlog binlog.000002 >> /tmp/statements.sql
mysql -u root -p -e "source /tmp/statements.sql"
从MySQL 8.0.12开始,你可以使用shell管道将多个二进制日志文件作为流式输入提供给mysqlbinlog。一个压缩的二进制日志文件存档可以被解压缩并直接提供给mysqlbinlog。在这个例子中,binlog-files_1.gz包含用于处理的多个二进制日志文件。管道提取binlog-files_1.gz的内容,将二进制日志文件作为标准输入传递给mysqlbinlog,并将mysqlbinlog的输出传递给mysql客户端以执行:
gzip -cd binlog-files_1.gz | ./mysqlbinlog - | ./mysql -uroot -p
你可以指定多个存档文件,例如:
gzip -cd binlog-files_1.gz binlog-files_2.gz | ./mysqlbinlog - | ./mysql -uroot -p
对于流式输入,不要使用–stop-position,因为mysqlbinlog无法识别应用此选项的最后一个日志文件。
LOAD DATA操作。mysqlbinlog可以生成不包含原始数据文件的LOAD DATA操作的输出。mysqlbinlog将数据复制到一个临时文件,并编写一个引用该文件的LOAD DATA LOCAL语句。这些文件写入的默认目录是系统特定的。要显式指定目录,请使用–local-load选项。
由于mysqlbinlog将LOAD DATA语句转换为LOAD DATA LOCAL语句(即添加LOCAL),因此用于处理语句的客户端和服务器都必须配置为启用LOCAL功能。
警告
为LOAD DATA LOCAL语句创建的临时文件不会自动删除,因为它们在您实际执行这些语句之前仍然需要。在不再需要语句日志后,您应该自己删除临时文件。这些文件可以在临时文件目录中找到,名称类似于original_file_name-#-#。