提交 48b13271 编写于 作者: A Ashwin Agrawal 提交者: Hubert Zhang

Avoid checking distributed snapshot for visibility checks on QD

This is partial cherry-pick from commit
b3f300b9.  In the QD, the distributed
transactions become visible at the same time as the corresponding
local ones, so we can rely on the local XIDs. This is true because the
modification of local procarray and globalXactArray are protected by
lock and hence a atomic operation during transaction commit.

We have seen many situations where catalog queries run very slow on QD
and potential reason is checking distributed logs. Process local
distributed log cache fall short for this usecase as most of XIDs are
unique and hence get frequent cache misses. Shared memory cache falls
short as only caches 8 pages and many times need many more pages to be
cached to be effective.
Co-authored-by: NHubert Zhang <hzhang@pivotal.io>
Co-authored-by: NGang Xiong <gangx@vmware.com>
上级 1fc8ed78
......@@ -52,6 +52,14 @@ localXidSatisfiesAnyDistributedSnapshot(TransactionId localXid)
{
DistributedSnapshotCommitted distributedSnapshotCommitted;
/*
* In the QD, the distributed transactions become visible at the same time
* as the corresponding local ones, so we can rely on the local XIDs and
* don't have to consult distributed log for vacuum or page prunning.
*/
if (GpIdentity.segindex == MASTER_CONTENT_ID)
return false;
/*
* In general expect this function to be called only for normal xid, as
* more performant for caller to avoid the call based on
......
......@@ -1576,8 +1576,12 @@ XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot,
* snapshot since it covers the correct past view of in-progress distributed
* transactions and also the correct future view of in-progress distributed
* transactions that may yet arrive.
*
* In the QD, the distributed transactions become visible at the same time
* as the corresponding local ones, so we can rely on the local XIDs.
*/
if (snapshot->haveDistribSnapshot && !distributedSnapshotIgnore)
if (snapshot->haveDistribSnapshot && !distributedSnapshotIgnore &&
GpIdentity.segindex != MASTER_CONTENT_ID)
{
DistributedSnapshotCommitted distributedSnapshotCommitted;
......
......@@ -56,3 +56,44 @@ gp_inject_fault_new
-------------------
t
(1 row)
-- check catalog tuple visibility while waiting for second phase of 2PC
SELECT gp_inject_fault_new( 'dtm_broadcast_commit_prepared', 'suspend', 1);
gp_inject_fault_new
-------------------
t
(1 row)
1&:CREATE TABLE test_qd_visibility(a int); <waiting ...>
SELECT gp_wait_until_triggered_fault( 'dtm_broadcast_commit_prepared', 1, 1);
gp_wait_until_triggered_fault
-----------------------------
t
(1 row)
-- confirm the transaction is committed in clog
SET gp_select_invisible to ON;
SET
SELECT status FROM gp_transaction_log WHERE transaction IN (SELECT xmin FROM pg_class WHERE relname = 'test_qd_visibility');
status
---------
Committed
(1 row)
SET gp_select_invisible to OFF;
SET
-- the tuple should not be visible
SELECT relname FROM pg_class WHERE relname = 'test_qd_visibility';
relname
-------
(0 rows)
SELECT gp_inject_fault_new( 'dtm_broadcast_commit_prepared', 'reset', 1);
gp_inject_fault_new
-------------------
t
(1 row)
1<: <... completed>
CREATE
-- now the tuple should be visible
SELECT relname FROM pg_class WHERE relname = 'test_qd_visibility';
relname
------------------
test_qd_visibility
(1 row)
......@@ -22,3 +22,18 @@ SELECT gp_inject_fault_new( 'abort_after_procarray_end', 'error', dbid) from gp_
2U: CREATE TABLE test_xact_abort_failure(a int);
2U: ABORT;
SELECT gp_inject_fault_new( 'abort_after_procarray_end', 'reset', dbid) from gp_segment_configuration where role = 'p' and content = 0;
-- check catalog tuple visibility while waiting for second phase of 2PC
SELECT gp_inject_fault_new( 'dtm_broadcast_commit_prepared', 'suspend', 1);
1&:CREATE TABLE test_qd_visibility(a int);
SELECT gp_wait_until_triggered_fault( 'dtm_broadcast_commit_prepared', 1, 1);
-- confirm the transaction is committed in clog
SET gp_select_invisible to ON;
SELECT status FROM gp_transaction_log WHERE transaction IN (SELECT xmin FROM pg_class WHERE relname = 'test_qd_visibility');
SET gp_select_invisible to OFF;
-- the tuple should not be visible
SELECT relname FROM pg_class WHERE relname = 'test_qd_visibility';
SELECT gp_inject_fault_new( 'dtm_broadcast_commit_prepared', 'reset', 1);
1<:
-- now the tuple should be visible
SELECT relname FROM pg_class WHERE relname = 'test_qd_visibility';
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册