# Architecture

> Architecture, catalogs, replication, execution, I/O, roles, and server internals.

---

LLMS index: [llms.txt](/en/llms.txt)

---

<div class="feature-source-note"><span class="feature-edition-badge">Beta 1</span><span><strong>Source pages:</strong> PDF 17-44</span><span><a href="https://github.com/nori-shinoda/documents/blob/1773200c5362476c4a549222b7d17fa91f546cae/postgresql19_beta1_new_features_en_20260606-1.pdf">Original PDF on GitHub</a></span></div>

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-17">PDF page 17</p>

Describes the improved architecture and features in PostgreSQL 19.

#### 3.1.1 Changed System Catalogs {#pg19-3-1-1-changed-system-catalogs}

The following catalogs and views have been changed. [[228c370](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=228c3708685542d34e6f02c74240656327a5c622), [167ed80](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=167ed8082f40ee1f3f4cd18cf02bd6d17df57dab), [fd5a1a0](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=fd5a1a0c3e566f7fc860838084466a1c25944281), [deb6744](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=deb674454c5cb7ecabecee2e04ca929eee570df4), [b71bae4](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=b71bae41a0cdda879db39d9946d2cc4af910bed1), [a5b5432](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=a5b543258aa29e181abe59b3183b685650d24651), [a850be2](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=a850be2fe653b3b529969946c1cefe0fd9e34a8d), [185e304](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=185e304263347d0979832f7a08a812872d136b18), [d3b6183](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=d3b6183dd988928dd369b4b7d641917e77f1ae4e), [96b3784](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=96b37849734673e7c82fb86c4f0a46a28f500ac8), [f9a09aa](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=f9a09aa2952039a9956b44d929b9df74d62a4cd4), [f6a4c49](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=f6a4c498dcf6f05b4ef79051e95de12cc48bdeee), [3edaf29](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=3edaf29fa5e0d4fd6419c7eb73fd6df5b0406789), [76b7872](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=76b78721ca49c16dfcbfbd2f4f87fcdb2db2bbb6), [e68b6ad](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=e68b6adad96d414fdf24e072fdb1d41fb4b8f0b7), [5db6a34](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=5db6a344abc2dfbc5df454cd93a096443ea4dd3e), [ab40db3](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=ab40db3852dfa093b64c9266dd372fee414e993f), [0d78952](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=0d789520619803cf6629ebf980e116d733b6756f), [f3c9e34](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=f3c9e341cdf167ae3378e74e770558e81f9aa48e), [c257ba8](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=c257ba83971892723c5c89955ab0dd1ef7c077d8), [a36164e](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=a36164e7465fd1e10e94569e9c1c07656e38a9de), [307447e](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=307447e6dbc035c0e6e7a8ce9cee704a3b710ee9), [fb80f38](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=fb80f388f4a140934f51f68578ba321152332ce7), [ac58465](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=ac58465e0618941842439eb3f5a2cf8bebd5a3f1), [723619e](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=723619eaa3a85f32ce8c2d32c063da26f89ca8d2), [8fe315f](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=8fe315f18d4181d37385c8e62ea3009084ba303a), [2f094e7](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=2f094e7ac691abc9d2fe0f4dcf0feac4a6ce1d9c), [3b88e50](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=3b88e50d6c2ef972748378a10fc444efae90ed14), [4019f72](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=4019f725f5d43f37b23222d06d20e3da1038d373), [01d485b](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=01d485b142e4c89aef79da9fd60f203c1bd4458b), [87f61f0](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=87f61f0c82806b7e4201f15bd77920e9e7108b11)]

**Table 4.** Add system catalogs and views

| View Name | Description |
| --- | --- |
| pg_dsm_registry_allocations | Provides information on Dynamic Shared Memory (DSM) |
| pg_propgraph_element | Property Graph Elements |
| pg_propgraph_element_label | Property Graph Element Labels |
| pg_propgraph_label | Property Graph Labels |
| pg_propgraph_label_property | Property Graph Label Properties |
| pg_propgraph_property | Property Graph Properties |
| pg_publication_sequences | Sequences including in PUBLICATION |
| pg_stat_autovacuum_scores | VACUUM score data for each table |
| pg_stat_lock | Runtime statistics for the locked condition |
| pg_stat_progress_data_checksums | Progress report on checksum configuration Changes |
| pg_stat_progress_repack | REPACK statement progress report |
| pg_stat_recovery | Report on the recovery status of the startup process |

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-18">PDF page 18</p>

**Table 5.** System catalogs\/views with additional columns

| View name | Added column | Data type | Description |
| --- | --- | --- | --- |
| pg_available_extensions | location | text | Directory for storing extension modules |
| pg_available_extension_versions | location | text | Directory for storing extension modules |
| pg_foreign_data_wrapper | fdwconnection | oid | OID for Foreign Data Wrapper connection function |
| pg_publication | puballsequences | boolean | Is FOR ALL SEQUENCES specified? |
| pg_publication_rel | prexcept | boolean | Indicates whether it is a replication exception table |
| pg_range | rngconstruct2 | regproc | OID for a two-argument constructor |
|  | rngconstruct3 | regproc | OID for a three-argument constructor |
|  | rngmltconstruct0 | regproc | OID for a multi-range constructor with zero arguments |
|  | rngmltconstruct1 | regproc | OID for a multi-range constructor with one arguments |
|  | rngmltconstruct2 | regproc | OID for a multi-range constructor with two arguments |
| pg_replication_slots | slotsync skip re__ ason | text | The reason for skipping slot synchronization |
| pg_stats | tableid | oid | OID of the table |
|  | attnum | smallint | Number of columns |
| pg_stats_ext | tableid | oid | OID of the table |
|  | statistics_id | oid | Extended statistics object OID |
| pg_stats_ext_exprs | tableid | oid | OID of the table |
|  | statistics_id | oid | Extended statistics object OID |
|  | range_length_histogram | anyarray | Histogram with non-empty bin length |
|  | range_empty_frac | real | Percentage of empty values |
|  | range_bounds_histogram | anyarray | Histogram of the upper and lower limits of a range |
| pg_stat_database_conflicts | stats_reset | timestamptz | Data reset timestamp |
| pg_stat_progress_analyze | started_by | text | ANALYZE trigger (manual, autovacuum) |
| pg_stat_progress_basebackup | backup_type | text | Specify the type of backup (full or incremental) |
| pg_stat_progress_vacuum | mode | text | VACUUM Execution Modes (normal, aggressive, failsafe) |
|  | started_by | text | VAUUM trigger (manual, autovacuum, autovacuum_wraparound) |
| pg_stat_replication_slots | mem exceeded__ count | bigint | Number of times the decoding memory usage exceeded logical_decoding_work_mem |
|  | slotsync skip co__ unt | bigint | Number of synchronization skips for replication slots |
|  | slotsync last ski__ p | timestamptz | Last timestamp of synchronization skip for replication slots |
| pg_stat_subscription_stats | confl_update_deleted | bigint | Number of times the item to be updated has been deleted in other sources |
|  | sync_seq_error_count | bigint | Number of sequence synchronization errors |
|  | sync_table_error_count | bigint | Number of synchronization errors for the table |
| pg_stat_user_functions | stats_reset | timestamptz | Statistics reset timestamp |
| pg_stat_wal | wal_fpi_bytes | numeric | Number of bytes for full-page write |
| pg_subscription | subretaindeadtup les | boolean | Is update_deleted detection enabled? |
|  | submaxretention | int | Maximum retention period for dead doubles |
|  | subretentionactiv e | boolean | To keep the dead tuple? |
|  | subserver | oid | OID of the FOREIGN SERVER for PUBLICATION connection |
|  | subwalrcvtimeou t | text | WAL receiver timeout |
| pg_stat_{all\|sys\|user}_{tables\|indexes} | stats_reset | timestamptz | Statistics reset timestamp |
| pg_statio_{all\|sys\|user}_{tables\|indexes} | stats_reset | timestamptz | Statistics reset timestamp |

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-19">PDF page 19</p>

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-20">PDF page 20</p>

**Table 6.** Vues within the pg\_catalog schema where columns have been deleted

| View name | Remove column | Description |
| --- | --- | --- |
| pg_stat_subscription_stats | sync_error_count | Renamed to sync_tale_error_count |

**Table 7.** Views in the added information\_schema schema

| View name | Description |
| --- | --- |
| pg_edge_table_components | Property Graph object information |
| pg_element_table_key_columns | Property Graph object key columns |
| pg_element_table_labels | Property Graph object labels |
| pg_element_table_properties | Property Graph object properties |
| pg_element_tables | Property Graph object tables |
| pg_labels | Property Graph object labels |
| pg_property_graph_privileges | Property Graph object privileges |
| property_graphs | Property Graph information |

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-21">PDF page 21</p>

**Table 8.** System catalogs\/views that had their content changed

| View name | Description |
| --- | --- |
| pg_aggregate | The aggtransspace column allows negative values. It is used when the transition state cannot be predicted, such as with array_agg function. |
| pg_class | The tuple with "relkind='g'", which indicates a PROPERTY GRAPH object, is added |
| pg_subscription_rel | Information about the sequences to be replicated is added |
| pg_stat_wal_receiver | The "connecting" message may appear in the status column |

##### View pg_dsm_registry_allocations {#pg19-p21-view-pg-dsm-registry-allocations}

The pg_dsm_registry_allocations view provides information about Dynamic Shared Memory (DSM). This view can only be accessed by users with the SUPERUSER privilege or who are members of the pg_read_all_stats role. [[167ed80](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=167ed8082f40ee1f3f4cd18cf02bd6d17df57dab)]

**Table 9.** Structure of the pg\_dsm\_registry\_allocations view

| Column name | Data type | Description |
| --- | --- | --- |
| name | text | Entry name |
| type | text | Indicates the entry type. The following values are returned.<br>• segment<br>• area<br>• hash |
| size | bigint | Entry size |

**Example 14.** Querying the pg\_dsm\_registry\_allocations view

```text
postgres=# SELECT * FROM pg_dsm_registry_allocations ;
    name     |  type   | size
-------------+---------+------
 autoprewarm | segment |   44
(1 row)
```

##### View pg_stat_lock {#pg19-p21-view-pg-stat-lock}

The pg_stat_lock view provides cumulative information on lock durations. This view is accessible to all users. [[4019f72](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=4019f725f5d43f37b23222d06d20e3da1038d373)]

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-22">PDF page 22</p>

**Table 10.** Structure of the pg\_stat\_lock view

| Column name | Data type | Description |
| --- | --- | --- |
| locktype | text | Type of the lock |
| waits | bigint | Total number of waiting times |
| wait_time | bigint | Total waiting time |
| fastpath_exceeded | bigint | Number of times a lock could not be acquired via the fast path |
| stats_reset | timestamp with time zone | Timestamp of the statistics reset |

**Example 15.** Querying of the pg\_stat\_lock view

```text
postgres=# SELECT locktype, waits, wait_time, fastpath_exceeded FROM
pg_stat_lock ;
     locktype     | waits | wait_time | fastpath_exceeded
------------------+-------+-----------+-------------------
 relation         |     1 |      1000 |                 0
 extend           |     0 |         0 |                 0
 frozenid         |     0 |         0 |                 0
 page             |     0 |         0 |                 0
 tuple            |     0 |         0 |                 0
 transactionid    |     0 |         0 |                 0
 virtualxid       |     0 |         0 |                 0
 spectoken        |     0 |         0 |                 0
 object           |     0 |         0 |                 0
 userlock         |     0 |         0 |                 0
 advisory         |     0 |         0 |                 0
 applytransaction |     0 |         0 |                 0
(12 rows)
```

##### View pg_stat_progress_data_checksums {#pg19-p22-view-pg-stat-progress-data-checksums}

The pg_stat_progress_data_checksums view allows real-time monitoring of the progress of checksum activation. [[f19c0ec](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=f19c0eccae9680f5785b11cdc58ef571998caec9)]

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-23">PDF page 23</p>

**Table 11.** Structure of the pg\_stat\_progress\_data\_checksums view

| Column name | Data type | Description | Note |
| --- | --- | --- | --- |
| pid | integer | Process ID of the worker |  |
| datid | oid | OID of the database |  |
| datname | name | Name of the database |  |
| phase | text | Current progressing phase |  |
| databases_totaldatabases_done | bigint | The total number of databases |  |
|  | bigint | The number of processed databases |  |
| relations_totalralations_done | bigint | The number of tables |  |
|  | bigint | The number of processed tables |  |
| blocks_totalblocks_done | bigint | The number of total blocks |  |
|  | bigint | The number of processed blocks |  |

**Example 16.** Querying of the pg\_stat\_progress\_data\_checksums view

```text
postgres=# SELECT * FROM pg_stat_progress_data_checksums
WHERE datname='postgres' ;
-[ RECORD 1 ]---+---------
pid             | 155779
datid           | 5
datname         | postgres
phase           | enabling
databases_total | 0
databases_done  | 0
relations_total | 293
relations_done  | 0
blocks_total    | 162163
blocks_done     | 64146
```

##### View pg_stat_progress_repack {#pg19-p23-view-pg-stat-progress-repack}

The pg_stat_progress_repack view allows real-time monitoring of the execution status of the REPACK statements. [[ac58465](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=ac58465e0618941842439eb3f5a2cf8bebd5a3f1)]

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-24">PDF page 24</p>

**Table 12.** Structure of the pg\_stat\_progress\_repack view

| Column name | Data type | Description |
| --- | --- | --- |
| pid | integer | Process ID of the backend server |
| datid | oid | OID of the database |
| datname | name | Name of the database |
| relid | oid | OID of the targeted for REPACK statement |
| command | text | SQL statements (REPACK, VACUUM FULL, etc.) |
| phase | text | Processing phase |
| repack_index_relid | oid | OID of the processing index |
| heap_tuples_scanned | bigint | Number of tuples scanned |
| heap_tuples_written | bigint | Number of tuples written |
| heap_blks_total | bigint | Number of blocks in the table |
| heap_blks_scanned | bigint | Number of blocks scanned |
| index_rebuild_count | bigint | Number of index rebuilds |

**Example 17.** Querying of the pg\_stat\_progress\_repack view

```text
postgres=> SELECT * FROM pg_stat_progress_repack ;
-[ RECORD 1 ]--------+------------------
pid                  | 53203
datid                | 5
datname              | postgres
relid                | 16390
command              | REPACK
phase                | seq scanning heap
repack_index_relid   | 0
heap_tuples_scanned  | 4141595
heap_tuples_inserted | 4141595
heap_tuples_updated  | 0
heap_tuples_deleted  | 0
heap_blks_total      | 54055
heap_blks_scanned    | 22387
index_rebuild_count  | 0
```

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-25">PDF page 25</p>

##### View pg_stat_recovery {#pg19-p25-view-pg-stat-recovery}

The pg_stat_recovery view provides the recovery status of the standby database. This view can be retrieved by users with the SUPERUSER privilege or who have the pg_monitor role. [[01d485b](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=01d485b142e4c89aef79da9fd60f203c1bd4458b)]

**Table 13.** Structure of the pg\_stat\_recovery view

| Column name | Data type | Description |
| --- | --- | --- |
| promote_triggered | boolean | Whether a promotion occurred |
| last_replayed_read_lsn | pg_lsn | Last start WAL position replayed |
| last_replayed_end_lsn | pg_lsn | Last end WAL position replayed |
| last_replayed_tli | integer | Last timeline replayed |
| replay_end_lsn | pg_lsn | WAL log location of the record currently being replayed |
| replay_end_tli | integer | Timeline of the WAL record replayed |
| recovery_last_xact_time | timestamp with time zone | Timestamp of the last transaction commit |
| current_chunk_start_time | timestamp with time zone | Time when the startup process observed |
| pause_state | text | Recovery pause state |

**Example 18.** Querying of the pg\_stat\_recovery view

```text
postgres=# SELECT * FROM pg_stat_recovery ;
-[ RECORD 1 ]------------+-----------------------------
promote_triggered        | f
last_replayed_read_lsn   | 0/030005D8
last_replayed_end_lsn    | 0/03000610
last_replayed_tli        | 1
replay_end_lsn           | 0/03000610
replay_end_tli           | 1
recovery_last_xact_time  | 2026-06-04 14:43:09.97718+09
current_chunk_start_time | 2026-06-04 14:45:43.83114+09
pause_state              | not paused
```

#### 3.1.2 Logical Replication Enhancements {#pg19-3-1-2-logical-replication-enhancements}

The following new features have been implemented for logical replication

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-26">PDF page 26</p>

##### Sequence Replication {#pg19-p26-sequence-replication}

Sequence replication is now supported in logical replication. On the publication side, create the publication by specifying the ALL SEQUENCES clause. The names of the sequences contained in the publication are stored in the pg_publication_sequences view. [[5509055](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=5509055d6956745532e65ab218e15b99d87d66ce)]

**Example 19.** Creating a publication that includes a sequence

```text
postgres=# CREATE PUBLICATION pub1 FOR ALL SEQUENCES ;
CREATE PUBLICATION
postgres=# SELECT * FROM pg_publication_sequences ;
 pubname | schemaname | sequencename
---------+------------+--------------
 pub1    | public     | seq01
(1 row)
```

```sql
On the subscriber side, create a subscription after first creating the sequences to be replicated. The
target sequences are stored in the pg_subscription_rel view.
```

**Example 20.** Create a subscription

```text
postgres=# CREATE SUBSCRIPTION sub1 CONNECTION
'host=dbsvr1 port=5432 dbname=postgres' PUBLICATION pub1 ;
NOTICE:  created replication slot "sub1" on publisher
CREATE SUBSCRIPTION
postgres=# SELECT * FROM pg_subscription_rel ;
 srsubid | srrelid | srsubstate |  srsublsn
---------+---------+------------+------------
   16390 |   16389 | r          | 0/030659C0
(1 row)
```

```sql
To synchronize sequence values, execute the ALTER SUBSCRIPTION REFRESH SEQUENCES
statement on the subscriber side.
```

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-27">PDF page 27</p>

**Example 21.** Synchronization of sequence values

```text
postgres=# SELECT setval('seq01', 1) ;
 setval
--------
      1
(1 row)
postgres=# ALTER SUBSCRIPTION sub1 REFRESH SEQUENCES ;
ALTER SUBSCRIPTION
postgres=# SELECT nextval('seq01') ;
 nextval
---------
      11
(1 row)
```

##### SERVER clause in the CREATE SUBSCRIPTION statement {#pg19-p27-server-clause-in-the-create-subscription-statement}

Previously, the connection information for connecting to the PUBLICATION was specified directly in the CONNECTION clause of the CREATE SUBSCRIPTION statement. In PostgreSQL 19, it is now possible to specify an existing SERVER object in the SERVER clause. [[8185bb5](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=8185bb53476378443240d57f7d844347d5fae1bf)]

**Example 22.** Specifying the SERVER clause

```text
postgres=# CREATE EXTENSION postgres_fdw ;
CREATE EXTENSION
postgres=# CREATE SERVER dbsvr1 FOREIGN DATA WRAPPER postgres_fdw OPTIONS
(host 'dbsvr1', port '5432', dbname 'postgres') ;
CREATE SERVER
postgres=# CREATE USER MAPPING FOR PUBLIC SERVER dbsvr1 OPTIONS
(user 'postgres', password '<<Password>>') ;
CREATE USER MAPPING
postgres=# CREATE SUBSCRIPTION sub1 SERVER dbsvr1 PUBLICATION pub1 ;
NOTICE:  created replication slot "sub1" on publisher
CREATE SUBSCRIPTION
```

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-28">PDF page 28</p>

##### Specifying Exception Tables {#pg19-p28-specifying-exception-tables}

The EXCEPT clause can be specified for the PUBLICATION that uses the ALL TABLES clause to designate tables to be excepted. The EXCEPT clause is specified in the CREATE PUBLICATION or ALTER PUBLICATION statement. The prexcept column has been added to the pg_publication_rel catalog to indicate exception tables. [[5984ea8](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=5984ea868eeeb202bddedfbdaca81adfe7ea6779), [fd36606](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=fd366065e06ae953c4f2d973d5c5f0474f3b87b6), [493f8c6](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=493f8c6439cf64d75883c650b5dd573d8fe0664b)]

**Example 23.** Specifying the exception table

```text
postgres=# CREATE PUBLICATION pub1 FOR ALL TABLES EXCEPT (TABLE extable1) ;
CREATE PUBLICATION
postgres=# SELECT * FROM pg_publication_rel ;
  oid  | prpubid | prrelid | prexcept | prqual | prattrs
-------+---------+---------+----------+--------+---------
 16414 |   16413 |   16402 | t        |        |
(1 row)
```

##### Subscription option retain_dead_tuples {#pg19-p28-subscription-option-retain-dead-tuples}

The retain_dead_tuples option has been added to subscriptions. Enabling this option causes the subscriber to retain deleted tuples until the remote transaction is completed. When setting the retain_dead_tuples option to "true", the track_commit_timestamp parameter must also be set to "true" (default: "false"). [[228c370](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=228c3708685542d34e6f02c74240656327a5c622)]

**Example 24.** Setting the retain\_dead\_tuples option

```text
postgres=# CREATE SUBSCRIPTION sub1 CONNECTION 'port=5432 dbname=postgres'
PUBLICATION pub1 WITH (RETAIN_DEAD_TUPLES = TRUE) ;
NOTICE:  created replication slot "sub1" on publisher
CREATE SUBSCRIPTION
postgres=# SELECT subname, subretaindeadtuples FROM pg_subscription ;
-[ RECORD 1 ]-------+-----
subname             | sub1
subretaindeadtuples | t
```

##### Subscription option max_retention_duration {#pg19-p28-subscription-option-max-retention-duration}

The max_retention_duration option has been added to subscriptions. This option sets the maximum retention period for non-deletable transaction IDs in environments where the retain_dead_tuples

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-29">PDF page 29</p>

option is enabled. Once this threshold is exceeded, the apply worker stops retaining conflict detection information. The setting for this option can be verified in the submaxretention column of the pg_subscription catalog. [[a850be2](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=a850be2fe653b3b529969946c1cefe0fd9e34a8d)]

**Example 25.** Setting the max\_retention\_duration option

```text
postgres=# CREATE SUBSCRIPTION sub1 CONNECTION 'port=5432 dbname=postgres'
PUBLICATION pub1 WITH (MAX_RETENTION_DURATION = 10, RETAIN_DEAD_TUPLES =
TRUE) ;
NOTICE:  created replication slot "sub1" on publisher
CREATE SUBSCRIPTION
postgres=# SELECT subname, submaxretention, subretentionactive FROM
pg_subscription ;
 subname | submaxretention | subretentionactive
---------+-----------------+--------------------
 sub1    |              10 | t
(1 row)
```

##### Detection of Memory Usage for Decoding {#pg19-p29-detection-of-memory-usage-for-decoding}

The mem_exceeded_count column has been added to the pg_stat_replication_slots view. This column indicates the number of times the memory used for logical decoding exceeded the logical_decoding_work_mem parameter. [[d3b6183](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=d3b6183dd988928dd369b4b7d641917e77f1ae4e)]

**Example 26.** Querying the pg\_stat\_replication\_slots view

```text
postgres=# SELECT slot_name, mem_exceeded_count FROM
pg_stat_replication_slots ;
-[ RECORD 1 ]------+-----
slot_name          | sub1
mem_exceeded_count | 0
```

##### Conflict Detection {#pg19-p29-conflict-detection}

The update_deleted conflict can now be detected when an update on a subscriber conflicts with a local deletion. To use this feature, the retain_dead_tuples option must be enabled on the subscriber. [[fd5a1a0](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=fd5a1a0c3e566f7fc860838084466a1c25944281)]

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-30">PDF page 30</p>

##### Automatic WAL Level Change {#pg19-p30-automatic-wal-level-change}

Even if the wal_level parameter is set to its default value of "replica", the WAL output level is automatically changed to "logical" when a logical replication slot is created. The internal parameter effective_wal_level has been added to indicate this state. When all logical replication slots are deleted, the value of the effective_wal_level parameter reverts to its original state. [[67c2097](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=67c20979ce72b8c236622e5603f9775968ff501c)]

**Example 27.** Automatic Update of WAL Output Level

```text
postgres=# SHOW wal_level ;
 wal_level
-----------
 replica
(1 row)
postgres=# SHOW effective_wal_level ;
 effective_wal_level
---------------------
 replica
(1 row)
postgres=# SELECT
 pg_create_logical_replication_slot('slot1', 'test_decoding') ;
slot_name |    lsn
-----------+------------
 slot1     | 0/95033BD8
(1 row)
postgres=# SHOW effective_wal_level ;
 effective_wal_level
---------------------
 logical
(1 row)
```

#### 3.1.3 Partition Table Enhancements {#pg19-3-1-3-partition-table-enhancements}

The following new features have been implemented in the partition table.

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-31">PDF page 31</p>

##### Merging Partitions {#pg19-p31-merging-partitions}

It is now possible to merge multiple partitions into a single partition using an ALTER TABLE statement on RANGE or LIST partitioned tables. Specify the existing partitions in the MERGE PARTITIONS clause and specify the name of the new partition to be created as the destination in the INTO clause. [[f2e4cc4](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=f2e4cc427951b7c46629fb7625a22f7898586f3a), [713e553](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=713e553e3213d53f4ba25dcb7a8c41994b7cab9d)]

#### Syntax 1 - MERGE PARTITIONS clause {#pg19-syntax-1}

```sql
ALTER TABLE table_name MERGE PARTITIONS (partition#1, partition#2, …)
INTO new_partition
```

The following example merges partitions part1v1 and part1v2 into the part1v12 partition.

**Example 28.** Merging Partitions

```text
postgres=> CREATE TABLE part1(c1 INT PRIMARY KEY, c2 VARCHAR(10))
PARTITION BY RANGE(c1) ;
CREATE TABLE
postgres=> CREATE TABLE part1v1 PARTITION OF part1 FOR VALUES
FROM (0) TO (1000000) ;
CREATE TABLE
postgres=> CREATE TABLE part1v2 PARTITION OF part1 FOR VALUES
FROM (1000000) TO (2000000) ;
CREATE TABLE
postgres=> INSERT INTO part1 VALUES (generate_series(1, 1999999), 'data1') ;
INSERT 0 1999999
postgres=> ALTER TABLE part1 MERGE PARTITIONS (part1v1, part1v2) INTO part1v12 ;
ALTER TABLE
```

```text
RANGE partitions whose data ranges are not contiguous cannot be merged.
```

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-32">PDF page 32</p>

**Example 29.** Partition merge failed

```text
postgres=> CREATE TABLE part2(c1 INT PRIMARY KEY, c2 VARCHAR(10))
PARTITION BY RANGE(c1) ;
CREATE TABLE
postgres=> CREATE TABLE part2v1 PARTITION OF part2 FOR VALUES
FROM (0) TO (1000000) ;
CREATE TABLE
postgres=> CREATE TABLE part2v2 PARTITION OF part2 FOR VALUES
FROM (1000000) TO (2000000) ;
CREATE TABLE
postgres=> CREATE TABLE part2v3 PARTITION OF part2
FOR VALUES FROM (2000000) TO (3000000) ;
CREATE TABLE
postgres=> ALTER TABLE part2 MERGE PARTITIONS (part2v1, part2v3) INTO part2v13 ;
ERROR:  cannot merge partition "part2v3" together with partition "part2v1"
DETAIL:  The lower bound of partition "part2v3" is not equal to the upper bound
of partition "part2v1"
HINT:  ALTER TABLE ... MERGE PARTITIONS requires the partition bounds to be
adjacent.
```

##### Partition Splitting {#pg19-p32-partition-splitting}

It is now possible to split a partition into multiple partitions using the ALTER TABLE statement on RANGE/LIST partition tables. Specify the source partition in the SPLIT PARTITION clause of the ALTER TABLE statement, and specify the destination partitions and partitioning values in the INTO clause. [[4b3d173](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=4b3d173629f4cd7ab6cd700d1053af5d5c7c9e37), [713e553](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=713e553e3213d53f4ba25dcb7a8c41994b7cab9d)]

#### Syntax 2 - SPLIT PARTITION clause {#pg19-syntax-2}

```sql
ALTER TABLE table_name SPLIT PARTITION old_partition INTO
(PARTITION partition#1 VALUES …,
 PARTITION parttiotn#2 VALUES …)
```

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-33">PDF page 33</p>

**Example 30.** Splitting the partition

```text
postgres=> CREATE TABLE part3(c1 INT PRIMARY KEY, c2 VARCHAR(10))
PARTITION BY RANGE(c1) ;
CREATE TABLE
postgres=> CREATE TABLE part3v1 PARTITION OF part3 FOR VALUES
FROM (0) TO (2000000) ;
CREATE TABLE
postgres=> INSERT INTO part3 VALUES (generate_series(1,1999999), 'data1') ;
INSERT 0 1999999
postgres=> ALTER TABLE part3 SPLIT PARTITION part3v1 INTO
(PARTITION part3v2 FOR VALUES FROM (0) TO (1000000),
PARTITION part3v3 FOR VALUES FROM (1000000) TO (2000000)) ;
ALTER TABLE
```

#### 3.1.4 SQL Property Graph {#pg19-3-1-4-sql-property-graph}

PostgreSQL 19 introduces the PROPERTY GRAPH object, which provides graph query features. This feature implements Property Graph Queries (SQL/PGQ) - ISO/IEC 9075-16:2023. PROPERTY GRAPH objects are created using the CREATE PROPERTY GRAPH statement. It creates a table that serves as the source for graph queries and maps it to a PROPERTY GRAPH. VERTEX and NODE, as well as EDGE and RELATIONSHIP, have the same meanings. This document does not provide detailed instructions on how to use it. [[2f094e7](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=2f094e7ac691abc9d2fe0f4dcf0feac4a6ce1d9c)]

#### Syntax 3 - Creating a Property Graph {#pg19-syntax-3}

```sql
CREATE PROPERTY GRAPH name
[{VERTEX|NODE} TABLES (vertex_table_definition [, …])]
[{EDGE|RELATIONSHIP} TABLES (edge_table_definition [, …])]
```

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-34">PDF page 34</p>

**Example 31.** Creating a Property Graph

```text
postgres=> CREATE TABLE member (member_id INT PRIMARY KEY, member_name TEXT) ;
CREATE TABLE
postgres=> CREATE TABLE follow (member_id1 INT, member_id2 INTEGER,
PRIMARY KEY(member_id1, member_id2)) ;
CREATE TABLE
postgres=> CREATE PROPERTY GRAPH graph1
VERTEX TABLES (member KEY (member_id) PROPERTIES (member_id, member_name))
EDGE TABLES (follow
SOURCE KEY (member_id1) REFERENCES member(member_id)
DESTINATION KEY (member_id2) REFERENCES member(member_id)) ;
```

```text
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=2f094e7ac691abc9d2fe0f4dcf0feac4
```

```sql
CREATE PROPERTY GRAPH
```

```text
a6ce1d9c
Several catalogs with names beginning with "pg_prograph" have been added for the Property Graph.
Use the GRAPH_TABLE function to query the Property Graph.
```

**Example 32.** Querying PROPERTY GRAPH

```text
postgres=> SELECT * FROM GRAPH_TABLE (graph1 MATCH
(mem1 IS member)-[follow1 IS follow]->(mem2 IS member)
-[follow2 IS follow]->(mem3 IS member)
WHERE mem1.member_id = mem3.member_id COLUMNS
(mem1.member_id, mem2.member_id)) ;
 member_id | member_id
-----------+-----------
       100 |       200
       200 |       100
(2 rows)
```

#### 3.1.5 SSL/SNI {#pg19-3-1-5-ssl-sni}

PostgreSQL now supports SSL Server Name Indication (SNI) on the server side. This feature is enabled by setting the ssl_sni parameter to "on" (the default value is "off"). To configure SNI, use the pg_hosts.conf file in the database cluster. In the pg_hosts.conf file, enter the following entries, one per line. [[4f43302](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=4f433025f666fa4a6209f0e847715767fb1c7ace)]

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-35">PDF page 35</p>

**Table 14.** Contents of the pg\_hosts\.conf file

| Setting | Description | Note |
| --- | --- | --- |
| HOSTNAME | Hostname (required) |  |
| SSL CERTIFICATE | SSL certificate file (required) |  |
| SSL KEY | SSL private key file (required) |  |
| SSL CA | SSL authentication file (optional) |  |
| PASSPHRASE COMMAND | Passphrase (optional) |  |
| PASSPHRASE COMMAND RELOAD | Reload passphrase (optional) |  |

#### 3.1.6 Dynamic Checksum Configuration {#pg19-3-1-6-dynamic-checksum-configuration}

It is now possible to enable or disable block checksums while the instance is running. To enable checksums, execute the pg_enable_data_checksums function; to disable them, execute the pg_disable_data_checksums function. Enabling checksums is executed by a background worker process. When enabling checksums, the pg_enable_data_checksums function allows specifying the cost_delay parameter (default value 0) and the cost_limit parameter (default value 100), which enables checksums in a behavior similar to VACUUM cost delay. Checksum enablement executes in the background, and progress can be tracked via the pg_stat_progress_data_checksums view. [[f19c0ec](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=f19c0eccae9680f5785b11cdc58ef571998caec9)]

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-36">PDF page 36</p>

**Example 33.** Dynamic Modification of Checksum Settings

```text
postgres=# SHOW data_checksums ;
-[ RECORD 1 ]--+---
data_checksums | on
postgres=# SELECT pg_disable_data_checksums() ;
-[ RECORD 1 ]-------------+-
pg_disable_data_checksums |
postgres=# SHOW data_checksums ;
-[ RECORD 1 ]--+----
data_checksums | off
postgres=# SELECT pg_enable_data_checksums(1, 110) ;
-[ RECORD 1 ]------------+-
pg_enable_data_checksums |
postgres=# SHOW data_checksums ;
-[ RECORD 1 ]--+---
data_checksums | inprogress-on
```

#### 3.1.7 Roles {#pg19-3-1-7-roles}

The pg_read_all_data and pg_write_all_data functions now support reading and writing large objects. In previous versions, the error "ERROR: permission denied for large object {OID}" occurred. [[d981976](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=d98197602790e60ddb63e491cd9768ab9fc410ed)]

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-37">PDF page 37</p>

**Example 34.** Permissions for large objects

```text
postgres=# SELECT lo_create(-1) ;
 lo_create
------------
 4294967295
(1 row)
postgres=# SELECT lo_put(4294967295, 1, E'\\xaa') ;
 lo_put
--------
(1 row)
postgres=# GRANT pg_read_all_data TO user1 ;
GRANT ROLE
postgres=# \connect postgres user1
You are now connected to database "postgres" as user "user1".
postgres=> SELECT lo_get(4294967295) ;
 lo_get
--------
 \x00aa
(1 row)
```

#### 3.1.8 Libpq {#pg19-3-1-8-libpq}

The following APIs have been added or enhanced.

##### Connection string servicefile {#pg19-p37-connection-string-servicefile}

The servicefile option has been added to the connection string to specify a service file. The

```text
PGSERVICEFILE environment variable can still be specified as previously.  [092f3c6]
```

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-38">PDF page 38</p>

**Example 35.** Connection string servicefile

```text
$ psql "servicefile=/tmp/serviceA.conf service=service1"
psql (19beta1)
Type "help" for help.
postgres=#
```

##### Connection string oauth_ca_file {#pg19-p38-connection-string-oauth-ca-file}

The oauth_ca_file option has been added to the connection string to specify an OAuth certificate. The PGOAUTHCAFILE environment variable is now available in non-debug modes as well. [[9933681](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=993368113c432832862db29f927c206dab0c0b8a)]

##### Retrieving Version Information {#pg19-p38-retrieving-version-information}

The get_pg_version function, which retrieves version information from the PG_VERSION file, has been added. This function is used by commands such as pg_resetwal, pg_combinebackup, pg_createsubscriber, and pg_upgrade. [[cd0be13](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=cd0be131ba6f7e8b1323d188db20d15c2504b021)]

##### Other API {#pg19-p38-other-api}

The following APIs have been added. [[fe07100](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=fe07100e82b096d3c848cace790d4b4daf0c4131), [7508169](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=750816971b35270971dd77f37ed1e9655fce4ed9), [e533524](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=e533524b23b8dd504d38c09c9f84b38289ca635d), [b8d7685](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=b8d76858353e40f888c809eb14a974cf13bf23ab)]

**Table 15.** Added API names

| API name | Description | Note |
| --- | --- | --- |
| pg_database_localeGetNamedDSAGetNamedDSHash | Retrieve the database's default locale Assign the DSA Assign the DSA hash |  |
| ParallelSlotSetIdlePQgetThreadLock | Mark ParallelSlot as idle Retrieve lock information for the current thread |  |

#### 3.1.9 I/O Processing {#pg19-3-1-9-i-o-processing}

These are the improvements to I/O processing in PostgreSQL 19.

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-39">PDF page 39</p>

##### Automatic Scaling of Asynchronous I/O Workers {#pg19-p39-automatic-scaling-of-asynchronous-i-o-workers}

The number of I/O workers now automatically increases or decreases in response to load. The number of active I/O workers is determined by the following parameters: As the I/O queue grows, the number of workers increases; if a worker remains idle for a certain period of time, it is stopped. [[d1c01b7](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=d1c01b79d4ae90e52bf9db9c05c9de17b7313e85)]

**Table 16.** Parameters related to I\/O workers

| Parameter name | Description | Default value |
| --- | --- | --- |
| io_min_workers | Minimum number of I/O workers | 2 |
| io_max_workers | Maximum number of I/O workers | 8 |
| io_worker_idle_timeout | Idle time before a worker terminates | 60s |
| io_worker_launch_interval | Interval between worker launches | 100ms |

##### Enhanced Streaming I/O {#pg19-p39-enhanced-streaming-i-o}

PostgreSQL 19 has enhanced the scope of streaming I/O.

- VACUUM for BRIN index [[a6eac22](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=a6eac2273e6e762003e763f45b880261fbd473a4)]

- Data deleting reads for hash index [[bfa3c4f](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=bfa3c4f106b1fb858ead1c8f05332f09d34f664a)]

- Index reads in the Contrib module bloom [[4c910f3](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=4c910f3bbe92aa4e84ff15fa27b4de2da0d7ae50), [d841ca2](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=d841ca2d149666b823525e7f5258efd9ef9d7fb1)]

- Index reads in the Contrib module pgstattuple [[213f007](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=213f0079b3415ad8f5f0a62d119ed1f0a448ad8f)]

##### Improvements to asynchronous I/O processing {#pg19-p39-improvements-to-asynchronous-i-o-processing}

When using io_uring with I/O methods, the behavior has been changed so that synchronous I/O is used for reads of four blocks or fewer. [[a9ee668](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=a9ee66881744d67193b56964b8398e5f83130956), [8ca147d](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=8ca147d582a5a9f3345478654408c46314758b50), [f63ca33](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=f63ca3379025ee4547865182da6cae14aec35d58)]

#### 3.1.10 Automatic Vacuum {#pg19-3-1-10-automatic-vacuum}

The following features have been added to the automatic VACUUM processing.

##### Using Parallel Workers {#pg19-p39-using-parallel-workers}

It is now possible to use parallel workers during automatic VACUUM operations. Automatic VACUUM performs the same processing as the VACUUM (PARALLEL) statement. The number of parallel workers is determined by the autovacuum_max_parallel_workers parameter. The default value for this parameter is 0. Refer to the automatic VACUUM log to verify that parallel workers are launched.

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-40">PDF page 40</p>

**Example 36.** Automatic VACUUM Log

```sql
LOG:  automatic vacuum of table "postgres.public.data1": index scans: 1
…
index scan needed: 5406 pages from table (100.00% of total) had 500000 dead …
parallel workers: index vacuum: 1 planned, 1 launched in total
…
```

##### Prioritization by scoring {#pg19-p40-prioritization-by-scoring}

PostgreSQL 19 introduced the scoring system that determines the execution order of automatic VACUUM operations. It prioritizes tables that deviate the most from the thresholds used to trigger VACUUM and ANALYZE operations. Scores are determined by the newly added pg_stat_autovacuum_scores view. For example, if 100 tuples are updated by an UPDATE statement and the VACUUM threshold is 80, the score will be 1.25. The actual score is determined by multiplying this value by the following parameters, which represent their respective weights. [[87f61f0](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=87f61f0c82806b7e4201f15bd77920e9e7108b11)]

**Table 17.** Parameters related to the score

| Parameter name | Default value | Description |
| --- | --- | --- |
| autovacuum_analyze_score_weight | 1.0 | ANALYZE score weight |
| autovacuum_freeze_score_weight | 1.0 | FREEZE score weight |
| autovacuum_multixact_freeze_score_weight | 1.0 | Multi-Transaction FREEZE score weight |
| autovacuum_vacuum_insert_score_weight | 1.0 | VACUUM INSRT score weight |
| autovacuum_vacuum_score_weight | 1.0 | VACUUM score weight |

The structure of the pg_stat_autovacuum_scores view is as follows.

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-41">PDF page 41</p>

**Table 18.** Structure of the pg\_stat\_autovacuum\_scores view

| Column name | Data type | Description |
| --- | --- | --- |
| relid | oid | OID of the table |
| schemaname | name | Name of the schema |
| relname | name | Name of the table |
| score | double precision | Maximum value of all component scores |
| xid_score | double precision | Transaction ID age score |
| vacuum_score | double precision | Vacuum score |
| vacuum_insert_score | double precision | Vacuum insert score |
| analyze_score | double precision | Analyze score |
| do_vacuum | boolean | Whether autovacuum would vacuum the table |
| do_analyze | boolean | Whether autovacuum would analyze the table |
| for_wraparound | boolean | Whether autovacuum would vacuum the table for wraparound prevention |

**Example 37.** Querying the pg\_stat\_autovacuum\_scores view

```text
postgres=> SELECT * FROM pg_stat_autovacuum_scores WHERE relname='data1' ;
-[ RECORD 1 ]-------+------------------
relid               | 16385
schemaname          | public
relname             | data1
score               | 9.99000999000999
xid_score           | 2e-08
mxid_score          | 0
vacuum_score        | 4.997501249375312
vacuum_insert_score | 0
analyze_score       | 9.99000999000999
do_vacuum           | t
do_analyze          | t
for_wraparound      | f
```

#### 3.1.11 Hook {#pg19-3-1-11-hook}

The following hooks have been added for the planner.

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-42">PDF page 42</p>

##### Hook planner_setup_hook, planner_shutdown_hook {#pg19-p42-hook-planner-setup-hook-planner-shutdown-hook}

The planner_setup_hook hook, which is executed when the PlannerGlobal object is initialized, and the planner_shutdown_hook hook, which is executed immediately before the object is destroyed, have been added. [[94f3ad3](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=94f3ad3961a2cb32d30c79f01a70db4caff13318), [0f4c8d3](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=0f4c8d33d49da012a04076159a008c9fa80bcc47)]

##### Hook joinrel_setup_hook, join_path_setup_hook {#pg19-p42-hook-joinrel-setup-hook-join-path-setup-hook}

The joinrel_setup_hook hook, which is executed when creating table join relations (joinrel), and the join_path_setup_hook hook, which is executed when adding paths to a joinrel, have been added. [[4020b37](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=4020b370f214315b8c10430301898ac21658143f)]

#### 3.1.12 Faster processing {#pg19-3-1-12-faster-processing}

Performance improvements have been implemented through changes to processor instructions and sorting algorithms.

##### Sorting {#pg19-p42-sorting}

Some sorting algorithms have been changed from Quick sort to Radix sort. If there are fewer than 40 items, Quick sort will be used. [[ef3c3cf](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=ef3c3cf6d021ff9884c513afd850a9fe85cad736)]

##### Internal functions hex_encode / hex_decode {#pg19-p42-internal-functions-hex-encode-hex-decode}

The hex_encode and hex_decode functions now support SIMD instructions for the x86-64 and Aarch64 architectures. The larger the input value, the more effective the performance improvement is expected to be. [[ec8719c](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=ec8719ccbfcd78c6b40b5f2b94f60769f3bd08aa)]

##### Page Checksum {#pg19-p42-page-checksum}

If available, AVX2 instructions are used to calculate the page checksum. [[5e13b0f](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=5e13b0f240397b210a0af11f83204d0b4f1713c2)]

##### CRC32C {#pg19-p42-crc32c}

If the Crypto Extension is available on an Arm v8 processor, it is used for CRC32C calculations. [[fbc57f2](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=fbc57f2bc2ee498958a4c5326002af39dd99c90b)]

##### COPY FROM statement {#pg19-p42-copy-from-statement}

Performance has been improved by using SIMD instructions to check for the presence of special characters. [[e0a3a3f](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=e0a3a3fd5361913502ff696ecf47770ca55975ae)]

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-43">PDF page 43</p>

#### 3.1.13 Log Output {#pg19-3-1-13-log-output}

The byte count for full-page images is now included in the logs generated by the automatic ANALYZE operation. [[ad25744](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=ad25744f436ed7809fc754e1a44630b087812fbc)]

**Example 38.** Automatic ANALYZE Log

```text
LOG:  automatic analyze of table "postgres.public.data1"
        avg read rate: 1.486 MB/s, avg write rate: 0.255 MB/s
        buffer usage: 10994 hits, 35 reads, 6 dirtied
        WAL usage: 14 records, 3 full page images, 27293 bytes, 24576 full page
image bytes, 0 buffers full
        system usage: CPU: user: 0.03 s, system: 0.01 s, elapsed: 0.18 s
```

#### 3.1.14 OAuth Authentication {#pg19-3-1-14-oauth-authentication}

The following new features have been added to the OAuth authentication feature.

##### File pg_hba.conf Settings {#pg19-p43-file-pg-hba-conf-settings}

It is now possible to specify OAuth validator information in the pg_hba.conf options. The following is an example of pg_hba.conf from the manual. [[b977bd3](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=b977bd308a09e8a70db1776db80e8abd84ca2b7e)]

**Example 39.** OAuth settings in the pg\_hba\.conf file

```text
hostssl  postgres   admin  0.0.0.0/0  oauth issuer=https://admin.example.com \
                                            scope="pg-admin openid email" \
                                            map=oauth-email \
                                            validator=my_validator \
                                            validator.foo="admin access" \
     validator.bar=https://magic.example.com
```

##### Validator Error Output {#pg19-p43-validator-error-output}

The following parameters have been added to control how errors generated by the validator are logged. [[d438a36](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=d438a36591c58f60e0748b341855ec5519e1e3b4)]

<p class="feature-page-marker" id="pgfeat-19-architecture-pdf-page-44">PDF page 44</p>

**Table 19.** Added parameters

| Parameter name | Description | Default value |
| --- | --- | --- |
| oauth_validator.error_detail | Error information contained in DETAIL | '' |
| oauth_validator.internal_error | Whether to output internal errors | false |

#### 3.1.15 Wait Events {#pg19-3-1-15-wait-events}

The following wait events have been added. [[6c5c393](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=6c5c393b74031351721f8a44e55bfaf6f249eefb), [e05a24c](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=e05a24c2d4eab3dd76741dc6e6c18bb0584771c5), [7a39f43](https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=7a39f43d885b44a78f366aa50535944c4e38bdbb)]

**Table 20.** Added Wait Events

| Wait event name | Description | Note |
| --- | --- | --- |
| WaitEventBufferCOPY_FROM_READCOPY_TO_WRITE | Waiting for the data buffer Waiting for the COPY FROM read Waiting for the COPY TO write | Changed from WaitEventBufferPin |
| WAIT_FOR_WAL_WRITE | Waiting to write to the standby |  |
