Skip to main content

1.使用复制进行备份

要将复制用作备份解决方案,请将数据从源复制到副本,然后备份副本。副本可以暂停和关闭,而不会影响源的运行操作,因此可以生成 “实时”数据的有效快照,否则需要关闭源。

备份数据库的方式取决于数据库的大小以及仅备份数据,还是备份数据和副本状态,以便在发生故障时可以重建副本。因此有两种选择:

  • 如果使用复制作为解决方案来备份源上的数据,并且数据库的大小不太大,则mysqldump工具可能适合。
  • 对于较大的数据库,mysqldump不切实际或效率低下,可以改为备份原始数据文件。使用原始数据文件选项还意味着可以备份二进制日志和中继日志,以便在副本发生故障时重新创建副本。

另一种可用于源服务器或副本服务器的备份策略是将服务器置于只读状态。备份是针对只读服务器执行的,然后将其更改回其通常的读/写操作状态。

使用 mysqldump 备份副本

使用 mysqldump 创建数据库的副本能够以某种格式捕获数据库中的所有数据,该格式使信息能够导入到 MySQL 服务器的另一个实例中。 由于信息的格式是 SQL 语句,因此在紧急情况下需要访问数据时,可以轻松地将文件分发并应用到正在运行的服务器。 但是,如果数据集的大小非常大,mysqldump 可能不切实际。

使用 mysqldump 时,应该在开始转储过程之前停止副本上的复制,以确保转储包含一组一致的数据:

  1. 停止副本处理请求。 可以使用 mysqladmin 在副本上完全停止复制:

    $> mysqladmin stop-replica

    或者,可以仅停止复制 SQL 线程来暂停事件执行:

    $> mysql -e 'STOP REPLICA SQL_THREAD;'

    这使得副本能够继续从源的二进制日志接收数据更改事件,并使用复制接收器线程将它们存储在中继日志中,但会阻止副本执行这些事件并更改其数据。 在繁忙的复制环境中,允许复制接收器线程在备份期间运行可能会在重新启动复制应用程序线程时加快追赶过程。

  2. 运行 mysqldump 转储数据库。 可以转储所有数据库或选择要转储的数据库。 例如,要转储所有数据库:

    $> mysqldump --all-databases > fulldb.dump 
  3. 转储完成后,再次开始复制:

    $> mysqladmin start-replica

在前面的示例中,可以将登录凭据(用户名、密码)添加到命令中,并将该过程捆绑到可以每天自动运行的脚本中。

如果使用此方法,请确保监视复制过程,以确保运行备份所花费的时间不会影响副本跟上源事件的能力。 如果副本无法跟上,可能需要添加另一个副本并分发备份过程。

从副本备份原始数据

为了保证复制文件的完整性,应在副本服务器关闭时备份 MySQL 副本上的原始数据文件。 如果MySQL服务器仍在运行,后台任务可能仍在更新数据库文件,特别是那些涉及具有后台进程的存储引擎(例如InnoDB)的任务。 对于 InnoDB,这些问题应该在崩溃恢复期间得到解决,但由于副本服务器可以在备份过程中关闭而不影响源的执行,因此利用此功能是有意义的。

关闭服务器并备份文件:

  1. 关闭副本 MySQL 服务器:

    $> mysqladmin shutdown
  2. 复制数据文件。 可以使用任何合适的复制或存档实用程序,包括 cp、tar 或 WinZip。 例如,假设数据目录位于当前目录下,则可以按如下方式归档整个目录:

    $> tar cf /tmp/dbbackup.tar ./data
  3. 再次启动 MySQL 服务器,在Unix下:

    $> mysqld_safe &

    在Windows下:

    C:\> "C:\Program Files\MySQL\MySQL Server 8.3\bin\mysqld"

通常,应该备份 MySQL 副本服务器的整个数据目录。 如果希望能够恢复数据并作为副本进行操作(例如,在副本发生故障时),除了数据之外,还需要拥有副本的连接元数据存储库和应用程序元数据存储库,以及 中继日志文件。 恢复副本数据后需要这些项目来恢复复制。 假设表已用于副本的连接元数据存储库和应用程序元数据存储库(这是 MySQL 8.3 中的默认设置),这些表将与数据目录一起备份 。 如果文件已用于存储库(已弃用),则必须单独备份它们。 如果中继日志文件放置在与数据目录不同的位置,则必须单独备份它们。

如果丢失了中继日志,但仍然拥有relay-log.info 文件,可以检查它以确定复制SQL 线程在源二进制日志中执行了多远。 然后,可以将 CHANGE REPLICATION SOURCE TO 与 SOURCE_LOG_FILE 和 SOURCE_LOG_POS 选项一起使用,告诉副本从该点重新读取二进制日志。 这要求二进制日志仍然存在于源服务器上。

如果副本正在复制 LOAD DATA 语句,还应该备份副本用于此目的的目录中存在的任何 SQL_LOAD-* 文件。 副本需要这些文件来恢复任何中断的 LOAD DATA 操作的复制。 该目录的位置是系统变量replica_load_tmpdir的值。 如果服务器不是使用该变量集启动的,则目录位置是 tmpdir 系统变量的值。

通过将源或副本设置为只读来备份源或副本

通过获取全局读锁并操作 read_only 系统变量来更改要备份的服务器的只读状态,可以在复制设置中备份源服务器或副本服务器:

  1. 将服务器设置为只读,以便它仅处理检索并阻止更新。
  2. 执行备份。
  3. 将服务器更改回正常的读/写状态。

注意:

本节中的说明将要备份的服务器置于对于从服务器获取数据的备份方法(例如 mysqldump)安全的状态)。 不应尝试使用这些指令通过直接复制文件来进行二进制备份,因为服务器可能仍将修改后的数据缓存在内存中而不刷新到磁盘。

以下说明描述了如何对源和副本执行此操作。 对于此处讨论的两种场景,假设具有以下复制设置:

  • 源服务器S1
  • 以 S1 作为源的副本服务器 R1
  • 客户端 C1 连接到 S1
  • 连接到 R1 的客户端 C2

在任一情况下,获取全局读锁和操作 read_only 变量的语句都在要备份的服务器上执行,并且不会传播到该服务器的任何副本。

场景 1:使用只读源进行备份

通过在源 S1 上执行以下语句将其置于只读状态:

mysql> FLUSH TABLES WITH READ LOCK;
mysql> SET GLOBAL read_only = ON;

当 S1 处于只读状态时,以下属性成立:

  • C1 发送到 S1 的更新请求会被阻止,因为服务器处于只读模式。
  • C1向S1发送查询结果请求成功。
  • 在 S1 上进行备份是安全的。

在 R1 上进行备份并不安全。 该服务器仍在运行,并且可能正在处理来自客户端 C2 的二进制日志或更新请求。

当 S1 为只读时,执行备份。 例如,可以使用 mysqldump。

S1 上的备份操作完成后,通过执行以下语句将 S1 恢复到正常运行状态:

mysql> SET GLOBAL read_only = OFF;
mysql> UNLOCK TABLES;

尽管在 S1 上执行备份是安全的(就备份而言),但它对于性能而言并不是最佳的,因为 S1 的客户端被阻止执行更新。

此策略适用于备份复制设置中的源,但也可用于非复制设置中的单个服务器。

场景 2:使用只读副本进行备份

通过在副本 R1 上执行以下语句将副本 R1 置于只读状态:

mysql> FLUSH TABLES WITH READ LOCK;
mysql> SET GLOBAL read_only = ON;
  • 当 R1 处于只读状态时,以下属性成立:
  • 源 S1 继续运行,因此在源上进行备份并不安全。

副本 R1 已停止,因此在副本 R1 上进行备份是安全的。

这些属性为流行的备份场景提供了基础:让一个副本忙于执行备份一段时间并不是问题,因为它不会影响整个网络,并且系统在备份期间仍在运行。 特别是,客户端仍然可以在源服务器上执行更新,而不会受到副本上备份活动的影响。

当 R1 为只读时,执行备份。 例如,可以使用 mysqldump。

R1 上的备份操作完成后,通过执行以下语句将 R1 恢复到正常运行状态:

mysql> SET GLOBAL read_only = OFF;
mysql> UNLOCK TABLES;

副本恢复正常操作后,它会通过捕获源二进制日志中任何未完成的更新来再次同步到源。