diff options
author | Andres Freund | 2025-03-18 18:40:05 +0000 |
---|---|---|
committer | Andres Freund | 2025-03-26 23:49:13 +0000 |
commit | c325a7633fcb33dbd73f46ddbbe91e95ddf3b227 (patch) | |
tree | 0aa7ab5b32bd5dd26eef0aff6b4d4b200a771d75 /src/include/storage | |
parent | 8eadd5c73c44708ecd45b9fd3ac54a550511d16f (diff) |
aio: Add io_method=io_uring
Performing AIO using io_uring can be considerably faster than
io_method=worker, particularly when lots of small IOs are issued, as
a) the context-switch overhead for worker based AIO becomes more significant
b) the number of IO workers can become limiting
io_uring, however, is linux specific and requires an additional compile-time
dependency (liburing).
This implementation is fairly simple and there are substantial optimization
opportunities.
The description of the existing AIO_IO_COMPLETION wait event is updated to
make the difference between it and the new AIO_IO_URING_EXECUTION clearer.
Reviewed-by: Noah Misch <[email protected]>
Reviewed-by: Jakub Wartak <[email protected]>
Discussion: https://postgr.es/m/uvrtrknj4kdytuboidbhwclo4gxhswwcpgadptsjvjqcluzmah%40brqs62irg4dt
Discussion: https://postgr.es/m/[email protected]
Discussion: https://postgr.es/m/stj36ea6yyhoxtqkhpieia2z4krnam7qyetc57rfezgk4zgapf@gcnactj4z56m
Diffstat (limited to 'src/include/storage')
-rw-r--r-- | src/include/storage/aio.h | 8 | ||||
-rw-r--r-- | src/include/storage/aio_internal.h | 13 | ||||
-rw-r--r-- | src/include/storage/lwlock.h | 1 |
3 files changed, 22 insertions, 0 deletions
diff --git a/src/include/storage/aio.h b/src/include/storage/aio.h index 25da0a31d18..cc987556e14 100644 --- a/src/include/storage/aio.h +++ b/src/include/storage/aio.h @@ -22,12 +22,20 @@ #include "storage/procnumber.h" +/* io_uring is incompatible with EXEC_BACKEND */ +#if defined(USE_LIBURING) && !defined(EXEC_BACKEND) +#define IOMETHOD_IO_URING_ENABLED +#endif + /* Enum for io_method GUC. */ typedef enum IoMethod { IOMETHOD_SYNC = 0, IOMETHOD_WORKER, +#ifdef IOMETHOD_IO_URING_ENABLED + IOMETHOD_IO_URING, +#endif } IoMethod; /* We'll default to worker based execution. */ diff --git a/src/include/storage/aio_internal.h b/src/include/storage/aio_internal.h index d7109706151..fb0425ccbfc 100644 --- a/src/include/storage/aio_internal.h +++ b/src/include/storage/aio_internal.h @@ -248,6 +248,15 @@ typedef struct PgAioCtl */ typedef struct IoMethodOps { + /* properties */ + + /* + * If an FD is about to be closed, do we need to wait for all in-flight + * IOs referencing that FD? + */ + bool wait_on_fd_before_close; + + /* global initialization */ /* @@ -314,6 +323,7 @@ extern PgAioResult pgaio_io_call_complete_local(PgAioHandle *ioh); /* aio_io.c */ extern void pgaio_io_perform_synchronously(PgAioHandle *ioh); extern const char *pgaio_io_get_op_name(PgAioHandle *ioh); +extern bool pgaio_io_uses_fd(PgAioHandle *ioh, int fd); /* aio_target.c */ extern bool pgaio_io_can_reopen(PgAioHandle *ioh); @@ -386,6 +396,9 @@ extern PgAioHandle *pgaio_inj_io_get(void); /* Declarations for the tables of function pointers exposed by each IO method. */ extern PGDLLIMPORT const IoMethodOps pgaio_sync_ops; extern PGDLLIMPORT const IoMethodOps pgaio_worker_ops; +#ifdef IOMETHOD_IO_URING_ENABLED +extern PGDLLIMPORT const IoMethodOps pgaio_uring_ops; +#endif extern PGDLLIMPORT const IoMethodOps *pgaio_method_ops; extern PGDLLIMPORT PgAioCtl *pgaio_ctl; diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h index ffa03189e2d..4df1d25c045 100644 --- a/src/include/storage/lwlock.h +++ b/src/include/storage/lwlock.h @@ -218,6 +218,7 @@ typedef enum BuiltinTrancheIds LWTRANCHE_SUBTRANS_SLRU, LWTRANCHE_XACT_SLRU, LWTRANCHE_PARALLEL_VACUUM_DSA, + LWTRANCHE_AIO_URING_COMPLETION, LWTRANCHE_FIRST_USER_DEFINED, } BuiltinTrancheIds; |