Firebird 2.5 - ami mindig hiányzott: stop start backup restore - és a sweep elkerülése


Szakmai szekció


Nehogy bárki azt gondolja, hogy a Windowsban gondolkodók által vallott módon a firebird nem képes Linux alatt teljesen korrekten dolgozni. De képes, csak információ nincs róla. Nem vagyok oda érte, mert sok bajom van vele, el voltam kényeztetve a MySQL-lel, de a partner olyan rendszert vett, amihez ez kell, akkor ezt kell használni.

Ha valaki szeretné leállítani a firebird-öt, akkor szalad a doksihoz és lám: /etc/init.d/firebird stop Hurrá!
Aztán jön a meglepi: ps aux
Jé, még mindig fut, nosza akkor
gfix -user KUKUTYIN -password EzaPassWord /server/firebird/FIREBIRD.FDB -shut -force 10>>/var/log/firebird/backup."$(date +%Y%m%d)".log aminek végeredményben 10 másodperc alatt be kéne zárni az összes futó szálat és lekapcsolni az adatbázist.
Nos, nem teszi.
S ha közben valaki új szálat indít, na az is megy.
Honnan tudom? Onnan, hogy az adatbázisok file-jainak legutolsó módosítási dátuma bizony szépen másodpercenként lép felfelé.
Tehát kissé erőszakosan kell vele bánni. Mivel kipróbáltam tehát nyugodtan lehet használni a következő kis scriptet, természetesen a megfelelő helyeken kéretik átírni:
(Hja és a log is van, tehát a /var/log alatt szükség lesz egy firebird könyvtárra!)


#!/bin/sh

/bin/echo "Firebird stop process start">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "inetd disable gds_db">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/usr/sbin/update-inetd --disable gds_db>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "openbds-inetd restart">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/etc/init.d/openbsd-inetd restart>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "Firebird Databases shutdown">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/usr/bin/gfix -user KUKUTYIN -password EzaPassWord /server/firebird/FIREBIRD.FDB -shut -force 10>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "killall firebird threads">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/usr/bin/killall fb_inet_server
/usr/bin/gfix -user KUKUTYIN -password EzaPassWord /server/firebird/FIREBIRD.FDB -shut -force 10>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/etc/init.d/firebird2.5-classic stop
/bin/echo "sleep 30 second">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/sleep 30
/bin/echo "sleep end">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "query the FIREBIRD.FDB file last modified time, if grater then 25 second, then backup/restore start">>/var/log/firebird/backup."$(date +%Y%m%d)".log
file='/server/firebird/FIREBIRD.FDB'
current=`date +%s`
last_modified=`stat -c "%Y" $file`
if [ $(($current-$last_modified)) -gt 25 ]; then
/bin/echo "the modified time grater then 25 second, firebird stop OK!">>/var/log/firebird/backup."$(date +%Y%m%d)".log
else
/bin/echo "the firebird stop process final, message: Error!">>/var/log/firebird/backup."$(date +%Y%m%d)".log
fi


Fontos tudni, hogy végeredményben a script az inetd konfigurációjában letiltja a 3050-es portot. Tehát kívülről nem lehet elérni a firebird-öt. Ettől függetlenül a szerveren lokálisan fut, tehát egy backup/restore lazán futtatható.

Most nézzük a start-ot!


#!/bin/sh
/bin/echo "Firebird start process start, firebird switch to online">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "inetd enable gds_db">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/usr/sbin/update-inetd --enable gds_db>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "openbds-inetd restart">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/etc/init.d/openbsd-inetd restart>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "Firebird Databases online">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/etc/init.d/firebird2.5-classic start
/usr/bin/gfix -user KUKUTYIN -password EzaPassWord /server/firebird/FIREBIRD.FDB -online>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "Firebird start process final, message: OK!">>/var/log/firebird/backup."$(date +%Y%m%d)".log



Azt kell tudni, hogy erre akkor van szükség, ha a stop scripttel állítottuk le a firebird-öt, mert ugye az inetd működésébe szóltunk bele.

A firebird egyik legnagyobb rákfenéje a sweep. Ez egy olyan program, aminek az a funkciója, hogy működés közben "kitakarítsa" az adatbázist. Nagyobb felhasználói létszámnál, nagyobb adatbázisnál iszonyatosan lelassítja a működést. Azt is hozzáteszem, hogy mindegy milyen szerverről van szó. Egy 6 magos Xeon 12 szállal dolgozó 64 Gbyte memóriával és ssd raid-ekkel rendelkező szerveren is hasznavehetetlenné válik. Pont azért, mert a sweep egy szálon fut és az ssd raid-eket teljesen kihajtja, azaz más már nem is fér hozzá. Hogy ezt ki tervezte nem tudom, de lenne pár javaslatom arra, hogy mivel kéne inkább foglalkoznia.
A sweep elkerülésére a legjobb lehetőség a backup és restore egymás utáni futtatása. A backupból a firebird az adatbázisait újraépíti és az újraépítés során az adatbázis kitisztul, naponta futtatva igen jó eredményt lehet produkálni, a rendszer - tapasztalatom szerint 40 felhasználó 1.5Gb-os adatbázis - jól megy.
A probléma úgy jelentkezik, hogy általában a Windows alatt fejlesztő azzal jön, hogy iszonyatosan lassú a backup/restore process, a fentebb említett esetben 8 óra, nem elírás tényleg nyolc óra. Sőt azt is fogja javasolni, hogy vegyen a felhasználó egy Windows szervert. Szerencsém volt, mert én ekkor hagytam, hogy próbából a partneremnél beállítsanak egy Windows-os szervert. Kísérleteztek vele majd három hétig, aztán valahogy a WIndows szerver erőltetése megszűnt.
Engem viszont nem hagyott nyugodni egy ötlet, ami arról szólt, hogy amennyiben a disk sebesség a gond, akkor próbáljuk meg a backup/restore process-t memóriában megoldani. Igaz, ehhez tényleg kell gép és memória. A script alább olvasható:


#!/bin/sh

/bin/echo "Firebird backup process start">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "create tmpfs on /ramdisk">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/mount -t tmpfs -o size=12G tmpfs /ramdisk>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/mkdir /ramdisk/source>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/mkdir /ramdisk/restore>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/mkdir /ramdisk/backup>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/chmod 0777 /ramdisk/source
/bin/chmod 0777 /ramdisk/restore
/bin/chmod 0777 /ramdisk/backup
/bin/echo "inetd disable gds_db">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/usr/sbin/update-inetd --disable gds_db>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "openbds-inetd restart">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/etc/init.d/openbsd-inetd restart>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "Firebird Databases shutdown">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/usr/bin/gfix -user KUKUTYIN -password EzaPassWord /server/firebird/FIREBIRD.FDB -shut -force 10>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "killall firebird threads">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/usr/bin/killall fb_inet_server
/usr/bin/gfix -user KUKUTYIN -password EzaPassWord /server/firebird/FIREBIRD.FDB -shut -force 10>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/etc/init.d/firebird2.5-classic stop
/bin/echo "sleep 30 second">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/sleep 30
/bin/echo "sleep end">>/var/log/firebird/backup."$(date +%Y%m%d)".log

/bin/echo "query the FIREBIRD.FDB file last modified time, if grater then 25 second, then backup/restore start">>/var/log/firebird/backup."$(date +%Y%m%d)".log

file='/server/firebird/FIREBIRD.FDB'
current=`date +%s`
last_modified=`stat -c "%Y" $file`
if [ $(($current-$last_modified)) -gt 25 ]; then
/bin/echo "the modified time grater then 25 second, firebird backup/restore process start">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "firebird database file attributes modify">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/chmod 0666 /server/firebird/FIREBIRD.FDB
/bin/echo "create directory on /server/firebird_backups">>/var/log/firebird/backup."$(date +%Y%m%d)".log
act_date="$(date +%Y%m%d)"
/bin/mkdir /server/firebird_backups/backup.$act_date.fb
/bin/chmod 0777 /server/firebird_backups/backup.$act_date.fb
/bin/mkdir /server/firebird_backups/backup.$act_date.fb/source
/bin/chmod 0777 /server/firebird_backups/backup.$act_date.fb/source
/bin/mkdir /server/firebird_backups/backup.$act_date.fb/backup
/bin/chmod 0777 /server/firebird_backups/backup.$act_date.fb/backup
/bin/mkdir /server/firebird_backups/backup.$act_date.fb/restore
/bin/chmod 0777 /server/firebird_backups/backup.$act_date.fb/restore
/bin/echo "copy the original .FDB file to /server/firebird_backups/DATE/source directories">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/cp /server/firebird/FIREBIRD.FDB /server/firebird_backups/backup.$act_date.fb/source/FIREBIRD.FDB>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "copy the original .FDB file to /ramdisk/source directory">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/cp /server/firebird/FIREBIRD.FDB /ramdisk/source/FIREBIRD.FDB>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "backup the firebird databases from /ramdisk/source/* to /ramdisk/backup/*">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/usr/bin/gbak -b -user KUKUTYIN -password EzaPassWord /ramdisk/source/FIREBIRD.FDB /ramdisk/backup/FIREBIRD.BAK>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "restore the firebird databases from /ramdisk/backup/* to /ramdisk/restore/*">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/usr/bin/gbak -c -user KUKUTYIN -password EzaPassWord /ramdisk/backup/FIREBIRD.BAK /ramdisk/restore/FIREBIRD.FDB>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "copy the backup .BAK file to /server/firebird_backups/DATE/backup directories">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/cp /ramdisk/backup/FIREBIRD.BAK /server/firebird_backups/backup.$act_date.fb/backup/FIREBIRD.BAK>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "copy the restore .FDB files to /server/firebird_backups/DATE/restore directories">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/cp /ramdisk/restore/FIREBIRD.FDB /server/firebird_backups/backup.$act_date.fb/restore/FIREBIRD.FDB>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "copy the restore .FDB files to /server/firebird directory">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/cp /ramdisk/restore/FIREBIRD.FDB /server/firebird/FIREBIRD.FDB>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "the backup/restore process end, firebird switch back to online">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "inetd enable gds_db">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/usr/sbin/update-inetd --enable gds_db>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "openbds-inetd restart">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/etc/init.d/openbsd-inetd restart>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "Firebird Databases online">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/etc/init.d/firebird2.5-classic start
/usr/bin/gfix -user KUKUTIYN -password EzaPassWord /server/firebird/FIREBIRD.FDB -online>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "umount the /ramdisk">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/umount /ramdisk>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "the backup/restore process final, message: OK!">>/var/log/firebird/backup."$(date +%Y%m%d)".log

else
/bin/echo "the modified time smaller then 25 second, firebird backup/restore process stop, firebird switch back to online">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "inetd enable gds_db">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/usr/sbin/update-inetd --enable gds_db>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "openbds-inetd restart">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/etc/init.d/openbsd-inetd restart>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "Firebird Databases online">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/etc/init.d/firebird2.5-classic start
/usr/bin/gfix -user KUKUTIYN -password EzaPassWord /server/firebird/FIREBIRD.FDB -online>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "umount the /ramdisk">>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/umount /ramdisk>>/var/log/firebird/backup."$(date +%Y%m%d)".log
/bin/echo "the backup/restore process final, message: Error!">>/var/log/firebird/backup."$(date +%Y%m%d)".log

fi


Fontos dolgok!
A scriptet értelemmel kell használni, tehát könyvtárakra odafigyelni.
A script nyers, csak a lényeget mutatja, nincsenek benne védelmek. És, hogy mire is kell figyelni? A firebird gbak és gfix utility ugyan működik, de nem nagyon beszédes, ez azt jelenti, hogy többször előfordult, hogy leakadt és elfelejtett szólni vagy logolni is bármit, hogy ugyan miért. Tehát a forrás mentése ezért fontos, ha véletlenül a gbak nem fut le vagy rosszul teszi, akkor a script visszamásolja a ramdiskből az esetlegesen be nem fejezett restore állományt. Ekkor ugye jön a "összeomlás". Ha előtte valahova még elmentjük, lásd /server/firebird_backup/source akkor van visszaút. Érdemes elmenteni az állományokat más gépre is természetesen.
A beállított ramdisk mérete a scriptben 12G, de a felhozott (1.5Gb adatbázisméret) példában azonban nem indokolt. Hozzávetőlegesen úgy érdemes kalkulálni, hogy a forrásadatbázis méretének kb. a fele a backup és a restore mérete a forrásnál kisebb kb. 10%-kal. A ramdisk méretével ne spóroljunk, mert ha nem elegendő, akkor leakad.
S még valami, ami azért mégiscsak fontos és úgy érzem másnak is majd örömet fog okozni. A script nem 8 óráig fut, hanem kb. 8 percig, igen jól tetszett olvasni 8 perc. Egy processzorszálat fog beterhelni 100%-ra, a disk amíg másol terhelt, de ami kívülről kezdeményezve 8 óra, nos, az itt 8 perc.

Remélem sikerült segítenem pár embernek!