Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  Alternative Storage Engines  /  The BLACKHOLE Storage Engine

18.6 BLACKHOLE 存储引擎

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,使用-DWITH_BLACKHOLE_STORAGE_ENGINE 选项来启用 BLACKHOLE 存储引擎。

要查看 BLACKHOLE 引擎的源代码,查阅 MySQL 源代码分发中的 sql 目录。

创建 BLACKHOLE 表时,服务器在全局数据字典中创建表定义。没有关联文件。

BLACKHOLE 存储引擎支持所有类型的索引。也就是说,可以在表定义中包含索引声明。

最大键长度为 3072 字节。

BLACKHOLE 存储引擎不支持分区。

可以使用SHOW ENGINES 语句来检查 BLACKHOLE 存储引擎是否可用。

将数据插入到 BLACKHOLE 表中不存储任何数据,但是如果启用了基于语句的二进制日志记录,SQL 语句将被记录并复制到副本服务器。这可以作为一个重复器或过滤机制。

假设您的应用程序需要副本端过滤规则,但是将所有二进制日志数据传输到副本端结果太多流量。在这种情况下,可以在复制源服务器上设置一个dummy副本进程,使用默认存储引擎为BLACKHOLE,如图所示:

图18.1 使用BLACKHOLE进行过滤

The replication source server uses a source mysqld process and a dummy mysqld process. On the replica, the mysqld process replicates from the dummy mysqld process.

源服务器写入其二进制日志。dummymysqld进程作为副本,应用所需的replicate-do-*replicate-ignore-*规则,并写入新的过滤后的二进制日志。 (参见第19.1.6节,“复制和二进制日志选项和变量”。) 这个过滤后的日志提供给副本。

dummy进程不实际存储任何数据,所以在复制源服务器上运行额外的mysqld进程所需处理开销很小。这种设置可以重复使用多个副本。

INSERT 语句对 BLACKHOLE 表工作正常。然而,因为 BLACKHOLE 表实际上不存储任何数据,UPDATEDELETE 触发器不被激活:触发器定义中的 FOR EACH ROW 子句不适用,因为没有行。

BLACKHOLE 存储引擎的其他可能用途包括:

  • 验证备份文件语法。

  • 通过比较性能,使用 BLACKHOLE 和不启用二进制日志来测量二进制日志的开销。

  • BLACKHOLE 实际上是一个“无操作”存储引擎,所以可以用于找到与存储引擎无关的性能瓶颈。

BLACKHOLE 引擎是事务感知的,已经提交的事务写入到二进制日志中,而回滚的事务不写入。

BLACKHOLE 引擎和自增列

BLACKHOLE 引擎是一个无操作引擎。对使用 BLACKHOLE 的表进行的任何操作都没有效果。这应该在考虑主键列自动递增时考虑到行为。引擎不自动递增字段值,也不保留自增字段状态。这对 replication 有重要影响。

考虑以下复制场景,其中三个条件都满足:

  1. 源服务器上有一张黑洞表,auto increment 字段是主键。

  2. 副本服务器上同样存在这张表,但使用 MyISAM 引擎。

  3. 在源服务器上执行 INSERT 语句时,不会显式设置 auto increment 值,也不使用 SET INSERT_ID 语句。

在这个场景下,复制失败,因为主键列出现重复值错误。

在语句级别复制中,INSERT_ID 的值总是相同。因此,复制失败,因为尝试插入一个主键列重复值的行。

在行级别复制中,引擎总是返回同样的值,每个插入操作都是一样的。这导致副本尝试重新播放两个插入日志条目,使用相同的主键列值,最后复制失败。

列过滤

在使用行级别复制时(binlog_format=ROW第19.5.1.9节,“源和副本服务器上的表定义不同”

这个过滤在副本服务器上工作,即将列复制到副本服务器,然后再过滤。至少有两个情况下,不想将列复制到副本:

  1. 如果数据是机密的,那么副本服务器 shouldn't 有访问权限。

  2. 如果源服务器有很多副本,发送到副本前进行过滤可能减少网络流量。

使用 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;