FirebirdSQL: Unterschied zwischen den Versionen

Aus OrgaMon Wiki
Zur Navigation springen Zur Suche springen
 
(201 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
Zur Datenhaltung verwendet OrgaMon den freien Datenbank Server firebird SQL. <br>
Firebird ist ein SQL-Datenbankserver. Firebird is a registered trademark of the Firebird Foundation [[https://firebirdsql.org]]
Zur Datenhaltung verwendet OrgaMon den freien Datenbank Server Firebird-SQL (https://firebirdsql.org/). <br>


== Installation ==
== Installation ==


(für Mehrprozessor-Systeme:) CS- Classic Server unter Linux<br>
Im Moment setze ich immer den SuperServer der Version 3 ein.


  rpm -vv -i Firebird..CS.rpm
=== OpenSuSE 15.1 / 15.2 ===
  chkconfig --add xinetd
  rcxinetd restart


(für Einprozessor-Systeme) SS- Super Server unter Linux<br>
zypper install firebird-server firebird-examples telnet


  rpm -vv -i Firebird..SS.rpm
#
  chkconfig --add firebird
# Sorge für angepasste Einstellungen
  rcfirebird restart
#
mv /etc/firebird/firebird.conf /etc/firebird/_firebird.conf
joe /etc/firebird/firebird.conf


* Sicherheitseinstellungen<br>
==== firebird.conf ====


Zunächst muss dem firebird SQL Server erlaubt werden auf die typischen Dienstbereiche
#
der Platte zuzugreifen: /srv Dort können dann auch verschiedene Volumes eingehängt werden.
# <b>/etc/firebird/firebird.conf</b>
Dazu muss jedoch der schreibende Zugriff erst mal ermöglicht werden:
#
# Einstellungen für erfolgreiches Konnektieren von 2.5 Clients
#
AuthServer = Legacy_Auth
AuthClient = Legacy_Auth
UserManager =  Legacy_UserManager
AllowEncryptedSecurityDatabase = false
WireCrypt = Enabled
WireCompression = false
RemoteAuxPort = 3051
DatabaseAccess = Restrict /srv/firebird


joe /opt/firebird/firebird.conf
DatabaseAccess = Restrict /srv


Bedeutung: dem FirebirdSQL Server ist der Datenbankzugriff nur in /srv und allen weiteren Unterverzeichnissen möglich.
#
# Start the server
#
systemctl enable firebird.service
systemctl start firebird.service
#
# test if server is running
#
telnet localhost 3050
#
# set the SYSDBA Password, MUST replace ***********
#
gsec -user sysdba -password masterkey -modify sysdba -pw ~DeinNeuesPasswortHier~
#
# Alternativ, aber unklar
#
isql-fb employee;
SQL> create or alter user SYSDBA password '***********';
SQL> commit;
SQL> quit;
 
 
==== /etc/crontab ====
 
* damit bei einem freigegebenen Share firebird-Datenbanken löschbar sind
 
#
# Firebird
#
00 10 * * * root chmod -R 777 /srv/firebird
 
==== /etc/samba/smb.conf ====
 
* Nehme die Freigabe des Datenbankverzeichnisses zu deinen Samba-Shares hinzu
* Die Arbeitsstationen müssen keinesfalls dieses Share mit einem Laufwerk verbinden
* OrgaMon wird bei der Datensicherung auf \\host\firebird zugreifen
 
 
...
 
[firebird]
      comment = Firebird
      path = /srv/firebird
      guest ok = yes
      writeable = yes
      create mode = 0777
      directory mode = 0777
      force create mode = 0777
      force directory mode = 0777
 
=== selbst compilieren 3.0.5 ===
 
zypper install libicu-devel libtommath-devel libtomcrypt-devel
wget http://web.firebirdsql.org/download/snapshot_builds/linux/fb3.0/Firebird-3.0.5.33221-0.tar.bz2
bunzip2 Firebird-3.0.5.33221-0.tar.bz2
tar -xf Firebird-3.0.5.33221-0.tar
cd Firebird-3.0.5.33221-0/
./configure
make
make install
 
* firebird.conf ist in /usr/local/firebird
* gbak: /usr/local/firebird/bin/gbak
* service ist: systemctl status firebird-superserver.service
 
 
=== selbst compilieren 3.0.7 ===
 
* gilt analog auch für firebird 3.0.8, 3.0.9,
* gilt nicht für  3.0.10 auf openSUSE 15.4, hier meint er "icu" hätte die falsche Versionsnummer
 
zypper install telnet libicu-devel libtommath-devel libtomcrypt-devel
wget https://github.com/FirebirdSQL/firebird/releases/download/R3_0_7/Firebird-3.0.7.33374-0.tar.bz2
# wget https://github.com/FirebirdSQL/firebird/releases/download/v3.0.10/Firebird-3.0.10.33601-0.tar.bz2
bunzip2 Firebird-3.0.7.33374-0.tar.bz2
tar -xf Firebird-3.0.7.33374-0.tar
cd Firebird-3.0.7.33374-0/
./configure
make
make install
 
* firebird.conf ist in /usr/local/firebird
* gbak: /usr/local/firebird/bin/gbak
* service ist: systemctl status firebird-superserver.service
 
#
# SYSDBA Passwort setzten
#
/usr/local/firebird/bin/gsec -user sysdba -password masterkey -modify sysdba -pw ~DeinNeuesPasswortHier~
 
=== selbst compilieren 3.0.10 ===
 
zypper install telnet libicu-devel libicu69 libtommath-devel libtomcrypt-devel
#wget https://github.com/FirebirdSQL/firebird/releases/download/v3.0.10/Firebird-3.0.10.33601-0.tar.bz2
wget https://github.com/FirebirdSQL/firebird/releases/download/v3.0.11/Firebird-3.0.11.33703-0.amd64.tar.gz
bunzip2 Firebird-___ .tar.bz2
tar -xf Firebird-___.tar
cd Firebird-___/
./configure
make
make install
 
* firebird.conf, databases.conf ist in /usr/local/firebird
* gbak: /usr/local/firebird/bin/gbak
* service ist: systemctl status firebird-superserver.service
 
#
# SYSDBA Passwort setzten
#
/usr/local/firebird/bin/gsec -user sysdba -password masterkey -modify sysdba -pw ~DeinNeuesPasswortHier~
 
=== selbst compilieren 3.0.11 ===
 
* openSUSE 15.5
wget https://github.com/FirebirdSQL/firebird/releases/download/v3.0.11/Firebird-3.0.11.33703-0.tar.bz2
zypper install telnet libicu-devel libicu69 libtommath-devel libtomcrypt-devel
zypper install gcc gcc-c++ make automake ncurses-devel zlib-devel
bunzip2 Firebird-___ .tar.bz2
tar -xf Firebird-___.tar
cd Firebird-___/
./configure
make
make install
* Bei make install soll man ein Passwort eingeben, das ist jedoch sinnlos, das eingegebene Passwort wird nicht verwendet
* Wie immer also:
 
#
# SYSDBA Passwort setzten
#
/usr/local/firebird/bin/gsec -user sysdba -password masterkey -modify sysdba -pw ~DeinNeuesPasswortHier~
 
==== systemd ====
 
* Es gibt scheinbar bestrebungen /var/run/ abzuschaffen, neu ist /run, das müsste auch im firebird geändert werden
 
(15/43) Installing: systemd-246.16-7.21.1.x86_64 .........................................................................................................[done]
Additional rpm output:
/usr/lib/tmpfiles.d/firebird.conf:1: Line references path below legacy directory /var/run/, updating /var/run/firebird → /run/firebird; please update the tmpfiles.d/ drop-in file accordingly.
/usr/lib/tmpfiles.d/net-snmp.conf:1: Line references path below legacy directory /var/run/, updating /var/run/net-snmp → /run/net-snmp; please update the tmpfiles.d/ drop-in file accordingly.
Too few arguments.
 
raib80:/usr/lib/tmpfiles.d # cat firebird.conf
d /var/run/firebird 0775 firebird firebird -
 
=== selbst compilieren 5.0.0 ===
 
zypper install telnet libicu-devel libicu69 libtommath-devel libtomcrypt-devel
zypper install gcc gcc-c++ make automake cmake ncurses-devel zlib-devel
wget https://github.com/FirebirdSQL/firebird/releases/download/v5.0.0/Firebird-5.0.0.1306-0-source.tar.xz
tar -xf Firebird-5.0.0.1306-0-source.tar.xz
 
=== Raspberry Pi / Debian ===


* SYSDBA Passwort<br>
apt install firebird3.0-server firebird3.0-examples telnet


die Zeiten, dass masterkey das Out-off-the-box Passwort für firebird war sind lange vorbei. Vielmehr befindet sich das im Rahmen der Installation frisch erzuegte Passwort des Datenbank Administrator in der Datei
isql-fb security.db


  /opt/firebird/SYSDBA.password
=== rpm direkt von firebirdsql ===


== Shell Befehle ==
## xinetd muss laufen!
chkconfig --add xinetd
rcxinetd start
## Dies installiert firebird und startet es (für immer!)
rpm -i FirebirdCS-2.0.0.12748-0.nptl.i686.rpm
## man muss noch das passwort notieren
 
cat /opt/firebird/SYSDBA.passwd
## man kann noch definieren, wo die firebird Datenbanken liegen dürfen
## auf alle Fälle muss man verhindern, dass von aussen die security.fdb
## geöffnet werden kann.
joe /opt/firebird/firebird.conf
 
DatabaseAccess = Restrict /srv
 
=== rpm direkt vom Buildservice OpenSuse ===
 
ein manuelles Installieren mit rpm -i firebird- usw. war mir nicht möglich, da ich die Referenz auf "firebird-arch" nicht auflösen konnte (grrr.).


netstat --numeric -p | grep fb_inet  // anzeigen aller an firebird connectierten
* Nehme im Yast das Build-Repository hinzu: http://download.opensuse.org/repositories/server:/database/openSUSE_13.1/
                                      // (eigentlich fb_inet_server, jedoch wird der volle Name oft durch
* Suche und Installiere nun den "firebird-classic"
                                      // netstat abgeschnitten)
* Gehe weg vom "default" Passwort für den SYSDBA: gsec -user sysdba -password masterkey -modify sysdba -pw ~DeinNeuesPasswortHier~
ps -A | grep fb                      // anzeigen aller firebird - Prozesse
* das wars ...
lsof <firebirddatenbankdatei>                // anzeigen aller User auf einer firebird Datenbank
lsof -p <PID eines fb_inet_servers>          // anzeigen der Dateien, die der Prozess offen hat
                                              // es wird auch angegeben wer (welcher remote) connectiert ist.


    /opt/interbase/bin/ibmgr -shut -user "SYSDBA" -password "masterkey"
=== OpenSuSE 13.1 ===
    /opt/interbase/bin/ibmgr -start -forever


== Hintergrundinfo ==


Im Moment setze ich auf SMP Systemen den "Classic Server (CS)" ein. Es bedeutet, es läuft kein einzelner Dämmon, sondern pro Verbindung wird ein Server-Prozess neu gestartet (fb_inet_server). Die Synchronisation erfolgt über Datei-Locks der jeweiligen Datenbank-Datei mit Hilfe eines monolitischen Prozesses (fb_lock_mgr). Bei dem Hochstarten der einzelnen Server-Prozesse hilft xinetd (ehemals inetd). Dies ist ein Programm, das dabei Hilft auf einzelnen Ports eines Linux-Systems
Im Moment setze ich auf SMP Systemen den "Classic Server (CS)" ein. Es bedeutet, es läuft kein einzelner Dämon, sondern pro Verbindung wird ein Server-Prozess neu gestartet (fb_inet_server). Die Synchronisation erfolgt über Datei-Locks der jeweiligen Datenbank-Datei mit Hilfe eines monolitischen Prozesses (fb_lock_mgr). Bei dem Hochstarten der einzelnen Server-Prozesse hilft xinetd (ehemals inetd). Dies ist ein Programm, das dabei Hilft auf einzelnen Ports eines Linux-Systems
Dienste anzubieten. Man beschreibt seinen Dienst in einer config-Datei, wenn dann ein Verbindungsversuch auf dem angegebenen (und von xinetd angebotenen) Port stattfindet startet xinetd das angegebene Programm und leitet die Anfrage an dieses Programm weiter.
Dienste anzubieten. Man beschreibt seinen Dienst in einer config-Datei, wenn dann ein Verbindungsversuch auf dem angegebenen (und von xinetd angebotenen) Port stattfindet startet xinetd das angegebene Programm und leitet die Anfrage an dieses Programm weiter.


Zeile 56: Zeile 237:
#
#


== Probleme mit Windows XP SP 2 ==
 
* Es funktioniert nur FirebirdCS-2.5.3.26780-0.i686.rpm, also die Classic 32 Bit Version.
* Nicht vergessen die firewall zu deaktivieren, oder zumindest Post 3050 öffnen
* firebird läuft noch über xinetd, also systemctl enable xinetd, systemctl start xinetd
 
 
joe /etc/xinet.d/firebird
 
# default: on
# description: FirebirdSQL server
#
# Be careful when commenting out entries in this file. Active key entry should
# be the first as some scripts (CSchangeRunUser.sh in particular) use sed
# scripting to modify it.
service gds_db
{
        disable        = no
        flags          = REUSE
        socket_type    = stream
        wait            = no
        user            = firebird
        bind            = 192.168.115.224
        server          = /opt/firebird/bin/fb_inet_server
}
 
=== OpenSuSE 42 ===
 
zypper install firebird-classic
systemctl enable firebird
systemctl start firebird
#
# Sicherheitsrelevant!
#
# Ändere nun das SYSDBA Passwort von "masterkey" auf was ordentliches
#
/usr/lib64/firebird/utils/changeDBAPassword.sh
 
* Konfiguration /etc/firebird/firebird.conf
* Benutzerdatenbank /var/lib/firebird/
* SYSDBA Passwort ändern: changeDBApassword.sh
 
 
=== openSUSE 42.3 ===
#
# Installation
#
zypper addrepo http://download.opensuse.org/repositories/server:/database/openSUSE_Tumbleweed/server:database.repo
zypper refresh
zypper install firebird-server
#
# zukünftiger Autostart
#
systemctl enable firebird
#
# Start
#
systemctl start firebird
#
# Test
#
telnet localhost 3050
 
=== Windows 7/8/10/Server ===
 
* Ich rate von der Verwendung des Firebird- Servers unter Windows allgemein ab, es sollte immer wenn möglich ein Linux- Server verwendet werden. Wenn es nicht anders geht muss man - wie immer bei Windows - etwas schrauben dass es funktioniert
** Das Passwort ist nach der Installation immer masterkey
** In der Defender Firewall muss man die eingehenden Ports 3050 und 3051 öffnen
** Die "Firebird.conf" sollte so aussehen
 
#
# Einstellungen für erfolgreiches Konnektieren von 2.5 Clients
#
AuthServer = Legacy_Auth
AuthClient = Legacy_Auth
UserManager =  Legacy_UserManager
AllowEncryptedSecurityDatabase = false
WireCrypt = Enabled
WireCompression = false
RemoteAuxPort = 3051
 
 
=== Windows XP SP 2 ===
<b></b>
<b></b>


Zeile 114: Zeile 380:
siehe [[Installation.Arbeitsplatz]]<br>
siehe [[Installation.Arbeitsplatz]]<br>


== Verwendung mit Delphi ==
== Shell Befehle ==
 
<syntaxhighlight lang="shell">
#
# Anzeigen aller offenen Firebird Verbindungen
#
ss | grep gds-db                     
ss -n | grep :3051 | sort
                   
ps -A | grep fb                      // anzeigen aller firebird - Prozesse
lsof <firebirddatenbankdatei>                // anzeigen aller User auf einer firebird Datenbank
lsof -p <PID eines fb_inet_servers>          // anzeigen der Dateien, die der Prozess offen hat
                                              // es wird auch angegeben wer (welcher remote) connectiert ist.
 
</syntaxhighlight>
 
== Verwendung als Embedded ==
 
* Dies bezeiht sich nur noch auf die freepascal win64 Programmierung
* die "fbclient.dll" der Version 3.0.7 ist automatisch eine embedded Version, einfach die .zip Distribution in das Anwendungsverzeichnis entpacken
* mit gbak kann man eine .fbak auf einem Netzwerk-share wieder in eine .fdb verwandeln, aber nur auf ein lokales Drive, also C:\ oder ein USB Stick F:\
* mit freepascal win64 ist mir das noch nicht gelungen, da ist noch ein problem
* man kann auf keine .fdb auf einem Netzwerk Share verbinden
** auch wenn man mit gfix die Datenbank in eine read-only Datenbank verwandelt hat
 
== Verwendung mit http://drbd.org ==
 
Um mit Firebird eine gewisse Ausfallsicherheit zu erreichen können 2 Massnahmen getroffen werden.
 
=== Operation auf einer Partition / Blockdevice ===
 
normalerweise ist eine FirebirdSQL-Datenbank eine Datei, die mit wachsendem Inhalt der Datenbank immer grösser wird. Man kann aber einfach firebirdSQL anweisen eine ganze Partition für die Ablage der Datenbank zu verwenden. Die Datenbank-Grösse kann dann nur bis zur Partitions-Grösse anwachsen. Auf den Backup und Restore Prozess hat dies keinen Einfluss.
 
Eine Performance-Messung ergab praktisch identische Zugriffszeiten bei der Operation auf einer Partition im Vergelich zu einer Datei auf der selben Platte. Der Restore in die Partition hinein wurde mit 16 K Page Size durchgeführt.
 
=== Operation auf DRBD ===
 
DRkann eine Partition auf einen anderen REchner spiegeln. Host A wird zum Master, wenn ein Prozess auf Host A schreibend auf das Block-Device zugreift wird diese Änderung auf Host B per Netzwerk übertragen. Auch Host B ändert nun sein Abbild und beide Partitionen sind wieder gleich.
Wir gewinnen einen gewissen Schutz beim Ausfall des Host A, dann können wir firebird auf Host B auf der Partition B starten.
 
=== Die Konfiguration ===
 
chkconfig --add drbd
cat /proc/drbd
 
* resouce in /etc/drbd.conf auf beiden Systemen definieren
 
resource r0 {
  protocol A;
  meta-disk internal;
  device /dev/drbd1;
  on raib24 {
    disk /dev/sdb2;
    address 192.168.115.24:7789;
  }
  on raib30 {
    disk /dev/sdb1;
    address 192.168.115.30:7789;
  }
  syncer {
    rate 10M;
  }
}
 
* Erstellen des /dev/drbd1
 
#
# Ich hatte das Problem, dass die Partitionen leicht unterschiedlich gross waren.
# Irgendwie hat die, in der Doku angesprochene "size determination method" versagt,
# oder ich hatte die Aushandlungsphase versehentlich verhindert, da ich zunächst auf dem Primary
# ohne Kopplung auf den Secondary die Metadata bereits geschrieben habe.
# Hier sollte noch eine Step by Step anleitung kommen, die die VErbindung
# VOR erzeugen der Metadaten setzt. Das wär' mir lieber!
# Ansonsten könnte man sagen
# Ich erstelle 2 PArtitionen, die einfach nur >=Size sind, danach setzte ich die Ursprünglich gedachte Size:
# -d, --disk-size size
# You can override DRBD's size determination method with this option. If you need to use the device before it was ever connected to its peer, use this option to pass the size of the DRBD device to the driver. Default unit is sectors (1s = 512 bytes).
# If you use the size parameter in drbd.conf, we strongly recommend to add an explicit unit postfix. drbdadm and drbdsetup used to have mismatching default units.
 
drbdadm create-md all
drbdadm -- --overwrite-data-of-peer primary all
 
# Ab hier kam ich in Probleme da ich beide Partitionen nicht genau gleicg gemacht hatte
# Egal was ich eingetragen hatte, irgend eine Rundung verwarf mir meine Angaben
# Es sind auch auf beiden Systemen nicht baugleiche Platten, so dass ich mir
# dieses Problem mit der Unterschiedlichen Partitions-Geometrie erkläre
# Es ging aber als ich die Sekundäre Partition etwas grösser machte, als die
# bereits "metadata" initialisierte primäre Partition. Es scheint so dass dann
# klaglos der Rest der Sekundären Partition unbenutzt bleibt.
#
@Secundary> drbdadm secundary all
# Beim Restore einer DB mit gbak als root gab es kein Problem
# aber der Zugriff auf die Partition war dann Firebird in der Rolle als Remote-Prozess nicht
# möglich. Hier wird nämlich das Dateisystem (in dem Fall das Blockdevice System) in der Rolle des
# User "firebird" angesprochen. Gute Infos zu dieser Thematik gibt es hier:
# http://fghaas.wordpress.com/2007/06/04/using-drbd-directly-without-a-file-system/
# Versuch 1) ich habe die Rechte von /dev/drbd1 entsprechend angepasst!
#            @primary> chmod o+rw /dev/drbd1
#            das ging genau 1mal, aber nach den "close" durch firebird waren die Rechte wieder auf
#            Original-Zustand zurückgesetzt.
# Versuch 2) ich habe den owner von root auf "firebird" gesetzt, das ging wieder nicht lange gut
# Versuch 3) ich wollte "firebird" zur Gruppe "disk" hinzufügen, das klingt eigentlich toll,
#            aber wie geht das? Über die ganzen Befehle kam ich nicht zu Ziel.
#            Ich habe einfach die Datei /etc/group editiert:
#
@primary> joe /etc/group
# Bei "disk" muss hinten der User "firebird" angehängt werden
#
disk:x:6:firebird
#
 
== Usage with ZNS (a concept) ==
 
* a firebird database is stored to a single file, all the data, tables and indexes share the same file
* this concept is so clean, that you can even use a partition to store a database
* Data is organized by fixed size Pages, there are different Page-types - for Row-Data, Index-Tables, or Metadata
* firebird storage is optimized for typical blockdevice, open the file, read, append to the end, and update Pages
* a firebird file can only grow, but there are unused pages within a firebird file, the more the older is the file
 
=== why ZNS for NVMe ===
 
* NVMes are perfect Blockdevices for firebird? Yes, they seem to be, but internal they do a lot of work to keep expectations
* They only emulate a perfect Blockdevice by the Housholding Algos of their internal Controller Software
* Under the hood, there is dramatic action going on:
** Reading Data ist not the problem, just works like reading Bits from a RAM Chip
** Writing "new" Data to prior unused space is no Problem
** Updating, or overwriting data is a Problem, internally this is not possible
** Updating is done by erasing a Zone an writing it new from left to right
** Updating n-Bytes can result in writing n*2*y-Bytes
 
=== Give NVMe more Info ===
 
* If the OS would give more Information to the NVMe, Live for it could be much easier
* The NVMe could avoid internal housholding writes, this is prelonging livetime
* What Information is helpfull:
** What data belongs to a file
** When you start writing a file, please tell me its size (if known)
* What breaks the "blockdevice" game
** We must understand the "zone" Ecosystem
** We must arrange data in Zones
** forget random writes to files
** remember the "artefacts", let the nvme do the garbage collect (by "simple copy")
 
=== The new Firebird Storagemode ===
 
==== Pages ====
 
* Pages, from nowone can only be saved to the end of the file
* Page Number 0 is not nessesarly on position 0 of the file
* You must ask a "bitmap" layer to get the real position
 
==== Bitmap ====
 
* We must implement a new "translating" level for PageNumbers
* This persistent Datastructure maps Pagenumbers to the real world
* It grows from 0.. , but data is interpreted from EOF..0
 
type
  BitmapElement = record
  PageNumber: int64;
  Zone: int64;
  Seek: int64;
  StopLookingBack: boolean;
  end;
  Bitmap = array of BitmapElement;
 
* If you ask for a PageNumber you get a Zone and a Seek back
* If you get no answer, you can assume Zone=0 and Seek=PageNumber
* if StopLookingBack is true, do not trust older BitmapElements with this PageNumber
 
=== Page-Zones ===
 
* In my Picture i will only look at the "Write"- Aspect of an NVMe, reading is done by magic!
* Imagine a Data-Storage Room with hundreds of Tape-Recorders
* One Tape is one Zone, the storage Controller can
** erase an entire single tape by sending the command resulting in a "magnetic flash"
** write data from 0..EOF the Tape, no update, no overwrite, only appending data until the tape is at its end
 
* firebird should ask how big the Zone-Size is and use now Zones for writing the Pages of all kind
* If a Page must be updated, do not write to the original file position of the page (no, dont use seek+write), append it to the actual End of the Database-file, this is in the highest
* So we have an Old representation and a new in our Page-File - wich is the correct one?
*
 
=== Bitmap-Zones ===
 
* With the help of a Bitmap-Datastructure firebird can calculate the true Position of Pages
* With a "perfect" ordered Database-File the Bitmap is empty
* If new or recently updated Pages grow the file the Bitmap grows.
* firebird has to calculate PageNo+Bitmap -> ZoneNumber, SeekPosition
* Even the Bitmap can only grow, there is no "updated" Bitmap-Data
* A persistent Bitmap must be read from right to the left (from newly saved Data to older ones)
* A newer Information about a Page-Position makes all the old-Data about Pages obsolet
 
=== simple copy ===
 
* use NVMe "simple copy" to "garbage collect" bitmap and Page File
 
==== The Page-Storage ====
 
DDXXDXDDDDDXXXXX
 
* D=actual real Page
* X=artefact of an old now unused page
* By reading old Parts of the Bitmap, firebird knows where artefacts live
* with the NVMe simple copy command you can ...
** move all the "D" to the append position
** send the info that the hole zone is now free!
** after such a "simple copy" the bitmap must mark the X Position as censored, that means a reserach and use of Position Data in old Bitmap Data is forbidden
 
==== The Bitmap-Storage ====
 
XXXBXBBBBBBXBBBBB
 
* if you parse the entire Bitmap from rigth to left, before reaching "0", there is a Point P where you have all the information you need for the hole Picture
* this is because some Information is "censored" and so, has no Information Content any more
* so you can free 0..P, in our sample you can free XXX
 
=== this causes more corruption? ===
 
* appending a new Pages? No risk
* updating a page means
** A: appending the page to the higest Page-Zone
** B: appending Bitmap-Info about this page writing a Page to the and add this Information to the Bitmap
** C (optional):a Page-Zones gets free, because the updated page was the last living object on that zone
** D (optional):a Bitmap-Zone gets free, because a zone is complete censored know (by Step C)
 
-> if you ensure A+B+C+D inside an atomic transaction, if a file system can help, this is save
 
== Verwendung mit PHP ==
== Verwendung mit PHP ==
== Verwendung mit Java Server Pages ==
== Client Install ==


C:\WINDOWS\system32, GDS32.dll
Die Verwendung unter PHP ist möglich indem man die Extension "interbase" bereitstellt.
MSVC8.0 Manifest usw.
 
=== 64-bit ===
 
Bekomme ich bei mir nicht zum laufen. Nach der Compilierung eines Mini-Programmes zur Abprüfung der existenz von libfbclient kann das Programm die Bibliothek nicht laden: "not compatible version of" ...
 
* Traurig: Nach so vielen Jahren 64-Bit läuft das immer noch nicht!
 
=== 32-bit ===
 
 
* Vorbereitung
 
 
zypper install libxml2-devel
zypper install FirebirdCS-2.5.0.26054-ReleaseCandidate3.i686.rpm
 
 
 
* Ermittle die PHP Versionsnummer, damit du weist welchen Source-Tar-Ball du ziehen must
 
 
php -v
 
 
* Lade vom Museum die Source-Code Distribution des PHP, in diesem Beispiel hat die Versionsprüfung 5.1.0 ergeben
 
 
wget http://museum.php.net/php5/php-5.1.0.tar.gz
gzip -d php-5.1.0.tar.gz
tar -xf php-5.1.0.tar
cd php-5.1.0
 
 
* Compiliere Dir selbst die Extension "interbase.so", ermittle zuvor den Installationspfad von firebirdsql, ab 2.5 heisst er z.B. nicht mehr "/opt/firebird" wie hier angegeben
 
 
./configure --with-interbase=shared,/opt/firebird
make
 
 
* so, jetzt das Compilat noch PHP zur Verfügung stellen
 
 
cp modules/interbase.so /usr/lib/php5/extensions
 
 
* Nun reicht es, im Verzeichnis <code>/etc/php5/conf.d</code> die Datei <code>interbase.ini</code> anzulegen:
 
extension=interbase.so
[Interbase]
ibase.timestampformat=%m-%d-%Y %H:%M:%S
 
 
den Apache 2 neu starten
 
rcapache2 restart
 
Diagnose, ob jetzt das interbase Module geladen ist:
 
php --modules
 
auf Fehler in der folgenden Datei achten:
 
/var/log/apache2/error_log
 
=== Win32 ===
 
Damit PHP auf Interbase/Firebird Datenbanken zugreifen kann, müssen die Routinen, die das ermöglichen, beim
Start von PHP als Erweiterung geladen werden. Dies geschieht mit Hilfe zweier Einträge in der "php.ini".
Erstens muss der Eintrag "extension_dir= " auf das Verzeichnis mit den Extension-Dlls gesetzt werden. Diese
befinden sich standardmäßig im Verzeichnis "extensions". Falls PHP zum Beispiel in "C:\Programme\Php" installiert
wurde, liegen die Erweiterungs-Dlls im Verzeichnis "C:\Programme\Php\extensions".
Der Eintrag in der "php.ini" lautet dann:
  <u>Win32</u>
  extension_dir = "C:\Programme\Php\ext"
  <u>Linux</u>
  extension_dir = "/usr/lib/php/extension"
 
Zweitens gibt es in der "php.ini" einen Abschnitt, der sich "Dynamic Extensions" nennt. Dort sind alle Erweiterungen in der Form ";extension=php_....dll" aufgeführt. Da ein Semikolon am Anfang steht, beachtet PHP diese Zeile nicht als Eintrag sondern als Kommentar. In der Zeile ";extension=php_interbase.dll" muss dieses Semikolon nun entfernt werden.
 
  <u>Win32</u>
  extension=php_interbase.dll
  extension=php_gd2.dll
  <u>Linux</u>
  extension=interbase.so
 
Der WebShop erfordert, dass Timestamps im richtigen Format übernommen werden. Dies geschieht durch folgende zwei Zeilen, die am besten ans Ende der "php.ini" gestellt werden:
 
  [Interbase]
  ibase.timestampformat=%m-%d-%Y %H:%M:%S
 
Jetzt sollten die PHP-Routinen für die Interbase-Anbindung zur Verfügung stehen. Falls dies nicht so ist, liegt es vielleicht daran, das die "php.ini" im falschen Verzeichnis liegt  (siehe Ende vorletztes Kapitel) oder der Pfad im Eintrag "extension_dir=" falsch gesetzt ist.
 
<u>Achtung</u>: Nach einer Änderung muss der Apache-Webserver mit "Startmenü\Alle Programme\Apache HTTP Server\Control Apache Server\Restart" neu gestartet werden.
 
== Datensicherung ==
 
Unter Linux setzt firebird die Dateizugriffsrechte bei der erstellung der Datenbank-Datei auf
 
-rw-rw--- firebird firebird
 
das ist eher unpassend, da ich mit rsync die Dateien nun nicht lesen also auch nicht sichern kann. Die Maske müsste eher
 
chmod 664 sicherung_00000006.fdb
 
"664" lauten. Bisher hab ich noch nicht rausgefunden wie und wo man das ändern kann. Hat man alle firebird Datenbanken in einem Unterverzeichnis vereint, so kann man mit einem Befehl alle *.fdb Dateien korrekt anpassen.
 
cd /your-firebirdsql-database-root-path
chmod 664 `find -name *.fdb`


== Parallele Dienstverarbeitung ==
== Parallele Dienstverarbeitung ==


Beispiele: eMail VErsenden, oder an einem ARTIKEL Datensatz eine Zelle Updaten!
Fragestellung: Im Mehrbenutzerbetrieb fallen Aufgabenstellungen an (Jobs). Wie kann man mehrere Arbeiter-Prozesse einsetzen, und deren Arbeit über eine Datenbank koordinieren? Insbesondere ist zu vermeiden, dass sich 2 Arbeiter den gleichen Job holen und abarbeiten.
Dazu muss eine Abfrage das Arbeitsvolumen ausgeben können, dieses wird pollend ausgeführt. Es sollten schon die "in Arbeit befindlichen" ausgeklammert werden. Entscheidet sich ein Arbeiter für einen Datensatz muss er diesen Datensatz für sich verlässlich exclusiv reservieren können, dabei wird seine eindeutige Arbeiter-ID UND ein Reservierungsdatum eingetragen. Für jede Arbeits wird ein verfallsdatum angegeben an der diese Reservierung wieder verfällt, die Aufhebung von Reservierungen macht ein globaler Arbeiter.
 
Nach dem ERFOLGREICHEN setzen des Exclusiven Abstecken des Claim kann die Arbeit beginnen. Um den Streit (der immer eindeutig entschieden werden muss) zwischen den Arbeitern zu vermeinden soll jedem Arbeiter eine "Prämisse" mitgegeebn werden, z.B. von "oben nach unten", oder "immer das Mittlere Element", oder von "unten nach oben" oder "RID DIV 5 = 3" usw.
Beispiele: eMail Versenden, oder an einem ARTIKEL-Datensatz eine Datenzelle Updaten!
Ist die Arbeit erledigt so wird ja eh ein gewisser "Erledigt" Status verbucht, so dass die "offene" Selektion diesen Datensatz nicht mehr sieht. Als aller letzter Schritt wird die REservierung entfernt.
 
Dazu muss eine Abfrage das Arbeitsvolumen ausgeben können, dieses wird pollend ausgeführt. Es sollten schon die "in Arbeit befindlichen" ausgeklammert werden. Entscheidet sich ein Arbeiter für einen Datensatz muss er diesen Datensatz für sich verlässlich exclusiv reservieren können, dabei wird sein eigener eindeutiger ~Kontext~ (in ARBEITER) und das Reservierungsdatum (in ZUGETEILT) eingetragen. Für jede Arbeit wird ein Verfallsdatum angegeben an der diese Reservierung wieder verfällt, die Aufhebung von Reservierungen macht ein globaler Arbeiter.
 
Nach dem ERFOLGREICHEN setzen des exclusiven (atomaren) Abstecken des Claim kann die Arbeit beginnen. Um den Streit (der immer eindeutig entschieden werden muss) zwischen den Arbeitern zu vermeinden soll jedem Arbeiter eine "Prämisse" mitgegeben werden, z. B. von "oben nach unten", oder "immer das Mittlere Element", oder von "unten nach oben" oder "RID DIV 5 = 3" usw. Ziel wäre es dass nicht unbedingt im an den aktuellen Anforderungen gearbeitet wird, sondern immer auch an ganz alten.
 
Ist die Arbeit erledigt so wird ein gewisser "Erledigt"-Status verbucht, der Datensatz ist dadurch nicht mehr "offen", so dass die "offene"-Selektion diesen Datensatz nicht mehr sieht. Auch für die verlorengegangenen Arbeiter ist dies dann unsichtbar.


=== Lösung ===
=== Lösung ===
   
   
  # reserviere einen oder mehrere JOBS für dich
Von einem einzelnen Arbeiter-Thread werden immer folgende Arbeiten ausgeführt
  update first 1 from JOBS set
 
   WORKER = ~ME~,
* Gibt es "offene" Sätze mit "ARBEITER=~Kontext~" -> arbeite diese ab bis leer
   ARBEITS_BEGINN = CURRENT_TIMESTAMP
 
select RID from TICKET where
  (ART = 22) and
  (ARBEITER='V97XWY2Q6') and
  (BEENDET is null)
  #  
# Ergibt sich hier ein Ergebnis wird dieser Job abgearbeitet
#
 
 
* Ist die Arbeitsliste fertig: Gewisse Anzahl von Arbeiten für mich reservieren (atomar, multithread fest!)
 
  update TICKET set
   ARBEITER = 'V97XWY2Q6',
   ZUGETEILT = CURRENT_TIMESTAMP
where
  RID=
(
  select first 1
  RID
from
  TICKET
  where
  where
   WORKER is null
   (ART = 22) and
   
  (ARBEITER is NULL)
# Sehe nun nach JOBs für Dich und arbeitet im Fall,
  )
# dass etwas da ist
 
select RID from JOBS where
* Von einem Service-Thread werden ab und an folgende Arbeiten ausgeführt
  (WORKER=ME) and (ARBEITS_BEGINN<TIME_OUT)
** Arbeiter-Punzen (in diesem Fall ARBEITER='V97XWY2Q6') deren Zuteilung zu lange her ist, und die noch nicht BEENDET sind: Feld ARBEITER leeren. Dadurch werden diese Jobs frisch zugeteilt.
** Vollständig erledigte Vorgänge die weit zurückliegen löschen


== GHOST - Attachements ==
== GHOST - Attachements ==
Zeile 205: Zeile 845:
Ich habe heute ein Geister-Attachement gekillt (2 offene Transaktionen), dann sichergestellt dass alle OrgaMons frisch gestartet sind. Danach habe ich einen Sweep ausgeführt. Während des Sweeps (ca. 15 min) habe ich parallel immer mal wieder die Record-Versions geprüft. Die gingen im Verlauf "schnell" runter auf fast 0!
Ich habe heute ein Geister-Attachement gekillt (2 offene Transaktionen), dann sichergestellt dass alle OrgaMons frisch gestartet sind. Danach habe ich einen Sweep ausgeführt. Während des Sweeps (ca. 15 min) habe ich parallel immer mal wieder die Record-Versions geprüft. Die gingen im Verlauf "schnell" runter auf fast 0!


  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL hebu.fdb | grep versions
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
     Average version length: 11.50, total versions: 313751, max versions: 25
     Average version length: 11.50, total versions: 313751, max versions: 25
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL hebu.fdb | grep versions
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
     Average version length: 11.50, total versions: 313751, max versions: 25
     Average version length: 11.50, total versions: 313751, max versions: 25
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL hebu.fdb | grep versions
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
     Average version length: 11.50, total versions: 313751, max versions: 25
     Average version length: 11.50, total versions: 313751, max versions: 25
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL hebu.fdb | grep versions
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
     Average version length: 11.41, total versions: 200754, max versions: 22
     Average version length: 11.41, total versions: 200754, max versions: 22
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL hebu.fdb | grep versions
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
     Average version length: 11.41, total versions: 195344, max versions: 22
     Average version length: 11.41, total versions: 195344, max versions: 22
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL hebu.fdb | grep versions
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
     Average version length: 11.41, total versions: 190157, max versions: 22
     Average version length: 11.41, total versions: 190157, max versions: 22
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL hebu.fdb | grep versions
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
     Average version length: 11.42, total versions: 153594, max versions: 22
     Average version length: 11.42, total versions: 153594, max versions: 22
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL hebu.fdb | grep versions
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
     Average version length: 11.77, total versions: 48805, max versions: 21
     Average version length: 11.77, total versions: 48805, max versions: 21
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL hebu.fdb | grep versions
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
     Average version length: 11.84, total versions: 38239, max versions: 21
     Average version length: 11.84, total versions: 38239, max versions: 21
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL hebu.fdb | grep versions
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
     Average version length: 11.97, total versions: 26478, max versions: 21
     Average version length: 11.97, total versions: 26478, max versions: 21
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL hebu.fdb | grep versions
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
     Average version length: 12.00, total versions: 19429, max versions: 21
     Average version length: 12.00, total versions: 19429, max versions: 21
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL hebu.fdb | grep versions
  newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
     Average version length: 15.33, total versions: 6, max versions: 2
     Average version length: 15.33, total versions: 6, max versions: 2


Zeile 253: Zeile 893:
==== 29.02.2012 ====
==== 29.02.2012 ====


Until Jason has a "silent commit and reopen on demand"- fix ready: Here is my workaround. it is a automatic cut-connection script wich is executed by OrgaMon at noon.
Until Jason has a "silent commit and reopen on demand"- fix ready: Here is my workaround. it is a automatic cut-connection script wich is executed by OrgaMon automatically at noon.


* OLAP Skript: "System.Tagwache.Verbindungen_trennen.OLAP.txt"
* OLAP Skript: "System.Tagwache.Verbindungen_trennen.OLAP.txt"


<code>
  --
  --
  -- Skript zum Anzeigen / Beenden all zu langer Datenbankverbindungen
  -- Skript zum Anzeigen / Beenden all zu langer Datenbankverbindungen
Zeile 291: Zeile 930:
  delete from MON$$ATTACHMENTS where (MON$$ATTACHMENT_ID=$RID)
  delete from MON$$ATTACHMENTS where (MON$$ATTACHMENT_ID=$RID)
  -
  -
</code>
 
==== 28.01.2014 ====
 
will den Fehler mal reproduzieren. recht aktueller Linux-Server 2.5.2 wird bereits genutzt.
 
* OrgaMon öffen
* die delikate Aktion im Tagesabschluss
* prüfung mit Anzeige der Record-Versions
* OrgaMon schliessen
* prüfung der langsamen Abnahme der Record-Versions


== firebird 3.0 ==
== firebird 3.0 ==


=== Erste Tests ===
* Für die Zukunft ist ungewiss ob die Quellen des OrgaMon auf nativ Firebird 3.0 umgestellt werden
* Es steht immer noch im Raum ev. auf Postgresql umzustellen
* Als Zwischenlösung konnektiere ich erfolgreich mit dem OrgaMon in Verbindung mit einer firebird Client DLL 2.5.x auf einen Firebird 3.0 Server
 
#
# Einstellungen für erfolgreiches Konnektieren von 2.5 Clients
#
AuthServer = Legacy_Auth
AuthClient = Legacy_Auth
UserManager = Legacy_UserManager
AllowEncryptedSecurityDatabase = false
WireCrypt = Enabled
WireCompression = false
RemoteAuxPort = 3051
DatabaseAccess = Restrict /srv/firebird
 
== SYSDBA Passwort abändern ==
 
gsec -user SYSDBA -password masterkey -modify sysdba -pw MyKey37
 
== Firebird Datenbank Crash? ==
 
    konkrete Verwendung einzelner Befehle für backup und restore.
    siehe ibreorg.bat in der Anlage. (der ist leider für 32-DOS-Box!)
    die Befehle müssen auch unter linux so gehen. der Pfad ist aber
    /opt/interbase/bin/gbak ....
    --- snip
    @echo off
    REM -------------------------------------------------
    REM Reparatur einer inkonsistenten FireBird Datenbank
    REM
    REM (c) Andreas Filsinger, www.orgamon.org
    REM -------------------------------------------------
    REM
    REM Usage
    REM
    REM reorg <Pfad und Name der Datenbank OHNE ".gdb">
    REM
    REM --------------------------------------------
    REM
    REM ACHTUNG: richtigen Pfad ermitteln, indem Sie nach der
    REM          Datei gbak.exe suchen lassen. Und hier eintragen:
    REM
    SET IBBIN=D:\programme\borland\interbase\bin\
    REM
    REM --------------------------------------------
    REM 1) fix erros
    REM
    %IBBIN%gfix -mend -full -ignore -user "SYSDBA" -password "masterkey" %1.fdb
    REM --------------------------------------------
    REM 2) backup fixed base
    REM
    %IBBIN%gbak -backup -v -ignore -garbage -user "SYSDBA" -password "masterkey" %1.fdb %1_neu.fbak
    REM --------------------------------------------
    REM 3) restore base
    REM
    REM zusätzlich noch "-i" wenn Indizes deaktiviert werden sollen
    REM
    %IBBIN%gbak -r -v -p 16384 -user "SYSDBA" -password "masterkey" %1_neu.fbak %1_neu.fdb
    REM --------------------------------------------
    REM 4) check new one
    REM
    %IBBIN%gfix -v -f -user "SYSDBA" -password "masterkey" %1_neu.fdb
    REM --------------------------------------------
    --- snap
 
    Bemerkungen
    ===========
 
    a) Backup-möglich aber fail beim Restore: wegen inkonsistenter Indizes
    ich habe mal erlebt, das foreign Key nicht mehr konsistent waren, und deshalb
    der restore abgebrochen hat. Alle Indizes kann man jedoch als inaktiv restoren,
    (Option -i )
    nach löschen /clearen der "Schuldigen" kann man alle indizes wieder aktivieren,
    wieder ein backup, wieder ein restore -> alles wieder gut.
    damit der OrgaMon alle indizes sehen kann braucht er "out.txt". Das ist die
    Ausgabe eines erfolgreichen restores, der alle indizes enthält.
    Unter linux gibt man die Ausgabe von gbak mit 2>/freigabe/out.txt in eine Datei
    aus.
 
    firebird-Erkenntnis
    ===================
 
    internal gds software consistency check (partner index description not found (175))
 
    dieser Fehler tritt beim löschen eines Datensatzes auf, der eventuell durch einen
    foreign key einer anderen Tabelle referenziert werden könnte. Ist dieser key
    deaktiviert so kann keine Aussage getroffen werden, ob das löschen ok ist, dieser
    interne Fehler ist die Folge!!
 
== Page Type Error ==
 
Behebung des Fehlers "Wrong page type":
=== Backup ist nicht mehr möglich ===
Beobachtung:
tokio:/srv/smb/fdb # gbak -b -g -ig -user sysdba -password **** /srv/smb/fdb/k-prod.fdb k-prod.fbak
gbak: ERROR:database file appears corrupt (/srv/smb/fdb/k-prod.fdb)
gbak: ERROR:    wrong page type
gbak: ERROR:    page 136509 is of wrong type (expected 4, found 5)
gbak: ERROR:gds_$compile_request failed
gbak:Exiting before completion due to errors
Auch mit der Option -mend : kein Erfolg
 
=== GFix ist nicht mehr möglich ===
 
Beobachtung:
tokio:/srv/smb/fdb # gfix -v -f -user sysdba -password * /srv/smb/fdb/k-prod.fdb
Summary of validation errors
        Number of pointer page errors  : 1
        Number of database page errors  : 28
 
=== IBAid "Repair" hat keine Wirkung ===
 
* der Direct Fix läuft durch und erweckt den Eindruck dass er das Problem gelöst hätte
* After the "fix", i did the suggested final steps: There were the known, old errors, finally gbak fails!
 
 
server:/srv/firebird/prod # gfix -v -full -user sysdba -password **** /srv/firebird/prod/k-prod.fdb
Summary of validation errors
        Number of pointer page errors  : 1
        Number of database page errors  : 28
 
server:/srv/firebird/prod # gfix -mend -ig -user sysdba -password **** /srv/firebird/prod/k-prod.fdb
Summary of validation errors
        Number of pointer page errors  : 1
        Number of database page errors  : 28
 
server:/srv/firebird/prod # gbak -b -g -ig -user sysdba -password **** /srv/firebird/prod/k-prod.fdb k-prod.fbak
gbak: ERROR:database file appears corrupt (/srv/firebird/prod/k-prod.fdb)
gbak: ERROR:    wrong page type
gbak: ERROR:    page 136509 is of wrong type (expected 4, found 5)
gbak: ERROR:gds_$compile_request failed
gbak:Exiting before completion due to errors
 
=== IBAid "Exract" bringt die Lösung ===
 
1) Beende alle Datenbank-Dienste und stelle die fdb bereit
2) Erstelle aus dieser defekten fdb eine leere fdb gleicher Metadatenstruktur
gbak -b -m -user sysdba -password ***** /srv/firebird/prod/2/l-prod.fdb l-prod.fbak
gbak -v -r -p 16384 -user sysdba -password ****** l-prod.fbak empty-prod.fdb
3) Starte IBAid und gehe direkt über den Wizzard
  "Extract" <Next>
  danach im Wesentlichen die Standard-Optionen
  lege die empty-.fdb auf deinen firebird server und geben die Connect Daten an
 
4) Es folgt dann das befüllen der fdb durch IBAid
dieser Vorgang hat in meinem Fall 7 Stunden gedauert
 
== table id n is not defined (invalid service handle) ==
 
* Kommt beim Backup einer Datenbank "table id * is not defined gds_$compile_request failed" so blockiert eine Verbindung, die Zugriff auf die $CLUB Tabellen hatte, dass firebird wieder in einen konsistenten Zustand kommt.
** Die $CLUB Tabellen sind temporäre Tabellen, die bei der Geolokalisierung verwendet werden um die aktuellen "Geolokalisierungs-Punkte"  zu einer Gruppe/Club zusammenzufassen.
** Die Verbindung/Transaktion ensteht am Tag durch Arbeiten am Geo-Arbeitsplatz. Der Tagesabschluss löscht dann "alte" $CLUB Tabellen, dadurch ensteht ein Konflikt.
* In der Folge zeigt das Backup-Programm in einer Endlosschleife an: <code>invalid service handle</code>
* Vorbeugend sollten "solche" langen Laufzeiten von Verbindungen vermieden werden (lang laufende Transaktionen)
 
[[Datei:Fehlermeldung invalid service handle.png]]
 
Lösung:
Neustart den Datenbank-Servers:
===============================
<b>systemctl stop firebird-superserver.service</b>
<b>systemctl start firebird-superserver.service</b>
 
== Scrub & Reboot ==
 
* Nach 3 wöchiger extensiver Nutzung hilft es, die Datenbank neu zu erzeugen und den DB-Server neu zu starten
* Es konnte nachgewiesen werden, dass sich unerklärbare Instabilitäten dadurch verringern lassen
* Das folgende Script wird wöchentlich (z.B. Mittwochs 02:00 Uhr) ausgeführt
* Die Schritte sind
** Ausschalten aller "Gateways" zur Datenbank die Änderungen an der Datenbank auslösen könnten (z.B. php-Scripte via Webserver)
** Ausschalten aller VMs, die eine Datenbankverbindung aufbauen (10 Sek. warten bis die VM runtergefahren ist)
** Ausschalten des Datenbank-Dienstes an sich, nun stürzen alle laufenden OrgaMon-Anwendungen ab, nun werden alle Ghost-Attachements an die Datenbank gekappt, nun werden alle hängenden Transaktionen und Locks beendet
** Verschieben der Datenbank-Datei, mit neuem Namen, sodass nicht reconnected werden kann
** Backup der DB danach Restore der DB aus dem frischen Backup in eine nagelneue Datei mit "bekanntem", "alten" Namen (vollständiger Scrub)
** Anpassung der Zugriffsrechte
** Dateisystem-Sync und Reboot des ganzen Servers
 
#!/bin/bash
#
# /root/full-server-restart.sh
#
# (c) 2022 Andreas Filsinger
#
#
systemctl stop vsftpd
systemctl stop nginx
systemctl stop VirtualBox@WIN7
sleep 10
systemctl stop firebird-superserver
PROD=firma.fdb
BAND=$(date +"%Y%m%d-%H%M%S")
#
# move the productive .fdb , so nobody can connect
#
mv /srv/firebird/$PROD /srv/firebird/$BAND.fdb
#
# backup
#
/usr/local/firebird/bin/gbak -V -USER SYSDBA -PASSWORD * /srv/firebird/$BAND.fdb /srv/firebird/$BAND.fbak
#
# restore to prod
#
/usr/local/firebird/bin/gbak -R -V -P 16384 -USER SYSDBA -PASSWORD * /srv/firebird/$BAND.fbak /srv/firebird/$PROD
chmod 777 /srv/firebird/$PROD
chgrp firebird /srv/firebird/$PROD
chown firebird /srv/firebird/$PROD
#
# backup is not longer needed
#
rm /srv/firebird/$BAND.fbak
sync
reboot
 
* ACHTUNG: Um eine Situation zu vermeiden, dass Backup und Restore nicht gelingen und man dann ohne eine Datei dasteht wird die Original .fdb Datei NICHT gelöscht
** Pro Woche entsteht hier eine zurückbleibende .fdb Datenbank-Datei, die manuell gelöscht werden muss
 
== Backup / Restore ==
 
#!/bin/sh
#
# parameter customize
#
NAMESPACE=yourname
DBPWD=********
 
#
# JJJJ-MM-DD
#
BAND=$(date +%Y-%m-%d)
#
# backup
#
rm $NAMESPACE-$BAND.fbak
/opt/firebird/bin/gbak -V -B -USER SYSDBA -PASSWORD $DBPWD $NAMESPACE.fdb $NAMESPACE-$BAND.fbak
#
# restore
#
rm $NAMESPACE-$BAND.fdb
/opt/firebird/bin/gbak -V -R -P 16384 -USER SYSDBA -PASSWORD $DBPWD $NAMESPACE-$BAND.fbak $NAMESPACE-$BAND.fdb
chown firebird $NAMESPACE-$BAND.fdb
chgrp firebird $NAMESPACE-$BAND.fdb
#
# clean-up
#
rm $NAMESPACE-$BAND.fbak
#
#
#
 
== Charset ==
 
* der Charset ist im Moment noch "NONE", ist implizit aber eigentlich "ISO8859_1"
 
update
  RDB$$DATABASE
set
  RDB$$CHARACTER_SET_NAME='ISO8859_1'
 
== FileCreate 660 ==
 
* fdb Dateien werden mit den Recht 660 angelegt, manchmal kann ein Client die Datenbank-Datei dann nicht löschen
* auf dem Server, der das Share /srv/firebird freigibt
 
#
# "nobody" wird in die Gruppe "firebird" verbracht
#
usermod -a -G firebird nobody
 
=== Prüfen ===
 
joe /etc/group
#
# Es muss eine Zeile geben
#
firebird:x:495:nobody
 
== UTF8-Migration ==
 
create database 'orgamon.fdb' default character set UTF8 collation de_de;
create table PERSON (
  RID int64 not null primary key,
  last_name  varchar (50),
  first_name varchar (50));
 
== Links ==


* http://libtom.org/ compilieren
* https://ib-aid.com/articles/firebird-gbak-backup-tips-and-tricks
* danach libtommath.a in eigenes verzeichnis kopieren
* ar x libtommath.a
* gcc -shared -o libtommath.so.1 *.o

Aktuelle Version vom 1. März 2024, 12:16 Uhr

Firebird ist ein SQL-Datenbankserver. Firebird is a registered trademark of the Firebird Foundation [[1]] Zur Datenhaltung verwendet OrgaMon den freien Datenbank Server Firebird-SQL (https://firebirdsql.org/).

Installation

Im Moment setze ich immer den SuperServer der Version 3 ein.

OpenSuSE 15.1 / 15.2

zypper install firebird-server firebird-examples telnet
#
# Sorge für angepasste Einstellungen
#
mv /etc/firebird/firebird.conf /etc/firebird/_firebird.conf
joe /etc/firebird/firebird.conf

firebird.conf

#
# /etc/firebird/firebird.conf
#
# Einstellungen für erfolgreiches Konnektieren von 2.5 Clients
#
AuthServer = Legacy_Auth
AuthClient = Legacy_Auth
UserManager =  Legacy_UserManager
AllowEncryptedSecurityDatabase = false
WireCrypt = Enabled
WireCompression = false
RemoteAuxPort = 3051
DatabaseAccess = Restrict /srv/firebird


#
# Start the server
#
systemctl enable firebird.service
systemctl start firebird.service

# 
# test if server is running
#
telnet localhost 3050

#
# set the SYSDBA Password, MUST replace ***********
#
gsec -user sysdba -password masterkey -modify sysdba -pw ~DeinNeuesPasswortHier~

#
# Alternativ, aber unklar
#
isql-fb employee;
SQL> create or alter user SYSDBA password '***********';
SQL> commit;
SQL> quit;


/etc/crontab

  • damit bei einem freigegebenen Share firebird-Datenbanken löschbar sind
#
# Firebird
#
00 10 * * * root chmod -R 777 /srv/firebird

/etc/samba/smb.conf

  • Nehme die Freigabe des Datenbankverzeichnisses zu deinen Samba-Shares hinzu
  • Die Arbeitsstationen müssen keinesfalls dieses Share mit einem Laufwerk verbinden
  • OrgaMon wird bei der Datensicherung auf \\host\firebird zugreifen


...
 
[firebird]
     comment = Firebird
     path = /srv/firebird
     guest ok = yes
     writeable = yes
     create mode = 0777
     directory mode = 0777
     force create mode = 0777
     force directory mode = 0777

selbst compilieren 3.0.5

zypper install libicu-devel libtommath-devel libtomcrypt-devel
wget http://web.firebirdsql.org/download/snapshot_builds/linux/fb3.0/Firebird-3.0.5.33221-0.tar.bz2
bunzip2 Firebird-3.0.5.33221-0.tar.bz2
tar -xf Firebird-3.0.5.33221-0.tar
cd Firebird-3.0.5.33221-0/
./configure
make
make install
  • firebird.conf ist in /usr/local/firebird
  • gbak: /usr/local/firebird/bin/gbak
  • service ist: systemctl status firebird-superserver.service


selbst compilieren 3.0.7

  • gilt analog auch für firebird 3.0.8, 3.0.9,
  • gilt nicht für 3.0.10 auf openSUSE 15.4, hier meint er "icu" hätte die falsche Versionsnummer
zypper install telnet libicu-devel libtommath-devel libtomcrypt-devel
wget https://github.com/FirebirdSQL/firebird/releases/download/R3_0_7/Firebird-3.0.7.33374-0.tar.bz2
# wget https://github.com/FirebirdSQL/firebird/releases/download/v3.0.10/Firebird-3.0.10.33601-0.tar.bz2
bunzip2 Firebird-3.0.7.33374-0.tar.bz2
tar -xf Firebird-3.0.7.33374-0.tar
cd Firebird-3.0.7.33374-0/
./configure
make
make install
  • firebird.conf ist in /usr/local/firebird
  • gbak: /usr/local/firebird/bin/gbak
  • service ist: systemctl status firebird-superserver.service
#
# SYSDBA Passwort setzten
#
/usr/local/firebird/bin/gsec -user sysdba -password masterkey -modify sysdba -pw ~DeinNeuesPasswortHier~

selbst compilieren 3.0.10

zypper install telnet libicu-devel libicu69 libtommath-devel libtomcrypt-devel
#wget https://github.com/FirebirdSQL/firebird/releases/download/v3.0.10/Firebird-3.0.10.33601-0.tar.bz2
wget https://github.com/FirebirdSQL/firebird/releases/download/v3.0.11/Firebird-3.0.11.33703-0.amd64.tar.gz
bunzip2 Firebird-___ .tar.bz2
tar -xf Firebird-___.tar
cd Firebird-___/
./configure
make
make install
  • firebird.conf, databases.conf ist in /usr/local/firebird
  • gbak: /usr/local/firebird/bin/gbak
  • service ist: systemctl status firebird-superserver.service
#
# SYSDBA Passwort setzten
#
/usr/local/firebird/bin/gsec -user sysdba -password masterkey -modify sysdba -pw ~DeinNeuesPasswortHier~

selbst compilieren 3.0.11

  • openSUSE 15.5
wget https://github.com/FirebirdSQL/firebird/releases/download/v3.0.11/Firebird-3.0.11.33703-0.tar.bz2
zypper install telnet libicu-devel libicu69 libtommath-devel libtomcrypt-devel
zypper install gcc gcc-c++ make automake ncurses-devel zlib-devel 
bunzip2 Firebird-___ .tar.bz2
tar -xf Firebird-___.tar
cd Firebird-___/
./configure
make
make install

  • Bei make install soll man ein Passwort eingeben, das ist jedoch sinnlos, das eingegebene Passwort wird nicht verwendet
  • Wie immer also:
#
# SYSDBA Passwort setzten
#
/usr/local/firebird/bin/gsec -user sysdba -password masterkey -modify sysdba -pw ~DeinNeuesPasswortHier~

systemd

  • Es gibt scheinbar bestrebungen /var/run/ abzuschaffen, neu ist /run, das müsste auch im firebird geändert werden
(15/43) Installing: systemd-246.16-7.21.1.x86_64 .........................................................................................................[done]
Additional rpm output:
/usr/lib/tmpfiles.d/firebird.conf:1: Line references path below legacy directory /var/run/, updating /var/run/firebird → /run/firebird; please update the tmpfiles.d/ drop-in file accordingly.
/usr/lib/tmpfiles.d/net-snmp.conf:1: Line references path below legacy directory /var/run/, updating /var/run/net-snmp → /run/net-snmp; please update the tmpfiles.d/ drop-in file accordingly.
Too few arguments.
raib80:/usr/lib/tmpfiles.d # cat firebird.conf
d /var/run/firebird 0775 firebird firebird -

selbst compilieren 5.0.0

zypper install telnet libicu-devel libicu69 libtommath-devel libtomcrypt-devel
zypper install gcc gcc-c++ make automake cmake ncurses-devel zlib-devel 
wget https://github.com/FirebirdSQL/firebird/releases/download/v5.0.0/Firebird-5.0.0.1306-0-source.tar.xz
tar -xf Firebird-5.0.0.1306-0-source.tar.xz

Raspberry Pi / Debian

apt install firebird3.0-server firebird3.0-examples telnet
isql-fb security.db

rpm direkt von firebirdsql

## xinetd muss laufen!
chkconfig --add xinetd
rcxinetd start

## Dies installiert firebird und startet es (für immer!) 
rpm -i FirebirdCS-2.0.0.12748-0.nptl.i686.rpm

## man muss noch das passwort notieren
 
cat /opt/firebird/SYSDBA.passwd

## man kann noch definieren, wo die firebird Datenbanken liegen dürfen
## auf alle Fälle muss man verhindern, dass von aussen die security.fdb
## geöffnet werden kann.

joe /opt/firebird/firebird.conf
 
DatabaseAccess = Restrict /srv

rpm direkt vom Buildservice OpenSuse

ein manuelles Installieren mit rpm -i firebird- usw. war mir nicht möglich, da ich die Referenz auf "firebird-arch" nicht auflösen konnte (grrr.).

OpenSuSE 13.1

Im Moment setze ich auf SMP Systemen den "Classic Server (CS)" ein. Es bedeutet, es läuft kein einzelner Dämon, sondern pro Verbindung wird ein Server-Prozess neu gestartet (fb_inet_server). Die Synchronisation erfolgt über Datei-Locks der jeweiligen Datenbank-Datei mit Hilfe eines monolitischen Prozesses (fb_lock_mgr). Bei dem Hochstarten der einzelnen Server-Prozesse hilft xinetd (ehemals inetd). Dies ist ein Programm, das dabei Hilft auf einzelnen Ports eines Linux-Systems Dienste anzubieten. Man beschreibt seinen Dienst in einer config-Datei, wenn dann ein Verbindungsversuch auf dem angegebenen (und von xinetd angebotenen) Port stattfindet startet xinetd das angegebene Programm und leitet die Anfrage an dieses Programm weiter.

SMP Regeln

  1. verwende den Classic Server
  2. stelle die DefaultDbCachePages auf eine KLEINE Zahl (=75)


  • Es funktioniert nur FirebirdCS-2.5.3.26780-0.i686.rpm, also die Classic 32 Bit Version.
  • Nicht vergessen die firewall zu deaktivieren, oder zumindest Post 3050 öffnen
  • firebird läuft noch über xinetd, also systemctl enable xinetd, systemctl start xinetd


joe /etc/xinet.d/firebird
# default: on
# description: FirebirdSQL server
#
# Be careful when commenting out entries in this file. Active key entry should
# be the first as some scripts (CSchangeRunUser.sh in particular) use sed
# scripting to modify it.

service gds_db
{
       disable         = no
       flags           = REUSE
       socket_type     = stream
       wait            = no
       user            = firebird
       bind            = 192.168.115.224
       server          = /opt/firebird/bin/fb_inet_server
}

OpenSuSE 42

zypper install firebird-classic
systemctl enable firebird
systemctl start firebird
#
# Sicherheitsrelevant!
# 
# Ändere nun das SYSDBA Passwort von "masterkey" auf was ordentliches
#
/usr/lib64/firebird/utils/changeDBAPassword.sh
  • Konfiguration /etc/firebird/firebird.conf
  • Benutzerdatenbank /var/lib/firebird/
  • SYSDBA Passwort ändern: changeDBApassword.sh


openSUSE 42.3

#
# Installation
#
zypper addrepo http://download.opensuse.org/repositories/server:/database/openSUSE_Tumbleweed/server:database.repo
zypper refresh
zypper install firebird-server

# 
# zukünftiger Autostart
#
systemctl enable firebird

#
# Start
#
systemctl start firebird

#
# Test
#
telnet localhost 3050

Windows 7/8/10/Server

  • Ich rate von der Verwendung des Firebird- Servers unter Windows allgemein ab, es sollte immer wenn möglich ein Linux- Server verwendet werden. Wenn es nicht anders geht muss man - wie immer bei Windows - etwas schrauben dass es funktioniert
    • Das Passwort ist nach der Installation immer masterkey
    • In der Defender Firewall muss man die eingehenden Ports 3050 und 3051 öffnen
    • Die "Firebird.conf" sollte so aussehen
#
# Einstellungen für erfolgreiches Konnektieren von 2.5 Clients
#
AuthServer = Legacy_Auth
AuthClient = Legacy_Auth
UserManager =  Legacy_UserManager
AllowEncryptedSecurityDatabase = false
WireCrypt = Enabled
WireCompression = false
RemoteAuxPort = 3051


Windows XP SP 2

Langsamer Applikationsstart seit Installation des Windows XP Service Pack 2

Voraussetzung: (Ursächlich ist das Service Pack 2 von Windows XP)

Problem:

Bis zu 10 Sekunden längerer Verbindungsaufbau bei Konnektierung auf den Linux Firebird Classic Server.

Lösung:

Die Firewall des Service-Pack 2 blockiert alle eingehenden Verbindungsversuche von aussen. xinetd versucht bei aktiviertem log_on_success = USERID den erfolgreichen Verbindungsaufbau zum firebird-dienst zu protokollieren. Dazu läuft ein Protokoll ab zur Verifizierung der Benutzer Identiät auf Port 113.

mehr Info auf http://grc.com/port_113.htm RFC auf http://www.faqs.org/rfcs/rfc1413.html

Dieser ist geblockt, xinetd gibt nach 3 maligem Versuch auf. log_on_success und log_on_fail sollte entfernt werden, oder auf HOST umgestellt werden:

joe /etc/xinetd.d/firebird       
//
// Folgende beide Zeile so verändern oder ganz auskommentieren 
// 
 log_on_success = HOST
 log_on_fail = HOST
//

ps -A | grep xinetd              
// merke Dir den PID des xinetd

kill -SIGUSR2 <PID des xinetd>
//
// dadurch wird xinetd gezwungen seine konfiguration neu einzulesen.
//

Alternative: öffnen des Port 113 auf den Windows XP Clients (von mir nicht empfohlen)

sollten Sie schon Windows XP Serivce Pack 2 erhalten haben, so deaktivieren Sie bitte die Anti-Virus Warnung:

Deaktivieren der Virenschutz-Warnmeldung

Start->Systemsteuerung->Sicherheitscenter->Empfehlungen->unteren Haken ankreuzen

es sollte sich folgendes Bild ergeben:

Firewall: aktiv. Automatische Updates: aktiv. Virenschutz: nicht überwacht.

OrgaMon wird geblockt: (wegen Webshop XML-RPC-Port)

siehe Installation.Arbeitsplatz

Firebird : Linux-Server

siehe Installation.Arbeitsplatz

Shell Befehle

 #
 # Anzeigen aller offenen Firebird Verbindungen
 #
 ss | grep gds-db                      
 
 ss -n | grep :3051 | sort
                     
 
 ps -A | grep fb                       // anzeigen aller firebird - Prozesse
 lsof <firebirddatenbankdatei>                // anzeigen aller User auf einer firebird Datenbank
 lsof -p <PID eines fb_inet_servers>          // anzeigen der Dateien, die der Prozess offen hat
                                              // es wird auch angegeben wer (welcher remote) connectiert ist.

Verwendung als Embedded

  • Dies bezeiht sich nur noch auf die freepascal win64 Programmierung
  • die "fbclient.dll" der Version 3.0.7 ist automatisch eine embedded Version, einfach die .zip Distribution in das Anwendungsverzeichnis entpacken
  • mit gbak kann man eine .fbak auf einem Netzwerk-share wieder in eine .fdb verwandeln, aber nur auf ein lokales Drive, also C:\ oder ein USB Stick F:\
  • mit freepascal win64 ist mir das noch nicht gelungen, da ist noch ein problem
  • man kann auf keine .fdb auf einem Netzwerk Share verbinden
    • auch wenn man mit gfix die Datenbank in eine read-only Datenbank verwandelt hat

Verwendung mit http://drbd.org

Um mit Firebird eine gewisse Ausfallsicherheit zu erreichen können 2 Massnahmen getroffen werden.

Operation auf einer Partition / Blockdevice

normalerweise ist eine FirebirdSQL-Datenbank eine Datei, die mit wachsendem Inhalt der Datenbank immer grösser wird. Man kann aber einfach firebirdSQL anweisen eine ganze Partition für die Ablage der Datenbank zu verwenden. Die Datenbank-Grösse kann dann nur bis zur Partitions-Grösse anwachsen. Auf den Backup und Restore Prozess hat dies keinen Einfluss.

Eine Performance-Messung ergab praktisch identische Zugriffszeiten bei der Operation auf einer Partition im Vergelich zu einer Datei auf der selben Platte. Der Restore in die Partition hinein wurde mit 16 K Page Size durchgeführt.

Operation auf DRBD

DRkann eine Partition auf einen anderen REchner spiegeln. Host A wird zum Master, wenn ein Prozess auf Host A schreibend auf das Block-Device zugreift wird diese Änderung auf Host B per Netzwerk übertragen. Auch Host B ändert nun sein Abbild und beide Partitionen sind wieder gleich. Wir gewinnen einen gewissen Schutz beim Ausfall des Host A, dann können wir firebird auf Host B auf der Partition B starten.

Die Konfiguration

chkconfig --add drbd
cat /proc/drbd
  • resouce in /etc/drbd.conf auf beiden Systemen definieren
resource r0 {

  protocol A;
  meta-disk internal;
  device /dev/drbd1;

  on raib24 {
    disk /dev/sdb2;
    address 192.168.115.24:7789;
  }

  on raib30 {
    disk /dev/sdb1;
    address 192.168.115.30:7789;
  }

  syncer {
    rate 10M;
  }

}
  • Erstellen des /dev/drbd1
# 
# Ich hatte das Problem, dass die Partitionen leicht unterschiedlich gross waren.
# Irgendwie hat die, in der Doku angesprochene "size determination method" versagt,
# oder ich hatte die Aushandlungsphase versehentlich verhindert, da ich zunächst auf dem Primary
# ohne Kopplung auf den Secondary die Metadata bereits geschrieben habe. 
# Hier sollte noch eine Step by Step anleitung kommen, die die VErbindung
# VOR erzeugen der Metadaten setzt. Das wär' mir lieber!
# Ansonsten könnte man sagen
# Ich erstelle 2 PArtitionen, die einfach nur >=Size sind, danach setzte ich die Ursprünglich gedachte Size:
# -d, --disk-size size
# You can override DRBD's size determination method with this option. If you need to use the device before it was ever connected to its peer, use this option to pass the size of the DRBD device to the driver. Default unit is sectors (1s = 512 bytes). 
# If you use the size parameter in drbd.conf, we strongly recommend to add an explicit unit postfix. drbdadm and drbdsetup used to have mismatching default units. 

drbdadm create-md all
drbdadm -- --overwrite-data-of-peer primary all
# Ab hier kam ich in Probleme da ich beide Partitionen nicht genau gleicg gemacht hatte
# Egal was ich eingetragen hatte, irgend eine Rundung verwarf mir meine Angaben
# Es sind auch auf beiden Systemen nicht baugleiche Platten, so dass ich mir
# dieses Problem mit der Unterschiedlichen Partitions-Geometrie erkläre
# Es ging aber als ich die Sekundäre Partition etwas grösser machte, als die
# bereits "metadata" initialisierte primäre Partition. Es scheint so dass dann
# klaglos der Rest der Sekundären Partition unbenutzt bleibt.
# 
@Secundary> drbdadm secundary all

# Beim Restore einer DB mit gbak als root gab es kein Problem
# aber der Zugriff auf die Partition war dann Firebird in der Rolle als Remote-Prozess nicht
# möglich. Hier wird nämlich das Dateisystem (in dem Fall das Blockdevice System) in der Rolle des
# User "firebird" angesprochen. Gute Infos zu dieser Thematik gibt es hier:
# http://fghaas.wordpress.com/2007/06/04/using-drbd-directly-without-a-file-system/
# Versuch 1) ich habe die Rechte von /dev/drbd1 entsprechend angepasst!
#            @primary> chmod o+rw /dev/drbd1
#            das ging genau 1mal, aber nach den "close" durch firebird waren die Rechte wieder auf
#            Original-Zustand zurückgesetzt.
# Versuch 2) ich habe den owner von root auf "firebird" gesetzt, das ging wieder nicht lange gut
# Versuch 3) ich wollte "firebird" zur Gruppe "disk" hinzufügen, das klingt eigentlich toll,
#            aber wie geht das? Über die ganzen Befehle kam ich nicht zu Ziel.
#            Ich habe einfach die Datei /etc/group editiert:
# 
@primary> joe /etc/group

# Bei "disk" muss hinten der User "firebird" angehängt werden
#
disk:x:6:firebird
#

Usage with ZNS (a concept)

  • a firebird database is stored to a single file, all the data, tables and indexes share the same file
  • this concept is so clean, that you can even use a partition to store a database
  • Data is organized by fixed size Pages, there are different Page-types - for Row-Data, Index-Tables, or Metadata
  • firebird storage is optimized for typical blockdevice, open the file, read, append to the end, and update Pages
  • a firebird file can only grow, but there are unused pages within a firebird file, the more the older is the file

why ZNS for NVMe

  • NVMes are perfect Blockdevices for firebird? Yes, they seem to be, but internal they do a lot of work to keep expectations
  • They only emulate a perfect Blockdevice by the Housholding Algos of their internal Controller Software
  • Under the hood, there is dramatic action going on:
    • Reading Data ist not the problem, just works like reading Bits from a RAM Chip
    • Writing "new" Data to prior unused space is no Problem
    • Updating, or overwriting data is a Problem, internally this is not possible
    • Updating is done by erasing a Zone an writing it new from left to right
    • Updating n-Bytes can result in writing n*2*y-Bytes

Give NVMe more Info

  • If the OS would give more Information to the NVMe, Live for it could be much easier
  • The NVMe could avoid internal housholding writes, this is prelonging livetime
  • What Information is helpfull:
    • What data belongs to a file
    • When you start writing a file, please tell me its size (if known)
  • What breaks the "blockdevice" game
    • We must understand the "zone" Ecosystem
    • We must arrange data in Zones
    • forget random writes to files
    • remember the "artefacts", let the nvme do the garbage collect (by "simple copy")

The new Firebird Storagemode

Pages

  • Pages, from nowone can only be saved to the end of the file
  • Page Number 0 is not nessesarly on position 0 of the file
  • You must ask a "bitmap" layer to get the real position

Bitmap

  • We must implement a new "translating" level for PageNumbers
  • This persistent Datastructure maps Pagenumbers to the real world
  • It grows from 0.. , but data is interpreted from EOF..0
type 
 BitmapElement = record 
  PageNumber: int64;
  Zone: int64;
  Seek: int64;
  StopLookingBack: boolean;
 end;
 Bitmap = array of BitmapElement;
  • If you ask for a PageNumber you get a Zone and a Seek back
  • If you get no answer, you can assume Zone=0 and Seek=PageNumber
  • if StopLookingBack is true, do not trust older BitmapElements with this PageNumber

Page-Zones

  • In my Picture i will only look at the "Write"- Aspect of an NVMe, reading is done by magic!
  • Imagine a Data-Storage Room with hundreds of Tape-Recorders
  • One Tape is one Zone, the storage Controller can
    • erase an entire single tape by sending the command resulting in a "magnetic flash"
    • write data from 0..EOF the Tape, no update, no overwrite, only appending data until the tape is at its end
  • firebird should ask how big the Zone-Size is and use now Zones for writing the Pages of all kind
  • If a Page must be updated, do not write to the original file position of the page (no, dont use seek+write), append it to the actual End of the Database-file, this is in the highest
  • So we have an Old representation and a new in our Page-File - wich is the correct one?

Bitmap-Zones

  • With the help of a Bitmap-Datastructure firebird can calculate the true Position of Pages
  • With a "perfect" ordered Database-File the Bitmap is empty
  • If new or recently updated Pages grow the file the Bitmap grows.
  • firebird has to calculate PageNo+Bitmap -> ZoneNumber, SeekPosition
  • Even the Bitmap can only grow, there is no "updated" Bitmap-Data
  • A persistent Bitmap must be read from right to the left (from newly saved Data to older ones)
  • A newer Information about a Page-Position makes all the old-Data about Pages obsolet

simple copy

  • use NVMe "simple copy" to "garbage collect" bitmap and Page File

The Page-Storage

DDXXDXDDDDDXXXXX
  • D=actual real Page
  • X=artefact of an old now unused page
  • By reading old Parts of the Bitmap, firebird knows where artefacts live
  • with the NVMe simple copy command you can ...
    • move all the "D" to the append position
    • send the info that the hole zone is now free!
    • after such a "simple copy" the bitmap must mark the X Position as censored, that means a reserach and use of Position Data in old Bitmap Data is forbidden

The Bitmap-Storage

XXXBXBBBBBBXBBBBB
  • if you parse the entire Bitmap from rigth to left, before reaching "0", there is a Point P where you have all the information you need for the hole Picture
  • this is because some Information is "censored" and so, has no Information Content any more
  • so you can free 0..P, in our sample you can free XXX

this causes more corruption?

  • appending a new Pages? No risk
  • updating a page means
    • A: appending the page to the higest Page-Zone
    • B: appending Bitmap-Info about this page writing a Page to the and add this Information to the Bitmap
    • C (optional):a Page-Zones gets free, because the updated page was the last living object on that zone
    • D (optional):a Bitmap-Zone gets free, because a zone is complete censored know (by Step C)

-> if you ensure A+B+C+D inside an atomic transaction, if a file system can help, this is save

Verwendung mit PHP

Die Verwendung unter PHP ist möglich indem man die Extension "interbase" bereitstellt.

64-bit

Bekomme ich bei mir nicht zum laufen. Nach der Compilierung eines Mini-Programmes zur Abprüfung der existenz von libfbclient kann das Programm die Bibliothek nicht laden: "not compatible version of" ...

  • Traurig: Nach so vielen Jahren 64-Bit läuft das immer noch nicht!

32-bit

  • Vorbereitung


zypper install libxml2-devel
zypper install FirebirdCS-2.5.0.26054-ReleaseCandidate3.i686.rpm


  • Ermittle die PHP Versionsnummer, damit du weist welchen Source-Tar-Ball du ziehen must


php -v


  • Lade vom Museum die Source-Code Distribution des PHP, in diesem Beispiel hat die Versionsprüfung 5.1.0 ergeben


wget http://museum.php.net/php5/php-5.1.0.tar.gz
gzip -d php-5.1.0.tar.gz
tar -xf php-5.1.0.tar
cd php-5.1.0


  • Compiliere Dir selbst die Extension "interbase.so", ermittle zuvor den Installationspfad von firebirdsql, ab 2.5 heisst er z.B. nicht mehr "/opt/firebird" wie hier angegeben


./configure --with-interbase=shared,/opt/firebird
make


  • so, jetzt das Compilat noch PHP zur Verfügung stellen


cp modules/interbase.so /usr/lib/php5/extensions 


  • Nun reicht es, im Verzeichnis /etc/php5/conf.d die Datei interbase.ini anzulegen:


extension=interbase.so

[Interbase]
ibase.timestampformat=%m-%d-%Y %H:%M:%S


den Apache 2 neu starten

rcapache2 restart

Diagnose, ob jetzt das interbase Module geladen ist:

php --modules

auf Fehler in der folgenden Datei achten:

/var/log/apache2/error_log

Win32

Damit PHP auf Interbase/Firebird Datenbanken zugreifen kann, müssen die Routinen, die das ermöglichen, beim Start von PHP als Erweiterung geladen werden. Dies geschieht mit Hilfe zweier Einträge in der "php.ini". Erstens muss der Eintrag "extension_dir= " auf das Verzeichnis mit den Extension-Dlls gesetzt werden. Diese befinden sich standardmäßig im Verzeichnis "extensions". Falls PHP zum Beispiel in "C:\Programme\Php" installiert wurde, liegen die Erweiterungs-Dlls im Verzeichnis "C:\Programme\Php\extensions". Der Eintrag in der "php.ini" lautet dann:

  Win32
  extension_dir = "C:\Programme\Php\ext"
  Linux
  extension_dir = "/usr/lib/php/extension"

Zweitens gibt es in der "php.ini" einen Abschnitt, der sich "Dynamic Extensions" nennt. Dort sind alle Erweiterungen in der Form ";extension=php_....dll" aufgeführt. Da ein Semikolon am Anfang steht, beachtet PHP diese Zeile nicht als Eintrag sondern als Kommentar. In der Zeile ";extension=php_interbase.dll" muss dieses Semikolon nun entfernt werden.

  Win32
  extension=php_interbase.dll
  extension=php_gd2.dll
  Linux
  extension=interbase.so

Der WebShop erfordert, dass Timestamps im richtigen Format übernommen werden. Dies geschieht durch folgende zwei Zeilen, die am besten ans Ende der "php.ini" gestellt werden:

  [Interbase]
  ibase.timestampformat=%m-%d-%Y %H:%M:%S

Jetzt sollten die PHP-Routinen für die Interbase-Anbindung zur Verfügung stehen. Falls dies nicht so ist, liegt es vielleicht daran, das die "php.ini" im falschen Verzeichnis liegt (siehe Ende vorletztes Kapitel) oder der Pfad im Eintrag "extension_dir=" falsch gesetzt ist.

Achtung: Nach einer Änderung muss der Apache-Webserver mit "Startmenü\Alle Programme\Apache HTTP Server\Control Apache Server\Restart" neu gestartet werden.

Datensicherung

Unter Linux setzt firebird die Dateizugriffsrechte bei der erstellung der Datenbank-Datei auf

-rw-rw--- firebird firebird

das ist eher unpassend, da ich mit rsync die Dateien nun nicht lesen also auch nicht sichern kann. Die Maske müsste eher

chmod 664 sicherung_00000006.fdb

"664" lauten. Bisher hab ich noch nicht rausgefunden wie und wo man das ändern kann. Hat man alle firebird Datenbanken in einem Unterverzeichnis vereint, so kann man mit einem Befehl alle *.fdb Dateien korrekt anpassen.

cd /your-firebirdsql-database-root-path
chmod 664 `find -name *.fdb`

Parallele Dienstverarbeitung

Fragestellung: Im Mehrbenutzerbetrieb fallen Aufgabenstellungen an (Jobs). Wie kann man mehrere Arbeiter-Prozesse einsetzen, und deren Arbeit über eine Datenbank koordinieren? Insbesondere ist zu vermeiden, dass sich 2 Arbeiter den gleichen Job holen und abarbeiten.

Beispiele: eMail Versenden, oder an einem ARTIKEL-Datensatz eine Datenzelle Updaten!

Dazu muss eine Abfrage das Arbeitsvolumen ausgeben können, dieses wird pollend ausgeführt. Es sollten schon die "in Arbeit befindlichen" ausgeklammert werden. Entscheidet sich ein Arbeiter für einen Datensatz muss er diesen Datensatz für sich verlässlich exclusiv reservieren können, dabei wird sein eigener eindeutiger ~Kontext~ (in ARBEITER) und das Reservierungsdatum (in ZUGETEILT) eingetragen. Für jede Arbeit wird ein Verfallsdatum angegeben an der diese Reservierung wieder verfällt, die Aufhebung von Reservierungen macht ein globaler Arbeiter.

Nach dem ERFOLGREICHEN setzen des exclusiven (atomaren) Abstecken des Claim kann die Arbeit beginnen. Um den Streit (der immer eindeutig entschieden werden muss) zwischen den Arbeitern zu vermeinden soll jedem Arbeiter eine "Prämisse" mitgegeben werden, z. B. von "oben nach unten", oder "immer das Mittlere Element", oder von "unten nach oben" oder "RID DIV 5 = 3" usw. Ziel wäre es dass nicht unbedingt im an den aktuellen Anforderungen gearbeitet wird, sondern immer auch an ganz alten.

Ist die Arbeit erledigt so wird ein gewisser "Erledigt"-Status verbucht, der Datensatz ist dadurch nicht mehr "offen", so dass die "offene"-Selektion diesen Datensatz nicht mehr sieht. Auch für die verlorengegangenen Arbeiter ist dies dann unsichtbar.

Lösung

Von einem einzelnen Arbeiter-Thread werden immer folgende Arbeiten ausgeführt

  • Gibt es "offene" Sätze mit "ARBEITER=~Kontext~" -> arbeite diese ab bis leer
select RID from TICKET where
 (ART = 22) and
 (ARBEITER='V97XWY2Q6') and
 (BEENDET is null)

# 
# Ergibt sich hier ein Ergebnis wird dieser Job abgearbeitet
#


  • Ist die Arbeitsliste fertig: Gewisse Anzahl von Arbeiten für mich reservieren (atomar, multithread fest!)
update TICKET set
 ARBEITER = 'V97XWY2Q6',
 ZUGETEILT = CURRENT_TIMESTAMP
where
 RID= 
(
 select first 1
 RID 
from 
 TICKET 
where
 (ART = 22) and
 (ARBEITER is NULL)
)
  • Von einem Service-Thread werden ab und an folgende Arbeiten ausgeführt
    • Arbeiter-Punzen (in diesem Fall ARBEITER='V97XWY2Q6') deren Zuteilung zu lange her ist, und die noch nicht BEENDET sind: Feld ARBEITER leeren. Dadurch werden diese Jobs frisch zugeteilt.
    • Vollständig erledigte Vorgänge die weit zurückliegen löschen

GHOST - Attachements

Ich habe offene Verbindungen beobachtet (in MON$ATTACHEMENTS), die auch Transaktionen offen halten, und ich denke dadurch werden zahlreiche Record-Versions generiert. Dem Rechner wurde sogar inzwischen eine neue IP-Adresse zugewiesen und die Verbindung war immer noch offen. Problemlos war jedoch die Löschung der entsprechenden zeile in MON$ATTACHEMENT!


Ein Sweep blockiert dann die ARTIKEL Tabelle. Der Sweep ist sehr langsam.

Entwicklung dieses Fehlers

27.01.2012

heute hatten wir wieder die Störung der Art, dass ein Zugriff auf die ARTIKEL Tabelle langsam bzw. "ewig" dauert. Leider war diesmal kein schneller backup / restore Lauf mit der aktuellen Datenbank möglich. Wir hatten somit einen Blackout von gestern 15:03 bis 13:00 Uhr.

Ich habe etwas geforscht und nun herausgefunden, woran es NICHT liegt:

  • der Webshop hält in diesem Moment keine Verbindung offen
  • es besteht in diesem Moment keine offene Transaktion die alles andere blockiert
  • es liegt nicht an einer einzelnen Verbindung, so dass man nach Trennung dieser Verbindung sagen kann die Störung sei behoben
  • von der Festplatte kam keine Störungsignal, auch das Dateisystem ist OK

Ergebnis: Zugriff auf die ARTIKEL Tabelle ist möglich aber sehr sehr langsam, irgendein Problem scheint es hier zu geben. Ich ziehe den Datenbank Server auf Paris um, mit der firebird Version 2.1.4.

-> Nun meine Frage: Wer hat eine Idee / eine Vermutung was ursächlich sein könnte: Also war zwischen 11:20 und 12:00 Uhr irgend etwas ungewöhnlich? Jede Idee ist willkommen!

Hallo zusammen,

also die Datenbank läuft nun auf Paris (der Rechner in der Garage). Sie wird jede Stunde gesichert. Leider konnte ich meinen Plan nicht 100% durchsetzen: Anstelle der 2.1.4 Version MUSS ich 2.5.2 einsetzen, da es keine Weg zurück gibt. Mit Geldud und Spucke habe ich unsere "Crash" Datenbank doch noch sichern können: Das bedeutet wir verfügen auf Anfrage über einen Funktionierenden Spare, d.h. auch die ARTIKEL Tabelle ist beim Spare funktionsfähig - ich denke die Warenbewegungen müssen im Spare auch geprüft werden und in der aktuelle Datenbank nachgezogen werden ...

-> bis Montag!

07.02.2012

Hallo zusammen,

heute nacht ist beim geplanten Backup- Restore- Lauf das ARTIKEL-Problem aufgetreten. Wie beim letzten Mal funktionierte das Backup jedoch, aber nur gaaanz langsam. Wir haben keinen Datenverlust aber waren 23:00 - bis 2 Uhr offline. Wir wissen jetzt also dass "newyork" als Server in Ordnung ist. Das Problem tritt somit bei 2.5.1 und beim Snapshot (kommende 2.5.2 Version) auf und wurde also bisher nicht gelöst. Die Haltbarkeit einer Datenbank ist also im Moment so ca. 10 Tage, wir machen als Massnahme immer Montags einen Backup- Restore- Lauf. Ich versuche das zu automatisieren:

Webshop ausschalten. Alle OrgaMons rausschmeissen BAckup- Restore- newyork: xmlrpc starten Wien Starten London starten Webshop einschalten.

Hallo zusammen,

wie der Betreff schon ankündigt bin ich mir noch nicht 100% sicher. Es liegt am Transaktionsmodell des firebird Servers, in Verbindung mit einem "sweep" VErhalten das ich im Moment als Bug in firebird einstufe. Also die Ursache ist:

Ein von ARTIKEL abhängige Transaktion T1 startet, wird aber nicht beendet. In meinem Fall war dies *NICHT* der Shop sondern eine Arbeitsstation. Der Tagesabschluss hämmert auf ARTIKEL ein, Grund "Rang" Berechnung UND Lieferzeitberechung. Da T1 noch in der Luft hängt baut firebird eine künstliche Welt auf die für T1 so aussieht wie zum Startzeitpunkt von T1. Das resultiert in 180.000 "alten" Versionen der Records in ARTIKEL. Und das pro Tagesabschluss! Läuft nun dieser OrgaMom mehrere Tage *UND* wird dann beendet, wird es richtig Stressig für firebird: Alle Record-Versionen werden jetzt aufgeräumt -> Die Tabelle ARTIKEL hängt. Warum das aufräumen einerseits alle anderen Blockiert, andererseits mit 1% CPU Last durchgeführt wird ist für mich en Rätsel ...

-> ich leite Schritt für Schritt Massnahmen ein ...


15.02.2012

Ich habe heute ein Geister-Attachement gekillt (2 offene Transaktionen), dann sichergestellt dass alle OrgaMons frisch gestartet sind. Danach habe ich einen Sweep ausgeführt. Während des Sweeps (ca. 15 min) habe ich parallel immer mal wieder die Record-Versions geprüft. Die gingen im Verlauf "schnell" runter auf fast 0!

newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
   Average version length: 11.50, total versions: 313751, max versions: 25
newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
   Average version length: 11.50, total versions: 313751, max versions: 25
newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
   Average version length: 11.50, total versions: 313751, max versions: 25
newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
   Average version length: 11.41, total versions: 200754, max versions: 22
newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
   Average version length: 11.41, total versions: 195344, max versions: 22
newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
   Average version length: 11.41, total versions: 190157, max versions: 22
newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
   Average version length: 11.42, total versions: 153594, max versions: 22
newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
   Average version length: 11.77, total versions: 48805, max versions: 21
newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
   Average version length: 11.84, total versions: 38239, max versions: 21
newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
   Average version length: 11.97, total versions: 26478, max versions: 21
newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
   Average version length: 12.00, total versions: 19429, max versions: 21
newyork:~ # /opt/firebird/bin/gstat -r -t ARTIKEL prod.fdb | grep versions
   Average version length: 15.33, total versions: 6, max versions: 2

Bleibt zu klären, wer oder was offene Transaktionen hält!

16.02.2012

Ich versuche über das Produkt FB Trace-Manager von Thomas Steinmaurer zu ergründen wo offene Transaktion verbleiben. Ich hab' einige Zeit gebraucht zuerst mal zu verstehen was der Trace Manager überhaupt ist. Hier mal eine grundsätzliche Info:

  • ab firebird 2.5 kann ein Client über das Netzwerk zum firebird Datenbank-Server ein Text-Verbindung öffnen und sich Infos aus verschiedenen Bereichen wünschen. Also man wünscht sich Infos wenn eine neue Verbindung zustande kommt, oder wenn eine Transaktion gestartet oder beendet wird. Tritt auf dem Server dieses Ereignis ein, sendet er einen entsprechenden Text an den Client. Das Trace API ist also so eine Art remote logging Mechanismus, in den man sich einklinken kann, den man steuern kann. Das Trace-Interface ist Multi-User fähig!
  • Der FB-Trace-Manager bereitet den Roh-Text ordentlich auf und stellt ihn tabelarisch dar. Unnötige Infos lassen sich rausfiltern. Ob der Trace-Manager ein Tracking bestizt weis ich noch nicht ...

17.02.2012

i did not find the guilty left open statement by now, but we nearly can reproduce the error by now! We let OrgaMon be active after some work with it, after 24 h we had again 330.000 "versions" in the ARTIKEL Table (gstat -r). Then - I just closed this OrgaMon, firebird started clean up immediatly down to 14 versions! This took 12 Minutes.

At Monday we make the next test: I have now a Button in OrgaMon "commit W Transaction", where the User can do a "IBO.Transaction_W.CommitRetaining" manually to my gultiy W-Transaction, i give you feedback what happened ... (we have the situation under control! It is not any more in an emergency state yet! Thanks yery much for your help!)

20.02.2012

  • it is all clear now: On Form Opens a IB_Query because a Grid is linked. This form *never* makes a change. It it just like "select * from ARTIKEL", this is done inside my default transaction (the W-Transaktion!) This OrgaMon is now left open for a long time ...
  • Another OrgaMon makes "Tagesabschluss" and update ARTIKEL in the sense of "update ARTIKEL set LIEFERZEIT=null". This generates a lot of record versions because the long running orgamon did not make a commit ...

29.02.2012

Until Jason has a "silent commit and reopen on demand"- fix ready: Here is my workaround. it is a automatic cut-connection script wich is executed by OrgaMon automatically at noon.

  • OLAP Skript: "System.Tagwache.Verbindungen_trennen.OLAP.txt"
--
-- Skript zum Anzeigen / Beenden all zu langer Datenbankverbindungen
--

$SERVERS=('192.168.100.90','192.168.100.91','192.168.100.182')
$STUNDEN=8 

select 
 MON$$ATTACHMENT_ID,
 MON$$TIMESTAMP, 
 MON$$REMOTE_ADDRESS 
from 
 MON$$ATTACHMENTS
where
 (MON$$STATE=1) and
 ((CURRENT_TIMESTAMP - MON$$TIMESTAMP) > ($STUNDEN.0 / 24.0) ) and
 (MON$$REMOTE_ADDRESS not in $SERVERS)

save 
numeric MON$ATTACHMENT_ID
-

excel
save as html
-

nop
-

repeat

delete from MON$$ATTACHMENTS where (MON$$ATTACHMENT_ID=$RID)
-

28.01.2014

will den Fehler mal reproduzieren. recht aktueller Linux-Server 2.5.2 wird bereits genutzt.

  • OrgaMon öffen
  • die delikate Aktion im Tagesabschluss
  • prüfung mit Anzeige der Record-Versions
  • OrgaMon schliessen
  • prüfung der langsamen Abnahme der Record-Versions

firebird 3.0

  • Für die Zukunft ist ungewiss ob die Quellen des OrgaMon auf nativ Firebird 3.0 umgestellt werden
  • Es steht immer noch im Raum ev. auf Postgresql umzustellen
  • Als Zwischenlösung konnektiere ich erfolgreich mit dem OrgaMon in Verbindung mit einer firebird Client DLL 2.5.x auf einen Firebird 3.0 Server
#
# Einstellungen für erfolgreiches Konnektieren von 2.5 Clients
#
AuthServer = Legacy_Auth
AuthClient = Legacy_Auth
UserManager =  Legacy_UserManager
AllowEncryptedSecurityDatabase = false
WireCrypt = Enabled
WireCompression = false
RemoteAuxPort = 3051
DatabaseAccess = Restrict /srv/firebird

SYSDBA Passwort abändern

gsec -user SYSDBA -password masterkey -modify sysdba -pw MyKey37

Firebird Datenbank Crash?

   konkrete Verwendung einzelner Befehle für backup und restore.
   siehe ibreorg.bat in der Anlage. (der ist leider für 32-DOS-Box!)
   die Befehle müssen auch unter linux so gehen. der Pfad ist aber

   /opt/interbase/bin/gbak ....

   --- snip
   @echo off
   REM -------------------------------------------------
   REM Reparatur einer inkonsistenten FireBird Datenbank
   REM
   REM (c) Andreas Filsinger, www.orgamon.org
   REM -------------------------------------------------
   REM
   REM Usage
   REM
   REM reorg <Pfad und Name der Datenbank OHNE ".gdb">
   REM
   REM --------------------------------------------
   REM
   REM ACHTUNG: richtigen Pfad ermitteln, indem Sie nach der
   REM          Datei gbak.exe suchen lassen. Und hier eintragen:
   REM
   SET IBBIN=D:\programme\borland\interbase\bin\
   REM
   REM --------------------------------------------
   REM 1) fix erros
   REM
   %IBBIN%gfix -mend -full -ignore -user "SYSDBA" -password "masterkey" %1.fdb
   REM --------------------------------------------
   REM 2) backup fixed base
   REM
   %IBBIN%gbak -backup -v -ignore -garbage -user "SYSDBA" -password "masterkey" %1.fdb %1_neu.fbak
   REM --------------------------------------------
   REM 3) restore base
   REM
   REM zusätzlich noch "-i" wenn Indizes deaktiviert werden sollen
   REM
   %IBBIN%gbak -r -v -p 16384 -user "SYSDBA" -password "masterkey" %1_neu.fbak %1_neu.fdb
   REM --------------------------------------------
   REM 4) check new one
   REM
   %IBBIN%gfix -v -f -user "SYSDBA" -password "masterkey" %1_neu.fdb
   REM --------------------------------------------
   --- snap
   Bemerkungen
   ===========
   a) Backup-möglich aber fail beim Restore: wegen inkonsistenter Indizes
   ich habe mal erlebt, das foreign Key nicht mehr konsistent waren, und deshalb
   der restore abgebrochen hat. Alle Indizes kann man jedoch als inaktiv restoren,
   (Option -i )
   nach löschen /clearen der "Schuldigen" kann man alle indizes wieder aktivieren,
   wieder ein backup, wieder ein restore -> alles wieder gut.
   damit der OrgaMon alle indizes sehen kann braucht er "out.txt". Das ist die
   Ausgabe eines erfolgreichen restores, der alle indizes enthält.
   Unter linux gibt man die Ausgabe von gbak mit 2>/freigabe/out.txt in eine Datei
   aus.
   firebird-Erkenntnis
   ===================
   internal gds software consistency check (partner index description not found (175))
   dieser Fehler tritt beim löschen eines Datensatzes auf, der eventuell durch einen
   foreign key einer anderen Tabelle referenziert werden könnte. Ist dieser key
   deaktiviert so kann keine Aussage getroffen werden, ob das löschen ok ist, dieser
   interne Fehler ist die Folge!!

Page Type Error

Behebung des Fehlers "Wrong page type":

Backup ist nicht mehr möglich

Beobachtung:

tokio:/srv/smb/fdb # gbak -b -g -ig -user sysdba -password **** /srv/smb/fdb/k-prod.fdb k-prod.fbak
gbak: ERROR:database file appears corrupt (/srv/smb/fdb/k-prod.fdb)
gbak: ERROR:    wrong page type
gbak: ERROR:    page 136509 is of wrong type (expected 4, found 5)
gbak: ERROR:gds_$compile_request failed
gbak:Exiting before completion due to errors

Auch mit der Option -mend : kein Erfolg

GFix ist nicht mehr möglich

Beobachtung:

tokio:/srv/smb/fdb # gfix -v -f -user sysdba -password * /srv/smb/fdb/k-prod.fdb
Summary of validation errors
       Number of pointer page errors   : 1
       Number of database page errors  : 28

IBAid "Repair" hat keine Wirkung

  • der Direct Fix läuft durch und erweckt den Eindruck dass er das Problem gelöst hätte
  • After the "fix", i did the suggested final steps: There were the known, old errors, finally gbak fails!


server:/srv/firebird/prod # gfix -v -full -user sysdba -password **** /srv/firebird/prod/k-prod.fdb
Summary of validation errors
       Number of pointer page errors   : 1
       Number of database page errors  : 28
server:/srv/firebird/prod # gfix -mend -ig -user sysdba -password **** /srv/firebird/prod/k-prod.fdb
Summary of validation errors
       Number of pointer page errors   : 1
       Number of database page errors  : 28
server:/srv/firebird/prod # gbak -b -g -ig -user sysdba -password **** /srv/firebird/prod/k-prod.fdb k-prod.fbak
gbak: ERROR:database file appears corrupt (/srv/firebird/prod/k-prod.fdb)
gbak: ERROR:    wrong page type
gbak: ERROR:    page 136509 is of wrong type (expected 4, found 5)
gbak: ERROR:gds_$compile_request failed
gbak:Exiting before completion due to errors

IBAid "Exract" bringt die Lösung

1) Beende alle Datenbank-Dienste und stelle die fdb bereit
2) Erstelle aus dieser defekten fdb eine leere fdb gleicher Metadatenstruktur

gbak -b -m -user sysdba -password ***** /srv/firebird/prod/2/l-prod.fdb l-prod.fbak
gbak -v -r -p 16384 -user sysdba -password ****** l-prod.fbak empty-prod.fdb

3) Starte IBAid und gehe direkt über den Wizzard
 "Extract" <Next>
 danach im Wesentlichen die Standard-Optionen
 lege die empty-.fdb auf deinen firebird server und geben die Connect Daten an
 
4) Es folgt dann das befüllen der fdb durch IBAid
dieser Vorgang hat in meinem Fall 7 Stunden gedauert

table id n is not defined (invalid service handle)

  • Kommt beim Backup einer Datenbank "table id * is not defined gds_$compile_request failed" so blockiert eine Verbindung, die Zugriff auf die $CLUB Tabellen hatte, dass firebird wieder in einen konsistenten Zustand kommt.
    • Die $CLUB Tabellen sind temporäre Tabellen, die bei der Geolokalisierung verwendet werden um die aktuellen "Geolokalisierungs-Punkte" zu einer Gruppe/Club zusammenzufassen.
    • Die Verbindung/Transaktion ensteht am Tag durch Arbeiten am Geo-Arbeitsplatz. Der Tagesabschluss löscht dann "alte" $CLUB Tabellen, dadurch ensteht ein Konflikt.
  • In der Folge zeigt das Backup-Programm in einer Endlosschleife an: invalid service handle
  • Vorbeugend sollten "solche" langen Laufzeiten von Verbindungen vermieden werden (lang laufende Transaktionen)

Lösung:

Neustart den Datenbank-Servers:
===============================

systemctl stop firebird-superserver.service
systemctl start firebird-superserver.service

Scrub & Reboot

  • Nach 3 wöchiger extensiver Nutzung hilft es, die Datenbank neu zu erzeugen und den DB-Server neu zu starten
  • Es konnte nachgewiesen werden, dass sich unerklärbare Instabilitäten dadurch verringern lassen
  • Das folgende Script wird wöchentlich (z.B. Mittwochs 02:00 Uhr) ausgeführt
  • Die Schritte sind
    • Ausschalten aller "Gateways" zur Datenbank die Änderungen an der Datenbank auslösen könnten (z.B. php-Scripte via Webserver)
    • Ausschalten aller VMs, die eine Datenbankverbindung aufbauen (10 Sek. warten bis die VM runtergefahren ist)
    • Ausschalten des Datenbank-Dienstes an sich, nun stürzen alle laufenden OrgaMon-Anwendungen ab, nun werden alle Ghost-Attachements an die Datenbank gekappt, nun werden alle hängenden Transaktionen und Locks beendet
    • Verschieben der Datenbank-Datei, mit neuem Namen, sodass nicht reconnected werden kann
    • Backup der DB danach Restore der DB aus dem frischen Backup in eine nagelneue Datei mit "bekanntem", "alten" Namen (vollständiger Scrub)
    • Anpassung der Zugriffsrechte
    • Dateisystem-Sync und Reboot des ganzen Servers
#!/bin/bash
#
# /root/full-server-restart.sh
#
# (c) 2022 Andreas Filsinger
#
#

systemctl stop vsftpd
systemctl stop nginx
systemctl stop VirtualBox@WIN7
sleep 10
systemctl stop firebird-superserver

PROD=firma.fdb
BAND=$(date +"%Y%m%d-%H%M%S")

#
# move the productive .fdb , so nobody can connect
#
mv /srv/firebird/$PROD /srv/firebird/$BAND.fdb

#
# backup
#
/usr/local/firebird/bin/gbak -V -USER SYSDBA -PASSWORD * /srv/firebird/$BAND.fdb /srv/firebird/$BAND.fbak

#
# restore to prod
#
/usr/local/firebird/bin/gbak -R -V -P 16384 -USER SYSDBA -PASSWORD * /srv/firebird/$BAND.fbak /srv/firebird/$PROD
chmod 777 /srv/firebird/$PROD
chgrp firebird /srv/firebird/$PROD
chown firebird /srv/firebird/$PROD

#
# backup is not longer needed
#
rm /srv/firebird/$BAND.fbak

sync
reboot
  • ACHTUNG: Um eine Situation zu vermeiden, dass Backup und Restore nicht gelingen und man dann ohne eine Datei dasteht wird die Original .fdb Datei NICHT gelöscht
    • Pro Woche entsteht hier eine zurückbleibende .fdb Datenbank-Datei, die manuell gelöscht werden muss

Backup / Restore

#!/bin/sh 

#
# parameter customize
#
NAMESPACE=yourname
DBPWD=********
 
#
# JJJJ-MM-DD
#
BAND=$(date +%Y-%m-%d)

#
# backup
#
rm $NAMESPACE-$BAND.fbak
/opt/firebird/bin/gbak -V -B -USER SYSDBA -PASSWORD $DBPWD $NAMESPACE.fdb $NAMESPACE-$BAND.fbak

#
# restore
#
rm $NAMESPACE-$BAND.fdb
/opt/firebird/bin/gbak -V -R -P 16384 -USER SYSDBA -PASSWORD $DBPWD $NAMESPACE-$BAND.fbak $NAMESPACE-$BAND.fdb
chown firebird $NAMESPACE-$BAND.fdb
chgrp firebird $NAMESPACE-$BAND.fdb

#
# clean-up
#
rm $NAMESPACE-$BAND.fbak

#
#
#

Charset

  • der Charset ist im Moment noch "NONE", ist implizit aber eigentlich "ISO8859_1"
update 
 RDB$$DATABASE 
set 
 RDB$$CHARACTER_SET_NAME='ISO8859_1'

FileCreate 660

  • fdb Dateien werden mit den Recht 660 angelegt, manchmal kann ein Client die Datenbank-Datei dann nicht löschen
  • auf dem Server, der das Share /srv/firebird freigibt
#
# "nobody" wird in die Gruppe "firebird" verbracht
#
usermod -a -G firebird nobody

Prüfen

joe /etc/group
#
# Es muss eine Zeile geben
#
firebird:x:495:nobody

UTF8-Migration

create database 'orgamon.fdb' default character set UTF8 collation de_de;

create table PERSON (
 RID int64 not null primary key,
 last_name  varchar (50),
 first_name varchar (50));

Links