首页 > 解决方案 > 我可以在删除旧分区后立即导入更新分区吗?

问题描述

我有一个名为transactions(简称别名txs)的表,其中包含 1500 万行PARTITIONED BY txs.year数据,这些数据在过去 10 年中累积(大约 1 到 150 万行/年)。此数据的来源是 MySQL 数据库,唯一更改的数据是current year. 我的策略是设置一个每日 CRON 作业,current year以压缩的 CSV 格式(即20XX-txs.csv.gz)导出所有记录,然后使用 AWS Glue/PySpark 将其转换为snappy.parquetformat PARTITIONED BY txs.year

我读过您可以轻松地DROP PARTITIONS使用 ClickHouse(参考)。一件事让我没有任何进一步的解释。他们的文件指出:

从表中删除指定的分区。此查询将分区标记为非活动并完全删除数据,大约在 10 分钟内

我想知道的是:

  1. 10 分钟部分在哪里出现?从我的测试中,我看到分区立即消失了。
  2. 我可以在旧分区之后立即INSERT从新创建的分区更新数据,还是必须等待整整10 分钟才能这样做?snappy.parquetDROPPINGcurrent_year

示例用例:

# STEP 1: Get updated data for current_year
# -----------------------------------------
$ wget https://s3.amazonaws.com/xxx.xxx/2021-txs.snappy.parquet

# STEP 2: Drop existing PARTITION for current_year
# -----------------------------------------
$ clickhouse-client --query="ALTER TABLE txs DROP PARTITION '2021'"

# STEP 3: INSERT updated data for current_year into the table
# -----------------------------------------
$ cat 2021-txs.snappy.parquet | clickhouse-client --query="INSERT INTO txs FORMAT Parquet"

标签: pysparkparquetclickhouse

解决方案


这与您的用例无关。

这是关于从磁盘中删除数据而不是关于表。(用户有时会担心磁盘释放)

此查询将分区标记为非活动并完全删除数据,大约在 10 分钟内。

这是合并的有趣副作用。

使用 DROP PARTITION 立即删除活动部件,但不使用非活动部件。

create table t(a Int64) Engine=MergeTree order by a;
插入 t 值 (1);
select name, active from system.parts where table = 't';
┌─名称──────┬─活跃─┐
│ all_1_1_0 │ 1 │
└────────────┴────────┘

优化表 t 最终;
-- 强制合并生成新部分 all_1_1_1(活动)并留下旧部分
-- 部分 all_1_1_0(非活动)。

select name, active from system.parts where table = 't';
┌─名称──────┬─活跃─┐
│ all_1_1_0 │ 0 │
│ all_1_1_1 │ 1 │
└────────────┴────────┘

alter table t drop partition tuple(); -- 数据被删除
-- 但只有活动部分

从 t 中选择 count();
┌─count()─┐
│ 0 │
└──────────┘

——但非活动部分仍在等待中
-- 后台进程在 8 分钟不活动后删除它们
select name, active from system.parts where table = 't';
┌─名称──────┬─活跃─┐
│ all_1_1_0 │ 0 │
└────────────┴────────┘

ls -1 /var/lib/clickhouse/data/default/t/
all_1_1_0
分离的
format_version.txt

10 - 分钟,实际上 8 (480s) 由 merge_tree 设置 old_parts_lifetime 控制

google translate:不活动的部分不会立即删除,因为在写入新块时,fsync不会调用,即在一段时间内,新块仅位于服务器的 RAM(OS 缓存)中。因此,如果服务器自发重启,新合并的部分可能会丢失或损坏。那么ClickHouse在启动过程中就是在检查parts的完整性,可以检测到问题,把不活跃的parts返回到active list,之后再重新合并。然后将损坏的部分重命名(添加前缀损坏)并移动到分离的文件夹。如果完整性检查在合并的块中没有检测到问题,则重命名原始的非活动块(添加忽略的前缀)并移动到分离的文件夹。


推荐阅读