lucasfang commented on code in PR #357:
URL: https://github.com/apache/paimon-cpp/pull/357#discussion_r4023944427


##########
src/paimon/core/operation/file_store_commit.cpp:
##########
@@ -272,11 +295,12 @@ Result<std::unique_ptr<FileStoreCommit>> 
FileStoreCommit::Create(
             options.LegacyPartitionNameEnabled(), external_paths, 
global_index_external_path,
             options.IndexFileInDataFileDir(), ctx->GetMemoryPool()));
 
-    auto snapshot_manager = 
std::make_shared<SnapshotManager>(options.GetFileSystem(), root_path);
+    auto snapshot_manager =

Review Comment:
   
   `FileStoreCommit::Create()` passes a branch-scoped `SnapshotManager` 
(`file_store_commit.cpp:298`, `:330`) to `ExpireSnapshots`, whose protection 
sets (`GetManifestSkippingSet` / `GetDataFileSkippingSet`) come only from that 
branch's `retained_snapshots`. Expiration never consults a tag and never scans 
other branches, while data/manifest files are shared across branches. So 
expiring `dev` deletes a file that has left `dev`'s retained set even when 
`main` still references it, and `main` then fails to read.
   
   **Repro:** create `dev` from a `main` tag, compact/overwrite on `dev`, then 
`Expire()`.
   
   The docs claim this matches Java's `ExpireSnapshotsImpl`, but that is only 
half true. Java collects tagged snapshots *before* deleting files 
(apache/paimon#9220), and a branch created from a tag carries that tag — which 
is exactly what protects the shared base files. C++ already has a branch-aware 
`TagManager` but expiration ignores it. Java is equivalent only for files 
referenced by another branch's *untagged* live snapshots.
   
   1. This PR's `expire_snapshots.cpp` diff is log-only, so the missing tag 
protection is a pre-existing gap that also hits `main`; the PR newly makes it 
reachable on branches.
   2. `TestBranchExpireLeavesMainSnapshotMetadataAlone` cannot catch it — 
`main` and `dev` commit the same append fixtures, so no shared file is actually 
deleted, and it only checks snapshot JSON/hints, not read integrity.
   
   Suggested fix (in order):
   1. Fold `TagManager`'s tagged snapshots into the skipping sets, matching 
Java's `ExpireSnapshotsImpl`.
   2. Otherwise, refuse or hard-warn at runtime on branch expiration until that 
lands.
   3. Add a regression test that compacts/overwrites on `dev` so a file truly 
leaves its retained set while `main` still references it, then reads `main` 
back in full.
   
   A documentation warning alone is not enough for a silent data-loss path.
   



-- 
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