bigywater.tech
MySQL / InnoDB · 92

Replica SQL Thread 与 IO Thread

分别单独停掉IO线程和SQL线程,用GTID集合的真实差值验证这两个线程各自独立的职责边界。

IO线程管传输
停IO,数据真实完全传不过来
SQL线程管重放
停SQL,数据真实收到了但不落地

做的事:单独停IO线程,看数据是不是真的传不过来

代码STOP REPLICA IO_THREAD; -- 在source上:INSERT INTO shop.orders (item, qty) VALUES ('cherry', 3);

验证:IO线程停了,数据真实完全过不来

实测 · 本机执行输出
IO线程停止期间,replica查询:
SELECT * FROM shop.orders;
→ 只有原来的2行,cherry真实没出现

START REPLICA IO_THREAD;
(等待约2秒)
SELECT * FROM shop.orders;
→ 真实出现了cherry这一行

IO线程真实的职责是"去source那边把新的binlog事件拉过来,写进本地的relay log文件",它一旦停止,replica真实完全收不到任何新的变更信息,不管SQL线程是不是在运行——重启IO线程之后,之前积压在source上的变更真实很快就被追上来了。

验证:单独停SQL线程,数据真实收到了但没应用

代码STOP REPLICA SQL_THREAD; -- source: INSERT INTO shop.orders (item, qty) VALUES ('date', 7);
实测 · 本机执行输出
SQL线程停止期间:
SELECT * FROM shop.orders;   → 还是没有date这一行(数据没落地)

SHOW REPLICA STATUS真实显示:
  Replica_IO_Running: Yes    (IO线程还在跑)
  Replica_SQL_Running: No
  Retrieved_Gtid_Set: ...1-7   ← IO线程真实已经收到了包含date的事务
  Executed_Gtid_Set:  ...1-6   ← SQL线程真实还停在上一个事务,没应用这条

START REPLICA SQL_THREAD;
(约1秒后)
SELECT * FROM shop.orders;   → date这一行真实出现了
这组对比真实把IO线程和SQL线程完全独立的职责拆开了看:IO线程只管"网络传输",负责把source的binlog事件搬到本地relay log;SQL线程只管"重放",负责把relay log里的事件真实应用到本地数据。Retrieved_Gtid_Set和Executed_Gtid_Set这两个字段的真实差值,就是"已经收到但还没应用"的事务集合——这也是为什么复制延迟(下一篇的主题)有两种真实不同的来源:网络/IO跟不上,或者SQL应用跟不上,需要分开诊断。

分步演示:单独停IO和单独停SQL的真实差别

每一步都是本文上面用真实两节点复制环境跑出来的原始结果。

两个线程,真实各管各的一段
这一步新验证的线程状态

    本文用到的工具

    • 本机真实的两节点复制实验环境(source端口19310,replica端口19311)
    • STOP/START REPLICA IO_THREAD / SQL_THREAD + Retrieved/Executed_Gtid_Set对比
    京ICP备2026067502号-1京公网安备11010502063487号