Pgbackrest kasutamine

Allikas: Imre kasutab arvutit
Mine navigeerimisribaleMine otsikasti

Sissejuhatus

pgbackrest https://github.com/pgbackrest/pgbackrest on C keeles Crunchy Data https://www.crunchydata.com/ poolt arendatud PostgreSQL andmebaasi varundamise tarkvara.

Misc

  • kas pgbackrest abil saab korraldada, et kasutajad saavad ise oma andmeid taastada (nt iga varundatava süsteemi pgbackrest protsess käivitatakse eraldi kasutajaga)
  • varunduse arvutis saab varundustest seise käivitada docker konteinerites (kasutades varundusele vastavat postgresql tarkvara versiooni ja extensionite jms koosseisu)

Tööpõhimõte

pgbackrest saab üldiselt kasutada kahes režiimis
  • lokaalselt - pgbackrest moodustab repo samasse arvutisse kus asuvad varundatavad andmed
  • kaugelt - pgbackrest repo ja varundatav arvuti on erinevad arvutid

Käesolev tekst tegeleb üle võrgu st kaugelt varundamise ja taastega.

     tf-vm-84                 tf-vm-86            tf-vm-87
      _______                  _______             _______
     |       |                |       |           |       |
     |       |                |       |           |       |
     |_______|                |_______|           |_______|
         |                        |                   |
         |                        |                   |
         |                        |                   |
   ------|-------------|----------|-------------------|
                       |
                       |
                    ___|___
                   |       | /var/lib/pgbackrest
                   |       |
                   |_______|

                    tf-vm-85

kus

  • arvutid saavad omavahel suhelda ssh võtmete abil moodustatud usalduse abil

Süsteemide ettevalmistamine

TODO

  • Andmebaas peab muu hulgas olema lähtestatud data-checksums toega, nt
# pg_createcluster --locale et_EE.UTF-8 10 main -- --data-checksums
  • Baasi seadistustes peab olema muu hulgas
root@tf-vm-84:~# grep archive_ /etc/postgresql/10/main/postgresql.conf 
archive_mode = on
archive_command = 'pgbackrest --stanza=db-tf-vm-84 archive-push %p'
  • ssh võtmete genereerimine ja laialijaotamine (varunduse arvutis on vajalik teha vaid üks kord)
varundatav-arvuti$ ssh-keygen
varunduse-arvuti$ ssh-keygen

Paigaldamine

Paigaldamiseks sobib kasutada apt.postgresql.org repot ja öelda nii varundamise kui varundatavas arvutis

# apt-get install curl ca-certificates gnupg2
# curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -

# cat /etc/apt/sources.list.d/pgdg.list
deb http://apt.postgresql.org/pub/repos/apt buster-pgdg main

# apt-get update
# apt-get install pgbackrest

Tulemusena paigaldatakse süsteemi lisaks sõltuvustena nt paketid

libgdbm-compat4 libgdbm6 libperl5.28 libpq5 perl perl-modules-5.28 pgbackrest pgdg-keyring postgresql-client-common postgresql-common ssl-cert

ja pgbackrest, mis sisaldab mõnda faili

/usr/bin/pgbackrest - programm
/etc/pgbackrest.conf - peamine seadistusfail

Eraldi kasutajat ei moodustata, tundub, et kõige sobilikum on tegutseda postgres kasutajana.

Varundamise seadistamine

Repo arvutis tuleb moodustada nt seadistusfail /etc/pgbackrest.conf

# cat /etc/pgbackrest.conf
[global]
repo-path=/var/lib/pgbackrest
repo1-retention-full=1
process-max=2
log-level-console=info
log-level-file=debug
start-fast=y
stop-auto=y

[db-primary]
pg1-path=/var/lib/postgresql/10/main
pg1-host=tf-vm-84
pg1-host-user=postgres

ja varundatavas arvutis seadistusfail /etc/pgbackrest.conf

# cat /etc/pgbackrest.conf
[global]
repo1-host=tf-vm-85
repo1-path=/var/lib/pgbackrest
repo1-host-user=postgres
process-max=2
log-level-console=info
log-level-file=debug

[db-primary]
pg1-path=/var/lib/postgresql/10/main

Varundamine

Varundamiseks sobib repo arvutis öelda nt

$ pgbackrest --stanza=db-tf-vm-84 stanza-create
$ pgbackrest --stanza=db-primary backup
$ pgbackrest --stanza=db-primary --type=full backup
$ pgbackrest --stanza=db-primary info

Taaste

Taastamiseks sobib varundatavas arvutis öelda nt (või ilma --delta suvandita)

$ pgbackrest --stanza=db-primary --delta restore

Varundusest eemaldamine

TODO

$ pgbackrest --stanza=db-primary stop
$ pgbackrest --stanza=db-primary stanza-delete --force

Vanade varunduste eemaldamine

Tavaliselt toimub see järgmise varunduse käigus automaatselt, aga seda saab ka käsitsi esile kutsuda, nt

  • pgbackrest töötamise põhimõttest tingituna ei saa vahepealseid varundusi eemaldada, saab eemalda suuremal või vähemal määral järjestikulist vanemat otsa
  • veenduda, et regulaarne varundamine on välja lülitatud ajutiselt (nt cron töö)
  • vähendada pgbackrest.conf seadistusfailis retention suurust sobivaks (nii, et tabatakse sobivat hulka vanu varundusi)
  • kustutada mida tabataks
$ pgbackrest --config /etc/pgbackrest.conf --stanza=pgcluster_13_main_toodang --dry-run expire
$ pgbackrest --config /etc/pgbackrest.conf --stanza=pgcluster_13_main_toodang expire
  • seadistada tagasi retention sobiv suurus

Integreerimine muu varundusega

Kui üldiselt on kasutuses nt Data Protector tarkvara, siis võiks korraldada kahe tasemelise varundamise

  • pgbackrest varundab varunduse arvuti failisüsteemi HP DP mõttes 1st stage varunduse
  • data protector kirjutab 1st stage varundust failisüsteemist 2nd stage varunduseks linti

Kasulikud lisamaterjalid

Timeline

PostgreSQL timeline on varundamisega tegelemisel väga oluline kontseptsioon

  • üks postgresql andmebaas st teenus ning temaga tegelev pgbackrest varundus viibivad ühel ajahetkel nö ühes ja samas kohas, st nad toimetavad kooskõlaliselt
  • kui mingeid nö segajaid ei ole (nt äsja ei ole taastatud andmebaasi varundusest), siis postgresqli baasi ja tema pgbackrest varundus nö kulgevad ühtlaselt ajas edasi
  • postgresqli baasil ja pgbackrest varundusel on võimekus hallata erinevaid kombinatsioone töötavast baasist ja tema varundusest
  • wal logi kuulub alati mingi ja ainult ühe timeline juurde
  • ühe absoluutse ajahetke taasteni ühest konkreetselt full varundusest viib ainult üks tee mööda timeline'isid (ja seotud wal failisid)

Näide töötava baasi ja varunduse nö kombinatsioonidest

  • alguses käivitati baas ja temast tehti esimene varundus - öeldakse, et süsteem toimib 'timeline 1' peal
  • baasi kasutatakse - hakatakse andmeid sisestama ja varundusse kopeeritakse järjest uusi timeline-1 seotud wal faile
  • seejärel baas taastati varundusest - öeldakse, et süsteem toimib 'timeline 2' peal
  • seejärel taastatud baas varundati - varunduses on nüüd timeline-1 ja timeline-2 variatsioonid full backupid + neile vastavad wal failid
  • seejärel baas taastati varundusest üsna käivitamise järgse puhta seisuga - öeldakse, et süsteem toimib 'timeline 3' peal
  • baas töötab ja wal logid liiguvad pgbackrest varundusse, aga nende wal logide juures on märge timeline-3 peale kuulumise kohta
  • ja taastatud baasi varundatakse - varunduses on nüüd kokku timeline-1, timeline-2 ja timeline-3 variatsioonid + vastavad wal failide komplektid

Kui sellisesse olekusse saabunud baasi taastada viimasele varundusele eelnevale ajahetkele, siis

  • taasteks on ainumõeldav kasutada timeline-1 varundusest alates, ja ühel hetkel liigub wal logide kasutamine timeline-3 peale - timeline-2 osakond jääb üldse vahele kuna ta ei puutu asjasse (timeline-3 seisukohast on tegu kõrvalharuga)
  • peale taastet toimetatakse timeline-4 peal

Käesoleva timeline väärtuse küsimine, vastus on '3'

postgres=# select pg_walfile_name(pg_current_wal_lsn());
     pg_walfile_name
--------------------------
 00000003000000000000006B
(1 row)

Milliseid wal logisid taastes kasutati

# grep "pg_wal/RECOVERYXLOG" /var/log/postgresql/postgresql-16-main.log | sed -r 's/exec-id.*//' | grep 03:1
2025-10-30 03:13:23.407 P00   INFO: archive-get command begin 2.56.0: [00000006000000000000006A, pg_wal/RECOVERYXLOG] --
2025-10-30 03:13:23.545 P00   INFO: archive-get command begin 2.56.0: [00000006000000000000006B, pg_wal/RECOVERYXLOG] --
#

Märkused

  • kui andmebaasist hoitakse erinevatele timeline'idele vastavaid eksemplare, siis vist teoreetiliselt saab neid varundada vastu ühte ja sama pgbackrest varundust (kuna erinevate timeline'ide wal failide kohta hoitakse iseseisvalt järge)

Taastel võib tekkida takistusi timeline soovimatu ületamise tõttu

Oct 30 11:08:48 pg-01.moraal.ee systemd[1]: Starting postgresql@16-main.service - PostgreSQL Cluster 16-main...
Oct 30 11:08:48 pg-01.moraal.ee postgres[477590]: [1-1] 2025-10-30 11:08:48.487 EET [477590] LOG:  ending log output to stderr
Oct 30 11:08:48 pg-01.moraal.ee postgres[477590]: [1-2] 2025-10-30 11:08:48.487 EET [477590] HINT:  Future log output will go to log destination "syslog".
Oct 30 11:08:48 pg-01.moraal.ee postgres[477590]: [2-1] 2025-10-30 11:08:48.489 EET [477590] LOG:  starting PostgreSQL 16.10 (Ubuntu 16.10-1.pgdg24.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0, 64-bit
Oct 30 11:08:48 pg-01.moraal.ee postgres[477590]: [3-1] 2025-10-30 11:08:48.492 EET [477590] LOG:  listening on IPv4 address "0.0.0.0", port 5432
Oct 30 11:08:48 pg-01.moraal.ee postgres[477590]: [4-1] 2025-10-30 11:08:48.494 EET [477590] LOG:  could not create IPv6 socket for address "::": Address family not supported by protocol
Oct 30 11:08:48 pg-01.moraal.ee postgres[477590]: [5-1] 2025-10-30 11:08:48.497 EET [477590] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
Oct 30 11:08:48 pg-01.moraal.ee postgres[477595]: [6-1] 2025-10-30 11:08:48.508 EET [477595] LOG:  database system was interrupted; last known up at 2025-10-30 03:14:35 EET
Oct 30 11:08:48 pg-01.moraal.ee postgres[477595]: [7-1] 2025-10-30 11:08:48.569 EET [477595] LOG:  restored log file "00000008.history" from archive
Oct 30 11:08:48 pg-01.moraal.ee postgres[477595]: [8-1] 2025-10-30 11:08:48.611 EET [477595] LOG:  restored log file "00000009.history" from archive
Oct 30 11:08:48 pg-01.moraal.ee postgres[477595]: [9-1] 2025-10-30 11:08:48.651 EET [477595] LOG:  restored log file "0000000A.history" from archive
Oct 30 11:08:48 pg-01.moraal.ee postgres[477595]: [10-1] 2025-10-30 11:08:48.692 EET [477595] LOG:  restored log file "0000000B.history" from archive
Oct 30 11:08:48 pg-01.moraal.ee postgres[477595]: [11-1] 2025-10-30 11:08:48.733 EET [477595] LOG:  restored log file "0000000C.history" from archive
Oct 30 11:08:48 pg-01.moraal.ee postgres[477595]: [12-1] 2025-10-30 11:08:48.774 EET [477595] LOG:  restored log file "0000000D.history" from archive
Oct 30 11:08:48 pg-01.moraal.ee postgres[477595]: [13-1] 2025-10-30 11:08:48.812 EET [477595] LOG:  starting point-in-time recovery to 2025-10-30 03:14:42+02
Oct 30 11:08:48 pg-01.moraal.ee postgres[477595]: [14-1] 2025-10-30 11:08:48.813 EET [477595] LOG:  starting backup recovery with redo LSN 0/6D000028, checkpoint LSN 0/6D005820, on timeline ID 7
Oct 30 11:08:48 pg-01.moraal.ee postgres[477595]: [15-1] 2025-10-30 11:08:48.853 EET [477595] LOG:  restored log file "0000000D.history" from archive
Oct 30 11:08:49 pg-01.moraal.ee postgres[477595]: [16-1] 2025-10-30 11:08:49.149 EET [477595] LOG:  restored log file "00000007000000000000006D" from archive
Oct 30 11:08:49 pg-01.moraal.ee postgres[477595]: [17-1] 2025-10-30 11:08:49.176 EET [477595] FATAL:  requested timeline 13 is not a child of this server's history
Oct 30 11:08:49 pg-01.moraal.ee postgres[477595]: [17-2] 2025-10-30 11:08:49.176 EET [477595] DETAIL:  Latest checkpoint is at 0/6D005820 on timeline 7, but in the history of the requested timeline, the server forked off from that timeline at 0/6E00DD48.
Oct 30 11:08:49 pg-01.moraal.ee postgres[477590]: [6-1] 2025-10-30 11:08:49.178 EET [477590] LOG:  startup process (PID 477595) exited with exit code 1
Oct 30 11:08:49 pg-01.moraal.ee postgres[477590]: [7-1] 2025-10-30 11:08:49.178 EET [477590] LOG:  aborting startup due to startup process failure
Oct 30 11:08:49 pg-01.moraal.ee postgres[477590]: [8-1] 2025-10-30 11:08:49.179 EET [477590] LOG:  database system is shut down

Lahenduseks on öelda süsteemile, et püsida taastel timeline 7 juures

# cat /var/lib/postgresql/16/main/postgresql.auto.conf | tail -n 4
restore_command = 'pgbackrest --stanza=pg_16 archive-get %f "%p"'
recovery_target_time = '2025-10-30 03:15:38+02:00'
recovery_target_timeline = '7'

kusjuures pgbacrest abil kopeeritud data kataloog on selline, st väga timeline = 7

# /usr/lib/postgresql/16/bin/pg_controldata /var/lib/postgresql/16/main/
pg_control version number:            1300
Catalog version number:               202307071
Database system identifier:           7563298480089063364
Database cluster state:               in production
pg_control last modified:             Thu 30 Oct 2025 03:14:35 AM EET
Latest checkpoint location:           0/DEAD
Latest checkpoint's REDO location:    0/6D000028
Latest checkpoint's REDO WAL file:    00000007000000000000006D
Latest checkpoint's TimeLineID:       7
Latest checkpoint's PrevTimeLineID:   7
Latest checkpoint's full_page_writes: on
Latest checkpoint's NextXID:          0:334825
Latest checkpoint's NextOID:          17028
Latest checkpoint's NextMultiXactId:  1
Latest checkpoint's NextMultiOffset:  0
Latest checkpoint's oldestXID:        722
Latest checkpoint's oldestXID's DB:   1
Latest checkpoint's oldestActiveXID:  334825
Latest checkpoint's oldestMultiXid:   1
Latest checkpoint's oldestMulti's DB: 1
Latest checkpoint's oldestCommitTsXid:0
Latest checkpoint's newestCommitTsXid:0
Time of latest checkpoint:            Thu 30 Oct 2025 03:14:30 AM EET
Fake LSN counter for unlogged rels:   0/3E8
Minimum recovery ending location:     0/0
Min recovery ending loc's timeline:   0
Backup start location:                0/0
Backup end location:                  0/0
End-of-backup record required:        no
wal_level setting:                    replica
wal_log_hints setting:                off
max_connections setting:              200
max_worker_processes setting:         8
max_wal_senders setting:              10
max_prepared_xacts setting:           0
max_locks_per_xact setting:           64
track_commit_timestamp setting:       off
Maximum data alignment:               8
Database block size:                  8192
Blocks per segment of large relation: 131072
WAL block size:                       8192
Bytes per WAL segment:                16777216
Maximum length of identifiers:        64
Maximum columns in an index:          32
Maximum size of a TOAST chunk:        1996
Size of a large-object chunk:         2048
Date/time type storage:               64-bit integers
Float8 argument passing:              by value
Data page checksum version:           0
Mock authentication nonce:            9f8347c70e309d6eac801a5556adc736693a105b0617f3f292292ce566f75819

Minio

# cat /etc/pgbackrest.conf
[global]
repo1-type=s3
repo1-s3-endpoint=s3-by-minio.moraal.ee:9000
repo1-s3-uri-style=path
repo1-s3-region=trt
repo1-path=/path-project-test-pgbackrest-1
repo1-s3-bucket=bucket-division-project-test
repo1-s3-key=key-division-project-test
repo1-s3-key-secret=keysecret-parool

repo1-retention-full=3
repo1-retention-diff=7

process-max=2
log-level-console=info
log-level-file=info

[pg_16]
pg1-path=/var/lib/postgresql/16/main

Käsundamine

# mc alias set pgrepotest https://s3-by-minio.moraal.ee:9000 key-division-project-test keysecret-parool

# mc ls pgrepotest/bucket-division-project-test/path-project-test-pgbackrest-1
[2025-10-30 00:56:02 EET]     0B archive/
[2025-10-30 00:56:02 EET]     0B backup/

# mc cp --recursive pgrepotest/bucket-division-project-test/path-project-test-pgbackrest-1 local-path-project-test-pgbackrest-1

# mc rm --recursive --force pgrepotest/bucket-division-project-test/path-project-test-pgbackrest-1/archive
# mc rm --recursive --force pgrepotest/bucket-division-project-test/path-project-test-pgbackrest-1/backup