Skip to content

Commit 2118532

Browse files
committed
merge with master
2 parents e0d5bd1 + b7df2b4 commit 2118532

752 files changed

Lines changed: 69670 additions & 3857 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

AGENTS.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ Prefer running the narrowest tests.
2121

2222
#### Java Tests (surefire)
2323

24-
- Single method: `mvn -pl <module> -Dtest=TestClassName#methodName test`
25-
- Single class: `mvn -pl <module> -Dtest=TestClassName test`
24+
- Single method: `mvn -pl <module> -DwildcardSuites=none -Dtest=TestClassName#methodName test`
25+
- Single class: `mvn -pl <module> -DwildcardSuites=none -Dtest=TestClassName test`
2626

2727
#### Scala Tests (scalatest)
2828

@@ -34,6 +34,18 @@ mvn -pl paimon-spark/paimon-spark-ut -am -Pfast-build -DfailIfNoTests=false \
3434
-Dtest=none test
3535
```
3636

37+
#### Required Maven Profiles
38+
- Spark tests: add `-Pspark3` or `-Pspark4`
39+
- Flink tests: add `-Pflink1` or `-Pflink2`
40+
41+
For example, run a Java test in the Spark UT with Spark 3:
42+
```shell
43+
mvn -pl paimon-spark/paimon-spark-ut -am -Pfast-build -Pspark3 \
44+
-DwildcardSuites=none \
45+
-DfailIfNoTests=false \
46+
-Dtest=SparkChainTableITCase#testChainTable test
47+
```
48+
3749
### Local Iteration Speedup
3850

3951
Use `-Pfast-build` to skip checkstyle, spotless, enforcer, and rat checks (not for final verification):

LICENSE

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,9 @@ paimon-format/src/main/java/org/apache/parquet/hadoop/ParquetFileReader.java
272272
paimon-format/src/main/java/org/apache/parquet/hadoop/ParquetWriter.java
273273
from https://parquet.apache.org/ version 1.14.0
274274

275+
paimon-format/src/main/java/org/apache/paimon/format/ArrowSchemaMetadata.java
276+
from https://arrow.apache.org/ version 15.0.0
277+
275278
paimon-common/src/main/java/org/apache/paimon/data/variant/GenericVariant.java
276279
paimon-common/src/main/java/org/apache/paimon/data/variant/GenericVariantBuilder.java
277280
paimon-common/src/main/java/org/apache/paimon/data/variant/GenericVariantUtil.java

docs/docs/concepts/spec/fileformat.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -849,13 +849,33 @@ BLOB files use the `.blob` extension and have the following structure:
849849
+------------------+
850850
```
851851

852+
Each physical BLOB file stores one logical field. The field can be either `BLOB` or
853+
`ARRAY<BLOB>`. For `ARRAY<BLOB>`, the variable-length data area in an entry uses the
854+
following nested payload:
855+
856+
```
857+
+----------------------+-----------------------------------------------+
858+
| Array Magic Number | 4 bytes (1094861634, Little Endian) |
859+
| Array Version | 1 byte |
860+
| Element Count | 4 bytes (Little Endian) |
861+
| Element Data | Concatenated bytes of all non-null elements |
862+
| Element Length Index | Delta-Varint compressed element lengths |
863+
| Index Length | 4 bytes (Little Endian) |
864+
+----------------------+-----------------------------------------------+
865+
```
866+
867+
An element length of `-1` represents a null array element. At the outer file index
868+
level, `-1` represents a null field and `-2` represents a field placeholder used by
869+
data evolution. An empty array is encoded with an element count of zero and an empty
870+
element index; it is distinct from a null array.
871+
852872
Key features:
853873
- **CRC32 Checksums**: Each blob entry has a CRC32 checksum for data integrity verification
854874
- **Indexed Access**: The index at the end enables efficient random access to any blob in the file
855875
- **Delta-Varint Compression**: The index uses delta-varint compression for space efficiency
856876

857877
Limitations:
858-
1. BLOB format only supports a single BLOB type column per file.
878+
1. BLOB format only supports a single `BLOB` or `ARRAY<BLOB>` field per physical file.
859879
2. BLOB format does not support predicate pushdown.
860880
3. Statistics collection is not supported for BLOB columns.
861881

docs/docs/concepts/system-tables.mdx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -439,16 +439,17 @@ You can query the partition files of the table.
439439
SELECT * FROM my_table$partitions;
440440

441441
/*
442-
+-----------+--------------+-------------------+------------+---------------------+---------------------+------------+------------+---------+---------------+-------+
443-
| partition | record_count | file_size_in_bytes| file_count | last_update_time | created_at | created_by | updated_by | options | total_buckets | done |
444-
+-----------+--------------+-------------------+------------+---------------------+---------------------+------------+------------+---------+---------------+-------+
445-
| {1} | 1 | 645 | 1 | 2024-06-24 10:25:57 | 2024-06-24 10:20:00 | admin | test_user | {} | 1 | false |
446-
+-----------+--------------+-------------------+------------+---------------------+---------------------+------------+------------+---------+---------------+-------+
442+
+-----------+--------------+-------------------+------------+---------------------+---------------------+------------+------------+---------+---------------+-------+----------------------+
443+
| partition | record_count | file_size_in_bytes| file_count | last_update_time | created_at | created_by | updated_by | options | total_buckets | done | deleted_record_count |
444+
+-----------+--------------+-------------------+------------+---------------------+---------------------+------------+------------+---------+---------------+-------+----------------------+
445+
| {1} | 1 | 645 | 1 | 2024-06-24 10:25:57 | 2024-06-24 10:20:00 | admin | test_user | {} | 1 | false | 0 |
446+
+-----------+--------------+-------------------+------------+---------------------+---------------------+------------+------------+---------+---------------+-------+----------------------+
447447
*/
448448
```
449449

450450
**Note**:
451451
- The `created_by`, `created_at`, `updated_by`, and `options` fields are populated from REST catalog audit information. For non-REST catalogs, these fields will be `NULL`.
452+
- The `deleted_record_count` field is the number of records marked deleted by deletion vectors in the partition. It is `0` when the partition has no deletion vectors and `NULL` when legacy deletion vector metadata does not contain cardinality.
452453

453454
### Buckets Table
454455

docs/docs/flink/lineage.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
title: "Data Lineage"
3+
sidebar_position: 13
4+
---
5+
6+
# Data Lineage
7+
8+
Paimon implements [FLIP-314](https://cwiki.apache.org/confluence/spaces/FLINK/pages/255070913/FLIP-314+Support+Customized+Job+Lineage+Listener) to expose lineage information through Flink's native [LineageVertexProvider](https://nightlies.apache.org/flink/flink-docs-stable/docs/internals/data_lineage/) interface. This allows lineage consumers (such as [OpenLineage](https://openlineage.io/docs/integrations/flink/flink2)) to automatically discover Paimon datasets in the Flink job graph.
9+
10+
:::info
11+
Data Lineage support is available only for Flink 2.0 and above.
12+
:::
13+
14+
## Table API / SQL
15+
16+
When using Paimon tables via Flink SQL or Table API, lineage is automatically reported for both source and sink tables.
17+
18+
Apart from the table lineage information provided by Flink natively (name, schema), Paimon enriches each dataset with a namespace and a **config facet** containing core table options and Iceberg metadata options.
19+
20+
:::warning
21+
Full Table API lineage support requires <a href="https://github.com/apache/flink/pull/27727" style="color: #1677ff; text-decoration: underline;">this upstream Flink change</a> which is pending merge. Without it, Flink will not call `getLineageVertex()` for `DataStreamScanProvider` and `DataStreamSinkProvider`, which can lead to potentially missing Paimon input or output datasets. This applies to all Flink 2.x versions that do not yet include this change.
22+
:::
23+
24+
## DataStream API
25+
26+
Paimon also supports lineage for the DataStream API. Lineage is automatically reported for sources built via `FlinkSourceBuilder` and for all sinks that extend `FlinkSink`.
27+
28+
Similar to the Table API, it reports all lineage information including name, namespace, schema facet, and config facet.
29+
30+
## Configuration
31+
32+
To consume lineage events, a [JobStatusChangedListener](https://nightlies.apache.org/flink/flink-docs-master/docs/deployment/advanced/job_status_listener/#configuration) must be added in your Flink configuration.
33+
34+
For example, to configure with OpenLineage:
35+
36+
```
37+
execution.job-status-changed-listeners = io.openlineage.flink.listener.OpenLineageJobStatusChangedListenerFactory
38+
```

docs/docs/flink/procedures.md

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ argument can be omitted. For the above example, the call statement is \
3737
``CALL sys.compact(`table` => 'default.t', options => 'sink.parallelism=4')``.
3838

3939
Specify partitions: we use string to represent partition filter. "," means "AND" and ";" means "OR". For example, if you want
40-
to specify two partitions date=01 and date=02, you need to write 'date=01;date=02'; If you want to specify one partition
40+
to specify two partitions date=01 or date=02, you need to write 'date=01;date=02'; If you want to specify one partition
4141
with date=01 and day=01, you need to write 'date=01,day=01'.
4242

4343
Table options syntax: we use string to represent table options. The format is 'key1=value1,key2=value2...'.
@@ -120,8 +120,8 @@ All available procedures are listed below.
120120
<td>
121121
To compact databases. Arguments:
122122
<li>includingDatabases: to specify databases. You can use regular expression.</li>
123-
<li>mode: compact mode. "divided": start a sink for each table, detecting the new table requires restarting the job;
124-
"combined" (default): start a single combined sink for all tables, the new table will be automatically detected.
123+
<li>mode: compact mode. "divided" (default): start a sink for each table, detecting the new table requires restarting the job;
124+
"combined": start a single combined sink for all tables, the new table will be automatically detected.
125125
</li>
126126
<li>includingTables: to specify tables. You can use regular expression.</li>
127127
<li>excludingTables: to specify tables that are not compacted. You can use regular expression.</li>
@@ -139,6 +139,29 @@ All available procedures are listed below.
139139
compat_strategy => 'full')
140140
</td>
141141
</tr>
142+
<tr>
143+
<td>compact_chain_table</td>
144+
<td>
145+
-- Use named argument<br/>
146+
CALL [catalog.]sys.compact_chain_table(
147+
`table` => 'table',
148+
partition => 'partition',
149+
overwrite => overwrite) <br/><br/>
150+
-- Use indexed argument<br/>
151+
CALL [catalog.]sys.compact_chain_table('table', 'partition') <br/>
152+
CALL [catalog.]sys.compact_chain_table('table', 'partition', overwrite) <br/><br/>
153+
</td>
154+
<td>
155+
To compact chain table by merging snapshot and delta branches into the snapshot branch. Arguments:
156+
<li>table: the target chain table identifier. Cannot be empty.</li>
157+
<li>partition: partition specification format (e.g., 'dt=20250810,hour=22'). Cannot be empty.</li>
158+
<li>overwrite: whether to overwrite if the partition already exists in the snapshot branch. Default is false. Optional.</li>
159+
</td>
160+
<td>
161+
CALL sys.compact_chain_table(`table` => 'default.T', partition => 'dt=20250810,hour=22')<br/><br/>
162+
CALL sys.compact_chain_table('default.T', 'dt=20250810,hour=22', true)
163+
</td>
164+
</tr>
142165
<tr>
143166
<td>create_tag</td>
144167
<td>
@@ -1117,6 +1140,35 @@ All available procedures are listed below.
11171140
`dry_run` => true)
11181141
</td>
11191142
</tr>
1143+
<tr>
1144+
<td>full_text_search</td>
1145+
<td>
1146+
CALL [catalog.]sys.full_text_search(<br/>
1147+
`table` => 'identifier',<br/>
1148+
`column` => 'columnName',<br/>
1149+
query => 'queryJson',<br/>
1150+
top_k => topK,<br/>
1151+
projection => 'col1,col2,__paimon_search_score',<br/>
1152+
options => 'key1=value1;key2=value2')<br/>
1153+
</td>
1154+
<td>
1155+
To perform full-text search on a table and return deterministically ordered JSON rows. Arguments:
1156+
<li>table(required): the target table identifier.</li>
1157+
<li>column(required): the character column to search.</li>
1158+
<li>query(required): native full-text query JSON.</li>
1159+
<li>top_k(required): the maximum number of results, from 1 through 10,000.</li>
1160+
<li>projection(optional): comma-separated result columns. Add <code>__paimon_search_score</code> to return the search relevance score.</li>
1161+
<li>options(optional): additional dynamic options of the table. The query authorization setting cannot be overridden.</li>
1162+
</td>
1163+
<td>
1164+
CALL sys.full_text_search(<br/>
1165+
`table` => 'default.articles',<br/>
1166+
`column` => 'content',<br/>
1167+
query => '{"match":{"column":"content","terms":"paimon lake"}}',<br/>
1168+
top_k => 10,<br/>
1169+
projection => 'id,content,__paimon_search_score')
1170+
</td>
1171+
</tr>
11201172
<tr>
11211173
<td>vector_search</td>
11221174
<td>

docs/docs/maintenance/metrics.md

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Paimon has supported built-in metrics to measure operations of **commits**, **sc
3737

3838
## Metrics List
3939

40-
Below is lists of Paimon built-in metrics. They are summarized into types of scan metrics, commit metrics, write metrics, write buffer metrics and compaction metrics.
40+
Below is lists of Paimon built-in metrics. They are summarized into types of scan metrics, commit metrics, write metrics, write buffer metrics, blob fetch metrics and compaction metrics.
4141

4242
### Scan Metrics
4343

@@ -226,6 +226,85 @@ Below is lists of Paimon built-in metrics. They are summarized into types of sca
226226
</tbody>
227227
</table>
228228

229+
### Blob Fetch Metrics
230+
231+
<table class="table table-bordered">
232+
<thead>
233+
<tr>
234+
<th class="text-left" style="width: 225pt">Metrics Name</th>
235+
<th class="text-left" style="width: 70pt">Type</th>
236+
<th class="text-left" style="width: 300pt">Description</th>
237+
</tr>
238+
</thead>
239+
<tbody>
240+
<tr>
241+
<td>blobFetchTotal</td>
242+
<td>Counter</td>
243+
<td>Total number of blob fetch outcomes handled during write, including successful fetches, failures, and missing resources written as NULL.</td>
244+
</tr>
245+
<tr>
246+
<td>blobFetchSuccess</td>
247+
<td>Counter</td>
248+
<td>Total number of blob fetches that completed successfully.</td>
249+
</tr>
250+
<tr>
251+
<td>blobFetchSuccessBytes</td>
252+
<td>Counter</td>
253+
<td>Total bytes written by successful blob fetches.</td>
254+
</tr>
255+
<tr>
256+
<td>blobFetchNullWritten</td>
257+
<td>Counter</td>
258+
<td>Total number of NULL values written because a blob resource was missing or failed to fetch.</td>
259+
</tr>
260+
<tr>
261+
<td>blobFetchMissingFileNullWritten</td>
262+
<td>Counter</td>
263+
<td>Total number of NULL values written because <code>blob-write-null-on-missing-file</code> handled a missing blob resource.</td>
264+
</tr>
265+
<tr>
266+
<td>blobFetchFailureNullWritten</td>
267+
<td>Counter</td>
268+
<td>Total number of NULL values written because <code>blob-write-null-on-fetch-failure</code> handled a non-404 blob fetch failure.</td>
269+
</tr>
270+
<tr>
271+
<td>blobFetchFailure</td>
272+
<td>Counter</td>
273+
<td>Total number of blob fetch failures that were not written as NULL.</td>
274+
</tr>
275+
<tr>
276+
<td>blobFetchHttpNotFound</td>
277+
<td>Counter</td>
278+
<td>Total number of HTTP 404 blob fetch failures.</td>
279+
</tr>
280+
<tr>
281+
<td>blobFetchHttpClientError</td>
282+
<td>Counter</td>
283+
<td>Total number of non-404 HTTP 4xx blob fetch failures.</td>
284+
</tr>
285+
<tr>
286+
<td>blobFetchHttpServerError</td>
287+
<td>Counter</td>
288+
<td>Total number of HTTP 5xx blob fetch failures.</td>
289+
</tr>
290+
<tr>
291+
<td>blobFetchHttpOtherError</td>
292+
<td>Counter</td>
293+
<td>Total number of blob fetch failures with HTTP status codes outside 4xx and 5xx.</td>
294+
</tr>
295+
<tr>
296+
<td>blobFetchInvalidUri</td>
297+
<td>Counter</td>
298+
<td>Total number of blob fetch failures caused by invalid URIs.</td>
299+
</tr>
300+
<tr>
301+
<td>blobFetchOtherError</td>
302+
<td>Counter</td>
303+
<td>Total number of blob fetch failures that are not classified as HTTP status or invalid URI failures.</td>
304+
</tr>
305+
</tbody>
306+
</table>
307+
229308
### Compaction Metrics
230309

231310
<table class="table table-bordered">
@@ -375,6 +454,11 @@ From Flink Web-UI, go to the committer operator's metrics, it's shown as:
375454
<td>&lt;host&gt;.taskmanager.&lt;tm_id&gt;.&lt;job_name&gt;.&lt;writer_operator_name&gt;.&lt;subtask_index&gt;</td>
376455
<td>paimon.table.&lt;table_name&gt;.writeBuffer</td>
377456
</tr>
457+
<tr>
458+
<td>Blob Fetch Metrics</td>
459+
<td>&lt;host&gt;.taskmanager.&lt;tm_id&gt;.&lt;job_name&gt;.&lt;writer_operator_name&gt;.&lt;subtask_index&gt;</td>
460+
<td>paimon.table.&lt;table_name&gt;.blobFetch</td>
461+
</tr>
378462
<tr>
379463
<td>Compaction Metrics</td>
380464
<td>&lt;host&gt;.taskmanager.&lt;tm_id&gt;.&lt;job_name&gt;.&lt;writer_operator_name&gt;.&lt;subtask_index&gt;</td>

docs/docs/maintenance/write-performance.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ execution.checkpointing.timeout = 60 min
126126
In the initialization of write, the writer of the bucket needs to read all historical files. If there is a bottleneck
127127
here (For example, writing a large number of partitions simultaneously), you can use `sink.writer-coordinator.enabled`
128128
to use a Flink coordinator to cache the read manifest data to accelerate initialization. The cache memory for coordinator
129-
is `sink.writer-coordinator.cache-memory`, default is 1GB in Job Manager.
129+
is `sink.writer-coordinator.cache-memory`, default is 2GB in Job Manager.
130130

131131
The coordinator manifest cache normally holds entries with soft references, so the JVM can reclaim them when the Job
132132
Manager runs low on heap. On a heavily loaded Job Manager this can backfire: the JVM reclaims cached manifests, writers

0 commit comments

Comments
 (0)