RestoreCommand returns the command for performing a pgBackRest restore. In addition to calling the pgBackRest restore command with any pgBackRest options provided, the script also does the following: - Removes the patroni.dynamic.json file if present. This ensures the configuration from the cluste
(postgresVersion int32, pgdata string, params *postgres.ParameterSet, args ...string)
| 207 | // This ensures compatibility with the "existing" bootstrap method that is included in the |
| 208 | // Patroni config when bootstrapping a cluster using an existing data directory. |
| 209 | func RestoreCommand(postgresVersion int32, pgdata string, params *postgres.ParameterSet, args ...string) []string { |
| 210 | ps := params.DeepCopy() |
| 211 | ps.Add("data_directory", pgdata) |
| 212 | |
| 213 | // Keep history and WAL files until the cluster starts with its normal |
| 214 | // archiving enabled. |
| 215 | ps.Add("archive_command", "false -- store WAL files locally for now") |
| 216 | ps.Add("archive_mode", "on") |
| 217 | |
| 218 | // Enable "hot_standby" so we can connect to Postgres and observe its |
| 219 | // progress during recovery. |
| 220 | ps.Add("hot_standby", "on") |
| 221 | |
| 222 | configure := strings.Join([]string{ |
| 223 | // With "hot_standby" on, some parameters cannot be smaller than they were |
| 224 | // when Postgres was backed up. Configure these to match values reported by |
| 225 | // "pg_controldata" before starting Postgres. These parameters are also |
| 226 | // written to WAL files and may change during recovery. When they increase, |
| 227 | // Postgres exits and we reconfigure it here. |
| 228 | // - https://www.postgresql.org/docs/current/app-pgcontroldata.html |
| 229 | `control=$(LC_ALL=C pg_controldata)`, |
| 230 | `read -r max_conn <<< "${control##*max_connections setting:}"`, |
| 231 | `read -r max_lock <<< "${control##*max_locks_per_xact setting:}"`, |
| 232 | `read -r max_ptxn <<< "${control##*max_prepared_xacts setting:}"`, |
| 233 | `read -r max_work <<< "${control##*max_worker_processes setting:}"`, |
| 234 | |
| 235 | // During recovery, only allow connections over the domain socket. |
| 236 | `echo > /tmp/pg_hba.restore.conf 'local all "postgres" peer'`, |
| 237 | |
| 238 | // Combine parameters from Go with those detected in Bash. |
| 239 | `cat > /tmp/postgres.restore.conf <<'EOF'`, ps.String(), `EOF`, |
| 240 | `cat >> /tmp/postgres.restore.conf <<EOF`, |
| 241 | `hba_file = '/tmp/pg_hba.restore.conf'`, |
| 242 | `max_connections = '${max_conn}'`, |
| 243 | `max_locks_per_transaction = '${max_lock}'`, |
| 244 | `max_prepared_transactions = '${max_ptxn}'`, |
| 245 | `max_worker_processes = '${max_work}'`, |
| 246 | `EOF`, |
| 247 | |
| 248 | `version=$(< "${PGDATA}/PG_VERSION")`, |
| 249 | |
| 250 | // PostgreSQL v12 introduced the "max_wal_senders" parameter. |
| 251 | `if [[ "${version}" -ge 12 ]]; then`, |
| 252 | `read -r max_wals <<< "${control##*max_wal_senders setting:}"`, |
| 253 | `echo >> /tmp/postgres.restore.conf "max_wal_senders = '${max_wals}'"`, |
| 254 | `fi`, |
| 255 | |
| 256 | // TODO(sockets): PostgreSQL v14 is able to connect over abstract sockets in the network namespace. |
| 257 | `PGHOST=$([[ "${version}" -ge 14 ]] && echo '/tmp' || echo '/tmp')`, |
| 258 | `echo >> /tmp/postgres.restore.conf "unix_socket_directories = '${PGHOST}'"`, |
| 259 | }, "\n") |
| 260 | |
| 261 | script := strings.Join([]string{ |
| 262 | `declare -r PGDATA="$1" opts="$2"; export PGDATA PGHOST`, |
| 263 | postgres.ShellPath(postgresVersion), |
| 264 | |
| 265 | // Remove any "postmaster.pid" file leftover from a prior failure. |
| 266 | `rm -f "${PGDATA}/postmaster.pid"`, |