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.96) (envelope-from ) id 1wbVwM-002cw2-2X for pgsql-hackers@arkaria.postgresql.org; Mon, 22 Jun 2026 04:07:19 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wbVwL-004HVj-20 for pgsql-hackers@arkaria.postgresql.org; Mon, 22 Jun 2026 04:07:17 +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.96) (envelope-from ) id 1wbVtB-004DSj-2F for pgsql-hackers@lists.postgresql.org; Mon, 22 Jun 2026 04:04:01 +0000 Received: from mail-yw1-x112f.google.com ([2607:f8b0:4864:20::112f]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wbVtA-00000001Wzt-0TkC for pgsql-hackers@lists.postgresql.org; Mon, 22 Jun 2026 04:04:00 +0000 Received: by mail-yw1-x112f.google.com with SMTP id 00721157ae682-8051ad12d23so2124347b3.3 for ; Sun, 21 Jun 2026 21:03:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1782101039; cv=none; d=google.com; s=arc-20240605; b=IcVXdBnDjAdj0YyIOovflH/UpKCq2BdeApKYyRnSEJ0uW0ShWkHCb2NUhLdYvAqoIA 1bun7mZ6dR9CCiF6R7sVkx468ISmLoqzc0R5p+i+bJEbiQVnJN9cAw+i0EFsB2g2jajh 4/ZmQLcv/FOEkog7ciFsJhhiDWh4yY7Wn6ceyu7EbrIhmzIxZc+nyX7W7kY00IchSTlp JxAkCqkXm29x+2ozyoC7TuFrU7x596DM9eBqaAVGlgp1M8LfE+gYcYxAS7VcC80BLPyw ejk6SQspavLaNSoMGcbh6pEpTBkhPJ/7R7376bu9wSoiSMGXBt1ucpDpeS1KYOs5J4wt I3Ew== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=DQfGDt7KoUpf9fxY0v2ZVZf0zJx7ajnyppZi2BzkRgs=; fh=aSJq65nb+b24U4g8XiEfu9UYOF4nf1CpIczyV7c+7w4=; b=byzryE4C7yWItpX7wSjiv98NPd4rTd1LZdJdlqC1WyrjcncMGXDrwq1jcFCkK1E5ci TT67qqZWBowTatR5FbBFaYqL5UxkG5RV3DOPotjpHWB5y//W5kqb/paEGvSqbFmoREjA ynKT5Or/xQs1Yist2dO/fciocf+tE7wPq6gHAqKpC1Lu8IQO1Y4VQPCXtMYnT1FkHQQX MU03/YyoBIa3oWmqqWOVw0scrKypcSypvHAizs3y7JDHOmrV0FrgQ6cFg0QbbdGRb+Rc lbgHGfCGJukWFfc1izqLZs183AqDXxFwcvipZFVhMgTK46EGSKXx9VXB1NwUByerwzO8 oYbw==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1782101039; x=1782705839; darn=lists.postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=DQfGDt7KoUpf9fxY0v2ZVZf0zJx7ajnyppZi2BzkRgs=; b=kjTy1FidpBG1wnLmGciH4UmWh4whb/HYqzW5lzyIoEo1Qu+OO6Jp1aWun4udOY5HzT E2kxScFFVH/r4jjArFZeFgQqrKuBCuOihhTJqPYcBAbXZ7/0E6kl8V/RKwSfX4yZ2IZ4 5lwmDVQIGNBiUL7xVDjswrxue+jn+9k0HqrgR/aXg8dgfbNbcWDBsWPKXIkeqMen7B3c 9+FEG0baqs8PJ+odZ4piTHZMuSZPdILxtMtT4zyhwF/7Z+6H4jWMOXqO82fQ5fBKfYYG rS1FBOWOR8A46V+NygCYR6Kcuy12BvrxR3hbJwyQHTl3kWmkqeKgcGaeUmSgY27RZUp1 RxyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782101039; x=1782705839; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=DQfGDt7KoUpf9fxY0v2ZVZf0zJx7ajnyppZi2BzkRgs=; b=MitZ/S9Dbee53aEezJar51kEZXLBLtPCOIWB1pOu08YdFWg3a1QUkknXm3vihlBIOR y0oRf4Ma6eBaMNGYI2ddQCARLI6ojAWYOFegadSFKEF90V+YEssReqvwWWpDi+JmNbCJ HrHe3ixK0pb/aM9YGz/20AcJJU/FKUjLUN9vQpnvLHkAu9jRTf1jr8b6+2rlFEkqRRby 8gRBEYE9dfHjzRHWY8ZEgSQg5rK3d68uL0+vBh+saqrYb5Bm4tsKULCzyvYH1/b4W2fl pomc8MMEwNHidsjAK7nc6OIywKgRA4BnsCidEpdiuzIkS3qPFcW9Wvn9vOdjqZkiSTuL YXuQ== X-Forwarded-Encrypted: i=1; AHgh+Roaby9L3e94+fsxzT5u5vwEEiU/ngiaiidiieMsa5h3Q9QKcA0z+oDafTLMBn26tczPdBRWuY9fPlqzPKhM@lists.postgresql.org X-Gm-Message-State: AOJu0YxbMchd7S2yIOuqnpwz7EJupzC/qwr2MA7IbEUJy3NpD7kns0wN dSfTg6DH+AAlg8ywYsThB2QMYCwKaKgvUVc3YBHMq1GX4WJ7BAuBCDAGWDOZu0qdqhKQEH8KLwL BSAHkHwo4UCgJ+st1yfF/s53Rr0vYPHI= X-Gm-Gg: AfdE7ckp9dn4V4lTGErKF0LGSpbMnAqbAV/g3u+LKgJoqnKGKvIAe3ljjZeD0GXapvr 3yOwl2JqNc+zLz4sH8dXkdgAiALHvoPF9EFMF9Cnqi81D/X+gHSLifyY6vin+aW+qvB+V+mKtii xbIzJw/z3UG0t3lZYEnvSmmWJq/XaQBLqJhgHx40zTnubQuSYA4rHXYVRExKEZygB42OR7ZHIDS zKGqpuJ3Noo9AJ9eyMdIe88JiFmrmycH6dkto2rXKWk3P6adyKwX7cBxfWtj059YlTc7Ziw6Slo 0ISCUgQGCQ== X-Received: by 2002:a05:690c:c45a:b0:7ff:839:e14f with SMTP id 00721157ae682-80130b07986mr112833247b3.9.1782101038578; Sun, 21 Jun 2026 21:03:58 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: vignesh C Date: Mon, 22 Jun 2026 09:33:44 +0530 X-Gm-Features: AVVi8Cd78-qENB9B0pDCvp1GJ-v0FLYLo3QlAqL6r9Xx5KaX3Qvv-QYJPiZm-vQ Message-ID: Subject: Re: Proposal: Conflict log history table for Logical Replication To: Amit Kapila Cc: Dilip Kumar , Shlok Kyal , Peter Smith , Nisha Moond , shveta malik , Masahiko Sawada , Bharath Rupireddy , PostgreSQL Hackers , shveta malik Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Mon, 22 Jun 2026 at 08:41, Amit Kapila wrote: > > On Sun, Jun 21, 2026 at 7:53=E2=80=AFPM vignesh C w= rote: > > > > While attempting to log a conflict, a concurrent ALTER SUBSCRIPTION > > can change the conflict logging destination from all to log. In this > > scenario, the apply worker may already have cached the conflictlogdest > > information, including the OID of the current conflict log table. > > However, the concurrent ALTER SUBSCRIPTION drops the conflict log > > table as part of the destination change: > > +Relation > > +GetConflictLogDestAndTable(ConflictLogDest *log_dest) > > +{ > > + Oid conflictlogrelid; > > + > > + /* > > + * Convert the text log destination to the internal enum. > > MySubscription > > + * already contains the data from pg_subscription. > > + */ > > + *log_dest =3D GetConflictLogDest(MySubscription->conflictlogdes= t); > > + > > + /* Quick exit if a conflict log table was not requested. */ > > + if (!CONFLICTS_LOGGED_TO_TABLE(*log_dest)) > > + return NULL; > > + > > + conflictlogrelid =3D MySubscription->conflictlogrelid; > > + > > + Assert(OidIsValid(conflictlogrelid)); > > + > > + return table_open(conflictlogrelid, RowExclusiveLock); > > +} > > > > As a result, when the apply worker later attempts to open the cached > > conflict log table, table_open() fails because the relation has > > already been dropped. This causes the error handling path itself to > > fail before the conflict record can be written to either the conflict > > log table or the server log. > > > > In such cases, the conflict record is effectively lost and is not > > logged anywhere. For example: > > 2026-06-21 19:31:13.592 IST [263598] LOG: logical replication apply > > worker for subscription "sub1" has started > > 2026-06-21 19:32:26.731 IST [263598] ERROR: could not open relation > > with OID 16405 > > 2026-06-21 19:32:26.731 IST [263598] CONTEXT: processing remote data > > for replication origin "pg_16404" during message type "INSERT" for > > replication target relation "public.t1" in transaction 698, finished > > at 0/017D39A0 > > 2026-06-21 19:32:26.735 IST [263471] LOG: background worker "logical > > replication apply worker" (PID 263598) exited with exit code 1 > > > > Ideally, failure to access the conflict log table should not prevent > > the conflict from being reported in the server log. This issue is > > present with the v52 version. I have not yet checked if Amit's recent > > patch posted a few minutes ago at [1] handles this issue. > > > > There are two places in the patch from where we LOG/Insert the > conflict data. First is ReportApplyConflict() where we LOG if the > conflict arises from a non-ERROR path (aka conflicts other > INSERT/UPDATE_EXISTS). In that case, the conflict data will be logged > even when we fail to insert into CLT. Second is the place for > conflicts that arose as ERRORs (aka INSERT/UPDATE_EXISTS), where the > conflict information will be logged along with insert failure as > CONTEXT. Can you please verify your test based on this input and share > your findings and thoughts? The scenario I am testing is an insert_exists conflict. On the publisher: CREATE TABLE t1 (c1 int); On the subscriber: CREATE TABLE t1 (c1 int PRIMARY KEY); Then execute the following on the publisher: INSERT INTO t1 VALUES (10); INSERT INTO t1 VALUES (10); The second insert generates an insert_exists conflict on the subscriber. The conflict is reported and logged through the following call chain: apply_handle_insert -> apply_handle_insert_internal -> ExecSimpleRelationInsert -> CheckAndReportConflict -> ReportApplyConflict Pause execution in ReportApplyConflict() at GetConflictLogDestAndTable(), immediately before opening the conflict log table: ... return table_open(conflictlogrelid, RowExclusiveLock); ... While the apply worker is paused, execute the following command concurrentl= y: ALTER SUBSCRIPTION sub1 SET (conflict_log_destination =3D 'log'); This succeeds and drops the conflict log table: NOTICE: dropped conflict log table "pg_conflict.pg_conflict_log_16404" for subscription "sub1" ALTER SUBSCRIPTION At this point, GetConflictLogDestAndTable() has already determined that the conflict should be logged to a table and has cached the corresponding relation OID. However, the concurrent ALTER SUBSCRIPTION has removed that table. When execution resumes, the subsequent table_open() call fails with: 2026-06-22 09:24:53.072 IST [304864] ERROR: could not open relation with OID 16405 As a result, conflict processing itself fails before the conflict details can be recorded. The conflict is therefore not logged to the conflict log table and is also not emitted to the server log. Regards, Vignesh