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 1nEQ34-0007Eg-NA for pgsql-hackers@arkaria.postgresql.org; Mon, 31 Jan 2022 06:20:22 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1nEQ33-0004Dh-2L for pgsql-hackers@arkaria.postgresql.org; Mon, 31 Jan 2022 06:20:21 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1nEQ32-0004DX-MQ for pgsql-hackers@lists.postgresql.org; Mon, 31 Jan 2022 06:20:20 +0000 Received: from mail-pj1-x1029.google.com ([2607:f8b0:4864:20::1029]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1nEQ2y-0001tM-9I for pgsql-hackers@lists.postgresql.org; Mon, 31 Jan 2022 06:20:20 +0000 Received: by mail-pj1-x1029.google.com with SMTP id z14-20020a17090ab10e00b001b6175d4040so11621107pjq.0 for ; Sun, 30 Jan 2022 22:20:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=date:message-id:to:cc:subject:from:in-reply-to:references :user-agent:mime-version:content-transfer-encoding; bh=ffDO9+irpsAGWs8xJL47kxuUg4TFc95IueEA96Np1jY=; b=Ym7rg3xqS9UHnmRv8jmDWWDImJF2SzYADA9DWjtg2YS+Q4vpI2uXkglxF9fKl4tg0r C3wSHQsw9JFy19dM470nTUZk3TwWk5YQlTfLry7hEr68eKPvTohbivKdlsrHQK8+W6We JJiVnhPLGzrUAdNOwihKa68NSJj6hHyAKFQ2NOvyEjOu+Nmy9Ps+MKphHWC45p/xB28e uVpa9BxPvARR8hA8mAfBQaGFUv48l5NwdT5RPB8xnCPVAvgiACOzYzAmxezmsZulBywV Hn/+eniurJb/LaET30dLqGCmGR7y9/T00Ws38JAJRdVCSfhEgfvh72xWRcpbK7N4S7ZE JjvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:message-id:to:cc:subject:from:in-reply-to :references:user-agent:mime-version:content-transfer-encoding; bh=ffDO9+irpsAGWs8xJL47kxuUg4TFc95IueEA96Np1jY=; b=otz13T77fzqnFzA1P+J3+1i9jhGZoQohR4Yt4eFeVQHeAYn2Baci46erHFbcIS+hqb AVa04i/OqfdZ1HzwMWNK+AU9g2kv6zQ8SxskE1gOz6LT8a8JsVAqT6xS07BQ8SFmFnGj fQMQc6RWbwACjGJJZkGJz+5AKXaTsTXE5ibtRdsE6utyL2lCQnq7fFQjqzCfLNZYSRj4 XwFN9hAR9YoVCqCwjdc6Doyv+UctQp5VkSG+tNtV8kOK43HgSXmQ5ACCSZZn7+gL+PfY xu4NJqXtNkTqzk4uR9qoPzLI60DqndMhVnwFMGqqkAamujtw24fzQuMWn8wmuno7E0fn pgfg== X-Gm-Message-State: AOAM5302IV0Ff0slIfO3iIaa1NRCUooU0JyJvFNbVVuVNi2j9Q+7Wh9X TweVWY9Xjd3+0NSwF4vBvKI= X-Google-Smtp-Source: ABdhPJwEXn2az/OxBraoxachYzlcA7lA5zrt3K2/Yx16r/bTirQ7OidwYCFD3s5OpeMsVsB6ZVMqhg== X-Received: by 2002:a17:90b:4a4c:: with SMTP id lb12mr22584778pjb.211.1643610014344; Sun, 30 Jan 2022 22:20:14 -0800 (PST) Received: from localhost (KD036014041111.ppp-bb.dion.ne.jp. [36.14.41.111]) by smtp.gmail.com with ESMTPSA id z17sm5215946pgf.91.2022.01.30.22.20.12 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sun, 30 Jan 2022 22:20:13 -0800 (PST) Date: Mon, 31 Jan 2022 15:20:11 +0900 (JST) Message-Id: <20220131.152011.148738317202375552.horikyota.ntt@gmail.com> To: dilipbalaut@gmail.com Cc: rjuju123@gmail.com, pgsql-hackers@lists.postgresql.org Subject: Re: Error "initial slot snapshot too large" in create replication slot From: Kyotaro Horiguchi In-Reply-To: <20220131.143158.896330709668373625.horikyota.ntt@gmail.com> References: <20220112103855.ib4455yyebaxkuwp@jrouhaud> User-Agent: Mew version 6.8 on Emacs 26.1 Mime-Version: 1.0 Content-Type: Multipart/Mixed; boundary="--Next_Part(Mon_Jan_31_15_20_11_2022_830)--" Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk ----Next_Part(Mon_Jan_31_15_20_11_2022_830)-- Content-Type: Text/Plain; charset=iso-8859-7 Content-Transfer-Encoding: base64 QXQgTW9uLCAxNyBKYW4gMjAyMiAwOToyNzoxNCArMDUzMCwgRGlsaXAgS3VtYXIgPGRpbGlwYmFs YXV0QGdtYWlsLmNvbT4gd3JvdGUgaW4gDQo+IE9uIFdlZCwgSmFuIDEyLCAyMDIyIGF0IDQ6MDkg UE0gSnVsaWVuIFJvdWhhdWQgPHJqdWp1MTIzQGdtYWlsLmNvbT4gd3JvdGU6DQo+ID4gVGhlIGNm Ym90IHJlcG9ydHMgdGhhdCB0aGlzIHBhdGNoIGRvZXNuJ3QgY29tcGlsZToNCj4gPiBodHRwczov L2NpcnJ1cy1jaS5jb20vdGFzay81NjQyMDAwMDczNDkwNDMyP2xvZ3M9YnVpbGQNCj4gPg0KPiA+ IFswMzowMToyNC40NzddIHNuYXBidWlsZC5jOiBJbiBmdW5jdGlvbiChU25hcEJ1aWxkSW5pdGlh bFNuYXBzaG90ojoNCj4gPiBbMDM6MDE6MjQuNDc3XSBzbmFwYnVpbGQuYzo1ODc6MjogZXJyb3I6 IKFuZXdzdWJ4Y250oiB1bmRlY2xhcmVkIChmaXJzdA0KPiA+IHVzZSBpbiB0aGlzIGZ1bmN0aW9u KTsgZGlkIHlvdSBtZWFuIKFuZXdzdWJ4aXCiPw0KPiA+IFswMzowMToyNC40NzddICAgNTg3IHwg IG5ld3N1YnhjbnQgPSAwOw0KPiA+IFswMzowMToyNC40NzddICAgICAgIHwgIF5+fn5+fn5+fn4N Cj4gPiBbMDM6MDE6MjQuNDc3XSAgICAgICB8ICBuZXdzdWJ4aXANCj4gPiBbMDM6MDE6MjQuNDc3 XSBzbmFwYnVpbGQuYzo1ODc6Mjogbm90ZTogZWFjaCB1bmRlY2xhcmVkIGlkZW50aWZpZXIgaXMN Cj4gPiByZXBvcnRlZCBvbmx5IG9uY2UgZm9yIGVhY2ggZnVuY3Rpb24gaXQgYXBwZWFycyBpbg0K PiA+IFswMzowMToyNC40NzddIHNuYXBidWlsZC5jOjUzNTo4OiB3YXJuaW5nOiB1bnVzZWQgdmFy aWFibGUgoW1heHhpZGNudKINCj4gPiBbLVd1bnVzZWQtdmFyaWFibGVdDQo+ID4gWzAzOjAxOjI0 LjQ3N10gICA1MzUgfCAgaW50ICAgbWF4eGlkY250Ow0KPiA+IFswMzowMToyNC40NzddICAgICAg IHwgICAgICAgIF5+fn5+fn5+fg0KPiA+DQo+ID4gQ291bGQgeW91IHNlbmQgYSBuZXcgdmVyc2lv bj8gIEluIHRoZSBtZWFudGltZSBJIHdpbGwgc3dpdGNoIHRoZSBwYXRjaCB0bw0KPiA+IFdhaXRp bmcgb24gQXV0aG9yLg0KPiA+DQo+IA0KPiBUaGFua3MgZm9yIG5vdGlmeWluZywgSSB3aWxsIHdv cmsgb24gdGhpcyBhbmQgc2VuZCB0aGUgdXBkYXRlIHBhdGNoIHNvb24uDQoNCm1lPiBNbW0uIFRo ZSBzaXplIG9mIHRoZSBhcnJheSBjYW5ub3QgYmUgbGFyZ2VyIHRoYW4gdGhlIG51bWJlcnMgdGhl DQptZT4gKkNvbm50KCkgZnVuY3Rpb25zIHJldHVybi4gIFRodXMgd2UgY2Fubm90IGF0dGFjaCB0 aGUgb3ZlcnNpemVkIGFycmF5DQptZT4gdG8gLT5zdWJ4aXAuICAoSSBkb24ndCByZWNhbGwgY2xl YXJseSBidXQgdGhhdCB3b3VsZCBsZWFkIHRvIGFzc2VydGlvbg0KbWU+IGZhaWx1cmUgc29tZXdo ZXJlLi4pDQoNClRoZW4sIEkgZml4ZWQgdGhlIHYzIGVycm9yIGFuZCBwb3N0IHY0Lg0KDQpUbyBy ZWNhcDoNCg0KU25hcEJVaWxkSW5pdGlhbFNuYXBzaG90IHRyaWVzIHRvIHN0b3JlIFhJRFMgb2Yg Ym90aCB0b3AgYW5kIHN1Yg0KdHJhbnNhY3Rpb25zIGludG8gc25hcHNob3QtPnhpcCBhcnJheSBi dXQgdGhlIGFycmF5IGlzIGVhc2lseQ0Kb3ZlcmZsb3dlZCBhbmQgQ1JFQVRFX1JFUExJQ0FUT0lO X1NMT1QgY29tbWFuZCBlbmRzIHdpdGggYW4gZXJyb3IuDQoNClRvIGZpeCB0aGlzLCB0aGlzIHBh dGNoIGlzIGRvaW5nIHRoZSBmb2xsb3dpbmcgdGhpbmdzLg0KDQotIFVzZSBzdWJ4aXAgYXJyYXkg aW5zdGVhZCBvZiB4aXAgYXJyYXkgdG8gYWxsb3cgdXMgaGF2ZSBsYXJnZXIgYXJyYXkNCiAgZm9y IHhpZHMuICBTbyB0aGUgc25hcHNob3QgaXMgbWFya2VkIGFzIHRha2VuRHVyaW5nUmVjb3Zlcnks IHdoaWNoDQogIGlzIGEga2luZCBvZiBhYnVzZSBidXQgbGFyZ2VseSByZWR1Y2VzIHRoZSBjaGFu Y2Ugb2YgZ2V0dGluZw0KICAiaW5pdGlhbCBzbG90IHNuYXBzaG90IHRvbyBsYXJnZSIgZXJyb3Iu DQoNCi0gU3RpbGwgaWYgc3VieGlwIGlzIG92ZXJmbG93ZWQsIHJldHJ5IHdpdGggZXhjbHVkaW5n IHN1YnRyYW5zYWN0aW9ucw0KICB0aGVuIHNldCBzdWJvdmVyZmxvd2VkLiAgVGhpcyBjYXVzZXMg WGlkSW5NVkNDU25hcHNob3QgKGZpbmFsbHkpDQogIHNjYW5zIG92ZXIgc3VieGlwIGFycmF5IGZv ciB0YXJnZXR0ZWQgdG9wLWxldmVsIHhpZC4NCg0KV2UgY291bGQgdGFrZSBhbm90aGVyIHdheTog bWFrZSBhICF0YWtlbkR1cmluZ1JlY292ZXJ5IHNuYXBzaG90IGJ5DQp1c2luZyB4aXAgaW5zdGVh ZCBvZiBzdWJ4aXAuIEl0IGlzIGNsZWFuZXIgYnV0IGl0IGhhcyBmYXIgbGFyZ2VyDQpjaGFuY2Ug b2YgbmVlZGluZyB0byByZXRyeS4NCg0KKHJlbmFtZWQgdGhlIHBhdGNoIHNpbmNlIGl0IHJlcHJl c2VudGVkIGEgcGFydCBvZiB0aGUgcGF0Y2gpDQoNCnJlZ2FyZHMuDQoNCi0tIA0KS3lvdGFybyBI b3JpZ3VjaGkNCk5UVCBPcGVuIFNvdXJjZSBTb2Z0d2FyZSBDZW50ZXINCg== ----Next_Part(Mon_Jan_31_15_20_11_2022_830)-- Content-Type: Text/X-Patch; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="v4-0001-Avoid-an-error-while-creating-logical-replication.patch" From 1e3ec40d70c2e7f8482632333001fe52527ef17a Mon Sep 17 00:00:00 2001 From: Kyotaro Horiguchi Date: Mon, 31 Jan 2022 15:03:33 +0900 Subject: [PATCH v4] Avoid an error while creating logical replication slot Snapshot can hold top XIDs up to the number of server processes but SnapBuildInitialSnapshot tries to store all top-level and sub XIDs to there and easily fails with "initial slot snapshot too large" error. Instead, create a "takenDuringRecovery" snapshot, which stores all XIDs in subxip array. This alone largely reduces the chance of getting the error. But to eliminate the chance of the error to occur, allow to create an overflowed snapshot by adding to reorder buffer a function to tell whether an XID is a top-level or not. Author: Dilip Kumar and Kyotaro Horiguchi --- .../replication/logical/reorderbuffer.c | 20 +++++++ src/backend/replication/logical/snapbuild.c | 54 ++++++++++++++----- src/include/replication/reorderbuffer.h | 1 + 3 files changed, 63 insertions(+), 12 deletions(-) diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c index 19b2ba2000..429e6296ab 100644 --- a/src/backend/replication/logical/reorderbuffer.c +++ b/src/backend/replication/logical/reorderbuffer.c @@ -3326,6 +3326,26 @@ ReorderBufferXidHasBaseSnapshot(ReorderBuffer *rb, TransactionId xid) } +/* + * ReorderBufferXidIsKnownSubXact + * Returns true if the xid is a known subtransaction. + */ +bool +ReorderBufferXidIsKnownSubXact(ReorderBuffer *rb, TransactionId xid) +{ + ReorderBufferTXN *txn; + + txn = ReorderBufferTXNByXid(rb, xid, false, + NULL, InvalidXLogRecPtr, false); + + /* a known subtxn? */ + if (txn && rbtxn_is_known_subxact(txn)) + return true; + + return false; +} + + /* * --------------------------------------- * Disk serialization support diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c index 83fca8a77d..21f30fa1d3 100644 --- a/src/backend/replication/logical/snapbuild.c +++ b/src/backend/replication/logical/snapbuild.c @@ -531,8 +531,9 @@ SnapBuildInitialSnapshot(SnapBuild *builder) { Snapshot snap; TransactionId xid; - TransactionId *newxip; - int newxcnt = 0; + TransactionId *newsubxip; + int newsubxcnt; + bool overflowed = false; Assert(!FirstSnapshotSet); Assert(XactIsoLevel == XACT_REPEATABLE_READ); @@ -568,9 +569,12 @@ SnapBuildInitialSnapshot(SnapBuild *builder) MyProc->xmin = snap->xmin; - /* allocate in transaction context */ - newxip = (TransactionId *) - palloc(sizeof(TransactionId) * GetMaxSnapshotXidCount()); + /* + * Allocate in transaction context. We use only subxip to store xids. See + * below and GetSnapshotData for details. + */ + newsubxip = (TransactionId *) + palloc(sizeof(TransactionId) * GetMaxSnapshotSubxidCount()); /* * snapbuild.c builds transactions in an "inverted" manner, which means it @@ -578,6 +582,9 @@ SnapBuildInitialSnapshot(SnapBuild *builder) * classical snapshot by marking all non-committed transactions as * in-progress. This can be expensive. */ +retry: + newsubxcnt = 0; + for (xid = snap->xmin; NormalTransactionIdPrecedes(xid, snap->xmax);) { void *test; @@ -591,12 +598,28 @@ SnapBuildInitialSnapshot(SnapBuild *builder) if (test == NULL) { - if (newxcnt >= GetMaxSnapshotXidCount()) - ereport(ERROR, - (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), - errmsg("initial slot snapshot too large"))); + /* + * If subtransactions fit the subxid array, we fill the array and + * call it a day. Otherwise we store only top-level transactions + * into the same subxip array. + */ + if (!overflowed || + !ReorderBufferXidIsKnownSubXact(builder->reorder, xid)) + { + if (newsubxcnt >= GetMaxSnapshotSubxidCount()) + { + if (overflowed) + ereport(ERROR, + (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), + errmsg("initial slot snapshot too large"))); - newxip[newxcnt++] = xid; + /* retry excluding subxids */ + overflowed = true; + goto retry; + } + + newsubxip[newsubxcnt++] = xid; + } } TransactionIdAdvance(xid); @@ -604,8 +627,15 @@ SnapBuildInitialSnapshot(SnapBuild *builder) /* adjust remaining snapshot fields as needed */ snap->snapshot_type = SNAPSHOT_MVCC; - snap->xcnt = newxcnt; - snap->xip = newxip; + snap->xcnt = 0; + snap->subxcnt = newsubxcnt; + snap->subxip = newsubxip; + snap->suboverflowed = overflowed; + /* + * Although this snapshot is taken actually not during recovery, all XIDs + * are stored in subxip even if it is not overflowed. + */ + snap->takenDuringRecovery = true; return snap; } diff --git a/src/include/replication/reorderbuffer.h b/src/include/replication/reorderbuffer.h index aa0a73382f..c05cf3078c 100644 --- a/src/include/replication/reorderbuffer.h +++ b/src/include/replication/reorderbuffer.h @@ -669,6 +669,7 @@ void ReorderBufferXidSetCatalogChanges(ReorderBuffer *, TransactionId xid, XLog bool ReorderBufferXidHasCatalogChanges(ReorderBuffer *, TransactionId xid); bool ReorderBufferXidHasBaseSnapshot(ReorderBuffer *, TransactionId xid); +bool ReorderBufferXidIsKnownSubXact(ReorderBuffer *rb, TransactionId xid); bool ReorderBufferRememberPrepareInfo(ReorderBuffer *rb, TransactionId xid, XLogRecPtr prepare_lsn, XLogRecPtr end_lsn, TimestampTz prepare_time, -- 2.27.0 ----Next_Part(Mon_Jan_31_15_20_11_2022_830)----