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 1sev5y-00ECqh-M2 for pgsql-hackers@arkaria.postgresql.org; Fri, 16 Aug 2024 11:26:14 +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 1sev5x-004ZsQ-BI for pgsql-hackers@arkaria.postgresql.org; Fri, 16 Aug 2024 11:26:13 +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 1sev5w-004ZsH-On for pgsql-hackers@lists.postgresql.org; Fri, 16 Aug 2024 11:26:13 +0000 Received: from relay4-d.mail.gandi.net ([2001:4b98:dc4:8::224]) by magus.postgresql.org with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sev5q-0058oX-RF for pgsql-hackers@postgresql.org; Fri, 16 Aug 2024 11:26:12 +0000 Received: by mail.gandi.net (Postfix) with ESMTPSA id 3D5D4E0003; Fri, 16 Aug 2024 11:26:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vondra.me; s=gm1; t=1723807563; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ab+5ycW2Xuw93IGD7rJ5EiWXx5z7LnHNFbef8F8oglk=; b=LW932PamgWLeCowdJ0Awu/6XeOpt+uR9OZ9HbkKi6sXI8c1Aa50f7V4JKooigTEJ8MPEKi k8Y+nUqT4stv4tK7N/QaP9291bIrj612qfh6a3UGgUw473vlWnj0evMBBwcUtxCkzIbQOY BiQSvGexJJ6x6HbcaydusMoOQtgVdZtlKVET/hGGmOfcVzHSN9iJ/+lrAUpVLv7ZK/+Do8 BtJ0lSTWTeNyG9XElSFTHvNa51AIAu+rDE7ywnohYC++CzzVUHxmw6GFmB+XqLBUsodQfB WimuzwQTBOkKNu50DJ3XPAGoHKhk8DiGgDdp3asgOg994wwBYsISNny9UDJWzA== Message-ID: <3f705d5f-4085-458a-a47f-dee3472f7beb@vondra.me> Date: Fri, 16 Aug 2024 13:26:01 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: Drop database command will raise "wrong tuple length" if pg_database tuple contains toast attribute. To: Ayush Tiwari , pgsql-hackers@postgresql.org References: Content-Language: en-US From: Tomas Vondra In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-GND-Sasl: tomas@vondra.me List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi Ayush, On 8/13/24 07:37, Ayush Tiwari wrote: > Hi hackers, > > We encountered an issue lately, that if the database grants too many > roles `datacl` is toasted, following which, the drop database command > will fail with error "wrong tuple length". > > To reproduce the issue, please follow below steps: > > CREATE DATABASE test; > > -- create helper function > CREATE OR REPLACE FUNCTION data_tuple() returns text as $body$ > declare >           mycounter int; > begin >           for mycounter in select i from generate_series(1,2000) i loop >                     execute 'CREATE > ROLE aaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbb ' || mycounter; >                     execute 'GRANT ALL ON DATABASE test to > aaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbb ' || mycounter; >           end loop; >           return 'ok'; > end; > $body$ language plpgsql volatile strict;  > > -- create roles and grant on the database. > SELECT data_tuple();  > > -- drop database command, this will result in "wrong tuple length" error. > DROP DATABASE test; > > The root cause of this behaviour is that the HeapTuple in dropdb > function fetches a copy of pg_database tuple from system cache. > But the system cache flattens any toast attributes, which cause the > length check to fail in heap_inplace_update. > > A patch for this issue is attached to the mail, the solution is to > change the logic to fetch the tuple by directly scanning pg_database > rather than using the catcache. > Thanks for the report. I can reproduce the issue following your instructions, and the fix seems reasonable ... But there's also one thing I don't quite understand. I did look for other places that might have a similar issue, that is places that 1) lookup tuple using SearchSysCacheCopy1 2) call on the tuple heap_inplace_update And I found about four places doing that: - index_update_stats (src/backend/catalog/index.c) - create_toast_table (src/backend/catalog/toasting.c) - vac_update_relstats / vac_update_datfrozenxid (commands/vacuum.c) But I haven't managed to trigger the same kind of failure for any of those places, despite trying. AFAIK that's because those places update pg_class, and that doesn't have TOAST, so the tuple length can't change. So this fix seems reasonable. -- Tomas Vondra