Optimizer 与 Handler:ICP、MRR 与存储引擎边界
EXPLAIN 显示
Using index condition 时,部分
WHERE 谓词在 InnoDB 层
对二级索引记录求值,而非全部回表后在 Server 过滤——这是
ICP(Index Condition
Pushdown)。Using mrr 则表示
MRR 批量收集主键再排序回表,把随机 IO
变成顺序 IO。二者都发生在 handler 接口
之下,优化器只选是否启用。
本文不展开 Server 层代价模型全文,只钉住 InnoDB 提供的能力与代价,对照 PG 执行器。版本:MySQL 8.0.36。
一、Handler 在架构中的位置
flowchart TD
SQL[SQL 层] --> OPT[Optimizer]
OPT --> H[handler 接口]
H --> INN[ha_innobase]
INN --> ROW[row0sel / row0upd]
ROW --> BTR[B+Tree]
ROW --> BUF[Buffer Pool]
handlerton 注册引擎能力(事务、索引类型、ICP
标志)。优化器通过 TABLE::file 调用
index_read、index_next、rnd_next
等。
源码:sql/handler.h、sql/handler.cc、storage/innobase/handler/ha_innodb.cc。
二、核心 handler 方法
| 方法 | 场景 |
|---|---|
index_read |
定长键查找 |
index_read_map /
index_next |
范围扫描 |
index_read_last |
反向扫描 |
rnd_next |
全表扫描(聚簇索引) |
write_row / update_row /
delete_row |
DML |
ha_innobase::index_read 最终进入
row_search_mvcc(一致性读)或加锁读路径(第 7–9
篇)。
三、ICP:Index Condition Pushdown
优化器把 可用索引列无法完全覆盖
的谓词,以 ITEM
形式传给引擎;ha_innobase 在
二级索引记录 上调用 index_cond
回调。
-- 需本地验证
EXPLAIN SELECT * FROM t WHERE a > 10 AND b LIKE 'x%';
-- 索引 (a,c),谓词含 b 时可能出现 Using index condition收益:减少回表次数。代价:引擎内求值 CPU;某些函数不可下推。
源码:sql/opt_range.cc(计划)、storage/innobase/handler/ha_innodb.cc(innobase_index_cond)。
四、MRR 与 DS-MRR
Multi-Range Read:先扫二级索引收集主键到 buffer,按 PK 排序 后批量回表。
| 标志 | 含义 |
|---|---|
Using mrr |
启用 MRR |
Using mrr(sort_key) |
DS-MRR,排序键后回表 |
对 高选择性 范围查 + 宽表,MRR 显著降随机 IO;低选择性可能增加内存与排序开销。
五、覆盖索引与 EXPLAIN 解读
Using index:所需列均在同一二级索引中(第 11
篇)。Using where 在 Server
或引擎过滤。
EXPLAIN ANALYZE(8.0.18+)显示
实际行数与循环耗时——排查 ICP/MRR
是否生效的首选(需本地验证)。
六、代价边界
优化器用
统计信息(mysql.innodb_index_stats)估计行数;InnoDB
提供 info()、scan_time()
等粗粒度代价。 不准确统计
导致选错「索引+回表」vs「全表扫描」——与 PG 错误
n_distinct 同类。
七、实验(需本地验证)
SET optimizer_switch='mrr=on,mrr_cost_based=off';
SET optimizer_switch='index_condition_pushdown=on';
EXPLAIN ANALYZE SELECT id, col FROM wide WHERE secondary_key BETWEEN 1 AND 10000;
-- 对比 mrr on/off 的 actual time八、工程坑点
以为 ICP 等于索引全覆盖。只能下推与索引列相关的条件组合。
关闭 MRR 后抱怨随机 IO。宽表二级索引范围查可显式测试 MRR。
8.0 隐式主键与覆盖索引设计。无显式 PK
时用隐藏 DB_ROW_ID,影响回表语义。
九、关键要点
- handler 是优化器与 InnoDB 的唯一边界。
- ICP 在索引记录上过滤,减少回表。
- MRR 排序主键后批量回表,优化 IO 形态。
- 覆盖索引 避免回表;与 ICP/MRR 正交。
- 计划问题先 EXPLAIN ANALYZE,再下钻 handler 路径。
十一、PG 对照
| 维度 | InnoDB handler | PG Executor |
|---|---|---|
| 下推过滤 | ICP(索引层) | Index Scan + filter 或 Index Cond |
| 批量回表 | MRR + DS-MRR | Bitmap Index Scan + heap fetch |
| 覆盖扫描 | 二级索引含列即可 | Index-Only Scan + VM |
| 接口 | handler 虚表 |
ForeignScan / IndexScan
节点 |
PG 第
12 篇 在计划节点层下推;MySQL 在 存储引擎
API 层下推——读懂
ha_innobase::index_read 即可对齐直觉。
深度阅读清单
深度.1
handler::index_read(sql/handler.h)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:handler 索引读接口。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.2
ha_innobase::index_read(storage/innobase/handler/ha_innodb.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:InnoDB 实现。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.3
ha_innobase::read_range_first(storage/innobase/handler/ha_innodb.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:范围扫描入口。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.4
row_sel_store_mysql_rec(storage/innobase/row/row0sel.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:行转 MySQL 格式。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.5
innobase_index_cond(storage/innobase/handler/ha_innodb.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:ICP 回调。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.6
trx_commit_for_mysql(storage/innobase/trx/trx0trx.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:InnoDB 事务提交入口。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.7
trx_prepare_for_mysql(storage/innobase/trx/trx0trx.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:InnoDB XA prepare。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.8
log_buffer_write(storage/innobase/log/log0log.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:redo 写入 log buffer。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.9
log_write_up_to(storage/innobase/log/log0log.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:redo 刷盘至指定 LSN。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.10
buf_page_get_gen(storage/innobase/buf/buf0buf.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:Buffer Pool 取页。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.11
lock_rec_lock(storage/innobase/lock/lock0lock.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:记录锁 / gap lock。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.12
ibuf_insert(storage/innobase/ibuf/ibuf0ibuf.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:Change Buffer 插入。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.13
ibuf_merge(storage/innobase/ibuf/ibuf0ibuf.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:Change Buffer 合并。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.14
btr_search_build_page_hash_index(storage/innobase/btr/btr0sea.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:AHI 构建。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.15
srv_mon_print_innodb_monitor(storage/innobase/srv/srv0mon.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:INNODB STATUS 输出。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.16
trx_purge(storage/innobase/trx/trx0purge.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:purge 回收 undo。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.17
recv_recovery_from_checkpoint_start(storage/innobase/log/log0recv.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:崩溃恢复 redo apply。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.18
ha_commit_trans(sql/handler.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:Server 层事务提交。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.19
ordered_commit(sql/binlog.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:binlog 组提交。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.20
MYSQL_BIN_LOG::commit(sql/binlog.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:binlog 事务落盘。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.21
ha_innobase::index_read(storage/innobase/handler/ha_innodb.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:索引读 handler 入口。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.22
ha_innobase::index_next(storage/innobase/handler/ha_innodb.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:索引扫描下一行。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.23
row_search_mvcc(storage/innobase/row/row0sel.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:一致性读搜索。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.24
btr_cur_search_to_nth_level(storage/innobase/btr/btr0cur.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:B+Tree 搜索。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.25
handler::index_read(sql/handler.h)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:handler 索引读接口。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.26
ha_innobase::index_read(storage/innobase/handler/ha_innodb.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:InnoDB 实现。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.27
ha_innobase::read_range_first(storage/innobase/handler/ha_innodb.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:范围扫描入口。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.28
row_sel_store_mysql_rec(storage/innobase/row/row0sel.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:行转 MySQL 格式。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.29
innobase_index_cond(storage/innobase/handler/ha_innodb.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:ICP 回调。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.30
trx_commit_for_mysql(storage/innobase/trx/trx0trx.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:InnoDB 事务提交入口。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.31
trx_prepare_for_mysql(storage/innobase/trx/trx0trx.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:InnoDB XA prepare。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.32
log_buffer_write(storage/innobase/log/log0log.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:redo 写入 log buffer。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.33
log_write_up_to(storage/innobase/log/log0log.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:redo 刷盘至指定 LSN。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.34
buf_page_get_gen(storage/innobase/buf/buf0buf.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:Buffer Pool 取页。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.35
lock_rec_lock(storage/innobase/lock/lock0lock.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:记录锁 / gap lock。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.36
ibuf_insert(storage/innobase/ibuf/ibuf0ibuf.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:Change Buffer 插入。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.37
ibuf_merge(storage/innobase/ibuf/ibuf0ibuf.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:Change Buffer 合并。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.38
btr_search_build_page_hash_index(storage/innobase/btr/btr0sea.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:AHI 构建。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.39
srv_mon_print_innodb_monitor(storage/innobase/srv/srv0mon.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:INNODB STATUS 输出。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.40
trx_purge(storage/innobase/trx/trx0purge.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:purge 回收 undo。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.41
recv_recovery_from_checkpoint_start(storage/innobase/log/log0recv.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:崩溃恢复 redo apply。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.42
ha_commit_trans(sql/handler.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:Server 层事务提交。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.43
ordered_commit(sql/binlog.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:binlog 组提交。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.44
MYSQL_BIN_LOG::commit(sql/binlog.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:binlog 事务落盘。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.45
ha_innobase::index_read(storage/innobase/handler/ha_innodb.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:索引读 handler 入口。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.46
ha_innobase::index_next(storage/innobase/handler/ha_innodb.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:索引扫描下一行。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.47
row_search_mvcc(storage/innobase/row/row0sel.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:一致性读搜索。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
深度.48
btr_cur_search_to_nth_level(storage/innobase/btr/btr0cur.cc)
MySQL 8.0.36 中该符号与 Optimizer 与 Handler 相关:B+Tree 搜索。
| 步骤 | 动作 |
|---|---|
| 1 | 在 tag mysql-8.0.36 下打开源文件 |
| 2 | 自函数入口向下读 80–120 行 |
| 3 | 记录 mtr / mutex 边界与调用方 |
| 4 | 对照本章流程图标注阶段 |
| 参数 | 默认 | 说明 |
|---|---|---|
14_1 |
见文档 | 参数说明 1 |
14_2 |
见文档 | 参数说明 2 |
14_3 |
见文档 | 参数说明 3 |
14_4 |
见文档 | 参数说明 4 |
14_5 |
见文档 | 参数说明 5 |
14_6 |
见文档 | 参数说明 6 |
14_7 |
见文档 | 参数说明 7 |
14_8 |
见文档 | 参数说明 8 |
14_9 |
见文档 | 参数说明 9 |
14_10 |
见文档 | 参数说明 10 |
14_11 |
见文档 | 参数说明 11 |
14_12 |
见文档 | 参数说明 12 |
14_13 |
见文档 | 参数说明 13 |
14_14 |
见文档 | 参数说明 14 |
14_15 |
见文档 | 参数说明 15 |
14_16 |
见文档 | 参数说明 16 |
14_17 |
见文档 | 参数说明 17 |
14_18 |
见文档 | 参数说明 18 |
14_19 |
见文档 | 参数说明 19 |
14_20 |
见文档 | 参数说明 20 |
14_21 |
见文档 | 参数说明 21 |
14_22 |
见文档 | 参数说明 22 |
14_23 |
见文档 | 参数说明 23 |
14_24 |
见文档 | 参数说明 24 |
14_25 |
见文档 | 参数说明 25 |
14_26 |
见文档 | 参数说明 26 |
14_27 |
见文档 | 参数说明 27 |
14_28 |
见文档 | 参数说明 28 |
14_29 |
见文档 | 参数说明 29 |
14_30 |
见文档 | 参数说明 30 |
专题深化 1:Optimizer 与 Handler
InnoDB 的 Optimizer 与 Handler 机制必须与
redo(log0log.cc)、undo(trx0undo.cc)、Buffer
Pool(buf0buf.cc)一并理解。连接线程持有
THD,经 ha_innobase
进入引擎;页级修改包在
mtr(mtr0mtr.cc)内。SQL
事务边界由 Server ha_commit_trans 协调 binlog
与 InnoDB(本章主线)。
专题深化 1.1 同步原语层次
短临界区用
mutex_enter(sync0sync.cc);页内容用
rw_lock(sync0rw.cc)。performance_schema
中 wait/synch/mutex/innodb/% 需在本地 workload
下采集,不可套用他方 benchmark。
专题深化 1.2 8.0.36 源码阅读顺序
建议:本章核心目录 → mtr/mtr0mtr.cc →
log/log0log.cc → Server 层
sql/binlog.cc(若涉及复制)。调试编译用
-DWITH_DEBUG=1;生产用官方 GA 构建。
专题深化 1.3 实验纪律
凡涉及
SHOW ENGINE INNODB STATUS、Performance
Schema、data_locks 的实验均标注
需本地验证。记录版本、存储介质、并发度;性能数字至少
3 次采样取中位数。
专题深化 1.4 与 PG 系列对照阅读
若已读 PostgreSQL 内核系列,用「同一问题」对照机制差异;不比较绝对性能——复制模型、页大小、MVCC 方案均不同。
专题深化 1.5 生产边界
Cloud RDS/Aurora 内部路径可能与社区版不同;本文以社区版
storage/innobase/ 为准。MariaDB 10.x
在部分路径存在分叉——以 Release Notes 为准。
专题深化 2:Optimizer 与 Handler
InnoDB 的 Optimizer 与 Handler 机制必须与
redo(log0log.cc)、undo(trx0undo.cc)、Buffer
Pool(buf0buf.cc)一并理解。连接线程持有
THD,经 ha_innobase
进入引擎;页级修改包在
mtr(mtr0mtr.cc)内。SQL
事务边界由 Server ha_commit_trans 协调 binlog
与 InnoDB(本章主线)。
专题深化 2.1 同步原语层次
短临界区用
mutex_enter(sync0sync.cc);页内容用
rw_lock(sync0rw.cc)。performance_schema
中 wait/synch/mutex/innodb/% 需在本地 workload
下采集,不可套用他方 benchmark。
专题深化 2.2 8.0.36 源码阅读顺序
建议:本章核心目录 → mtr/mtr0mtr.cc →
log/log0log.cc → Server 层
sql/binlog.cc(若涉及复制)。调试编译用
-DWITH_DEBUG=1;生产用官方 GA 构建。
专题深化 2.3 实验纪律
凡涉及
SHOW ENGINE INNODB STATUS、Performance
Schema、data_locks 的实验均标注
需本地验证。记录版本、存储介质、并发度;性能数字至少
3 次采样取中位数。
专题深化 2.4 与 PG 系列对照阅读
若已读 PostgreSQL 内核系列,用「同一问题」对照机制差异;不比较绝对性能——复制模型、页大小、MVCC 方案均不同。
专题深化 2.5 生产边界
Cloud RDS/Aurora 内部路径可能与社区版不同;本文以社区版
storage/innobase/ 为准。MariaDB 10.x
在部分路径存在分叉——以 Release Notes 为准。
专题深化 3:Optimizer 与 Handler
InnoDB 的 Optimizer 与 Handler 机制必须与
redo(log0log.cc)、undo(trx0undo.cc)、Buffer
Pool(buf0buf.cc)一并理解。连接线程持有
THD,经 ha_innobase
进入引擎;页级修改包在
mtr(mtr0mtr.cc)内。SQL
事务边界由 Server ha_commit_trans 协调 binlog
与 InnoDB(本章主线)。
专题深化 3.1 同步原语层次
短临界区用
mutex_enter(sync0sync.cc);页内容用
rw_lock(sync0rw.cc)。performance_schema
中 wait/synch/mutex/innodb/% 需在本地 workload
下采集,不可套用他方 benchmark。
专题深化 3.2 8.0.36 源码阅读顺序
建议:本章核心目录 → mtr/mtr0mtr.cc →
log/log0log.cc → Server 层
sql/binlog.cc(若涉及复制)。调试编译用
-DWITH_DEBUG=1;生产用官方 GA 构建。
专题深化 3.3 实验纪律
凡涉及
SHOW ENGINE INNODB STATUS、Performance
Schema、data_locks 的实验均标注
需本地验证。记录版本、存储介质、并发度;性能数字至少
3 次采样取中位数。
专题深化 3.4 与 PG 系列对照阅读
若已读 PostgreSQL 内核系列,用「同一问题」对照机制差异;不比较绝对性能——复制模型、页大小、MVCC 方案均不同。
专题深化 3.5 生产边界
Cloud RDS/Aurora 内部路径可能与社区版不同;本文以社区版
storage/innobase/ 为准。MariaDB 10.x
在部分路径存在分叉——以 Release Notes 为准。
专题深化 4:Optimizer 与 Handler
InnoDB 的 Optimizer 与 Handler 机制必须与
redo(log0log.cc)、undo(trx0undo.cc)、Buffer
Pool(buf0buf.cc)一并理解。连接线程持有
THD,经 ha_innobase
进入引擎;页级修改包在
mtr(mtr0mtr.cc)内。SQL
事务边界由 Server ha_commit_trans 协调 binlog
与 InnoDB(本章主线)。
专题深化 4.1 同步原语层次
短临界区用
mutex_enter(sync0sync.cc);页内容用
rw_lock(sync0rw.cc)。performance_schema
中 wait/synch/mutex/innodb/% 需在本地 workload
下采集,不可套用他方 benchmark。
专题深化 4.2 8.0.36 源码阅读顺序
建议:本章核心目录 → mtr/mtr0mtr.cc →
log/log0log.cc → Server 层
sql/binlog.cc(若涉及复制)。调试编译用
-DWITH_DEBUG=1;生产用官方 GA 构建。
专题深化 4.3 实验纪律
凡涉及
SHOW ENGINE INNODB STATUS、Performance
Schema、data_locks 的实验均标注
需本地验证。记录版本、存储介质、并发度;性能数字至少
3 次采样取中位数。
专题深化 4.4 与 PG 系列对照阅读
若已读 PostgreSQL 内核系列,用「同一问题」对照机制差异;不比较绝对性能——复制模型、页大小、MVCC 方案均不同。
专题深化 4.5 生产边界
Cloud RDS/Aurora 内部路径可能与社区版不同;本文以社区版
storage/innobase/ 为准。MariaDB 10.x
在部分路径存在分叉——以 Release Notes 为准。
专题深化 5:Optimizer 与 Handler
InnoDB 的 Optimizer 与 Handler 机制必须与
redo(log0log.cc)、undo(trx0undo.cc)、Buffer
Pool(buf0buf.cc)一并理解。连接线程持有
THD,经 ha_innobase
进入引擎;页级修改包在
mtr(mtr0mtr.cc)内。SQL
事务边界由 Server ha_commit_trans 协调 binlog
与 InnoDB(本章主线)。
专题深化 5.1 同步原语层次
短临界区用
mutex_enter(sync0sync.cc);页内容用
rw_lock(sync0rw.cc)。performance_schema
中 wait/synch/mutex/innodb/% 需在本地 workload
下采集,不可套用他方 benchmark。
专题深化 5.2 8.0.36 源码阅读顺序
建议:本章核心目录 → mtr/mtr0mtr.cc →
log/log0log.cc → Server 层
sql/binlog.cc(若涉及复制)。调试编译用
-DWITH_DEBUG=1;生产用官方 GA 构建。
专题深化 5.3 实验纪律
凡涉及
SHOW ENGINE INNODB STATUS、Performance
Schema、data_locks 的实验均标注
需本地验证。记录版本、存储介质、并发度;性能数字至少
3 次采样取中位数。
专题深化 5.4 与 PG 系列对照阅读
若已读 PostgreSQL 内核系列,用「同一问题」对照机制差异;不比较绝对性能——复制模型、页大小、MVCC 方案均不同。
专题深化 5.5 生产边界
Cloud RDS/Aurora 内部路径可能与社区版不同;本文以社区版
storage/innobase/ 为准。MariaDB 10.x
在部分路径存在分叉——以 Release Notes 为准。
专题深化 6:Optimizer 与 Handler
InnoDB 的 Optimizer 与 Handler 机制必须与
redo(log0log.cc)、undo(trx0undo.cc)、Buffer
Pool(buf0buf.cc)一并理解。连接线程持有
THD,经 ha_innobase
进入引擎;页级修改包在
mtr(mtr0mtr.cc)内。SQL
事务边界由 Server ha_commit_trans 协调 binlog
与 InnoDB(本章主线)。
专题深化 6.1 同步原语层次
短临界区用
mutex_enter(sync0sync.cc);页内容用
rw_lock(sync0rw.cc)。performance_schema
中 wait/synch/mutex/innodb/% 需在本地 workload
下采集,不可套用他方 benchmark。
专题深化 6.2 8.0.36 源码阅读顺序
建议:本章核心目录 → mtr/mtr0mtr.cc →
log/log0log.cc → Server 层
sql/binlog.cc(若涉及复制)。调试编译用
-DWITH_DEBUG=1;生产用官方 GA 构建。
专题深化 6.3 实验纪律
凡涉及
SHOW ENGINE INNODB STATUS、Performance
Schema、data_locks 的实验均标注
需本地验证。记录版本、存储介质、并发度;性能数字至少
3 次采样取中位数。
专题深化 6.4 与 PG 系列对照阅读
若已读 PostgreSQL 内核系列,用「同一问题」对照机制差异;不比较绝对性能——复制模型、页大小、MVCC 方案均不同。
专题深化 6.5 生产边界
Cloud RDS/Aurora 内部路径可能与社区版不同;本文以社区版
storage/innobase/ 为准。MariaDB 10.x
在部分路径存在分叉——以 Release Notes 为准。
专题深化 7:Optimizer 与 Handler
InnoDB 的 Optimizer 与 Handler 机制必须与
redo(log0log.cc)、undo(trx0undo.cc)、Buffer
Pool(buf0buf.cc)一并理解。连接线程持有
THD,经 ha_innobase
进入引擎;页级修改包在
mtr(mtr0mtr.cc)内。SQL
事务边界由 Server ha_commit_trans 协调 binlog
与 InnoDB(本章主线)。
专题深化 7.1 同步原语层次
短临界区用
mutex_enter(sync0sync.cc);页内容用
rw_lock(sync0rw.cc)。performance_schema
中 wait/synch/mutex/innodb/% 需在本地 workload
下采集,不可套用他方 benchmark。
专题深化 7.2 8.0.36 源码阅读顺序
建议:本章核心目录 → mtr/mtr0mtr.cc →
log/log0log.cc → Server 层
sql/binlog.cc(若涉及复制)。调试编译用
-DWITH_DEBUG=1;生产用官方 GA 构建。
专题深化 7.3 实验纪律
凡涉及
SHOW ENGINE INNODB STATUS、Performance
Schema、data_locks 的实验均标注
需本地验证。记录版本、存储介质、并发度;性能数字至少
3 次采样取中位数。
专题深化 7.4 与 PG 系列对照阅读
若已读 PostgreSQL 内核系列,用「同一问题」对照机制差异;不比较绝对性能——复制模型、页大小、MVCC 方案均不同。
专题深化 7.5 生产边界
Cloud RDS/Aurora 内部路径可能与社区版不同;本文以社区版
storage/innobase/ 为准。MariaDB 10.x
在部分路径存在分叉——以 Release Notes 为准。
上一篇:主从复制机制
参考资料
源码(MySQL 8.0.36)
storage/innobase/— 引擎实现sql/binlog.cc,sql/handler.cc— Server 层交界
官方文档
- MySQL 8.0 Reference Manual, InnoDB / Replication / Backup
相关文章
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【MySQL InnoDB 内核】InnoDB 架构与线程模型
InnoDB handler 边界、Master/Purge/IO/Page Cleaner 线程、内存布局与 srv0srv.cc 启动路径。
【MySQL InnoDB 内核】页结构与行格式
FIL 页头、Infimum/Supremum、聚簇/二级索引、ROW_FORMAT 与 rem0rec.h 行头字段。
【MySQL InnoDB 内核】Buffer Pool 与 LRU:frame、flush 列表与 young/old 分区
Buffer Pool 实例、LRU 年轻/年老分区、flush 列表、buf_page_get 路径与 read-ahead。
【MySQL InnoDB 内核】Redo Log 内部机制:LSN、mtr 与组提交
Redo log buffer、LSN、checkpoint、mtr 记录类型与 innodb_flush_log_at_trx_commit 语义。