## A.14 MySQL 8.0 常见问题解答：复制

[](<>)

在下一节中，我们提供了有关 MySQL 复制的最常见问题的答案。

[](<>)A.14.1.[副本必须一直连接到源吗？](faqs-replication.html#faq-replication-have-connected-replica)A.14.2。[我必须在我的源和副本上启用网络以启用复制吗？](faqs-replication.html#faq-replication-have-enable-networking)A.14.3.[我如何知道副本与源相比晚了多长时间？换句话说，我如何知道副本复制的最后一条语句的日期？](faqs-replication.html#faq-replication-how-compare-replica-date)A.14.4。[如何强制源阻止更新，直到副本赶上？](faqs-replication.html#faq-replication-how-block-updates)A.14.5。[设置双向复制时应该注意哪些问题？](faqs-replication.html#faq-replication-how-two-way-problems)A.14.6。[如何使用复制来提高系统性能？](faqs-replication.html#faq-replication-how-improves-performance)A.14.7.[我应该怎么做才能在我自己的应用程序中准备客户端代码以使用性能增强复制？](faqs-replication.html#faq-replication-how-prepare-for-replication)A.14.8。[MySQL 复制何时以及在多大程度上可以提高我的系统性能？](faqs-replication.html#faq-replication-how-benefits-me)A.14.9。[如何使用复制来提供冗余或高可用性？](faqs-replication.html#faq-replication-how-high-availability)A.14.10。[如何判断复制源服务器是使用基于语句还是基于行的二进制日志记录格式？](faqs-replication.html#faq-replication-how-know-log-format)A.14.11。[如何告诉副本使用基于行的复制？](faqs-replication.html#faq-replication-how-use-row-based)A.14.12。[如何防止 GRANT 和 REVOKE 语句复制到副本机器？](faqs-replication.html#faq-replication-how-prevent-grant-revoke)A.14.13。[复制是否适用于混合操作系统（例如，源代码在Linux上运行，而副本在macOS和Windows上运行）？](faqs-replication.html#faq-replication-can-mix-os)A.14.14。[复制是否适用于混合硬件体系结构（例如，源运行在64位机器上，而副本运行在32位机器上）？](faqs-replication.html#faq-replication-can-mix-arch)

| [](<>)[](<>)<br/><br/>**A.14.1。** | 复制副本必须一直连接到源吗？ |
| :-------------------------------- | :------------- |
|  | 不，没有。复制副本可能会停机或断开连接数小时甚至数天，然后重新连接并赶上更新。例如，您可以通过拨号链路建立源/副本关系，其中该链路仅偶尔和短时间地接通。这意味着，在任何给定时间，除非您采取一些特殊措施，否则复制副本都不能保证与源同步。<br/><br/>为了确保已断开连接的复制副本可以进行捕获，您不能从源中删除包含尚未复制到复制副本的信息的二进制日志文件。只有当复制副本能够从上次读取事件的位置继续读取二进制日志时，异步复制才能工作。 |
| [](<>)[](<>)<br/><br/>**A.14.2。** | 我必须在源和副本上启用网络才能启用复制吗？ |
|  | 是的，必须在源和副本上启用网络。如果未启用网络，复制副本将无法连接到源并传输二进制日志。验证[`跳过网络`](server-system-variables.html#sysvar_skip_networking)两台服务器的配置文件中均未启用系统变量。 |
| [](<>)[](<>)<br/><br/>**A.14.3。** | 我如何知道复制副本与源副本的比较时间？换句话说，我如何知道复制副本复制的最后一条语句的日期？ |
|  | 检查`比大师晚几秒`输出中的列[`显示副本|从机状态`](show-replica-status.html)看见[第17.1.7.1节，“检查复制状态”](replication-administration-status.html).<br/><br/>当复制SQL线程执行从源读取的事件时，它会将自己的时间修改为事件时间戳。（这就是原因[`时间戳`](datetime.html)这是很好的复制。）在`时间`输出中的列[`显示进程列表`](show-processlist.html)，为复制SQL线程显示的秒数是上次复制事件的时间戳与副本计算机的实时时间之间的秒数。您可以使用它来确定上次复制事件的日期。请注意，如果您的复制副本已与源断开连接一个小时，然后重新连接，您可能会立即看到较大的错误`时间`中复制SQL线程的3600等值[`显示进程列表`](show-processlist.html)。这是因为复制副本正在执行一小时前的语句。看见[第17.2.3节，“复制线程”](replication-implementation-details.html). |
| [](<>)[](<>)<br/><br/>**A.14.4。** | 如何强制源阻止更新，直到复制副本赶上？ |
|  | 使用以下步骤：<br/><br/>1.在源代码上，执行以下语句：<br/><br/>   `<br/>mysql>使用读锁刷新表<br/>mysql>显示主机状态<br/>`<br/><br/>从输出中记录复制坐标（当前二进制日志文件名和位置）[`显示`](show.html)陈述<br/><br/>2.在副本上，发出以下语句，其中[`SOURCE_POS_WAIT（）`](miscellaneous-functions.html#function_source-pos-wait)或[`大师，等等`](miscellaneous-functions.html#function_master-pos-wait)函数是在上一步中获得的复制坐标值：<br/><br/>   `<br/>mysql>选择MASTER_POS_WAIT（'log_name'，log_POS）<br/><br/>`<br/><br/>这个[`选择`](select.html)语句阻塞，直到副本到达指定的日志文件和位置。此时，复制副本与源同步，语句返回。<br/><br/>3.在源上，发出以下语句以使源再次开始处理更新：<br/><br/>   `<br/>mysql>解锁表<br/>` |
| [](<>)[](<>)<br/><br/>**A.14.5。** | 设置双向复制时应注意哪些问题？ |
|  | MySQL复制目前不支持源和副本之间的任何锁定协议，以保证分布式（跨服务器）更新的原子性。换句话说，客户机A可以对co source 1进行更新，同时，在它传播到co source 2之前，客户机B可以对co source 2进行更新，从而使客户机A的更新与在co source 1上进行的更新不同。因此，当客户端A更新到co source 2时，它生成的表与co source 1上的表不同，即使co source 2的所有更新也已传播。这意味着您不应该以双向复制关系将两台服务器链接在一起，除非您确定您的更新可以以任何顺序安全地进行，或者除非您在客户端代码中以某种方式处理了顺序错误的更新。<br/><br/>您还应该意识到，就更新而言，双向复制实际上并不能极大地提高性能（如果有的话）。每个服务器都必须执行相同数量的更新，就像一台服务器一样。唯一的区别是锁争用少了一点，因为源于另一台服务器的更新在一个复制线程中序列化。甚至这种好处也可能被网络延迟所抵消。 |
| [](<>)[](<>)<br/><br/>**A.14.6。** | 如何使用复制来提高系统的性能？ |
|  | 将一台服务器设置为源服务器，并将所有写入操作定向到该服务器。然后根据预算和机架空间配置尽可能多的副本，并在源和副本之间分配读取。您还可以使用[`--跳过innodb`](innodb-parameters.html#option_mysqld_innodb)选项，启用[`低优先级更新`](server-system-variables.html#sysvar_low_priority_updates)系统变量，并设置[`延迟按键写入`](server-system-variables.html#sysvar_delay_key_write)系统变量为`全部的`以提高复制端的速度。在这种情况下，复制副本使用非事务性`米萨姆`而不是桌子`InnoDB`表可以通过消除事务开销来提高速度。 |
| [](<>)[](<>)<br/><br/>**A.14.7。** | 我应该如何在自己的应用程序中准备客户端代码，以使用性能增强型复制？ |
|  | 请参阅将复制用作扩展解决方案的指南，[第17.4.5节，“使用复制进行扩展”](replication-solutions-scaleout.html). |
| [](<>)[](<>)<br/><br/>**A.14.8。** | MySQL复制何时以及在多大程度上可以提高我的系统性能？ |
|  | MySQL复制对于处理频繁读取和不频繁写入的系统最为有利。理论上，通过使用单源/多副本设置，可以通过添加更多副本来扩展系统，直到网络带宽耗尽，或者更新负载增长到源无法处理的程度。<br/><br/>要确定在增加的好处开始变平之前可以使用多少副本，以及可以提高站点性能的程度，必须了解查询模式，并通过基准测试典型源和典型副本上的读写吞吐量之间的关系，以经验方式确定。这里的示例显示了一个相当简化的计算，即对于一个假设的系统，通过复制可以得到什么。允许`读到`和`写`分别表示每秒的读写次数。<br/><br/>假设系统负载由10%的写入和90%的读取组成，我们通过基准测试确定了这一点`读到`是1200-2\* `写`换言之，系统每秒可以进行1200次读取，无需写入，平均写入速度是平均读取速度的两倍，并且这种关系是线性的。假设源和每个副本具有相同的容量，并且我们有一个源和一个副本*`N`*复制品。然后，我们为每台服务器（源或副本）提供：<br/><br/>`读到` = 1200 - 2 \* `写`<br/><br/>`读到` = 9 \* `写` / (*`N`*+1）（读取被拆分，但写入被复制到所有副本）<br/><br/> 9 \* `写` / (*`N`* + 1) + 2 \* `写` = 1200<br/><br/>`写` = 1200 / (2 + 9/(*`N`* + 1))<br/><br/>最后一个等式表示的最大写入次数*`N`*复制副本，最大可能读取速率为每秒1200次，每次写入9次。<br/><br/>该分析得出以下结论：<br/><br/>*如果*`N`*=0（这意味着我们没有复制），我们的系统每秒可以处理大约1200/11=109次写入。<br/><br/>*如果*`N`*=1时，每秒最多可写入184次。<br/><br/>*如果*`N`*=8时，每秒最多可写入400次。<br/><br/>*如果*`N`*=17时，每秒最多可写入480次。<br/><br/>*最终*`N`*接近无穷大（我们的预算为负无穷大），我们每秒可以进行接近600次写入，将系统吞吐量提高约5.5倍。然而，由于只有八台服务器，我们将其增加了近四倍。<br/><br/>这些计算假设无限的网络带宽，忽略了对系统可能重要的其他几个因素。在许多情况下，您可能无法执行与刚才显示的类似的计算，以准确预测如果添加*`N`*复制品。但是，回答以下问题可以帮助您决定复制是否可以提高系统性能，以及可以提高多少：<br/><br/>*您的系统的读/写比率是多少？<br/><br/>*如果减少读取，一台服务器可以处理多大的写负载？<br/><br/>*您的网络上有多少副本的可用带宽？ |
| [](<>)[](<>)<br/><br/>**A.14.9。** | 如何使用复制来提供冗余或高可用性？ |
|  | 如何实现冗余完全取决于应用程序和环境。高可用性解决方案（具有自动故障切换）需要主动监控和自定义脚本或第三方工具，以提供从原始MySQL服务器到副本的故障切换支持。<br/><br/>要手动处理该过程，您应该能够通过更改应用程序以与新服务器对话，或者通过将MySQL服务器的DNS从故障服务器调整到新服务器，从故障源切换到预配置的副本。<br/><br/>有关更多信息和一些示例解决方案，请参阅[第17.4.8节，“故障切换期间切换源”](replication-solutions-switch.html). |
| [](<>)[](<>)<br/><br/>**A.14.10。** | 如何判断复制源服务器使用的是基于语句的还是基于行的二进制日志记录格式？ |
|  | 检查[`binlog_格式`](replication-options-binary-log.html#sysvar_binlog_format)系统变量：<br/><br/>`<br/>mysql>显示“binlog_格式”等变量<br/>`<br/><br/>显示的值始终为以下值之一：`陈述`, `一行`或`混合的`对于`混合的`模式下，默认情况下使用基于语句的日志记录，但在某些情况下（例如不安全的语句），复制会自动切换到基于行的日志记录。有关何时可能发生这种情况的信息，请参阅[第5.4.4.3节，“混合二进制记录格式”](binary-log-mixed.html). |
| [](<>)[](<>)<br/><br/>**A.14.11。** | 如何告诉复制副本使用基于行的复制？ |
|  | 副本会自动知道使用哪种格式。 |
| [](<>)[](<>)<br/><br/>**A.14.12。** | 如何预防[`授予`](grant.html)和[`撤销`](revoke.html)从复制到复制计算机的语句？ |
|  | 使用以下命令启动服务器：[`--复制wild ignore table=mysql.%`](replication-options-replica.html#option_mysqld_replicate-wild-ignore-table)选项忽略中表的复制`mysql`数据库 |
| [](<>)[](<>)<br/><br/>**A.14.13。** | 复制是否适用于混合操作系统（例如，源代码在Linux上运行，而副本在macOS和Windows上运行）？ |
|  | 对 |
| [](<>)[](<>)<br/><br/>**A.14.14。** | 复制是否适用于混合硬件体系结构（例如，源运行在64位机器上，而副本运行在32位机器上）？ |
|  | 对 |
