BUG #19369: Not documented that io_uring on kernel versions between 5.1 and below 5.6 does not work - Mailing list pgsql-bugs

From PG Bug reporting form
Subject BUG #19369: Not documented that io_uring on kernel versions between 5.1 and below 5.6 does not work
Date
Msg-id 19369-aa853da20e970a89@postgresql.org
Whole thread Raw
Responses Re: BUG #19369: Not documented that io_uring on kernel versions between 5.1 and below 5.6 does not work
List pgsql-bugs
The following bug has been logged on the website:

Bug reference:      19369
Logged by:          Evan Si
Email address:      evsi@amazon.com
PostgreSQL version: 18.1
Operating system:   Amazon Linux 2
Description:

Hello,

The documentation doesn't explicitly state a minimum kernel version for
io_uring, but in src/backend/storage/aio/README.md, it claims that:

> io_method=io_uring is available on Linux 5.1+.

Attempting to set io_method to io_uring on versions without io_uring at all
(below 5.1) causes the server to graciously report that "[the k]ernel does
not support io_uring".
But setting io_uring on kernel versions between 5.1 and 5.6 sees the server
start but connections failing with EINVAL.

```
[ec2-user@ip-172-31-56-49 postgres]$ psql postgres
psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed:
FATAL:  could not read blocks 0..0 in file "global/1260": Invalid argument
```

It seems like the implementation in postgres leverages non-vectored I/O
(i.e. io_uring_prep_read and io_uring_prep_write) in
src/backend/storage/aio/method_io_uring.c.

But, these opcodes aren't actually available until kernel 5.6
(https://github.com/axboe/liburing/issues/44),
(https://man7.org/linux/man-pages/man2/io_uring_enter.2.html - under
IORING_OP_READ, IORING_OP_WRITE).

It seems kernel 5.4 LTS ended last month, but this seems worth clarifying, I
think.

--

Precise reproduction example:

OS details
```
[ec2-user@ip-172-31-56-49 postgres]$ uname -a
Linux ip-172-31-56-49.us-west-2.compute.internal
5.4.301-221.450.amzn2.x86_64 #1 SMP Tue Nov 18 16:40:04 UTC 2025 x86_64
x86_64 x86_64 GNU/Linux
```

Build postgres with liburing 2.8, set postgresql.conf with
io_method=io_uring, log_min_messages = debug3.

Postgres starts without complaint, but trying to connect will fail:

```
[ec2-user@ip-172-31-56-49 postgres]$ psql postgres
psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed:
FATAL:  could not read blocks 0..0 in file "global/1260": Invalid argument
```
Inside logfile:
```
2026-01-02 22:35:43.862 UTC [8517] DEBUG:  io 6400      |op invalid|target
invalid|state HANDED_OUT      : adding cb #1, id
2/aio_shared_buffer_readv_cb
2026-01-02 22:35:43.862 UTC [8517] DEBUG:  io 6400      |op invalid|target
smgr|state HANDED_OUT      : adding cb #2, id 1/aio_md_readv_cb
2026-01-02 22:35:43.863 UTC [8517] DEBUG:  io 6400      |op readv|target
smgr|state DEFINED         : calling cb #1
2/aio_shared_buffer_readv_cb->stage(0)
2026-01-02 22:35:43.863 UTC [8517] DEBUG:  io 6400      |op readv|target
smgr|state STAGED          : staged (synchronous: 0, in_batch: 1)
2026-01-02 22:35:43.863 UTC [8517] DEBUG:  io 6400      |op readv|target
smgr|state SUBMITTED       : wait_one io_gen: 3, ref_gen: 3, cycle 0
2026-01-02 22:35:43.863 UTC [8517] LOG:  could not read blocks 0..0 in file
"global/1262": Invalid argument
2026-01-02 22:35:43.863 UTC [8517] DEBUG:  io 6400      |op readv|target
smgr|state COMPLETED_IO    : after shared completion: distilled result:
(status ERROR, id 1, error_data: 22, result 0), raw_result: -22
2026-01-02 22:35:43.863 UTC [8517] DEBUG:  io 6400      |op readv|target
smgr|state COMPLETED_SHARED: after local completion: result: (status ERROR,
id 1, error_data 22, result 0), raw_result: -22
2026-01-02 22:35:43.863 UTC [8517] DEBUG:  drained 1/1, now expecting 0
2026-01-02 22:35:43.863 UTC [8517] DEBUG:  io 6400      |op invalid|target
invalid|state IDLE            : wait_one io_gen: 4, ref_gen: 3, cycle 0
2026-01-02 22:35:43.863 UTC [8517] DEBUG:  wait_one with 0 sleeps
2026-01-02 22:35:43.863 UTC [8517] ERROR:  could not read blocks 0..0 in
file "global/1262": Invalid argument
2026-01-02 22:35:44.057 UTC [8512] DEBUG:  assigned pm child slot 1 for
backend
2026-01-02 22:35:44.058 UTC [8512] DEBUG:  forked new client backend,
pid=8521 socket=151
2026-01-02 22:35:44.058 UTC [8521] DEBUG:  InitPostgres
2026-01-02 22:35:44.059 UTC [8521] DEBUG:  io 0         |op invalid|target
invalid|state HANDED_OUT      : adding cb #1, id
2/aio_shared_buffer_readv_cb
2026-01-02 22:35:44.059 UTC [8521] DEBUG:  io 0         |op invalid|target
smgr|state HANDED_OUT      : adding cb #2, id 1/aio_md_readv_cb
2026-01-02 22:35:44.059 UTC [8521] DEBUG:  io 0         |op readv|target
smgr|state DEFINED         : calling cb #1
2/aio_shared_buffer_readv_cb->stage(0)
2026-01-02 22:35:44.059 UTC [8521] DEBUG:  io 0         |op readv|target
smgr|state STAGED          : staged (synchronous: 0, in_batch: 1)
2026-01-02 22:35:44.059 UTC [8521] DEBUG:  io 0         |op readv|target
smgr|state SUBMITTED       : wait_one io_gen: 1, ref_gen: 1, cycle 0
2026-01-02 22:35:44.059 UTC [8521] LOG:  could not read blocks 0..0 in file
"global/1260": Invalid argument
2026-01-02 22:35:44.059 UTC [8521] DEBUG:  io 0         |op readv|target
smgr|state COMPLETED_IO    : after shared completion: distilled result:
(status ERROR, id 1, error_data: 22, result 0), raw_result: -22
2026-01-02 22:35:44.059 UTC [8521] DEBUG:  io 0         |op readv|target
smgr|state COMPLETED_SHARED: after local completion: result: (status ERROR,
id 1, error_data 22, result 0), raw_result: -22
2026-01-02 22:35:44.059 UTC [8521] DEBUG:  drained 1/1, now expecting 0
2026-01-02 22:35:44.059 UTC [8521] DEBUG:  io 0         |op invalid|target
invalid|state IDLE            : wait_one io_gen: 2, ref_gen: 1, cycle 0
2026-01-02 22:35:44.059 UTC [8521] DEBUG:  wait_one with 0 sleeps
2026-01-02 22:35:44.059 UTC [8521] FATAL:  could not read blocks 0..0 in
file "global/1260": Invalid argument
2026-01-02 22:35:44.059 UTC [8521] DEBUG:  shmem_exit(1): 5
before_shmem_exit callbacks to make
2026-01-02 22:35:44.059 UTC [8521] DEBUG:  shmem_exit(1): 7 on_shmem_exit
callbacks to make
2026-01-02 22:35:44.059 UTC [8521] DEBUG:  proc_exit(1): 2 callbacks to make
2026-01-02 22:35:44.059 UTC [8521] DEBUG:  exit(1)
2026-01-02 22:35:44.059 UTC [8521] DEBUG:  shmem_exit(-1): 0
before_shmem_exit callbacks to make
2026-01-02 22:35:44.059 UTC [8521] DEBUG:  shmem_exit(-1): 0 on_shmem_exit
callbacks to make
2026-01-02 22:35:44.059 UTC [8521] DEBUG:  proc_exit(-1): 0 callbacks to
make
2026-01-02 22:35:44.060 UTC [8512] DEBUG:  releasing pm child slot 1
2026-01-02 22:35:44.060 UTC [8512] DEBUG:  client backend (PID 8521) exited
with exit code 1
2026-01-02 22:35:44.863 UTC [8517] DEBUG:  io 6400      |op invalid|target
invalid|state HANDED_OUT      : adding cb #1, id
2/aio_shared_buffer_readv_cb
2026-01-02 22:35:44.863 UTC [8517] DEBUG:  io 6400      |op invalid|target
smgr|state HANDED_OUT      : adding cb #2, id 1/aio_md_readv_cb
2026-01-02 22:35:44.863 UTC [8517] DEBUG:  io 6400      |op readv|target
smgr|state DEFINED         : calling cb #1
2/aio_shared_buffer_readv_cb->stage(0)
2026-01-02 22:35:44.863 UTC [8517] DEBUG:  io 6400      |op readv|target
smgr|state STAGED          : staged (synchronous: 0, in_batch: 1)
2026-01-02 22:35:44.863 UTC [8517] DEBUG:  io 6400      |op readv|target
smgr|state SUBMITTED       : wait_one io_gen: 4, ref_gen: 4, cycle 0
2026-01-02 22:35:44.863 UTC [8517] LOG:  could not read blocks 0..0 in file
"global/1262": Invalid argument
2026-01-02 22:35:44.863 UTC [8517] DEBUG:  io 6400      |op readv|target
smgr|state COMPLETED_IO    : after shared completion: distilled result:
(status ERROR, id 1, error_data: 22, result 0), raw_result: -22
2026-01-02 22:35:44.863 UTC [8517] DEBUG:  io 6400      |op readv|target
smgr|state COMPLETED_SHARED: after local completion: result: (status ERROR,
id 1, error_data 22, result 0), raw_result: -22
2026-01-02 22:35:44.863 UTC [8517] DEBUG:  drained 1/1, now expecting 0
2026-01-02 22:35:44.863 UTC [8517] DEBUG:  io 6400      |op invalid|target
invalid|state IDLE            : wait_one io_gen: 5, ref_gen: 4, cycle 0
2026-01-02 22:35:44.863 UTC [8517] DEBUG:  wait_one with 0 sleeps
2026-01-02 22:35:44.863 UTC [8517] ERROR:  could not read blocks 0..0 in
file "global/1262": Invalid argument
```


pgsql-bugs by date:

Previous
From: Paul A Jungwirth
Date:
Subject: Re: BUG #19098: Can't create unique gist index, where pg_indexes says that WITHOUT OVERLAPS does exacly that
Next
From: Marian Muller Rebeyrol
Date:
Subject: Re: BUG #19353: Error XX000 if referencing expanded array in grouping set: variable not found in subplan target list