15.17 InnoDB Backup and Recovery
15.17.1 InnoDB Backup
15.17.2 InnoDB Recovery
15.17.1 InnoDB Backup
数据库安全管理的关键是定期备份。根据你的数据量、MySQL服务器数量和数据库工作负载等情况,可以单独或组合使用这些备份技术:
MySQL 企业级的热备份(MySQL Enterprise Backup hot backup)
MySQL 服务器关闭时,通过复制文件进行的冷备份(cold backup)
MYSQLDUMP 进行的逻辑备份(logical backup)
Hot Backups
mysqlbackup命令是MySQL Enterprise Backup组件的一部分,它允许你备份一个正在运行的MySQL实例(包括InnoDB表),在生成数据库的一致快照的同时,对操作的影响最小。当mysqlbackup复制InnoDB表时,可以继续对InnoDB表进行读写操作。
Cold Backups
如果可以关闭 MySQL 服务器,则可以进行物理备份,其中包含 InnoDB 用于管理表的所有文件。过程如下:
缓慢关闭 MySQL 服务器,并确保它停止时没有错误
将所有 InnoDB 数据文件(ibdata 文件和 .ibd 文件)复制到一个安全的地方
将所有 InnoDB 日志文件(ib_logfile 文件)复制到一个安全的地方
将 my.cnf 配置文件复制到安全的地方
Logical Backups Using mysqldump
除了物理备份之外,建议通过使用 mysqldump 转储表来定期创建逻辑备份。二进制文件可能会在你没有注意到的情况下被损坏。此外 mysqldump 还有一个--single-transaction配置选项,用于在不锁定其他客户端的情况下创建一致的快照。
此外 Replication 使用的是 InnoDB 表,因此可以使用 MySQL 复制功能在需要高可用性的数据库架构上保存数据库副本。
15.17.2 InnoDB Recovery
InnoDB 的恢复包含以下几点:
Point-in-Time Recovery
Recovery from Data Corruption or Disk Failure
InnoDB Crash Recovery
Tablespace Discovery During Crash Recovery
Lost or Corrupted Tablespace Map Files
Point-in-Time Recovery
要想恢复使用逻辑备份的 InnoDB 数据库到某个时间点,你首先必须要开启二进制日志并且在这之前还要有一个完整的备份。首先恢复之前的备份,然后使用二进制日志恢复从上一次完整备份到现在这个时间范围内发生的操作。
Recovery from Data Corruption or Disk Failure
如果数据库损坏或出现磁盘故障,则必须使用备份执行恢复。在损坏的情况下,首先找到一个没有损坏的备份。在恢复基本备份之后,使用 mysqlbinlog 和 mysql 从二进制日志文件中进行时间点恢复,以恢复备份之后发生的更改。
在某些数据库损坏的情况下,转储、删除和重新创建一个或几个损坏的表就足够了。你可以使用 CHECK TABLE 语句检查表是否损坏,尽管 CHECK TABLE 不能检测到所有可能的类型的损坏。
在某些情况下,明显的数据库页面损坏实际上是由于操作系统损坏了它自己的文件缓存,并且磁盘上的数据可能没有问题。最好先试着重新启动计算机。这样做可以消除看起来是数据库页面损坏的错误。如果 MySQL 仍然因为 InnoDB 一致性问题而无法启动,可以先试着考虑使用“强制InnoDB恢复”即“Forcing InnoDB Recovery”。
InnoDB Crash Recovery
要从 MySQL 服务器崩溃中恢复,需要重新启动 MySQL 服务器。InnoDB 会自动检查日志并执行数据库的前滚操作。InnoDB 自动回滚在崩溃时存在的未提交的事务。在恢复期间,mysqld 会显示类似的输出:
InnoDB: The log sequence number 664050266 in the system tablespace does not match
the log sequence number 685111586 in the ib_logfiles!
InnoDB: Database was not shutdown normally!
InnoDB: Starting crash recovery.
InnoDB: Using 'tablespaces.open.2' max LSN: 664075228
InnoDB: Doing recovery: scanned up to log sequence number 690354176
InnoDB: Doing recovery: scanned up to log sequence number 695597056
InnoDB: Doing recovery: scanned up to log sequence number 700839936
InnoDB: Doing recovery: scanned up to log sequence number 706082816
InnoDB: Doing recovery: scanned up to log sequence number 711325696
InnoDB: Doing recovery: scanned up to log sequence number 713458156
InnoDB: Applying a batch of 1467 redo log records ...
InnoDB: 10%
InnoDB: 20%
InnoDB: 30%
InnoDB: 40%
InnoDB: 50%
InnoDB: 60%
InnoDB: 70%
InnoDB: 80%
InnoDB: 90%
InnoDB: 100%
InnoDB: Apply batch completed!
InnoDB: 1 transaction(s) which must be rolled back or cleaned up in total 561887 row
operations to undo
InnoDB: Trx id counter is 4096
...
InnoDB: 8.0.1 started; log sequence number 713458156
InnoDB: Waiting for purge to start
InnoDB: Starting in background the rollback of uncommitted transactions
InnoDB: Rolling back trx with id 3596, 561887 rows to undo
...
./mysqld: ready for connections....
InnoDB 崩溃恢复包括以下几个步骤:
Tablespace discovery
Tablespace discovery is the process that InnoDB uses to identify tablespaces that require redo log application
Redo logapplication
在接受任何连接之前,在初始化期间执行重做日志应用程序。如果所有更改都从缓冲池刷新到表空间(ibdata*和*.ibd 文件),当关闭或崩溃时,重做日志应用程序被跳过。如果 redo日志文件在启动时丢失,InnoDB 也会跳过 redo 日志应用程序。
当前的最大自动增量计数器值将在每次值更改时写入重做日志,这使得它不会崩溃。在恢复期间,InnoDB 扫描 redo 日志以收集计数器值更改并将更改应用到内存中的表对象。
当遇到索引树损坏时,InnoDB 在重做日志中写入一个损坏标志,这使得损坏标志是安全的。InnoDB 还将内存中的腐败标记数据写入每个检查点的引擎-私有系统表中。在恢复期间,InnoDB 从两个位置读取损坏标志并合并结果,然后将内存表和索引对象标记为损坏。
不建议删除重做日志以加速恢复,即使某些数据丢失是可以接受的。删除重做日志应该只在完全关闭之后才考虑,innodb_fast_shutdown 设置为 0 或 1。
Roll backof incompletetransactions
不完全事务是任何在崩溃或快速关闭时活跃的事务。回滚不完整事务所需的时间可以是事务在中断前活动的时间的三到四倍,这取决于服务器负载。
不能取消回滚的事务。在极端情况下,当回滚事务需要非常长的时间时,使用innodb_force_recovery 设置为 3 或更高的值启动 InnoDB 可能会更快。
Change buffermerge
将更改缓冲区的更改应用到次要索引的页,因为索引页被读入缓冲池。
Purge
删除已删除的、对活动事务不再可见的记录。
重做日志应用程序后面的步骤不依赖重做日志,并与正常处理并行执行。其中,只有不完整事务的回滚对于崩溃恢复是特殊的。插入缓冲区合并和清除在正常处理期间执行。
在重做日志应用程序之后,InnoDB 尝试尽早接受连接,以减少停机时间。作为崩溃恢复的一部分,InnoDB 回滚未提交的事务或服务器崩溃时处于 XA 准备状态的事务。回滚是由一个后台线程执行的,它与来自新连接的事务并行执行。在回滚操作完成之前,新连接可能会与恢复的事务发生锁定冲突。
在大多数情况下,即使 MySQL 服务器在繁重的活动中意外死亡,恢复过程也会自动发生,DBA 也不需要任何操作。如果硬件故障或严重的系统错误损坏了InnoDB 数据,MySQL 可能会拒绝启动。
Tablespace Discovery During Crash Recovery
如果在恢复期间,InnoDB 遇到自上次检查点以来写入的重做日志,则必须将重做日志应用于受影响的表空间。在恢复期间标识受影响表空间的过程称为tablespace discovery。
tablespace discovery 使用表空间映射文件执行,这些文件将表空间 id 映射到表空间文件名。表空间映射文件存储在 innodb_data_home_dir 目录中。如果 innodb_data_home_dir未配置,则默认位置为 MySQL 数据目录 datadir。
有两个表空间映射文件(tablespaces.open.1 和 tablespac .open.2)。表空间映射文件只在恢复期间使用。在正常启动时忽略这些文件。
Lost or Corrupted Tablespace Map Files
如果表空间映射文件丢失或损坏,可以使用 innodb_scan_directory 选项在启动时指定表空间文件目录。此选项使 InnoDB 读取指定目录中的每个表空间文件的第一页,并重新创建表空间映射文件,以便恢复过程可以应用重做日志。
这个选项也可以用来指定丢失的表空间文件的目录路径。例如,如果恢复报告由于缺少表空间文件而导致的错误,你可以配置 innodb_scan_directory 以在特定目录中搜索表空间文件。
innodb_scan_directory 可以在启动命令或 MySQL 选项文件中指定为选项。引号用于参数值,因为在其他情况下,一些命令解释器将分号(;)解释为特殊字符。例如,Unix shell 将它视为命令终止符。
# mysqld --innodb-scan-directories="directory_path_1;directory_path_2"
[mysqld]
innodb_scan_directories="directory_path_1;directory_path_2"
当 innodb_scan_directory 在启动时指定时,InnoDB 启动过程打印如下所示的消息,报告所扫描的目录和找到的表空间文件数量:
InnoDB: Directories to scan 'directory_path_1;directory_path_2'
InnoDB: Scanning 'directory_path_1'
InnoDB: Scanning 'directory_path_2'
InnoDB: Found 10 '.ibd' file(s)
领取专属 10元无门槛券
私享最新 技术干货