Skip to content

Commit 9aa988c

Browse files
archive-async by default with spool-path (#3962)
* archive-async by default with spool-path Issue: PGO-1371 PGO-1142
1 parent 5f07d66 commit 9aa988c

File tree

7 files changed

+62
-8
lines changed

7 files changed

+62
-8
lines changed

internal/controller/postgrescluster/pgbackrest_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -2072,7 +2072,7 @@ func TestReconcileCloudBasedDataSource(t *testing.T) {
20722072
result: testResult{
20732073
configCount: 1, jobCount: 1, pvcCount: 1,
20742074
expectedClusterCondition: nil,
2075-
conf: "|\n # Generated by postgres-operator. DO NOT EDIT.\n # Your changes will not be saved.\n\n [global]\n log-path = /pgdata/pgbackrest/log\n repo1-path = /pgbackrest/repo1\n\n [db]\n pg1-path = /pgdata/pg13\n pg1-port = 5432\n pg1-socket-path = /tmp/postgres\n",
2075+
conf: "|\n # Generated by postgres-operator. DO NOT EDIT.\n # Your changes will not be saved.\n\n [global]\n archive-async = y\n log-path = /pgdata/pgbackrest/log\n repo1-path = /pgbackrest/repo1\n spool-path = /pgdata/pgbackrest-spool\n\n [db]\n pg1-path = /pgdata/pg13\n pg1-port = 5432\n pg1-socket-path = /tmp/postgres\n",
20762076
},
20772077
}, {
20782078
desc: "global/configuration set",
@@ -2089,7 +2089,7 @@ func TestReconcileCloudBasedDataSource(t *testing.T) {
20892089
result: testResult{
20902090
configCount: 1, jobCount: 1, pvcCount: 1,
20912091
expectedClusterCondition: nil,
2092-
conf: "|\n # Generated by postgres-operator. DO NOT EDIT.\n # Your changes will not be saved.\n\n [global]\n log-path = /pgdata/pgbackrest/log\n repo1-path = elephant\n\n [db]\n pg1-path = /pgdata/pg13\n pg1-port = 5432\n pg1-socket-path = /tmp/postgres\n",
2092+
conf: "|\n # Generated by postgres-operator. DO NOT EDIT.\n # Your changes will not be saved.\n\n [global]\n archive-async = y\n log-path = /pgdata/pgbackrest/log\n repo1-path = elephant\n spool-path = /pgdata/pgbackrest-spool\n\n [db]\n pg1-path = /pgdata/pg13\n pg1-port = 5432\n pg1-socket-path = /tmp/postgres\n",
20932093
},
20942094
}, {
20952095
desc: "invalid option: stanza",
@@ -2104,7 +2104,7 @@ func TestReconcileCloudBasedDataSource(t *testing.T) {
21042104
result: testResult{
21052105
configCount: 1, jobCount: 0, pvcCount: 1,
21062106
expectedClusterCondition: nil,
2107-
conf: "|\n # Generated by postgres-operator. DO NOT EDIT.\n # Your changes will not be saved.\n\n [global]\n log-path = /pgdata/pgbackrest/log\n repo1-path = /pgbackrest/repo1\n\n [db]\n pg1-path = /pgdata/pg13\n pg1-port = 5432\n pg1-socket-path = /tmp/postgres\n",
2107+
conf: "|\n # Generated by postgres-operator. DO NOT EDIT.\n # Your changes will not be saved.\n\n [global]\n archive-async = y\n log-path = /pgdata/pgbackrest/log\n repo1-path = /pgbackrest/repo1\n spool-path = /pgdata/pgbackrest-spool\n\n [db]\n pg1-path = /pgdata/pg13\n pg1-port = 5432\n pg1-socket-path = /tmp/postgres\n",
21082108
},
21092109
}, {
21102110
desc: "cluster bootstrapped init condition missing",
@@ -2123,7 +2123,7 @@ func TestReconcileCloudBasedDataSource(t *testing.T) {
21232123
Reason: "ClusterAlreadyBootstrapped",
21242124
Message: "The cluster is already bootstrapped",
21252125
},
2126-
conf: "|\n # Generated by postgres-operator. DO NOT EDIT.\n # Your changes will not be saved.\n\n [global]\n log-path = /pgdata/pgbackrest/log\n repo1-path = /pgbackrest/repo1\n\n [db]\n pg1-path = /pgdata/pg13\n pg1-port = 5432\n pg1-socket-path = /tmp/postgres\n",
2126+
conf: "|\n # Generated by postgres-operator. DO NOT EDIT.\n # Your changes will not be saved.\n\n [global]\n archive-async = y\n log-path = /pgdata/pgbackrest/log\n repo1-path = /pgbackrest/repo1\n spool-path = /pgdata/pgbackrest-spool\n\n [db]\n pg1-path = /pgdata/pg13\n pg1-port = 5432\n pg1-socket-path = /tmp/postgres\n",
21272127
},
21282128
}}
21292129

internal/pgbackrest/config.go

+4
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,10 @@ func populatePGInstanceConfigurationMap(
291291
global := iniMultiSet{}
292292
stanza := iniMultiSet{}
293293

294+
// For faster and more robust WAL archiving, we turn on pgBackRest archive-async.
295+
global.Set("archive-async", "y")
296+
// pgBackRest spool-path should always be co-located with the Postgres WAL path.
297+
global.Set("spool-path", "/pgdata/pgbackrest-spool")
294298
// pgBackRest will log to the pgData volume for commands run on the PostgreSQL instance
295299
global.Set("log-path", naming.PGBackRestPGDataLogPath)
296300

internal/pgbackrest/config_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ pg1-socket-path = /tmp/postgres
131131
# Your changes will not be saved.
132132
133133
[global]
134+
archive-async = y
134135
log-path = /pgdata/pgbackrest/log
135136
repo1-host = repo-hostname-0.pod-service-name.test-ns.svc.`+domain+`
136137
repo1-host-ca-file = /etc/pgbackrest/conf.d/~postgres-operator/tls-ca.crt
@@ -151,6 +152,7 @@ repo4-s3-bucket = s-bucket
151152
repo4-s3-endpoint = endpoint-s
152153
repo4-s3-region = earth
153154
repo4-type = s3
155+
spool-path = /pgdata/pgbackrest-spool
154156
155157
[db]
156158
pg1-path = /pgdata/pg12

internal/postgres/config.go

+14-4
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,17 @@ func DataDirectory(cluster *v1beta1.PostgresCluster) string {
103103
func WALDirectory(
104104
cluster *v1beta1.PostgresCluster, instance *v1beta1.PostgresInstanceSetSpec,
105105
) string {
106-
// When no WAL volume is specified, store WAL files on the main data volume.
107-
walStorage := dataMountPath
106+
return fmt.Sprintf("%s/pg%d_wal", WALStorage(instance), cluster.Spec.PostgresVersion)
107+
}
108+
109+
// WALStorage returns the absolute path to the disk where an instance stores its
110+
// WAL files. Use [WALDirectory] for the exact directory that Postgres uses.
111+
func WALStorage(instance *v1beta1.PostgresInstanceSetSpec) string {
108112
if instance.WALVolumeClaimSpec != nil {
109-
walStorage = walMountPath
113+
return walMountPath
110114
}
111-
return fmt.Sprintf("%s/pg%d_wal", walStorage, cluster.Spec.PostgresVersion)
115+
// When no WAL volume is specified, store WAL files on the main data volume.
116+
return dataMountPath
112117
}
113118

114119
// Environment returns the environment variables required to invoke PostgreSQL
@@ -307,6 +312,11 @@ chmod +x /tmp/pg_rewind_tde.sh
307312
`echo Initializing ...`,
308313
`results 'uid' "$(id -u ||:)" 'gid' "$(id -G ||:)"`,
309314

315+
// The pgbackrest spool path should be co-located with wal. If a wal volume exists, symlink the spool-path to it.
316+
`if [[ "${pgwal_directory}" == *"pgwal/"* ]] && [[ ! -d "/pgwal/pgbackrest-spool" ]];then rm -rf "/pgdata/pgbackrest-spool" && mkdir -p "/pgwal/pgbackrest-spool" && ln --force --symbolic "/pgwal/pgbackrest-spool" "/pgdata/pgbackrest-spool";fi`,
317+
// When a pgwal volume is removed, the symlink will be broken; force pgbackrest to recreate spool-path.
318+
`if [[ ! -e "/pgdata/pgbackrest-spool" ]];then rm -rf /pgdata/pgbackrest-spool;fi`,
319+
310320
// Abort when the PostgreSQL version installed in the image does not
311321
// match the cluster spec.
312322
`results 'postgres path' "$(command -v postgres ||:)"`,

internal/postgres/reconcile_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,8 @@ initContainers:
255255
)
256256
echo Initializing ...
257257
results 'uid' "$(id -u ||:)" 'gid' "$(id -G ||:)"
258+
if [[ "${pgwal_directory}" == *"pgwal/"* ]] && [[ ! -d "/pgwal/pgbackrest-spool" ]];then rm -rf "/pgdata/pgbackrest-spool" && mkdir -p "/pgwal/pgbackrest-spool" && ln --force --symbolic "/pgwal/pgbackrest-spool" "/pgdata/pgbackrest-spool";fi
259+
if [[ ! -e "/pgdata/pgbackrest-spool" ]];then rm -rf /pgdata/pgbackrest-spool;fi
258260
results 'postgres path' "$(command -v postgres ||:)"
259261
results 'postgres version' "${postgres_version:=$(postgres --version ||:)}"
260262
[[ "${postgres_version}" =~ ") ${expected_major_version}"($|[^0-9]) ]] ||
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
apiVersion: kuttl.dev/v1beta1
2+
kind: TestStep
3+
commands:
4+
- script: |
5+
PRIMARY=$(
6+
kubectl get pod --namespace "${NAMESPACE}" \
7+
--output name --selector '
8+
postgres-operator.crunchydata.com/role=master'
9+
)
10+
11+
LIST=$(
12+
kubectl exec --namespace "${NAMESPACE}" -c database "${PRIMARY}" -- \
13+
ls -l /pgdata
14+
)
15+
16+
contains() { bash -ceu '[[ "$1" == *"$2"* ]]' - "$@"; }
17+
contains "$LIST" "pgbackrest-spool" || exit 1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
apiVersion: kuttl.dev/v1beta1
2+
kind: TestStep
3+
commands:
4+
- script: |
5+
PRIMARY=$(
6+
kubectl get pod --namespace "${NAMESPACE}" \
7+
--output name --selector '
8+
postgres-operator.crunchydata.com/role=master'
9+
)
10+
11+
LIST=$(
12+
kubectl exec --namespace "${NAMESPACE}" -c database "${PRIMARY}" -- \
13+
ls -l /pgdata
14+
)
15+
16+
contains() { bash -ceu '[[ "$1" == *"$2"* ]]' - "$@"; }
17+
18+
# Confirm that the pgbackrest spool-path has been symlinked to the wal volume.
19+
contains "$LIST" "pgbackrest-spool -> /pgwal/pgbackrest-spool" || exit 1

0 commit comments

Comments
 (0)