8.4 中文镜像

MySQL 8.4 参考手册 · 中文镜像

正文为中文,英文原文默认隐藏。点击任意中文段落即可展开 / 收起对应英文原文。

打开官方英文原文 ↗

译文由机器翻译生成,仅供理解参考;有疑问请以官方英文原文为准。

MySQL 8.4 参考手册 / 9 备份与恢复 / 9.5 时间点(增量)恢复 / 9.5.2 使用事件位置进行时间点恢复
中文点击中文段落可显示 / 隐藏英文原文本页译文覆盖 100%

9.5.2 使用事件位置进行时间点恢复9.5.2 Point-in-Time Recovery Using Event Positions

上一节,第 9.5.1 节,“使用二进制日志进行时间点恢复”,解释了使用二进制日志执行时间点恢复的一般概念。本节通过示例详细说明了操作过程。The last section, Section 9.5.1, “Point-in-Time Recovery Using Binary Log”, explains the general idea of using the binary log to perform a point-in-time-recovery. The section explains the operation in details with an example.

例如,假设在 2020 年 3 月 11 日大约 20:06:00 执行了一条删除表的 SQL 语句。您可以执行时间点恢复,以将服务器恢复到删除表之前的状态。以下是实现此操作的一些示例步骤:As an example, suppose that around 20:06:00 on March 11, 2020, an SQL statement was executed that deleted a table. You can perform a point-in-time recovery to restore the server up to its state right before the table deletion. These are some sample steps to achieve that:

  1. 恢复在感兴趣的时间点之前创建的最后一次完整备份(称为tp,例如我们的示例中为 2020 年 3 月 11 日 20:06:00)。完成后,记下你已经恢复服务器的二进制日志位置以备后用,然后重启服务器。Restore the last full backup created before the point-in-time of interest (call it tp, which is 20:06:00 on March 11, 2020 in our example). When finished, note the binary log position up to which you have restored the server for later use, and restart the server.

    Note

    在恢复和服务器重启后,InnoDB 也会显示最后恢复的二进制日志位置,但这 不是 获取恢复结束日志位置的可靠方法,因为在显示的位置所反映的时间之后,可能已经发生了 DDL 事件和非 InnoDB 的更改。您的备份和恢复工具应该为您提供恢复所需的最后二进制日志位置:例如,如果您使用 mysqlbinlog 执行此任务,请检查二进制日志重放的停止位置;如果您使用 MySQL Enterprise Backup,最后的二进制日志位置已保存在您的备份中。请参见 时间点恢复。While the last binary log position recovered is also displayed by InnoDB after the restore and server restart, that is not a reliable means for obtaining the ending log position of your restore, as there could be DDL events and non-InnoDB changes that have taken place after the time reflected by the displayed position. Your backup and restore tool should provide you with the last binary log position for your recovery: for example, if you are using mysqlbinlog for the task, check the stop position of the binary log replay; if you are using MySQL Enterprise Backup, the last binary log position has been saved in your backup. See Point-in-Time Recovery.

  2. 找到对应于您希望恢复数据库的时间点的精确二进制日志事件位置。在我们的示例中,假设我们知道表删除发生的大概时间(tp),我们可以通过使用 mysqlbinlog 工具检查该时间附近的日志内容来找到日志位置。使用 --start-datetime 和 --stop-datetime 选项来指定 tp 附近的一小段时间,然后在输出中查找该事件。例如:Find the precise binary log event position corresponding to the point in time up to which you want to restore your database. In our example, given that we know the rough time where the table deletion took place (tp), we can find the log position by checking the log contents around that time using the mysqlbinlog utility. Use the --start-datetime and --stop-datetime options to specify a short time period around tp, and then look for the event in the output. For example:

    $> mysqlbinlog --start-datetime="2020-03-11 20:05:00" \
                       --stop-datetime="2020-03-11 20:08:00" --verbose \
             /var/lib/mysql/bin.123456 | grep -C 15 "DROP TABLE"
     
    /*!80014 SET @@session.original_server_version=80019*//*!*/;
    /*!80014 SET @@session.immediate_server_version=80019*//*!*/;
    SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    # at 232
    #200311 20:06:20 server id 1  end_log_pos 355 CRC32 0x2fc1e5ea 	Query	thread_id=16	exec_time=0	error_code=0
    SET TIMESTAMP=1583971580/*!*/;
    SET @@session.pseudo_thread_id=16/*!*/;
    SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    SET @@session.sql_mode=1168113696/*!*/;
    SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    /*!\C utf8mb4 *//*!*/;
    SET @@session.character_set_client=255,@@session.collation_connection=255,@@session.collation_server=255/*!*/;
    SET @@session.lc_time_names=0/*!*/;
    SET @@session.collation_database=DEFAULT/*!*/;
    /*!80011 SET @@session.default_collation_for_utf8mb4=255*//*!*/;
    DROP TABLE `pets`.`cats` /* generated by server */
    /*!*/;
    # at 355
    #200311 20:07:48 server id 1  end_log_pos 434 CRC32 0x123d65df 	Anonymous_GTID	last_committed=1	sequence_number=2	rbr_only=no	original_committed_timestamp=1583971668462467	immediate_commit_timestamp=1583971668462467	transaction_length=473
    # original_commit_timestamp=1583971668462467 (2020-03-11 20:07:48.462467 EDT)
    # immediate_commit_timestamp=1583971668462467 (2020-03-11 20:07:48.462467 EDT)
    /*!80001 SET @@session.original_commit_timestamp=1583971668462467*//*!*/;
    /*!80014 SET @@session.original_server_version=80019*//*!*/;
    /*!80014 SET @@session.immediate_server_version=80019*//*!*/;
    SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    # at 434
    #200311 20:07:48 server id 1  end_log_pos 828 CRC32 0x57fac9ac 	Query	thread_id=16	exec_time=0	error_code=0	Xid = 217
    use `pets`/*!*/;
    SET TIMESTAMP=1583971668/*!*/;
    /*!80013 SET @@session.sql_require_primary_key=0*//*!*/;
    CREATE TABLE dogs
    

    从 mysqlbinlog 的输出中,可以在二进制日志的 # at 232 与 # at 355 行之间找到 DROP TABLE `pets`.`cats` 语句,这意味着该语句发生在日志位置 232 之后,且在 DROP TABLE 语句之后日志位于位置 355。From the output of mysqlbinlog, the DROP TABLE `pets`.`cats` statement can be found in the segment of the binary log between the line # at 232 and # at 355, which means the statement takes place after the log position 232, and the log is at position 355 after the DROP TABLE statement.

    Note

    仅使用--start-datetime和--stop-datetime选项来帮助你找到实际感兴趣的事件位置。不推荐使用这两个选项来指定要应用的二进制日志段范围:使用这些选项时,遗漏二进制日志事件的风险较高。请改用--start-position和--stop-position。Only use the --start-datetime and --stop-datetime options to help you find the actual event positions of interest. Using the two options to specify the range of binary log segment to apply is not recommended: there is a higher risk of missing binary log events when using the options. Use --start-position and --stop-position instead.

  3. 将二进制日志文件中的事件应用到服务器,从您在步骤 1 中找到的日志位置开始(假设为 155),直到在步骤 2 中找到的、位于您感兴趣的时间点 之前 的位置(即 232):Apply the events in binary log file to the server, starting with the log position your found in step 1 (assume it is 155) and ending at the position you have found in step 2 that is before your point-in-time of interest (which is 232):

    $> mysqlbinlog --start-position=155 --stop-position=232 /var/lib/mysql/bin.123456 \
             | mysql -u root -p
    

    该命令会从起始位置恢复所有事务直到停止位置之前。因为 mysqlbinlog 的输出在每条记录的 SQL 语句之前都包含 SET TIMESTAMP 语句,所以恢复的数据和相关的 MySQL 日志反映了事务执行的原始时间。The command recovers all the transactions from the starting position until just before the stop position. Because the output of mysqlbinlog includes SET TIMESTAMP statements before each SQL statement recorded, the recovered data and related MySQL logs reflect the original times at which the transactions were executed.

    您的数据库现在已恢复到感兴趣的时间点 tp,也就是在表 pets.cats 被删除之前。Your database has now been restored to the point-in-time of interest, tp, right before the table pets.cats was dropped.

  4. 在已完成的时间点恢复之外,如果您还想重新执行所有在感兴趣时间点 之后 的语句,请再次使用 mysqlbinlog 将所有在 tp 之后的事件应用到服务器上。我们在步骤 2 中注意到,在我们想跳过的语句之后,日志的位置是 355;我们可以将其用于 --start-position 选项,以便包含位置之后的任何语句:Beyond the point-in-time recovery that has been finished, if you also want to reexecute all the statements after your point-in-time of interest, use mysqlbinlog again to apply all the events after tp to the server. We noted in step 2 that after the statement we wanted to skip, the log is at position 355; we can use it for the --start-position option, so that any statements after the position are included:

    $> mysqlbinlog --start-position=355 /var/lib/mysql/bin.123456 \
             | mysql -u root -p
    

    您的数据库已恢复二进制日志文件中记录的最新语句,但已跳过所选事件。Your database has been restored the latest statement recorded in the binary log file, but with the selected event skipped.