黑洞存储引擎充当一个 “黑洞”,接受数据但抛弃它,不存储它。检索总是返回一个空结果:
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 语句将被记录并复制到副本服务器上。这可以作为一个中继或过滤机制。
假设您的应用程序需要副本侧过滤规则,但将所有二进制日志数据传输到副本服务器上会导致太多流量。在这种情况下,可以在复制源服务器上设置一个 “虚拟” 副本进程,其默认存储引擎为黑洞,如下所示:
源服务器写入二进制日志。“虚拟” mysqld 进程充当副本,应用所需的 replicate-do-*
和 replicate-ignore-*
规则,并写入一个新的、过滤后的二进制日志。(见 第 19.1.6 节,“复制和二进制日志选项和变量”。)这个过滤日志将被提供给副本。
虚拟进程不实际存储任何数据,因此在复制源服务器上运行附加的 mysqld 进程不会产生太多处理开销。这种设置可以重复使用多个副本。
插入
触发器对于 黑洞
表工作正常。然而,因为 黑洞
表不实际存储任何数据,更新
和 删除
触发器不被激活:触发器定义中的 FOR EACH ROW
子句不适用,因为没有行。
其他可能使用 黑洞
存储引擎的用途包括:
-
转储文件语法验证。
-
测量二进制日志记录的开销,通过比较启用和禁用二进制日志记录的性能。
-
黑洞
基本上是一个 “无操作” 存储引擎,因此它可以用于查找与存储引擎无关的性能瓶颈。
黑洞
引擎是事务感知的,即提交的事务被写入二进制日志,而回滚的事务不被写入。
黑洞引擎和自动递增列
黑洞
引擎是一个无操作引擎。在使用 黑洞
的表上执行的任何操作都没有效果。这应该在考虑主键列的自动递增行为时被考虑。引擎不自动递增字段值,也不保留自动递增字段状态。这在复制中有重要的影响。
考虑以下复制场景,其中所有三个条件都适用:
-
在源服务器上,有一个黑洞表,其中自动递增字段是主键。
-
在副本上,同一个表存在,但使用 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;