相关文档 下载本手册
PDF(US Letter) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


MySQL 8.4 参考手册  /  备用存储引擎  /  BLACKHOLE 存储引擎

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,要启用 BLACKHOLE 存储引擎,请使用 -DWITH_BLACKHOLE_STORAGE_ENGINE 选项调用 CMake

要检查 BLACKHOLE 引擎的源代码,请查看 MySQL 源代码发行版中的 sql 目录。

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

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

最大键长度为 3072 字节。

BLACKHOLE 存储引擎不支持分区。

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

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

假设您的应用程序需要副本侧过滤规则,但先将所有二进制日志数据传输到副本会导致流量过大。在这种情况下,可以在复制源服务器上设置一个默认存储引擎为 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.

源写入其二进制日志。“虚拟”mysqld 进程充当副本,应用所需的 replicate-do-*replicate-ignore-* 规则组合,并写入自己的新的、经过过滤的二进制日志。(请参阅 第 19.1.6 节“复制和二进制日志记录选项和变量”。)此过滤后的日志将提供给副本。

虚拟进程实际上不存储任何数据,因此在复制源服务器上运行额外的 mysqld 进程不会产生多少处理开销。可以使用其他副本重复这种类型的设置。

BLACKHOLE 表的 INSERT 触发器按预期工作。但是,由于 BLACKHOLE 表实际上不存储任何数据,因此不会激活 UPDATEDELETE 触发器:触发器定义中的 FOR EACH ROW 子句不适用,因为没有行。

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

  • 验证转储文件语法。

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

  • BLACKHOLE 本质上是一个“无操作”存储引擎,因此它可以用于查找与存储引擎本身无关的性能瓶颈。

BLACKHOLE 引擎是事务感知的,这意味着已提交的事务会写入二进制日志,而回滚的事务则不会。

Blackhole 引擎和自动递增列

BLACKHOLE 引擎是一个无操作引擎。对使用 BLACKHOLE 的表执行的任何操作都不会产生任何影响。在考虑自动递增的主键列的行为时,应牢记这一点。该引擎不会自动递增字段值,也不会保留自动递增字段状态。这对复制具有重要意义。

请考虑以下复制场景,其中以下所有三个条件都适用:

  1. 源服务器上有一个 blackhole 表,其中包含一个作为主键的自动递增字段。

  2. 在副本上,存在相同的表,但使用 MyISAM 引擎。

  3. 在未在 INSERT 语句本身中显式设置自动递增值或未通过使用 SET INSERT_ID 语句的情况下,将数据插入到源表中。

在这种情况下,复制将失败,并在主键列上出现重复条目错误。

在基于语句的复制中,上下文事件中 INSERT_ID 的值始终相同。因此,由于尝试插入主键列的值重复的行,复制将失败。

在基于行的复制中,引擎为每一行返回的值对于每次插入始终相同。这会导致副本尝试使用主键列的相同值重放两个插入日志条目,从而导致复制失败。

列过滤

使用基于行的复制时(binlog_format=ROW),支持副本中缺少表中最后一列的情况,如 第 19.5.1.9 节“源和副本上具有不同表定义的复制” 中所述。

此过滤在副本端进行,也就是说,列在过滤掉之前会被复制到副本。至少有两种情况下不希望将列复制到副本:

  1. 如果数据是机密的,则副本服务器不应访问它。

  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;