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 1qEnVZ-0005NM-TP for pgsql-bugs@arkaria.postgresql.org; Thu, 29 Jun 2023 09:00:10 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1qEnVY-00059o-5I for pgsql-bugs@arkaria.postgresql.org; Thu, 29 Jun 2023 09:00:08 +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 1qEnVX-000592-OJ for pgsql-bugs@lists.postgresql.org; Thu, 29 Jun 2023 09:00:07 +0000 Received: from mail-lf1-x12e.google.com ([2a00:1450:4864:20::12e]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1qEnVV-0014Kd-7o for pgsql-bugs@lists.postgresql.org; Thu, 29 Jun 2023 09:00:06 +0000 Received: by mail-lf1-x12e.google.com with SMTP id 2adb3069b0e04-4fb9ae4cef6so641166e87.3 for ; Thu, 29 Jun 2023 02:00:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1688029203; x=1690621203; h=content-transfer-encoding:in-reply-to:from:references:cc:to :content-language:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=tUIQq0PyLiW00tcEtxV3GmNwzLsdx18OI5GTZUv0TlU=; b=ajf5NX6l8KpfzrEyVCrpnlWM1gPdDeJexh3w6F7FPAxNIsa1PyxQyw2POxafcG+NKL 39UqGEkw8i76Vm/WtjH4fYgfJZb7WUkhyIP6pxLVOfDmhIP1mlG2Z9Fz1GJaB7alO2iY ptzDU8RnHsmVGAp+8DBzJzZrSBSo+/F5JI6O+2qrdRPV/RLfDcsNxO/gihGzEcKxMHmy YtG98OJb1xsWnqwYmh2cUPcCoRU4kxHUCH1RGc0qxnr1u4XJsax302cahi6sys8DkSKN lySEj9E082YV6CoKch4rhIdcWxFz+VmXzVa1nMCb0od8V/GUTWLlJsGkVhW9NNeFK6C6 wvJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688029203; x=1690621203; h=content-transfer-encoding:in-reply-to:from:references:cc:to :content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=tUIQq0PyLiW00tcEtxV3GmNwzLsdx18OI5GTZUv0TlU=; b=I49GI6PyVCIXIzj35XzcuTEsqVjcfIW+pR3P0VpbRgvkPsgUXMgyqnGWxIS3sPhC4A tVXO1fPUmm3VmtMG/Cq8vD+VJSTNxD7f36g55J5aVEfQMwQErgkAgmJmX1mXQa/P1BaL FH6Ms/7iFwejN05huwF2RUoyPeiMMb1CsZQJXhnxhRT79qRSAtrRab/D3X0d92rOiUpb YfVLLMkAAbSLY03Ihcpt/SKzMliAMRho2JUqklUO0L9WIotBQ2uMe1iY6QUVLaymPUlq saIEFoiq87iH5tW3x8MGGb9clTZe9Zcaeg3wO3ar1ME1nS2Za1p/1R1HtkltdEfNv2kS 8xdg== X-Gm-Message-State: AC+VfDxWM952oE2EsQeXNjn/d4P8L58/jDFx7yjY7YeCqx/SdYu24cRq oqpvlWOtSRf7VFGPZO+/NShhEHl2MNQ= X-Google-Smtp-Source: ACHHUZ6HcC95EdOqPYjmG0AM/k2Ps0saJ8ZQAzvVnGYMeYKo++9UD6VuIQWAquelehJ5DgFcNndbew== X-Received: by 2002:a19:e011:0:b0:4f8:5886:186d with SMTP id x17-20020a19e011000000b004f85886186dmr20868274lfg.9.1688029203250; Thu, 29 Jun 2023 02:00:03 -0700 (PDT) Received: from [1.0.0.7] ([178.155.23.108]) by smtp.gmail.com with ESMTPSA id j8-20020ac24548000000b004f5e681eec1sm2257267lfm.92.2023.06.29.02.00.01 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 29 Jun 2023 02:00:02 -0700 (PDT) Message-ID: <611182a0-172e-cb80-965d-d6c69a1bde62@gmail.com> Date: Thu, 29 Jun 2023 12:00:00 +0300 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.4.2 Subject: Re: BUG #17997: Assert failed in validatePartitionedIndex() when attaching partition index to child of valid index Content-Language: en-US To: Michael Paquier Cc: Tom Lane , pgsql-bugs@lists.postgresql.org References: <17997-a044c27aef95daf8@postgresql.org> <509915.1687704058@sss.pgh.pa.us> <14987634-43c0-0cb3-e075-94d423607e08@gmail.com> <3eaa2c33-2ed1-2996-c6b6-0e7552a64cae@gmail.com> From: Alexander Lakhin In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi Michael, 28.06.2023 10:02, Michael Paquier wrote: >> This looks like a second bug to me in DefineIndex() where we shouldn't >> even try to link to the invalid index tp1_1_expr_idx, and we should >> try to create a new index instead. Repeating the last CREATE INDEX >> command leads to a failure, which is what I'd expect, because we get >> the computation failure. > > > I have looked into this one, and decided that we should just rely on > the existing business in DefineIndex() where we switch indisvalid to > false on a parent if the index found for the match is itself invalid. > The code had two bugs: > - First, we did not re-check if an index freshly created was itself > invalid, which could happen when recursing through more than one > level for the creation of a partitioned index. > - We need to have a CCI after switch the parent's indisvalid to false, > so as the follow up recursions are able to see that, and do the update > of indisvalid across the parents up to the top-most parent. > > Attached is a patch to fix all that, with regression tests that play > with multiple partition levels to show the recursion and the problems > we'd have without the patch. > > Alexander, what do you think? I'm somewhat confused by two things. First, if we extend your test case by adding DETACH parted_isvalid_tab_11, we get:            indexrelid           | indisvalid |       indrelid        |           inhparent --------------------------------+------------+-----------------------+-------------------------------  parted_isvalid_idx             | f          | parted_isvalid_tab    |  parted_isvalid_idx_11          | f          | parted_isvalid_tab_11 |  parted_isvalid_tab_12_expr_idx | t          | parted_isvalid_tab_12 | parted_isvalid_tab_1_expr_idx  parted_isvalid_tab_1_expr_idx  | f          | parted_isvalid_tab_1  | parted_isvalid_idx  parted_isvalid_tab_2_expr_idx  | t          | parted_isvalid_tab_2  | parted_isvalid_idx (5 rows) That is, the partition tree is containing no invalid indexes now, but the upper-level indexes in the tree are still invalid. Moreover, I don't know how to make them valid: reindex index parted_isvalid_idx; / reindex index parted_isvalid_tab_1_expr_idx; doesn't affect their flags indisvalid. (Though REINDEX for a top-level index can make leaf indexes valid.) Reattaching parted_isvalid_tab_11 after "update parted_isvalid_tab_11 set b=1" doesn't help either. > It seems to me that validatePartitionedIndex() is what defines the > use of the flag for partitioned indexes. indisvalid = false for a > partitioned index means that at least one of its partitions *may* not > have a valid index mapping to it, and that it should be switched to > true once we are sure that all its partitions have a valid index. > indisvalid = true on a partitioned table has much a stronger meaning, > where all the partitions *have* to have valid indexes. Your first > case would follow that, but not the second. So the above test case makes me wonder, is it realistic in principle to maintain this definition of indisvalid up-to-date for a partition tree? And even if so, which visible behavior this definition leads (or should lead) to? As I noted previously, the leaf index is still used when it's parent has indisvalid = false. (That's the second thing that confuses me.) For example, with the partition index tree:            indexrelid           | indisvalid |       indrelid        |           inhparent --------------------------------+------------+-----------------------+-------------------------------  parted_isvalid_idx             | f          | parted_isvalid_tab    |  parted_isvalid_idx_11          | f          | parted_isvalid_tab_11 |  parted_isvalid_tab_11_expr_idx | t          | parted_isvalid_tab_11 | parted_isvalid_tab_1_expr_idx  parted_isvalid_tab_12_expr_idx | t          | parted_isvalid_tab_12 | parted_isvalid_tab_1_expr_idx  parted_isvalid_tab_1_expr_idx  | f          | parted_isvalid_tab_1  | parted_isvalid_idx  parted_isvalid_tab_2_expr_idx  | t          | parted_isvalid_tab_2  | parted_isvalid_idx (6 rows) explain select * from parted_isvalid_tab where a / b = 1;  Append  (cost=0.12..23.14 rows=12 width=8)    ->  Index Scan using parted_isvalid_tab_11_expr_idx on parted_isvalid_tab_11 parted_isvalid_tab_1  (cost=0.1 2..8.14 rows=1 width=8)          Index Cond: ((a / b) = 1)    ->  Bitmap Heap Scan on parted_isvalid_tab_12 parted_isvalid_tab_2  (cost=4.24..14.94 rows=11 width=8)          Recheck Cond: ((a / b) = 1)          ->  Bitmap Index Scan on parted_isvalid_tab_12_expr_idx (cost=0.00..4.24 rows=11 width=0)                Index Cond: ((a / b) = 1) So I can't resist asking a question: what would break if indisvalid flags were always true (or always false) for the upper-level partition indexes? I've made validatePartitionedIndex() a no-op just to check that and the only differences I observe doing `make check` are indisvalid flags printed; there are no behavioral changes. Though `make check-world` fails on src/bin/pg_upgrade (only); I need more time to investigate this — maybe more sophisticated query to select appropriate indexes for processing could help there. Best regards, Alexander