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.89) (envelope-from ) id 1gtGek-0001rL-4z for pgsql-hackers@arkaria.postgresql.org; Mon, 11 Feb 2019 18:50:14 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1gtGei-0005lt-4o for pgsql-hackers@arkaria.postgresql.org; Mon, 11 Feb 2019 18:50:12 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gtGeh-0005kg-ON for pgsql-hackers@lists.postgresql.org; Mon, 11 Feb 2019 18:50:11 +0000 Received: from mail-qk1-x741.google.com ([2607:f8b0:4864:20::741]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gtGee-0003jU-HE for pgsql-hackers@postgresql.org; Mon, 11 Feb 2019 18:50:11 +0000 Received: by mail-qk1-x741.google.com with SMTP id a15so7121373qkc.1 for ; Mon, 11 Feb 2019 10:50:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=2ndquadrant-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:mime-version:content-disposition :content-transfer-encoding:in-reply-to:user-agent; bh=dVHqIQXvEi4q/+qKkqGPNHFVx49jakW4H+Pop10Q7jA=; b=MGo9Amyue+JYmokorrWPapqkHoFbR/ZtCESBTEtPVPbas6PlyDqTTQY/ahW6AQWlde aODCfRuEGlt/llXizBCs95EmcYLqxT6YOLS+KDmHGipWOYXED3uIXLQRtJL7sxwAaXMo UT2TQOYgk5KplwZENtm5POR6nkIaumXGJkmLqd1O4c80/MPQl1iTOSiFbfW3bnQWSng/ GH68Ijm6bqrrYdGXZqK8JBA88DGSLaWESsvrmhKoATrdPD8iO4LNOa5FFFzVjpE9ibpO S/LmqmM+q7riGNKh9Z5+TKogqbl0tfvaXVF2utnHSnSsyMYn0hIBm7IsuJD1BIeFTgxc GGvw== 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:mime-version :content-disposition:content-transfer-encoding:in-reply-to :user-agent; bh=dVHqIQXvEi4q/+qKkqGPNHFVx49jakW4H+Pop10Q7jA=; b=V8mOgIOTR/J8H0BrG2DdT+yuV1X0F2lvZGom8vTFEr8oaH2Ch3wbvzhHmDZI7Tkjsl 5/meKD7VkzBaaj6MzaKbpvZIhUZPz/rEUjXl2gFZKCIfnc7wQWtJmWhgPe/sd4qX1KJl pxLYbQEdEzWA64zpV8SBI609lLAFNhFDXKo8chMoe9E7TysBqcSQBOT+NPYNqwTG+kC0 +0fXP+UpSuX5kqRu/Iq4ADmjhGBsG7m7nEV4+ZAFt7sPjh3vGpp97tMsfNxJBoFzsmIF CCtobIuvGh28ErwiHesyQCeBWFit8FvaQJTUmengwYB921HEjBYV1Y7BgkjGuMfTsK0r pQ7g== X-Gm-Message-State: AHQUAuYqARgr92V2ubn5tTq2TMRvm5JpwlGoOvFVvwIii+MP++f0vSLR ImktS3zrmAyu3znqSw44yrVG7OHKVAo= X-Google-Smtp-Source: AHgI3Iaw86B3DrNYzh7zT0Tw7IV7oSHPt2hZ9Jrc8VUn0gMFMzZswvIsOSOh205ahJvqdHEghPGqlA== X-Received: by 2002:a37:8504:: with SMTP id h4mr27050253qkd.123.1549911006877; Mon, 11 Feb 2019 10:50:06 -0800 (PST) Received: from nimloth.alvh.no-ip.org ([201.186.80.67]) by smtp.gmail.com with ESMTPSA id r24sm6311103qte.60.2019.02.11.10.50.05 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 11 Feb 2019 10:50:06 -0800 (PST) Received: by nimloth.alvh.no-ip.org (Postfix, from userid 1000) id 3E024124691; Mon, 11 Feb 2019 15:50:03 -0300 (-03) Date: Mon, 11 Feb 2019 15:50:03 -0300 From: Alvaro Herrera To: Arseny Sher Cc: pgsql-hackers , Alexander Lakhin Subject: Re: Too rigorous assert in reorderbuffer.c Message-ID: <20190211185003.GA27084@alvherre.pgsql> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="zYM0uCDKw75PZbzx" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <871s4k7zje.fsf@ars-thinkpad> User-Agent: Mutt/1.9.4 (2018-02-28) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --zYM0uCDKw75PZbzx Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit On 2019-Feb-07, Arseny Sher wrote: > Alvaro Herrera writes: > > Ah, okay. Does the test still fail when run without the code fix? > > Yes. The problem here is overriding cmax of catalog (pg_attribute in the > test) tuples, so it fails without any data at all. Makes sense. I thought the blanket removal of the assert() was excessive, and we can relax it instead; what do you think of the attached? -- Álvaro Herrera https://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services --zYM0uCDKw75PZbzx Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v3-0001-Remove-assertion-in-reorderbuffer-that-cmax-is-stabl.patch" diff --git a/contrib/test_decoding/expected/ddl.out b/contrib/test_decoding/expected/ddl.out index 1ead37a7291..a04038555ef 100644 --- a/contrib/test_decoding/expected/ddl.out +++ b/contrib/test_decoding/expected/ddl.out @@ -338,6 +338,24 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc COMMIT (6 rows) +-- check that DDL in aborted subtransactions handled correctly +CREATE TABLE tr_sub_ddl(data int); +BEGIN; +SAVEPOINT a; +ALTER TABLE tr_sub_ddl ALTER COLUMN data TYPE text; +INSERT INTO tr_sub_ddl VALUES ('blah-blah'); +ROLLBACK TO SAVEPOINT a; +ALTER TABLE tr_sub_ddl ALTER COLUMN data TYPE bigint; +INSERT INTO tr_sub_ddl VALUES(43); +COMMIT; +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +-------------------------------------------------- + BEGIN + table public.tr_sub_ddl: INSERT: data[bigint]:43 + COMMIT +(3 rows) + /* * Check whether treating a table as a catalog table works somewhat */ diff --git a/contrib/test_decoding/sql/ddl.sql b/contrib/test_decoding/sql/ddl.sql index 7f3446e70d4..ae9835fe869 100644 --- a/contrib/test_decoding/sql/ddl.sql +++ b/contrib/test_decoding/sql/ddl.sql @@ -215,6 +215,19 @@ INSERT INTO tr_sub(path) VALUES ('5-top-1-#1'); COMMIT; +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + +-- check that DDL in aborted subtransactions handled correctly +CREATE TABLE tr_sub_ddl(data int); +BEGIN; +SAVEPOINT a; +ALTER TABLE tr_sub_ddl ALTER COLUMN data TYPE text; +INSERT INTO tr_sub_ddl VALUES ('blah-blah'); +ROLLBACK TO SAVEPOINT a; +ALTER TABLE tr_sub_ddl ALTER COLUMN data TYPE bigint; +INSERT INTO tr_sub_ddl VALUES(43); +COMMIT; + SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c index 42d44816241..fbc2b6fe1ee 100644 --- a/src/backend/replication/logical/reorderbuffer.c +++ b/src/backend/replication/logical/reorderbuffer.c @@ -1326,15 +1326,19 @@ ReorderBufferBuildTupleCidHash(ReorderBuffer *rb, ReorderBufferTXN *txn) } else { + /* + * Maybe we already saw this tuple before in this transaction, + * but if so it must have the same cmin. + */ Assert(ent->cmin == change->data.tuplecid.cmin); - Assert(ent->cmax == InvalidCommandId || - ent->cmax == change->data.tuplecid.cmax); /* - * if the tuple got valid in this transaction and now got deleted - * we already have a valid cmin stored. The cmax will be - * InvalidCommandId though. + * cmax may be initially invalid, but once set it can only grow, + * and never become invalid again. */ + Assert((ent->cmax == InvalidCommandId) || + ((change->data.tuplecid.cmax != InvalidCommandId) && + (change->data.tuplecid.cmax > ent->cmax))); ent->cmax = change->data.tuplecid.cmax; } } --zYM0uCDKw75PZbzx--