Branch
https://paimon.apache.org/docs/0.9/maintenance/manage-branches/
paimon借鉴了git的管理机制,在我们开发代码的时候,为了不影响主分支的功能,我们一般会新建一个分支进行迭代,待新分支完善后,合并回主分支,在新的分支做任何数据操作都不会影响主分支。
在paimon中,我们也可以对表创建分支,相当于在当前数据状态下复制出来了一张新的表,我习惯称 新建的表叫做分支表,原表称为主表,两表互不影响,而且能够从分支表上进行合并,将分支表的数据覆盖到主表
维护Branch
创建
创建一个空的分支(数据空的)
bin/flink run \
lib/paimon-flink-action-0.9.0.jar \
create_branch \
--warehouse file:///data/soft/paimon/catalog \
--database default \
--table t_branch \
--branch_name slave
从指定tag创建分支,复制指定tag所有信息,包括数据、快照、schema等
-- 创建tg
bin/flink run \
lib/paimon-flink-action-0.9.0.jar \
create_tag \
--warehouse file:///data/soft/paimon/catalog \
--database default \
--table t_branch \
--tag_name tg
-- 从指定tg创建分支
bin/flink run \
lib/paimon-flink-action-0.9.0.jar \
create_branch \
--warehouse file:///data/soft/paimon/catalog \
--database default \
--table t_branch \
--tag_name tg \
--branch_name slave
删除
-- 删除
bin/flink run \
lib/paimon-flink-action-0.9.0.jar \
delete_branch \
--warehouse file:///data/soft/paimon/catalog \
--database default \
--table t_branch \
--branch_name slave
快进( 覆盖合并)
-- 覆盖合并分支表数据到主表
bin/flink run \
lib/paimon-flink-action-0.9.0.jar \
fast_forward \
--warehouse file:///data/soft/paimon/catalog \
--database default \
--table t_branch \
--branch_name slave
使用Branch
环境创建
CREATE CATALOG fs_catalog WITH (
'type'='paimon',
'warehouse'='file:/data/soft/paimon/catalog'
);
-- 创建之后需要use
use catalog fs_catalog ;
-- 控制批流操作,此处设置为批模式
SET 'execution.runtime-mode' = 'batch';
-- 设置结果展示形式,默认: table,能设为 : tableau、changelog
SET 'sql-client.execution.result-mode' = 'tableau';
测试
-- create Paimon table
CREATE TABLE t_branch (
dt STRING NOT NULL,
name STRING NOT NULL,
amount BIGINT
) PARTITIONED BY (dt);
bin/flink run \
lib/paimon-flink-action-0.9.0.jar \
create_branch \
--warehouse file:///data/soft/paimon/catalog \
--database default \
--table t_branch \
--branch_name slave
Flink SQL> select * from t_branch$branches;
+-----------------+------------------+-----------------------+-------------------------+
| branch_name | created_from_tag | created_from_snapshot | create_time |
+-----------------+------------------+-----------------------+-------------------------+
| slave | <NULL> | <NULL> | 2024-12-19 16:15:01.000 |
+-----------------+------------------+-----------------------+-------------------------+
1 row in set
-- 写入分支表
INSERT INTO `t_branch$branch_slave` VALUES ('20240725', 'apple', 4), ('20240726', 'cherry', 3);
-- 修改分支表
ALTER TABLE t_branch$branch_slave add new_col string;
-- 写入分支表
INSERT INTO `t_branch$branch_slave` VALUES ('20240725', 'apple', 4,'new');
Flink SQL> select * from t_branch$branch_slave;
+----------+--------+--------+---------+
| dt | name | amount | new_col |
+----------+--------+--------+---------+
| 20240725 | apple | 4 | <NULL> |
| 20240725 | apple | 4 | new |
| 20240726 | cherry | 3 | <NULL> |
+----------+--------+--------+---------+
3 rows in set
-- 只有分支表有数据,主表没有
Flink SQL> select * from t_branch;
Empty set
fast_forward
将分支表复制到主表,并且删除主表在分支表创建之后生成的所有快照、标签和schema,将快照、标签和schema从分支表复制到主表,
并且分支表数据覆盖主表数据
,
-- 合并分支表(Fast Forward),删除主表的一切数据,并将分支表的一切数据拷贝到主表
bin/flink run \
lib/paimon-flink-action-0.9.0.jar \
fast_forward \
--warehouse file:///data/soft/paimon/catalog \
--database default \
--table t_branch \
--branch_name slave
-- 合并完成后,我们拥有分支表的所有信息,包括新增的schema(如果涉及schema修改, 合并任务退出后,需要等一会1min才能看到效果。。不知道为什么)
Flink SQL> select * from t_branch;
+----------+--------+--------+---------+
| dt | name | amount | new_col |
+----------+--------+--------+---------+
| 20240726 | cherry | 3 | <NULL> |
| 20240725 | apple | 4 | <NULL> |
| 20240725 | apple | 4 | new |
+----------+--------+--------+---------+
3 rows in set
fallback
假设你创建了一个按日期分区的 Paimon 表。您有一个长时间运行的 streaming job,该作业将记录插入到 Paimon 中,以便及时查询今天的数据。你还有一个每天晚上运行的批处理作业,将昨天更正后的记录插入到 Paimon 中,这样就可以保证数据的精确性。
当你从这个 Paimon 表中查询时,你希望首先读取 batch job 的结果。但是,如果分区(例如,今天的分区)在其结果中不存在,则您希望从流式处理作业的结果中读取。在这种情况下,您可以为流式处理作业创建一个分支,并将 scan.fallback-branch 设置为此流式处理分支。
只能按照分区进行合并。如果一个表没有分区字段,相当于就1个分区,主表永远会覆盖分支表,因此该任务只适合有分区字段的表
-- 清空主表
insert overwrite t_branch/*+ OPTIONS('dynamic-partition-overwrite' = 'false') */ select * from t_branch where false;
bin/flink run \
lib/paimon-flink-action-0.9.0.jar \
create_branch \
--warehouse file:///data/soft/paimon/catalog \
--database default \
--table t_branch \
--branch_name stream
-- 写入分支表
INSERT INTO `t_branch$branch_stream` VALUES ('20240724', 'org4', 4,'new'),('20240725', 'org5', 5,'new');
Flink SQL> select * from t_branch$branch_stream;
+----------+------+--------+---------+
| dt | name | amount | new_col |
+----------+------+--------+---------+
| 20240725 | org5 | 5 | new |
| 20240724 | org4 | 4 | new |
+----------+------+--------+---------+
2 rows in set
-- 写入主表
INSERT INTO `t_branch` VALUES ('20240724', 'app4', 4,'new'),('20240724', 'cherry4', 4,'new');
Flink SQL> select * from t_branch;
+----------+---------+--------+---------+
| dt | name | amount | new_col |
+----------+---------+--------+---------+
| 20240724 | app4 | 4 | new |
| 20240724 | cherry4 | 4 | new |
+----------+---------+--------+---------+
2 rows in set
-- set fallback branch stream,绑定fallback表,按照分区力度进行对比,如果主表从存在使用主表中分区的数据,否则使用从表中分区的数据
ALTER TABLE t_branch SET (
'scan.fallback-branch' = 'stream'
);
-- 我们发现24号的分区使用了主表中的数据,25号分区主表没有,使用了分支表中的数据
Flink SQL> select * from t_branch;
+----------+---------+--------+---------+
| dt | name | amount | new_col |
+----------+---------+--------+---------+
| 20240724 | app4 | 4 | new |
| 20240724 | cherry4 | 4 | new |
| 20240725 | org5 | 5 | new |
+----------+---------+--------+---------+
3 rows in set
-- 取消fallback绑定
Flink SQL> ALTER TABLE t_branch RESET( 'scan.fallback-branch');
[INFO] Execute statement succeed.
Flink SQL> select * from t_branch;
+----------+---------+--------+---------+
| dt | name | amount | new_col |
+----------+---------+--------+---------+
| 20240724 | app4 | 4 | new |
| 20240724 | cherry4 | 4 | new |
+----------+---------+--------+---------+
2 rows in set