fix(upload-journal): accept Amazon Aurora PostgreSQL (full_page_writes=off) #65

Merged
james.maes merged 1 commits from fix/aurora-full-page-writes-develop into develop 2026-11-10 15:27:46 +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 2837f41 (cherry-pick of c6edde7 from the release/1.1 pull request; the two commits differ only in pom.xml, which neither changes):

  • Focused and full ./mvnw -B verify results for this branch are added as a comment.

Same change as the release/1.1 pull request, for develop, so the next 1.2 and later builds keep the rule. release/1.2 is not changed by either pull request.

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 `2837f41` (cherry-pick of `c6edde7` from the `release/1.1` pull request; the two commits differ only in `pom.xml`, which neither changes): - Focused and full `./mvnw -B verify` results for this branch are added as a comment. Same change as the `release/1.1` pull request, for `develop`, so the next `1.2` and later builds keep the rule. `release/1.2` is not changed by either pull request. 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:41 +00:00
fix(upload-journal): accept Amazon Aurora PostgreSQL (full_page_writes=off)
maven / build (push) Successful in 9m8s
build / maven (push) Successful in 9m8s
2837f4152a
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 2837f41 (this pull request's head; cherry-pick of c6edde7 from #64).

Local, Windows 11, Java 21, Docker 29.9.2:

  • ./mvnw -B -DpostgresJournalTests=true verify, one run: 335 tests run, 0 failures, 0 errors, 11 skipped, Checkstyle 0 violations, All coverage checks have been met, BUILD SUCCESS. Within it PostgresUploadJournalTest (real postgres:17 container, includes the three Aurora cases) ran 15 tests with 0 failures, 0 errors, 0 skipped, and PostgresJournalDatabaseTest ran 3 with 0 failures. The 11 skipped are the opt-in MySqlUploadJournalTest.
  • 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 7339 (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.

Verification of commit `2837f41` (this pull request's head; cherry-pick of `c6edde7` from #64). Local, Windows 11, Java 21, Docker 29.9.2: - `./mvnw -B -DpostgresJournalTests=true verify`, one run: 335 tests run, 0 failures, 0 errors, 11 skipped, Checkstyle 0 violations, `All coverage checks have been met`, BUILD SUCCESS. Within it `PostgresUploadJournalTest` (real `postgres:17` container, includes the three Aurora cases) ran 15 tests with 0 failures, 0 errors, 0 skipped, and `PostgresJournalDatabaseTest` ran 3 with 0 failures. The 11 skipped are the opt-in `MySqlUploadJournalTest`. - 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 7339 (`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`.
james.maes merged commit c6b077321c into develop 2026-11-10 15:27:46 +00:00
Sign in to join this conversation.