diff --git a/postgres/defaults/main.yml b/postgres/defaults/main.yml index 1f70df5df2a9ee6163768a95c4350a4e71bfe20a..22c6be75d123128054a0929958348d8bb6114f8a 100644 --- a/postgres/defaults/main.yml +++ b/postgres/defaults/main.yml @@ -3,6 +3,12 @@ postgres_pgdg_repo: false postgres_rsnapshot: false postgres_commvault_compat: false +postgres_pgbackrest: false +postgres_wal_archive: "{{ postgres_commvault_compat or postgres_pgbackrest }}" + +pgbackrest_retention_diff: 7 +pgbackrest_retention_full: 2 +pgbackrest_frequently_minute: "*/15" postgres_versions_debian: buster: "11" diff --git a/postgres/files/wal-archive-commvault.sh b/postgres/files/wal-archive-commvault.sh new file mode 100755 index 0000000000000000000000000000000000000000..3aba082ec3bd6e209278c09c9633bdf0e7e63ae9 --- /dev/null +++ b/postgres/files/wal-archive-commvault.sh @@ -0,0 +1,4 @@ +#!/bin/sh +set -e +[ $# -lt 2 ] && exit 1 +cp --reflink=auto "$1" "/var/backups/pg_wal/$2" diff --git a/postgres/files/wal-archive-pgbackrest.sh b/postgres/files/wal-archive-pgbackrest.sh new file mode 100755 index 0000000000000000000000000000000000000000..5f68615359a889a87168cd10459926cfaaebdea0 --- /dev/null +++ b/postgres/files/wal-archive-pgbackrest.sh @@ -0,0 +1,4 @@ +#!/bin/sh +set -e +[ $# -lt 1 ] && exit 1 +pgbackrest --stanza=main archive-push "$1" diff --git a/postgres/tasks/main.yml b/postgres/tasks/main.yml index 6ac01b7622612bc72a17b029a349dc65120d5973..4bc8c14f7ded1c81ce2b0fbf08eb3557413a402a 100644 --- a/postgres/tasks/main.yml +++ b/postgres/tasks/main.yml @@ -60,26 +60,52 @@ path: /etc/cron.d/postgres-snapshot state: absent -- name: Configure Commvault backup compatibility - when: postgres_commvault_compat +- name: Configure Postgres WAL archive framework + when: postgres_wal_archive block: - - name: Create WAL backup directory + - name: Create WAL archiver drop-in directory file: - path: /var/backups/pg_wal + path: /etc/postgresql/wal-archive state: directory - owner: postgres + owner: root group: postgres - mode: '0750' + mode: "0750" - name: Configure Postgres WAL archive postgresql_set: name: "{{ item.name }}" value: "{{ item.value }}" + become: true + become_user: postgres loop: - name: archive_mode value: "on" - name: archive_command - value: 'cp %p /var/backups/pg_wal/%f' + # pgBackRest checks the Postgres configuration, archive_command + # _needs_ to contain the string "pgbackrest", so add it as (unused) + # argument + value: >- + run-parts --report --arg=%p --arg=%f --arg=pgbackrest + /etc/postgresql/wal-archive + +- name: Configure Commvault backup compatibility + when: postgres_commvault_compat + block: + - name: Create WAL backup directory + file: + path: /var/backups/pg_wal + state: directory + owner: postgres + group: postgres + mode: '0750' + + - name: Configure Commvault Postgres WAL archive + copy: + src: wal-archive-commvault.sh + dest: /etc/postgresql/wal-archive/commvault + owner: root + group: postgres + mode: "0755" - name: Configure Postgres ident mappings blockinfile: @@ -106,3 +132,7 @@ options: map=postgres notify: - Restart Postgres + +- name: Configure pgBackRest + when: postgres_pgbackrest + import_tasks: pgbackrest.yml diff --git a/postgres/tasks/pgbackrest.yml b/postgres/tasks/pgbackrest.yml new file mode 100644 index 0000000000000000000000000000000000000000..fb06c97a58b9452562c521e09c54fb7c908ac570 --- /dev/null +++ b/postgres/tasks/pgbackrest.yml @@ -0,0 +1,76 @@ +--- + +- name: Install pgBackRest + apt: + name: pgbackrest + state: present + +- name: Create pgBackRest repository + file: + path: /var/backups/pgbackrest + state: directory + owner: postgres + group: postgres + mode: "0750" + +- name: Configure pgBackRest + template: + src: pgbackrest.conf + dest: /etc/pgbackrest.conf + owner: root + group: postgres + mode: "0640" + +- name: Initialise pgBackRest + command: + cmd: pgbackrest stanza-create --stanza=main + creates: /var/backups/pgbackrest/backup/main + become: true + become_user: postgres + +- name: Configure pgBackRest Postgres WAL archive + copy: + src: wal-archive-pgbackrest.sh + dest: /etc/postgresql/wal-archive/pgbackrest + owner: root + group: postgres + mode: "0750" + +- name: Configure pgBackRest cron env + cron: + cron_file: pgbackrest + user: postgres + env: true + name: SHELL + value: /bin/bash + +- name: Configure pgBackRest cron jobs + cron: + cron_file: pgbackrest + weekday: "{{ item.weekday }}" + hour: "{{ item.hour }}" + minute: "{{ item.minute }}" + name: pgbackrest-{{ item.name }} + user: postgres + job: >- + {% if item.sleep %}sleep $(($RANDOM \% 3600)) &&{% endif %} + pgbackrest backup --stanza=main --type={{ item.type }} + loop: + - name: frequently + weekday: "*" + hour: "*" + minute: "{{ pgbackrest_frequently_minute }}" + sleep: false + type: incr + - name: daily + weekday: 1-6 + hour: 3 + minute: 5 + sleep: true + type: diff + - name: weekly + weekday: 0 + hour: 3 + minute: 5 + sleep: true + type: full diff --git a/postgres/templates/pgbackrest.conf b/postgres/templates/pgbackrest.conf new file mode 100644 index 0000000000000000000000000000000000000000..a84affa4a2b862c0792127d4b7f4c63163fc5857 --- /dev/null +++ b/postgres/templates/pgbackrest.conf @@ -0,0 +1,7 @@ +[global] +repo1-path=/var/backups/pgbackrest +repo1-retention-diff={{ pgbackrest_retention_diff }} +repo1-retention-full={{ pgbackrest_retention_full }} + +[main] +db-path=/var/lib/postgresql/{{ postgres_version }}/main