The PostgreSQL database server contains many Assert
statements in its code. These statements are additional checks that can be evaluated to ensure that the performed operations are executeed as expecteed. However, evaluating of these statements takes some CPU time. Therefore, they are disabled in most production environments.
PostgreSQL is a very extensible and pluggable software. The PostgreSQL server can be extended by extensions. These PostgreSQL Extensions can use Asserts statements in the code.
Such a statement looks as follows:
Assert(state->number_of_rows >= 0);
The Assert statements are implemented as C Macros. If the condition is fulfilled, nothing happens. If the condition is not met, the software is interrupted and an error message is logged.
These Assert macros are defined in the file /usr/include/postgresql/12/server/c.h
:
#ifndef USE_ASSERT_CHECKING
#define Assert(condition) ((void)true)
[...]
#elif defined(FRONTEND)
[...]
#define Assert(p) assert(p)
[...]
#else
[...]
#define Assert(condition) Trap(!(condition), "FailedAssertion")
#endif
As can be seen in the listing, the Assert macro are only active if the USE_ASSERT_CHECKING
option is set (or FRONTEND
code is compiled). Otherwise, the Assert macro is replaced by true
statements at compile time, which disables the evaluation of the Assert conditions.
To check whether the current PostgreSQL installation evaluates Assert statements or not, the following command can be executed:
grep USE_ASSERT_CHECKING /usr/include/postgresql/12/server/pg_config.h
If this returns a value of 1
, the assertions are active. In addition, all extensions that are complied against this server are also evaluate the Assert statements.
Recompiling the PostgreSQL with
If the check above returns 0
, the PostgreSQL server needs to be recompiled. If a Debian-based distribution is used, it is a good idea to modify and replace the existing Debian package. This will then behave exactly like the original Debian package (e.g., the distribution’s own patches and changes are included) with the only difference that the assert statements are checked.
To rebuild the PostgreSQL package, the source repositories must be included in the /etc/apt/sources.list
file. Depending on whether the package is used from the Debian distribution or from the PostgreSQL Apt repository, other source repositories must be included.
# For the Debian repository
deb-src http://deb.debian.org/debian bullseye main
deb-src http://deb.debian.org/debian bullseye-updates main
# For the official PostgreSQL Apt repository
deb-src http://apt.postgresql.org/pub/repos/apt bullseye-pgdg main
In this example, the PostgreSQL Server in version 12.10 is used from the PostgreSQL Apt repository running on a Debian 11 distribution. To download and unpack the sources of the PostgreSQL server, the following command can be used:
apt-get source postgresql-12
cd postgresql-12-12.10
Before the sources can be rebuilt, the needed build dependencies need to be installed. This can be done as follows:
apt-get build-dep postgresql
Now, the sources can be compiled with the needed Assert statements. To perform this, the environment variable DEB_BUILD_PROFILES
must be set to the value pkg.postgresql.cassert
. This enables the required option --enable-cassert
in the configure
call during the build process. The build process can be started by executing dpkg-buildpackage -rfakeroot
.
export DEB_BUILD_OPTIONS=nocheck
export DEB_BUILD_PROFILES=pkg.postgresql.cassert
dpkg-buildpackage -rfakeroot
After the software has been compiled, in the parent directory, the following Debian packages should be created:
jan@debian11-work:~# ls -l *.deb
-rw-r--r-- 1 jan jan 61056 Mar 7 22:51 libecpg6_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 110940 Mar 7 22:51 libecpg6-dbgsym_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 19456 Mar 7 22:51 libecpg-compat3_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 18508 Mar 7 22:51 libecpg-compat3-dbgsym_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 285252 Mar 7 22:51 libecpg-dev_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 231952 Mar 7 22:51 libecpg-dev-dbgsym_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 47648 Mar 7 22:51 libpgtypes3_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 88972 Mar 7 22:51 libpgtypes3-dbgsym_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 179048 Mar 7 22:51 libpq5_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 249980 Mar 7 22:51 libpq5-dbgsym_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 142964 Mar 7 22:51 libpq-dev_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 16277416 Mar 7 22:52 postgresql-12_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 14727144 Mar 7 22:51 postgresql-12-dbgsym_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 1444016 Mar 7 22:52 postgresql-client-12_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 1726260 Mar 7 22:52 postgresql-client-12-dbgsym_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 1892552 Mar 7 22:52 postgresql-doc-12_12.10-1.pgdg110+1_all.deb
-rw-r--r-- 1 jan jan 83916 Mar 7 22:52 postgresql-plperl-12_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 151000 Mar 7 22:52 postgresql-plperl-12-dbgsym_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 110372 Mar 7 22:52 postgresql-plpython3-12_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 159572 Mar 7 22:52 postgresql-plpython3-12-dbgsym_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 41536 Mar 7 22:52 postgresql-pltcl-12_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 71884 Mar 7 22:52 postgresql-pltcl-12-dbgsym_12.10-1.pgdg110+1_amd64.deb
-rw-r--r-- 1 jan jan 993124 Mar 7 22:52 postgresql-server-dev-12_12.10-1.pgdg110+1_amd64.deb
These needed packages can be installed by calling dpkg -i <filenames>
or all produced Debian packages can be installed by executing:
dpkg -i *.deb
Afterward, a PostgreSQL server with active Assert macros is installed. This can be verified by executing:
grep USE_ASSERT_CHECKING /usr/include/postgresql/12/server/pg_config.h