]> git.immae.eu Git - github/fretlink/ansible-postgresql-role.git/commitdiff
standby-clone: Allow cloning of standby server with pg_basebackup
authorPaul B <paul@bonaud.fr>
Thu, 28 May 2020 16:41:49 +0000 (18:41 +0200)
committerPaul B <paul@bonaud.fr>
Fri, 5 Jun 2020 12:37:21 +0000 (14:37 +0200)
Right now the role assumes you have a base backup available with
Barman. However if you don't have an initial barman backup you might
want to clone the primary server directly to setup your standby
server.

This PR adds a new `primary.pg_basebackup` option to the cluster
configuration which if enabled (set to `true`) will create a
`/root/standby-clone-{{ postgres_version }}-{{ postgres_cluster_name }}.sh`
script on the standby server which helps to initialise a standby
server.

⚠️ Breaking change: the current role behavior which creates a cloning
script fetching the initial backup from barman will not be
enabled by default anymore. You will need to add the new
`primary.restore_barman_directory` option in your role
configuration to do so. ⚠️

tasks/postgres-cluster.yml
tasks/postgres-standby-barman.yml
tasks/postgres-standby-basebackup.yml [new file with mode: 0644]
templates/standby-barman-clone.sh.j2 [moved from templates/standby-clone.sh.j2 with 100% similarity]
templates/standby-pg_basebackup-clone.sh.j2 [new file with mode: 0755]

index a8e96c11ac4d83102a3a7572a17807c98c89e3c2..4f62d31a770168157adcc38cab7b156543206efb 100644 (file)
 
 - name: Add standby clone from barman script
   include: postgres-standby-barman.yml
-  when: postgres_barman_server is defined
+  when: postgres_barman_server is defined and postgres_primary.restore_barman_directory is defined
+
+- name: Add standby clone from pg_basebackup
+  include: postgres-standby-basebackup.yml
+  when: postgres_primary and postgres_primary.pg_basebackup is defined
 
 - name: Determine SSD or rotational disks
   raw: 'lsblk --noheadings --nodeps --raw --output=rota | grep -q 1'
index 6a94b755d6fd77073c3a6bff4d0c10967f311dc0..fb71d32e9dfd6c65381f115be64041702e97d90b 100644 (file)
@@ -11,8 +11,8 @@
     path: "{{ postgres_barman_path_prefix | default('~') }}"
     rsync_password_file: "{{ postgres_barman_rsync_enabled | ternary(' --password-file=/var/lib/postgresql/.rsync_pass ', '') }}"
 
-- name: Copy secondary script
-  template: src=standby-clone.sh.j2 dest=/root/standby-clone-{{ postgres_version }}-{{ postgres_cluster_name }}.sh mode=0755
+- name: Copy secondary barman clone script
+  template: src=standby-barman-clone.sh.j2 dest=/root/standby-clone-{{ postgres_version }}-{{ postgres_cluster_name }}.sh mode=0755
 
 - name: Copy rsync password file
   copy:
diff --git a/tasks/postgres-standby-basebackup.yml b/tasks/postgres-standby-basebackup.yml
new file mode 100644 (file)
index 0000000..db52d55
--- /dev/null
@@ -0,0 +1,4 @@
+---
+- name: Copy secondary pg_basebackup clone script
+  template: src=standby-pg_basebackup-clone.sh.j2 dest=/root/standby-clone-{{ postgres_version }}-{{ postgres_cluster_name }}.sh mode=0755
+  no_log: true
diff --git a/templates/standby-pg_basebackup-clone.sh.j2 b/templates/standby-pg_basebackup-clone.sh.j2
new file mode 100755 (executable)
index 0000000..ca34a05
--- /dev/null
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+# {{ ansible_managed }}
+
+set -eo pipefail
+
+CLUSTER_VERSION="{{ postgres_version }}"
+CLUSTER_NAME="{{ postgres_cluster_name }}"
+PRIMARY_CLUSTER_HOST="{{ postgres_primary.host }}"
+PRIMARY_CLUSTER_PORT="{{ postgres_primary.port }}"
+PRIMARY_CLUSTER_USER="{{ postgres_primary.replication_user }}"
+PRIMARY_CLUSTER_PASSWORD="{{ postgres_primary.replication_password }}"
+{% if postgres_primary.replication_dbname is defined %}
+PRIMARY_CLUSTER_DBNAME=" dbname='{{ postgres_primary.replication_dbname }}'"
+{% endif %}
+
+read -p "You are about to clone the primary cluster (${PRIMARY_CLUSTER_HOST}:${PRIMARY_CLUSTER_PORT}) with pg_basebackup. This will replace the local ${CLUSTER_VERSION}/${CLUSTER_NAME} cluster. Are you sure? [y/n] " -r go
+
+if [ "$go" != "y" ]; then
+    echo "Aborted."
+    exit 1
+fi
+
+BACKUP_DATE=$(date +%s)
+
+echo "Stopping PostgreSQL"
+pg_ctlcluster "${CLUSTER_VERSION}" "${CLUSTER_NAME}" stop || true
+
+echo "Cleaning up old cluster directory"
+sudo -u postgres mv "/var/lib/postgresql/${CLUSTER_VERSION}/${CLUSTER_NAME}"{,"_${BACKUP_DATE}"}
+
+echo "Creating new directory"
+sudo -u postgres mkdir -p "/var/lib/postgresql/${CLUSTER_VERSION}/${CLUSTER_NAME}"
+
+echo "Get backup from primary server"
+sudo -u postgres \
+  time "/usr/lib/postgresql/${CLUSTER_VERSION}/bin/pg_basebackup" --format=p -R \
+  -d "host='${PRIMARY_CLUSTER_HOST}' port='${PRIMARY_CLUSTER_PORT}' user='${PRIMARY_CLUSTER_USER}' password='${PRIMARY_CLUSTER_PASSWORD}' ${PRIMARY_CLUSTER_DBNAME} sslmode=require" \
+  -D "/var/lib/postgresql/${CLUSTER_VERSION}/${CLUSTER_NAME}/"
+
+echo "Restoring .conf and server certificate"
+sudo -u postgres cp -a "/var/lib/postgresql/${CLUSTER_VERSION}/${CLUSTER_NAME}_${BACKUP_DATE}/"{*.conf,server.crt,server.key} "/var/lib/postgresql/${CLUSTER_VERSION}/${CLUSTER_NAME}/"
+
+echo "Ensure rights are correcly set"
+chown -R postgres:postgres "/var/lib/postgresql/${CLUSTER_VERSION}/"
+chmod 0700 "/var/lib/postgresql/${CLUSTER_VERSION}/"
+chmod -R o-rwx "/var/lib/postgresql/${CLUSTER_VERSION}/"
+
+echo "Starting PostgreSQL"
+sudo pg_ctlcluster "${CLUSTER_VERSION}" "${CLUSTER_NAME}" start