galaxyproject / ansible-postgresql

An Ansible role for managing a PostgreSQL server
https://galaxy.ansible.com/galaxyproject/postgresql
122 stars 58 forks source link

Backups not working on Postgres 15 #55

Closed paulkre closed 2 months ago

paulkre commented 7 months ago

Running /var/lib/postgresql/backup/bin/backup.py --rsync-backup-opts '\-rptg' --keep 30 --backup --clean-archive /archive will fail with

INFO:root:Initiating backup with pg_start_backup()
INFO:root:Connecting to database
INFO:root:Backup label is: 20240216T184527Z
Traceback (most recent call last):
  File "/var/lib/postgresql/backup/bin/backup.py", line 313, in <module>
    main(sys.argv[1:])
  File "/var/lib/postgresql/backup/bin/backup.py", line 300, in main
    initiate_backup()
  File "/var/lib/postgresql/backup/bin/backup.py", line 155, in initiate_backup
    state.cursor.execute(START_BACKUP_SQL, {'label': state.label})
psycopg2.errors.UndefinedFunction: function pg_start_backup(unknown, boolean, boolean) does not exist
LINE 1: SELECT pg_start_backup('20240216T184527Z', false, false)
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

because the pg_start_backup() function was removed in the PostgreSQL 15 release.

hexylena commented 6 months ago

https://www.postgresql.org/docs/15/release-15.html

Remove long-deprecated exclusive backup mode (David Steele, Nathan Bossart)

If the database server stops abruptly while in this mode, the server could fail to start. The non-exclusive backup mode is considered superior for all purposes. Functions pg_start_backup()/pg_stop_backup() have been renamed to pg_backup_start()/pg_backup_stop(), and the functions pg_backup_start_time() and pg_is_in_backup() have been removed.

looks like a simple name swap at least.

hlovdal commented 2 months ago

This seems to have been fixed in commit 9f8f86c157 (Support PITR backups on PostgreSQL 15+) made on 2024-04-19 which adds an explicit version check to decide which function to call:

def initiate_backup():
    log.info("Initiating backup with pg_start_backup()")
    if state.pg_major_version < 15:
        start_backup_sql = "SELECT pg_start_backup(%(label)s, false, false)"
    else:
        start_backup_sql = "SELECT pg_backup_start(%(label)s, false)"
    state.cursor.execute(start_backup_sql, {'label': state.label})

and similarly to finalize_backup.