fix(postgres): accept full_page_writes off on Amazon Aurora PostgreSQL only
Generation qualification refused every Amazon Aurora PostgreSQL server:
Aurora always reports full_page_writes = off and has no parameter to change
it, because its storage layer does not write torn pages.
The settings query now also returns
to_regprocedure('aurora_version()') IS NOT NULL (true on Aurora, false on
stock PostgreSQL, never an error). full_page_writes = off is accepted only
when that is true. Stock PostgreSQL must still report it on, and fsync on,
synchronous_commit on or remote_apply and every other check are unchanged
on both. The refusal text now says full-page writes are not required on
Aurora.
Tests run on a real postgres:17 engine whose settings are really changed;
only Aurora is simulated, by creating a function named aurora_version() in
the test database.
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
1 parent
1dc265647d
commit
cfbf0744f9
4 files changed
+168
-11
No files matched your search
+44
-1
@@ -52,13 +52,24 @@ final class PostgresGenerationDatabase implements AutoCloseable
|
||||
** Starts only this suite's loopback container with durable settings.
|
||||
***************************************************************************/
|
||||
PostgresGenerationDatabase()
|
||||
{
|
||||
this(true);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
** Pinned durability settings come from the server command line, which no
|
||||
** ALTER SYSTEM can override. An unpinned engine starts with the same values
|
||||
** (the PostgreSQL defaults) and lets a test weaken them through system().
|
||||
***************************************************************************/
|
||||
PostgresGenerationDatabase(boolean pinned)
|
||||
{
|
||||
// pgjdbc announces the JVM zone as the session TimeZone; qualification requires UTC.
|
||||
previousZone = java.util.TimeZone.getDefault();
|
||||
java.util.TimeZone.setDefault(java.util.TimeZone.getTimeZone("UTC"));
|
||||
container = new GenericContainer<>(IMAGE)
|
||||
.withEnv("POSTGRES_PASSWORD", rootPassword).withEnv("POSTGRES_DB", "bootstrap")
|
||||
.withCommand("postgres", "-c", "fsync=on", "-c", "synchronous_commit=on", "-c", "full_page_writes=on", "-c", "max_connections=60")
|
||||
.withCommand(pinned ? new String[] { "postgres", "-c", "fsync=on", "-c", "synchronous_commit=on", "-c", "full_page_writes=on", "-c", "max_connections=60" }
|
||||
: new String[] { "postgres", "-c", "max_connections=60" })
|
||||
.withExposedPorts(5432)
|
||||
.withCreateContainerCmdModifier(command -> command.getHostConfig().withMemory(768L * 1024 * 1024).withNanoCPUs(2_000_000_000L)
|
||||
.withPortBindings(FixtureEndpoint.publishedBinding(5432)))
|
||||
@@ -143,6 +154,38 @@ final class PostgresGenerationDatabase implements AutoCloseable
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
** Change one reloadable server setting of an unpinned engine (ALTER SYSTEM and
|
||||
** a configuration reload), then wait until a new session actually reports it.
|
||||
** Fixed fixture names and values only, never application input.
|
||||
***************************************************************************/
|
||||
void system(String name, String value) throws Exception
|
||||
{
|
||||
ConnectionManager.closeConnectionProviders();
|
||||
try(var connection = DriverManager.getConnection(server + "bootstrap" + OPTIONS, "postgres", rootPassword); var statement = connection.createStatement())
|
||||
{
|
||||
statement.execute("ALTER SYSTEM SET " + name + " = '" + value + "'");
|
||||
statement.execute("SELECT pg_reload_conf()");
|
||||
}
|
||||
long deadline = System.nanoTime() + java.time.Duration.ofSeconds(30).toNanos();
|
||||
while(true)
|
||||
{
|
||||
try(var connection = DriverManager.getConnection(server + "bootstrap" + OPTIONS, "postgres", rootPassword); var statement = connection.createStatement();
|
||||
var row = statement.executeQuery("SELECT current_setting('" + name + "')"))
|
||||
{
|
||||
if(row.next() && value.equals(row.getString(1)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(System.nanoTime() >= deadline)
|
||||
{
|
||||
throw new IllegalStateException("PostgreSQL fixture did not apply " + name);
|
||||
}
|
||||
Thread.sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
** Cold server restart retains only this container's data layer (committed
|
||||
** data must survive; Docker may publish a different loopback port).
|
||||
|
||||
Reference in new issue
Block a user