This page contains solutions to common problems when implementing Postgresql as a storage engine.
If an exception such as the following appears in the server logs:
org.postgresql.util.PSQLException: The hostname XXX.XXX.XXX.XXX could not be verified by hostnameverifier PgjdbcHostnameVerifier
Most recent distributions of Postgresql use TLS encryption for connection to the database by default. This is good security practice, but can cause issues if the database server is being accessed by IP address since the database client is not able to verify the identity of the server by default.
This issue is typically caused by using an IP address in the database connection URL, such as the example shown below:
There are several ways of solving this issue. The most secure solution to this issue is to obtain a TLS certificate for the server, and use the server's host name instead of its IP address in the JDBC connection URL.
An example JDBC URL using a host name is shown below. Note that it is not sufficient to simply use the host name in your URL; you will also need to install the appropriate certificates in both the client and the server.
If obtaining a TLS certificate for your database server hostname is impractical (e.g. the server is a development server with no fixed host name) you can disable hostname verification by adding the parameter
sslmode=allow to your database connection URL. Disabling hostname verification means that the database client has no means to verify that it is actually talking to the intended server, so this should only be done within closed networks with careful consideration.
An example JDBC URL containing this parameter is shown below:
If you are experiencing hung connections (often due to firewalls and other network infrastructure), this can often be resolved by enabling TCP Keepalive.
Add the following to your connection URL:
These parameters are described here: https://jdbc.postgresql.org/documentation/93/connect.html
In Persistence module configuration, setting
Inline Resource Storage Below Size (chars) property to a low number or zero can change the way FHIR resources are stored in PostgreSQL in a significant way.
PostgreSQL can store large objects in an internal table, named
pg_largeobject. Any table record referring to a large object record only needs to keep an internal id (OID) to it.
Inline Resource Storage Below Size (chars) property value is used to determine if a resource body text is stored inline in the FHIR
HFJ_RES_VER table, if the number of characters of the resource body text is lower than this threshold value, or as a large object in
pg_largeobject internal table.
For example, when
Inline Resource Storage Below Size (chars) is set to zero, it means the body text of all resources will be kept as large objects, instead of being stored inline in the FHIR
pg_largeobject table extensively has two potential effects:
pg_largeobjecttable, large object records that are no longer referenced by any other table record, that can waste a significant amount of disk space if they are not cleared up 2. some deleted / expunged FHIR resources could be unwittingly kept in
pg_largeobjecttable and could be accessed using a database client
To understand why it is happening, see PostgreSQL large objects module implementation details. HAPI FHIR / Smile CDR is not using
lo_manage trigger for obvious performance and maintenance reasons, as it doesn't solve orphaned entries in
pg_largeobject table completely.
To make sure these entries are cleared up, you should run PostgreSQL vacuumlo command on a regular basis.
It is especially important that
Inline Resource Storage Below Size (chars) property is set to a proper value and that
vacuumlo command is run regularly for PostgreSQL instances hosted in the cloud, to reduce cost and security risk.
Important note: changing the
Inline Resource Storage Below Size (chars) property value does not affect the location of the FHIR resources currently stored. It will only change the location of the new FHIR resources stored afterward.