This is an automated email from the ASF dual-hosted git repository.

voonhous pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/hudi.git


The following commit(s) were added to refs/heads/asf-site by this push:
     new e313ed231e84 docs(cleaning): document that clean metadata records 
instant (start) times (#19552)
e313ed231e84 is described below

commit e313ed231e84d98f93052c0b5d90cb96f33add4c
Author: deepakpanda93 <[email protected]>
AuthorDate: Sun Aug 9 13:34:20 2026 +0530

    docs(cleaning): document that clean metadata records instant (start) times 
(#19552)
    
    * docs(cleaning): document that clean metadata records instant (start) times
    
    Hudi 1.x stamps every action with both a requested instant time and a
    completion time and orders the timeline by completion time, but nothing in
    the docs said which of the two the cleaner records. A user reading clean
    metadata to debug cannot tell whether earliestCommitToRetain is a start time
    or a completion time.
    
    It is a start time, on every field, verified at release-1.2.0 and master:
    
    - HoodieCleanerPlan.earliestInstantToRetain is built from
      hoodieInstant.requestedTime() (CleanPlanActionExecutor:111 and :177), and
      HoodieCleanMetadata.earliestCommitToRetain is copied from the plan
      (CleanActionExecutor:172-179 and :265).
    - lastCompletedCommitTimestamp is
      getCommitTimeline().lastInstant().requestedTime() (CleanPlanner:655-657),
      so despite the name it is a start time; the source carries the same note
      at CleanPlanActionExecutor:178.
    - startCleanTime is inflightInstant.requestedTime() on both the normal and
      the empty-clean path (CleanActionExecutor:228-232 and :256).
    - Incremental clean planning likewise ranges over instant.requestedTime()
      (CleanPlanner:241-245).
    
    Add a section to the Cleaning page tabulating these four fields, and a
    matching field table to the Cleaning section of the 1.0 tech spec.
    
    Note this documents behavior as it stands. The parent ticket HUDI-8077,
    which would have moved clean metadata to completion time, is resolved
    Won't Do and its PR apache/hudi#11972 was closed unmerged.
    
    Applied to next and to version-1.2.0, the current released docs. The tech
    spec is served unversioned from the learn plugin, so it has a single copy.
    
    Closes #17274.
    
    * docs(cleaning): name both endpoints of the incremental clean range
    
    Review feedback on apache/hudi#19552: "between the previous clean's
    earliestCommitToRetain and the current one" left the upper endpoint to be
    inferred.
    
    Name it, and while here state the bounds exactly. CleanPlanner:241-245 
filters
    completed commits with
    
        requestedTime >= cleanMetadata.getEarliestCommitToRetain()
        requestedTime <  newInstantToRetain.requestedTime()
    
    so the range is half-open: inclusive of the previous clean's
    earliestCommitToRetain, exclusive of this clean's. newInstantToRetain is the
    instant returned by CleanPlanner#getEarliestCommitToRetain
    (CleanPlanActionExecutor:129), the same one written to the plan as
    earliestInstantToRetain (:177), so "this clean's earliestCommitToRetain" 
names
    it accurately.
    
    Applied to both cleaning.md copies and the tech spec, which carried the same
    sentence.
    
    * docs(cleaning): note the two clean-metadata fields that read wrong
    
    Two values in the new clean-metadata table are easy to misread, and neither
    is visible in a single-writer reproduction.
    
    lastCompletedCommitTimestamp mixes the two orderings. CleanPlanner:655-656
    is getCommitTimeline().lastInstant().map(HoodieInstant::requestedTime), and
    getCommitTimeline() (CleanPlanner:121-126) is getCompletedCommitsTimeline(),
    which 1.x orders by completion time. So the instant is picked by completion
    order and then recorded as a start time. Given commits A (requested t1,
    completed t4) and B (requested t2, completed t3) with t1 < t2 < t3 < t4, the
    field holds t1 even though the completed commit B started at t2. Saying "the
    last completed write" invited reading it as the largest requested time.
    
    earliestCommitToRetain can be an empty string. CleanerUtils:126-156 has no
    branch for KEEP_LATEST_FILE_VERSIONS, so getEarliestCommitToRetain() is 
empty
    under that policy, and CleanPlanActionExecutor:177 stores null in the plan.
    That policy still cleans - getPartitionPathsToClean falls through to
    getPartitionPathsForFullCleaning (CleanPlanner:161-165) - so the run 
produces
    clean stats, CleanActionExecutor:184 substitutes "" for the missing instant,
    and CleanerUtils.convertCleanMetadata:93 copies it straight into
    HoodieCleanMetadata. A reader debugging retention on that policy sees an
    empty field and no explanation.
    
    Applied to both cleaning.md copies as a short list under the table, and
    folded into the corresponding tech spec rows.
    
    ---------
    
    Co-authored-by: voon <[email protected]>
---
 website/docs/cleaning.md                         | 29 +++++++++++++++++++++++-
 website/learn/tech-specs.md                      | 14 +++++++++++-
 website/versioned_docs/version-1.2.0/cleaning.md | 29 +++++++++++++++++++++++-
 3 files changed, 69 insertions(+), 3 deletions(-)

diff --git a/website/docs/cleaning.md b/website/docs/cleaning.md
index fa92192f04eb..936944347668 100644
--- a/website/docs/cleaning.md
+++ b/website/docs/cleaning.md
@@ -3,7 +3,7 @@ title: Cleaning
 toc: true
 toc_min_heading_level: 2
 toc_max_heading_level: 4
-last_modified_at: 2026-05-27T00:00:00-00:00
+last_modified_at: 2026-08-06T15:17:36+05:30
 ---
 ## Background
 Cleaning is a table service employed by Hudi to reclaim space occupied by 
older versions of data and keep storage costs 
@@ -86,6 +86,33 @@ takes precedence over the regex.
 | `hoodie.clean.partition.filter.regex` | (none) | Java regex pattern; only 
partitions whose path matches are cleaned. |
 | `hoodie.clean.partition.filter.selected` | (none) | Comma-separated list of 
partition paths to clean; takes precedence over the regex when both are set. |
 
+### Instant Times in Clean Metadata
+
+Hudi 1.x stamps every action with both a requested instant time and a 
completion time, and orders actions on the
+timeline by completion time — see [timeline](timeline.md). The cleaner's own 
plan and metadata, however, record
+**instant (start) times** throughout. Keep this in mind when reading them for 
debugging.
+
+| Field | Written to | Value |
+|---|---|---|
+| `earliestInstantToRetain.timestamp` | `HoodieCleanerPlan` (the 
`clean.requested` instant) | Instant time of the oldest commit this clean run 
retains. |
+| `earliestCommitToRetain` | `HoodieCleanMetadata` (the completed `clean` 
instant) | Copied from the plan, so also an instant time. |
+| `lastCompletedCommitTimestamp` | both | Instant time of the write that 
completed most recently before the clean was planned. Despite the name, this is 
a start time, not a completion time. |
+| `startCleanTime` | `HoodieCleanMetadata` | Instant time of the clean action 
itself. |
+
+Two details are easy to trip over when reading these values back:
+
+- `lastCompletedCommitTimestamp` mixes the two orderings. The instant is taken 
from the end of the completed-commits
+  timeline, which is ordered by completion time, but what gets recorded is 
that instant's start time. Concurrent writers
+  can complete in a different order than they started in, so this is not 
always the largest instant time among the
+  completed commits.
+- `earliestCommitToRetain` is an empty string under the 
`KEEP_LATEST_FILE_VERSIONS` policy. That policy retains a fixed
+  number of file versions per file group rather than a range of the timeline, 
so the plan carries no
+  `earliestInstantToRetain` for the metadata to copy.
+
+Incremental clean planning follows the same convention: it selects the commits 
whose **requested** instant time is at or
+after the previous clean's `earliestCommitToRetain` and before this clean's, 
then scans only the partitions those
+commits touched.
+
 ### Configs
 For details about all possible configurations and their default values see the 
[configuration 
docs](https://hudi.apache.org/docs/next/configurations/#Clean-Configs).
 For Flink related configs refer 
[here](https://hudi.apache.org/docs/next/configurations/#FLINK_SQL).
diff --git a/website/learn/tech-specs.md b/website/learn/tech-specs.md
index 0f8d3acd2acc..f542c4c5b651 100644
--- a/website/learn/tech-specs.md
+++ b/website/learn/tech-specs.md
@@ -2,7 +2,7 @@
 
 | **Syntax** | **Description** |
 | ---|-----------------|
-| Last Updated | Jul 2026        |
+| Last Updated | Aug 2026        |
 | [Table 
Version](https://github.com/apache/hudi/blob/master/hudi-common/src/main/java/org/apache/hudi/common/table/HoodieTableVersion.java)
 | 9               |
 | Reflects release | Hudi 1.2.0 (May 2026) |
 
@@ -698,6 +698,18 @@ For e.g, there are a couple of retention policies 
supported in Apache Hudi platf
 Apache Hudi provides snapshot isolation between writers and readers by 
managing multiple files with MVCC concurrency. These file versions provide 
history
 and enable time travel and rollbacks, but it is important to manage how much 
history you keep to balance your storage costs.
 
+Cleaning is planned and tracked in terms of **instant (start) times**, even 
though actions on the timeline are ordered
+by completion time. The fields below all hold the requested instant time of 
the action they refer to.
+
+| Field | Description |
+|---|---|
+| earliestInstantToRetain | Instant time, action and state of the oldest 
commit the clean run retains. Held in `HoodieCleanerPlan`, and copied to 
`HoodieCleanMetadata` as `earliestCommitToRetain`. Absent under 
`KEEP_LATEST_FILE_VERSIONS`, which retains a fixed number of file versions per 
file group rather than a range of the timeline; `earliestCommitToRetain` is 
then an empty string |
+| lastCompletedCommitTimestamp | Instant time of the write that completed most 
recently before the clean was planned. Despite the name, this is a start time. 
The instant is chosen by completion order, so with concurrent writers it is not 
always the largest instant time among completed commits |
+| startCleanTime | Instant time of the clean action itself, in 
`HoodieCleanMetadata` |
+
+Incremental clean planning selects commits whose requested instant time is at 
or after the previous clean's
+`earliestCommitToRetain` and before this clean's, and scans only the 
partitions those commits touched.
+
 
 ### Indexing
 
diff --git a/website/versioned_docs/version-1.2.0/cleaning.md 
b/website/versioned_docs/version-1.2.0/cleaning.md
index 5cc6a8726469..4e1707ed03e3 100644
--- a/website/versioned_docs/version-1.2.0/cleaning.md
+++ b/website/versioned_docs/version-1.2.0/cleaning.md
@@ -3,7 +3,7 @@ title: Cleaning
 toc: true
 toc_min_heading_level: 2
 toc_max_heading_level: 4
-last_modified_at: 2026-05-27T00:00:00-00:00
+last_modified_at: 2026-08-06T15:17:36+05:30
 ---
 ## Background
 Cleaning is a table service employed by Hudi to reclaim space occupied by 
older versions of data and keep storage costs 
@@ -86,6 +86,33 @@ takes precedence over the regex.
 | `hoodie.clean.partition.filter.regex` | (none) | Java regex pattern; only 
partitions whose path matches are cleaned. |
 | `hoodie.clean.partition.filter.selected` | (none) | Comma-separated list of 
partition paths to clean; takes precedence over the regex when both are set. |
 
+### Instant Times in Clean Metadata
+
+Hudi 1.x stamps every action with both a requested instant time and a 
completion time, and orders actions on the
+timeline by completion time — see [timeline](timeline.md). The cleaner's own 
plan and metadata, however, record
+**instant (start) times** throughout. Keep this in mind when reading them for 
debugging.
+
+| Field | Written to | Value |
+|---|---|---|
+| `earliestInstantToRetain.timestamp` | `HoodieCleanerPlan` (the 
`clean.requested` instant) | Instant time of the oldest commit this clean run 
retains. |
+| `earliestCommitToRetain` | `HoodieCleanMetadata` (the completed `clean` 
instant) | Copied from the plan, so also an instant time. |
+| `lastCompletedCommitTimestamp` | both | Instant time of the write that 
completed most recently before the clean was planned. Despite the name, this is 
a start time, not a completion time. |
+| `startCleanTime` | `HoodieCleanMetadata` | Instant time of the clean action 
itself. |
+
+Two details are easy to trip over when reading these values back:
+
+- `lastCompletedCommitTimestamp` mixes the two orderings. The instant is taken 
from the end of the completed-commits
+  timeline, which is ordered by completion time, but what gets recorded is 
that instant's start time. Concurrent writers
+  can complete in a different order than they started in, so this is not 
always the largest instant time among the
+  completed commits.
+- `earliestCommitToRetain` is an empty string under the 
`KEEP_LATEST_FILE_VERSIONS` policy. That policy retains a fixed
+  number of file versions per file group rather than a range of the timeline, 
so the plan carries no
+  `earliestInstantToRetain` for the metadata to copy.
+
+Incremental clean planning follows the same convention: it selects the commits 
whose **requested** instant time is at or
+after the previous clean's `earliestCommitToRetain` and before this clean's, 
then scans only the partitions those
+commits touched.
+
 ### Configs
 For details about all possible configurations and their default values see the 
[configuration 
docs](https://hudi.apache.org/docs/next/configurations/#Clean-Configs).
 For Flink related configs refer 
[here](https://hudi.apache.org/docs/next/configurations/#FLINK_SQL).

Reply via email to