fix(upload-journal): accept Amazon Aurora PostgreSQL (full_page_writes=off) [release/1.1] #64

Merged
james.maes merged 1 commits from fix/aurora-full-page-writes-1.1 into release/1.1 2026-11-10 13:00:14 +00:00
Owner

Defect

The retained upload journal's PostgreSQL 17 qualification (PostgresJournalDatabase) refuses every call unless current_setting('full_page_writes') is on. Amazon Aurora PostgreSQL reports full_page_writes = off (measured on engine 17.9: context sighup, source default, not present in the cluster parameter group), so the journal cannot be used there.

Rule implemented

  • The settings query gains an eleventh column: to_regprocedure('aurora_version()') IS NOT NULL. It is true on Aurora, false on stock PostgreSQL 17, and never raises.
  • full_page_writes qualifies when it is on, or when it is off and that column is true (PostgresJournalDatabase.tornPagesPrevented).
  • Nothing else changes. Stock PostgreSQL with full_page_writes = off is still refused. On Aurora, synchronous_commit, fsync, recovery state, read-only state, isolation, time zone, lock timeout (1 to 5000 ms), server version, catalog, table and index checks are exactly as before. The refusal message is unchanged.

Why it is safe on Aurora and not on stock PostgreSQL: stock PostgreSQL repairs a partly written page from the full page image in the write-ahead log, so off can lose committed rows after a crash. Aurora's storage layer does not write torn pages, and the parameter cannot be changed there.

Known limit, documented in docs/RETAINED-UPLOAD-JOURNAL.md: the detection is a name lookup, so a function named aurora_version() on the search path of a stock server is reported as Aurora.

Other places with the same assumption

full_page_writes is read in one place only, PostgresJournalDatabase. MySqlJournalDatabase (MySQL 8.4 innodb_doublewrite, Aurora MySQL refused) and the H2 WRITE_DELAY=0 check are different backends and are not changed.

Tests

  • New PostgresJournalDatabaseTest (always runs, no database): the pure decision, and that the settings query detects Aurora only through to_regprocedure as its last column.
  • PostgresUploadJournalTest (opt-in with -DpostgresJournalTests=true, real postgres:17 container), three new cases: the settings query returns the detection column as the application role without aborting the transaction; full_page_writes = off is refused on stock PostgreSQL and accepted once Aurora is detected; Aurora with synchronous_commit off or fsync off is still refused.
  • What is simulated: no Aurora server is used. A function named aurora_version() is created in the test database so to_regprocedure resolves, and full_page_writes (and fsync) are turned off on the stock server with ALTER SYSTEM and a reload. The container no longer passes fsync=on and full_page_writes=on on the command line, because a command-line value cannot be changed by a reload; both are set to on with ALTER SYSTEM at start and before every test.

Verification

Local, Windows 11, Java 21, Docker 29.9.2, commit c6edde7:

  • ./mvnw -B -DpostgresJournalTests=true -Dtest=PostgresUploadJournalTest,PostgresJournalDatabaseTest test: 18 tests run, 0 failures, 0 errors, 0 skipped (15 real PostgreSQL 17 cases, 3 pure cases); Checkstyle reported 0 violations.
  • ./mvnw -B verify: in progress when this pull request was opened; the result is added as a comment.

Targets release/1.1 because that branch publishes the 1.1.0 release candidates: its head is the v1.1.0-RC.1 tag with <revision>1.1.0-RC.1</revision>, and a push to it publishes 1.1.0-RC.2. This is the only change between 1.1.0-RC.1 and 1.1.0-RC.2. The same change is opened against develop separately.

Not merged, tagged or released by the author.

🤖 Generated with Claude Code

## Defect The retained upload journal's PostgreSQL 17 qualification (`PostgresJournalDatabase`) refuses every call unless `current_setting('full_page_writes')` is `on`. Amazon Aurora PostgreSQL reports `full_page_writes = off` (measured on engine 17.9: context sighup, source default, not present in the cluster parameter group), so the journal cannot be used there. ## Rule implemented - The settings query gains an eleventh column: `to_regprocedure('aurora_version()') IS NOT NULL`. It is true on Aurora, false on stock PostgreSQL 17, and never raises. - `full_page_writes` qualifies when it is `on`, or when it is `off` and that column is true (`PostgresJournalDatabase.tornPagesPrevented`). - Nothing else changes. Stock PostgreSQL with `full_page_writes = off` is still refused. On Aurora, `synchronous_commit`, `fsync`, recovery state, read-only state, isolation, time zone, lock timeout (1 to 5000 ms), server version, catalog, table and index checks are exactly as before. The refusal message is unchanged. Why it is safe on Aurora and not on stock PostgreSQL: stock PostgreSQL repairs a partly written page from the full page image in the write-ahead log, so `off` can lose committed rows after a crash. Aurora's storage layer does not write torn pages, and the parameter cannot be changed there. Known limit, documented in `docs/RETAINED-UPLOAD-JOURNAL.md`: the detection is a name lookup, so a function named `aurora_version()` on the search path of a stock server is reported as Aurora. ## Other places with the same assumption `full_page_writes` is read in one place only, `PostgresJournalDatabase`. `MySqlJournalDatabase` (MySQL 8.4 `innodb_doublewrite`, Aurora MySQL refused) and the H2 `WRITE_DELAY=0` check are different backends and are not changed. ## Tests - New `PostgresJournalDatabaseTest` (always runs, no database): the pure decision, and that the settings query detects Aurora only through `to_regprocedure` as its last column. - `PostgresUploadJournalTest` (opt-in with `-DpostgresJournalTests=true`, real `postgres:17` container), three new cases: the settings query returns the detection column as the application role without aborting the transaction; `full_page_writes = off` is refused on stock PostgreSQL and accepted once Aurora is detected; Aurora with `synchronous_commit` off or `fsync` off is still refused. - What is simulated: no Aurora server is used. A function named `aurora_version()` is created in the test database so `to_regprocedure` resolves, and `full_page_writes` (and `fsync`) are turned off on the stock server with `ALTER SYSTEM` and a reload. The container no longer passes `fsync=on` and `full_page_writes=on` on the command line, because a command-line value cannot be changed by a reload; both are set to `on` with `ALTER SYSTEM` at start and before every test. ## Verification Local, Windows 11, Java 21, Docker 29.9.2, commit `c6edde7`: - `./mvnw -B -DpostgresJournalTests=true -Dtest=PostgresUploadJournalTest,PostgresJournalDatabaseTest test`: 18 tests run, 0 failures, 0 errors, 0 skipped (15 real PostgreSQL 17 cases, 3 pure cases); Checkstyle reported 0 violations. - `./mvnw -B verify`: in progress when this pull request was opened; the result is added as a comment. Targets `release/1.1` because that branch publishes the `1.1.0` release candidates: its head is the `v1.1.0-RC.1` tag with `<revision>1.1.0-RC.1</revision>`, and a push to it publishes `1.1.0-RC.2`. This is the only change between `1.1.0-RC.1` and `1.1.0-RC.2`. The same change is opened against `develop` separately. Not merged, tagged or released by the author. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
james.maes added 1 commit 2026-11-10 02:28:40 +00:00
fix(upload-journal): accept Amazon Aurora PostgreSQL (full_page_writes=off)
maven / build (push) Successful in 8m26s
build / maven (push) Successful in 8m25s
c6edde7339
The PostgreSQL 17 journal qualification refused every call on Amazon Aurora
PostgreSQL, which reports full_page_writes=off and does not expose the
parameter in its cluster parameter group.

- The settings query gains an eleventh column,
  to_regprocedure('aurora_version()') IS NOT NULL, which is true on Aurora,
  false on stock PostgreSQL 17 and never raises.
- full_page_writes=off is accepted only when that column is true. Stock
  PostgreSQL with full_page_writes=off is still refused, and synchronous_commit,
  fsync, recovery, isolation, time zone and lock timeout are unchanged on Aurora.
- The decision is the pure function tornPagesPrevented, covered by an always-on
  unit test. The opt-in real PostgreSQL 17 suite simulates Aurora with a
  function named aurora_version() and full_page_writes=off on the server.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Author
Owner

Verification of commit c6edde7 (this pull request's head).

Local, Windows 11, Java 21, Docker 29.9.2:

  • ./mvnw -B -DpostgresJournalTests=true -Dtest=PostgresUploadJournalTest,PostgresJournalDatabaseTest test: 18 tests run, 0 failures, 0 errors, 0 skipped. Checkstyle: 0 violations.
  • ./mvnw -B verify, first run: 335 tests run, 0 failures, 1 error, 26 skipped, BUILD FAILURE. The error was AttachmentTransactionsPostgresTest.deleteOuterRollbackPreservesAttachment, java.net.SocketException: No buffer space available (maximum connections reached?): connect while opening a connection to its test container. That test and class are not touched by this change.
  • ./mvnw -B verify, second run, same commit, nothing changed: 335 tests run, 0 failures, 0 errors, 26 skipped, Checkstyle 0 violations, All coverage checks have been met, BUILD SUCCESS. The 26 skipped are the opt-in suites (MySqlUploadJournalTest 11, PostgresUploadJournalTest 15), which are off by default.
  • No gate was skipped. Maven was given a settings file that only adds the QRun-IO Gitea registry as a repository, as the CI workflow does.

Gitea Actions run 7338 (build.yaml, push of this branch): completed, success, first attempt. Its log shows Build kind: verify, Tests run: 335, Failures: 0, Errors: 0, Skipped: 26, BUILD SUCCESS. CI does not enable postgresJournalTests, so the three new real-PostgreSQL cases ran locally only; the three new pure cases ran in CI.

Verification of commit `c6edde7` (this pull request's head). Local, Windows 11, Java 21, Docker 29.9.2: - `./mvnw -B -DpostgresJournalTests=true -Dtest=PostgresUploadJournalTest,PostgresJournalDatabaseTest test`: 18 tests run, 0 failures, 0 errors, 0 skipped. Checkstyle: 0 violations. - `./mvnw -B verify`, first run: 335 tests run, 0 failures, 1 error, 26 skipped, BUILD FAILURE. The error was `AttachmentTransactionsPostgresTest.deleteOuterRollbackPreservesAttachment`, `java.net.SocketException: No buffer space available (maximum connections reached?): connect` while opening a connection to its test container. That test and class are not touched by this change. - `./mvnw -B verify`, second run, same commit, nothing changed: 335 tests run, 0 failures, 0 errors, 26 skipped, Checkstyle 0 violations, `All coverage checks have been met`, BUILD SUCCESS. The 26 skipped are the opt-in suites (`MySqlUploadJournalTest` 11, `PostgresUploadJournalTest` 15), which are off by default. - No gate was skipped. Maven was given a settings file that only adds the QRun-IO Gitea registry as a repository, as the CI workflow does. Gitea Actions run 7338 (`build.yaml`, push of this branch): completed, success, first attempt. Its log shows `Build kind: verify`, `Tests run: 335, Failures: 0, Errors: 0, Skipped: 26`, `BUILD SUCCESS`. CI does not enable `postgresJournalTests`, so the three new real-PostgreSQL cases ran locally only; the three new pure cases ran in CI.
james.maes merged commit 8f04068371 into release/1.1 2026-11-10 13:00:14 +00:00
Sign in to join this conversation.