为什么要保存以后无法检索的东西?重点是什么?
3 回答
它在所有 SQL 语句都在所有节点上运行的复制环境中很有用,但您只希望某些节点实际存储结果。这是文档中给出的一个用例:http: //dev.mysql.com/doc/refman/5.0/en/blackhole-storage-engine.html
文档中给出的其他用途包括:
- 验证转储文件语法。
- 通过比较使用 BLACKHOLE 启用和不启用二进制日志记录的性能来测量二进制日志记录的开销。
- BLACKHOLE 本质上是一个“无操作”的存储引擎,因此它可以用于查找与存储引擎本身无关的性能瓶颈。
假设您有两台计算机,每台计算机都运行一个 MySQL 服务器。一台计算机托管主数据库,第二台计算机托管您用作备份的复制从属服务器。
此外,假设您的主服务器包含一些您不想备份的数据库或表。也许它们是高流失率的缓存表,如果丢失它们的内容也没关系。因此,为了节省磁盘空间并避免不必要地使用 CPU、内存和磁盘 IO,您可以使用复制选项来配置从属服务器以忽略影响您不想备份的表的语句。
但是由于复制过滤器只在从服务器上应用,所以在主服务器上执行的所有语句的二进制日志仍然需要通过网络传输。这里浪费了带宽;主服务器正在发送事务的二进制日志,从属服务器在接收到它们后将简单地丢弃它们。我们能否做得更好,并避免不必要的带宽使用?
是的,我们可以,这就是 BLACKHOLE 引擎的用武之地。在运行主服务器的同一台计算机上,我们运行第二个虚拟引擎mysqld
进程,这个托管一个 BLACKHOLE 数据库。我们将这个虚拟进程配置为从主进程的 binlog 进行复制,使用与真正的从属相同的复制选项,并生成自己的 binlog。虚拟进程的 binlog 现在只包含真正的 slave 需要的语句,除了从 binlog 中过滤掉不需要的语句(因为它使用 BLACKHOLE 引擎)之外,它没有做任何实际的工作。最后,我们将真正的从属配置为从虚拟进程的 binlog 中复制,而不是从原始主进程的 binlog 中复制。我们现在已经消除了托管主服务器和从服务器的两台计算机之间不必要的网络流量。
此设置是本段和BLACKHOLE 文档中的图表所描述和说明的(更简洁):
假设你的应用需要slave端过滤规则,但是先将所有二进制日志数据传输到slave会导致流量过大。在这种情况下,可以在 master 主机上设置一个“dummy”从属进程,其默认存储引擎为 BLACKHOLE,如下所示:
除了过滤之外,文档还神秘地暗示使用启用了 binlogging 的 BLACKHOLE 服务器“可以用作中继器......机制”。这个用例在文档中的充实较少,但可以想象一个有意义的场景。例如,假设您有很多从属服务器,它们都位于本地网络上的计算机上,彼此之间具有快速的本地连接,它们都需要从只能通过 Internet 连接的远程从属服务器复制大量数据。您不想让它们全部直接从主盒复制,因为从那时起,您将多次获得相同的数据,并且使用的互联网带宽比您必须使用的多几倍。但假设你也不想让您现有的从服务器中的一个从主服务器复制,而其他从服务器复制该从服务器,可能是因为您的从服务器运行在比主服务器更不可靠的机器上,或者正在运行其他一些可能会杀死机器的进程通过吃掉它所有的 CPU 或内存,并且您不想冒中间从属设备发生软件或硬件故障的风险,从而导致整个从属网络瘫痪。你做什么工作?
一种可能的折衷方案是在您的从属网络中引入一个额外的盒子作为中介,针对可靠性和性能而不是存储进行优化。给它一个小的、可靠的 SSD 驱动器,除了从远程主机复制的进程之外什么都不运行mysqld
,让它生成其他从机可以订阅的二进制日志。而且,当然,设置这个中间从站使用 BLACKHOLE 引擎,这样它就不需要存储空间了。
这和文档中详细描述的中间过滤从属都是边缘情况;大多数 MySQL 用户永远不会发现自己可以从使用这些策略中的任何一个中受益,更不用说受益到足以证明进行实际设置它们的工作的合理性了。但至少在理论上,BLACKHOLE 引擎可用于在复制从属网络中创建一个中间节点作为带宽节约策略,而无需该节点将数据实际存储在磁盘上。
对于在您不想保留的数据上运行触发器很有用。
例如,mysql 目前不支持遍历查询结果 - 因此您可以使用“插入 <blackhole_table> (select col1, col2, col3 from <some_other_table> where )”来实现执行相同工作的解决方案
然后将 am on-insert 触发器添加到该黑洞表中,该表执行您想要在所选数据的“for each”操作中执行的任务。
blackhole 不存储结果,因此无需事后清理,您最终会得到一个简单的 for-each 解决方案。