Skip to content

Commit ef38739

Browse files
committed
Wait only for local write of controller SQL
When Postgres replication is broken and synchronous commit is enabled, the controller blocks waiting for a remote write that will never happen. This change allows the controller to return from SQL writes and repair replication. Issue: PGO-1592
1 parent 4454815 commit ef38739

File tree

9 files changed

+37
-4
lines changed

9 files changed

+37
-4
lines changed

internal/controller/postgrescluster/pgmonitor_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ func TestReconcilePGMonitorExporterStatus(t *testing.T) {
602602
podExecCalled: false,
603603
// Status was generated manually for this test case
604604
// TODO (jmckulk): add code to generate status
605-
status: v1beta1.MonitoringStatus{ExporterConfiguration: "6d874c58df"},
605+
status: v1beta1.MonitoringStatus{ExporterConfiguration: "5c5f955485"},
606606
statusChangedAfterReconcile: false,
607607
}} {
608608
t.Run(test.name, func(t *testing.T) {

internal/pgaudit/postgres.go

+2
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ func EnableInPostgreSQL(ctx context.Context, exec postgres.Executor) error {
3535

3636
stdout, stderr, err := exec.ExecInAllDatabases(ctx,
3737
// Quiet the NOTICE from IF EXISTS, and install the pgAudit event triggers.
38+
// Use the default setting for "synchronous_commit".
3839
// - https://www.postgresql.org/docs/current/runtime-config-client.html
40+
// - https://www.postgresql.org/docs/current/runtime-config-wal.html
3941
// - https://github.com/pgaudit/pgaudit#settings
4042
`SET client_min_messages = WARNING; CREATE EXTENSION IF NOT EXISTS pgaudit;`,
4143
map[string]string{

internal/pgbouncer/postgres.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ func DisableInPostgreSQL(ctx context.Context, exec postgres.Executor) error {
6868
// - https://www.postgresql.org/docs/current/runtime-config-client.html
6969
`SET client_min_messages = WARNING;`,
7070

71+
// Do not wait for changes to be replicated. [Since PostgreSQL v9.1]
72+
// - https://www.postgresql.org/docs/current/runtime-config-wal.html
73+
`SET synchronous_commit = LOCAL;`,
74+
7175
// Drop the following objects in a transaction.
7276
`BEGIN;`,
7377

@@ -102,7 +106,7 @@ SELECT pg_catalog.format('DROP OWNED BY %I CASCADE', :'username')
102106
// Remove the PgBouncer user now that the objects and other privileges are gone.
103107
stdout, stderr, err = exec.ExecInDatabasesFromQuery(ctx,
104108
`SELECT pg_catalog.current_database()`,
105-
`SET client_min_messages = WARNING; DROP ROLE IF EXISTS :"username";`,
109+
`SET client_min_messages = WARNING; SET synchronous_commit = LOCAL; DROP ROLE IF EXISTS :"username";`,
106110
map[string]string{
107111
"username": postgresqlUser,
108112

@@ -130,6 +134,10 @@ func EnableInPostgreSQL(
130134
// - https://www.postgresql.org/docs/current/runtime-config-client.html
131135
`SET client_min_messages = WARNING;`,
132136

137+
// Do not wait for changes to be replicated. [Since PostgreSQL v9.1]
138+
// - https://www.postgresql.org/docs/current/runtime-config-wal.html
139+
`SET synchronous_commit = LOCAL;`,
140+
133141
// Create the following objects in a transaction so that permissions
134142
// are correct before any other session sees them.
135143
// - https://www.postgresql.org/docs/current/ddl-priv.html

internal/pgbouncer/postgres_test.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ func TestDisableInPostgreSQL(t *testing.T) {
4949
assert.NilError(t, err)
5050
assert.Equal(t, string(b), strings.TrimSpace(`
5151
SET client_min_messages = WARNING;
52+
SET synchronous_commit = LOCAL;
5253
BEGIN;
5354
DROP FUNCTION IF EXISTS :"namespace".get_auth(username TEXT);
5455
DROP SCHEMA IF EXISTS :"namespace" CASCADE;
@@ -90,7 +91,7 @@ COMMIT;`))
9091

9192
b, err := io.ReadAll(stdin)
9293
assert.NilError(t, err)
93-
assert.Equal(t, string(b), `SET client_min_messages = WARNING; DROP ROLE IF EXISTS :"username";`)
94+
assert.Equal(t, string(b), `SET client_min_messages = WARNING; SET synchronous_commit = LOCAL; DROP ROLE IF EXISTS :"username";`)
9495
gomega.NewWithT(t).Expect(command).To(gomega.ContainElements(
9596
`--set=username=_crunchypgbouncer`,
9697
), "expected query parameters")
@@ -135,6 +136,7 @@ func TestEnableInPostgreSQL(t *testing.T) {
135136
assert.NilError(t, err)
136137
assert.Equal(t, string(b), strings.TrimSpace(`
137138
SET client_min_messages = WARNING;
139+
SET synchronous_commit = LOCAL;
138140
BEGIN;
139141
SELECT pg_catalog.format('CREATE ROLE %I NOLOGIN', :'username')
140142
WHERE NOT EXISTS (SELECT 1 FROM pg_catalog.pg_roles WHERE rolname = :'username')

internal/pgmonitor/postgres.go

+8
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ func EnableExporterInPostgreSQL(ctx context.Context, exec postgres.Executor,
7979
// - https://www.postgresql.org/docs/current/runtime-config-client.html
8080
`SET client_min_messages = WARNING;`,
8181

82+
// Do not wait for changes to be replicated. [Since PostgreSQL v9.1]
83+
// - https://www.postgresql.org/docs/current/runtime-config-wal.html
84+
`SET synchronous_commit = LOCAL;`,
85+
8286
// Exporter expects that extension(s) to be installed in all databases
8387
// pg_stat_statements: https://access.crunchydata.com/documentation/pgmonitor/latest/exporter/
8488
"CREATE EXTENSION IF NOT EXISTS pg_stat_statements;",
@@ -103,6 +107,10 @@ func EnableExporterInPostgreSQL(ctx context.Context, exec postgres.Executor,
103107
// - https://www.postgresql.org/docs/current/runtime-config-client.html
104108
`SET client_min_messages = WARNING;`,
105109

110+
// Do not wait for changes to be replicated. [Since PostgreSQL v9.1]
111+
// - https://www.postgresql.org/docs/current/runtime-config-wal.html
112+
`SET synchronous_commit = LOCAL;`,
113+
106114
// Setup.sql file from the exporter image. sql is specific
107115
// to the PostgreSQL version
108116
setup,

internal/postgis/postgis.go

+4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ func EnableInPostgreSQL(ctx context.Context, exec postgres.Executor) error {
2626
// - https://www.postgresql.org/docs/current/runtime-config-client.html
2727
`SET client_min_messages = WARNING;`,
2828

29+
// Do not wait for changes to be replicated. [Since PostgreSQL v9.1]
30+
// - https://www.postgresql.org/docs/current/runtime-config-wal.html
31+
`SET synchronous_commit = LOCAL;`,
32+
2933
`CREATE EXTENSION IF NOT EXISTS postgis;`,
3034
`CREATE EXTENSION IF NOT EXISTS postgis_topology;`,
3135
`CREATE EXTENSION IF NOT EXISTS fuzzystrmatch;`,

internal/postgis/postgis_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ func TestEnableInPostgreSQL(t *testing.T) {
2929
b, err := io.ReadAll(stdin)
3030
assert.NilError(t, err)
3131
assert.Equal(t, string(b), `SET client_min_messages = WARNING;
32+
SET synchronous_commit = LOCAL;
3233
CREATE EXTENSION IF NOT EXISTS postgis;
3334
CREATE EXTENSION IF NOT EXISTS postgis_topology;
3435
CREATE EXTENSION IF NOT EXISTS fuzzystrmatch;

internal/postgres/users.go

+8
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ func WriteUsersInPostgreSQL(
6969
var err error
7070
var sql bytes.Buffer
7171

72+
// Do not wait for changes to be replicated. [Since PostgreSQL v9.1]
73+
// - https://www.postgresql.org/docs/current/runtime-config-wal.html
74+
_, _ = sql.WriteString(`SET synchronous_commit = LOCAL;`)
75+
7276
// Prevent unexpected dereferences by emptying "search_path". The "pg_catalog"
7377
// schema is still searched, and only temporary objects can be created.
7478
// - https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-SEARCH-PATH
@@ -219,6 +223,10 @@ func WriteUsersSchemasInPostgreSQL(ctx context.Context, exec Executor,
219223
// - https://www.postgresql.org/docs/current/runtime-config-client.html
220224
`SET client_min_messages = WARNING;`,
221225

226+
// Do not wait for changes to be replicated. [Since PostgreSQL v9.1]
227+
// - https://www.postgresql.org/docs/current/runtime-config-wal.html
228+
`SET synchronous_commit = LOCAL;`,
229+
222230
// Creates a schema named after and owned by the user
223231
// - https://www.postgresql.org/docs/current/ddl-schemas.html
224232
// - https://www.postgresql.org/docs/current/sql-createschema.html

internal/postgres/users_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func TestWriteUsersInPostgreSQL(t *testing.T) {
6363
b, err := io.ReadAll(stdin)
6464
assert.NilError(t, err)
6565
assert.Equal(t, string(b), strings.TrimSpace(`
66-
SET search_path TO '';
66+
SET synchronous_commit = LOCAL;SET search_path TO '';
6767
CREATE TEMPORARY TABLE input (id serial, data json);
6868
\copy input (data) from stdin with (format text)
6969
\.

0 commit comments

Comments
 (0)