#### 17.4.1.3 以只读方式备份源或副本

通过获取全局读锁并操作[`只读`](server-system-variables.html#sysvar_read_only)更改要备份的服务器的只读状态的系统变量：

1.  将服务器设为只读，以便它只处理检索并阻止更新。

2.  执行备份。

3.  将服务器更改回其正常的读/写状态。

笔记

本节中的说明将要备份的服务器置于对从服务器获取数据的备份方法安全的状态，例如[**mysql转储**](mysqldump.html)（看[第 4.5.4 节，“mysqldump - 数据库备份程序”](mysqldump.html)）。您不应尝试使用这些说明通过直接复制文件来进行二进制备份，因为服务器可能仍将修改后的数据缓存在内存中并且未刷新到磁盘。

以下说明描述了如何对源和副本执行此操作。对于此处讨论的两种方案，假设您具有以下复制设置：

-   源服务器 S1

-   以 S1 作为其源的副本服务器 R1

-   连接到 S1 的客户端 C1

-   连接到 R1 的客户端 C2

    在任何一种情况下，获取全局读锁并操作[`只读`](server-system-variables.html#sysvar_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 为只读时，执行备份。例如，您可以使用[**mysql转储**](mysqldump.html).

    在 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 为只读时，执行备份。例如，您可以使用[**mysql转储**](mysqldump.html).

    在 R1 上的备份操作完成后，通过执行以下语句将 R1 恢复到其正常操作状态：


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

在 replca 恢复正常运行后，它会再次通过从源的二进制日志中赶上任何未完成的更新来同步到源。
