hudi-agent commented on code in PR #19272:
URL: https://github.com/apache/hudi/pull/19272#discussion_r3729276815


##########
website/blog/2026-08-05-migrating-from-apache-iceberg-to-hudi.md:
##########
@@ -0,0 +1,139 @@
+---
+title: "Migrating from Apache Iceberg to Apache Hudi"
+excerpt: "A practical guide to adopting Apache Hudi on existing Iceberg tables 
— via XTable metadata translation or a one-time rewrite — while keeping every 
Iceberg-based reader working through reverse sync."
+description: "How to migrate Iceberg tables to Apache Hudi with XTable 
metadata conversion or a Spark rewrite, keeping Snowflake, BigQuery and Trino 
Iceberg readers working."
+authors: [sivabalan]
+category: how-to
+image: 
/assets/images/blog/2025-07-02-Lakehouse-Architecture-apache-hudi-and-apache-iceberg.png
+tags:
+- migration
+- apache xtable
+- apache iceberg
+- guide
+---
+
+You can adopt Apache Hudi on an existing Apache Iceberg table either by 
translating its metadata with [Apache XTable](https://xtable.apache.org) — no 
data rewrite, since both formats store data as Parquet files — or via a 
one-time rewrite; and because XTable also works in the reverse direction, 
projecting a Hudi table back out as Iceberg, your existing Iceberg readers can 
keep working after the switch. That second point changes the shape of the whole 
exercise. "Migrating from Iceberg to Hudi" does not have to mean a hard cutover 
of every writer, reader, catalog entry and dashboard on the same weekend. It 
can mean moving just the *write path* to Hudi — to get record-level indexes, 
streaming upserts and built-in table services — while every Snowflake, BigQuery 
or Trino consumer that speaks Iceberg continues reading the same table, unaware 
anything changed underneath.
+
+This guide walks through both migration options with working configuration and 
code, the cutover sequence that de-risks the switch, an honest look at which 
Iceberg features do not map one-to-one, and a validation checklist with a 
rollback story. It is the Iceberg-side companion to our guides on [using Hudi 
with Apache Iceberg via 
XTable](/blog/2026/07/28/using-hudi-with-apache-iceberg-via-xtable) and 
[migrating from Delta Lake to 
Hudi](/blog/2026/08/04/migrating-from-delta-lake-to-hudi).
+
+## Why Teams Move from Iceberg to Hudi
+
+The migrations we see are almost always driven by the write side. Apache 
Iceberg has broad catalog and engine support, and for append-mostly batch 
analytics it serves many teams fine. The friction shows up when workloads 
become mutation-heavy or latency-sensitive:
+
+- **Record-level indexes for fast upserts.** Hudi maintains a [multi-modal 
indexing subsystem](/docs/indexes) — record-level index, bloom filters, 
expression and secondary indexes — that maps record keys to file groups. An 
upsert locates exactly the files it must touch instead of planning a join or 
scan against the target to find matching rows. For CDC pipelines applying 
millions of scattered updates, this is routinely the difference between minutes 
and hours.
+- **Merge-on-Read designed for streaming ingest.** Hudi's MOR tables absorb 
updates as compact log files merged on read, so writers sustain high-frequency 
commits — minute-level or faster from Kafka, Flink or Spark Structured 
Streaming — without churning out rewritten Parquet on every batch.
+- **Built-in table services.** Compaction, clustering, cleaning and file 
sizing are part of the Hudi runtime and run inline or asynchronously without 
external orchestration. With Iceberg, that maintenance is left to engines, 
scheduled Spark procedures or a vendor service — someone has to own it.
+- **CDC-grade change streams.** Hudi tables serve [incremental 
queries](/docs/sql_queries#incremental-query): give me exactly the records that 
changed between two points on the timeline, including before/after images in 
CDC mode. Downstream pipelines chain off tables directly instead of re-reading 
snapshots and diffing.
+
+The gap is measurable. In benchmarks run with the open-source 
[LakeLoader](https://github.com/onehouseinc/lake-loader) framework — Spark 3.5, 
Hudi 1.1.1, Iceberg 1.10.0, on S3 — we observed roughly 4× lower incremental 
write latency for Hudi on a 10 TB partitioned fact table with skewed updates, 
and about 8× lower steady-state latency on Merge-on-Read tables taking sparse, 
column-level updates, with Hudi's record-level index sidestepping the 
full-table-scan merge joins that dominate the alternative write path. The 
workload definitions are format-agnostic and repeatable, so you can rerun the 
comparison on your own update patterns before deciding.
+
+The point is not that Iceberg cannot handle these workloads — it is that 
Hudi's write path, indexing and self-managing services are built for mutable, 
streaming-oriented workloads. If that describes the tables you are running, 
here is how to move them.
+
+## Migrate the Writer, Keep the Readers
+
+The biggest source of migration risk is rarely the table itself — it is the 
long tail of consumers. A warehouse reading through an Iceberg catalog, BI 
dashboards, other teams' Spark jobs. A migration plan that requires all of them 
to change on cutover day is fragile enough that most teams never start.
+
+The two-way XTable pattern removes that requirement:
+
+1. **Writers move to Hudi.** Your ingestion pipeline gains Hudi's upsert 
indexes, MOR streaming writes and table services.
+2. **XTable continuously projects the Hudi table back out as Iceberg.** After 
each Hudi commit (or on a schedule), XTable translates the Hudi timeline into 
Iceberg metadata over the *same* Parquet data files, and its catalog sync can 
keep Hive Metastore or AWS Glue entries current.
+3. **Readers keep reading Iceberg.** Snowflake, BigQuery, Trino Iceberg 
catalogs, anything else that only speaks Iceberg — all keep working. They can 
each move to native Hudi reads later, on their own schedule, or never.
+
+Because the data files are shared and only lightweight metadata is generated, 
the reverse projection is cheap and stays fresh. The migration decision 
decomposes: the writer cutover is one contained change, and every reader 
migration becomes optional and independent. We cover the reader-side mechanics 
in depth in the [Hudi + Iceberg interoperability 
guide](/blog/2026/07/28/using-hudi-with-apache-iceberg-via-xtable); the rest of 
this post focuses on getting the table and the writer onto Hudi.
+
+## Option A: Convert Iceberg Metadata to Hudi with Apache XTable
+
+XTable (incubating) translates table metadata between Hudi, Iceberg and Delta 
Lake in any direction. Pointed at an Iceberg table, it reads the Iceberg 
snapshot and writes Hudi metadata — a `.hoodie` timeline with schema, commit 
history, partition and column statistics — referencing the existing Parquet 
files in place. Nothing is copied or rewritten.
+
+Grab the XTable bundled jar (build from 
[source](https://github.com/apache/incubator-xtable) or download from GitHub 
packages) and create a config:
+
+```yaml md title="iceberg_to_hudi.yaml"
+sourceFormat: ICEBERG
+targetFormats:
+  - HUDI
+datasets:
+  -
+    tableBasePath: s3://warehouse/orders
+    tableDataPath: s3://warehouse/orders/data
+    tableName: orders
+    partitionSpec: order_date:VALUE

Review Comment:
   🤖 Is `partitionSpec` needed for an Iceberg source? In XTable, partition 
information for Delta and Iceberg sources is generally derived from the source 
table's own metadata, and `partitionSpec` is documented as required mainly for 
Hudi source tables — the in-repo `syncing_xtable.md` example only shows it 
under a `sourceFormat: HUDI` config. Including it here for `sourceFormat: 
ICEBERG` may be unnecessary and could confuse readers who copy the config 
verbatim. It might help to verify against the XTable docs and either drop it or 
add a note that it's optional for Iceberg sources.
   
   <sub><i>⚠️ AI-generated; verify before applying. React 👍/👎 to flag 
quality.</i></sub>



##########
website/blog/2026-08-04-migrating-from-delta-lake-to-hudi.md:
##########
@@ -0,0 +1,148 @@
+---
+title: "Migrating from Delta Lake to Apache Hudi"
+excerpt: "A practical guide to moving Delta Lake tables to Apache Hudi — 
metadata-only conversion with Apache XTable, a one-time Spark rewrite, 
validation, and rollback."
+description: "How to migrate Delta Lake tables to Apache Hudi: XTable metadata 
translation with no data rewrite, or a one-time Spark bulk insert — plus 
validation and rollback."
+authors: [sivabalan]
+category: how-to
+image: 
/assets/images/blog/2023-08-09-Lakehouse-Trifecta-Delta-Lake-Apache-Iceberg-and-Apache-Hudi.png
+tags:
+- migration
+- apache xtable
+- delta lake
+- guide
+---
+
+You can migrate a Delta Lake table to Apache Hudi either by translating its 
metadata with [Apache XTable](https://xtable.apache.org) — no data rewrite 
required, since both formats store data as Apache Parquet — or by rewriting the 
table once with a Spark `bulk_insert`; many teams start by running both formats 
side by side via XTable and cut writers over only after validating the Hudi 
side.
+
+That single sentence is the whole decision in miniature, but a production 
migration deserves more care than a summary. This guide walks through why teams 
make this move, the three migration strategies and when each fits, the exact 
XTable and Spark commands involved, the Delta-specific features that need 
per-table attention, and how to validate and — if necessary — roll back. 
Throughout, the framing to keep in mind is that both Delta Lake and Hudi are 
[open table formats](/blog/2026/07/14/what-is-an-open-table-format): metadata 
layers over Parquet files. That shared foundation is precisely what makes a 
metadata-level migration possible.
+
+## Why Teams Move from Delta Lake to Hudi
+
+Delta Lake takes a deliberately simple approach on disk and is closely 
integrated with Spark. Teams that migrate to Hudi are usually not fleeing Delta 
so much as reaching for write-side machinery that Hudi builds in:
+
+- **Record-level indexing.** Hudi maintains a [multi-modal indexing 
subsystem](/docs/indexes) — record-level indexes, bloom filters, column 
statistics, expression indexes — inside an internal metadata table. For 
update-heavy workloads such as CDC ingestion, an index that maps record keys to 
file groups means the writer can locate the files affected by an update without 
scanning or joining against the whole table.
+- **Streaming-first Merge-on-Read design.** Hudi's MOR table type absorbs 
updates into compact log files that are compacted asynchronously, decoupling 
write latency from file rewrite cost. Workloads that need minute-level 
freshness under continuous upserts tend to be the strongest motivation for the 
move.
+- **Built-in table services.** Compaction, clustering, cleaning, and indexing 
ship with the project and run inline or asynchronously, without a separate 
orchestration layer or a commercial service to keep tables healthy.
+- **Built-in ingestion tooling.** Hudi Streamer provides a self-contained 
ingestion utility with sources for Kafka, DFS, and JDBC, checkpoint management, 
transformations, and catalog syncing.
+
+These differences are measurable, not just architectural. In benchmarks run 
with the open-source [LakeLoader](https://github.com/onehouseinc/lake-loader) 
framework — Spark 3.5, Hudi 1.1.1, Delta Lake 3.3.2, on S3 — we observed 
roughly 6× lower incremental write latency for Hudi on a 10 TB partitioned fact 
table with skewed updates, and about 5× lower steady-state latency on 
Merge-on-Read tables taking sparse, column-level updates. The workload 
definitions are format-agnostic and repeatable, so you can rerun the comparison 
against your own update patterns before committing to a migration.
+
+None of this is a knock on Delta — if your workload is mostly appends with 
occasional merges, run entirely on Spark, and you are happy with your current 
operational model, you may not need to migrate at all. The rest of this guide 
assumes you have concluded the write-side capabilities matter for your workload.
+
+## Understand the Three Migration Options
+
+| | A. XTable metadata translation | B. Full rewrite (Spark bulk insert) | C. 
Incremental dual-write cutover |
+|---|---|---|---|
+| **Data movement** | None — metadata only | Full copy of the table | Full 
copy, spread over time |
+| **Downtime for writers** | None during sync; brief pause at cutover | Pause 
writes during the rewrite (or reconcile a delta) | None — new writer runs in 
parallel |
+| **Resulting table** | Hudi metadata over existing Parquet files | Native 
Hudi table, freshly laid out | Native Hudi table |
+| **Lets you re-key / re-partition / resize files** | No — inherits Delta's 
layout | Yes | Yes |
+| **Reversible** | Trivially — source metadata untouched | Source table left 
intact until decommission | Source table left intact until decommission |
+| **Best for** | Large tables, fast side-by-side evaluation, low-risk cutover 
| Small-to-medium tables, or when you want a clean re-layout | Very large, hot 
tables that cannot pause and need a new layout |
+
+A few rules of thumb. If the table is large and its current Parquet layout is 
acceptable, start with **Option A** — it costs almost nothing to try and keeps 
both formats readable while you evaluate. If the table is small enough that a 
rewrite finishes in an acceptable window, or you want to change record keys, 
partitioning, or file sizes as part of the move, **Option B** is simpler to 
reason about. **Option C** — standing up a parallel Hudi pipeline fed from the 
same upstream source, backfilling history, then switching consumers — is really 
Option B with a longer runway, and is worth the extra coordination only for 
tables that can neither pause nor tolerate an inherited layout. Hudi's 
[migration guide](/docs/migration_guide) covers additional bootstrapping modes 
(such as metadata-only bootstrap) that occupy a middle ground for plain Parquet 
sources.
+
+## Option A: Convert with Apache XTable
+
+[Apache XTable](https://xtable.apache.org) (incubating) is an open source 
project that translates table metadata between Delta Lake, Hudi, and Iceberg in 
any direction, without copying or rewriting data files. For this migration, 
Delta is the source and Hudi is the target. XTable reads the Delta transaction 
log and writes out the equivalent Hudi metadata — schema, commit history, 
partition information, and column statistics — alongside the existing Parquet 
files. (The same tool also works in the other directions; see the companion 
post on [using Hudi with Apache Iceberg via 
XTable](/blog/2026/07/28/using-hudi-with-apache-iceberg-via-xtable) for the 
interop angle.)
+
+Create a config file describing the source and target:
+
+```yaml
+# my_config.yaml
+sourceFormat: DELTA
+targetFormats:
+  - HUDI
+datasets:
+  - tableBasePath: s3://bucket/warehouse/orders
+    tableName: orders
+```
+
+Then run the sync with the bundled XTable jar (built from 
[source](https://github.com/apache/incubator-xtable) or downloaded from the 
project's GitHub packages):
+
+```shell
+java -jar path/to/xtable-utilities-bundled.jar --datasetConfig my_config.yaml
+```
+
+When the sync completes, the table's base path contains a `.hoodie` directory 
with Hudi's timeline and metadata, side by side with Delta's `_delta_log`. No 
Parquet file was read or written — the job's runtime scales with the amount of 
metadata (number of files and commits), not with data volume. The same 
directory is now readable as a Delta table *and* as a Hudi table.
+
+Two operational notes, faithful to the [XTable 
documentation](https://xtable.apache.org/docs/how-to):
+
+- **Syncs are repeatable and incremental.** XTable supports incremental sync 
(translating only new commits since the last run) with a fallback to full sync, 
so you can run it on a schedule — or after each Delta commit — to keep the Hudi 
metadata current while the Delta writer keeps running.
+- **Catalog registration is a separate step.** XTable produces metadata in 
storage; to query the table as Hudi from your engines, register it in your 
catalog (Hive Metastore, AWS Glue) using Hudi's catalog sync tools or XTable's 
own catalog sync support. Hudi's [XTable page](/docs/syncing_xtable) shows the 
reverse direction and the Hudi Streamer integration.
+
+## The Catch: Converted vs Native Tables
+
+Here is the honest fine print. A converted table is *readable* as a Hudi table 
— snapshot queries, engine integrations, and catalog syncing all work. But most 
of the reasons you are migrating live on the **write path**: record-level 
indexes are built and maintained by Hudi writers; streaming upserts, MOR log 
files, and table services all require Hudi to be the one committing to the 
table. XTable gives you a Hudi-readable table; it does not retroactively give 
your Delta writer Hudi's write-side machinery.
+
+So a metadata conversion is the first half of the migration, not the whole 
thing. The second half is the writer cutover, which follows a simple sequence:
+
+1. **Stop the Delta writer.** Pause the job or pipeline committing to the 
Delta table. In-flight data can queue upstream (e.g., in Kafka) during the 
brief window.
+2. **Run a final XTable sync.** Translate the last Delta commits so the Hudi 
metadata reflects the table's final Delta-written state.
+3. **Start the Hudi writer.** Point your pipeline — Spark structured 
streaming, Hudi Streamer, or batch jobs following the [quick start 
guide](/docs/quick-start-guide) — at the same base path, configured with the 
record key, ordering field, and table type you validated beforehand. From this 
commit forward, Hudi owns the table and begins building its indexes and running 
table services on new data.

Review Comment:
   🤖 This step could clarify what actually happens when a Hudi writer starts on 
top of XTable-converted metadata. The pre-existing Parquet files were written 
by Delta and don't carry Hudi's record-metadata columns (`_hoodie_record_key`, 
`_hoodie_commit_time`, …), and those historical records aren't present in 
Hudi's record index. So an upsert whose key already exists in the converted 
data can be treated as an insert (creating a duplicate) rather than being 
merged. The Iceberg companion post handles exactly this by recommending Hudi's 
bootstrap mechanism or a full rewrite instead of "writing directly on top of 
converted metadata" — it would help to carry the same caveat here. @yihua could 
you confirm the supported cutover path (bootstrap vs. writing directly onto 
converted metadata) for making historical records upsertable without duplicates?
   
   <sub><i>⚠️ AI-generated; verify before applying. React 👍/👎 to flag 
quality.</i></sub>



##########
website/blog/2026-08-04-migrating-from-delta-lake-to-hudi.md:
##########
@@ -0,0 +1,148 @@
+---
+title: "Migrating from Delta Lake to Apache Hudi"
+excerpt: "A practical guide to moving Delta Lake tables to Apache Hudi — 
metadata-only conversion with Apache XTable, a one-time Spark rewrite, 
validation, and rollback."
+description: "How to migrate Delta Lake tables to Apache Hudi: XTable metadata 
translation with no data rewrite, or a one-time Spark bulk insert — plus 
validation and rollback."
+authors: [sivabalan]
+category: how-to
+image: 
/assets/images/blog/2023-08-09-Lakehouse-Trifecta-Delta-Lake-Apache-Iceberg-and-Apache-Hudi.png
+tags:
+- migration
+- apache xtable
+- delta lake
+- guide
+---
+
+You can migrate a Delta Lake table to Apache Hudi either by translating its 
metadata with [Apache XTable](https://xtable.apache.org) — no data rewrite 
required, since both formats store data as Apache Parquet — or by rewriting the 
table once with a Spark `bulk_insert`; many teams start by running both formats 
side by side via XTable and cut writers over only after validating the Hudi 
side.
+
+That single sentence is the whole decision in miniature, but a production 
migration deserves more care than a summary. This guide walks through why teams 
make this move, the three migration strategies and when each fits, the exact 
XTable and Spark commands involved, the Delta-specific features that need 
per-table attention, and how to validate and — if necessary — roll back. 
Throughout, the framing to keep in mind is that both Delta Lake and Hudi are 
[open table formats](/blog/2026/07/14/what-is-an-open-table-format): metadata 
layers over Parquet files. That shared foundation is precisely what makes a 
metadata-level migration possible.
+
+## Why Teams Move from Delta Lake to Hudi
+
+Delta Lake takes a deliberately simple approach on disk and is closely 
integrated with Spark. Teams that migrate to Hudi are usually not fleeing Delta 
so much as reaching for write-side machinery that Hudi builds in:
+
+- **Record-level indexing.** Hudi maintains a [multi-modal indexing 
subsystem](/docs/indexes) — record-level indexes, bloom filters, column 
statistics, expression indexes — inside an internal metadata table. For 
update-heavy workloads such as CDC ingestion, an index that maps record keys to 
file groups means the writer can locate the files affected by an update without 
scanning or joining against the whole table.
+- **Streaming-first Merge-on-Read design.** Hudi's MOR table type absorbs 
updates into compact log files that are compacted asynchronously, decoupling 
write latency from file rewrite cost. Workloads that need minute-level 
freshness under continuous upserts tend to be the strongest motivation for the 
move.
+- **Built-in table services.** Compaction, clustering, cleaning, and indexing 
ship with the project and run inline or asynchronously, without a separate 
orchestration layer or a commercial service to keep tables healthy.
+- **Built-in ingestion tooling.** Hudi Streamer provides a self-contained 
ingestion utility with sources for Kafka, DFS, and JDBC, checkpoint management, 
transformations, and catalog syncing.
+
+These differences are measurable, not just architectural. In benchmarks run 
with the open-source [LakeLoader](https://github.com/onehouseinc/lake-loader) 
framework — Spark 3.5, Hudi 1.1.1, Delta Lake 3.3.2, on S3 — we observed 
roughly 6× lower incremental write latency for Hudi on a 10 TB partitioned fact 
table with skewed updates, and about 5× lower steady-state latency on 
Merge-on-Read tables taking sparse, column-level updates. The workload 
definitions are format-agnostic and repeatable, so you can rerun the comparison 
against your own update patterns before committing to a migration.
+
+None of this is a knock on Delta — if your workload is mostly appends with 
occasional merges, run entirely on Spark, and you are happy with your current 
operational model, you may not need to migrate at all. The rest of this guide 
assumes you have concluded the write-side capabilities matter for your workload.
+
+## Understand the Three Migration Options
+
+| | A. XTable metadata translation | B. Full rewrite (Spark bulk insert) | C. 
Incremental dual-write cutover |
+|---|---|---|---|
+| **Data movement** | None — metadata only | Full copy of the table | Full 
copy, spread over time |
+| **Downtime for writers** | None during sync; brief pause at cutover | Pause 
writes during the rewrite (or reconcile a delta) | None — new writer runs in 
parallel |
+| **Resulting table** | Hudi metadata over existing Parquet files | Native 
Hudi table, freshly laid out | Native Hudi table |
+| **Lets you re-key / re-partition / resize files** | No — inherits Delta's 
layout | Yes | Yes |
+| **Reversible** | Trivially — source metadata untouched | Source table left 
intact until decommission | Source table left intact until decommission |
+| **Best for** | Large tables, fast side-by-side evaluation, low-risk cutover 
| Small-to-medium tables, or when you want a clean re-layout | Very large, hot 
tables that cannot pause and need a new layout |
+
+A few rules of thumb. If the table is large and its current Parquet layout is 
acceptable, start with **Option A** — it costs almost nothing to try and keeps 
both formats readable while you evaluate. If the table is small enough that a 
rewrite finishes in an acceptable window, or you want to change record keys, 
partitioning, or file sizes as part of the move, **Option B** is simpler to 
reason about. **Option C** — standing up a parallel Hudi pipeline fed from the 
same upstream source, backfilling history, then switching consumers — is really 
Option B with a longer runway, and is worth the extra coordination only for 
tables that can neither pause nor tolerate an inherited layout. Hudi's 
[migration guide](/docs/migration_guide) covers additional bootstrapping modes 
(such as metadata-only bootstrap) that occupy a middle ground for plain Parquet 
sources.
+
+## Option A: Convert with Apache XTable
+
+[Apache XTable](https://xtable.apache.org) (incubating) is an open source 
project that translates table metadata between Delta Lake, Hudi, and Iceberg in 
any direction, without copying or rewriting data files. For this migration, 
Delta is the source and Hudi is the target. XTable reads the Delta transaction 
log and writes out the equivalent Hudi metadata — schema, commit history, 
partition information, and column statistics — alongside the existing Parquet 
files. (The same tool also works in the other directions; see the companion 
post on [using Hudi with Apache Iceberg via 
XTable](/blog/2026/07/28/using-hudi-with-apache-iceberg-via-xtable) for the 
interop angle.)
+
+Create a config file describing the source and target:
+
+```yaml
+# my_config.yaml
+sourceFormat: DELTA
+targetFormats:
+  - HUDI
+datasets:
+  - tableBasePath: s3://bucket/warehouse/orders
+    tableName: orders
+```
+
+Then run the sync with the bundled XTable jar (built from 
[source](https://github.com/apache/incubator-xtable) or downloaded from the 
project's GitHub packages):
+
+```shell
+java -jar path/to/xtable-utilities-bundled.jar --datasetConfig my_config.yaml
+```
+
+When the sync completes, the table's base path contains a `.hoodie` directory 
with Hudi's timeline and metadata, side by side with Delta's `_delta_log`. No 
Parquet file was read or written — the job's runtime scales with the amount of 
metadata (number of files and commits), not with data volume. The same 
directory is now readable as a Delta table *and* as a Hudi table.
+
+Two operational notes, faithful to the [XTable 
documentation](https://xtable.apache.org/docs/how-to):
+
+- **Syncs are repeatable and incremental.** XTable supports incremental sync 
(translating only new commits since the last run) with a fallback to full sync, 
so you can run it on a schedule — or after each Delta commit — to keep the Hudi 
metadata current while the Delta writer keeps running.
+- **Catalog registration is a separate step.** XTable produces metadata in 
storage; to query the table as Hudi from your engines, register it in your 
catalog (Hive Metastore, AWS Glue) using Hudi's catalog sync tools or XTable's 
own catalog sync support. Hudi's [XTable page](/docs/syncing_xtable) shows the 
reverse direction and the Hudi Streamer integration.
+
+## The Catch: Converted vs Native Tables
+
+Here is the honest fine print. A converted table is *readable* as a Hudi table 
— snapshot queries, engine integrations, and catalog syncing all work. But most 
of the reasons you are migrating live on the **write path**: record-level 
indexes are built and maintained by Hudi writers; streaming upserts, MOR log 
files, and table services all require Hudi to be the one committing to the 
table. XTable gives you a Hudi-readable table; it does not retroactively give 
your Delta writer Hudi's write-side machinery.
+
+So a metadata conversion is the first half of the migration, not the whole 
thing. The second half is the writer cutover, which follows a simple sequence:
+
+1. **Stop the Delta writer.** Pause the job or pipeline committing to the 
Delta table. In-flight data can queue upstream (e.g., in Kafka) during the 
brief window.
+2. **Run a final XTable sync.** Translate the last Delta commits so the Hudi 
metadata reflects the table's final Delta-written state.
+3. **Start the Hudi writer.** Point your pipeline — Spark structured 
streaming, Hudi Streamer, or batch jobs following the [quick start 
guide](/docs/quick-start-guide) — at the same base path, configured with the 
record key, ordering field, and table type you validated beforehand. From this 
commit forward, Hudi owns the table and begins building its indexes and running 
table services on new data.
+
+Until step 1, you can run the two formats side by side indefinitely: Delta 
writers keep writing, XTable keeps both metadata layers in sync, and your 
Hudi-native engines and pipelines read the converted table. That side-by-side 
period is where the de-risking happens — you validate reads, permissions, 
catalog integration, and downstream jobs against real data before any writer 
changes.
+
+## Option B: Full Rewrite with Spark
+
+If the table is modest in size, or you want to change its physical layout — 
different partitioning, tuned file sizes, a proper record key for upserts — a 
one-time rewrite is the simplest path. Read the Delta table with Spark, write 
it back as Hudi using `bulk_insert`, the write operation designed for exactly 
this initial-load case:
+
+```scala
+// spark-shell with both Delta and Hudi bundles on the classpath
+val df = spark.read.format("delta").load("s3://bucket/warehouse/orders")
+
+df.write.format("hudi").

Review Comment:
   🤖 Since the guide leads with Merge-on-Read's streaming-upsert benefits, it 
might help to note that this `bulk_insert` example produces a Copy-on-Write 
table by default (`hoodie.datasource.write.table.type` is unset). Readers who 
followed the MOR motivation above and want that behavior would need to add 
`option("hoodie.datasource.write.table.type", "MERGE_ON_READ")`, and table type 
is fixed at creation. The Iceberg companion's Option B example (line 91) has 
the same omission.
   
   <sub><i>⚠️ AI-generated; verify before applying. React 👍/👎 to flag 
quality.</i></sub>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to