• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 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)
    

    BLACKHOLE如果要从源代码构建MySQL,则要启用存储引擎,请使用-DWITH_BLACKHOLE_STORAGE_ENGINE选项调用CMake

    要检查BLACKHOLE引擎的源代码,请参见sqlMySQL源代码分发目录。

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

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

    BLACKHOLE存储引擎不支持分区。

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

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

    假设您的应用程序需要从属端过滤规则,但是先将所有二进制日志数据传输到从属端会导致流量过多。在这种情况下,可以在主控主机上设置一个“虚拟”从属进程,其默认存储引擎为BLACKHOLE,如下所示:

    图16.1使用BLACKHOLE进行过滤的复制

    主机写入其二进制日志。的“虚设”的mysqld过程是一个从机,施加的所需组合replicate-do-*replicate-ignore-*规则,并写入它自己的新的,过滤二进制日志。(请参见“复制和二进制日志记录选项和变量”。)此过滤后的日志提供给从属服务器。

    虚拟进程实际上并不存储任何数据,因此在复制主控主机上运行附加的mysqld进程几乎不会产生处理开销。可以使用其他复制从属重复这种设置。

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

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

    • 验证转储文件语法。
    • 通过比较BLACKHOLE启用和未启用二进制日志记录时的性能来测量二进制日志记录的开销。
    • BLACKHOLE本质上是一个“无操作”存储引擎,因此它可用于查找与存储引擎本身无关的性能瓶颈。

    BLACKHOLE引擎是事务感知的,从某种意义上说,已提交的事务将被写入二进制日志,而回滚的事务则不会。

    黑洞引擎和自动增量列

    黑洞引擎是无操作引擎。使用Blackhole在表上执行的任何操作均无效。在考虑自动递增的主键列的行为时应牢记这一点。引擎不会自动增加字段值,并且不会保留自动增加字段状态。这在复制中具有重要意义。

    考虑以下所有三个条件均适用的复制方案:

    1. 在主服务器上,存在一个黑洞表,该表具有作为主键的自动增量字段。
    2. 在从站上,存在相同的表,但是使用MyISAM引擎。
    3. 无需在INSERT语句本身或通过使用SET INSERT_ID语句来显式设置自动增量值的情况下,即可执行插入到主表中的操作。

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

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

    在基于行的复制中,引擎为该行返回的值对于每个插入始终是相同的。这将导致从服务器尝试使用主键列的相同值重播两个插入日志条目,因此复制将失败。

    列过滤

    使用基于行的复制(binlog_format=ROW)时,支持第一个表中缺少最后一列的从属服务器,如“在主服务器和从属服务器上使用不同的表定义进行复制”中所述。

    这种过滤在从属端起作用,即,在将列过滤掉之前,将这些列复制到从属端。至少有两种情况不希望将列复制到从属服务器:

    1. 如果数据是机密的,则从属服务器不应访问它。
    2. 如果主节点有许多从节点,则在发送给从节点之前进行过滤可能会减少网络流量。

    主列过滤可以使用BLACKHOLE引擎来实现。通过使用BLACKHOLE引擎和--replicate-do-tableor --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;