Repository navigation
[core] Unify catalog lock interfaces and snapshot commit scopes - #10498
Conversation
Retry acquisition failures within the commit retry limits without treating them as uncertain publications. Preserve publication retry state and successful post-commit callbacks when lock release fails. Keep preparation errors and interruption fail-fast, with regression tests for expired snapshots, cancellation and manifest reuse.
leaves12138
left a comment
There was a problem hiding this comment.
Reviewed the latest head b6f8585. No blocking findings.
Checked the bound SnapshotCommit/Lock contract, all four publication paths, fresh-head reads within each attempt, separate APPEND/COMPACT scopes, post-commit callbacks after release, catalog policy/identity propagation, and resource ownership. Also checked Hive/JDBC renewal, owner-checked JDBC release, lock-table migration, and the new preservation of successful/uncertain publication state across acquisition and release failures, including interruption handling.
Independent local verification on JDK 8 with normal Maven checks enabled: 145 core cases and 14 Hive cases passed, with zero failures, errors, or skips; the reactor package build succeeded. This includes all 99 FileStoreCommitTest cases. I did not run live MySQL/PostgreSQL container integration locally.
Full CI for this latest head is still in progress; please wait for it before merging. The intentionally changed lock/publisher SPIs and JDBC ALTER/rolling-upgrade prerequisites are documented.
Acquire a closable lock scope and distinguish acquisition failures from operation failures. Preserve the operation outcome on release failure and stop interrupted acquisition. Keep the no-op lock on its direct execution path and simplify commit retries without changing preparation or publication.
Purpose
Catalog locks currently guard atomic snapshot publication while reading the head, detecting conflicts and preparing manifests happen outside that scope. Acquire a table lock before reading the head and hold it through validation, preparation and publication on every attempt. The four single-attempt entry points (
tryCommitOnce,replaceManifestListOnce,rollbackToAsLatestOnceandcompactManifestOnce) acquire the scope and delegate to private implementations. Retry waits and post-commit callbacks run after release; APPEND and COMPACT publications use separate scopes.Bind locking and publication in a
SnapshotCommitabstract class. Construction requires a lock, and finalcommit,acquire,runWithLock,ensureValidandclosemethods enforce the shared contract. Backend implementations provide protected publication and resource-cleanup hooks. Directcommitcalls acquire and validate the bound lock; publication inside a preparation scope reuses it and revalidates the lease.FileStoreCommitImplowns only this publisher: remove its separate lock field andwithLocksetter.CatalogEnvironment.snapshotCommitcreates the lock and publisher together using the branch, table UUID, exact commit user and runtime table options, and owns one loaded catalog. Remove the overload accepting an externally supplied publication lock and the independent writer-lock helper. Construction failures close acquired resources, and lock-close failures still close the publisher/catalog.Use
Lockas the only catalog locking interface.Lock.acquirereturns anAutoCloseablescope, which is released on the acquiring thread. The defaultrunWithLockdistinguishes acquisition failures with a checkedAcquisitionException, propagates operation failures unchanged, and retains the operation's result or original exception when releasing the scope fails. Acquisition interruption stops the operation; release failures are logged and attached to an existing failure.Lock.empty()directly invokes the callable and bypasses scope acquisition, reentrancy state and lock exception handling.FileStoreCommitImplkeeps its preparation/publication body unchanged and only retries acquisition failures in its retry loop, retaining any earlier publication retry state.Catalog.createLockandCatalogLockFactory.createLockreturn a table-boundLock; the factory receives the identifier/branch, table UUID, commit user and runtime options at creation. RemoveCatalogLock, its named-callback adapter and the legacy factory fallback when a catalog provides its own policy. Hive/JDBC schema operations and snapshot commits use the same catalog entry point, including customlock.typeselection. The factory and publisher SPIs intentionally change without compatibility adapters.Move lock configuration and factory selection to the concrete catalogs. Hive and JDBC define and consume
lock.enabled,lock.type,lock-check-max-sleepandlock-acquire-timeoutin their own options classes, preserving the existing keys, defaults and object-store enablement policy. Remove the genericCatalogOptionslock constants and migrate consumers toHiveCatalogOptionsorJdbcCatalogOptions.AbstractCatalogandFileSystemCatalogdo not interpret these backend options and default to a no-op lock. Update generated configuration tables and concurrency documentation.Longer preparation requires renewable leases: Hive heartbeats and checks the server before publication; JDBC renews and releases by an internal owner and rejects expired renewal. Zero changed-row renewal results recheck the unexpired owner rather than treating an unchanged timestamp as lost ownership. Existing JDBC lock tables receive a nullable
lock_ownercolumn on catalog initialization, requiring ALTER permission. All JDBC writers should upgrade before relying on owner-checked release after expiry. The client Hive transaction timeout must match the metastore timeout.This extracts the generic locking prerequisite from #10489 so a subsequent REST implementation can use the same abstraction. It adds no REST endpoints, request models, table options or owner-aware REST rollback API. Snapshot and file conflict validation remain required; this does not add a storage fencing token.
Tests
FileStoreCommitTestcases.