PostgreSQL version 15 is on its way and we get a better and better look, what will be included in the future release. So it’s time to have a look at some new future features
1. Create privilege on public schema removed
Until today with PostgreSQL 14 it is possible for everybody to write into the public schema per default. With PostgreSQL 15 this won’t be possible anymore. The public schema is owned by the “pg_database_owner” now. Let’s do a short test.
postgres=# create user test; CREATE ROLE postgres=# du List of roles Role name | Attributes | Member of -----------+------------------------------------------------------------+----------- postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {} test | | {} postgres=# c postgres test You are now connected to database "postgres" as user "test". postgres=> create table t1 (a int); ERROR: permission denied for schema public LINE 1: create table t1 (a int); ^ postgres=
If you want to be able again to write into the public schema, the permission has to be granted again explicitly.
2. Extended pg_basebackup compression
There are some extensions coming for pg_basebackup. Especially the compression improves. First of all –compress is now able to accept a compression method and an (optional) compression level using e.g. gzip:9. Futhermore –compress accepts client-gzip and server-gzip as compression method to define where to compress the backup. Another plus is that the compression can also be used with –format=p now. This gives you the opportunity to compress your pg_basebackup on server side and extract it again on client side automatically. Especially for slow network connections this can be a benefit. Let’s have a short look at the new –compress syntax.
postgres@pgdebian:/u99/backup2/ [PG15] pg_basebackup --help | grep -A 1 compress -z, --gzip compress tar output -Z, --compress=[{client|server}-]METHOD[:DETAIL] compress on client or server as specified -Z, --compress=none do not compress tar output
To create a backup it looks like this now. Really simple and easy to use.
postgres@pgdebian:/u99/backup2/ [PG15] pg_basebackup -h localhost -p 5438 -Ft --compress=client-gzip:9 --pgdata=/u99/backup2/ -Xs postgres@pgdebian:/u99/backup2/ [PG15] ll total 3136 -rw------- 1 postgres postgres 136487 Mar 28 15:49 backup_manifest -rw------- 1 postgres postgres 3050084 Mar 28 15:49 base.tar.gz -rw------- 1 postgres postgres 17649 Mar 28 15:49 pg_wal.tar.gz postgres@pgdebian:/u99/backup2/ [PG15]
Or with lz4 (available for client or server side compression):
postgres@pgdebian:/u99/backup2/ [PG15] pg_basebackup -h localhost -p 5438 -Ft --compress=lz4:9 --pgdata=/u99/backup2/ -Xs postgres@pgdebian:/u99/backup2/ [PG15] ll total 20096 -rw------- 1 postgres postgres 136487 Mar 28 15:18 backup_manifest -rw------- 1 postgres postgres 3657232 Mar 28 15:18 base.tar.lz4 -rw------- 1 postgres postgres 16779264 Mar 28 15:18 pg_wal.tar
3. New role: pg_checkpointer
Until PostgreSQL 14 only the superuser(s) were allowed to execute CHECKPOINT commands. Starting with PostgreSQL 15 there is a new role called pg_checkpointer. Once you grant that role to an user, it is able to execute CHECKPOINT commands.
postgres=# create user checky; CREATE ROLE postgres=# c postgres checky You are now connected to database "postgres" as user "checky". postgres=> checkpoint; ERROR: must be superuser or have privileges of pg_checkpointer to do CHECKPOINT postgres=> c postgres postgres You are now connected to database "postgres" as user "postgres". postgres=# grant pg_checkpointer to checky; GRANT ROLE postgres=# c postgres checky You are now connected to database "postgres" as user "checky". postgres=> checkpoint; CHECKPOINT postgres=>
4. MERGE command
MERGE gives you the opportunity to execute one SQL statement that INSERT/UPDATE/DELETE rows in regular and partitioned tables and more. There is some overhead if you use it as a single SQL command, because you need a lot of WHEN / THEN expressions.
Let’s have a look at this new feature using a simple example with two table which are similar, but there are some more entries.
dvdrental=# select * from category; category_id | name | last_update -------------+-------------+--------------------- 1 | Action | 2006-02-15 09:46:27 2 | Animation | 2006-02-15 09:46:27 3 | Children | 2006-02-15 09:46:27 4 | Classics | 2006-02-15 09:46:27 5 | Comedy | 2006-02-15 09:46:27 6 | Documentary | 2006-02-15 09:46:27 7 | Drama | 2006-02-15 09:46:27 8 | Family | 2006-02-15 09:46:27 9 | Foreign | 2006-02-15 09:46:27 10 | Games | 2006-02-15 09:46:27 11 | Horror | 2006-02-15 09:46:27 12 | Music | 2006-02-15 09:46:27 13 | New | 2006-02-15 09:46:27 14 | Sci-Fi | 2006-02-15 09:46:27 15 | Sports | 2006-02-15 09:46:27 16 | Travel | 2006-02-15 09:46:27 (16 rows) dvdrental=# select * from category_new; category_id | name | last_update -------------+-------------+---------------------------- 1 | Action | 2006-02-15 09:46:27 2 | Animation | 2006-02-15 09:46:27 3 | Children | 2006-02-15 09:46:27 4 | Classics | 2006-02-15 09:46:27 5 | Comedy | 2006-02-15 09:46:27 6 | Documentary | 2006-02-15 09:46:27 7 | Drama | 2006-02-15 09:46:27 8 | Family | 2006-02-15 09:46:27 9 | Foreign | 2006-02-15 09:46:27 10 | Games | 2006-02-15 09:46:27 11 | Horror | 2006-02-15 09:46:27 12 | Music | 2006-02-15 09:46:27 13 | Biography | 2022-04-12 11:53:34.986878 14 | Sci-Fi | 2006-02-15 09:46:27 15 | Sports | 2006-02-15 09:46:27 16 | Travel | 2006-02-15 09:46:27 17 | Dramedy | 2022-04-12 11:48:49.559058 18 | Love | 2022-04-12 11:49:32.072536 (17 rows) dvdrental=# MERGE INTO category AS c USING category_new AS n ON c.category_id = n.category_id WHEN MATCHED AND c.name = n.name THEN DO NOTHING WHEN MATCHED AND c.name n.name THEN UPDATE SET name=n.name WHEN NOT MATCHED THEN INSERT VALUES (n.category_id, n.name, n.last_update) ; MERGE 17 dvdrental=#
Once the MERGE command is done, select the original table again, to see if it added and updated everything as planned:
dvdrental=# select * from category order by 1; category_id | name | last_update -------------+-------------+---------------------------- 1 | Action | 2006-02-15 09:46:27 2 | Animation | 2006-02-15 09:46:27 3 | Children | 2006-02-15 09:46:27 4 | Classics | 2006-02-15 09:46:27 5 | Comedy | 2006-02-15 09:46:27 6 | Documentary | 2006-02-15 09:46:27 7 | Drama | 2006-02-15 09:46:27 8 | Family | 2006-02-15 09:46:27 9 | Foreign | 2006-02-15 09:46:27 10 | Games | 2006-02-15 09:46:27 11 | Horror | 2006-02-15 09:46:27 12 | Music | 2006-02-15 09:46:27 13 | Biography | 2022-04-12 13:42:26.187381 14 | Sci-Fi | 2006-02-15 09:46:27 15 | Sports | 2006-02-15 09:46:27 16 | Travel | 2006-02-15 09:46:27 17 | Dramedy | 2022-04-12 11:48:49.559058 18 | Love | 2022-04-12 11:49:32.072536 (18 rows)
Merge does not support foreign tables or updatable views. Maybe this will come later, if there is need for it. But for the moment it is not planned.
Conclusion
These are only a few new features coming with PostgreSQL Version 15. Much more new stuff to follow. Especially with replication there is a lot more to check out and also in cases of security PostgreSQL improves with every new release.