How to Run Multiple Instances of Firebird Server

0
1570

Firebird is a relational database that runs on Linux, Windows and many UNIX platforms, and is commercially independent. It has been developed by C and C++ programmers in association with technical advisors and supporters to develop on the source code released by Borland Software Corp.

If it’s the first time that you’re reading about Firebird, then here’s what you should know — Firebird technology has been in use for 20 years, which makes it a very mature and stable product. It’s a fully featured RDBMS that can handle databases ranging in size from just a few KB to many gigabytes, with good performance, and it is almost maintenance-free. Another cool thing about Firebird is that the installer size usually is less than 7MB (depending on the OS) and it is fully automated. This might leave some of us thinking that Firebird can only be used with just small databases and a few connections. You’re totally mistaken! It is used with many big databases and lots of connections.

Firebird comes with a full set of command line utilities that allow you to create databases, retrieve database statistics, run SQL commands and scripts, perform backups and restores, etc. If you prefer to use a GUI (graphical user interface) tool, there are lots of options to choose from.

The Firebird server comes in four flavours: SuperServer, Classic, SuperClassic and Embedded. If you are a newbie, I’d recommend you to start with SuperServer. Right now, Classic is recommended for use with SMP machines and some other specific situations. SuperServer shares its cache among the database connections, and it uses threads to handle each connection. It is a multi-threaded, multi-client architecture that requires few resources when additional connections are spawned off.

Resource allocation and lock management are much more efficient in the SuperServer architecture, because separate processes do not have to wait for others to finish before they can be addressed. Classic starts an independent server process for each connection made, while SuperClassic offers a multi-threaded single process server with an independent cache for each connection. One awesome feature about Firebird is that it allows you to run multiple servers on a single machine — for example, when you want to test a new version of Firebird or when you have different applications using different server versions and you want to use only one server machine, or if your testing/integration database is running on the same environment as your production database (this is usually not preferable, but you may require such a setup to cut costs).

Here’s a quick guide on how that can be achieved in Firebird 3.0. The same procedure is applicable to other versions of Firebird as long as you want to use the Classic Server. Mixing different versions should also work, because the required libraries will all be isolated in single directories.

Step 1: Installation and setup
Once you’re done with installation, you will have two separate Firebird 3.0 instances in your machine. Let’s call them firebird01 and firebird02, with two different fb_inet_server executables. To distinguish between them further, let’s name their executables as fb_inet_server01 and fb_inet_server02 respectively. Firebird01 will listen on standard Firebird Port 3050 and firebird02 will listen on Port 3060, as shown below.

First, visit the official Firebird site and download the desired package. I chose Firebird-3.0.4.33054-0.i686.tar.gz.
We will need some dependencies such as libstdc++5 in Ubuntu 10.10 Maverick. One can do apt-get to install it. Once you extract the package, you will find a file called buildroot.tar.gz, which holds all the files needed to get the Firebird 3.0 server up and running. After extraction, extract FirebirdCS-3.0.4.33054-0.i686/buildroot.tar.gz and copy the FirebirdCS-3.0.4.33054-0.i686/opt/firebird over to /opt/firebird01.

root@host:/root# tar xzvf FirebirdCS-3.0.4.33054-0.i686.tar.gz
FirebirdCS-3.0.4.33054-0.i686/
FirebirdCS-3.0.4.33054-0.i686/scripts/
FirebirdCS-3.0.4.33054-0.i686/scripts/tarMainInstall.sh
FirebirdCS-3.0.4.33054-0.i686/scripts/postuninstall.sh
FirebirdCS-3.0.4.33054-0.i686/scripts/preinstall.sh
FirebirdCS-3.0.4.33054-0.i686/scripts/preuninstall.sh
FirebirdCS-3.0.4.33054-0.i686/scripts/taruninstall.sh
FirebirdCS-3.0.4.33054-0.i686/scripts/postinstall.sh
FirebirdCS-3.0.4.33054-0.i686/scripts/tarinstall.sh
FirebirdCS-3.0.4.33054-0.i686/scripts/rpmfiles.txt
FirebirdCS-3.0.4.33054-0.i686/scripts/tarMainUninstall.sh
FirebirdCS-3.0.4.33054-0.i686/scripts/rpmheader.txt
FirebirdCS-3.0.4.33054-0.i686/install.sh
FirebirdCS-3.0.4.33054-0.i686/buildroot.tar.gz
FirebirdCS-3.0.4.33054-0.i686/manifest.txt
root@host:/root# cd FirebirdCS-3.0.4.33054-0.i686/
root@host:/root/FirebirdCS-3.0.4.33054-0.i686# tar xzvf buildroot.tar.gz
./
./opt/
./opt/firebird/
./opt/firebird/misc/
./opt/firebird/misc/upgrade/
./opt/firebird/misc/upgrade/ib_udf/
./opt/firebird/misc/upgrade/ib_udf/ib_udf_upgrade.sql
./opt/firebird/misc/upgrade/ib_udf/ib_udf2_params.txt
./opt/firebird/misc/upgrade/ib_udf/ib_udf_params.txt
./opt/firebird/misc/upgrade/metadata/
./opt/firebird/misc/upgrade/metadata/metadata_charset.txt
./opt/firebird/misc/upgrade/metadata/metadata_charset_drop.sql
./opt/firebird/misc/upgrade/metadata/metadata_charset_create.sql
./opt/firebird/misc/upgrade/security/
./opt/firebird/misc/upgrade/security/security_database.sql
./opt/firebird/misc/upgrade/security/security_database.txt
./opt/firebird/misc/intl.sql
./opt/firebird/misc/firebird.xinetd
./opt/firebird/UDF/
./opt/firebird/UDF/ib_udf.sql
./opt/firebird/UDF/ib_udf.so
./opt/firebird/UDF/fbudf.sql
./opt/firebird/UDF/ib_udf2.sql
./opt/firebird/UDF/fbudf.so
./opt/firebird/WhatsNew
./opt/firebird/aliases.conf
....... TOO MUCH OUTPUT .......
root@host:/root/FirebirdCS-3.0.4.33054-0.i686# mkdir /opt/firebird01
root@host:/root/FirebirdCS-3.0.4.33054-0.i686# cp -R opt/firebird/* /opt/firebird01/

Now that your Firebird directory has been created, we can check if the dependencies for lifbclient are met. Run ldd in libfbclient.so.3.0.4 inside the /opt/firebird01/lib you just created. As long as you don’t come across anything such as not found, you are good.

root@host:/opt/firebird01/lib# ldd libfbclient.so.3.0.4
linux-gate.so.1 => (0x00635000)
libm.so.6 => /lib/libm.so.6 (0x00110000)
libdl.so.2 => /lib/libdl.so.2 (0x006f9000)
libncurses.so.5 => /lib/libncurses.so.5 (0x00a46000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00281000)
libc.so.6 => /lib/libc.so.6 (0x0029b000)
/lib/ld-linux.so.2 (0x00f59000)

Now, we need to add a new user called firebird, which we will use to run the Firebird server:

root@host:/# groupadd firebird
root@host:/# useradd -d /opt/firebird01 -s /bin/false -c “Firebird Database Owner” -g firebird firebird

Step 2: Setting up the first environment
Firebird needs to have a default password set for the SYSDBA user, which is the admin user of the Firebird server. To set this up, use the following code:

root@host:/opt/firebird01/lib# export FIREBIRD=/opt/firebird01/
root@host:/opt/firebird01/lib# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/firebird01/lib/
root@host:/opt/firebird01/lib# cd ../bin
root@xubuntu:/opt/firebird01/bin# ./gsec
GSEC> modify SYSDBA -pw masterkey
Warning - maximum 8 significant bytes of password used
GSEC> quit

Let’s make a copy of the working environment:

root@host:/opt# cd /opt
root@host:/opt# cp firebird01/ firebird02/ -R

Now, let’s change the names of the executables in both directories:

root@host:/opt# mv firebird01/bin/fb_inet_server firebird01/bin/fb_inet_server01
root@host:/opt# mv firebird02/bin/fb_inet_server firebird02/bin/fb_inet_server02

So, moving forward, let’s set up xinetd to start the right server, depending on which port the server receives incoming connections from.

Step 3: Xinetd
Now we have two separate installations of the Firebird 3.0.4 Classic Server. The next step will be to set up xinetd to associate different ports with different Firebird servers.
Xinetd is a connection manager, a so-called Super Internet Server, which will launch a specified server only when a user is trying to connect to a specified port. For instance, if you have an ftp server set up that is listening on Port 21, when a connection is being made to Port 21, xinetd will launch the service associated with this port. Let’s look into the following example for more clarity.
Let’s first create the Firebird service entry. Therefore, open up /etc/services. Remove the following two lines:

gds_db 3050/tcp # InterBase server
gds_db 3050/udp

Add the above two lines to the end of the following file.

# Local services
firebird01 3050/tcp # Firebird01
firebird01 3050/udp
firebird02 3060/tcp # Firebird02
firebird02 3060/udp

Now we’ll have to specify what xinetd should start when a connection attempt is being made to port 3050 or 3060. Therefore, let’s create two files: /etc/xinet.d/firebird01 and /etc/xinet.d/firebird2.
These will hold the definitions for xinetd for these services.

service firebird01
{
flags = REUSE
socket_type = stream
wait = no
user = firebird
server = /opt/firebird01/bin/fb_inet_server01
env =FIREBIRD=/opt/firebird01
env +=LD_LIBRARY_PATH=/opt/firebird01/lib:LD_LIBRARY_PATH
disable = no
}
service firebird02
{
flags = REUSE
socket_type = stream
wait = no
user = firebird
server = /opt/firebird02/bin/fb_inet_server02
instances = UNLIMITED
env =FIREBIRD=/opt/firebird02
env +=LD_LIBRARY_PATH=/opt/firebird02/lib:LD_LIBRARY_PATH
disable = no
}

We now have the services ports defined in /etc/services and we’ve got two xinetd definitions in /etc/xinetd.d/. To verify your setup for xinetd, you can try to restart xinetd and check the log xinetd creates in /var/log/daemon.log. If you see two available services, it means you’ve successfully set up xinetd.

root@host:/# /etc/init.d/xinetd restart
* Stopping internet superserver xinetd [ OK ]
* Starting internet superserver xinetd [ OK ]
root@host:/# tail -f /var/log/daemon.log
18 19:28:49 xubuntu xinetd[19919]: removing daytime
18 19:28:49 xubuntu xinetd[19919]: removing daytime
18 19:28:49 xubuntu xinetd[19919]: removing discard
18 19:28:49 xubuntu xinetd[19919]: removing discard
18 19:28:49 xubuntu xinetd[19919]: removing echo
18 19:28:49 xubuntu xinetd[19919]: removing echo
18 19:28:49 xubuntu xinetd[19919]: removing time
18 19:28:49 xubuntu xinetd[19919]: removing time
18 19:28:49 xubuntu xinetd[19919]: xinetd Version 3.0.4 started with libwrap loadavg options compiled in.
18 19:28:49 xubuntu xinetd[19919]: Started working: 2 available services

The only one thing that’s left is the firebird.conf file in which the port Firebird should listen on. We need to set the following ports to the config files created:

In /opt/firebird01/firebird.conf:
# RemoteServicePort = 3050
to
RemoteServicePort = 3050
In /opt/firebird02/firebird.conf:
# RemoteServicePort = 3050
to
RemoteServicePort = 3060

Now, you can try to connect to the two separate Firebird servers using telnet. If you get something like what’s shown below, then you are good:

root@host:/# telnet localhost 3050
Trying::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.``

Connection closed by foreign host
root@host:/# telnet localhost 3060
Trying::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

Connection closed by foreign host

Some people often wonder why they need to make the effort to switch to a new database when they are already familiar with PostgreSQL or MySQL. As a matter of fact, the latter are the two data base management systems (DBMSs) taught in CS related courses in universities and training institutions. I’d say Firebird is worth the effort to migrate from the legacy DBMSs since it offers a smooth migration path from a closed source, commercial database to an open source database. If you are already familiar with any of the popular RDBMSs, then the transition to Firebird is smooth since it offers virtually all the features available in high-end databases without much impact on the performance. If you’re looking for a database for your project, then you ought to try Firebird.

LEAVE A REPLY

Please enter your comment!
Please enter your name here