Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

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

18.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,请使用 CMake 选项 -DWITH_BLACKHOLE_STORAGE_ENGINE

要检查黑洞引擎的源代码,请查看 MySQL 源代码分布的 sql 目录。

当您创建一个黑洞表时,服务器在全局数据字典中创建表定义。没有与表关联的文件。

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

最大键长为 3072 字节。

黑洞存储引擎不支持分区。

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

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

假设您的应用程序需要副本侧过滤规则,但将所有二进制日志数据传输到副本服务器上会导致太多流量。在这种情况下,可以在复制源服务器上设置一个 虚拟 副本进程,其默认存储引擎为黑洞,如下所示:

图 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 进程不会产生太多处理开销。这种设置可以重复使用多个副本。

插入 触发器对于 黑洞 表工作正常。然而,因为 黑洞 表不实际存储任何数据,更新删除 触发器不被激活:触发器定义中的 FOR EACH ROW 子句不适用,因为没有行。

其他可能使用 黑洞 存储引擎的用途包括:

  • 转储文件语法验证。

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

  • 黑洞 基本上是一个 无操作 存储引擎,因此它可以用于查找与存储引擎无关的性能瓶颈。

黑洞 引擎是事务感知的,即提交的事务被写入二进制日志,而回滚的事务不被写入。

黑洞引擎和自动递增列

黑洞 引擎是一个无操作引擎。在使用 黑洞 的表上执行的任何操作都没有效果。这应该在考虑主键列的自动递增行为时被考虑。引擎不自动递增字段值,也不保留自动递增字段状态。这在复制中有重要的影响。

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

  1. 在源服务器上,有一个黑洞表,其中自动递增字段是主键。

  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;