BLACKHOLE
存储引擎就像一个“黑洞”,它接受数据但不保存数据,而是直接丢弃。检索操作始终返回空结果。
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 并启用 BLACKHOLE
存储引擎,请在调用 CMake 时使用 -DWITH_BLACKHOLE_STORAGE_ENGINE
选项。
要查看 BLACKHOLE
引擎的源代码,请查看 MySQL 源代码发行版中的 sql
目录。
创建 BLACKHOLE
表时,服务器会在全局数据字典中创建表定义。该表没有任何关联文件。
BLACKHOLE
存储引擎支持所有类型的索引。也就是说,您可以在表定义中包含索引声明。
最大键长度为 3072 字节。
BLACKHOLE
存储引擎不支持分区。
您可以使用 SHOW ENGINES
语句检查 BLACKHOLE
存储引擎是否可用。
插入到 BLACKHOLE
表中的数据不会被存储,但如果启用了基于语句的二进制日志记录,则 SQL 语句会被记录并复制到副本服务器。这可以用作中继器或过滤器机制。
假设您的应用程序需要在副本侧进行过滤规则,但先将所有二进制日志数据传输到副本会导致流量过大。在这种情况下,可以在复制源服务器上设置一个默认存储引擎为 BLACKHOLE
的“虚拟”复制进程,如下图所示:
源服务器将数据写入其二进制日志。“虚拟”mysqld 进程充当副本,应用所需的 replicate-do-*
和 replicate-ignore-*
规则组合,并写入自己的新的、经过过滤的二进制日志。(请参阅 第 19.1.6 节,“复制和二进制日志记录选项和变量”。)此经过过滤的日志将提供给副本。
虚拟进程实际上并不存储任何数据,因此在复制源服务器上运行额外的 mysqld 进程不会产生太多处理开销。可以使用其他副本重复此类设置。
BLACKHOLE
表的 INSERT
触发器按预期工作。但是,由于 BLACKHOLE
表实际上并不存储任何数据,因此 UPDATE
和 DELETE
触发器不会被激活:触发器定义中的 FOR EACH ROW
子句不适用,因为没有行。
BLACKHOLE
存储引擎的其他可能用途包括:
验证转储文件语法。
通过比较启用和未启用二进制日志记录时使用
BLACKHOLE
的性能,来测量二进制日志记录的开销。BLACKHOLE
本质上是一个“无操作”存储引擎,因此它可以用于查找与存储引擎本身无关的性能瓶颈。
BLACKHOLE
引擎是事务感知的,这意味着已提交的事务会被写入二进制日志,而回滚的事务则不会。
Blackhole 引擎和自动递增列
BLACKHOLE
引擎是一个无操作引擎。对使用 BLACKHOLE
的表执行的任何操作都不会生效。在考虑自动递增的主键列的行为时,应牢记这一点。该引擎不会自动递增字段值,也不会保留自动递增字段状态。这对复制有重要影响。
考虑以下复制场景,其中以下所有三个条件都适用:
在源服务器上,有一个 blackhole 表,其中包含一个作为主键的自动递增字段。
在副本上,存在相同的表,但使用 MyISAM 引擎。
在没有在
INSERT
语句本身中显式设置自动递增值或通过使用SET INSERT_ID
语句的情况下,将数据插入到源服务器的表中。
在这种情况下,复制将失败,并在主键列上出现重复条目错误。
在基于语句的复制中,上下文事件中 INSERT_ID
的值始终相同。因此,由于尝试插入具有重复主键列值的行,复制将失败。
在基于行的复制中,引擎为该行返回的值对于每次插入始终相同。这会导致副本尝试使用相同的主键列值重放两个插入日志条目,从而导致复制失败。
列过滤
使用基于行的复制(binlog_format=ROW
)时,支持表中缺少最后几列的副本,如 第 19.5.1.9 节,“源和副本上具有不同表定义的复制” 中所述。
此过滤在副本侧进行,也就是说,列在被过滤掉之前会被复制到副本。在至少两种情况下,不希望将列复制到副本:
如果数据是机密的,则副本服务器不应访问它。
如果源服务器有许多副本,则在发送到副本之前进行过滤可以减少网络流量。
可以使用 BLACKHOLE
引擎实现源列过滤。这与实现源表过滤的方式类似 - 使用 BLACKHOLE
引擎和 --replicate-do-table
或 --replicate-ignore-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;