IntroductionThose DBAs who are experts in one database system look for other database systems to have “similar features”. It is a human tendency to look at any new technology and compare it with a world they are familiar with. Most of the time, I keep addressing Oracle DBAs who are looking for similar features or setup in PostgreSQL, but this time it is for MySQL DBA. MySQL historically ships mysqld_multi to manage multiple instances of MySQL on a server. Even though this is not a core feature in MySQL, but rather a wrapper, I understand that it is something widely used and my colleague Fernando blogged about it.
In a discussion a few months back, one of my friends asked how PostgreSQL manages multiple instances and I agreed to write on that as it will be useful for anyone who looks for a similar setup. In short, the answer is that the PostgreSQL community manages it using wrapper scripts and the Linux service manager. During this time, systemd started becoming a standard among Linux distros and every Linux package started relying on it for service management. To my surprise, some of the MySQL packages started removing mysqld_multi from the bundle and started moving towards systemd as the way to manage multiple instances. So everything is getting converged to systemd in the new world. In this blog, I want to show how this can be done on Ubuntu/Debian Linux because all necessary wrapper scripts already exist on those distros as part of postgres-common package which gets installed by default with every PostgreSQL installation. Nothing prevents us from doing a similar wrapper on other Linux distros also.
|
1 |
$ dpkg -l | grep postgresql-common<br>ii postgresql-common 201.pgdg18.10+1 all PostgreSQL database-cluster manager |
The default installation of PostgreSQL from apt repo of postgresql.org will contain postgresql-common backage for Debian/Ubuntu.
|
1 |
$ sudo apt install postgresql-11<br>Reading package lists... Done<br>...<br>The following additional packages will be installed:<br> libllvm7 libpq5 libsensors4 pgdg-keyring postgresql-client-11 postgresql-client-common postgresql-common ssl-cert sysstat<br>Suggested packages:<br>... |
By default, a PostgreSQL instance/cluster will be created with name “main” which uses the default port of PostgreSQL 5432.
|
1 |
$ pg_lsclusters<br>Ver Cluster Port Status Owner Data directory Log file<br>11 main 5432 online postgres /var/lib/postgresql/11/main /var/log/postgresql/postgresql-11-main.log<br> |
All the configuration files including the PostgreSQL parameter file sits under the /etc/postgresql directory.
|
1 |
$ ls -R /etc/postgresql<br>/etc/postgresql:<br>11<br><br>/etc/postgresql/11:<br>main<br><br>/etc/postgresql/11/main:<br>conf.d environment pg_ctl.conf pg_hba.conf pg_ident.conf postgresql.conf start.conf<br><br>/etc/postgresql/11/main/conf.d:<br> |
postgres-common gives a wrapper pg_ctlcluster which is wrapper on the top of pg_ctl
|
1 |
$ pg_ctlcluster 11 main status<br>pg_ctl: server is running (PID: 15544)<br>/usr/lib/postgresql/11/bin/postgres "-D" "/var/lib/postgresql/11/main" "-c" "config_file=/etc/postgresql/11/main/postgresql.conf"<br> |
However, many of the files including security certificates are accessible only by the root user. The integration with systemd allows an easy solution to start and stop as follows:
|
1 |
$ sudo systemctl start postgresql@11-main<br>$ sudo systemctl stop postgresql@11-main |
Adding a new PostgreSQL is as simple as executing pg_createcluster with the version of the PostgreSQL and clustername.
|
1 |
$ pg_createcluster 11 standby1<br>Creating new PostgreSQL cluster 11/standby1 ...<br>/usr/lib/postgresql/11/bin/initdb -D /var/lib/postgresql/11/standby1 --auth-local peer --auth-host md5<br>The files belonging to this database system will be owned by user "postgres".<br>This user must also own the server process.<br><br>The database cluster will be initialized with locale "en_US.UTF-8".<br>The default database encoding has accordingly been set to "UTF8".<br>The default text search configuration will be set to "english".<br><br>Data page checksums are disabled.<br><br>fixing permissions on existing directory /var/lib/postgresql/11/standby1 ... ok<br>creating subdirectories ... ok<br>selecting default max_connections ... 100<br>selecting default shared_buffers ... 128MB<br>selecting dynamic shared memory implementation ... posix<br>creating configuration files ... ok<br>running bootstrap script ... ok<br>performing post-bootstrap initialization ... ok<br>syncing data to disk ... ok<br><br>Success. You can now start the database server using:<br><br> pg_ctlcluster 11 standby1 start<br><br>Warning: systemd does not know about the new cluster yet. Operations like "service postgresql start" will not handle it. To fix, run:<br> sudo systemctl daemon-reload<br>Ver Cluster Port Status Owner Data directory Log file<br>11 standby1 5433 down postgres /var/lib/postgresql/11/standby1 /var/log/postgresql/postgresql-11-standby1.log<br> |
Now let us examine the above output and understand what is happening:
The automatic values taken by pg_clustercreate can be overridden by specifying explicit values as a parameter as follows:
|
1 |
$ pg_createcluster 11 anotherdb -d /home/postgres/adb -p 5439 |
The above command will create a PostgreSQL 11 instance with name “anotherdb” with data directory at /home/postgres/adb and listening at TCP/IP port 5439.
The start command for pg_ctlcluster shows a more reliable way to start the same instance using systemd.
|
1 |
$ pg_ctlcluster 11 anotherdb start<br>Warning: the cluster will not be running as a systemd service. Consider using systemctl:<br> sudo systemctl start postgresql@11-anotherdb<br> |
Stopping the instance also can be done in either way. For example:
|
1 |
pg_ctlcluster 11 anotherdb stop |
or
|
1 |
sudo systemctl stop postgresql@11-anotherdb |
So far we have seen instances of the same version, but we are not limited to the same version. If we need to create an instance of other PostgreSQL version, we just need to install the PostgreSQL binaries for the same.
|
1 |
$ sudo apt install postgresql-10 |
Just like the PostgreSQL 11 version discussed, this also will create a “main” instance/cluster by default.
|
1 |
Ver Cluster Port Status Owner Data directory Log file<br>10 main 5434 online postgres /var/lib/postgresql/10/main /var/log/postgresql/postgresql-10-main.log<br> |
We can add more clusters using the new version:
|
1 |
$ pg_createcluster 10 pg10test |
Now running pg_lscluster reveals all the postgresql instances running:
|
1 |
$ pg_lsclusters<br>Ver Cluster Port Status Owner Data directory Log file<br>10 main 5434 online postgres /var/lib/postgresql/10/main /var/log/postgresql/postgresql-10-main.log<br>10 pg10test 5435 online postgres /var/lib/postgresql/10/pg10test /var/log/postgresql/postgresql-10-pg10test.log<br>11 anotherdb 5439 online postgres /home/postgres/adb /var/log/postgresql/postgresql-11-anotherdb.log<br>11 main 5432 online postgres /var/lib/postgresql/11/main /var/log/postgresql/postgresql-11-main.log<br>11 standby1 5433 online postgres /var/lib/postgresql/11/standby1 /var/log/postgresql/postgresql-11-standby1.log<br> |
The major difference is that postgres-common tools keep all configurations in a directory structure under /etc/postgres, while MySQL world deals with single configuration files with multiple sections as documented. For example all the configuration files for PostgreSQL 11 instance “anotherdb” will be under: /etc/postgresql/11/anotherdb. There are mainly 3 configuration files which decide the behavior of service:
|
1 |
$ ls -R /etc/postgresql/11/standby1<br>/etc/postgresql/11/standby1:<br>conf.d environment pg_ctl.conf pg_hba.conf pg_ident.conf postgresql.conf start.conf<br> |
Resources
RELATED POSTS