MySQL 8.4 Release Notes
19.5.1.27 复制和行搜索
当使用行基于的复制格式的副本应用UPDATE
或DELETE
操作时,它必须搜索相关表以找到匹配的行。用于实现这个过程的算法使用表的一個索引来进行搜索,作为首选,如果没有合适的索引,则使用哈希表。
算法首先评估表定义中的可用索引,以确定是否有合适的索引可用,如果有多个可能性,则选择最适合的索引。算法忽略以下类型的索引:
-
全文索引。
-
隐藏索引。
-
生成索引。
-
多值索引。
-
索引,其中before-image的行事件不包含索引中的所有列。
如果没有合适的索引,算法不使用索引进行搜索。如果有合适的索引,算法从候选索引中选择一个索引,按照以下优先顺序:
-
主键。
-
唯一索引,其中每个索引列都具有NOT NULL属性。如果有多个这样的索引,算法选择最左侧的索引。
-
其他索引。如果有多个这样的索引,算法选择最左侧的索引。
如果算法能够选择主键或唯一索引,其中每个索引列都具有NOT NULL
属性,它使用这个索引来遍历UPDATE
或DELETE
操作的每个行。在每个行事件中,算法查找行在索引中以找到表记录以更新。如果找不到匹配的记录,返回错误ER_KEY_NOT_FOUND并停止复制应用程序线程。
如果算法不能找到合适的索引,或者只能找到非唯一索引或包含null的索引,使用哈希表来帮助识别表记录。算法创建一个哈希表,其中包含UPDATE
或DELETE
操作的所有行,键为行的完整before-image。然后,算法遍历目标表中的所有记录,使用选择的索引如果找到一个,否则执行全表扫描。对于目标表中的每个记录,算法确定该行是否存在于哈希表中。如果行在哈希表中,记录在目标表中被更新,行从哈希表中被删除。最后,算法验证哈希表是否为空。如果哈希表中仍然有未匹配的行,算法返回错误ER_KEY_NOT_FOUND并停止复制应用程序线程。