

# 排查 MariaDB 只读副本问题
<a name="USER_ReadRepl.Troubleshooting.MariaDB"></a>

MariaDB 的复制技术是异步的。由于它们是异步的，因此，源数据库实例上偶发的 `BinLogDiskUsage` 会增多，而只读副本上应有 `ReplicaLag`。例如，对源数据库实例的大量写入操作可以并行进行。与之对比的是，对只读副本的写入操作使用单个 I/O 线程串行进行，这会导致源实例与只读副本之间存在滞后。有关 MariaDB 文档中只读副本的更多信息，请转到[复制概述](http://mariadb.com/kb/en/mariadb/replication-overview/)。

您可通过多种方式来减少对源数据库实例的更新与对只读副本的后续更新之间的滞后，例如：
+ 将只读副本的存储大小和数据库实例类调整到与源数据库实例类似。
+ 确保源数据库实例和只读副本使用的数据库参数组中的参数设置相兼容。有关更多信息和示例，请参阅本部分后面的有关 `max_allowed_packet` 参数的讨论。

Amazon RDS 监控只读副本的复制状态，如果由于任何原因停止复制，则将只读副本实例的 `Replication State` 字段更新为 `Error`。可能会有这样的例子，在您的只读副本上运行的 DML 查询与对源数据库实例的更新冲突。

可通过查看 `Replication Error` 字段来检查 MariaDB 引擎引发的关联错误的详细信息。还生成指示只读副本状态的事件，包括 [RDS-EVENT-0045](USER_Events.Messages.md#RDS-EVENT-0045)、[RDS-EVENT-0046](USER_Events.Messages.md#RDS-EVENT-0046) 和 [RDS-EVENT-0047](USER_Events.Messages.md#RDS-EVENT-0047)。有关这些事件和事件订阅的详细信息，请参阅 [使用 Amazon RDS 事件通知](USER_Events.md)。如果返回 MariaDB 错误消息，则检查 [MariaDB 错误消息文档](http://mariadb.com/kb/en/mariadb/mariadb-error-codes/)中的错误。

一个可导致复制出错的常见问题是只读副本的 `max_allowed_packet` 参数的值小于源数据库实例的 `max_allowed_packet` 参数的值。`max_allowed_packet` 参数是可在数据库参数组中进行设置的自定义参数，用于指定可在数据库上运行的最大 DML 代码大小。有时候，与源数据库实例关联的数据库参数组中的 `max_allowed_packet` 参数值，要小于与源的只读副本关联的数据库参数组中的 `max_allowed_packet` 参数值。在这些情况下，复制过程可能会引发错误 (数据包大于 'max\$1allowed\$1packet' 字节) 并停止复制。通过将源和只读副本设置为使用具有相同 `max_allowed_packet` 参数值的数据库参数组，即可更正此错误。

其他可导致复制错误的常见情况包括：
+ 对只读副本上的表进行写入操作。如果是在只读副本上创建索引，则需要将 `read_only` 参数设置为 **0** 才能创建索引。如果对只读副本上的表进行写入操作，则可能会中断复制。
+ 使用非事务性存储引擎，如 MyISAM。只读副本需要使用事务性存储引擎。仅 MariaDB 上的 InnoDB 存储引擎支持复制。
+ 使用不安全的不确定性查询，如 `SYSDATE()`。有关更多信息，请参阅[确定二进制日志记录中的安全和不安全语句](https://dev.mysql.com/doc/refman/8.0/en/replication-rbr-safe-unsafe.html)。

如果您确定可安全跳过错误，那么可以按照[跳过 RDS for MySQL 的当前复制错误](Appendix.MySQL.CommonDBATasks.SkipError.md)中描述的步骤操作。否则，可删除只读副本，然后使用相同的数据库实例标识符创建实例，以使终端节点保持与旧只读副本的终端节点相同。如果复制错误得到纠正，则 `Replication State` 将更改为 *replicating*。

对于 MariaDB 数据库实例，在某些情况下，如果某些二进制日志 (binlog) 事件在故障期间未刷新，则只读副本将无法切换到辅助可用区。在这些情况下，请手动删除并重新创建只读副本。您可通过设置以下参数值来降低发生这种情况的可能性：`sync_binlog=1` 和 `innodb_flush_log_at_trx_commit=1`。这些设置可能降低性能，因此，请先测试其影响，然后在生产环境中实施更改。