跳转到主要内容
将待写入的数据缓存在 RAM 中,并定期将其刷新到另一张表。读取时,会同时从缓冲区和另一张表中读取数据。
建议启用异步插入,作为 Buffer 表引擎的替代方案。
Buffer(database, table, num_layers, min_time, max_time, min_rows, max_rows, min_bytes, max_bytes [,flush_time [,flush_rows [,flush_bytes]]])

引擎参数

database

database – 数据库名称。你可以使用 currentDatabase() 或其他返回字符串的常量表达式。

table

table – 用于将数据刷写到的表。

num_layers

num_layers – 并行层级。从物理上看,该表会表现为 num_layers 个相互独立的缓冲区层。

min_time, max_time, min_rows, max_rows, min_bytes, and max_bytes

控制缓冲区数据刷写的条件。

可选引擎参数

flush_time, flush_rows, and flush_bytes

在后台从缓冲区刷写数据的条件 (省略或设为零表示不使用 flush* 参数) 。 如果满足全部 min* 条件,或至少满足一个 max* 条件,数据就会从缓冲区刷写并写入目标表。 此外,如果至少满足一个 flush* 条件,也会在后台发起刷写。这与 max* 不同,因为 flush* 允许你单独配置后台刷写,从而避免为向 Buffer 表执行 INSERT 查询增加延迟。

min_time, max_time, and flush_time

从首次写入缓冲区开始计算、以秒为单位的时间条件。

min_rows, max_rows, and flush_rows

缓冲区中行数的条件。

min_bytes, max_bytes, and flush_bytes

用于限定缓冲区中字节数的条件。 在写入过程中,数据会被插入到一个或多个随机缓冲区中 (由 num_layers 配置) 。或者,如果要插入的数据分区片段足够大 (大于 max_rowsmax_bytes) ,则会直接写入目标表,跳过缓冲区。 数据刷写的条件会针对 num_layers 个缓冲区中的每一个分别计算。例如,如果 num_layers = 16max_bytes = 100000000,则最大的 RAM 消耗量为 1.6 GB。 示例:
CREATE TABLE merge.hits_buffer AS merge.hits ENGINE = Buffer(merge, hits, 1, 10, 100, 10000, 1000000, 10000000, 100000000)
创建一个与 merge.hits 结构相同、使用 Buffer 引擎的 merge.hits_buffer 表。向该表写入时,数据会先缓存在 RAM 中,随后写入 merge.hits 表。系统会创建一个缓冲区,并在满足以下任一条件时将数据刷写出去:
  • 距离上次刷写已过去 100 秒 (max_time) 或
  • 已写入 100 万行 (max_rows) 或
  • 已写入 100 MB 数据 (max_bytes) 或
  • 已过去 10 秒 (min_time) ,且已写入 10,000 行 (min_rows) 和 10 MB (min_bytes) 数据
例如,如果只写入了一行数据,那么无论如何,100 秒后它都会被刷写。但如果写入了很多行,数据就会更早刷写。 当服务器停止,或执行 DROP TABLEDETACH TABLE 时,缓冲的数据也会被刷写到目标表。 你可以将数据库名和表名设置为空字符串 (使用单引号) 。这表示不存在目标表。在这种情况下,当达到数据刷写条件时,缓冲区只会被直接清空。这对于在内存中保留一个数据窗口可能很有用。 从 Buffer 表读取时,会同时处理缓冲区中的数据和目标表中的数据 (如果目标表存在) 。 请注意,Buffer 表不支持索引。换句话说,缓冲区中的数据会被全表扫描,这在缓冲区较大时可能会很慢。 (对于目标表中的数据,则会使用其支持的索引。) 如果 Buffer 表中的列集合与目标表中的列集合不匹配,则会插入两个表中共同存在的列子集。 如果 Buffer 表中的某一列与目标表中对应列的类型不匹配,则会在服务器日志中记录一条错误消息,并清空缓冲区。 如果在刷写缓冲区时目标表不存在,也会发生同样的情况。
在 2021 年 10 月 26 日之前发布的发行版中,对 Buffer 表执行 ALTER 会导致 Block structure mismatch 错误 (参见 #15117#30565) ,因此唯一的办法是删除 Buffer 表后再重新创建。在尝试对 Buffer 表执行 ALTER 之前,请先确认你的发行版中该错误已修复。
如果服务器异常重启,缓冲区中的数据会丢失。 FINALSAMPLE 对 Buffer 表无法正常工作。这些条件会传递给目标表,但不会用于处理缓冲区中的数据。如果需要这些功能,我们建议仅将 Buffer 表用于写入,而从目标表读取。 向 Buffer 表写入数据时,其中一个缓冲区会被锁定。如果同时正在从该表执行读取操作,这会导致延迟。 插入到 Buffer 表中的数据,最终进入目标表时,其顺序和所在块都可能不同。因此,很难正确地使用 Buffer 表向 CollapsingMergeTree 写入数据。为避免问题,你可以将 num_layers 设置为 1。 如果目标表是复制表,那么通过写入 Buffer 表会丢失复制表的一些预期特性。行顺序和数据分区片段大小的随机变化会导致数据去重失效,这意味着无法对复制表实现可靠的“恰好一次”写入。 由于这些缺点,我们只建议在极少数情况下使用 Buffer 表。 当单位时间内从大量服务器接收到过多 INSERT,且无法在插入前先缓冲数据,也就是说 INSERT 执行得不够快时,可以使用 Buffer 表。 请注意,即使对于 Buffer 表,逐行插入数据也并不合理。这样每秒只能达到几千行,而插入更大的数据块时,每秒可超过一百万行。
最后修改于 2026年6月10日