@clickzetta/cz-cli-linux-x64 0.3.1 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/cz-cli CHANGED
Binary file
@@ -56,10 +56,15 @@ description: |
56
56
  ## 前置依赖
57
57
 
58
58
  - ClickZetta Lakehouse Studio 账户,具备创建同步任务权限
59
- - 源端数据源已在 Studio 中配置,且账号具备 CDC 所需权限
59
+ - 源端数据源已在 Studio 中配置(通过 Studio UI 添加数据源,不是 SQL Storage Connection),且账号具备 CDC 所需权限
60
60
  - Sync VCluster 可用(多表实时同步任务 task_type=281 必须使用 Sync VCluster)
61
61
  - clickzetta-studio-mcp 工具可用(`create_task`、`save_cdc_realtime_task`、`publish_task`、`list_data_sources`、`LH_show_object_list` 等)
62
62
 
63
+ > ⚠️ **重要区分**:CDC 多表同步使用 **Studio 数据源**(通过 Studio UI 或 API 配置),不是 SQL 的 `CREATE STORAGE CONNECTION`。
64
+ > - `CREATE STORAGE CONNECTION` 仅支持对象存储类型(OSS/COS/S3)和 Kafka
65
+ > - MySQL / PostgreSQL 等关系数据库的连接通过 **Studio 数据源管理** 配置
66
+ > - 使用 `list_data_sources` API 查看已配置的数据源
67
+
63
68
  ## 源端数据库准备
64
69
 
65
70
  ### MySQL 参数要求
@@ -359,8 +364,9 @@ PostgreSQL 权限要求(建议用管理员账号执行):
359
364
 
360
365
  | 问题 | 排查方向 |
361
366
  |------|---------|
367
+ | `CREATE STORAGE CONNECTION TYPE MYSQL` 报错 | ❌ ClickZetta 不支持 MySQL/PostgreSQL 类型的 Storage Connection。CDC 数据源通过 **Studio UI 数据源管理** 配置,不是 SQL 命令 |
362
368
  | 任务创建失败 | 检查是否有可用 Sync VCluster |
363
- | 源端连接失败 | 检查数据源配置、网络可达性、账号权限 |
369
+ | 源端连接失败 | 检查 Studio 中数据源配置、网络可达性、账号权限 |
364
370
  | Binlog 读取失败 | 确认 MySQL `log_bin=ON`、`binlog_format=ROW`、`binlog_row_image=FULL` |
365
371
  | WAL 读取失败 | 确认 PostgreSQL `wal_level=logical`,slot 未被其他任务占用 |
366
372
  | Slot 启动冲突 | 不同任务不要复用同一个 slot,检查是否有其他运行中任务占用 |
@@ -442,6 +448,7 @@ PostgreSQL 权限要求(建议用管理员账号执行):
442
448
 
443
449
  ## 已知局限
444
450
 
451
+ - **不支持 SQL 创建 MySQL/PostgreSQL Connection**:`CREATE STORAGE CONNECTION TYPE MYSQL/POSTGRESQL` 会报错 `no connection info factory for connection kind 'STORAGE', type 'mysql'`。CDC 数据源必须通过 Studio UI 数据源管理配置
445
452
  - Schema Evolution 暂不支持变更字段类型、不支持自动新增表
446
453
  - 仅支持带主键(PK)字段的表,非 PK 表不支持同步
447
454
  - 源端不同库表中若存在主键相同的数据,同步结果会异常
@@ -41,7 +41,7 @@ description: |
41
41
 
42
42
  | 数据源 | 实时性 | 同步范围 | 推荐方式 | 对应 Skill |
43
43
  |--------|--------|---------|---------|-----------|
44
- | Kafka | 实时/准实时 | 单 topic | PIPE 持续导入 | `clickzetta-kafka-ingest-pipeline` |
44
+ | Kafka | 实时/准实时 | 单 topic | Kafka PIPE 持续导入(SQL) | `clickzetta-kafka-ingest-pipeline` |
45
45
  | Kafka | 实时 | 多 topic | Studio 实时同步 | `clickzetta-realtime-sync-pipeline` |
46
46
  | 对象存储 (OSS/S3/COS) | 准实时/批量 | 文件持续到达 | PIPE 持续导入 | `clickzetta-oss-ingest-pipeline` |
47
47
  | 对象存储 | 一次性 | 批量文件 | COPY INTO 命令 | `clickzetta-file-import-pipeline`(COPY INTO 部分) |
@@ -24,8 +24,8 @@ description: |
24
24
  **不要问问卷式问题。先动手看数据,再给出有依据的选择题。**
25
25
 
26
26
  用户最多只需要回答 2 个问题:
27
- 1. 选择 agent 给出的方案选项(A/B/C)
28
- 2. 补充 agent 看不到的信息(业务用途、查询场景)
27
+ 1. 选择给出的方案选项(A/B/C)
28
+ 2. 补充看不到的信息(业务用途、查询场景)
29
29
 
30
30
  ---
31
31
 
@@ -72,7 +72,7 @@ SELECT * FROM <schema>.<table> LIMIT 5;
72
72
 
73
73
  基于探索结果,向用户呈现三部分内容:
74
74
 
75
- ### 1. 数据现状摘要(agent 自己总结,不问用户)
75
+ ### 1. 数据现状摘要(自主总结,不问用户)
76
76
 
77
77
  ```
78
78
  我看了一下你的数据:
@@ -52,6 +52,7 @@ SHOW TABLES IN silver WHERE table_name = 'orders_daily';
52
52
  INTERVAL 支持的单位:`SECOND`、`MINUTE`、`HOUR`、`DAY`,最小值为 1 分钟。
53
53
 
54
54
  > 建议使用 GP 型集群刷新动态表。动态表刷新过程中会自动执行小文件合并,AP 型集群不支持此功能。
55
+ > ⚠️ **VCluster 类型限制**:创建动态表时如果指定了 AP 型集群(如 `default_ap`),刷新仍可执行但不会进行小文件合并,长期运行可能导致查询性能下降。建议始终使用 GP 型集群(如 `default`)。
55
56
 
56
57
  ### 开启增量刷新的前提
57
58
 
@@ -60,6 +61,29 @@ INTERVAL 支持的单位:`SECOND`、`MINUTE`、`HOUR`、`DAY`,最小值为 1
60
61
  ALTER TABLE bronze.raw_orders SET PROPERTIES ('change_tracking' = 'true');
61
62
  ```
62
63
 
64
+ ### 增量刷新 vs 全量刷新
65
+
66
+ 通过 `SHOW DYNAMIC TABLE REFRESH HISTORY` 的 `refresh_mode` 字段可查看刷新模式:
67
+ - `INCREMENTAL`:增量刷新(仅处理变更数据,高效)
68
+ - `FULL`:全量刷新(重新计算所有数据)
69
+ - `NO_DATA`:无数据变更,跳过刷新
70
+
71
+ **触发全量刷新的条件**:
72
+ | 条件 | 说明 |
73
+ |---|---|
74
+ | 源表未开启 `change_tracking` | 系统无法识别增量数据 |
75
+ | 查询含不支持增量的算子 | 如某些复杂 JOIN、子查询 |
76
+ | `CREATE OR REPLACE` 修改了计算逻辑 | 如修改 WHERE、GROUP BY、JOIN key |
77
+ | 手动设置强制全量 | `SET cz.optimizer.incremental.force.full.refresh = true` |
78
+ | 维度表变更 | 被 JOIN 的维度表数据变化时,增量结果可能不一致 |
79
+
80
+ **确认是否支持增量刷新**:
81
+ ```sql
82
+ SET cz.optimizer.explain.can.incrementalize = true;
83
+ EXPLAIN REFRESH DYNAMIC TABLE my_dt;
84
+ -- 查看 CanBeIncrementalized 字段:Yes = 支持增量,No = 不支持(会给出原因)
85
+ ```
86
+
63
87
  ---
64
88
 
65
89
  ## dt-creator/
@@ -77,10 +101,12 @@ Dynamic Table 最佳实践与避坑指南(维度表 JOIN 场景、性能优化
77
101
 
78
102
  | 问题 | 原因 | 解决方案 |
79
103
  |---|---|---|
80
- | 刷新一直是 FULL 模式 | 源表未开启 change_tracking,或查询含不支持增量的算子 | 开启 change_tracking;参考 sql-limitations.md |
104
+ | 刷新一直是 FULL 模式 | 源表未开启 change_tracking,或查询含不支持增量的算子 | 开启 change_tracking;用 `EXPLAIN REFRESH` 检查 |
81
105
  | 刷新延迟超过预期 | VCluster 资源不足,或查询复杂度高 | 升级 VCluster 规格;拆分管道 |
82
106
  | `SUSPEND` 后数据不更新 | 已暂停 | 执行 `ALTER DYNAMIC TABLE ... RESUME` |
83
107
  | 依赖链中下游不刷新 | 上游 Dynamic Table 刷新失败 | 先修复上游,再手动 `REFRESH` 下游 |
84
108
  | 删除报错 | 有下游 Dynamic Table 依赖 | 先删除下游,再删除上游 |
85
109
  | 增量结果与全量不一致 | 维度表变更未触发重算 | 执行全量刷新:`SET cz.optimizer.incremental.force.full.refresh = true` |
86
110
  | 状态表损坏 | 系统异常 | `SET cz.optimizer.incremental.rebuild.rule.based.state.table = true` |
111
+ | 手动 REFRESH 后历史未显示 | 刷新历史有短暂延迟 | 等待几秒后重新查询 `SHOW DYNAMIC TABLE REFRESH HISTORY` |
112
+ | AP 集群刷新后查询变慢 | AP 集群不支持小文件合并 | 改用 GP 型集群(`CREATE OR REPLACE` 重建) |
@@ -14,11 +14,14 @@ description: |
14
14
 
15
15
  ### 步骤 1:获取源文件并上传到 Volume
16
16
  根据数据来源选择对应方式:
17
- - HTTP/HTTPS URL:使用 `put_file_to_volume` source_path 参数直接传入 URL,工具会自动下载并上传
18
- - 本地文件:使用 `put_file_to_volume` 指定 source_path 为本地路径
19
- - Volume 路径(`volume://vol_name/path`):文件已在 Volume 上,跳过此步骤
17
+ - **HTTP/HTTPS URL**:需要先用外部工具下载到本地,然后用 `PUT` 命令上传到 User Volume
18
+ - **本地文件**:执行 SQL `PUT '/local/path/file.csv' TO USER VOLUME` 上传
19
+ - **Volume 路径**:文件已在 Volume 上,跳过此步骤
20
+ - **外部 Volume(OSS/S3/COS)**:文件已在外部 Volume,直接使用
20
21
  - 记录上传后的 Volume 名称和文件名,后续步骤需要
21
22
 
23
+ > ⚠️ **注意**:文件上传操作参考 `clickzetta-volume-manager` skill。
24
+
22
25
  ### 步骤 2:推断文件格式
23
26
  根据文件扩展名推断格式(ClickZetta COPY INTO 支持的格式):
24
27
  - `.csv`, `.tsv`, `.txt` → CSV 格式
@@ -26,48 +29,54 @@ description: |
26
29
  - `.parquet`, `.pq` → PARQUET 格式
27
30
  - `.orc` → ORC 格式
28
31
  - `.bson` → BSON 格式
29
- 如果扩展名不明确,使用 `preview_volume_data` 预览文件内容来确认格式和 schema。
32
+ 如果扩展名不明确,执行 `SELECT FROM VOLUME ... USING format` 预览文件内容来确认格式和 schema。
30
33
 
31
34
  ### 步骤 3:确认或创建目标表
32
35
  根据写入模式处理目标表:
33
- - **create 模式**:表必须不存在。使用 `preview_volume_data` 推断 schema,然后用 `create_table` 创建表
34
- - **append 模式**:表必须已存在。用 `desc_object`(object_type='TABLE') 确认表存在并检查列兼容性
35
- - **overwrite 模式**:表存在则先清空。用 `write_query` 执行 `TRUNCATE TABLE table_name`,再执行 COPY INTO
36
+ - **create 模式**:表必须不存在。执行 `SELECT FROM VOLUME ... LIMIT 5` 推断 schema,然后执行 `CREATE TABLE` 创建表
37
+ - **append 模式**:表必须已存在。用 `DESC TABLE <table_name>` 确认表存在并检查列兼容性
38
+ - **overwrite 模式**:表存在则先清空。执行 `TRUNCATE TABLE table_name`,再执行 COPY INTO(⚠️ 不支持 `COPY OVERWRITE INTO` 语法)
36
39
 
37
40
  ### 步骤 4:执行 COPY INTO 导入数据
38
- 使用 `write_query` 执行 COPY INTO 语句。核心语法:
41
+ 执行 COPY INTO 语句。核心语法:
39
42
 
40
43
  ```sql
41
44
  COPY INTO target_table
42
45
  FROM VOLUME volume_name
43
46
  USING format_type
47
+ OPTIONS('option_name' = 'value')
44
48
  FILES('filename');
45
49
  ```
46
50
 
47
- 对于 USER VOLUME(通过 put_file_to_volume 上传的文件):
51
+ 对于 USER VOLUME(通过 PUT 命令上传的文件):
48
52
  ```sql
49
53
  COPY INTO target_table
50
54
  FROM USER VOLUME
51
55
  USING CSV
56
+ OPTIONS('header' = 'true')
52
57
  FILES('uploaded_filename');
53
58
  ```
54
59
 
55
60
  CSV 格式可附加 OPTIONS:
56
61
  ```sql
57
62
  COPY INTO target_table
58
- FROM VOLUME vol USING CSV
59
- FILES('data.csv')
60
- OPTIONS('header'='true', 'sep'=',', 'quote'='"', 'nullValue'='');
63
+ FROM VOLUME vol
64
+ USING CSV
65
+ OPTIONS('header' = 'true', 'sep' = ',', 'quote' = '"', 'nullValue' = '')
66
+ FILES('data.csv');
61
67
  ```
62
68
 
63
- overwrite 模式使用 COPY OVERWRITE:
69
+ ⚠️ **语法顺序要求**:`OPTIONS` 必须在 `FILES` 之前,否则报错 `Syntax error - missing EQ at '('`
70
+
71
+ overwrite 模式(⚠️ 不支持 `COPY OVERWRITE INTO`):
64
72
  ```sql
65
- COPY OVERWRITE INTO target_table
66
- FROM VOLUME vol USING CSV FILES('data.csv');
73
+ -- 正确方式:先 TRUNCATE 再 COPY
74
+ TRUNCATE TABLE target_table;
75
+ COPY INTO target_table FROM VOLUME vol USING CSV FILES('data.csv');
67
76
  ```
68
77
 
69
78
  ### 步骤 5:验证导入结果
70
- 使用 `read_query` 执行验证查询:
79
+ 执行验证查询:
71
80
  ```sql
72
81
  SELECT COUNT(*) as row_count FROM target_table;
73
82
  SELECT * FROM target_table LIMIT 5;
@@ -77,41 +86,71 @@ SELECT * FROM target_table LIMIT 5;
77
86
  ## 示例
78
87
 
79
88
  ### 示例 1:从 URL 导入 CSV 到新表
80
- ```
81
- 1. put_file_to_volume(source_path='https://example.com/data.csv', target_volume='my_vol')
82
- 2. preview_volume_data(source_volume='my_vol', files='data.csv', format='CSV', limit='5')
83
- → 推断出列: id INT, name STRING, value DOUBLE
84
- 3. create_table(table_name='imported_data', columns='id INT, name STRING, value DOUBLE')
85
- 4. write_query(query="COPY INTO imported_data FROM VOLUME my_vol USING CSV FILES('data.csv') OPTIONS('header'='true')")
86
- 5. read_query(query="SELECT COUNT(*) FROM imported_data")
89
+ ```sql
90
+ -- 1. 下载 URL 文件到本地,然后上传到 User Volume
91
+ PUT '/tmp/data.csv' TO USER VOLUME;
92
+
93
+ -- 2. 预览文件内容推断 schema
94
+ SELECT * FROM USER VOLUME USING CSV OPTIONS('header' = 'true') FILES('data.csv') LIMIT 5;
95
+ -- 推断出列:id INT, name STRING, value DOUBLE
96
+
97
+ -- 3. 创建目标表
98
+ CREATE TABLE imported_data (id INT, name STRING, value DOUBLE);
99
+
100
+ -- 4. 执行 COPY INTO 导入(注意:OPTIONS 必须在 FILES 之前)
101
+ COPY INTO imported_data FROM USER VOLUME USING CSV OPTIONS('header' = 'true') FILES('data.csv');
102
+
103
+ -- 5. 验证导入结果
104
+ SELECT COUNT(*) FROM imported_data;
87
105
  ```
88
106
 
89
107
  ### 示例 2:追加 Parquet 数据到已有表
108
+ ```sql
109
+ -- 1. 上传本地文件到 User Volume
110
+ PUT '/local/new_batch.parquet' TO USER VOLUME;
111
+
112
+ -- 2. 确认目标表存在
113
+ DESC TABLE existing_table;
114
+
115
+ -- 3. 执行 COPY INTO 导入(Parquet 格式通常不需要 OPTIONS)
116
+ COPY INTO existing_table FROM USER VOLUME USING PARQUET FILES('new_batch.parquet');
117
+
118
+ -- 4. 验证导入结果
119
+ SELECT COUNT(*) FROM existing_table;
90
120
  ```
91
- 1. put_file_to_volume(source_path='/local/new_batch.parquet', target_volume='data_vol')
92
- 2. desc_object(object_name='existing_table', object_type='TABLE') → 确认表存在
93
- 3. write_query(query="COPY INTO existing_table FROM VOLUME data_vol USING PARQUET FILES('new_batch.parquet')")
94
- 4. read_query(query="SELECT COUNT(*) FROM existing_table")
121
+
122
+ ### 示例 3:从外部 Volume(OSS)导入
123
+ ```sql
124
+ -- 1. 查看 Volume 中的文件列表
125
+ SHOW VOLUME DIRECTORY my_oss_volume;
126
+
127
+ -- 2. 预览文件内容
128
+ SELECT * FROM VOLUME my_oss_volume USING CSV OPTIONS('header' = 'true') FILES('data.csv') LIMIT 5;
129
+
130
+ -- 3. 创建目标表并导入(注意:OPTIONS 必须在 FILES 之前)
131
+ CREATE TABLE imported_data (col1 INT, col2 STRING);
132
+ COPY INTO imported_data FROM VOLUME my_oss_volume USING CSV OPTIONS('header' = 'true') FILES('data.csv');
95
133
  ```
96
134
 
97
135
  ## 故障排除
98
136
 
99
- 错误:COPY INTO "table not found"
100
- 原因:create 模式下表未创建,或 append 模式下表名拼写错误
101
- 解决方案:先用 `show_object_list`(object_type='TABLES') 确认表是否存在
137
+ | 错误 | 原因 | 解决方案 |
138
+ |------|------|----------|
139
+ | COPY INTO 报 "table not found" | create 模式下表未创建,或 append 模式下表名拼写错误 | 先用 `SHOW TABLES` 确认表是否存在 |
140
+ | COPY INTO 报 "file not found" | FILES 中的文件名与 Volume 上的实际文件名不匹配 | 执行 `SHOW VOLUME DIRECTORY vol_name` 或 `SHOW USER VOLUME DIRECTORY` 确认文件名,注意大小写敏感 |
141
+ | COPY INTO 报语法错误 "missing EQ at '('" | OPTIONS 放在了 FILES 之后 | 调整顺序,确保 `OPTIONS` 在 `FILES` 之前:`USING CSV OPTIONS(...) FILES(...)` |
142
+ | CSV 导入列数不匹配 | CSV 文件有 header 行但未指定 `OPTIONS('header'='true')`,导致 header 被当作数据行 | 添加 `OPTIONS('header' = 'true')`,或检查 CSV 分隔符是否正确(sep 参数) |
143
+ | COPY INTO 报 "schema mismatch" | 文件中的数据类型与目标表列定义不兼容 | 执行 `SELECT FROM VOLUME ... USING format LIMIT 5` 预览实际数据,调整表定义或使用列映射 |
144
+ | overwrite 模式数据未清空 | 使用了 `COPY OVERWRITE INTO` 语法(不支持) | overwrite 模式应先用 `TRUNCATE TABLE` 清空表,再执行 `COPY INTO` |
145
+ | SELECT FROM VOLUME 报错 | 格式不匹配或多格式文件混合 | 确认 USING 后的格式与实际文件格式一致;使用 `FILES()` 指定文件或 `SUBDIRECTORY` 指定子目录 |
146
+ | PUT 命令失败 | 本地文件路径不存在 | 确认本地文件路径正确,文件存在 |
102
147
 
103
- 错误:COPY INTO 报 "file not found"
104
- 原因:FILES 中的文件名与 Volume 上的实际文件名不匹配
105
- 解决方案:用 `list_files_on_volume` 确认文件名,注意大小写敏感
106
-
107
- 错误:CSV 导入列数不匹配
108
- 原因:CSV 文件有 header 行但未指定 OPTIONS(header='true'),导致 header 被当作数据行
109
- 解决方案:添加 OPTIONS(header='true'),或检查 CSV 分隔符是否正确(sep 参数)
148
+ ---
110
149
 
111
- 错误:COPY INTO 报 "schema mismatch"
112
- 原因:文件中的数据类型与目标表列定义不兼容
113
- 解决方案:用 `preview_volume_data` 预览实际数据,调整表定义或使用列映射
150
+ ## 依赖的 Skills
114
151
 
115
- 错误:overwrite 模式数据未清空
116
- 原因:使用了普通 COPY INTO 而非 COPY OVERWRITE INTO
117
- 解决方案:overwrite 模式必须使用 `COPY OVERWRITE INTO` 语法
152
+ | 操作 | 需要加载的 Skill |
153
+ |------|-----------------|
154
+ | 文件上传/下载/删除 | `clickzetta-volume-manager` |
155
+ | 查询 Volume 文件内容 | `clickzetta-volume-manager` |
156
+ | COPY INTO 导入 | 本 Skill |