Earlier this year, I was in Canada for PGConf 2023, where I talked about the evolution of PostgreSQL from a Berkeley research project to its current status as the most advanced open-source database, and discussed the various changes introduced for PostgreSQL 16, particularly regarding logical replication.
To better appreciate the long journey that PostgreSQL has taken since its early days, I think it's important to revisit its progress, and the impressive list of features it accumulated along the way, thanks to the work of our committed and dedicated community.
Evolution of PostgreSQL with its major milestones across versions
We have started this project in 1997 from the University of California, at Berkeley Project, which had been running since 1986, and from then on, a new version with major features has been released every year.
It is interesting to note how, from inception, PostgreSQL has been geared towards handling large volumes of data, and has been evolving since then in that direction.
With version 15, we introduced theMERGE command, which was being discussed for a couple of years in the community, and we finally had the chance to implement it. We also introduced shared memory statistics, which improved over the previous statistics mechanism, and improved logical replication further, by introducing row and column filters. Finally, we added server-side compression for faster and smaller backups.
Version 16 introduces a lot of new features, with several improvements to the logical replication mechanism. One of the most important ones in my view is the ability to perform logical replication from the standby node, which I will discuss below.
Prior to Postgres 16, setting a bi-directional or logical replication among nodes was difficult, because if we set up replication for a table, it would lead to an infinite loop. By adding the ability to filter data based on origin, we can set up n-way logical replication, and that will prevent loops when performing bi-directional replication. You can read more in our blog postBi-directional replication using origin filtering in PostgreSQL.
This requireswal_level = logical on both primary and standby.
This ability can be used for workload distribution, by allowing subscribers to subscribe from the standby when the primary is busy.
The non-superusers must have been granted pg_create_subscription role, and are required to specify a password for authentication.
Superusers can setpassword_required = false for non-superusers that own the subscription.
Performance improvement in the range of 25-40% has been observed (for further details, checkhere).
Each large transaction is assigned to one of the available workers, which improves lag by immediately applying instead of waiting till whole transaction is received by the subscriber. The worker remains assigned until the transaction completes.
max_parallel_apply_workers_per_subscription sets the maximum number of parallel apply workers per subscription.
Copying tables in binary format may reduce the time spent, depending on column types
Using REPLICA IDENTITY FULL on the publisher can lead to a full table scan per tuple change on the subscriber when REPLICA IDENTITY or PK index is not available.
The index that can be used must be a btree index, not a partial index, and the leftmost field must be a column (not an expression) that references the remote relation column.
The performance improvement is proportional to the amount of data in the table.
The newest version provides significant improvement (3x for 16 clients) for concurrent COPY into a single relation.
The relation extension lock is held just during relation extension, whereas previously the relation extension lock was held while the system:
We still update BRIN-index if the corresponding columns are updated. This does not apply to attributes referenced in index predicates, an update of such attribute always disables HOT.
This allows to ask the kernel to minimize caching effects for relation data and WAL files. Currently, this feature reduces system performance, and is not intended for end users, so it is disabled by default. This option can be enabled by GUC debug_io_direct (valid values are: data, wal, wal_init).
The further plan is to introduce our own I/O mechanisms like read-ahead, etc. to replace the facilities that the kernel disables with this option. Align all I/O buffers at 4096 to have a better performance with direct I/O.
This reduces the cost of freezing by reducing WAL volume.
The view contains one row for each combination of backend type, target I/O object, and I/O context, showing cluster-wide I/O statistics.
The view tracks various I/O operations like reads, writes, extends, hits, evictions, reuses, fsyncs. A high evictions count can indicate that shared buffers should be increased. Large numbers of fsyncs by client backends could indicate misconfiguration of shared buffers or of the checkpointer.
The stats do not differentiate between data which had to be fetched from disk and that which already resided in the kernel page cache.
A new option BUFFER_USAGE_LIMIT has been added, which allows user to control the size of shared buffers. Larger values can make vacuum run faster at the cost of slowing down other concurrent queries.
vacuum_buffer_usage_limit (GUC) provides another way to control, but BUFFER_USAGE_LIMIT would take precedence. GUC allows even autovacuum to use the specified limit.
We have also added --buffer-usage-limit option to vacuumdb.
The new version comes with a host of new features that give users more options, among others, for collation and JSON data manipulation.
The line above places g after a, before b.
New options are added to CREATE COLLATION, CREATE DATABASE, createdb, and initdb to set the rules.
Determine the ICU default locale from the environment.
IS JSON [VALUE], IS JSON ARRAY, IS JSON OBJECT, IS JSON SCALAR
Previously, we always needed to sort tuples before doing aggregation.
With PostgreSQL 16, an index can provide pre-sorted input, which will be directly used for aggregation
This reduces the overhead of bulk-loading into partitioned tables where many consecutive tuples belong to the same partition.
The following methods may be specified:password,md5,gss,sspi,scram-sha-256, ornone.
This option can also be used to disallow certain authentication methods, by prefixing the method with!.
If the server does not use the required authentication request, the connection attempt will fail.
This is enabled withsslrootcert = system. The magic system value will take precedence over a local certificate file with the same name.
The SET option, if set to TRUE, allows the member to change to the granted role using the SET ROLE command. To create an object owned by another role or to give ownership of an existing object to another role, you must have the ability to SET ROLE to that role. Otherwise, commands such as ALTER ... OWNER TO or CREATE DATABASE ... OWNER will fail.
Testing has shown about 8% speedup of COPY into a table containing 2 INT columns.
In the initial data sort, if the bucket numbers are the same, then sort on hash value next. The build is sped up by skipping needless binary searches. Hash Index build speed up by 5-15%.
The header size for each allocation was reduced from 16+ to 8 bytes, and performance of the slab memory allocator, which is used to allocate memory during logical decoding, was improved.
This optimizes processing of subtransaction searches and ASCII and JSON strings.
The settingload_balance_hosts = random allows hosts and addresses to be connected to in random order. This parameter can be used in combination with target_session_attrs to load balance over standby servers only.
It is recommended to also configure a reasonable value for connect_timeout to allow other nodes to be tried when the chosen one is not responding.
This is controlled by the postgres_fdw batch_size option.
Users should use the pg_ctl promote command or pg_promote() function to promote a standby.
This has been unnecessary since hot_standby_feedback and replication slots were added.
The full list of new/enhanced features and other changes can be foundhere.
Before wrapping up, I would like to share some of the changes that the PostgreSQL community is currently discussing for future PostgreSQL versions, like PostgreSQL 17 and later. Please keep in mind that this list isn't set in stone, and there's no guarantee that all these features will make it to the final cut - it's based on my own observations from the discussions happening within the PostgreSQL community.
Topics:PostgreSQL,PostgreSQL community,PostgreSQL development,PostgreSQL event
Read our most recent articles regarding all aspects of PostgreSQL and Fujitsu Enterprise Postgres.
Fill the form to receive notifications of future posts