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 1sI1m0-00CHCs-Mf for pgsql-hackers@arkaria.postgresql.org; Fri, 14 Jun 2024 07:55:00 +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 1sI1lx-00F2wr-Vy for pgsql-hackers@arkaria.postgresql.org; Fri, 14 Jun 2024 07:54:58 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sI1lx-00F2sf-Hh for pgsql-hackers@lists.postgresql.org; Fri, 14 Jun 2024 07:54:58 +0000 Received: from mail-wr1-x42b.google.com ([2a00:1450:4864:20::42b]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1sI1lv-001FWH-Li for pgsql-hackers@lists.postgresql.org; Fri, 14 Jun 2024 07:54:57 +0000 Received: by mail-wr1-x42b.google.com with SMTP id ffacd0b85a97d-35f0d6255bdso1720254f8f.1 for ; Fri, 14 Jun 2024 00:54:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1718351694; x=1718956494; darn=lists.postgresql.org; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date:from:to :cc:subject:date:message-id:reply-to; bh=bIfnWtesByATMkBh8obOvN0AWs5MuukKjc8UlktVGFQ=; b=gbEuqOCE4qBe4anzOAMEg6NpAb0ITtytmO0KeG3BiQRCc/f9Fs1Q/cy/ieofYssQ0u hz6ZAba6QpykxDWDrJRY4fFX3cL222X4ibExB9modqWfisuFeT8fwPG67JZ0cy0JwGB3 yNlSWfDQKsW0u2xWjCMaBDHxQ/Wf8jk8LukF2TQP69N8BFTCljIA+ywo1T4RyX9zIkvL FefVb0F5deWBouX86aA3cBbYOu9mtlFghM6ZoPul2iIMz4N6Pm0QeH3OHu79zmbybIkr 1MT5jI/z7CiDlBRWL7tDyXemkum/vs2BkDT+qyX8bSBZ/VCl+w+ejgQNItPrYducYduM HN8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718351694; x=1718956494; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=bIfnWtesByATMkBh8obOvN0AWs5MuukKjc8UlktVGFQ=; b=C69m/ZnVYPuT0kA8PFUWwTELWwDx76Wy0WRsoOP+jIfiOcPV2VMDJyZf7SVaCy04vc s5/vGPXEo9dz0AWofC12GZ3ek+jixNh3mtluWKD6VtT9Ww6SJEiNztkdkaXhjzfRCByw wfBgBGIhm/KnvPUvJcKxDVshZOZlcEdz+D5dpK3Jc8P34ooDsvyGKI8REto9FD4DpvS8 /Js/wf9Bvb8Y1M6HcNdF8bsxtvXuHuGTjv8/xns4F+a+QjyNzKCrY23R4+KoIlcXBCd2 sAkDyZBlPf73iT0t4UU5iXd5BRIPWnbLUofAMEetQaaeujO/ASMfk2KCxEv9sLB2y7UV I9ZA== X-Forwarded-Encrypted: i=1; AJvYcCVBjtdZs0B0bhpehZDW9hJFdLvr/UzZKPbdofjYA35cx9T0ykb7nLMiorm3EPOLMHfPwdHNSTKobs9RrE7LtoKlXQx2DkD1XXCw+V3X7QP/jk8X X-Gm-Message-State: AOJu0YywvxmKN7sRuaaBHoTXtjv78T3m8ZC8NqgEVvG69VaEj147TdXa ISgJvFBHdBccxUqp2Iy4r/Zh7Qc/mQ9ebsPfYXVVF/7tYC6NODEC X-Google-Smtp-Source: AGHT+IE5LvsVm11gmzx7kLohBDja/5B2mTQjplEiRfp4OB9YFYCEMYVg7qV1vKs+nNP5fVStrbhwXg== X-Received: by 2002:adf:e2c8:0:b0:360:7b8b:624e with SMTP id ffacd0b85a97d-3607b8b6291mr1108887f8f.6.1718351693814; Fri, 14 Jun 2024 00:54:53 -0700 (PDT) Received: from ip-10-97-1-34.eu-west-3.compute.internal (ec2-15-236-134-5.eu-west-3.compute.amazonaws.com. [15.236.134.5]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3607509c8b7sm3562578f8f.26.2024.06.14.00.54.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Jun 2024 00:54:53 -0700 (PDT) Date: Fri, 14 Jun 2024 07:54:52 +0000 From: Bertrand Drouvot To: Robert Haas Cc: Michael Paquier , Alexander Lakhin , pgsql-hackers@lists.postgresql.org, Tom Lane Subject: Re: Avoid orphaned objects dependencies, take 3 Message-ID: References: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi, On Thu, Jun 13, 2024 at 02:27:45PM -0400, Robert Haas wrote: > On Thu, Jun 13, 2024 at 12:52 PM Bertrand Drouvot > wrote: > > > > table_open(childRelId, ...) would lock any "ALTER TABLE DROP CONSTRAINT" > > > > already. Not sure I understand your concern here. > > > > > > I believe this is not true. This would take a lock on the table, not > > > the constraint itself. > > > > I agree that it would not lock the constraint itself. What I meant to say is that > > , nevertheless, the constraint can not be dropped. Indeed, the "ALTER TABLE" > > necessary to drop the constraint (ALTER TABLE DROP CONSTRAINT) would > > be locked by the table_open(childRelId, ...). > > Ah, right. So, I was assuming that, with either this version of your > patch or the earlier version, we'd end up locking the constraint > itself. Was I wrong about that? The child contraint itself is not locked when going through ConstraintSetParentConstraint(). While at it, let's look at a full example and focus on your concern. Let's do that with this gdb file: " $ cat gdb.txt b dependency.c:1542 command 1 printf "Will return for: classId %d and objectId %d\n", object->classId, object->objectId c end b dependency.c:1547 if object->classId == 2606 command 2 printf "Will lock constraint: classId %d and objectId %d\n", object->classId, object->objectId c end " knowing that: " Line 1542 is the return here in depLockAndCheckObject() (your concern): if (object->classId == RelationRelationId || object->classId == AuthMemRelationId) return; Line 1547 is the lock here in depLockAndCheckObject(): /* assume we should lock the whole object not a sub-object */ LockDatabaseObject(object->classId, object->objectId, 0, AccessShareLock); " So, with gdb attached to a session let's: 1. Create the parent relation CREATE TABLE upsert_test ( a INT, b TEXT ) PARTITION BY LIST (a); gdb produces: --- Will return for: classId 1259 and objectId 16384 Will return for: classId 1259 and objectId 16384 --- Oid 16384 is upsert_test, so I think the return (dependency.c:1542) is fine as we are creating the object (it can't be dropped as not visible to anyone else). 2. Create another relation (will be the child) CREATE TABLE upsert_test_2 (b TEXT, a int); gdb produces: --- Will return for: classId 1259 and objectId 16391 Will return for: classId 1259 and objectId 16394 Will return for: classId 1259 and objectId 16394 Will return for: classId 1259 and objectId 16391 --- Oid 16391 is upsert_test_2 Oid 16394 is pg_toast_16391 so I think the return (dependency.c:1542) is fine as we are creating those objects (can't be dropped as not visible to anyone else). 3. Attach the partition ALTER TABLE upsert_test ATTACH PARTITION upsert_test_2 FOR VALUES IN (2); gdb produces: --- Will return for: classId 1259 and objectId 16384 --- That's fine because we'd already had locked the relation 16384 through AlterTableLookupRelation()->RangeVarGetRelidExtended()->LockRelationOid(). 4. Add a constraint on the child relation ALTER TABLE upsert_test_2 add constraint bdtc2 UNIQUE (a); gdb produces: --- Will return for: classId 1259 and objectId 16391 Will lock constraint: classId 2606 and objectId 16397 --- That's fine because we'd already had locked the relation 16391 through AlterTableLookupRelation()->RangeVarGetRelidExtended()->LockRelationOid(). Oid 16397 is the constraint we're creating (bdtc2). 5. Add a constraint on the parent relation (this goes through ConstraintSetParentConstraint()) ALTER TABLE upsert_test add constraint bdtc1 UNIQUE (a); gdb produces: --- Will return for: classId 1259 and objectId 16384 Will lock constraint: classId 2606 and objectId 16399 Will return for: classId 1259 and objectId 16398 Will return for: classId 1259 and objectId 16391 Will lock constraint: classId 2606 and objectId 16399 Will return for: classId 1259 and objectId 16391 --- Regarding "Will return for: classId 1259 and objectId 16384": That's fine because we'd already had locked the relation 16384 through AlterTableLookupRelation()->RangeVarGetRelidExtended()->LockRelationOid(). Regarding "Will lock constraint: classId 2606 and objectId 16399": Oid 16399 is the constraint that we're creating. Regarding "Will return for: classId 1259 and objectId 16398": That's fine because Oid 16398 is an index that we're creating while creating the constraint (so the index can't be dropped as not visible to anyone else). Regarding "Will return for: classId 1259 and objectId 16391": That's fine because 16384 we'd be already locked (as mentioned above). And I think that's fine because trying to drop "upsert_test_2" (aka 16391) would produce RemoveRelations()->RangeVarGetRelidExtended()->RangeVarCallbackForDropRelation() ->LockRelationOid(relid=16384, lockmode=8) and so would be locked. Regarding this example, I don't think that the return in depLockAndCheckObject(): " if (object->classId == RelationRelationId || object->classId == AuthMemRelationId) return; " is an issue. Indeed, the example above shows it would return for an object that we'd be creating (so not visible to anyone else) or for an object that we'd already have locked. Is it an issue outside of this example?: I've the feeling it's not as we're already careful when we deal with relations. That said, to be on the safe side we could get rid of this return and make use of LockRelationOid() instead. Regards, -- Bertrand Drouvot PostgreSQL Contributors Team RDS Open Source Databases Amazon Web Services: https://aws.amazon.com