#### 17.2.4.2 复制元数据存储库

副本服务器创建两个复制元数据存储库，连接元数据存储库和应用程序元数据存储库。复制元数据存储库在副本服务器关闭后仍然存在。如果正在使用基于二进制日志文件位置的复制，则当副本重新启动时，它会读取两个存储库以确定它之前从源读取二进制日志和处理自己的中继日志的进度。如果正在使用基于 GTID 的复制，则副本不会为此目的使用复制元数据存储库，但它们包含的其他元数据确实需要它们。

-   复制品的*连接元数据存储库*包含复制 I/O（接收器）线程需要连接到复制源服务器并从源的二进制日志中检索事务的信息。此存储库中的元数据包括连接配置、复制用户帐户详细信息、连接的 SSL 设置以及复制接收器线程当前从源的二进制日志中读取的文件名和位置。

-   复制品的*应用程序元数据存储库*包含复制 SQL（应用程序）线程需要从副本的中继日志读取和应用事务的信息。此存储库中的元数据包括复制应用程序线程在中继日志中执行事务的文件名和位置，以及源二进制日志中的等效位置。它还包括应用事务过程的元数据，例如工作线程的数量和`PRIVILEGE_CHECKS_USER`占渠道。

    连接元数据存储库被写入`slave_master_info`表中的`mysql`系统模式，并且应用程序元数据存储库被写入`slave_relay_log_info`表中的`mysql`系统架构。如果出现警告消息，则会发出[**mysqld**](mysqld.html)无法初始化复制元数据存储库的表，但允许副本继续启动。当从不支持对存储库使用表的 MySQL 版本升级到支持它们的版本时，最有可能发生这种情况。

重要的

1.  不要尝试更新或插入行`mysql.slave_master_info`要么`mysql.slave_relay_log_info`手动表。这样做会导致未定义的行为，并且不受支持。执行任何需要在其中一个或两个上写锁的语句`slave_master_info`和`slave_relay_log_info`复制正在进行时不允许使用表（尽管任何时候都允许只执行读取的语句）。

2.  连接元数据存储库表的访问权限`mysql.slave_master_info`应该仅限于数据库管理员，因为它包含用于连接到源的复制用户帐户名和密码。使用受限访问模式来保护包含此表的数据库备份。从 MySQL 8.0.21 开始，您可以从连接元数据存储库中清除复制用户帐户凭据，而是始终使用[`开始复制`](start-replica.html)声明或[`开始 GROUP_REPLICATION`](start-group-replication.html)启动复制通道的语句。这种方法意味着复制通道总是需要操作员干预才能重新启动，但帐户名和密码不会记录在复制元数据存储库中。

[`重置副本`](reset-replica.html)清除复制元数据存储库中的数据，复制连接参数除外（取决于 MySQL 服务器版本）。有关详细信息，请参阅说明[`重置副本`](reset-replica.html).

从 MySQL 8.0.27 开始，您可以设置`GTID_ONLY`上的选项[`将复制源更改为`](change-replication-source-to.html)用于停止复制通道在复制元数据存储库中保留文件名和文件位置的语句。这避免了在基于 GTID 的复制实际上不需要它们的情况下对表进行写入和读取。随着`GTID_ONLY`设置时，连接元数据存储库和应用程序元数据存储库不会在副本排队和应用事务中的事件时更新，或者当复制线程停止和启动时。文件位置在内存中进行跟踪，并且可以使用[`显示副本状态`](show-replica-status.html)如果需要，请声明。复制元数据存储库仅在以下情况下同步：

-   当一个[`将复制源更改为`](change-replication-source-to.html)发表声明。

-   当一个[`重置副本`](reset-replica.html)发表声明。`全部重置副本`删除而不是更新存储库，因此它们是隐式同步的。

-   初始化复制通道时。

-   如果复制元数据存储库从文件移动到表。

    在 MySQL 8.0 之前，要将复制元数据存储库创建为表，需要指定[`master_info_repository=表`](replication-options-replica.html#sysvar_master_info_repository)和[`relay_log_info_repository=表`](replication-options-replica.html#sysvar_relay_log_info_repository)在服务器启动时。否则，存储库将创建为名为的数据目录中的文件`主信息`和`中继日志信息`，或由指定的替代名称和位置[`--主信息文件`](replication-options-replica.html#option_mysqld_master-info-file)选项和[`中继日志信息文件`](replication-options-replica.html#sysvar_relay_log_info_file)系统变量。从 MySQL 8.0 开始，将复制元数据存储库创建为表是默认设置，并且不推荐使用所有这些系统变量。

    这`mysql.slave_master_info`和`mysql.slave_relay_log_info`表是使用[`InnoDB`](innodb-storage-engine.html)事务存储引擎。对应用程序元数据存储库表的更新与事务一起提交，这意味着该存储库中记录的副本的进度信息始终与已应用于数据库的内容一致，即使在服务器意外停机的情况下也是如此。有关对意外停止最具弹性的副本上的设置组合的信息，请参阅[第 17.4.2 节，“处理副本的意外停止”](replication-solutions-unexpected-replica-halt.html).

    当您备份副本的数据或传输其数据的快照以创建新副本时，请确保包含`mysql.slave_master_info`和`mysql.slave_relay_log_info`包含复制元数据存储库的表。对于克隆操作，请注意，当复制元数据存储库被创建为表时，它们会在克隆操作期间被复制到接收者，但当它们被创建为文件时，它们不会被复制。当使用基于二进制日志文件位置的复制时，需要复制元数据存储库在重新启动恢复、复制或克隆的副本后恢复复制。如果您没有中继日志文件，但仍有应用程序元数据存储库，则可以检查它以确定复制 SQL 线程在源的二进制日志中执行了多长时间。然后你可以使用一个[`将复制源更改为`](change-replication-source-to.html)语句（来自 MySQL 8.0.23）或[`将主更改为`](change-master-to.html)语句（在 MySQL 8.0.23 之前）与`SOURCE_LOG_FILE`\|`MASTER_LOG_FILE`和`SOURCE_LOG_POS`\|`MASTER_LOG_POS`告诉副本从该点重新读取源中的二进制日志的选项（前提是源上仍然存在所需的二进制日志）。

    另一个存储库，即应用程序工作人员元数据存储库，主要是为内部使用而创建的，它保存有关多线程副本上工作线程的状态信息。应用程序工作人员元数据存储库包括中继日志文件的名称和位置以及每个工作线程的源二进制日志文件。如果将应用程序元数据存储库创建为表（这是默认设置），则应用程序工作程序元数据存储库将写入`mysql.slave_worker_info`桌子。如果将应用程序元数据存储库写入文件，则应用程序工作器元数据存储库将写入`worker-relay-log.info`文件。对于外部使用，工作线程的状态信息显示在性能模式中[`replication_applier_status_by_worker`](performance-schema-replication-applier-status-by-worker-table.html)桌子。

    复制元数据存储库最初包含的信息类似于[`显示副本状态`](show-replica-status.html)声明，这是在讨论[第 13.4.2 节，“用于控制副本服务器的 SQL 语句”](replication-statements-replica.html).此后，更多信息已添加到复制元数据存储库中，[`显示副本状态`](show-replica-status.html)陈述。

    对于连接元数据存储库，下表显示了`mysql.slave_master_info`表，显示的列[`显示副本状态`](show-replica-status.html)，以及已弃用的行`主信息`文件。

| `slave_master_info`表列 | `显示副本状态`柱子 | `主信息`文件行 | 描述 |
| --------------------- | ---------- | -------- | --- |
| `Number_of_lines` | [没有] | 1 | 表中的列数（或文件中的行数） |
| `Master_log_name` | `Source_Log_File` | 2 | 当前正在从源读取的二进制日志的名称 |
| `Master_log_pos` | `Read_Source_Log_Pos` | 3 | 已从源读取的二进制日志中的当前位置 |
| `主持人` | `源主机` | 4 | 复制源服务器的主机名 |
| `用户名` | `Source_User` | 5 | 用于连接到源的复制用户帐户名 |
| `用户密码` | 密码（未显示[`显示副本状态`](show-replica-status.html)) | 6 | 用于连接到源的复制用户帐户密码 |
| `港口` | `源端口` | 7 | 用于连接复制源服务器的网络端口 |
| `连接重试` | `Connect_Retry` | 8 | 副本在尝试重新连接到源之前等待的时间段（以秒为单位） |
| `已启用_ssl` | `Source_SSL_Allowed` | 9 | 副本是否支持 SSL 连接 |
| `Ssl_ca` | `Source_SSL_CA_File` | 10 | 用于证书颁发机构 (CA) 证书的文件 |
| `Ssl_capath` | `Source_SSL_CA_Path` | 11 | 证书颁发机构 (CA) 证书的路径 |
| `Ssl_cert` | `Source_SSL_Cert` | 12 | SSL 证书文件的名称 |
| `Ssl_cipher` | `Source_SSL_Cipher` | 13 | SSL 连接握手中使用的可能密码列表 |
| `Ssl_key` | `Source_SSL_Key` | 14 | SSL 密钥文件的名称 |
| `Ssl_verify_server_cert` | `Source_SSL_Verify_Server_Cert` | 15 | 是否验证服务器证书 |
| `心跳` | [没有] | 16 | 复制心跳之间的间隔，以秒为单位 |
| `绑定` | `Source_Bind` | 17 | 应使用副本的哪个网络接口连接到源 |
| `Ignored_server_ids` | `Replicate_Ignore_Server_Ids` | 18 | 要忽略的服务器 ID 列表。请注意，对于`Ignored_server_ids`服务器 ID 列表前面是要忽略的服务器 ID 总数。 |
| `用户界面` | `源_UUID` | 19 | 源的唯一 ID |
| `重试次数` | `Source_Retry_Count` | 20 | 允许的最大重新连接尝试次数 |
| `Ssl_crl` | [没有] | 21 | SSL 证书吊销列表文件的路径 |
| `Ssl_crlpath` | [没有] | 22 | 包含 SSL 证书吊销列表文件的目录的路径 |
| `Enabled_auto_position` | `自动定位` | 23 | 是否使用 GTID 自动定位 |
| `频道名称` | `频道名称` | 24 | 复制通道的名称 |
| `Tls_version` | `Source_TLS_Version` | 25 | 源上的 TLS 版本 |
| `Public_key_path` | `Source_public_key_path` | 26 | RSA 公钥文件的名称 |
| `获取_public_key` | `获取_source_public_key` | 27 | 是否从源请求 RSA 公钥 |
| `网络命名空间` | `网络命名空间` | 28 | 网络命名空间 |
| `Master_compression_algorithm` | [没有] | 29 | 连接到源的允许的压缩算法 |
| `Master_zstd_compression_level` | [没有] | 30 | `zstd`压缩级别 |
| `Tls_ciphersuites` | [没有] | 31 | TLSv1.3 允许的密码套件 |
| `Source_connection_auto_failover` | [没有] | 32 | 是否开启异步连接故障转移机制 |
| `Gtid_only` | [没有] | 33 | 频道是否仅使用 GTID 且不保留仓位 |

对于应用程序元数据存储库，下表显示了应用程序中的列之间的对应关系`mysql.slave_relay_log_info`表，显示的列[`显示副本状态`](show-replica-status.html)，以及已弃用的行`中继日志信息`文件。

| `slave_relay_log_info`表列 | `显示副本状态`柱子 | 输入`中继日志信息`文件 | 描述 |
| ------------------------ | ---------- | ------------ | --- |
| `Number_of_lines` | [没有] | 1 | 表格中的列数或文件中的行数 |
| `中继日志名称` | `Relay_Log_File` | 2 | 当前中继日志文件的名称 |
| `中继日志位置` | `Relay_Log_Pos` | 3 | 中继日志文件中的当前位置；到此位置的事件已在副本数据库上执行 |
| `Master_log_name` | `Relay_Source_Log_File` | 4 | 从中读取中继日志文件中的事件的源二进制日志文件的名称 |
| `Master_log_pos` | `Exec_Source_Log_Pos` | 5 | 已在副本上执行的事件在源二进制日志文件中的等效位置 |
| `Sql_delay` | `SQL_延迟` | 6 | 副本必须落后于源的秒数 |
| `Number_of_workers` | [没有] | 7 | 并行应用复制事务的工作线程数 |
| `Id` | [没有] | 8 | 用于内部目的的 ID；目前这始终是 1 |
| `频道名称` | `频道名称` | 9 | 复制通道的名称 |
| `Privilege_checks_username` | [没有] | 10 | 的用户名`PRIVILEGE_CHECKS_USER`占渠道 |
| `Privilege_checks_hostname` | [没有] | 11 | 的主机名`PRIVILEGE_CHECKS_USER`占渠道 |
| `Require_row_format` | [没有] | 12 | 通道是否只接受基于行的事件 |
| `Require_table_primary_key_check` | [没有] | 13 | 通道关于表是否必须具有主键的策略`创建表`和`更改表`操作 |
| `分配_gtids_to_anonymous_transactions_type` | [没有] | 14 | 通道是否将 GTID 分配给尚未复制的事务，如果是，它是使用副本的本地 UUID 还是手动设置的 UUID |
| `分配_gtids_to_anonymous_transactions_value` | [没有] | 15 | 分配给匿名事务的 GTID 中使用的 UUID |
