MySQL-10-执行备份

目标:

  • 使用 MySQL Enterprise Backup执行一致性备份
  • 使用 mysqldumpmysqlpump工具执行逻辑备份
  • 解释何时及如何使用物理文件备份
  • 从复制从库进行备份
  • 使用二进制日志恢复数据库

MySQL备份工具

备份工具概述:

  • 用于逻辑备份的 SQL 语句
  • 结合 SQL 语句与操作系统命令的物理备份
    • 示例:LOCK TABLES
  • 其他 MySQL 备份工具:
    • MySQL Enterprise Backup:物理备份
    • mysqldump:逻辑备份
    • mysqlpump:逻辑备份
  • 第三方工具

1. 逻辑备份的 SQL 语句

逻辑备份通过 SQL 语句导出数据的逻辑结构(如 SQL 脚本),而非直接复制物理文件。常见的 SQL 方法包括:

  • SELECT ... INTO OUTFILE

    将查询结果导出为文本文件(如 CSV),适合灵活筛选数据:

    1
    
    SELECT * FROM users WHERE id > 100 INTO OUTFILE '/tmp/users.csv';
    
  • SHOW CREATE TABLE

    获取创建表的 SQL 语句,用于备份表结构:

    1
    
    SHOW CREATE TABLE orders;
    
  • mysqldump 的底层原理 本质上是执行一系列 SELECTSHOW CREATE 语句,生成完整的 SQL 备份文件。

2. 物理备份的 SQL 与系统命令结合

物理备份直接复制数据库文件(如 .ibd.frm),需通过 SQL 语句确保数据一致性:

  • LOCK TABLES ... READ

    (适用于 MyISAM 等非事务引擎)

    1
    
    LOCK TABLES users READ;  -- 锁定表为只读状态,防止备份期间数据变更
    
  • FLUSH TABLES WITH READ LOCK

    (适用于全库备份)

    1
    
    FLUSH TABLES WITH READ LOCK;  -- 刷新所有表到磁盘并加全局读锁
    
  • 操作系统命令复制文件

    1
    2
    
    # Linux 示例:复制 InnoDB 数据文件
    cp -R /var/lib/mysql/data/ /backup/
    
  • 解锁表

    1
    
    UNLOCK TABLES;  -- 备份完成后释放锁
    

使用 MySQL Enterprise Backup进行物理备份

MySQL Enterprise Backup

  • 适用于 MySQL 的多平台热备份工具
    • 可通过命令行运行:mysqlbackup
  • 针对 InnoDB 表进行了优化
    • 也能备份 MySQL 支持的其他存储引擎的表
  • 支持的功能:
    • 除常规全量备份外,还支持增量备份和差异备份
    • 单文件备份:
      • 可流式传输到其他存储设备或文件服务器
      • 可备份到磁带
      • 可直接备份到云存储
    • 备份加密与压缩
    • 部分备份和可传输表空间(transportable tablespace)
  • 可在 MySQL 企业级监控(MySQL Enterprise Monitor)的备份仪表盘中监控备份状态

对于 MySQL Server 8.0,应使用与服务器版本号相同的 MySQL 企业级备份(MySQL Enterprise Backup)版本

MySQL Enterprise Backup: Storage Engines

InnoDB 引擎

MySQL 企业级备份(MySQL Enterprise Backup)对 InnoDB 表执行热备份:

  • 备份过程中,连接到数据库的应用程序可以正常运行。
  • 这种备份不会阻塞正常的数据库操作。
  • 即使在备份过程中数据发生变更,这些变更也会被捕获。

其他存储引擎

MySQL 企业级备份对其他存储引擎执行温备份:

  • 应用程序可以读取数据库表。
  • 在非 InnoDB 表的备份过程中:
    • 8.0.16 版本之前,数据库无法被修改。
    • 从 8.0.16 版本开始,仅非 InnoDB 表无法被修改,而 InnoDB 表允许执行 DML(数据操纵语言)操作,但不允许执行 DDL(数据定义语言)操作。

MySQL 企业级备份不支持离线(冷)备份。MySQL 服务器必须处于运行状态,mysqlbackup 工具才能连接到服务器并启动备份。

MySQL Enterprise Backup: InnoDB Files

使用 mysqlbackup 备份的原始 InnoDB 文件包括:

  • ibdata* 文件:共享表空间文件,包含系统表空间,可能还包含一些用户表的数据。
  • mysql.ibd:包含数据字典的 mysql 表空间文件。
  • .ibd 文件:每个表对应的数据文件和通用表空间文件。
  • undo_* 文件:撤销日志(undo log)表空间文件。
  • ib_logfile* 文件
    • ib_logfile* 文件中提取的数据会存储在一个名为 ibbackup_logfile 的新备份文件中。
      • ibbackup_logfile包含备份过程中发生的新变更(因热备份时数据仍在写入)
    • 这包括重做日志(redo log)信息,这些信息记录了备份过程中发生的数据变更。

MySQL Enterprise Backup: Non-InnoDB Files

  • MySQL 企业级备份(MySQL Enterprise Backup)针对 InnoDB 进行了优化。
  • 若满足以下条件,可使用该工具备份非 InnoDB 数据:
    • 待备份的 MySQL 服务器支持 InnoDB。
    • 服务器中至少包含一个 InnoDB 表。
  • 默认情况下,mysqlbackup会备份数据目录(datadir)下所有子目录中的文件。
    • 若指定 --only-known-file-types 选项,备份将仅包含 MySQL 识别的扩展名的文件。
  • 例如,对于 MyISAM 存储的数据,以下文件会被备份:
    • .MYD:MyISAM 数据文件
    • .MYI:MyISAM 索引文件
    • .sdi:元数据文件(存储表结构等信息)

MySQL 企业级备份(MEB)的核心优势在于对 InnoDB 的热备份支持,但也能处理非 InnoDB 引擎的数据,需满足以下条件:

  1. 兼容性前提

    • 必须支持 InnoDB:MEB 依赖 InnoDB 的事务和 MVCC 机制来协调备份过程,因此服务器必须安装并启用 InnoDB 引擎。
    • 至少存在一个 InnoDB 表:即使主要数据使用 MyISAM 等其他引擎存储,也需有至少一个 InnoDB 表,以确保工具能正常启动备份流程。
  2. 备份范围控制

    • 默认行为:备份数据目录下的所有文件,包括自定义日志、临时文件等,可能包含无关内容。
    • --only-known-file-types 选项:仅备份 MySQL 官方识别的文件类型(如 .MYD.ibd.sdi),过滤掉无关文件,使备份更 “纯净”。 例如:
    1
    
    mysqlbackup --only-known-file-types backup-to-image /path/to/backup
    
  3. MyISAM 引擎文件备份 对于 MyISAM 表,MEB 会备份以下关键文件:

    • .MYD:存储表的实际数据(类似 CSV 结构,但为二进制格式)。
    • .MYI:存储表的索引信息(如主键、索引键的 B-Tree 结构)。
    • .sdi(MySQL 8.0+):存储表的元数据(如列定义、约束),替代了早期版本的 .frm 文件。 注意:MyISAM 不支持事务,备份时需通过锁表确保数据一致性(温备份),可能短暂影响业务写入。
  4. 其他非 InnoDB 引擎支持 MEB 理论上可备份所有 MySQL 支持的存储引擎(如 MEMORY、CSV、ARCHIVE 等),但需注意:

    • MEMORY 表:数据存储在内存中,备份时仅保存表结构(.frm.sdi),重启后数据丢失。
    • CSV 表:数据以文本 CSV 格式存储,备份 .CSV 文件和元数据(.sdi)。
    • ARCHIVE 表:适合历史归档数据,备份 .ARM(数据)和 .ARZ(索引)文件。

全量备份

  • 启动方式
    • 需在 MySQL 服务器主机上启动 mysqlbackup,而非远程执行。
    • 使用与 mysql 客户端相同的选项提供认证信息和服务器坐标,包括 --user--port--password
    • --backup_dir 选项指定存储备份数据和元数据的目录。
  • 基础命令
    • backup:执行备份的初始阶段(创建备份文件但不应用最新变更)。
    • backup-and-apply-log:包含备份的初始阶段,并在第二阶段更新备份中的 InnoDB 表,使其包含备份过程中发生的所有数据变更。

单文件备份

  • 使用 backup-to-image 命令可将备份写入单个文件:

    1
    2
    3
    4
    
    mysqlbackup --user=root --password=xxx \
      --backup-image=/backup/full_backup_20250714.img \  # 单文件路径
      --backup_dir=/tmp/backup_temp \  # 临时元数据目录
      backup-to-image
    
    • --backup-image 选项指定存储备份的文件名和路径。
    • --backup_dir 选项指定用于存储备份元数据的临时文件夹。
  • 单文件备份的优势:

    • 更易于管理
      • 每次备份对应一个文件
    • 可流式传输到其他设备或服务器
    • 可备份到磁带
    • 可备份到云存储

备份过程

  1. mysqlbackup 建立与 MySQL 服务器的连接。
  2. mysqlbackup对 InnoDB 表执行在线备份。
    • 此阶段不干扰正常的数据库处理(如读写操作)。
  3. mysqlbackup运行接近完成时,它会:
    • 执行 SQL 语句LOCK INSTANCE FOR BACKUP
      • 这会阻塞 DDL 操作(如 ALTER TABLE),但允许 DML 操作(如 INSERTUPDATE)继续执行。
    • 对备份中包含的所有非 InnoDB 表执行 SQL 语句 FLUSH TABLES tbl_name, ... WITH READ LOCK
    • 将非 InnoDB 文件(如 MyISAM 的 .MYI.MYD 文件)复制到备份目录。
  4. mysqlbackup 运行完成后,解锁表和实例

如果满足以下条件,读锁阶段(read-locked phase)的持续时间会很短:

  • 在 read lock 生效期间,不在数据库中执行长时间的 SELECT 或其他查询。
  • 非 InnoDB 表的体积较小。

上述的步骤 3 描述的是 mysqlbackup 8.0.16 及更新版本的流程。

对于 8.0.16 之前版本的 mysqlbackup,步骤 3 会通过 SQL 语句 FLUSH TABLES WITH READ LOCK 锁定整个数据库,这会阻塞所有表上的写入操作。

增量备份

每次增量备份仅包含自上一次备份(该备份本身可以是全量备份或增量备份)以来的变更。

1
2
3
mysqlbackup --user=username --password --port=portnumber 
       --incremental --incremental-base=history:last_backup 
       --backup_dir=incr-backup-directory backup
  • 添加 --incremental 选项以执行增量备份。
  • 使用 --incremental-base 选项指定上一次备份作为增量备份的基础。
  • 如果在两次备份间隔期间,大部分数据未发生变化,增量备份可提高备份速度并减少存储备份所需的空间。
  • 适用于 InnoDB 表,或只读、极少更新的非 InnoDB 表。
    • 对于非 InnoDB 文件,若自上一次备份以来文件有变化,则整个文件会被包含在增量备份中。

可以通过将备份命令替换为 backup-to-image 命令并指定 --backup-image 选项,将备份写入单个文件。

--incremental-base=history:last_backup 选项会使 mysqlbackupbackup_history 表中记录的上一次成功的非 TTS(表空间传输)备份中查询 end_lsn 值(该表位于正在备份的服务器实例中)。

或者,你可以指定 dir:directory_path 作为 --incremental-base 选项的值,以指定包含上一次备份的目录路径。

除了 --incremental-base 选项,你还可以使用 --start-lsn 选项指定上一次备份中包含的最大 LSN(日志序列号)值,将其用作增量备份的基础。

  1. 增量备份基本逻辑:增量备份只关注两次备份间数据的变化部分,基于上一次全量或增量备份做差异捕获,能有效减少备份数据量和存储占用,提升备份效率,不过恢复时需按顺序整合全量 + 各增量备份。
  2. 命令参数说明:
    • --incremental 是开启增量备份模式的关键标识;--incremental-base 用于指定增量备份的 “基准”,history:last_backup 是从备份历史表找基准,dir:directory_path 则指定基准备份所在目录 。
    • --start-lsn 通过明确 LSN(日志序列号,记录数据库变更的关键标识)值作为基准,原理和 --incremental-base 类似,灵活适配不同场景。
  3. 适用场景与限制:对 InnoDB 表、只读 / 少更新的非 InnoDB 表友好,利用了 InnoDB 事务日志等特性高效捕获变更;但非 InnoDB 表若有变化,是整文件备份,若这类表体积大且频繁变,增量优势就会受限。
  4. 单文件备份拓展:结合 backup-to-image 可把增量备份输出为单个文件,方便存储、传输(如传至磁带、云存储),和全量备份的单文件模式配合,统一管理备份文件形态 。
  5. 版本与兼容性:依托 backup_history 表等机制,是 MySQL Enterprise Backup 工具在 8.0 等版本的功能,体现了商业备份工具对备份流程精细化、高效化的支持,不过使用时要留意数据库版本、备份历史记录维护等问题,确保基准备份可查、可用 。

差异备份

每次差异备份会包含自上一次全量备份以来对数据所做的所有变更。这是增量备份的一种特殊情况,以全量备份作为其基础。

  • 使用 --incremental-base=history:last_full_backup 选项指定上一次全量备份作为增量备份的基础。该选项从 8.0.17 版本开始可用。
  • 与增量备份类似,不同之处在于其基础始终是全量备份。

你可以通过将备份命令替换为 backup-to-image 命令并指定 --backup-image 选项,将备份写入单个文件。

可以使用 --start-lsn 选项来替代 --incremental-base 选项,指定上一次全量备份中包含的最大 LSN(日志序列号)值,作为差异备份的基础。如果你指定的是上一次增量备份的最大 LSN 值(而非全量备份的),那么该备份会变成增量备份,而非差异备份。

注意:增量备份和差异备份的命令类似;你指定的基础备份决定了该备份是增量备份还是差异备份。

验证操作

validate 命令用于检查备份的完整性。

  • 验证备份镜像

    1
    
    mysqlbackup --backup-image=image-file validate
    
  • 验证备份目录

    1
    
    mysqlbackup --backup-dir=backup-directory validate
    
    • 验证备份中每个数据页的校验和(checksum)值。
  • 限制

    • 仅验证 InnoDB 数据文件(ibdata**.ibd 文件)。
    • 无法检测从 *.ibd 文件中被移除或截断的缺失页。
    • 无法检测备份中缺失的文件或已被删除的文件。

恢复操作

  1. 关闭 MySQL 服务器。
  2. 删除服务器数据目录内的所有文件。
    • 删除由 --innodb_data_home_dir--innodb_log_group_home_dir--innodb_undo_directory 选项指定目录中的所有文件。
  3. 运行 mysqlbackup 从全量备份中恢复备份文件。
  4. 如有可用的增量备份或差异备份,可选择从这些备份进行恢复(可选操作)。
  5. 应用可用的二进制日志,以:
    • 恢复上一次备份后对数据库所做的所有更改。
    • 执行时间点恢复,防止错误操作损坏数据。
  6. 启动 MySQL 服务器。

恢复命令

  • copy-back

    • 恢复已使用 apply-log 命令处理为一致状态的目录备份。
    1
    
    mysqlbackup --backup-dir=backup-dir copy-back
    
    • 将备份目录(backup-dir)中的文件恢复到数据目录。
  • copy-back-and-apply-log

    • 一步操作中,恢复单文件备份或目录备份,并对恢复的数据执行 apply-log 操作。
    1
    2
    
    mysqlbackup --backup-dir=temp-backup-dir 
        --backup-image=image-file copy-back-and-apply-log
    
    • 使用 temp-backup-dir 存储临时文件,将 image-file 中的文件恢复到数据目录。

当使用 copy-back 命令时,MySQL 企业级备份(MySQL Enterprise Backup)会:

  • 将数据文件、日志和其他已备份的文件从备份目录复制到其原始位置。
  • 对这些文件执行任何所需的后处理操作。

copy-back 过程中,mysqlbackup 无法从服务器查询其设置,因此它会读取标准配置文件以获取诸如 datadir 等选项的信息。

  • 如果想恢复到不同的服务器,可使用 --defaults-file 选项提供非标准的默认配置文件。

恢复增量备份(Restoring Incremental Backups)

  • 恢复增量备份或差异备份之前,必须先恢复正确的基础备份(全量备份 )。

  • 在恢复操作中添加--incremental选项

    • 从增量备份目录恢复:

      1
      2
      
      mysqlbackup --incremental-backup-dir=incr-backup-dir \
        --incremental copy-back-and-apply-log
      
    • 从单文件增量备份恢复:

      1
      2
      
      mysqlbackup --backup-dir=temp-backup-dir --backup-image=image-file \
        --incremental copy-back-and-apply-log
      

更新操作(Update Operations)

全量备份的目录备份可通过以下方式更新:

  • apply-log 操作

    1
    
    mysqlbackup --backup-dir=backup-dir apply-log
    
    • 使用 backup 命令进行的全量备份,若已通过 apply-log 命令更新,则可直接使用 copy-back 命令恢复,而非 copy-back-and-apply-log 命令。
  • apply-incremental-backup 操作

    1
    2
    
    mysqlbackup --incremental-backup-dir=incr-backup-dir \
      --backup-dir=backup-dir apply-incremental-backup
    
    • backup-dir 中的全量备份,可使用以该全量备份为基础的增量备份进行更新。
    • 这可加快恢复过程,因为它能减少需要恢复的增量备份数量。这也可加快备份速度,因为它能将增量备份转换为全量备份。

这是 MySQL 企业级备份中优化备份链、加速恢复的关键操作,核心是通过 apply-logapply-incremental-backup 提前合并变更,减少恢复时的步骤:

1. apply-log:预合并 redo 日志
  • 作用: 对全量备份(目录形式)执行 apply-log,会将备份期间的 redo 日志(如 ibbackup_logfile)应用到备份文件中,使备份文件处于 “可立即恢复” 的一致状态。
  • 恢复简化: 若备份已执行 apply-log,恢复时无需再运行 copy-back-and-apply-log,直接用 copy-back 即可(因为日志已提前合并),减少恢复步骤。
2. apply-incremental-backup:增量合并到全量
  • 作用: 将增量备份(--incremental-backup-dir 指定)合并到基础全量备份(--backup-dir 指定)中,使全量备份 “升级” 为包含增量变更的新全量备份。
  • 价值:
    • 加速恢复:恢复时无需依次应用多个增量备份,直接恢复合并后的全量备份即可。
    • 转换备份类型:将增量备份转换为全量备份,适合需要长期保留全量备份、减少增量备份数量的场景。
3. 实际应用场景
  • 定期优化备份链: 每周日做全量备份,周一至周六做增量备份。每周六执行 apply-incremental-backup,将周一至周六的增量合并到周日的全量备份,生成新的全量备份,减少恢复时需处理的增量数量。
  • 简化恢复流程: 对重要的全量备份提前执行 apply-log,确保恢复时只需 copy-back,降低故障时的恢复复杂度。
4. 关键注意事项
  • 备份目录一致性apply-incremental-backup 的基础全量备份必须与增量备份的基准一致(通过 LSN 或备份历史匹配),否则会因变更冲突导致数据损坏。
  • 空间占用: 合并增量备份会增加全量备份的体积(需存储增量变更),需平衡存储成本和恢复效率。

单文件操作(Single-File Operations)

  • 将现有备份目录转换为单文件备份

    1
    2
    
    mysqlbackup --backup_dir=backup-dir \
      --backup-image=image-file backup-dir-to-image
    
  • 列出单文件备份的内容

    1
    
    mysqlbackup --backup-image=image-file list-image
    
  • 从单文件备份中提取文件

    1
    2
    
    mysqlbackup --backup-image=image-file --src-entry=file-to-extract \
      --dst-entry=file-to-extract extract
    
    • --src-entry:指定要从单文件备份中提取的文件或目录。
    • --dst-entry:与单文件备份配合使用,将单个文件或目录提取到用户指定的路径。

这是 MySQL 企业级备份中 ** 单文件备份(镜像文件)** 的核心操作,支持转换、查看、提取,解决多文件备份管理复杂的问题:

1. backup-dir-to-image:目录转单文件
  • 作用: 将分散的备份目录(含 .ibd.MYD 等文件)打包为单个镜像文件(如 .img),便于存储、传输(如上传到云存储、写入磁带)。
  • 命令解析:
    • --backup_dir:指定现有备份目录的路径。
    • --backup-image:指定生成的单文件镜像的路径(需提前创建空文件或指定新路径)。
  • 应用场景: 定期将全量备份目录转换为单文件,简化异地容灾的传输流程。
2. list-image:查看单文件内容
  • 作用: 列出单文件备份中包含的所有文件和目录结构,类似 ls 命令,用于快速校验备份内容。
  • 命令解析: 只需指定 --backup-image(单文件路径),即可输出备份内的文件列表(如 ibdata1mydb/mytable.ibd 等)。
  • 实践价值: 恢复前确认备份包含目标文件(如误删表的 .ibd 文件),避免恢复后发现文件缺失。
3. extract:从单文件提取文件
  • 作用: 从单文件备份中提取指定文件或目录,无需恢复整个备份,适合快速恢复单个表或文件。
  • 命令解析:
    • --src-entry:指定要提取的文件路径(需与 list-image 查看的路径一致,如 mydb/mytable.ibd)。
    • --dst-entry:指定提取到的目标路径(如 /restore/mytable.ibd)。
  • 典型场景: 误删某张表的 .ibd 文件时,从全量备份镜像中直接提取该文件,无需恢复整个数据库。
4. 关键注意事项
  • 依赖备份结构

    操作单文件备份前,需确保备份是通过 backup-to-imagebackup-dir-to-image 生成的标准镜像,否则可能因格式不兼容失败。

  • 路径精确匹配extract--src-entry 需严格匹配 list-image 显示的路径(包括目录层级),否则无法找到文件。

  • 提取后的兼容性: 提取的文件需手动适配权限、配置(如 InnoDB 表空间文件需确保 ibdata1 一致),否则可能无法直接使用。

MySQL 企业版备份所需的基本权限

所需的最低权限:

  • BACKUP_ADMIN(适用于 8.0.16 及更高版本)和对所有数据库及表的 RELOAD 权限
  • mysql.backup_progress 表的 CREATE、INSERT、UPDATE、DROP 权限
  • mysql.backup_history 表的 CREATE、INSERT、UPDATE、DROP、SELECT、ALTER 权限
  • SUPER 权限:用于启用和禁用日志记录,以及优化锁定机制,以最大程度减少对数据库处理的干扰
  • REPLICATION CLIENT 权限:用于检索备份中存储的二进制日志位置
  • PROCESS 权限:用于处理带有 ALGORITHM=INPLACE 子句的 DDL 语句
  • performance_schema.replication_group_membersSELECT 权限:用于判断服务器实例是否属于组复制(Group Replication)配置
  • 对于 8.0.16 及更高版本,还需要对 performance_schema.variables_infoperformance_schema.log_statusSELECT 权限
授予所需权限

以下脚本设置了 backupuser使用者所需权限:

1
2
3
4
5
6
7
8
CREATE USER 'mysqlbackup'@'localhost' IDENTIFIED BY 'password';
GRANT BACKUP_ADMIN, RELOAD ON *.* TO 'mysqlbackup'@'localhost';
GRANT CREATE, INSERT, DROP, UPDATE ON mysql.backup_progress TO 'mysqlbackup'@'localhost';
GRANT CREATE, INSERT, DROP, UPDATE, SELECT, ALTER ON mysql.backup_history TO 'mysqlbackup'@'loaclhost';
GRANT SUPER, REPLICATION CLIENT, PROCESS ON *.* TO 'mysqlbackup'@'localhost';
GRANT SELECT ON performance_schema, variable_info TO 'mysqlbackup'@'localhost';
GRANT SELECT ON performance_schema.varibale_info TO 'mysqlbackup'@'localhost';
GRANT SELECT ON performance_schema.log_status TO 'mysqlbackup'@'localhost';

使用 mysqldumpmysqlpump 进行逻辑备份

mysqldumpmysqlpump

  • mysqldumpmysqlpump 工具包含在 MySQL 发行版中。
  • 它们用于执行逻辑备份,且适用于任何数据库引擎。
    • 某些功能(如 “热备份”)仅能对 InnoDB 表执行。
    • 默认情况下,对于所有存储引擎,它们均以 “温备份” 方式运行。
  • 可通过 Linux 和 UNIX 系统中的 crontab 或 Windows 系统中的 “任务计划程序” 实现自动化操作。
  • mysqldumpmysqlpump 没有跟踪或报告工具

mysqldump

  • 将表内容导出到文件:

    • 可导出所有数据库、特定数据库或特定表
    • 允许备份本地或远程服务器
    • 与存储引擎无关
    • 以文本格式写入
    • 具有可移植性
    • 是出色的复制 / 迁移策略
    • 适合小型导出,但不适合全量备份
  • 基本用法:

    1
    
    mysqldump --user=username --password=password db_name > backup.file
    

    **存储位置:**对于包含 CREATE TABLEINSERT 语句的 SQL 格式导出文件,服务器会将表内容发送至 mysqldump,再由 mysqldump 将输出写入客户端主机

使用 mysqldump 保证数据的一致性

确保一致性:

  • --master-data 可选参数

    • 备份期间通过 FLUSH TABLES WITH READ LOCK 锁定所有表
    • 在备份文件中以 CHANGE MASTER TO 语句记录二进制日志位置
    • --master-data=2 会将该位置记录为注释
  • 同时使用 --master-data--single-transaction 参数

    • 不锁定表
    • 仅保证 InnoDB 表的一致性
    • 在备份操作开始时获取全局锁,以获取一致的二进制日志位置
  • --lock-all-tables 参数

    • 在整个导出过程中锁定所有表,以此保证一致性
  • --flush-logs 参数 - 启动一个新的二进制日志

--single-transaction 选项通过使用可重复读隔离级别的事务来读取所有 InnoDB 数据,从而实现非阻塞的数据一致性

mysqldump 中用于创建对象的选项
  • --no-create-db

    • 不生成 CREATE DATABASE 语句
  • --no-create-info

    • 不生成 CREATE TABLE 语句
  • --no-data

    • 只创建数据库和表结构,不导出数据
  • --no-tablespaces

    • 告知 MySQL 服务器不要在输出中写入任何 CREATE LOGFILE GROUPCREATE TABLESPACE 语句
  • --quick

    • 从表中逐行检索数据,而不缓冲多行数据
mysqldump 中用于删除对象的选项
  • --add-drop-database
    • 在每一个 CREATE DATABASE语句前 增加一个 DROP DATABASE 语句
  • --add-drop-table
    • 在每一个 CREATE TABLE语句前 增加一个 DROP TABLE 语句
mysqldump 常规选项
  • 存储例程、事件和触发器:

  • --routines

    • 导出所备份数据库中的存储例程(存储过程和存储函数)
  • --events

    • 导出为事件调度器(Event Schedu ler)创建的事件
  • --triggers

    • 导出每个被备份表的触发器
  • 一站式选项(--opt

    • 用于创建高效且完整的备份文件的最常用选项的简写形式
      • 包含 --add-drop-table--add-locks--create-options--disable-keys--extended-insert--lock-tables--quick--set-charset 选项。

MySQL 8.0 将存储例程和调度事件存储在数据字典中,而非像早期版本的 MySQL 服务器那样存储在表中。因此,对 mysql 数据库的备份并不包含存储过程和事件。必须在 mysqldump 中显式指定 --routines--events 选项才能对它们进行备份。

--triggers--opt 选项默认是启用的;可使用 --skip-triggers--skip-opt 来禁用它们。

恢复 mysqldump 备份
  • 使用 mysql 重新加载 mysqldump 备份

    1
    
    mysql --login-path=login-path database < backup_file.sql
    
    • 如果备份文件中不包含指定数据库的 USE 语句,你必须指明数据库名称。
    • 如果你使用–database或–all-databases选项执行mysqldump:
      • 转储文件会包含合适的 USE db_name 语句。
      • 从该转储文件重新加载时,无需指定目标数据库名称。
  • 从一个数据库复制到另一个数据库

    1
    
    mysqldump -uuser -ppassword orig-db | mysql -uuser -ppassword copy-db
    
从一个数据库复制到另一个数据库

可以使用 mysqldump 的输出来恢复表或数据库,以及复制它们。mysql 可以从管道读取数据,因此 mysqldumpmysql 的使用可以组合成一条单一命令,将表从一个数据库复制到另一个数据库。这种管道技术还可用于通过网络将数据库或表复制到另一台服务器。

使用 mysqlimport
  • 如果你使用 --tab 选项调用 mysqldump,它会生成以制表符分隔的数据文件:
    • 一个包含 CREATE TABLE 语句的 .sql 文件
    • 一个包含表数据的 .txt 文本文件
  • 要重新加载表,请按以下步骤操作:
    1. 切换到备份目录。
    2. 使用 mysql 处理 .sql 文件。
    3. 使用 mysqlimport 加载 .txt 文件。
1
2
3
cd backup_dir  
② mysql -uuser -ppassword database < table.sql  
③ mysqlimport -uuser -ppassword database table.txt  
mysqlimport 补充说明

如果将 --tab 选项与 --fields-terminated-by(字段分隔符)、--fields-enclosed-by(字段包围符)等格式控制选项结合使用,需要在 mysqlimport 中指定相同的格式控制选项,这样它才能知道如何解析数据文件。

mysqldump 所需权限

要使用 mysqldump,你必须具备以下权限:

  • 对要备份的表有 SELECT 权限
  • 对要备份的视图有 SHOW VIEW 权限
  • 对要备份的触发器有 TRIGGER 权限
  • LOCK TABLES 权限(除非你使用 --single-transaction 选项)

其他选项可能需要额外权限。例如:

  • 要使用 --flush-logs--master-data 选项,你必须具备 RELOAD 权限。
  • 要使用 --tab 选项生成制表符分隔的输出,你必须具备 FILE 权限。
  • 要使用 --routines 选项备份存储函数和存储过程,你必须具备全局 SELECT 权限。
重新加载转储文件所需的权限

要重新加载转储文件(即恢复备份),你必须具备以下权限:

  • 对每个被转储(备份)的对象,拥有 CREATE 权限
  • 对每个被转储(备份)的表,拥有 INSERT 权限
  • 如果 mysqldump 输出中包含用于更改数据库排序规则以保留字符编码的语句,需对数据库拥有 ALTER 权限

mysqlpump

mysqlpumpmysqldump 非常相似,但有以下增强功能:

  • 通过使用并行线程提取数据,提供比 mysqldump 更好的性能
    • mysqlpump 会将转储过程拆分为多个子任务,然后将这些子任务添加到一个多线程队列中。
    • 之后由若干线程(默认是两个)处理该队列。
  • 能更好地控制在每个线程上转储哪些数据库对象
  • CREATE USER/GRANT 语句的形式转储用户,而非向 mysql 系统数据库中插入记录
  • 支持压缩输出
  • 显示进度指示器
  • 为 InnoDB 表提供更快的辅助索引重新加载(恢复)

补充说明

为 InnoDB 表实现更快的辅助索引重新加载,是通过在插入行之后再添加索引来达成的。

使用 mysqlpump 指定要备份的对象

mysqlpump 工具提供了许多选项,用于指定要备份哪些数据库对象,例如:

  • 备份所有数据库(默认行为)

    1
    
    mysqlpump -uuser -ppassword > full_backup.sql
    
  • 仅备份 employeesworld 数据库

    1
    2
    
    mysqlpump -uuser -ppassword \
    --databases employees world > emp_world_backup.sql
    
  • 备份所有名称以 db. 开头的数据库

    1
    2
    
    mysqlpump -uuser -ppassword \
    --include-databases=db% --result-file=all_db_backup.sql
    
  • 备份所有内容,但排除名为 t1 的表

    1
    2
    
    mysqlpump -uuser -ppassword --exclude-tables=t1 \
    --result-file=partial_backup.sql
    
补充说明

mysqldump 不同,mysqlpump 的默认行为是备份所有数据库。如果执行 mysqlpump 时未指定要包含的模式(数据库),此选项会隐式生效。

默认情况下,mysqlpump 不会备份以下内部数据库:PERFORMANCE_SCHEMAINFORMATION_SCHEMAsysndbinfo。若要备份这些数据库,需通过 --databases--include-databases 选项显式指定它们的名称。

mysqlpump 会以逻辑账户的形式备份用户(使用 CREATE USERGRANT 语句,例如使用 --include-users--users 选项时)。因此,默认情况下,mysql 系统数据库的备份不包含存储用户定义的授权表(如 userdbtables_privcolumns_privprocs_privproxies_priv 表 )。若要备份这些授权表,需指定 mysql 数据库及对应的表名。

使用 mysqlpump 进行并行处理

你可以使用 --default-parallelism--parallel-schemas 选项配置 mysqlpump 所用的线程数量。例如:

  • 使用 4 个线程备份所有数据库

    1
    2
    
    mysqlpump --user --password \
    --default-parallelism=4 > full_backup.sql
    
  • 创建两个队列:一个用于处理 db1db2,另一个用于处理 db3db4。在第一个队列使用 5 个线程,第二个队列使用 2 个线程,对所有其他模式(数据库)的默认队列使用 3 个线程:

    1
    2
    3
    4
    
    mysqlpump --user --password \
    --parallel-schemas=5:db1,db2 \
    --parallel-schemas=2:db3,db4 \
    --default-parallelism=3 > full_backup.sql
    
注意事项

--default-parallelism 选项的默认线程数量是 2。

其他物理备份方法

InnoDB 物理备份:概述

  • 物理(二进制)备份操作会生成完整的 InnoDB 备份。
    • 包含所有 InnoDB 表的备份
    • 生成所有表空间文件的精确副本
  • 所有数据库中的 InnoDB 表必须一起进行备份。
    • InnoDB 会在系统表空间中集中维护一些信息。
    • 其他 InnoDB 表空间包含的表数据,依赖于系统表空间中 InnoDB 的数据字典。
  • 在文件复制期间,必须关闭 MySQL 服务器,以确保所有表空间的一致性。
    • 这是一种 “冷备份”

物理备份的可移植性

  • 二进制可移植性
    • 二进制数据库文件可从一台 MySQL 服务器复制到另一台。
    • 当在一台机器上制作的物理备份要用于架构不同的另一台机器时,二进制可移植性很有用。
      • 例如,你可通过复制二进制数据库文件,将数据库从一台 MySQL 服务器复制到另一台。
  • 存储引擎可移植性
    • InnoDB:
      • 数据库的所有表空间和日志文件可直接复制。
        • 示例:你可将表空间文件从一台机器上的 MySQL 服务器直接复制到另一台机器的 MySQL 服务器,第二台服务器可访问该表空间。
        • 源系统和目标系统上的数据库目录名称必须相同。
    • MyISAM 和 Archive:
      • 单个表的所有文件可直接复制,且元数据可从 .sdi 文件导入。
Windows 系统的文件名兼容性
  • MySQL 服务器在 Windows 系统上会内部存储小写的数据库和表名称。

  • 对于区分大小写的文件系统,使用选项文件语句:

    1
    
    lower_case_table_names=1
    
  • 在 MySQL 8.0 中,禁止使用与服务器初始化时不同的 lower_case_table_names 设置启动服务器。你必须在初始化数据目录前设置该选项,之后无法更改

InnoDB 物理备份流程

  1. 执行服务器的慢速(干净)关闭。
    • 需要设置 innodb_fast_shutdown=0(默认值为 1 )
    • 允许在关闭前完成额外的 InnoDB 刷新操作
    • 关闭耗时更长,但启动会更快
  2. 复制所有 InnoDB 数据、日志和配置文件:
    • 数据文件:ibdata*.ibd
    • 重做日志文件:ib_logfile*
    • 回滚表空间文件:undo_*
    • 服务器应用的所有配置文件,如 my.cnf
  3. 重启服务器

从 InnoDB 物理备份中恢复

  • 要使用物理备份恢复 InnoDB 表,需执行以下操作:
    1. 停止服务器
    2. 替换备份过程中复制的所有组件
    3. 重启服务器
  • InnoDB 将表元数据存储在共享表空间中。必须:
    • 将共享表空间和每个表的表空间文件作为一个组进行复制
      • 这会替换目标系统表空间。
    • 复制相应的重做日志文件和回滚表空间文件

使用可传输表空间进行备份

当使用可传输表空间备份 InnoDB 表时:

  • 可以执行部分备份
    • 按表备份,或备份属于某个业务功能的多张表
  • 无需在另一台服务器加载这些表
    • 如果想读取备份副本用于分析或其他用途,需确保在目标服务器上 InnoDB 设为只读。
    • 还必须确保源服务器和只读服务器的 InnoDB 页大小和行格式匹配。
    • 不得在另一台服务器中使用这些表进行修改操作。
    • 如果修改了这些表,备份将不再具备完整性。
  • 可以按表或按业务功能恢复部分备份

可传输表空间:将表复制到另一个实例

  1. 在源实例上,执行 FLUSH TABLES...FOR EXPORT 来让表进入静默状态并创建 .cfg 元数据文件:

    1
    
    mysql> FLUSH TABLES db.table FOR EXPORT;
    
    • .cfg 文件会在 InnoDB 数据目录中创建。
  2. .ibd.cfg 文件从源实例复制到目标实例。

  3. 在源实例上,执行 UNLOCK TABLES 来释放锁。

  4. 在目标实例上,创建一个与源实例上表结构相同的表。

  5. 在目标实例上,丢弃现有表空间:

    1
    
    mysql> ALTER TABLE db.table DISCARD TABLESPACE;
    
  6. 在目标实例上,导入表空间:

    1
    
    mysql> ALTER TABLE db.table IMPORT TABLESPACE;
    
补充说明

如果你复制的是 InnoDB 分区表,每个分区会有单独的表空间(.ibd 文件)和 .cfg 文件。你必须在目标实例上丢弃每个分区的表空间,复制所有 .ibd.cfg 文件,并导入所有表空间

物理 MyISAM 和 ARCHIVE 备份

  • 物理 MyISAM 和 ARCHIVE 备份包含 MySQL 用于表示表的文件。
    • 对于 MyISAM 表,这些文件是.sdi、.MYD 和.MYI 文件。
    • 对于 ARCHIVE 表,这些文件是.sdi 和.ARZ 文件。
  • 在复制操作期间,其他程序(包括服务器)不得修改正在复制的文件。
    • 为避免服务器交互问题,在复制操作期间锁定并刷新表,或者停止服务器
注意

在 Linux 系统上,锁定表而非关闭服务器这种方式是可行的。在 Windows 系统上,文件锁定行为使得对于被服务器锁定的表,可能无法复制其表文件。在这种情况下,复制表文件前请停止服务器

物理 MyISAM 和 ARCHIVE 备份流程

  1. 当服务器正在运行时,锁定要复制的表:

    1
    2
    
    mysql> USE world_myisam
    mysql> FLUSH TABLES city WITH READ LOCK;
    
  2. 执行文件系统复制:

    1
    
    # cp datadir/world_myisam/city.* /backupdir/
    
  3. 启动一个新的二进制日志文件

    1
    
    mysql> FLUSH LOGS;
    
    • 新的二进制日志文件包含备份之后所有更改数据的语句(以及任何后续的二进制日志文件 )。
  4. 文件系统复制完成后,释放锁

1
2
mysql> USE world_myisam
mysql> FLUSH TABLES city WITH READ LOCK;

如果你不想刷新日志,可以使用 SHOW MASTER STATUS 命令记录当前日志坐标,该命令会返回当前二进制日志文件名和位置。

从物理 MyISAM 或 Archive 备份中恢复

要从物理备份中恢复 MyISAM 或 ARCHIVE 表,请按以下步骤操作:

  1. 如果存在现有表,则删除该表

  2. 将备份的数据文件复制到相应的数据库目录中

  3. 将备份的.sdi 文件复制到服务器主机上的临时目录

  4. 运行 IMPORT TABLE 语句,指定.sdi 文件的路径,以将表加载到数据库中

    1
    
    mysql> IMPORT TABLE FROM 'sdi_file_path';
    

请注意,.sdi 文件包含模式名称(即数据库名 )和表名。如果要将其恢复到不同的数据库或表名,你可能需要编辑该文件。 IMPORT TABLE 语句会将数据字典加载到 MySQL 服务器中

LVM 快照

逻辑卷管理器(LVM):

  • 管理物理介质上的存储区域,比磁盘分区更具灵活性
    • 物理卷
    • 逻辑卷
    • 卷组
  • 使用一种称为 “写时复制(copy - on - write)” 的机制来创建快照
    • 快照的表现就好像它是创建快照时文件系统的即时副本。
    • 在内部,快照会记录创建快照后发生变化的磁盘块的原始版本。
    • 当你访问快照时,LVM 会从文件系统返回未更改的块,或者返回已更改块的原始副本。
写时复制快照

当你从新创建的快照中读取文件时,LVM 会从原始卷中读取这些文件。当原始卷发生更改时,LVM 会在更改原始卷上的数据之前,立即将数据复制到快照中,这样,自创建快照以来发生更改的任何数据都以其原始形式存储在快照中。其结果是,当你从快照中读取文件时,它会提供创建快照瞬间存在的数据版本。

因为快照几乎是即时创建的,你可以认为在创建快照期间,底层数据不会发生变化。这使得快照对于备份 InnoDB 数据库非常有用,如果你所有文件都存储在一个可以作为单个快照进行快照的逻辑卷中,则无需关闭服务器。如果文件分布在多个逻辑卷上,则必须关闭 MySQL 数据库服务器,并快照所有包含 MySQL 数据文件的卷,然后再重新启动服务器。

LVM 备份流程

  • 在以下情况时,使用 LVM 快照执行物理备份:

    • 主机支持 LVM
      • 示例:Linux 支持 LVM2。
    • 包含 MySQL 数据目录的文件系统位于逻辑卷上
  • 备份流程:

    1. 如有需要,关闭 MySQL 服务器或锁定表。

      • 如果 InnoDB 文件分布在多个卷上,或者你想要进行一致性备份,则需要关闭服务器。

      • 如果你要备份非 InnoDB 表,可以使用 FLUSH TABLES WITH READ LOCK

    2. 为包含 MySQL 数据目录的逻辑卷创建快照。

    3. 如有需要,重启 MySQL 服务器或解锁表。

    4. 从快照执行物理备份。

    5. 删除快照。

LVM 命令示例
  • /dev/VG_MYSQL/lv_datadir 逻辑卷创建名为 lv_datadirbackup、预留大小为 2GB 的快照。

    1
    
    lvcreate -s -n lv_datadirbackup -L 2G /dev/VG_MYSQL/lv_datadir
    
  • 挂载快照并使用 tar 备份文件。

    1
    2
    3
    4
    
    mkdir /mnt/snap
    mount /dev/VG_MYSQL/lv_datadirbackup /mnt/snap
    tar -cvzf backup.tar /mnt/snap
    umount /mnt/snap
    
  • 从卷 VG_MYSQL 中删除名为 lv_datadirbackup 的快照。

    1
    
    lvremove VG_MYSQL/lv_datadirbackup
    

备份日志和状态文件

  • 二进制日志文件
  • 服务器使用的选项文件(my.cnf 和 my.ini 文件 )
  • 复制相关文件:
  • 复制从服务器数据文件
    • SQL_LOAD - *
  • MySQL 二进制文件和库
  • 策略:
    • 静态文件:在服务器运行时,使用常规系统工具进行备份
    • 动态文件:在服务器停止时,使用常规系统工具进行备份
二进制日志文件

二进制日志存储备份完成后所做的更新操作。

服务器使用的选项文件(my.cnf 和 my.ini 文件 )

这些文件包含发生崩溃后必须恢复的配置信息。

复制相关文件

复制从服务器会创建 master.info 文件,其中包含连接到主服务器所需的信息;还会创建 relay-log.info 文件,用于指示处理中继日志的当前进度。

复制从服务器数据文件

复制从服务器会创建用于处理 LOAD DATA INFILE 语句的数据文件。这些文件位于由 slave_load_tmpdir 系统变量命名的目录中,你可以通过 –slave-load-tmpdir 选项设置该变量。如果未设置 slave_load_tmpdir,则使用 tmpdir 系统变量的值。为保护复制从服务器数据,请备份以 SQL_LOAD - 开头的文件。

基于复制的备份

利用复制辅助备份

复制到另一台服务器,以避免备份带来的开销。

  • 使用从服务器进行备份,而非从主服务器进行备份。
  • 通过使用从服务器进行备份,可实现:
    • 使用主服务器的应用程序不会因表锁定或刷新操作而变慢
    • 备份过程不会给主服务器增加处理负载
    • 备份文件无需在主服务器上占用额外的硬盘空间或进行额外处理

从复制从服务器进行备份

  1. 停止从服务器以进行备份:

    • 1
      
        STOP SLAVE SQL_THREAD
      
      • 如果你要进行逻辑备份,需刷新表。
    • 或者,停止服务器以进行物理文件复制。

  2. 备份从服务器的数据库:

    • 使用 mysqldumpmysqlbackup 备份正在运行的服务器的内容。
    • 如果你停止了服务器,使用系统工具复制物理文件。
      • 在停止从服务器之前,确保 slave_open_temp_tables 状态变量的值为 0 。
  3. 启动从服务器:

    • 如果服务器已停止,则启动服务器。
    • START SLAVE SQL_THREAD

如果从服务器因存在已打开、用于尚未执行的更新操作的临时表而停止,当从服务器重启时,那些更新操作所需的临时表将不再可用。

从多个源备份到单个服务器

  • 多源复制可用于:
    • 将多个服务器备份到单个服务器
    • 合并表分片
    • 将来自多个服务器的数据整合到单个服务器
  • 从服务器会为每个向其发送事务的主服务器创建一个复制通道。
    • 使用 CHANGE MASTER TO... FOR CHANNEL channelname 语法:
1
2
3
CHANGE MASTER TO ...
  MASTER_LOG_FILE='binlog.000006',
  MASTER_LOG_POS=143 FOR CHANNEL 'shard-1';
  • 可同时复制所有通道,或启动 / 停止单个通道:
1
START SLAVE IO_THREAD FOR CHANNEL 'shard-1';

如果在备份策略中要整合多个分片,可以仅在一天中的特定时段启用从服务器的 IO 线程,以避免在高峰时段给分片主服务器带来过大压力。但要注意,主服务器上所有相关事件都必须完成复制,而这在从服务器上可能需要花费相当长的时间。

使用二进制文件恢复数据库

处理二进制日志内容

  1. 确定备份完成后写入了哪些日志。

  2. 使用 mysqlbinlog 转换日志内容:mysqlbinlog binlog.000050 binlog.000051 binlog.000052 | mysql

    • 用一条命令处理所有二进制日志。
  3. 删除服务器主机上不再有用且占用空间的二进制日志:

    • 使用 mysqldump 创建备份时,可使用 --delete-master-logs 选项。

    • 执行 PURGE BINARY LOGS来删除不再有用的文件或事件。

      • 不要删除尚未复制或备份的日志文件或事件。 PURGE BINARY LOGS TO 'binlog.000048';

在恢复二进制备份文件或重新加载文本备份文件后,通过重新处理服务器二进制日志中记录的数据更改来完成恢复操作。为此,你必须确定备份完成后写入了哪些日志。然后,需要使用 mysqlbinlog 程序将这些二进制日志的内容转换为文本 SQL 语句,以便用 mysql 处理生成的语句。

选择性二进制日志处理

  • 恢复部分二进制日志:

    • 1
      
        --start-position
      
      • 指定要提取的第一条日志语句的日志位置
    • 1
      
        --stop-position
      
      • 指定停止提取日志内容的日志位置
1
mysqlbinlog --start-position=23456 binlog.000004 | mysql
  • 使用 --database 仅选择那些在选定特定默认数据库后发生的事件:
1
mysqlbinlog --database=sales binlog.000043 | mysql
  • 使用 --rewrite-db 恢复到不同的数据库:
1
mysqlbinlog --rewrite-db='sales->sales_03' binlog.000082 | mysql

mysqlbinlog 还支持 --start-datetime--stop-datetime 选项。这些选项使用二进制日志中记录的事件时间戳(事件开始时间 )。由于二进制日志中的事件是根据提交顺序排序的,事件时间戳可能不是按排序顺序排列的。建议检查二进制日志以获取位置,而不是使用日期时间选项。

时间点恢复

你可能希望仅应用二进制日志中某个时间点之前或之后的部分内容:

  • 之前:
    • 如果你知道有人意外执行了有破坏性的语句,且你想将更改恢复到该时间点之前的状态。
    • 如果你要将更改恢复到某一特定日期的最后时刻,并同步到分析服务器。
  • 之后:
    • 如果你在全量备份之后,或者在已备份的、已刷新的二进制日志之后,使用二进制日志来应用更改,那么你可以应用该时间点之后的日志。

配置 MySQL 以进行恢复操作

  • MySQL 客户端程序可能因缓冲区溢出而失败。

    • 在使用 mysqldump 进行逻辑备份期间
    • 在使用 mysql 进行转储文件恢复期间
    • 在使用 mysqlbinlogmysql 进行二进制日志恢复操作期间
  • 配置以下变量:

    • 1
      
        --max-allowed-packet=256M
      
      • 默认值:64M
      • 确保在备份和恢复操作期间该值足够大,以免超过 MySQL 的数据包大小限制
0 次浏览