# 16.6 黑洞存储引擎
这黑洞
存储引擎充当“黑洞”,接受数据但将其丢弃而不存储。检索总是返回空结果:
mysql> CREATE TABLE test(i INT, c CHAR(10)) ENGINE = BLACKHOLE;
Query OK, 0 rows affected (0.03 sec)
mysql> INSERT INTO test VALUES(1,'record one'),(2,'record two');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM test;
Empty set (0.00 sec)
要启用黑洞
存储引擎,如果你从源代码构建 MySQL,调用制作与-DWITH_BLACKHOLE_STORAGE_ENGINE
选项。
检查源黑洞
发动机,看看sql
MySQL 源代码分发的目录。
当你创建一个黑洞
表,服务器在全局数据字典中创建表定义。没有与该表关联的文件。
这黑洞
存储引擎支持各种索引。也就是说,您可以在表定义中包含索引声明。
从 MySQL 8.0.27 开始,最大密钥长度为 3072 字节。在 8.0.27 之前,最大密钥长度为 1000 字节。
这黑洞
存储引擎不支持分区。
您可以检查是否黑洞
存储引擎可与显示引擎
陈述。
插入一个黑洞
table 不存储任何数据,但如果启用了基于语句的二进制日志记录,则会记录 SQL 语句并将其复制到副本服务器。这可用作中继器或过滤器机制。
假设您的应用程序需要副本端过滤规则,但首先将所有二进制日志数据传输到副本会导致流量过多。在这种情况下,可以在复制源服务器上设置一个“虚拟”副本进程,其默认存储引擎为黑洞
,描绘如下:
图 16.1 使用 BLACKHOLE 进行过滤的复制

源写入其二进制日志。“假人”mysqld过程充当复制品,应用所需的组合复制做-*
和复制忽略-*
规则,并写入自己的新过滤二进制日志。(看第 17.1.6 节,“复制和二进制日志记录选项和变量”.) 此过滤后的日志提供给副本。
虚拟进程实际上并不存储任何数据,因此运行附加进程所产生的处理开销很小mysqld复制源服务器上的进程。可以使用其他副本重复这种类型的设置。
插入
触发黑洞
表按预期工作。然而,由于黑洞
表实际上并不存储任何数据,更新
和删除
触发器未激活:每一行
触发器定义中的子句不适用,因为没有行。
其他可能的用途黑洞
存储引擎包括:
验证转储文件语法。
通过比较性能来测量二进制日志记录的开销
黑洞
启用和不启用二进制日志记录。黑洞
本质上是一个“无操作”的存储引擎,因此它可以用于查找与存储引擎本身无关的性能瓶颈。这
黑洞
引擎是事务感知的,从某种意义上说,已提交的事务被写入二进制日志,而回滚事务则没有。
黑洞引擎和自动增量列
这黑洞
引擎是无操作引擎。使用对表执行的任何操作黑洞
没有效果。在考虑自动递增的主键列的行为时,应牢记这一点。引擎不会自动递增字段值,也不会保留自动递增字段状态。这对复制具有重要意义。
考虑以下所有三个条件都适用的复制场景:
在源服务器上,有一个黑洞表,其中包含一个作为主键的自动增量字段。
在副本上存在同一个表,但使用的是 MyISAM 引擎。
插入是在源表中执行的,而无需在
插入
声明本身或通过使用设置 INSERT_ID
陈述。在这种情况下,复制失败,主键列出现重复条目错误。
在基于语句的复制中,值
INSERT_ID
在上下文中事件总是相同的。因此,由于尝试为主键列插入具有重复值的行,复制失败。在基于行的复制中,引擎为行返回的值对于每个插入始终是相同的。这导致副本尝试使用相同的主键列值重播两个插入日志条目,因此复制失败。
列过滤
使用基于行的复制时,(binlog_format=行
),支持表中缺少最后一列的副本,如 部分所述第 17.5.1.9 节,“在源和副本上具有不同表定义的复制”.
此过滤在副本端起作用,即列在被过滤掉之前被复制到副本中。至少有两种情况不希望将列复制到副本:
如果数据是机密的,那么副本服务器应该无权访问它。
如果源有许多副本,则在发送到副本之前进行过滤可能会减少网络流量。
源列过滤可以使用
黑洞
引擎。这以类似于实现源表过滤的方式执行 - 通过使用黑洞
发动机和--replicate-do-table
要么--复制忽略表
选项。源的设置是:
CREATE TABLE t1 (public_col_1, ..., public_col_N,
secret_col_1, ..., secret_col_M) ENGINE=MyISAM;
受信任副本的设置是:
CREATE TABLE t1 (public_col_1, ..., public_col_N) ENGINE=BLACKHOLE;
不受信任副本的设置是:
CREATE TABLE t1 (public_col_1, ..., public_col_N) ENGINE=MyISAM;