缓冲要写入 RAM 的数据,定期将其刷新到另一个表。在读操作期间,同时从缓冲区和另一个表中读取数据。
Buffer(database, table, num_layers, min_time, max_time, min_rows, max_rows, min_bytes, max_bytes)
表引擎参数:
-
database
- 数据库名称。可以使用返回字符串的常量表达式来代替数据库名称。 -
table
– 要将数据刷新到的表。 -
num_layers
– 并行层。在物理上,该表将被表示为num_layers
独立的缓冲区。推荐值:16。 -
min_time
,max_time
,min_rows
,max_rows
,min_bytes
, andmax_bytes
– 从缓冲区刷新数据的条件。
可选引擎参数:
-
flush_time
,flush_rows
,flush_bytes
– 从缓冲区刷新数据的条件,仅在后台发生(省略或零表示无flush*
参数)。
min*
如果满足所有条件或至少一个max*
条件,数据将从缓冲区刷新并写入目标表。
此外,如果在后台启动刷新至少flush*
满足一个条件,这与 不同max*
,因为flush*
允许单独配置后台刷新以避免增加INSERT
(into Buffer
) 查询的延迟。
-
min_time
,max_time
,flush_time
– 从第一次写入缓冲区开始的时间(以秒为单位)的条件。 -
min_rows
,max_rows
,flush_rows
– 缓冲区中行数的条件。 -
min_bytes
,max_bytes
,flush_bytes
– 缓冲区中字节数的条件。
在写操作期间,数据被插入到num_layers
多个随机缓冲区中。或者,如果要插入的数据部分足够大(大于max_rows
或max_bytes
),则将其直接写入目标表,省略缓冲区。
num_layers
为每个缓冲区单独计算刷新数据的条件。例如,如果num_layers = 16
和max_bytes = 100000000
,则最大 RAM 消耗为 1.6 GB。
例子:
CREATE TABLE merge.hits_buffer AS merge.hits ENGINE = Buffer(merge, hits, 16, 10, 100, 10000, 1000000, 10000000, 100000000)
使用与 Buffer 引擎merge.hits_buffer
相同的结构创建表。merge.hits
写入此表时,数据在 RAM 中缓冲,然后写入“merge.hits”表。创建了 16 个缓冲区。如果经过了 100 秒,或者已经写入了一百万行,或者已经写入了 100 MB 数据,则它们中的每个数据都会被刷新;或者如果同时过去了 10 秒并且已经写入了 10,000 行和 10 MB 的数据。例如,如果只写入了一行,那么无论如何都会在 100 秒后刷新。但是如果已经写入了很多行,数据将被更快地刷新。
当服务器停止时,使用DROP TABLE
或DETACH TABLE
,缓冲区数据也被刷新到目标表。
可以在单引号中为数据库和表名设置空字符串。这表明没有目标表。在这种情况下,当达到数据刷新条件时,简单地清除缓冲区。这对于在内存中保留数据窗口可能很有用。
从缓冲区表中读取数据时,会同时处理来自缓冲区和目标表(如果有的话)的数据。请注意,缓冲区表不支持索引。换句话说,缓冲区中的数据被完全扫描,这对于大缓冲区可能会很慢。(对于从属表中的数据,将使用其支持的索引。)
如果 Buffer 表中的列集与从属表中的列集不匹配,则插入两个表中都存在的列子集。
如果缓冲区表和从属表中的列之一的类型不匹配,则会在服务器日志中输入错误消息,并清除缓冲区。如果在刷新缓冲区时从属表不存在,也会发生同样的事情。
注意:在 2021 年 10 月 26 日之前发布的版本中,在 Buffer 表上运行 ALTER 会导致Block structure mismatch
错误,因此删除 Buffer 表然后重新创建是唯一的选择。建议在尝试对 Buffer 表运行 ALTER 之前检查此错误是否已在的版本中修复。
如果服务器异常重启,缓冲区中的数据就会丢失。
FINAL
并且SAMPLE
对于缓冲区表不能正常工作。这些条件被传递到目标表,但不用于处理缓冲区中的数据。如果需要这些功能,我们建议仅使用缓冲区表进行写入,同时从目标表中读取。
向缓冲区添加数据时,其中一个缓冲区被锁定。如果同时从表中执行读取操作,这会导致延迟。
插入 Buffer 表的数据可能会以不同的顺序和不同的块最终出现在从属表中。因此,很难使用 Buffer 表正确写入 CollapsingMergeTree。为避免出现问题,可以设置num_layers
为 1。
如果目标表被复制,则在写入 Buffer 表时,复制表的一些预期特征会丢失。对数据部分的行顺序和大小的随机更改会导致重复数据删除停止工作,这意味着不可能对复制表进行可靠的“恰好一次”写入。
由于这些缺点,我们只能建议在极少数情况下使用 Buffer 表。
当在一个单位时间内从大量服务器接收到过多的 INSERT 并且数据在插入之前无法缓冲,这意味着 INSERT 不能足够快地运行时,使用缓冲表。
请注意,一次插入一行数据是没有意义的,即使对于 Buffer 表也是如此。这只会产生每秒几千行的速度,而插入更大的数据块每秒可以产生超过一百万行。
示例:
--创建一个来源表
create table tb_user(uid Int8 , name String) engine=TinyLog ;
--创建一个缓存表
CREATE TABLE tb_user_buffer AS tb_user ENGINE = Buffer(test, tb_user, 16, 20, 200, 20000, 2000000, 20000000, 200000000) ;
--向缓存表中插入数据
insert into tb_user_buffer values(1,'zts'),(2,'lst') ,(3,'wyw') ;
--等待以后查看目标表中的数据
select * from tb_user ;
SELECT *
FROM tb_user
Query id: 166285c1-db48-4e96-8a86-022d5b5b8dfd
┌─uid─┬─name─┐
│ 1 │ zts │
│ 2 │ lst │
│ 3 │ wyw │
└─────┴──────┘
3 rows in set. Elapsed: 0.003 sec.