PYR1-1773 Delete GWC layers one at a time during workspace removal - #101
Conversation
GeoServer's DiskQuota store bills every tile-layer delete to a single ___GLOBAL_QUOTA___ row inside a SERIALIZABLE transaction. Fanning the deletes out meant concurrent writers to that row, which Postgres aborts with "could not serialize access due to concurrent update" - 14,248 HTTP 500s in 6 days on dev. 1. Add delete-cached-layers!, which issues the deletes sequentially and still treats 404 as success 2. Call it from remove-workspace! in place of make-parallel-rest-requests The add path keeps its parallel requests; registration throughput depends on them.
|
Verified on Removal - zero new serialization errors
parrot05, two workspaces on port 31338: parrot04, one 328-layer workspace on port 31337: None of the three logged Cost325 sequential deletes took 27s, about 83ms each. The 15-layer weather workspaces took 1-2s. Acceptable at current layer counts, and the bounded-concurrency-plus-retry option stays open if it stops being. Re-registration
Three |
Purpose
Delete GWC tile layers one at a time during workspace removal. GeoServer's DiskQuota store bills every delete to a single
___GLOBAL_QUOTA___row inside a SERIALIZABLE transaction, so concurrent deletes conflict and Postgres aborts the losers withcould not serialize access due to concurrent update.delete-cached-layers!issues the deletes sequentially and still treats 404 as success, as before.remove-workspace!calls it in place ofmake-parallel-rest-requests.core.clj:738) keeps its parallel requests - registration throughput depends on them.Why now
PYR1-1745 moved the DiskQuota store from embedded H2/HSQL to PostgreSQL. The contention already existed; H2 takes a table lock and blocks, Postgres aborts immediately. Counts over the same 8-day window:
geoserver-utility-dev(PostgreSQL) - 14,248geoserver-west(H2) - 18, asCannotAcquireLockException: Timeout trying to lock table TILESETgeoserver-utilityprod (HSQL) - 0JDBCQuotaStore's constructor hardcodessetIsolationLevel(8)=ISOLATION_SERIALIZABLE, verified by disassemblinggwc-diskquota-jdbc-1.28.5.jar. There is no configuration knob for it, so the fix has to be on the caller side.Related Issues
Closes PYR1-1773
Testing
clojure -M:test-runner- 6 tests, 27 assertions, 0 failures.The new test redefines
make-rest-requestto track in-flight requests and asserts peak concurrency of 1 across 20 deletes. Confirmed it has teeth: swapping themapvforpmapfails it with(not (= 1 11)).clj-kondo --lint src test- 0 errors, 0 warnings.Not yet exercised against a live GeoServer; the acceptance check is a dev workspace removal producing zero
could not serialize accessentries.Trade-off
Removal gets slower in proportion to layer count - parrot04 carries ~18k gwc-layers. Sequential deletes are the cost of not having a retry loop; if removal wall time becomes a problem, bounded concurrency plus retry-on-serialization-failure is the next step.