跳到主要内容
跳到主要内容

Buffer 表引擎

将要写入的数据缓冲在 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 和 max_bytes

从缓冲区刷新数据的条件。

可选引擎参数:

flush_time、flush_rows 和 flush_bytes

在后台从缓冲区刷新数据的条件(省略或零表示没有 flush* 参数)。

如果满足所有 min* 条件或至少满足一个 max* 条件,则数据将从缓冲区刷新并写入目标表。

此外,如果至少满足一个 flush* 条件,则会在后台启动刷新。这与 max* 不同,因为 flush* 允许您单独配置后台刷新,以避免为 INSERT 查询添加到 Buffer 表的延迟。

min_time、max_time 和 flush_time

自首次写入缓冲区时刻起的时间(秒)条件。

min_rows、max_rows 和 flush_rows

缓冲区中行数的条件。

min_bytes、max_bytes 和 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 结构相同的 merge.hits_buffer 表,并使用 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,并且数据无法在插入前缓冲时,可以使用 Buffer 表,这意味着 INSERT 无法足够快地运行。

请注意,即使对于 Buffer 表,一次插入一行数据也是没有意义的。这将只会产生每秒几千行的速度,而插入更大的数据块可以产生每秒超过一百万行的速度。