Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.92) (envelope-from ) id 1j9toD-0007Fe-M2 for pgsql-hackers@arkaria.postgresql.org; Thu, 05 Mar 2020 16:57:17 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1j9toC-0007u8-F0 for pgsql-hackers@arkaria.postgresql.org; Thu, 05 Mar 2020 16:57:16 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1j9toB-0007u1-UM for pgsql-hackers@lists.postgresql.org; Thu, 05 Mar 2020 16:57:16 +0000 Received: from mail-lf1-x144.google.com ([2a00:1450:4864:20::144]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1j9to9-0000no-9T for pgsql-hackers@postgresql.org; Thu, 05 Mar 2020 16:57:14 +0000 Received: by mail-lf1-x144.google.com with SMTP id w27so5238777lfc.1 for ; Thu, 05 Mar 2020 08:57:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=76UkLaVg+M0M1B6S4OP9JZ3Lvl/jLMyb8WsnbGJ5UT8=; b=QTf1fp0dlFabYXpY/sFMaO2M+UMumRFAl4xdu7NMQ6k/fX47mgoXJfvE5lh6QAh1aL 3b36H5K7DBVpzedVcJ+DuysukA//UolRs1UP04y4WjzjUUTG37/v6jzODZuz/tZR4h5O eGelngjt8GipulIQ6uQ+FqYRbdUXVQl6uRW7XmU1NLX8dyCJnCkWx9r3aI72xWRNIE+x EoOmOgX0RJFdXw11LJdPk4MfhIe7zHFN0RK9VcxO4t6wjzbX1w4Qorn+btGRFKKyyNvP ndWA/aJA6T2M4XRJOIOv8/kL5+1bAonS2lKL1tP10M1nQh5rC/fVlPnyEcQbSgxHmIU/ NdGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=76UkLaVg+M0M1B6S4OP9JZ3Lvl/jLMyb8WsnbGJ5UT8=; b=BnLxQGDs7LBPZcEs3/ddkaKNulDC26gGLbAfjlMRs+rPnKYQJ7DcModR82TJZ2HPc2 HXzXG3kTnfyHyc2MzbPjLjk819oZ+b8bEjuo/zOoWHGL9Mhxp45eYJrMqGjrXJDQFmlr DrZcmit6S4dJUVmavygJdyQtUqPm+G1bbqADGfCrCgRc85dEj1++tRbfDk+7PKJwMQfn DNA++L22hEXdMGYDFzIsolQj2izZkHGn7mFoW2bVCMhlGvgxZ2lwa3MNBQ/1PptGBdJV yyBRjVq+Nt9nqFnUc6/7DsRp17vTz2+ePo9qPt273Qv/3f3/UuRvP4oSdNUYJEkLWKYl 3Fzw== X-Gm-Message-State: ANhLgQ0aoa2CcpJwl68p8gbWB/lQd839NIYFb0oB8XA5F3gpze5RzSjH z3WY2ny72Z4yEsR68pNTPKDwTHW8nz0VXA== X-Google-Smtp-Source: ADFU+vs4IemllwWwSSG+5vTdZCm+GMlhmH0y7rgHdUKAjJV8G3j/sesqhMfhmkQSreCBJkZI0pnDXQ== X-Received: by 2002:ac2:442e:: with SMTP id w14mr5832593lfl.119.1583427431475; Thu, 05 Mar 2020 08:57:11 -0800 (PST) Received: from nol (82-64-124-11.subs.proxad.net. [82.64.124.11]) by smtp.gmail.com with ESMTPSA id h14sm8034631lfc.74.2020.03.05.08.57.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Mar 2020 08:57:10 -0800 (PST) Date: Thu, 5 Mar 2020 17:57:07 +0100 From: Julien Rouhaud To: Michael Paquier Cc: Justin Pryzby , Sergei Kornilov , Peter Eisentraut , Michael Paquier , Andreas Karlsson , pgsql-hackers Subject: Re: reindex concurrently and two toast indexes Message-ID: <20200305165707.GA35281@nol> References: <20200222070924.GA57285@nol> <20200222150657.GA54846@nol> <20200227073211.GA403330@paquier.xyz> <20200227080735.l32fqcauy73lon7o@nol> <20200303080642.GA1890@paquier.xyz> <20200303092551.GB1890@paquier.xyz> <20200304051510.GE2593@paquier.xyz> <20200305035354.GQ2593@paquier.xyz> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="EeQfGwPcQSOJBaQU" Content-Disposition: inline In-Reply-To: <20200305035354.GQ2593@paquier.xyz> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --EeQfGwPcQSOJBaQU Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Thu, Mar 05, 2020 at 12:53:54PM +0900, Michael Paquier wrote: > On Wed, Mar 04, 2020 at 09:21:45AM +0100, Julien Rouhaud wrote: > > Thanks for the patch! I started to look at it during the weekend, but > > I got interrupted and unfortunately didn't had time to look at it > > since. > > No problem, thanks for looking at it. I have looked at it again this > morning, and applied it. > > > The fix looks good to me. I also tried multiple failure scenario and > > it's unsurprisingly working just fine. Should we add some regression > > tests for that? I guess most of it could be borrowed from the patch > > to fix the toast index issue I sent last week. > > I have doubts when it comes to use a strategy based on > pg_cancel_backend() and a match of application_name (see for example > 5ad72ce but I cannot find the associated thread). I think that we > could design something more robust here and usable by all tests, with > two things coming into my mind: > - A new meta-command for isolation tests to be able to cancel a > session with PQcancel(). > - Fault injection in the backend. > For the case of this thread, the cancellation command would be a better > match. I agree that the approach wasn't quite robust. I'll try to look at adding a new command for isolationtester, but that's probably not something we want to put in pg13? Here's a v3 that takes address the various comments you previously noted, and for which I also removed the regression tests. Note that while looking at it, I noticed another bug in RIC: # create table t1(id integer, val text); create index on t1(val); CREATE TABLE CREATE INDEX # reindex table concurrently t1; ^CCancel request sent ERROR: 57014: canceling statement due to user request LOCATION: ProcessInterrupts, postgres.c:3171 # select indexrelid::regclass, indrelid::regclass, indexrelid, indrelid from pg_index where not indisvalid; indexrelid | indrelid | indexrelid | indrelid -------------------------------------+-------------------------+------------+---------- t1_val_idx_ccold | t1 | 16401 | 16395 pg_toast.pg_toast_16395_index_ccold | pg_toast.pg_toast_16395 | 16400 | 16398 (2 rows) # reindex table concurrently t1; WARNING: 0A000: cannot reindex invalid index "public.t1_val_idx_ccold" concurrently, skipping LOCATION: ReindexRelationConcurrently, indexcmds.c:2821 WARNING: XX002: cannot reindex invalid index "pg_toast.pg_toast_16395_index_ccold" concurrently, skipping LOCATION: ReindexRelationConcurrently, indexcmds.c:2867 REINDEX # reindex index concurrently t1_val_idx_ccold; REINDEX That case is also fixed in this patch. --EeQfGwPcQSOJBaQU Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="0001-Don-t-reindex-invalid-indexes-on-TOAST-tables-v3.patch" From 77ec865a9a655b2b973846f9a8fa93c966ca55f5 Mon Sep 17 00:00:00 2001 From: Julien Rouhaud Date: Fri, 21 Feb 2020 20:15:04 +0100 Subject: [PATCH] Don't reindex invalid indexes on TOAST tables. Such indexes can only be duplicated leftovers of failed REINDEX CONCURRENTLY commands. As we only allow to drop invalid indexes on TOAST tables, reindexing those would lead to useless duplicated indexes that can't be dropped anymore. Reported-by: Sergei Kornilov, Justin Pryzby Author: Julien Rouhaud Reviewed-by: Michael Paquier Discussion: https://postgr.es/m/36712441546604286%40sas1-890ba5c2334a.qloud-c.yandex.net Discussion: https://postgr.es/m/20200216190835.GA21832@telsasoft.com Backpatch-through: 12 --- src/backend/catalog/index.c | 30 ++++++++++++++++++++ src/backend/commands/indexcmds.c | 47 +++++++++++++++++++++++++------- 2 files changed, 67 insertions(+), 10 deletions(-) diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 7223679033..d3d28df97a 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -46,6 +46,7 @@ #include "catalog/pg_depend.h" #include "catalog/pg_description.h" #include "catalog/pg_inherits.h" +#include "catalog/pg_namespace_d.h" #include "catalog/pg_opclass.h" #include "catalog/pg_operator.h" #include "catalog/pg_tablespace.h" @@ -3724,6 +3725,35 @@ reindex_relation(Oid relid, int flags, int options) { Oid indexOid = lfirst_oid(indexId); + /* + * We skip any invalid index on a TOAST table. Those can only be + * a duplicate leftover of a failed REINDEX CONCURRENTLY, and if we + * rebuild it it won't be possible to drop it anymore. + */ + if (rel->rd_rel->relnamespace == PG_TOAST_NAMESPACE) + { + HeapTuple tup; + bool skipit; + + tup = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexOid)); + if (!HeapTupleIsValid(tup)) + elog(ERROR, "cache lookup failed for index %u", indexOid); + + skipit = ((Form_pg_index) GETSTRUCT(tup))->indisvalid == false; + + ReleaseSysCache(tup); + + if (skipit) + { + ereport(WARNING, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot reindex invalid TOAST index \"%s.%s\", skipping", + get_namespace_name(get_rel_namespace(indexOid)), + get_rel_name(indexOid)))); + continue; + } + } + reindex_index(indexOid, !(flags & REINDEX_REL_CHECK_CONSTRAINTS), persistence, options); diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index ec20ba38d1..7985d98aa8 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -28,6 +28,7 @@ #include "catalog/pg_am.h" #include "catalog/pg_constraint.h" #include "catalog/pg_inherits.h" +#include "catalog/pg_namespace_d.h" #include "catalog/pg_opclass.h" #include "catalog/pg_opfamily.h" #include "catalog/pg_tablespace.h" @@ -2337,6 +2338,7 @@ ReindexIndex(RangeVar *indexRelation, int options, bool concurrent) Oid indOid; Relation irel; char persistence; + bool invalidtoastindex; /* * Find and lock index, and check permissions on table; use callback to @@ -2362,6 +2364,9 @@ ReindexIndex(RangeVar *indexRelation, int options, bool concurrent) */ irel = index_open(indOid, NoLock); + invalidtoastindex = (irel->rd_rel->relkind == RELKIND_INDEX && + !irel->rd_index->indisvalid); + if (irel->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) { ReindexPartitionedIndex(irel); @@ -2371,6 +2376,16 @@ ReindexIndex(RangeVar *indexRelation, int options, bool concurrent) persistence = irel->rd_rel->relpersistence; index_close(irel, NoLock); + if (invalidtoastindex) + { + ereport(WARNING, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot reindex invalid TOAST index \"%s.%s\", skipping", + get_namespace_name(get_rel_namespace(indOid)), + get_rel_name(indOid)))); + return; + } + if (concurrent && persistence != RELPERSISTENCE_TEMP) ReindexRelationConcurrently(indOid, options); else @@ -2890,25 +2905,37 @@ ReindexRelationConcurrently(Oid relationOid, int options) case RELKIND_INDEX: { Oid heapId = IndexGetRelation(relationOid, false); + Relation indexRelation = index_open(relationOid, + ShareUpdateExclusiveLock); if (IsCatalogRelationOid(heapId)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot reindex system catalogs concurrently"))); + else if (!indexRelation->rd_index->indisvalid) + ereport(WARNING, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot reindex invalid index \"%s.%s\" concurrently, skipping", + get_namespace_name(get_rel_namespace(relationOid)), + get_rel_name(relationOid)))); + else + { + /* Save the list of relation OIDs in private context */ + oldcontext = MemoryContextSwitchTo(private_context); - /* Save the list of relation OIDs in private context */ - oldcontext = MemoryContextSwitchTo(private_context); + /* Track the heap relation of this index for session locks */ + heapRelationIds = list_make1_oid(heapId); - /* Track the heap relation of this index for session locks */ - heapRelationIds = list_make1_oid(heapId); + /* + * Save the list of relation OIDs in private context. Note + * that invalid indexes are allowed here. + */ + indexIds = lappend_oid(indexIds, relationOid); - /* - * Save the list of relation OIDs in private context. Note - * that invalid indexes are allowed here. - */ - indexIds = lappend_oid(indexIds, relationOid); + MemoryContextSwitchTo(oldcontext); + } - MemoryContextSwitchTo(oldcontext); + index_close(indexRelation, NoLock); break; } case RELKIND_PARTITIONED_TABLE: -- 2.20.1 --EeQfGwPcQSOJBaQU--