PostgreSQL¶
PostgreSQL also known as Postgres, is a free and open-source relational database management system (RDBMS) emphasizing extensibility and SQL compliance.
In this guideline we will take a look on the Postgresql database setup and configurations for Repository Production instance. Using PostgreSQL Version 11, and VM invenio03-prod.tugraz.at
Installation¶
$ apt-get update
$ apt-get install postgresql postgresql-contrib
By default PostgreSQL has a default user postgres. We can access the database with this user su postgres and access the shell with psql.
To change the postgres user password:
$ su postgres
(postgres) $ psql
(postgres) ALTER USER postgres WITH PASSWORD '************';
Users and Database¶
Create a admin user:
CREATE USER <USERNAME> WITH PASSWORD '************';
Give the user permissions:
ALTER USER "USERNAME" WITH SUPERUSER;
Create Database:
CREATE database DATABASE_NAME;
Grant permissions of database for created user:
GRANT ALL PRIVILEGES ON DATABASE "DATABASE_NAME" to USER;
Configuration¶
Allow access¶
Allow remote connection to the webserver VMs.
Open the /etc/postgresql/11/main/pg_hba.conf file and edit it as below:
# TYPE DATABASE USER ADDRESS METHOD
host all <user> ********/28 trust
host all <user> ********/28 trust
host all <user> repository.tugraz.at trust
Listen address¶
Listen to other VMs.
Open the /etc/postgresql/11/main/postgresql.conf file and edit it as below:
#------------------------------------------------------------------------------
# CONNECTIONS AND AUTHENTICATION
#------------------------------------------------------------------------------
# - Connection Settings -
- #listen_addresses = 'localhost' # what IP address(es) to listen on;
+ listen_addresses = '<ip addresses>' # what IP address(es) to listen on;
Test connection¶
Access the database from one of the configured machines.
psql
Make sure you have postgres client installed.
psql -U USERNAME -d DATABASE -h HOST_IP
Performance¶
Default PostgreSQL configuration is deliberately conservative. It assumes the server has 128 MB of RAM and a single spinning disk. If you're running on a modern server with 16 GB of RAM and SSD storage, the defaults may leave performance on the table.
Key Settings That Affect Query Performance
| Setting | Default | Recommended Starting Point | What It Controls |
|---|---|---|---|
shared_buffers |
128 MB | 25% of total RAM | PostgreSQL's shared memory cache |
work_mem |
4 MB | 64-256 MB | Memory for sorts and hash operations per query |
effective_cache_size |
4 GB | 50-75% of total RAM | Planner's estimate of available OS cache |
random_page_cost |
4.0 | 1.1 for SSD, 2.0 for HDD | Cost of random disk reads (affects index usage) |
effective_io_concurrency |
1 | 200 for SSD | Number of concurrent disk I/O operations |
shared_buffers
shared_buffers is one of the most important PostgreSQL settings.
PostgreSQL uses it as its primary data cache.
- Too low: PostgreSQL frequently re-reads data from disk.
- Too high: PostgreSQL competes with the operating system's page cache.
A value around 25% of total RAM is a good starting point for most workloads.
Example:
16 GB RAM → shared_buffers = 4 GB
8 GB RAM → shared_buffers = 2 GB
2 GB RAM → shared_buffers = 512 MB
work_mem
work_mem is more complicated because it is allocated per operation, not per query.
A complex query with:
- 5 sort operations
- 3 hash joins
could potentially use:
8 × work_mem
Setting:
work_mem = 256 MB
may seem reasonable, but with:
50 concurrent connections
memory usage can grow significantly.
A safer approach:
- Start with 64 MB
- Monitor memory usage
- Increase only if needed
effective_cache_size
effective_cache_size does not allocate memory.
It tells the PostgreSQL query planner how much memory is likely available for caching:
- PostgreSQL shared buffers
- Operating system cache
It helps PostgreSQL choose better query plans.
Recommended starting point:
50-75% of total RAM
random_page_cost
This setting is often overlooked.
The default:
random_page_cost = 4.0
tells PostgreSQL that random disk reads are four times more expensive than sequential reads.
This was designed for spinning HDDs.
For SSD storage:
random_page_cost = 1.1
makes random reads closer in cost to sequential reads and encourages PostgreSQL to use indexes more often.
effective_io_concurrency
Controls how many concurrent disk I/O operations PostgreSQL assumes are possible.
Defaults:
effective_io_concurrency = 1
For SSD storage:
effective_io_concurrency = 200
is a common starting point.
For HDD storage:
effective_io_concurrency = 1-2
is usually more appropriate.
Applying Changes
The following settings can be changed without restarting PostgreSQL:
ALTER SYSTEM SET work_mem = '64MB';
ALTER SYSTEM SET effective_cache_size = '12GB';
ALTER SYSTEM SET random_page_cost = 1.1;
ALTER SYSTEM SET effective_io_concurrency = 200;
SELECT pg_reload_conf();
shared_buffers requires a PostgreSQL restart:
ALTER SYSTEM SET shared_buffers = '4GB';
Verify Settings
Check the active values:
SHOW shared_buffers;
SHOW work_mem;
SHOW effective_cache_size;
SHOW random_page_cost;
SHOW effective_io_concurrency;
Test Query Performance
After changing settings, test slow queries with:
EXPLAIN (ANALYZE, BUFFERS)
SELECT ...
Look for improvements such as:
- More
Index ScanorIndex Only Scan - In-memory sorts instead of disk-based sorts
- Reduced disk reads
- Better query execution times
Settings applied in TUG instances
Test instance
ALTER SYSTEM SET shared_buffers = '512MB';
ALTER SYSTEM SET work_mem = '16MB';
ALTER SYSTEM SET effective_cache_size = '1536MB';
ALTER SYSTEM SET random_page_cost = 1.1;
ALTER SYSTEM SET effective_io_concurrency = 200;
SELECT pg_reload_conf();
Production instance
ALTER SYSTEM SET shared_buffers = '2GB';
ALTER SYSTEM SET work_mem = '32MB';
ALTER SYSTEM SET effective_cache_size = '6GB';
ALTER SYSTEM SET random_page_cost = 1.1;
ALTER SYSTEM SET effective_io_concurrency = 200;
SELECT pg_reload_conf();
Backup & Restore¶
Requirements¶
- A server running Linux operating system with PostgreSQL installed.
- A root password is setup on your server.
Backup a Single PostgreSQL Database¶
You will need to use pg_dump tool to backup a PostgreSQL database. This tool will dump all content of a database into a single file.
The basic syntax to backup a PostgreSQL database is shown below:
pg_dump -U [option] [database_name] > [backup_name]
A brief explanation of all available option is shown below:
- -U : Specify the PostgreSQL username.
- -W : Force pg_dump command to ask for a password.
- -F : Specify the format of the output file.
- -f : Specify the output file.
- p : Plain text SQL script.
- c : Specify the custom formate.
- d : Specify the directory format.
- t : Specify tar format archive file.
For example, create a backup of the PostgreSQL database named db1 in the tar format, run the following command:
pg_dump -U postgres -F c db1 > db1.tar
If you want to save the backup in a Plain-text (SQL), run the following command:
pg_dump db1 > db1_backup.sql
If you want to save the backup in a directory format, run the following command:
pg_dump -U postgres -F d db1 > db1_backup
If your database is very large and wants to generate a small backup file then you can use pg_dump with a compression tool such as gzip to compress the database backup.
pg_dump -U postgres db1 | gzip > db1.gz
You can also reduce the database backup time by dumping number_of_jobs tables simultaneously using the -j flag.
pg_dump -U postgres -F d -j 5 db1 -f db1_backup
Note : Also keep in mind that the above command will reduce the time of the backup but it also increases the load on the server.
Restore a Single PostgreSQL Database¶
If you choose custom, directory, or archive format when taking a database backup. Then, you will need to use pg_restore command to restore your database.
The basic syntax to restore a database with pg_restore is shown below:
pg_restore -U [option] [db_name] [db_backup]
A brief explanation of each option is shown below:
- -c : Used to drop database objects before recreating them.
- -C : Used to create a database before restoring into it.
- -e : Exit if an error has been encountered.
- -F format : Used to specify the format of the archive.
For example, restore a backup from the file db1.tar, you will need to consider two options:
- If the database already exists.
- The format of your backup.
If your database already exists, you can restore it with the following command:
pg_restore -U postgres -Ft -d db1 < db1.tar
If your database is not exists, you can restore it with the following command:
pg_restore -U postgres -Ft -C -d db1 < db1.tar
Backup a Remote PostgreSQL Database¶
In order to perform the database backup on the remote PostgreSQL server. You will need to configure your PostgreSQL server to allow remote connection.
The basic syntax to backup a remote PostgreSQL database is shown below:
pg_dump -h [remote-postgres-server-ip] -U [option] [database_name] > [backup_name]
For example, create a backup of the PostgreSQL database on the remote server ( 192.168.0.100 ) with name remote_db1 in the tar format, run the following command:
pg_dump -h 192.168.0.100 -U postgres -F c remote_db1 > remote_db1.tar
Restore a Remote PostgreSQL Database¶
The basic syntax to restore a remote PostgreSQL database is shown below:
pg_restore -h [remote-postgres-server-ip] -U [option] [database_name] < [backup_name]
For example, restore a database from the file remote_db1.tar on the remote server ( 192.168.0.100 ), run the following command:
pg_restore -h 192.168.0.100 -U postgres -Ft -d remote_db1 < remote_db1.tar
Note to restore from plain-text format you need to use psql command instead:
psql db1 < db1_backup.sql
For more information, you can see the pg_dump and pg_restore reference pages.
Indexes¶
Some operations are highly reliant on database queries. Some tables can have 100k + rows. In order to increase the performance of the filtering, an INDEX needs to be created to speed up the lookup.
Example:
Indexes for our setup:
- job_id index for jobs_run table
CREATE INDEX idx_jobs_run_job_id_created
ON jobs_run (job_id, created DESC);