Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nKYBJ-0002Ae-Lg for pgsql-hackers@arkaria.postgresql.org; Thu, 17 Feb 2022 04:14:13 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1nKYBH-00067z-Sk for pgsql-hackers@arkaria.postgresql.org; Thu, 17 Feb 2022 04:14:11 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nKYBH-00067p-CS for pgsql-hackers@lists.postgresql.org; Thu, 17 Feb 2022 04:14:11 +0000 Received: from mail-pl1-x635.google.com ([2607:f8b0:4864:20::635]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1nKYBE-0005ji-Ht for pgsql-hackers@postgresql.org; Thu, 17 Feb 2022 04:14:10 +0000 Received: by mail-pl1-x635.google.com with SMTP id j4so3627221plj.8 for ; Wed, 16 Feb 2022 20:14:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=5leFOHWDAR1yAxEUrK3bwN8DrErzcT4re9cAMBNIl+A=; b=fpOXcvSOEP3+mTEeluD1+4HmzW2sYaPaUJiz4Yon32JC11fPRS4uafVEJ2bP5wLBc5 JRE8i9AN4YqiLm6CFES2/0P9Cy5G976/SCuNaphHro7bEwflsCoDzYRH3F06vzreSiLo JkFIoIgwNWshvYcDqo5aUeR6EjbHyrnbjMsZE1HmcuOws/grvBOfPkzOXCG2yaeOxn3I CwqUm0bJcJbCgHw3y1Swr1LAj4Bsbz5Z4B8yPPfSYGWIcM4c1LQIyZB+JSkYXpxS09Mk OvQWs3RNzizDr/U5UmVykbmUdqEZx2KTdVjNJxCFYbJC6/ToAkzJ6cL7Xn21O7RsLKFr i4TA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=5leFOHWDAR1yAxEUrK3bwN8DrErzcT4re9cAMBNIl+A=; b=hWjiAQ46dFgyWrRgJiZuhOH3Nli3Db3nhC1iKh7godkhlPHzwz26FZh6ncdnR/Lz3x 8k+GhZP1iQ+45NFPMqzggD/daMv6NWrJjox/37dcnxciozTYuCnS2rFGJtHz/U+9VvT5 +FhBAVVZAQ8CvpKKKXkaayGV50tNKxdE4Z0HyawbJ/gq8wM3/m1Lz7Vt8YBjpCMN7CQ5 Rx2NVnJn95WZ1D+MEvSsfTQ5FaChvJdaDNQsPhp7QwFcWER+YoBs05o4veCVGA96Pd4u VHmXhqyRa7C6wQg5X43uo30jkl3sBDwmJHuX1o3SuQhlmW9G7ViPN1rAmfXzroRRcLhz Xj6Q== X-Gm-Message-State: AOAM532g3Uc/U/4ytSvq/KXpdvhToHg33wdJPnhCWkqqjNF4VBo9BjwY m+AROfogIjByDz66QKdU1/E= X-Google-Smtp-Source: ABdhPJylklk38gXZdEj78hdo5hwt+olMd4n81rUUC2W8YHjELC1IhCmcdWxYfRI/npiWMLVKOQqnxg== X-Received: by 2002:a17:90a:7803:b0:1bb:9945:d68c with SMTP id w3-20020a17090a780300b001bb9945d68cmr4631260pjk.100.1645071246758; Wed, 16 Feb 2022 20:14:06 -0800 (PST) Received: from nathanxps13 ([50.54.155.70]) by smtp.gmail.com with ESMTPSA id h4sm45288611pfv.166.2022.02.16.20.14.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Feb 2022 20:14:06 -0800 (PST) Date: Wed, 16 Feb 2022 20:14:04 -0800 From: Nathan Bossart To: Andres Freund Cc: "Bossart, Nathan" , Bharath Rupireddy , Maxim Orlov , Amul Sul , Bruce Momjian , Robert Haas , "pgsql-hackers@postgresql.org" Subject: Re: O(n) tasks cause lengthy startups and checkpoints Message-ID: <20220217041404.GA3243546@nathanxps13> References: <20220102212601.ep4ui5bjzffzh7rj@alap3.anarazel.de> <83BE6E07-CEF5-445B-A8F9-2A2DD56F08CA@amazon.com> <83A7426F-A7B6-4A10-A8F0-179AE30B871D@amazon.com> <20220211180249.GA1886051@nathanxps13> <20220217005057.GA3201038@nathanxps13> <20220217015052.2y3wxibeommk37ey@alap3.anarazel.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20220217015052.2y3wxibeommk37ey@alap3.anarazel.de> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi Andres, I appreciate the feedback. On Wed, Feb 16, 2022 at 05:50:52PM -0800, Andres Freund wrote: >> + /* Since not using PG_TRY, must reset error stack by hand */ >> + if (sigsetjmp(local_sigjmp_buf, 1) != 0) >> + { > > I also think it's a bad idea to introduce even more copies of the error > handling body. I think we need to unify this. And yes, it's unfair to stick > you with it, but it's been a while since a new aux process has been added. +1, I think this is useful refactoring. I might spin this off to its own thread. >> + /* >> + * These operations are really just a minimal subset of >> + * AbortTransaction(). We don't have very many resources to worry >> + * about. >> + */ > > Given what you're proposing this for, are you actually confident that we don't > need more than this? I will give this a closer look. >> +extern void RemovePgTempDir(const char *tmpdirname, bool missing_ok, >> + bool unlink_all); > > I don't like functions with multiple consecutive booleans, they tend to get > swapped around. Why not just split unlink_all=true/false into different > functions? Will do. >> Subject: [PATCH v5 3/8] Split pgsql_tmp cleanup into two stages. >> >> First, pgsql_tmp directories will be renamed to stage them for >> removal. > > What if the target name already exists? The integer at the end of the target name is incremented until we find a unique name. >> Note that temporary relation files cannot be cleaned up via the >> aforementioned strategy and will not be offloaded to the custodian. > > This should be in the prior commit message, otherwise people will ask the same > question as I did. Will do. >> + /* >> + * Find a name for the stage directory. We just increment an integer at the >> + * end of the name until we find one that doesn't exist. >> + */ >> + for (int n = 0; n <= INT_MAX; n++) >> + { >> + snprintf(stage_path, sizeof(stage_path), "%s/%s%d", parent_path, >> + PG_TEMP_DIR_TO_REMOVE_PREFIX, n); > > Uninterruptible loops up to INT_MAX do not seem like a good idea. I modeled this after ChooseRelationName() in indexcmds.c. Looking again, I see that it loops forever until a unique name is found. I suspect this is unlikely to be a problem in practice. What strategy would you recommend for choosing a unique name? Should we just append a couple of random characters? >> + dir = AllocateDir(stage_path); >> + if (dir == NULL) >> + { > > Why not just use stat()? That's cheaper, and there's no > time-to-check-time-to-use issue here, we're the only one writing. I'm not sure why I didn't use stat(). I will update this. >> - while ((spc_de = ReadDirExtended(spc_dir, "pg_tblspc", LOG)) != NULL) >> + while (!ShutdownRequestPending && >> + (spc_de = ReadDirExtended(spc_dir, "pg_tblspc", LOG)) != NULL) > > Uh, huh? It strikes me as a supremely bad idea to have functions *silently* > not do their jobs when ShutdownRequestPending is set, particularly without a > huge fat comment. The idea was to avoid delaying shutdown because we're waiting for the custodian to finish relatively nonessential tasks. Another option might be to just exit immediately when the custodian receives a shutdown request. >> + /* >> + * If we just staged some pgsql_tmp directories for removal, wake up the >> + * custodian process so that it deletes all the files in the staged >> + * directories as well as the directories themselves. >> + */ >> + if (stage && ProcGlobal->custodianLatch) >> + SetLatch(ProcGlobal->custodianLatch); > > Just signalling without letting the custodian know what it's expected to do > strikes me as a bad idea. Good point. I will work on that. >> From 9c2013d53cc5c857ef8aca3df044613e66215aee Mon Sep 17 00:00:00 2001 >> From: Nathan Bossart >> Date: Sun, 5 Dec 2021 22:02:40 -0800 >> Subject: [PATCH v5 5/8] Move removal of old serialized snapshots to custodian. >> >> This was only done during checkpoints because it was a convenient >> place to put it. However, if there are many snapshots to remove, >> it can significantly extend checkpoint time. To avoid this, move >> this work to the newly-introduced custodian process. >> --- >> src/backend/access/transam/xlog.c | 2 -- >> src/backend/postmaster/custodian.c | 11 +++++++++++ >> src/backend/replication/logical/snapbuild.c | 13 +++++++------ >> src/include/replication/snapbuild.h | 2 +- >> 4 files changed, 19 insertions(+), 9 deletions(-) > > Why does this not open us up to new xid wraparound issues? Before there was a > hard bound on how long these files could linger around. Now there's not > anymore. Sorry, I'm probably missing something obvious, but I'm not sure how this adds transaction ID wraparound risk. These files are tied to LSNs, and AFAIK they won't impact slots' xmins. >> +#ifdef HAVE_SYNCFS >> + >> + /* >> + * If we are doing a shutdown or end-of-recovery checkpoint, let's use >> + * syncfs() to flush the mappings to disk instead of flushing each one >> + * individually. This may save us quite a bit of time when there are many >> + * such files to flush. >> + */ > > I am doubtful this is a good idea. This will cause all dirty files to be > written back, even ones we don't need to be written back. At once. Very > possibly *slowing down* the shutdown. > > What is even the theory of the case here? That there's so many dirty mapping > files that fsyncing them will take too long? That iterating would take too > long? Well, yes. My idea was to model this after 61752af, which allows using syncfs() instead of individually fsync-ing every file in the data directory. However, I would likely need to introduce a GUC because 1) as you pointed out, it might be slower and 2) syncfs() doesn't report errors on older versions of Linux. TBH I do feel like this one is a bit of a stretch, so I am okay with leaving it out for now. >> 5 files changed, 317 insertions(+), 9 deletions(-) > > This seems such an increase in complexity and fragility that I really doubt > this is a good idea. I think that's a fair point. I'm okay with leaving this one out for now, too. -- Nathan Bossart Amazon Web Services: https://aws.amazon.com