Paimon通过提供action jar 包的方式来支持诸多复杂功能,其中很重要的一个功能就是merge into,通过该方式可以实现行级别的更新操作
Action jar
pamon-flink-action 是 paimon 的 flink action jar 包,内部封装了很多高级功能,包括merge into、compact、delete、drop_partition 等
下载地址:Index of /groups/snapshots/org/apache/paimon/paimon-flink-action
从apache的快照仓库结合自身的flink和paimon的版本选择即可。在启动了flink集群后,就可以通过flink run 的方式来执行任务
<FLINK_HOME>/bin/flink run \
/path/to/paimon-flink-action-0.8.2.jar \
<action>
<args>
Merge into 使用
Paimon利用mege into可以实现类似于upsert的行级别更新,此外paimon的action工具包中还定义了诸多复杂的功能,使我们对要合并的两张表做一下更复杂的计算操作
Merge into使用前提
- Paimon表必须设有主键
- 目前merge into 只支持flink batch批处理模式
- merge into 操作是不会产生update before记录的,因此对于change-log-producer不建议设置成input
语法参数
merge_into 操作使用“upsert”语义而不是“update”,这意味着如果行存在,则执行更新,否则执行插入。例如,对于非主键表,您可以更新每一列,但对于主键表,如果您想更新主键,则必须插入一个新行,该行的主键与表中的行不同。在这种情况下,“upsert”很有用。merge into的语法可以理解为下面语句。
MERGE INTO target-table
USING source_table | source-expr AS source-alias
ON merge-condition
WHEN MATCHED [AND matched-condition]
THEN UPDATE SET xxx
WHEN MATCHED [AND matched-condition]
THEN DELETE
WHEN NOT MATCHED [AND not_matched_condition]
THEN INSERT VALUES (xxx)
WHEN NOT MATCHED BY SOURCE [AND not-matched-by-source-condition]
THEN UPDATE SET xxx
WHEN NOT MATCHED BY SOURCE [AND not-matched-by-source-condition]
THEN DELETE
可以分为五部分来理解:如何连接、目标表连接上的要干啥、目标表连接不上的要干啥、来源表连接上的要干啥、来源表连接不上的要干啥。flink提交merge into的官网命令如下
<FLINK_HOME>/bin/flink run \
/path/to/paimon-flink-action-0.8.2.jar \
merge_into \
--warehouse <warehouse-path> \
--database <database-name> \
--table <target-table> \
[--target_as <target-table-alias>] \
--source_table <source_table-name> \
[--source_sql <sql> ...]\
--on <merge-condition> \
--merge_actions <matched-upsert,matched-delete,not-matched-insert,not-matched-by-source-upsert,not-matched-by-source-delete> \
--matched_upsert_condition <matched-condition> \
--matched_upsert_set <upsert-changes> \
--matched_delete_condition <matched-condition> \
--not_matched_insert_condition <not-matched-condition> \
--not_matched_insert_values <insert-values> \
--not_matched_by_source_upsert_condition <not-matched-by-source-condition> \
--not_matched_by_source_upsert_set <not-matched-upsert-changes> \
--not_matched_by_source_delete_condition <not-matched-by-source-condition> \
[--catalog_conf <paimon-catalog-conf> [--catalog_conf <paimon-catalog-conf> ...]]
- warehouse、database、table:分别对应目标表的catalog地址、数据库和表名
- source sql:如果没有source表,可以使用sql的方式在提交命令里使用SQL构建source表,如:
bin/flink run \
/opt/model/paimon-flink-action-0.8-20240709.052248-82.jar \
merge-into \
--warehouse hdfs://node001:8020/paimon/fs \
--database default \
--table ws_t \
--source-sql "CREATE CATALOG fs2 WITH ('type'='paimon','warehouse' ='hdfs://node001:8020/paimon/fs2')" \
--source-sql "CREATE DATABASE IF NOT EXISTS fs2.test" \
--source-sql "CREATE TEMPORARY VIEW fs2.test.ws2 AS SELECT id+10 as id,ts,vc FROM ws1" \
--source-table fs2.test.ws2 \
--on " ws_t.id = ws2.id " \
--merge-actions not-matched-insert \
--not-matched-insert-values "*"
- on:两张表进行合并的连接条件
- merge_actions:合并时要执行的操作列表,可以传多个操作,操作之间使用逗号隔开,目前支持五种
-
- matched-upsert:目标表匹配上的执行upsert。
- matched-delete:目标表匹配上的执行删除。
- not-matched-insert:source表没匹配上的插入到目标表。
- not-matched-by-source-upsert:目标表没匹配上的执行upsert。
- not-matched-by-source-delete:目标表没匹配上的执行删除 。
- matched_upsert_condition <matched-condition> :目标表匹配上的数据执行upsert要满足的condition。
- matched_upsert_set <upsert-changes> :目标表匹配上的数据执行upsert的set语句。
- matched_delete_condition <matched-condition>:目标表匹配上的数据执行delete要满足的condition。
- not_matched_insert_condition <not-matched-condition> :目标表匹配上的数据执行insert要满足的condition。
- not_matched_insert_values <insert-values> :目标表匹配上的数据执行insert的具体值,直接插入可以写 "*"。
- not_matched_by_source_upsert_condition <not-matched-by-source-condition> :目标表没有匹配上的数据执行upsert要满足的condition。
- not_matched_by_source_upsert_set <not-matched-upsert-changes> :目标表没有匹配上的数据执行upsert的set语句。
- not_matched_by_source_delete_condition <not-matched-by-source-condition> :目标表没有匹配上的数据执行delete要满足的condition。
这里把condition这个东西理解成where就可以了:where(condititon) 匹配或者匹配上的数据 满足什么条件则set(具体操作)
实际案例
创建测试ws1和ws_t
create table ws1 (
id int,
ts bigint,
vc int,
primary key (id) not ENFORCED
);
insert into ws1 values (1,1,1),(2,2,2),(3,3,3);
create table ws_t (
id int,
ts bigint,
vc int,
primary key (id) not ENFORCED
);
insert into ws_t values (2,2,2),(3,3,3),(4,4,4),(5,5,5);
- 需求一:ws_t 与 ws1 匹配 将 ws_t 中 ts > 2 的 vc 改为 10 ,ts<=2 的删除
bin/flink run \
/opt/model/paimon-flink-action-0.8-20240709.052248-82.jar \
merge-into \
--warehouse hdfs://node001:8020/paimon/fs \
--database default \
--table ws_t \
--source-table default.ws1 \
--on "ws_t.id = ws1.id" \
--merge-actions matched-upsert,matched-delete \
--matched-upsert-condition "ws_t.ts > 2" \
--matched-upsert-set "vc = 10" \
--matched-delete-condition "ws_t.ts <= 2"
- 需求二:ws_t 和 wsl 匹配 id 匹配上的将 ws_t 中 vc + 10 ws1 没匹配上的插入ws_t 中
bin/flink run \
/opt/model/paimon-flink-action-0.8-20240709.052248-82.jar \
merge-into \
--warehouse hdfs://node001:8020/paimon/fs \
--database default \
--table ws_t \
--source-table default.ws1 \
--on "ws_t.id = ws1.id" \
--merge-actions matched-upsert,not-matched-insert \
--matched-upsert-set " vc = ws_t.vc + 10 " \
--not-matched-insert-values "*"
- sql-souce案例:构造ws2表,将ws1的id+10后和ws_t进行匹配,并将source匹配不上的写入ws_t中
bin/flink run \
/opt/model/paimon-flink-action-0.8-20240709.052248-82.jar \
merge-into \
--warehouse hdfs://node001:8020/paimon/fs \
--database default \
--table ws_t \
--source-sql "CREATE CATALOG fs2 WITH ('type'='paimon','warehouse' ='hdfs://node001:8020/paimon/fs2')" \
--source-sql "CREATE DATABASE IF NOT EXISTS fs2.test" \
--source-sql "CREATE TEMPORARY VIEW fs2.test.ws2 AS SELECT id+10 as id,ts,vc FROM ws1" \
--source-table fs2.test.ws2 \
--on " ws_t.id = ws2.id " \
--merge-actions not-matched-insert \
--not-matched-insert-values "*"
1472

被折叠的 条评论
为什么被折叠?



