You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 28fd283
Browse filesBrowse the repository at this point in the historyBrowse files
[#13893] fix(cache): Recover late change logs and fence cache publication (#13831)
### What changes were proposed in this pull request?
- Replay recent change-log rows behind the cursor with bounded ID
deduplication, diagnostics, and explicit listener opt-in.
- Start a replay sweep at most once per `max(pollIntervalSecs,
replayWindowSecs / 4)` (15s by default), and expose
`replay-records-total`, `replay-failures-total`, and
`dedup-evictions-total` metrics.
- Fence point-read/insert cache publication without requiring reentrant
SPI locks, and document that `invalidateOnKeyChange` may run under the
entity's own cache lock.
- Invalidate local and replayed catalog events while preserving
operation leases; update configuration and metrics documentation.
### Why are the changes needed?
ID allocation order differs from commit order. Concurrent cache
publication and name-based local catalog markers can also leave stale
entries.
Fix: #13893
Part of #13828; this PR implements its three P0 fixes and leaves the
remaining EPIC work open.
### Does this PR introduce _any_ user-facing change?
Adds `gravitino.entityChangeLog.replayWindowSecs` (default `60`; `0`
disables replay) and `gravitino.entityChangeLog.replayMaxEntries`
(default `100000`), plus three `entity-change-log` counters:
`replay-records-total`, `replay-failures-total`, and
`dedup-evictions-total`. Existing third-party listeners remain
incremental-only. No schema or cache-TTL change.
Replay adds database reads and possible catalog reloads. Its window uses
recorded `created_at`, including PostgreSQL transaction-start
timestamps; long transactions, pruned history, or overload can still
lose invalidations. Each sweep rereads the whole window. Throttling
sweep starts to a quarter of the window bounds this to about four reads
per row per server, instead of window/poll interval (20 by default). The
cost: late-commit recovery can take up to one extra sweep interval, and
a row is guaranteed to be replayed only if it becomes visible within the
window minus one sweep interval (45s by default). A finer
gap/low-water-mark scheme was considered and deferred for
maintainability. Replay-only full-page cycles still perform incremental,
tail, and replay queries. A late row behind an already scanned page
waits for the next sweep; the replay window is a history range, not a
delivery deadline.
### How was this patch tested?
- Full core suite: 2,761 tests, zero failures/errors, two existing
skips. Final focused suite: 39 tests, including the added timing
regression, all passed. Previously validated unchanged server-common:
485 tests, all passed.
- Local H2/MySQL/PostgreSQL late-commit probes and shared-PostgreSQL
three-JVM checks for ten cacheable entity types passed.
- Three P0 regressions fail when old behavior is restored; the
non-reentrant SPI regression fails on the initial implementation and
passes after the compatibility fix.
- Default 3s polling: real PostgreSQL/three-JVM probes converged in
2.702s (incremental) and 3.101s (late commit) with small history; the
late-commit figure predates sweep throttling, which can add up to one
sweep interval. A controlled ordinary-incremental budget test delivers
in 5.7s with 0.9s incremental work and 0.9s replay work; moving delivery
after replay fails at 6.6s. A separate multi-page late-replay probe
takes 7.5s, so these checks do not establish a universal 6s replay
deadline.
- Sweep throttling and metrics: 37 `TestEntityChangeLogPoller` tests
pass, including new throttle, poll-interval floor, and eviction-counter
tests; the two throttle tests fail with a zero sweep interval.
`TestCacheCommitOrdering` passes on H2, MySQL, and PostgreSQL.
- Catalog modules that mock `Config` (generic lakehouse, fileset, Kafka,
model) now stub the replay settings: 29/232/15/37 tests passed; the JMH
benchmark compiles.
- After merging main (#13792): the new
`TestRelationalEntityStoreLockWaitTimeout` mocks `Config` and now stubs
the replay settings (all 7 cases NPE without them). 14 affected core
classes on H2: 204 tests passed.
- Review round (5a1312f, 6a242d6): the first replay sweep after
startup logs at INFO and later sweeps keep the late-commit WARN (pinned
in tests; the INFO assertion fails without the change); a failed
mid-sweep page resumes from the saved page cursor (fails if the cursor
is reset). `TestEntityChangeLogPoller` (39) plus related store/cache
classes: 115 tests passed on H2.
- Spotless, compilation, and diff checks passed.
Unit-suite command:
```bash
LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 ./gradlew :core:test :server-common:test -PskipITs -PskipDockerTests=true
```
---------
Signed-off-by: yuqi <yuqi@datastrato.com>
Co-authored-by: yuqi <yuqi4733@protonmail.com>
Copy file name to clipboardExpand all lines: catalogs/catalog-fileset/src/test/java/org/apache/gravitino/catalog/fileset/TestFilesetCatalogOperations.java
Copy file name to clipboardExpand all lines: catalogs/catalog-lakehouse-generic/src/test/java/org/apache/gravitino/catalog/lakehouse/generic/TestGenericCatalogOperations.java
0 commit comments