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 1lUNm7-0003Ty-KW for pgsql-hackers@arkaria.postgresql.org; Thu, 08 Apr 2021 06:04:19 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1lUNm5-0007Ls-PE for pgsql-hackers@arkaria.postgresql.org; Thu, 08 Apr 2021 06:04:17 +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 1lUNm4-0007Ll-Lb for pgsql-hackers@lists.postgresql.org; Thu, 08 Apr 2021 06:04:17 +0000 Received: from new4-smtp.messagingengine.com ([66.111.4.230]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lUNm2-0001Wm-0q for pgsql-hackers@lists.postgresql.org; Thu, 08 Apr 2021 06:04:15 +0000 Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by mailnew.nyi.internal (Postfix) with ESMTP id D08DA58088E; Thu, 8 Apr 2021 02:04:12 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute2.internal (MEProxy); Thu, 08 Apr 2021 02:04:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; bh=mgCI0guD8IDQmwpsjMrS0jNMZIWO8Gm9H9AKFCjwKDk=; b=uR0KrNh6 z6q/Z9o5Ok8RP7qa+cgl/mRuIU2pSfax3JEUAJoTBQj6YgN+aLop3bd4v1u+TVzd j6g2hk5UZnHE6n0ycqAJxfW+ULAS00GNb/FfUKNf5LrB8COIlb7ZJNEbswcB6UjA ST+QDKYptRTeRLNVQ7FTVABt+VrPjDUmfw80Bn1GA5M8C34VYQ9k7vO9jP08FQGS UN1sW1nVAUvmmi/sBA0CRto6o5o/ml8CFGlXff+cSzmGL/+LTmkRZOe71TgSSyMU v19uVR+ybmMzWotucLpWGAfnhjyXElb33jYc5aQyEVUL2a85G6KoP4c9laYzkUnl dRo7xbX1Ul7RLw== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrudejkedguddtfecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpeffhffvuffkgggtugfgjggfsehmkeerredtredunecuhfhrohhmpeetlhhv rghrohcujfgvrhhrvghrrgcuoegrlhhvhhgvrhhrvgesrghlvhhhrdhnohdqihhprdhorh hgqeenucggtffrrghtthgvrhhnpefhfeegleekgfejueehgfefveelfeetvdehffdtueet gffhkefhudehffekudetkeenucfkphepudeltddrleehrdduledrleehnecuvehluhhsth gvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomheprghlvhhhvghrrhgvsegr lhhvhhdrnhhoqdhiphdrohhrgh X-ME-Proxy: Received: from perhan.alvh.no-ip.org (unknown [190.95.19.95]) by mail.messagingengine.com (Postfix) with ESMTPA id D0580240057; Thu, 8 Apr 2021 02:04:10 -0400 (EDT) Received: by perhan.alvh.no-ip.org (Postfix, from userid 1000) id 516952A07B4; Thu, 8 Apr 2021 02:04:08 -0400 (-04) Date: Thu, 8 Apr 2021 02:04:08 -0400 From: Alvaro Herrera To: yuzuko Cc: Tomas Vondra , David Steele , Kyotaro Horiguchi , Justin Pryzby , Daniel Gustafsson , Amit Langote , Masahiko Sawada , Laurenz Albe , PostgreSQL Hackers , Greg Stark Subject: Re: Autovacuum on partitioned table (autoanalyze) Message-ID: <20210408060408.GA31695@alvherre.pgsql> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="17pEHd4RhPHOinZp" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20210408032235.GA6842@alvherre.pgsql> User-Agent: Mutt/1.10.1 (2018-07-13) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --17pEHd4RhPHOinZp Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit On 2021-Apr-07, Alvaro Herrera wrote: > However, I just noticed there is a huge problem, which is that the new > code in relation_needs_vacanalyze() is doing find_all_inheritors(), and > we don't necessarily have a snapshot that lets us do that. While adding > a snapshot acquisition at that spot is a very easy fix, I hesitate to > fix it that way, because the whole idea there seems quite wasteful: we > have to look up, open and lock every single partition, on every single > autovacuum iteration through the database. That seems bad. I'm > inclined to think that a better idea may be to store reltuples for the > partitioned table in pg_class.reltuples, instead of having to add up the > reltuples of each partition. I haven't checked if this is likely to > break anything. I forgot to comment on this aspect. First, I was obviously mistaken about there not being an active snapshot. I mean, it's correct that there isn't. The issue is that it's really a bug to require that there is one; it just hasn't failed before because partially detached partitions aren't very common. So I patched that as a bug in a preliminary patch. Next, the idea of storing the number of tuples in pg_class.reltuples is a nice one, and I think we should consider it in the long run. However, while it can be done as a quick job (shown in the attached, which AFAICT works fine) there are side-effects -- for example, TRUNCATE doesn't clear the value, which is surely wrong. I suspect that if I try to handle it in this way, it would blow up in some corner case I forgot to consider. So, I decided not to go that way, at least for now. -- Álvaro Herrera Valdivia, Chile --17pEHd4RhPHOinZp Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="partitioned-reltuples.patch" commit 5ddb7c00e5f1d63eb251d334afce738919a772c0 Author: Alvaro Herrera AuthorDate: Wed Apr 7 23:52:33 2021 -0400 CommitDate: Wed Apr 7 23:52:33 2021 -0400 set pg_class.reltuples for partitioned tables diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index 0789117bb8..36e35722bc 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -656,6 +656,17 @@ do_analyze_rel(Relation onerel, VacuumParams *params, in_outer_xact); } } + else if (onerel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + { + /* + * Partitioned tables don't have storage, so we don't set any of these + * value in their pg_class entries. However, reltuples is necessary + * in order for auto-analyze to work properly, so update that. + */ + vac_update_relstats(onerel, 0, totalrows, + 0, false, InvalidTransactionId, InvalidMultiXactId, + in_outer_xact); + } /* * Now report ANALYZE to the stats collector. For regular tables, we do diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index 5517836be6..48c1bf048f 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -3208,44 +3208,7 @@ relation_needs_vacanalyze(Oid relid, */ if (PointerIsValid(tabentry) && AutoVacuumingActive()) { - if (classForm->relkind != RELKIND_PARTITIONED_TABLE) - { - reltuples = classForm->reltuples; - } - else - { - /* - * If the relation is a partitioned table, we must add up - * children's reltuples. - */ - List *children; - ListCell *lc; - - reltuples = 0; - - /* Find all members of inheritance set taking AccessShareLock */ - children = find_all_inheritors(relid, AccessShareLock, NULL); - - foreach(lc, children) - { - Oid childOID = lfirst_oid(lc); - HeapTuple childtuple; - Form_pg_class childclass; - - childtuple = SearchSysCache1(RELOID, ObjectIdGetDatum(childOID)); - childclass = (Form_pg_class) GETSTRUCT(childtuple); - - /* Skip a partitioned table and foreign partitions */ - if (RELKIND_HAS_STORAGE(childclass->relkind)) - { - /* Sum up the child's reltuples for its parent table */ - reltuples += childclass->reltuples; - } - ReleaseSysCache(childtuple); - } - - list_free(children); - } + reltuples = classForm->reltuples; vactuples = tabentry->n_dead_tuples; instuples = tabentry->inserts_since_vacuum; anltuples = tabentry->changes_since_analyze; --17pEHd4RhPHOinZp--