diff options
| author | Andres Freund | 2025-03-17 22:51:33 +0000 |
|---|---|---|
| committer | Andres Freund | 2025-03-17 22:51:33 +0000 |
| commit | 02844012b304ba80d1c48d51f6fe10bb622490cc (patch) | |
| tree | c7753eb6c900a00ebdaa2311b87aefbb21d9f588 /src/backend/utils | |
| parent | 65db3963ae7154b8f01e4d73dc6b1ffd81c70e1e (diff) | |
aio: Basic subsystem initialization
This commit just does the minimal wiring up of the AIO subsystem, added in the
next commit, to the rest of the system. The next commit contains more details
about motivation and architecture.
This commit is kept separate to make it easier to review, separating the
changes across the tree, from the implementation of the new subsystem.
We discussed squashing this commit with the main commit before merging AIO,
but there has been a mild preference for keeping it separate.
Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi>
Reviewed-by: Noah Misch <noah@leadboat.com>
Discussion: https://postgr.es/m/uvrtrknj4kdytuboidbhwclo4gxhswwcpgadptsjvjqcluzmah%40brqs62irg4dt
Diffstat (limited to 'src/backend/utils')
| -rw-r--r-- | src/backend/utils/init/postinit.c | 7 | ||||
| -rw-r--r-- | src/backend/utils/misc/guc_tables.c | 23 | ||||
| -rw-r--r-- | src/backend/utils/misc/postgresql.conf.sample | 6 | ||||
| -rw-r--r-- | src/backend/utils/resowner/resowner.c | 29 |
4 files changed, 65 insertions, 0 deletions
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 4b2faf1ba9d..7958ea11b73 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -43,6 +43,7 @@ #include "replication/slot.h" #include "replication/slotsync.h" #include "replication/walsender.h" +#include "storage/aio_subsys.h" #include "storage/bufmgr.h" #include "storage/fd.h" #include "storage/ipc.h" @@ -635,6 +636,12 @@ BaseInit(void) */ pgstat_initialize(); + /* + * Initialize AIO before infrastructure that might need to actually + * execute AIO. + */ + pgaio_init_backend(); + /* Do local initialization of storage and buffer managers */ InitSync(); smgrinit(); diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index 9c0b10ad4dc..0d3ebf06a95 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -72,6 +72,7 @@ #include "replication/slot.h" #include "replication/slotsync.h" #include "replication/syncrep.h" +#include "storage/aio.h" #include "storage/bufmgr.h" #include "storage/bufpage.h" #include "storage/large_object.h" @@ -3255,6 +3256,18 @@ struct config_int ConfigureNamesInt[] = }, { + {"io_max_concurrency", + PGC_POSTMASTER, + RESOURCES_IO, + gettext_noop("Max number of IOs that one process can execute simultaneously."), + NULL, + }, + &io_max_concurrency, + -1, -1, 1024, + check_io_max_concurrency, NULL, NULL + }, + + { {"backend_flush_after", PGC_USERSET, RESOURCES_IO, gettext_noop("Number of pages after which previously performed writes are flushed to disk."), gettext_noop("0 disables forced writeback."), @@ -5311,6 +5324,16 @@ struct config_enum ConfigureNamesEnum[] = NULL, NULL, NULL }, + { + {"io_method", PGC_POSTMASTER, RESOURCES_IO, + gettext_noop("Selects the method for executing asynchronous I/O."), + NULL + }, + &io_method, + DEFAULT_IO_METHOD, io_method_options, + NULL, assign_io_method, NULL + }, + /* End-of-list marker */ { {NULL, 0, 0, NULL, NULL}, NULL, 0, NULL, NULL, NULL, NULL diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 8de86e0c945..43c2ec2153e 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -202,6 +202,12 @@ #maintenance_io_concurrency = 10 # 1-1000; 0 disables prefetching #io_combine_limit = 128kB # usually 1-32 blocks (depends on OS) +#io_method = sync # sync (change requires restart) +#io_max_concurrency = -1 # Max number of IOs that one process + # can execute simultaneously + # -1 sets based on shared_buffers + # (change requires restart) + # - Worker Processes - #max_worker_processes = 8 # (change requires restart) diff --git a/src/backend/utils/resowner/resowner.c b/src/backend/utils/resowner/resowner.c index ac5ca4a765e..d39f3e1b655 100644 --- a/src/backend/utils/resowner/resowner.c +++ b/src/backend/utils/resowner/resowner.c @@ -47,6 +47,8 @@ #include "common/hashfn.h" #include "common/int.h" +#include "lib/ilist.h" +#include "storage/aio.h" #include "storage/ipc.h" #include "storage/predicate.h" #include "storage/proc.h" @@ -155,6 +157,12 @@ struct ResourceOwnerData /* The local locks cache. */ LOCALLOCK *locks[MAX_RESOWNER_LOCKS]; /* list of owned locks */ + + /* + * AIO handles need be registered in critical sections and therefore + * cannot use the normal ResourceElem mechanism. + */ + dlist_head aio_handles; }; @@ -425,6 +433,8 @@ ResourceOwnerCreate(ResourceOwner parent, const char *name) parent->firstchild = owner; } + dlist_init(&owner->aio_handles); + return owner; } @@ -725,6 +735,13 @@ ResourceOwnerReleaseInternal(ResourceOwner owner, * so issue warnings. In the abort case, just clean up quietly. */ ResourceOwnerReleaseAll(owner, phase, isCommit); + + while (!dlist_is_empty(&owner->aio_handles)) + { + dlist_node *node = dlist_head_node(&owner->aio_handles); + + pgaio_io_release_resowner(node, !isCommit); + } } else if (phase == RESOURCE_RELEASE_LOCKS) { @@ -1082,3 +1099,15 @@ ResourceOwnerForgetLock(ResourceOwner owner, LOCALLOCK *locallock) elog(ERROR, "lock reference %p is not owned by resource owner %s", locallock, owner->name); } + +void +ResourceOwnerRememberAioHandle(ResourceOwner owner, struct dlist_node *ioh_node) +{ + dlist_push_tail(&owner->aio_handles, ioh_node); +} + +void +ResourceOwnerForgetAioHandle(ResourceOwner owner, struct dlist_node *ioh_node) +{ + dlist_delete_from(&owner->aio_handles, ioh_node); +} |
