Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tw95Q-00B9YF-8n for pgsql-hackers@arkaria.postgresql.org; Sun, 23 Mar 2025 00:21:08 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1tw95N-005MvI-DD for pgsql-hackers@arkaria.postgresql.org; Sun, 23 Mar 2025 00:21:05 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tw95M-005MvA-R4 for pgsql-hackers@lists.postgresql.org; Sun, 23 Mar 2025 00:21:05 +0000 Received: from mail-pl1-x62e.google.com ([2607:f8b0:4864:20::62e]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1tw95J-000aTH-0F for pgsql-hackers@postgresql.org; Sun, 23 Mar 2025 00:21:04 +0000 Received: by mail-pl1-x62e.google.com with SMTP id d9443c01a7336-22398e09e39so64641285ad.3 for ; Sat, 22 Mar 2025 17:21:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=leadboat.com; s=google; t=1742689258; x=1743294058; darn=postgresql.org; h=user-agent:in-reply-to:content-disposition:mime-version:references :message-id:subject:cc:to:from:date:from:to:cc:subject:date :message-id:reply-to; bh=nd77U4l7GTSZk7DGAEH+H+JxmObr7hojm777W0gi6BI=; b=acnyYYhVEjIFpXkDB4qQ1K+aTiQpUV+8BEZdQbwIVNCpXXboXFcRFY+g4EqS7jgi8s qelacOHJgb7CsbQomO9jJSinq6saDexg0QZV5YnphQ8S0e1CsrINTifj2YmUPY4Ic65K tB0TVYOR0expfTK3kHBdMx5TRe2YfM1bSNkQA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742689258; x=1743294058; h=user-agent:in-reply-to:content-disposition:mime-version:references :message-id:subject:cc:to:from:date:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nd77U4l7GTSZk7DGAEH+H+JxmObr7hojm777W0gi6BI=; b=DNRMK9kuIyE4wGWWABPEU98Pj3dXr9GItYp6XMcIqN1xzeLXp9Zpi9CI7Yx/swGpw5 1ZPsMfe7rTMi2tE32AmcBCqmLrfOcNTM33ypu1U0woHC+BxNfNa5EYwJ9GuaiI4C3/d7 10oPN4gBXNoWVaFpARnjEc2OqEyV/vQzrzU6p42fPEErsa2q73NkawP79DxU+K/TvmnT 6IzNZRSgM9eV/LpUbEoL/HWfoJttzOy9TOrlZdMcc2EJIpPhbE7Wzr88vC2Q9ielUWlX YpsNuLieibnJrDb6vBSYruXQ4xERkMacY2k5kMFSvEEH+qS2+h76XpxYwCmy6DurrCej rD0Q== X-Forwarded-Encrypted: i=1; AJvYcCWtNiz2/uR3DJmz3om6JHe0f3+KLFY4gSr71ogmb75a34ud6zxnRjPxYbqQW9IjMvGgx6p2gtu9XgVdY6NJ@postgresql.org X-Gm-Message-State: AOJu0YzBP40rHCs3Rj7Yd6uPr6BPoK7CUgsS5PUBRi21k8GDF5YSf/uJ 7GXlzyPYXrs+JTPaMCAjZh48og91OX3dk+ACVSgL6/F6PBPqYuH/22HVjfAkeA== X-Gm-Gg: ASbGnctJkn32GJ18gNg/ZkuLFni4B24ZllYrv7FyDwrLlY8YcOhD/mv03Z6qquDeBpf 3JyQcSfES5nldZBpOwqZVdhnSqxbdgQ4YzKuT8N0sThv+rsHdhBeuA+s7yGgWgM1oDQ2Yqz4vMp E2hqYRH7876M05X4oCvn6c1qkPAXGArdSJaSuDuCHPgYWuADa5wH/+YpeTQhBmAmddPfPGJG0Qf Ynlt+Oazyw757xPuUB9llpvc/IrMyX/Y6cpwQM3SwiFW2FTMwCvDUk8tkGfHTCMRQ5jDkBREK20 03gbJ0FKLy3sxl1425Rd/hB4ep/cyO2WngOraM7lGuDJie3slDs6 X-Google-Smtp-Source: AGHT+IFNw+FOf0LSpXKH8hqSPbjXDBURcN6BIuX9G1z2+kkqzCtzhHQVgX3Ei3DAsSlAVMRpfz/lBw== X-Received: by 2002:a17:903:22c7:b0:220:d601:a704 with SMTP id d9443c01a7336-22780c7b0b8mr100840265ad.18.1742689258459; Sat, 22 Mar 2025 17:20:58 -0700 (PDT) Received: from google.com ([2601:647:5600:80d0::31cd]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-22780f45954sm41715225ad.62.2025.03.22.17.20.57 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 22 Mar 2025 17:20:57 -0700 (PDT) Date: Sat, 22 Mar 2025 17:20:56 -0700 From: Noah Misch To: Andres Freund Cc: Antonin Houska , pgsql-hackers@postgresql.org, Thomas Munro , Heikki Linnakangas , Robert Haas , Jakub Wartak , Jelte Fennema-Nio Subject: Re: AIO v2.5 Message-ID: <20250323002056.95.nmisch@google.com> References: <20250311194108.c5.nmisch@google.com> <5dzyoduxlvfg55oqtjyjehez5uoq6hnwgzor4kkybkfdgkj7ag@rbi4gsmzaczk> <20250312035743.f5.nmisch@google.com> <4b3f32ug3cayekysqlgspz2qjmeb7lca3gvazayglxr2m3d4dv@il33accgsji7> <17906.1741863183@localhost> <3yxd5r23zly5bytvgyktbxtxq2r3gbpi7xd4dugevh3h4w4q6c@lu6oatjjpltz> <6ak556uyqiptdwjaci4kbi5eykwkmzqgkbtkyaosjnopjhncrc@2v4ac2jwyz22> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <6ak556uyqiptdwjaci4kbi5eykwkmzqgkbtkyaosjnopjhncrc@2v4ac2jwyz22> User-Agent: Mutt/2.2.12 (2023-09-09) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Thu, Mar 20, 2025 at 09:58:37PM -0400, Andres Freund wrote: > Attached v2.11, with the following changes: > - Added an error check for FileStartReadV() failing > > FileStartReadV() actually can fail, if the file can't be re-opened. I > thought it'd be important for the error message to differ from the one > that's issued for read actually failing, so I went with: > > "could not start reading blocks %u..%u in file \"%s\": %m" > > but I'm not sure how good that is. Message looks good. > - Improved error message if io_uring_queue_init() fails > > Added errhint()s for likely cases of failure. > > Added errcode(). I was tempted to use errcode_for_file_access(), but that > doesn't support ENOSYS - perhaps I should add that instead? Either way is fine with me. ENOSYS -> ERRCODE_FEATURE_NOT_SUPPORTED is a good general mapping to have in errcode_for_file_access(), but it's also not a problem to keep it the way v2.11 has it. > - Disable io_uring method when using EXEC_BACKEND, they're not compatible > > I chose to do this with a define aio.h, but I guess we could also do it at > configure time? That seems more complicated though - how would we even know > that EXEC_BACKEND is used on non-windows? Agreed, "make PROFILE=-DEXEC_BACKEND" is a valid way to get EXEC_BACKEND. > Not sure yet how to best disable testing io_uring in this case. We can't > just query EXEC_BACKEND from pg_config.h unfortunately. I guess making the > initdb not fail and checking the error log would work, but that doesn't work > nicely with Cluster.pm. How about "postgres -c io_method=io_uring -C ": --- a/src/test/modules/test_aio/t/001_aio.pl +++ b/src/test/modules/test_aio/t/001_aio.pl @@ -29,7 +29,13 @@ $node_worker->stop(); # Test io_method=io_uring ### -if ($ENV{with_liburing} eq 'yes') +sub have_io_uring +{ + local %ENV = $node_worker->_get_env(); # any node works + return run_log [qw(postgres -c io_method=io_uring -C io_method)]; +} + +if (have_io_uring()) { my $node_uring = create_node('io_uring'); $node_uring->start(); > Questions: > > > - We only "look" at BM_IO_ERROR for writes, isn't that somewhat weird? > > See AbortBufferIO(Buffer buffer) > > It doesn't really matter for the patchset, but it just strikes me as an oddity. That caught my attention in an earlier review round, but I didn't find it important enough to raise. It's mildly unfortunate to be setting BM_IO_ERROR for reads when the only thing BM_IO_ERROR drives is message "Multiple failures --- write error might be permanent." It's minor, so let's leave it that way for the foreseeable future. > Subject: [PATCH v2.11 01/27] aio, bufmgr: Comment fixes Ready to commit, though other comment fixes might come up in later reviews. One idea so far is to comment on valid states after some IoMethodOps callbacks: --- a/src/include/storage/aio_internal.h +++ b/src/include/storage/aio_internal.h @@ -310,6 +310,9 @@ typedef struct IoMethodOps /* * Start executing passed in IOs. * + * Shall advance state to PGAIO_HS_SUBMITTED. (By the time this returns, + * other backends might have advanced the state further.) + * * Will not be called if ->needs_synchronous_execution() returned true. * * num_staged_ios is <= PGAIO_SUBMIT_BATCH_SIZE. @@ -321,6 +324,12 @@ typedef struct IoMethodOps /* * Wait for the IO to complete. Optional. * + * On return, state shall be PGAIO_HS_COMPLETED_IO, + * PGAIO_HS_COMPLETED_SHARED or PGAIO_HS_COMPLETED_LOCAL. (The callback + * need not change the state if it's already one of those.) If state is + * PGAIO_HS_COMPLETED_IO, state will reach PGAIO_HS_COMPLETED_SHARED + * without further intervention. + * * If not provided, it needs to be guaranteed that the IO method calls * pgaio_io_process_completion() without further interaction by the * issuing backend. > Subject: [PATCH v2.11 02/27] aio: Change prefix of PgAioResultStatus values to > PGAIO_RS_ Ready to commit > Subject: [PATCH v2.11 03/27] Redefine max_files_per_process to control > additionally opened files Ready to commit > Subject: [PATCH v2.11 04/27] aio: Add liburing dependency > --- a/meson.build > +++ b/meson.build > @@ -944,6 +944,18 @@ endif > > > > +############################################################### > +# Library: liburing > +############################################################### > + > +liburingopt = get_option('liburing') > +liburing = dependency('liburing', required: liburingopt) > +if liburing.found() > + cdata.set('USE_LIBURING', 1) > +endif This is a different style from other deps; is it equivalent to our standard style? Example for lz4: lz4opt = get_option('lz4') if not lz4opt.disabled() lz4 = dependency('liblz4', required: false) # Unfortunately the dependency is named differently with cmake if not lz4.found() # combine with above once meson 0.60.0 is required lz4 = dependency('lz4', required: lz4opt, method: 'cmake', modules: ['LZ4::lz4_shared'], ) endif if lz4.found() cdata.set('USE_LZ4', 1) cdata.set('HAVE_LIBLZ4', 1) endif else lz4 = not_found_dep endif > --- a/configure.ac > +++ b/configure.ac > @@ -975,6 +975,14 @@ AC_SUBST(with_readline) > PGAC_ARG_BOOL(with, libedit-preferred, no, > [prefer BSD Libedit over GNU Readline]) > > +# > +# liburing > +# > +AC_MSG_CHECKING([whether to build with liburing support]) > +PGAC_ARG_BOOL(with, liburing, no, [io_uring support, for asynchronous I/O], Fourth arg generally starts with "build" for args like this. I suggest "build with io_uring support, for asynchronous I/O". Comparable options: --with-llvm build with LLVM based JIT support --with-tcl build Tcl modules (PL/Tcl) --with-perl build Perl modules (PL/Perl) --with-python build Python modules (PL/Python) --with-gssapi build with GSSAPI support --with-pam build with PAM support --with-bsd-auth build with BSD Authentication support --with-ldap build with LDAP support --with-bonjour build with Bonjour support --with-selinux build with SELinux support --with-systemd build with systemd support --with-libcurl build with libcurl support --with-libxml build with XML support --with-libxslt use XSLT support when building contrib/xml2 --with-lz4 build with LZ4 support --with-zstd build with ZSTD support > + [AC_DEFINE([USE_LIBURING], 1, [Define to build with io_uring support. (--with-liburing)])]) > +AC_MSG_RESULT([$with_liburing]) > +AC_SUBST(with_liburing) > > # > # UUID library > @@ -1463,6 +1471,9 @@ elif test "$with_uuid" = ossp ; then > fi > AC_SUBST(UUID_LIBS) > > +if test "$with_liburing" = yes; then > + PKG_CHECK_MODULES(LIBURING, liburing) > +fi We usually put this right after the AC_MSG_CHECKING ... AC_SUBST block. This currently has unrelated stuff separating them. Also, with the exception of icu, we follow PKG_CHECK_MODULES uses by absorbing flags from pkg-config and use AC_CHECK_LIB to add the actual "-l". By not absorbing flags, I think a liburing in a nonstandard location would require --with-libraries and --with-includes, unlike the other PKG_CHECK_MODULES-based dependencies. lz4 is a representative example of our standard: ``` AC_MSG_CHECKING([whether to build with LZ4 support]) PGAC_ARG_BOOL(with, lz4, no, [build with LZ4 support], [AC_DEFINE([USE_LZ4], 1, [Define to 1 to build with LZ4 support. (--with-lz4)])]) AC_MSG_RESULT([$with_lz4]) AC_SUBST(with_lz4) if test "$with_lz4" = yes; then PKG_CHECK_MODULES(LZ4, liblz4) # We only care about -I, -D, and -L switches; # note that -llz4 will be added by AC_CHECK_LIB below. for pgac_option in $LZ4_CFLAGS; do case $pgac_option in -I*|-D*) CPPFLAGS="$CPPFLAGS $pgac_option";; esac done for pgac_option in $LZ4_LIBS; do case $pgac_option in -L*) LDFLAGS="$LDFLAGS $pgac_option";; esac done fi # ... later in file ... if test "$with_lz4" = yes ; then AC_CHECK_LIB(lz4, LZ4_compress_default, [], [AC_MSG_ERROR([library 'lz4' is required for LZ4 support])]) fi ``` I think it's okay to not use the AC_CHECK_LIB and rely on explicit src/backend/Makefile code like you've done, but we shouldn't miss CPPFLAGS/LDFLAGS (or should have a comment on why missing them is right). > --- a/doc/src/sgml/installation.sgml > +++ b/doc/src/sgml/installation.sgml lz4 and other deps have a mention in , in addition to sections edited here. > Subject: [PATCH v2.11 05/27] aio: Add io_method=io_uring (Still reviewing this one.)