PostgreSQL - Folyamatos archiválás

A RoolWikiBÓL

(Változatok közti eltérés)
2007. október 15., 10:23 változat (szerkesztés)
212.40.118.115 (Vita)
(Az archiválás leállítása)
← Előző változtatások
Aktuális változat (2008. április 1., 14:27) (szerkesztés) (undo)
Rozsahegyil (Vita | szerkesztései)
A (Az archiválás leállítása)
 
(13 intermediate revisions not shown.)
1. sor: 1. sor:
Ez a folyamatos archiválás teszt és dokumentáció a [http://www.postgresql.org/docs/8.2/interactive/continuous-archiving.html 23.3. Continuous Archiving and Point-In-Time Recovery (PITR)] és a [http://developer.postgresql.org/pgdocs/postgres/warm-standby.html] postgresql dokumentáció alapján készült. Ez a folyamatos archiválás teszt és dokumentáció a [http://www.postgresql.org/docs/8.2/interactive/continuous-archiving.html 23.3. Continuous Archiving and Point-In-Time Recovery (PITR)] és a [http://developer.postgresql.org/pgdocs/postgres/warm-standby.html] postgresql dokumentáció alapján készült.
-A cél egy másik számítógépre duplikálni a fő adatbázist, úgy hogy folyamatosan - a lehető leginkább - naprakész legyen. +A cél egy másik számítógépre duplikálni a fő adatbázist úgy, hogy folyamatosan - a lehető leginkább - naprakész legyen.
Ha a fő rendszer bármilyen hiba miatt működésképtelenné válik, akkor ez a biztonsági léphet a helyébe. Ha a fő rendszer bármilyen hiba miatt működésképtelenné válik, akkor ez a biztonsági léphet a helyébe.
A biztonsági adatbázis nem hozzáférhető ebben az üzemmódban. A használatba állításához le kell állítani a folytonos mentés funkcióját. A biztonsági adatbázis nem hozzáférhető ebben az üzemmódban. A használatba állításához le kell állítani a folytonos mentés funkcióját.
19. sor: 19. sor:
(egy sorba kell írni a parancsot!) (egy sorba kell írni a parancsot!)
-Elő lehet írni, hogy ha egy megadott időn belül nem készül wal log fájl, akkor készítse el:+Elő lehet írni, hogy ha egy megadott időn belül nem készül wal log fájl (mert nem történt elegendő változás), akkor készítse el:
archive_timeout = 1h archive_timeout = 1h
39. sor: 39. sor:
* Fájlrendszer szintű mentést kell készíteni * Fájlrendszer szintű mentést kell készíteni
- tar cjf data_wal_start.tbz2 data+ tar cjf data.backup.tbz2 data
* backup mód vége * backup mód vége
50. sor: 50. sor:
* PostgreSQL telepítése a backup gépre. (Ugyanaz a verzió legyen mint a forrás rendszeren!) * PostgreSQL telepítése a backup gépre. (Ugyanaz a verzió legyen mint a forrás rendszeren!)
-* A data_wal_start.tbz2 kicsomagolása+* A data.backup.tbz2 kicsomagolása
-** Töröljük a pg_log, pg_xlog tartalmát+** Töröljük a data/pg_log, data/pg_xlog és data/pg_xlog/archive_status mappákból a fájlokat
-** Töröljük a serverlog, postgresql.pid fájlt!+** Töröljük a data/serverlog, data/postgresql.pid fájlt!
** Szerkesszük át a postgresql.conf fáljt: ne legyen bekapcsolva a wal archiválás! ** Szerkesszük át a postgresql.conf fáljt: ne legyen bekapcsolva a wal archiválás!
- archive_command = <két egymást követő aposztróf>+ archive_command = &#39;&#39;
archive_timeout = 0 archive_timeout = 0
63. sor: 63. sor:
* Indítsuk el a szervert! * Indítsuk el a szervert!
-Ekkor nem lesz folytonos a mentés. Induláskor amíg talál wal szegmenst, addig azokat betölti, de ezután leáll a visszaállító mód. Ezután hiába jönnek létre a fő szerveren wal szegmensek, azok nem kerülnek át a biztonsági szerverre. A "restore commnad" minden wal szegmensre ki lesz adva, ha az nincs a pg_xlog mappában. Ha egy olyan parancsot írunk ide (lehet egy szkript is), ami addig vár, amíg elérhető nem lesz a következő szegmens, majd végrehajtja a másolást, akkor elérhető a folyamatos mentés. Ezzel magyarázható az is, hogy a biztonsági adatbázis nem használható lekérdezésre.+<small>Az archiv fájl kicsomagolását és a törléseket nálunk egy szkript elvégzi:
-=== A folytonos archiválást biztosító program ===+ [ -d /uhu/pgsql8.2.3/data ] && echo Először törölni kell a data mappát! && exit 1
- + echo Új data létrehozása.
- #!/bin/bash+ cd /uhu/pgsql8.2.3
<br> <br>
- SOURCE=$1+ DATABACKUP=data.backup.tbz2
- TARGET=$2+
- OK=0+
- LOGFILE=masol.txt+
<br> <br>
- SIZE_EXPECTED=16777216 #bytes 16 MB+ [ ! -f $DATABACKUP ] && echo Nem létezik a $DATABACKUP fájl. && exit 2
 + tar xjf $DATABACKUP
<br> <br>
- echo >> $LOGFILE+ echo Új data inicializálása.
- echo $SOURCE >> $LOGFILE+ cd ./data
- COUNTER=0+
- WRONG_SIZE_COUNTER=0+
<br> <br>
- if [ $SOURCE == "00000001.history" ]+ rm postmaster.pid
- then+ rm -r pg_log/*
- exit 1+ rm pg_xlog/0*
- fi+ rm -r pg_xlog/safe
 + rm pg_xlog/archive_status/*
<br> <br>
- while [ 1 ]+ cp ../postgresql.conf .
- do+ cp ../recovery.conf .
- echo `date` Copy $SOURCE to $TARGET >> $LOGFILE+ cp ../000* pg_xlog/
- scp 192.168.1.13:/home/postgres/wal_ahead_log_8.2.3/$SOURCE $TARGET+
- RET=$?+
- echo Copy returns $RET >> $LOGFILE+
- if [ "$RET" -ne "0" ]+
- then+
- ((COUNTER++))+
- echo $COUNTER. returns $RET >> $LOGFILE+
- if [ $COUNTER -gt 10 ]+
- then+
- exit 1+
- fi+
- echo sleep 10 minutes >> $LOGFILE+
- sleep 10m+
- else+
- if [ -f $TARGET ]+
- then+
- TARGET_SIZE=$(stat -c '%s' ${TARGET})+
- else+
- TARGET_SIZE=-1+
- fi+
- echo target size is $TARGET_SIZE >> $LOGFILE+
- if [ $TARGET_SIZE -eq $SIZE_EXPECTED ]+
- then+
- echo done. >> $LOGFILE+
- exit 0+
- else+
- ((WRONG_SIZE_COUNTER++))+
- echo $WRONG_SIZE_COUNTER. wrong size: $TARGET_SIZE >> $LOGFILE+
- if [ $WRONG_SIZE_COUNTER -gt 1 ]+
- then+
- exit 0+
- fi+
- echo sleep 1 minute >> $LOGFILE+
- sleep 1m+
- fi+
- fi+
- done+
<br> <br>
- echo "HIBA" >> $LOGFILE+ echo Új data kész.
 + exit 0
 + 
 +</small>
 + 
 +Ekkor nem lesz folytonos a mentés. Induláskor amíg talál wal szegmenst, addig azokat betölti, de ezután leáll a visszaállító mód. Ezután hiába jönnek létre a fő szerveren wal szegmensek, azok nem kerülnek át a biztonsági szerverre. A "restore commnad" minden wal szegmensre ki lesz adva, ha az nincs a pg_xlog mappában. Ha egy olyan parancsot írunk ide (lehet egy szkript is), ami addig vár, amíg elérhető nem lesz a következő szegmens, majd végrehajtja a másolást, akkor elérhető a folyamatos mentés. Ezzel magyarázható az is, hogy a biztonsági adatbázis nem használható lekérdezésre.
 + 
 +=== A folytonos archiválást biztosító program ===
 + 
 +A recovery.conf tartalma ekkor a következő lesz:
 + 
 + restore_command = '/uhu/pgsql8.2.3/bin/get_wal.sh %f %p'
 + 
 +A get_wal.sh program:
 + 
 + #!/bin/bash
 + 
 + #exit 100
 + 
 + SOURCE=$1
 + TARGET=$2
 + OK=0
 + LOGFILE=masol.txt
 + WAL_DIR=/uhu/pgsql8.2.3/wal
 + WAL_FILE=$WAL_DIR/$SOURCE
 + SOURCE_PATH=192.168.1.13:/home/postgres/wal_ahead_log_8.2.3
 + SIZE_EXPECTED=16777216 #bytes 16 MB
 + 
 + echo >> $LOGFILE
 + echo $SOURCE >> $LOGFILE
 + COUNTER=0
 + WRONG_SIZE_COUNTER=0
 + 
 + if [ $SOURCE == "00000001.history" ]
 + then
 + exit 1
 + fi
 + 
 + while [ 1 ]
 + do
 + echo `date` Copy $SOURCE_PATH/$SOURCE to $WAL_FILE >> $LOGFILE
 + scp $SOURCE_PATH/$SOURCE $WAL_FILE 2>&1 >> $LOGFILE
 + RET=$?
 + echo Copy returns $RET >> $LOGFILE
 + if [ "$RET" -ne "0" ]
 + then
 + ((COUNTER++))
 + echo $COUNTER. returns $RET >> $LOGFILE
 + if [ $COUNTER -gt 10 ]
 + then
 + exit 1
 + fi
 + echo sleep 10 minutes >> $LOGFILE
 + sleep 10m
 + else
 + TARGET_SIZE=-1
 + [ -f $WAL_FILE ] && TARGET_SIZE=$(stat -c '%s' ${WAL_FILE})
 + echo target size is $TARGET_SIZE >> $LOGFILE
 + if [ $TARGET_SIZE -eq $SIZE_EXPECTED ]
 + then
 + echo file is ok. >> $LOGFILE
 + echo rm last before wal >> $LOGFILE && rm -f $WAL_DIR/last/* && echo [ok] >> $LOGFILE
 + 
 + echo copy $WAL_FILE to $TARGET >> $LOGFILE && cp $WAL_FILE $TARGET && echo [ok] >> $LOGFILE
 + 
 + echo copy $WAL_FILE to $WAL_DIR/last/$SOURCE >> $LOGFILE && mv $WAL_FILE $WAL_DIR/last/$SOURCE && echo [ok] >> $LOGFILE
 + 
 + echo safe copy done. >> $LOGFILE
 + exit 0
 + else
 + ((WRONG_SIZE_COUNTER++))
 + echo $WRONG_SIZE_COUNTER. wrong size: $TARGET_SIZE >> $LOGFILE
 + if [ $WRONG_SIZE_COUNTER -gt 1 ]
 + then
 + exit 0
 + fi
 + echo "sleep 1 minute (wrong size)" >> $LOGFILE
 + sleep 1m
 + fi
 + fi
 + done
 + 
 + echo "OK" >> $LOGFILE
=== Az archiválás leállítása === === Az archiválás leállítása ===
-* Szabványos módon leállítjuk a PostgreSQL adatbázis szervert.+* Szabványos módon (szabályosan) leállítjuk a PostgreSQL adatbázis szervert.
/etc/init.d/postgresql8.2.3 stop /etc/init.d/postgresql8.2.3 stop
-* Kicseréljük az visszaállító parancsot (restore_command), hogy ne várjon a következő archive log elkészültére, de ha létezik a kért fájl, akkor azt másolja a megadott helyre.+* Kicseréljük a visszaállító parancsot (restore_command), hogy ne várjon a következő archive log elkészültére, de ha létezik a kért fájl, akkor azt másolja a megadott helyre.
- scp 192.168.1.13:/home/postgres/wal_ahead_log_8.2.3/$SOURCE $TARGET+ scp 192.168.1.13:/home/postgres/wal_ahead_log_8.2.3/%f %p
* újraindítjuk a PostgreSQL adatbázis szervert. * újraindítjuk a PostgreSQL adatbázis szervert.
/etc/init.d/postgresql8.2.3 start /etc/init.d/postgresql8.2.3 start
- 
Az utolsó - a leállítás előtt sikeresen betöltött - archive logot fogja még kérni a szerver, majd - ha időközben több nem jött létre - befejezi a visszaállító módot (database system is ready). Az utolsó - a leállítás előtt sikeresen betöltött - archive logot fogja még kérni a szerver, majd - ha időközben több nem jött létre - befejezi a visszaállító módot (database system is ready).
 +
 +=== A biztonsági szerver élesítése, ha a fő szerver elromlik ===
 +
 +* Egyik lehetőség, hogy kivárjuk azt az időt, amíg a "if [ $COUNTER -gt 10 ]" parancs miatt az archiválás leáll, majd használhatjuk a szervert. A fenti szkriptben 10-szer próbáljuk a másolást, 10 perces szünetekkel, így maximum 100 percet kell várni. Ez az idő csökkenthető az ismétlés számának és/vagy a várakozási időnek a csökkentésével. Arra kell figyelni, hogy biztosított legyen a wal szegmens elkészülte a maximális várakozási időn belül, ami az ismétlés*várakozás. Ha ez nincs így, akkor előfordulhat az archiválás leállása a főszerver szabályos működése közben is. Ezért legyen az archive_timeout&nbsp;<&nbsp;(ismétlés-1)&nbsp;*&nbsp;várakozás.
 +
 +* Ha sürgősen kell, akkor
 +** szabályosan leállítjuk a PostgreSQL adatbázis szervert.
 +** az utolsó wal szegmenst bemásoljuk a pg_xlog mappába (a restore command biztosítja ennek a fáljnak a meglétét)
 + cp /uhu/pgsql8.2.3/wal/last/* /uhu/pgsql8.2.3/data/pg_xlog
 +** kitöröljük a recovery.conf fájlt
 +** újraindítjuk a PostgreSQL adatbázis szervert.
 +
 +Fontos, hogy a mentést végző adatbázis szerver egynél többször ne legyen leállítva úgy, hogy nem érhető el számára a kért wal szegmens, mert az adatvesztéshez vezethet. (Ezt a logfájljában jelzi ilyen esetben.)

Aktuális változat

Ez a folyamatos archiválás teszt és dokumentáció a 23.3. Continuous Archiving and Point-In-Time Recovery (PITR) és a [1] postgresql dokumentáció alapján készült.

A cél egy másik számítógépre duplikálni a fő adatbázist úgy, hogy folyamatosan - a lehető leginkább - naprakész legyen. Ha a fő rendszer bármilyen hiba miatt működésképtelenné válik, akkor ez a biztonsági léphet a helyébe. A biztonsági adatbázis nem hozzáférhető ebben az üzemmódban. A használatba állításához le kell állítani a folytonos mentés funkcióját.


Tartalomjegyzék

Engedélyezzük a WAL log archiválást

A postgresql.conf fájlban az archive_command változónak kell értéket adni. pl:

archive_command = '
  echo %f >> /home/postgres/wal_ahead_log_8.2.3/date 
  && date >> /home/postgres/wal_ahead_log_8.2.3/date 
  && test ! -f /home/postgres/wal_ahead_log_8.2.3/%f 
  && echo copy >> /home/postgres/wal_ahead_log_8.2.3/date 
  && cp %p /home/postgres/wal_ahead_log_8.2.3/%f
'

(egy sorba kell írni a parancsot!) Elő lehet írni, hogy ha egy megadott időn belül nem készül wal log fájl (mert nem történt elegendő változás), akkor készítse el:

archive_timeout = 1h

A wal_ahead_log_8.2.3 mappában összegyűlt fájlokat majd egy másik hoszton működő szerver fogja magához másolni, amikor szüksége van rá. Ezt az scp paranccsal teszi. Mivel a másolás a háttérben történik, be kell állítani, hogy az scp ne kérjen jelszót.

Újra kell olvastatni a postgresql-el a konfigurációs fájlokat.

/etc/init.d/postgresql8.2.3 reload

Készíteni kell egy alap mentést

  • Működjön a wal logok archiválása!
  • Be kell lépni a backup módba.
select pg_start_backup('label');
  • Fájlrendszer szintű mentést kell készíteni
 tar cjf data.backup.tbz2 data
  • backup mód vége
 select pg_stop_backup();

Befejezi a backup módot. Kiírja az utolsó wal szegmens számát. Eddig felhasználva a wal szegmenseket (azaz log fájlokat) a stop backuppal azonos állapotú adatbázis jön majd létre.

Létrehozzuk a backup adatbázist

  • PostgreSQL telepítése a backup gépre. (Ugyanaz a verzió legyen mint a forrás rendszeren!)
  • A data.backup.tbz2 kicsomagolása
    • Töröljük a data/pg_log, data/pg_xlog és data/pg_xlog/archive_status mappákból a fájlokat
    • Töröljük a data/serverlog, data/postgresql.pid fájlt!
    • Szerkesszük át a postgresql.conf fáljt: ne legyen bekapcsolva a wal archiválás!
archive_command = ''
archive_timeout = 0
  • A data mappában létre kell hozni egy recovery.conf állományt. Ez tartalmazza a rendszer visszaállítást vezérlő paramétereket. Nekünk most a következő kell:
restore_command = 'scp 192.168.1.13:/home/postgres/wal_ahead_log_8.2.3/%f %p'
  • Indítsuk el a szervert!

Az archiv fájl kicsomagolását és a törléseket nálunk egy szkript elvégzi:

[ -d /uhu/pgsql8.2.3/data ] && echo Először törölni kell a data mappát! && exit 1
echo Új data létrehozása.
cd /uhu/pgsql8.2.3

DATABACKUP=data.backup.tbz2
[ ! -f $DATABACKUP ] && echo Nem létezik a $DATABACKUP fájl. && exit 2 tar xjf $DATABACKUP
echo Új data inicializálása. cd ./data
rm postmaster.pid rm -r pg_log/* rm pg_xlog/0* rm -r pg_xlog/safe rm pg_xlog/archive_status/*
cp ../postgresql.conf . cp ../recovery.conf . cp ../000* pg_xlog/
echo Új data kész. exit 0

Ekkor nem lesz folytonos a mentés. Induláskor amíg talál wal szegmenst, addig azokat betölti, de ezután leáll a visszaállító mód. Ezután hiába jönnek létre a fő szerveren wal szegmensek, azok nem kerülnek át a biztonsági szerverre. A "restore commnad" minden wal szegmensre ki lesz adva, ha az nincs a pg_xlog mappában. Ha egy olyan parancsot írunk ide (lehet egy szkript is), ami addig vár, amíg elérhető nem lesz a következő szegmens, majd végrehajtja a másolást, akkor elérhető a folyamatos mentés. Ezzel magyarázható az is, hogy a biztonsági adatbázis nem használható lekérdezésre.

A folytonos archiválást biztosító program

A recovery.conf tartalma ekkor a következő lesz:

 restore_command = '/uhu/pgsql8.2.3/bin/get_wal.sh %f %p'

A get_wal.sh program:

 #!/bin/bash
 #exit 100
 SOURCE=$1
 TARGET=$2
 OK=0
 LOGFILE=masol.txt
 WAL_DIR=/uhu/pgsql8.2.3/wal
 WAL_FILE=$WAL_DIR/$SOURCE
 SOURCE_PATH=192.168.1.13:/home/postgres/wal_ahead_log_8.2.3
 SIZE_EXPECTED=16777216 #bytes     16 MB
 echo >> $LOGFILE
 echo $SOURCE >> $LOGFILE
 COUNTER=0
 WRONG_SIZE_COUNTER=0
 if [ $SOURCE == "00000001.history" ]
 then
   exit 1
 fi
 while [ 1 ]
 do
   echo `date` Copy $SOURCE_PATH/$SOURCE to $WAL_FILE >> $LOGFILE
   scp $SOURCE_PATH/$SOURCE $WAL_FILE 2>&1 >> $LOGFILE
   RET=$?
   echo Copy returns $RET >> $LOGFILE
   if [ "$RET" -ne "0" ] 
   then
     ((COUNTER++))
     echo $COUNTER. returns $RET >> $LOGFILE
     if [ $COUNTER -gt 10 ]
     then
       exit 1
     fi
     echo sleep 10 minutes >> $LOGFILE
     sleep 10m
   else
     TARGET_SIZE=-1 
     [ -f $WAL_FILE ] && TARGET_SIZE=$(stat -c '%s' ${WAL_FILE}) 
     echo target size is $TARGET_SIZE >> $LOGFILE
     if [ $TARGET_SIZE -eq $SIZE_EXPECTED ]
     then
       echo file is ok. >> $LOGFILE
       echo rm last before wal >> $LOGFILE && rm -f $WAL_DIR/last/* && echo [ok] >> $LOGFILE
       echo copy $WAL_FILE to $TARGET >> $LOGFILE && cp $WAL_FILE $TARGET && echo [ok] >> $LOGFILE
       echo copy $WAL_FILE to $WAL_DIR/last/$SOURCE >> $LOGFILE && mv $WAL_FILE $WAL_DIR/last/$SOURCE && echo [ok] >> $LOGFILE
       echo safe copy done. >> $LOGFILE
       exit 0
     else
       ((WRONG_SIZE_COUNTER++))
       echo $WRONG_SIZE_COUNTER. wrong size: $TARGET_SIZE >> $LOGFILE
       if [ $WRONG_SIZE_COUNTER -gt 1 ]
       then
         exit 0
       fi
       echo "sleep 1 minute (wrong size)" >> $LOGFILE
       sleep 1m
     fi
   fi
 done
 echo "OK"  >> $LOGFILE

Az archiválás leállítása

  • Szabványos módon (szabályosan) leállítjuk a PostgreSQL adatbázis szervert.
/etc/init.d/postgresql8.2.3 stop
  • Kicseréljük a visszaállító parancsot (restore_command), hogy ne várjon a következő archive log elkészültére, de ha létezik a kért fájl, akkor azt másolja a megadott helyre.
 scp 192.168.1.13:/home/postgres/wal_ahead_log_8.2.3/%f %p
  • újraindítjuk a PostgreSQL adatbázis szervert.
/etc/init.d/postgresql8.2.3 start

Az utolsó - a leállítás előtt sikeresen betöltött - archive logot fogja még kérni a szerver, majd - ha időközben több nem jött létre - befejezi a visszaállító módot (database system is ready).

A biztonsági szerver élesítése, ha a fő szerver elromlik

  • Egyik lehetőség, hogy kivárjuk azt az időt, amíg a "if [ $COUNTER -gt 10 ]" parancs miatt az archiválás leáll, majd használhatjuk a szervert. A fenti szkriptben 10-szer próbáljuk a másolást, 10 perces szünetekkel, így maximum 100 percet kell várni. Ez az idő csökkenthető az ismétlés számának és/vagy a várakozási időnek a csökkentésével. Arra kell figyelni, hogy biztosított legyen a wal szegmens elkészülte a maximális várakozási időn belül, ami az ismétlés*várakozás. Ha ez nincs így, akkor előfordulhat az archiválás leállása a főszerver szabályos működése közben is. Ezért legyen az archive_timeout < (ismétlés-1) * várakozás.
  • Ha sürgősen kell, akkor
    • szabályosan leállítjuk a PostgreSQL adatbázis szervert.
    • az utolsó wal szegmenst bemásoljuk a pg_xlog mappába (a restore command biztosítja ennek a fáljnak a meglétét)
 cp /uhu/pgsql8.2.3/wal/last/* /uhu/pgsql8.2.3/data/pg_xlog
    • kitöröljük a recovery.conf fájlt
    • újraindítjuk a PostgreSQL adatbázis szervert.

Fontos, hogy a mentést végző adatbázis szerver egynél többször ne legyen leállítva úgy, hogy nem érhető el számára a kért wal szegmens, mert az adatvesztéshez vezethet. (Ezt a logfájljában jelzi ilyen esetben.)

Személyes eszközök