MySQL BLACKHOLE 存储引擎适合什么复制中转场景
如果你把 MySQL BLACKHOLE 当成普通业务表,最容易得到两个错误结论:一是以为插入成功就能再查出来,二是以为没有表数据就不会参与复制。它真正适合的是“让一个中转 mysqld 进程接收并过滤复制事件,再把新的二进制日志交给下游副本”的架构。
官方地址:https://dev.mysql.com/doc/refman/8.4/en/blackhole-storage-engine.html
BLACKHOLE 表本身不落盘,读取总是空结果;但在启用 statement-based binary logging 时,写入语句仍可以进入二进制日志并复制到下游。因此它更像复制链路中的“无数据中转层”,而不是缓存、归档表或业务存储。下面按实际决策顺序说明它适合什么场景,以及上线前需要避开的边界。
先确认 BLACKHOLE 的读写语义
先把表的两个事实分开:表数据不保存,复制日志可以保存事件。官方文档给出的行为是,INSERT 能返回成功,但随后执行 SELECT 不会得到刚才写入的行。这个特征正是它能做中转节点的原因,也是它不能替代 InnoDB 的原因。
-- 创建一个只保留表定义、不保留行数据的表
CREATE TABLE relay_events (
event_id BIGINT NOT NULL,
payload VARBINARY(1024) NOT NULL,
PRIMARY KEY (event_id)
) ENGINE = BLACKHOLE;
-- 写入语句可以成功,但 BLACKHOLE 不保存行
INSERT INTO relay_events(event_id, payload)
VALUES (1001, X'010203');
-- 查询不会返回上面插入的记录
SELECT event_id, payload
FROM relay_events;
这里的“成功”只表示服务器接受了写入操作,不表示数据已经落在某个可查询的数据页中。即使表定义里声明了索引,也不能把索引当作可供查询的持久化数据结构。需要重放、查询、补偿或审计原始行时,应使用真正保存数据的引擎。

把 BLACKHOLE 放进复制过滤链路
最典型的架构不是“业务应用直接连 BLACKHOLE”,而是在复制源旁边运行一个 dummy mysqld。源服务器先写自己的二进制日志,dummy mysqld 作为副本接收事件,再依据 replicate-do-* 或 replicate-ignore-* 规则应用需要的过滤,最后由这个中转进程写出新的二进制日志,供下游副本继续复制。
-- 下面是中转实例上的过滤意图示例;实际参数应写入该实例的启动配置
-- 只让指定业务库进入中转实例的复制链路
replicate-do-db=orders
-- 对不需要下发的表进行过滤,避免把无关事件交给下游
replicate-ignore-table=orders.tmp_import
-- 中转实例上的业务表使用 BLACKHOLE,表定义仍需与复制规则匹配
CREATE TABLE orders.order_events (
id BIGINT NOT NULL,
event_type VARCHAR(64) NOT NULL,
created_at TIMESTAMP NOT NULL
) ENGINE = BLACKHOLE;
这个方案的价值是把过滤动作提前到靠近源端的位置:下游副本不必先接收所有二进制日志再丢弃,多个副本还可以复用同一个过滤后的日志出口。BLACKHOLE 负责“不保存表行”,dummy mysqld 负责“接收、过滤并重新产生日志”,两者不要混为一个概念。

哪些复制中转场景适合使用
可以用下面的判断表快速缩小范围:
| 场景 | 是否适合 | 原因 |
|---|---|---|
| 源端先过滤,再给多个下游副本 | 适合 | 中转实例可以生成过滤后的二进制日志,减少下游接收无关事件。 |
| 只测量二进制日志和复制开销 | 适合 | 存储引擎不落盘,便于把存储层开销从测量目标中剥离。 |
| 临时验证 dump 文件中的 SQL 语法 | 适合 | 可以接受写入而不保留数据,适合做语句层面的检查。 |
| 需要查询、补偿或恢复业务数据 | 不适合 | 写入不会留下可读取的行,无法承担数据恢复职责。 |
| 依赖 UPDATE/DELETE 行触发器 | 不适合 | BLACKHOLE 没有实际行,UPDATE 和 DELETE 的行级触发器不会按普通表工作。 |
所以,标题中的“中转”必须指复制日志的中转,而不是业务数据的中转。若下游需要完整的行数据,应该让过滤后的事件落到合适的持久化引擎,再由下游消费。
上线前要避开的复制边界
自增列不能按普通表理解
BLACKHOLE 是 no-op 引擎,不会自动维护自增值,也不保留自增状态。如果源端的 BLACKHOLE 表依赖自增主键,而下游表使用 MyISAM 等实际存储引擎,且 INSERT 没有显式设置自增值,复制可能因为重复主键而失败。中转表最好使用业务侧明确生成的主键,或者在复制协议中明确处理 INSERT_ID,不要把自增状态交给 BLACKHOLE。
-- 中转表显式接收业务生成的唯一 ID,避免依赖 BLACKHOLE 的自增状态
CREATE TABLE relay_events (
event_id BIGINT NOT NULL,
body VARBINARY(2048) NOT NULL,
PRIMARY KEY (event_id)
) ENGINE = BLACKHOLE;
-- 写入时由上游明确提供 ID,复制两端看到的键保持一致
INSERT INTO relay_events(event_id, body)
VALUES (9000001, X'0A0B0C');
触发器和表结构差异要单独评估
BLACKHOLE 表上的 INSERT 触发器可以按预期工作,但 UPDATE 和 DELETE 触发器依赖实际行,不能按普通 InnoDB 表推断。使用 row-based replication 时,列过滤也有明确边界:源端可以先准备公开列和敏感列,中转或可信副本使用不同的表定义配合过滤规则。这个设计需要把表结构、binlog_format 和复制选项一起审阅,不能只改 ENGINE。
一份可执行的落地清单
- 先执行
SHOW ENGINES,确认当前实例的 BLACKHOLE 状态可用,再决定是否部署中转实例。 - 把中转实例和业务源实例分开看:前者负责复制接收、过滤和日志输出,后者负责真实业务数据。
- 逐张核对中转表定义,尤其是主键、自增列、触发器、列顺序和下游表引擎。
- 明确复制格式与过滤参数,记录哪些库表会进入中转日志,哪些事件会在源端被排除。
- 把“查询为空”写进运维说明和告警判断,避免值班人员把它误判成复制延迟或数据丢失。
-- 上线前快速确认存储引擎是否被当前实例启用
SHOW ENGINES;
-- 只检查表定义,不把空查询误认为表不可用
SHOW CREATE TABLE relay_events;
最终可以这样做选择:如果目标是靠近源端过滤复制事件、减少下游无关日志,BLACKHOLE 适合做轻量中转;如果目标是保存、查询或恢复数据,就应选择真正持久化的存储引擎。它的优势来自“不保存”,风险也恰恰来自“不保存”。
相关问题
BLACKHOLE 表为什么 INSERT 成功后 SELECT 为空?
因为它接受写入后直接丢弃行数据,查询没有可读取的记录;成功不等于保存。
BLACKHOLE 能不能当临时缓存表?
不能。它没有可供后续读取的行,也不保留自增状态,不具备缓存表的基本语义。
为什么 BLACKHOLE 还能参与复制?
在适用的二进制日志配置下,写入语句仍可以进入 binary log;复制链路传播的是日志事件,不是 BLACKHOLE 表里已经保存的行。
复制中转表应该使用自增主键吗?
不建议把主键生成依赖 BLACKHOLE 的自增状态。更稳妥的方式是由上游明确生成并写入唯一 ID,再让复制两端保持一致。
MySQL BIT_COUNT 怎么统计位标志中被置为 1 的数量
- 上一篇
- MySQL BIT_COUNT 怎么统计位标志中被置为 1 的数量
- 下一篇
- MySQL C API 读取含零字节字段时怎么使用 mysql_fetch_lengths
-
- 数据库 · MySQL | 14小时前 | MySQL · 存储过程 ·
- MySQL 处理器中 STACKED 与 CURRENT 诊断区有什么区别
- 301浏览 收藏
-
- 数据库 · MySQL | 15小时前 | mysql 空间函数 LineString ST_NumPoints ST_NumGeometries
- MySQL ST_NumPoints 与 ST_NumGeometries 怎样区分线段点数和几何成员数
- 412浏览 收藏
-
- 数据库 · MySQL | 16小时前 | MySQL · 数据库 · 复制 · mysql gtid Clone Plugin 复制坐标
- MySQL 克隆副本后怎样取得随数据转移的复制坐标
- 387浏览 收藏
-
- 数据库 · MySQL | 16小时前 |
- MySQL clone_progress 怎样查看克隆各阶段耗时
- 344浏览 收藏
-
- 数据库 · MySQL | 18小时前 |
- MySQL 锁定服务的命名空间与锁名怎样区分
- 146浏览 收藏
-
- 数据库 · MySQL | 19小时前 | MySQL · 数据库 · ip地址 · mysql IPv6 INET6_ATON IPv4-mapped IPv6 IS_IPV4_MAPPED
- MySQL IS_IPV4_MAPPED 怎样识别映射形式的 IPv6 地址
- 416浏览 收藏
-
- 数据库 · MySQL | 20小时前 |
- MySQL ORD 为什么不等于 Unicode 码点
- 466浏览 收藏
-
- 数据库 · MySQL | 20小时前 |
- MySQL 分页总数怎样从 FOUND_ROWS 迁移到独立 COUNT
- 116浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 974次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 980次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 1096次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 1068次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 906次使用
-
- 用查询属性把页面或请求来源传给当前 SQL 并在服务器端读取
- 2026-11-05 501浏览
-
- MySQL JSON_TABLE 展开数组时如何保留缺失字段
- 2026-09-10 501浏览
-
- MySQL 分区表怎么处理跨分区唯一键:分区列约束与建表取舍
- 2026-08-30 501浏览
-
- MySQL权限管理设置全攻略
- 2026-03-29 501浏览
-
- MySQL分片实现方法及常见方案解析
- 2025-06-24 501浏览

