Merge pull request #5748 from citusdata/improve_visibility_of_citus_stats

Improve visibility rules for non-priviledge roles on citus_stat_activity
pull/5754/head^2
Önder Kalacı 2022-03-02 18:11:35 +01:00 committed by GitHub
commit 2f0c346c8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 147 additions and 79 deletions

View File

@ -83,6 +83,7 @@ typedef struct BackendManagementShmemData
static void StoreAllActiveTransactions(Tuplestorestate *tupleStore, TupleDesc static void StoreAllActiveTransactions(Tuplestorestate *tupleStore, TupleDesc
tupleDescriptor); tupleDescriptor);
static bool UserHasPermissionToViewStatsOf(Oid currentUserId, Oid backendOwnedId);
static uint64 GenerateGlobalPID(void); static uint64 GenerateGlobalPID(void);
static shmem_startup_hook_type prev_shmem_startup_hook = NULL; static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
@ -114,8 +115,6 @@ assign_distributed_transaction_id(PG_FUNCTION_ARGS)
{ {
CheckCitusVersion(ERROR); CheckCitusVersion(ERROR);
Oid userId = GetUserId();
/* prepare data before acquiring spinlock to protect against errors */ /* prepare data before acquiring spinlock to protect against errors */
int32 initiatorNodeIdentifier = PG_GETARG_INT32(0); int32 initiatorNodeIdentifier = PG_GETARG_INT32(0);
uint64 transactionNumber = PG_GETARG_INT64(1); uint64 transactionNumber = PG_GETARG_INT64(1);
@ -144,9 +143,6 @@ assign_distributed_transaction_id(PG_FUNCTION_ARGS)
"transaction id"))); "transaction id")));
} }
MyBackendData->databaseId = MyDatabaseId;
MyBackendData->userId = userId;
MyBackendData->transactionId.initiatorNodeIdentifier = initiatorNodeIdentifier; MyBackendData->transactionId.initiatorNodeIdentifier = initiatorNodeIdentifier;
MyBackendData->transactionId.transactionNumber = transactionNumber; MyBackendData->transactionId.transactionNumber = transactionNumber;
MyBackendData->transactionId.timestamp = timestamp; MyBackendData->transactionId.timestamp = timestamp;
@ -357,49 +353,44 @@ StoreAllActiveTransactions(Tuplestorestate *tupleStore, TupleDesc tupleDescripto
{ {
Datum values[ACTIVE_TRANSACTION_COLUMN_COUNT]; Datum values[ACTIVE_TRANSACTION_COLUMN_COUNT];
bool isNulls[ACTIVE_TRANSACTION_COLUMN_COUNT]; bool isNulls[ACTIVE_TRANSACTION_COLUMN_COUNT];
bool showAllTransactions = superuser(); bool showAllBackends = superuser();
const Oid userId = GetUserId(); const Oid userId = GetUserId();
/* if (!showAllBackends && is_member_of_role(userId, ROLE_PG_MONITOR))
* We don't want to initialize memory while spinlock is held so we
* prefer to do it here. This initialization is done only for the first
* row.
*/
memset(values, 0, sizeof(values));
memset(isNulls, false, sizeof(isNulls));
if (is_member_of_role(userId, ROLE_PG_MONITOR))
{ {
showAllTransactions = true; showAllBackends = true;
} }
/* we're reading all distributed transactions, prevent new backends */ /* we're reading all distributed transactions, prevent new backends */
LockBackendSharedMemory(LW_SHARED); LockBackendSharedMemory(LW_SHARED);
for (int backendIndex = 0; backendIndex < MaxBackends; ++backendIndex) for (int backendIndex = 0; backendIndex < TotalProcCount(); ++backendIndex)
{ {
bool showCurrentBackendDetails = showAllBackends;
BackendData *currentBackend = BackendData *currentBackend =
&backendManagementShmemData->backends[backendIndex]; &backendManagementShmemData->backends[backendIndex];
PGPROC *currentProc = &ProcGlobal->allProcs[backendIndex];
/* to work on data after releasing g spinlock to protect against errors */ /* to work on data after releasing g spinlock to protect against errors */
uint64 transactionNumber = 0; uint64 transactionNumber = 0;
SpinLockAcquire(&currentBackend->mutex); SpinLockAcquire(&currentBackend->mutex);
if (currentBackend->globalPID == INVALID_CITUS_INTERNAL_BACKEND_GPID) if (currentProc->pid == 0)
{ {
/* unused PGPROC slot */
SpinLockRelease(&currentBackend->mutex); SpinLockRelease(&currentBackend->mutex);
continue; continue;
} }
/* /*
* Unless the user has a role that allows seeing all transactions (superuser, * Unless the user has a role that allows seeing all transactions (superuser,
* pg_monitor), skip over transactions belonging to other users. * pg_monitor), we only follow pg_stat_statements owner checks.
*/ */
if (!showAllTransactions && currentBackend->userId != userId) if (!showCurrentBackendDetails &&
UserHasPermissionToViewStatsOf(userId, currentProc->roleId))
{ {
SpinLockRelease(&currentBackend->mutex); showCurrentBackendDetails = true;
continue;
} }
Oid databaseId = currentBackend->databaseId; Oid databaseId = currentBackend->databaseId;
@ -418,16 +409,42 @@ StoreAllActiveTransactions(Tuplestorestate *tupleStore, TupleDesc tupleDescripto
SpinLockRelease(&currentBackend->mutex); SpinLockRelease(&currentBackend->mutex);
bool missingOk = true; memset(values, 0, sizeof(values));
int nodeId = ExtractNodeIdFromGlobalPID(currentBackend->globalPID, missingOk); memset(isNulls, false, sizeof(isNulls));
values[0] = ObjectIdGetDatum(databaseId); /*
values[1] = Int32GetDatum(backendPid); * We imitate pg_stat_activity such that if a user doesn't have enough
values[2] = Int32GetDatum(nodeId); * privileges, we only show the minimal information including the pid,
values[3] = !distributedCommandOriginator; * global pid and distributedCommandOriginator.
values[4] = UInt64GetDatum(transactionNumber); *
values[5] = TimestampTzGetDatum(transactionIdTimestamp); * pid is already can be found in pg_stat_activity for any process, and
values[6] = UInt64GetDatum(currentBackend->globalPID); * the rest doesn't reveal anything critial for under priviledge users
* but still could be useful for monitoring purposes of Citus.
*/
if (showCurrentBackendDetails)
{
bool missingOk = true;
int initiatorNodeId =
ExtractNodeIdFromGlobalPID(currentBackend->globalPID, missingOk);
values[0] = ObjectIdGetDatum(databaseId);
values[1] = Int32GetDatum(backendPid);
values[2] = Int32GetDatum(initiatorNodeId);
values[3] = !distributedCommandOriginator;
values[4] = UInt64GetDatum(transactionNumber);
values[5] = TimestampTzGetDatum(transactionIdTimestamp);
values[6] = UInt64GetDatum(currentBackend->globalPID);
}
else
{
isNulls[0] = true;
values[1] = Int32GetDatum(backendPid);
isNulls[2] = true;
values[3] = !distributedCommandOriginator;
isNulls[4] = true;
isNulls[5] = true;
values[6] = UInt64GetDatum(currentBackend->globalPID);
}
tuplestore_putvalues(tupleStore, tupleDescriptor, values, isNulls); tuplestore_putvalues(tupleStore, tupleDescriptor, values, isNulls);
@ -444,6 +461,35 @@ StoreAllActiveTransactions(Tuplestorestate *tupleStore, TupleDesc tupleDescripto
} }
/*
* UserHasPermissionToViewStatsOf returns true if currentUserId can
* see backends of backendOwnedId.
*
* We follow the same approach with pg_stat_activity.
*/
static
bool
UserHasPermissionToViewStatsOf(Oid currentUserId, Oid backendOwnedId)
{
if (has_privs_of_role(currentUserId, backendOwnedId))
{
return true;
}
if (is_member_of_role(currentUserId,
#if PG_VERSION_NUM >= PG_VERSION_14
ROLE_PG_READ_ALL_STATS))
#else
DEFAULT_ROLE_READ_ALL_STATS))
#endif
{
return true;
}
return false;
}
/* /*
* InitializeBackendManagement requests the necessary shared memory * InitializeBackendManagement requests the necessary shared memory
* from Postgres and sets up the shared memory startup hook. * from Postgres and sets up the shared memory startup hook.
@ -649,8 +695,6 @@ UnSetDistributedTransactionId(void)
{ {
SpinLockAcquire(&MyBackendData->mutex); SpinLockAcquire(&MyBackendData->mutex);
MyBackendData->databaseId = 0;
MyBackendData->userId = 0;
MyBackendData->cancelledDueToDeadlock = false; MyBackendData->cancelledDueToDeadlock = false;
MyBackendData->transactionId.initiatorNodeIdentifier = 0; MyBackendData->transactionId.initiatorNodeIdentifier = 0;
MyBackendData->transactionId.transactionOriginator = false; MyBackendData->transactionId.transactionOriginator = false;
@ -674,6 +718,8 @@ UnSetGlobalPID(void)
SpinLockAcquire(&MyBackendData->mutex); SpinLockAcquire(&MyBackendData->mutex);
MyBackendData->globalPID = 0; MyBackendData->globalPID = 0;
MyBackendData->databaseId = 0;
MyBackendData->userId = 0;
SpinLockRelease(&MyBackendData->mutex); SpinLockRelease(&MyBackendData->mutex);
} }
@ -755,13 +801,9 @@ AssignDistributedTransactionId(void)
uint64 nextTransactionNumber = pg_atomic_fetch_add_u64(transactionNumberSequence, 1); uint64 nextTransactionNumber = pg_atomic_fetch_add_u64(transactionNumberSequence, 1);
int32 localGroupId = GetLocalGroupId(); int32 localGroupId = GetLocalGroupId();
TimestampTz currentTimestamp = GetCurrentTimestamp(); TimestampTz currentTimestamp = GetCurrentTimestamp();
Oid userId = GetUserId();
SpinLockAcquire(&MyBackendData->mutex); SpinLockAcquire(&MyBackendData->mutex);
MyBackendData->databaseId = MyDatabaseId;
MyBackendData->userId = userId;
MyBackendData->transactionId.initiatorNodeIdentifier = localGroupId; MyBackendData->transactionId.initiatorNodeIdentifier = localGroupId;
MyBackendData->transactionId.transactionOriginator = true; MyBackendData->transactionId.transactionOriginator = true;
MyBackendData->transactionId.transactionNumber = nextTransactionNumber; MyBackendData->transactionId.transactionNumber = nextTransactionNumber;
@ -793,9 +835,15 @@ AssignGlobalPID(void)
globalPID = ExtractGlobalPID(application_name); globalPID = ExtractGlobalPID(application_name);
} }
Oid userId = GetUserId();
SpinLockAcquire(&MyBackendData->mutex); SpinLockAcquire(&MyBackendData->mutex);
MyBackendData->globalPID = globalPID; MyBackendData->globalPID = globalPID;
MyBackendData->distributedCommandOriginator = distributedCommandOriginator; MyBackendData->distributedCommandOriginator = distributedCommandOriginator;
MyBackendData->databaseId = MyDatabaseId;
MyBackendData->userId = userId;
SpinLockRelease(&MyBackendData->mutex); SpinLockRelease(&MyBackendData->mutex);
} }

View File

@ -42,7 +42,7 @@ query |query_hostname |query_hostport|d
(1 row) (1 row)
step s3-view-worker: step s3-view-worker:
SELECT query, query_hostname, query_hostport, distributed_query_host_name, distributed_query_host_port, state, wait_event_type, wait_event, usename, datname FROM citus_worker_stat_activity WHERE query NOT ILIKE '%pg_prepared_xacts%' AND query NOT ILIKE '%COMMIT%' ORDER BY query DESC; SELECT query, query_hostname, query_hostport, distributed_query_host_name, distributed_query_host_port, state, wait_event_type, wait_event, usename, datname FROM citus_worker_stat_activity WHERE query NOT ILIKE '%pg_prepared_xacts%' AND query NOT ILIKE '%COMMIT%' AND backend_type = 'client backend' ORDER BY query DESC;
query |query_hostname|query_hostport|distributed_query_host_name|distributed_query_host_port|state |wait_event_type|wait_event|usename |datname query |query_hostname|query_hostport|distributed_query_host_name|distributed_query_host_port|state |wait_event_type|wait_event|usename |datname
--------------------------------------------------------------------- ---------------------------------------------------------------------
@ -112,7 +112,7 @@ query |query_hostname |query_hostport|di
(1 row) (1 row)
step s3-view-worker: step s3-view-worker:
SELECT query, query_hostname, query_hostport, distributed_query_host_name, distributed_query_host_port, state, wait_event_type, wait_event, usename, datname FROM citus_worker_stat_activity WHERE query NOT ILIKE '%pg_prepared_xacts%' AND query NOT ILIKE '%COMMIT%' ORDER BY query DESC; SELECT query, query_hostname, query_hostport, distributed_query_host_name, distributed_query_host_port, state, wait_event_type, wait_event, usename, datname FROM citus_worker_stat_activity WHERE query NOT ILIKE '%pg_prepared_xacts%' AND query NOT ILIKE '%COMMIT%' AND backend_type = 'client backend' ORDER BY query DESC;
query |query_hostname|query_hostport|distributed_query_host_name|distributed_query_host_port|state |wait_event_type|wait_event|usename |datname query |query_hostname|query_hostport|distributed_query_host_name|distributed_query_host_port|state |wait_event_type|wait_event|usename |datname
--------------------------------------------------------------------- ---------------------------------------------------------------------
@ -176,7 +176,7 @@ query |query_hostname |query_hostport|distribute
(1 row) (1 row)
step s3-view-worker: step s3-view-worker:
SELECT query, query_hostname, query_hostport, distributed_query_host_name, distributed_query_host_port, state, wait_event_type, wait_event, usename, datname FROM citus_worker_stat_activity WHERE query NOT ILIKE '%pg_prepared_xacts%' AND query NOT ILIKE '%COMMIT%' ORDER BY query DESC; SELECT query, query_hostname, query_hostport, distributed_query_host_name, distributed_query_host_port, state, wait_event_type, wait_event, usename, datname FROM citus_worker_stat_activity WHERE query NOT ILIKE '%pg_prepared_xacts%' AND query NOT ILIKE '%COMMIT%' AND backend_type = 'client backend' ORDER BY query DESC;
query |query_hostname|query_hostport|distributed_query_host_name|distributed_query_host_port|state |wait_event_type|wait_event|usename |datname query |query_hostname|query_hostport|distributed_query_host_name|distributed_query_host_port|state |wait_event_type|wait_event|usename |datname
--------------------------------------------------------------------- ---------------------------------------------------------------------
@ -243,7 +243,7 @@ query |query_hostname |query_
(1 row) (1 row)
step s3-view-worker: step s3-view-worker:
SELECT query, query_hostname, query_hostport, distributed_query_host_name, distributed_query_host_port, state, wait_event_type, wait_event, usename, datname FROM citus_worker_stat_activity WHERE query NOT ILIKE '%pg_prepared_xacts%' AND query NOT ILIKE '%COMMIT%' ORDER BY query DESC; SELECT query, query_hostname, query_hostport, distributed_query_host_name, distributed_query_host_port, state, wait_event_type, wait_event, usename, datname FROM citus_worker_stat_activity WHERE query NOT ILIKE '%pg_prepared_xacts%' AND query NOT ILIKE '%COMMIT%' AND backend_type = 'client backend' ORDER BY query DESC;
query |query_hostname|query_hostport|distributed_query_host_name|distributed_query_host_port|state |wait_event_type|wait_event|usename |datname query |query_hostname|query_hostport|distributed_query_host_name|distributed_query_host_port|state |wait_event_type|wait_event|usename |datname
--------------------------------------------------------------------- ---------------------------------------------------------------------

View File

@ -8,10 +8,10 @@ run_command_on_workers
(2 rows) (2 rows)
step s1-grant: step s1-grant:
GRANT ALL ON test_table TO test_user_1; GRANT ALL ON test_table TO test_user_1;
SELECT bool_and(success) FROM run_command_on_placements('test_table', 'GRANT ALL ON TABLE %s TO test_user_1'); SELECT bool_and(success) FROM run_command_on_placements('test_table', 'GRANT ALL ON TABLE %s TO test_user_1');
GRANT ALL ON test_table TO test_user_2; GRANT ALL ON test_table TO test_user_2;
SELECT bool_and(success) FROM run_command_on_placements('test_table', 'GRANT ALL ON TABLE %s TO test_user_2'); SELECT bool_and(success) FROM run_command_on_placements('test_table', 'GRANT ALL ON TABLE %s TO test_user_2');
bool_and bool_and
--------------------------------------------------------------------- ---------------------------------------------------------------------
@ -24,19 +24,19 @@ t
(1 row) (1 row)
step s1-begin-insert: step s1-begin-insert:
BEGIN; BEGIN;
SET ROLE test_user_1; SET ROLE test_user_1;
INSERT INTO test_table VALUES (100, 100); INSERT INTO test_table VALUES (100, 100);
step s2-begin-insert: step s2-begin-insert:
BEGIN; BEGIN;
SET ROLE test_user_2; SET ROLE test_user_2;
INSERT INTO test_table VALUES (200, 200); INSERT INTO test_table VALUES (200, 200);
step s3-as-admin: step s3-as-admin:
-- Admin should be able to see all transactions -- Admin should be able to see all transactions
SELECT count(*) FROM get_all_active_transactions() WHERE transaction_number != 0; SELECT count(*) FROM get_all_active_transactions() WHERE transaction_number != 0;
SELECT count(*) FROM get_global_active_transactions() WHERE transaction_number != 0; SELECT count(*) FROM get_global_active_transactions() WHERE transaction_number != 0;
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
@ -49,26 +49,35 @@ count
(1 row) (1 row)
step s3-as-user-1: step s3-as-user-1:
-- User should only be able to see its own transactions -- Eventhough we change the user via SET ROLE, the backends' (e.g., s1/2-begin-insert)
SET ROLE test_user_1; -- userId (e.g., PG_PROC->userId) does not change, and hence none of the
SELECT count(*) FROM get_all_active_transactions() WHERE transaction_number != 0; -- transactions show up because here we are using test_user_1. This is a
SELECT count(*) FROM get_global_active_transactions() WHERE transaction_number != 0; -- limitation of isolation tester, we should be able to re-connect with
-- test_user_1 on s1/2-begin-insert to show that test_user_1 sees only its own processes
SET ROLE test_user_1;
SELECT count(*) FROM get_all_active_transactions() WHERE transaction_number != 0;
SELECT count(*) FROM get_global_active_transactions() WHERE transaction_number != 0;
count
---------------------------------------------------------------------
0
(1 row)
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
1 1
(1 row) (1 row)
count
---------------------------------------------------------------------
2
(1 row)
step s3-as-readonly: step s3-as-readonly:
-- Other user should not see transactions -- Eventhough we change the user via SET ROLE, the backends' (e.g., s1/2-begin-insert)
SET ROLE test_readonly; -- userId (e.g., PG_PROC->userId) does not change, and hence none of the
SELECT count(*) FROM get_all_active_transactions() WHERE transaction_number != 0; -- transactions show up because here we are using test_readonly. This is a
SELECT count(*) FROM get_global_active_transactions() WHERE transaction_number != 0; -- limitation of isolation tester, we should be able to re-connect with
-- test_readonly on s1/2-begin-insert to show that test_readonly sees only
-- its own processes
SET ROLE test_readonly;
SELECT count(*) FROM get_all_active_transactions() WHERE transaction_number != 0;
SELECT count(*) FROM get_global_active_transactions() WHERE transaction_number != 0;
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
@ -81,10 +90,10 @@ count
(1 row) (1 row)
step s3-as-monitor: step s3-as-monitor:
-- Monitor should see all transactions -- Monitor should see all transactions
SET ROLE test_monitor; SET ROLE test_monitor;
SELECT count(*) FROM get_all_active_transactions() WHERE transaction_number != 0; SELECT count(*) FROM get_all_active_transactions() WHERE transaction_number != 0;
SELECT count(*) FROM get_global_active_transactions() WHERE transaction_number != 0; SELECT count(*) FROM get_global_active_transactions() WHERE transaction_number != 0;
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
@ -97,10 +106,10 @@ count
(1 row) (1 row)
step s1-commit: step s1-commit:
COMMIT; COMMIT;
step s2-commit: step s2-commit:
COMMIT; COMMIT;
run_command_on_workers run_command_on_workers
--------------------------------------------------------------------- ---------------------------------------------------------------------

View File

@ -119,10 +119,11 @@ step s2-view-worker:
query NOT ILIKE '%COMMIT%' AND query NOT ILIKE '%COMMIT%' AND
query NOT ILIKE '%dump_local_%' AND query NOT ILIKE '%dump_local_%' AND
query NOT ILIKE '%citus_internal_local_blocked_processes%' AND query NOT ILIKE '%citus_internal_local_blocked_processes%' AND
query NOT ILIKE '%add_node%' query NOT ILIKE '%add_node%' AND
backend_type = 'client backend'
ORDER BY query, query_hostport DESC; ORDER BY query, query_hostport DESC;
query |query_hostname|query_hostport|distributed_query_host_name|distributed_query_host_port|state |wait_event_type|wait_event|usename |datname query |query_hostname|query_hostport|distributed_query_host_name|distributed_query_host_port|state |wait_event_type|wait_event|usename |datname
--------------------------------------------------------------------- ---------------------------------------------------------------------
UPDATE public.ref_table_1500777 ref_table SET a = (a OPERATOR(pg_catalog.+) 1)|localhost | 57638| | 0|idle in transaction|Client |ClientRead|postgres|regression UPDATE public.ref_table_1500777 ref_table SET a = (a OPERATOR(pg_catalog.+) 1)|localhost | 57638| | 0|idle in transaction|Client |ClientRead|postgres|regression
UPDATE public.ref_table_1500777 ref_table SET a = (a OPERATOR(pg_catalog.+) 1)|localhost | 57637| | 0|idle in transaction|Client |ClientRead|postgres|regression UPDATE public.ref_table_1500777 ref_table SET a = (a OPERATOR(pg_catalog.+) 1)|localhost | 57637| | 0|idle in transaction|Client |ClientRead|postgres|regression

View File

@ -89,7 +89,7 @@ step "s3-rollback"
step "s3-view-worker" step "s3-view-worker"
{ {
SELECT query, query_hostname, query_hostport, distributed_query_host_name, distributed_query_host_port, state, wait_event_type, wait_event, usename, datname FROM citus_worker_stat_activity WHERE query NOT ILIKE '%pg_prepared_xacts%' AND query NOT ILIKE '%COMMIT%' ORDER BY query DESC; SELECT query, query_hostname, query_hostport, distributed_query_host_name, distributed_query_host_port, state, wait_event_type, wait_event, usename, datname FROM citus_worker_stat_activity WHERE query NOT ILIKE '%pg_prepared_xacts%' AND query NOT ILIKE '%COMMIT%' AND backend_type = 'client backend' ORDER BY query DESC;
} }
// we prefer to sleep before "s2-view-dist" so that we can ensure // we prefer to sleep before "s2-view-dist" so that we can ensure

View File

@ -77,7 +77,11 @@ step "s3-as-admin"
step "s3-as-user-1" step "s3-as-user-1"
{ {
-- User should only be able to see its own transactions -- Even though we change the user via SET ROLE, the backends' (e.g., s1/2-begin-insert)
-- userId (e.g., PG_PROC->userId) does not change, and hence none of the
-- transactions show up because here we are using test_user_1. This is a
-- limitation of isolation tester, we should be able to re-connect with
-- test_user_1 on s1/2-begin-insert to show that test_user_1 sees only its own processes
SET ROLE test_user_1; SET ROLE test_user_1;
SELECT count(*) FROM get_all_active_transactions() WHERE transaction_number != 0; SELECT count(*) FROM get_all_active_transactions() WHERE transaction_number != 0;
SELECT count(*) FROM get_global_active_transactions() WHERE transaction_number != 0; SELECT count(*) FROM get_global_active_transactions() WHERE transaction_number != 0;
@ -85,7 +89,12 @@ step "s3-as-user-1"
step "s3-as-readonly" step "s3-as-readonly"
{ {
-- Other user should not see transactions -- Even though we change the user via SET ROLE, the backends' (e.g., s1/2-begin-insert)
-- userId (e.g., PG_PROC->userId) does not change, and hence none of the
-- transactions show up because here we are using test_readonly. This is a
-- limitation of isolation tester, we should be able to re-connect with
-- test_readonly on s1/2-begin-insert to show that test_readonly sees only
-- its own processes
SET ROLE test_readonly; SET ROLE test_readonly;
SELECT count(*) FROM get_all_active_transactions() WHERE transaction_number != 0; SELECT count(*) FROM get_all_active_transactions() WHERE transaction_number != 0;
SELECT count(*) FROM get_global_active_transactions() WHERE transaction_number != 0; SELECT count(*) FROM get_global_active_transactions() WHERE transaction_number != 0;

View File

@ -93,7 +93,8 @@ step "s2-view-worker"
query NOT ILIKE '%COMMIT%' AND query NOT ILIKE '%COMMIT%' AND
query NOT ILIKE '%dump_local_%' AND query NOT ILIKE '%dump_local_%' AND
query NOT ILIKE '%citus_internal_local_blocked_processes%' AND query NOT ILIKE '%citus_internal_local_blocked_processes%' AND
query NOT ILIKE '%add_node%' query NOT ILIKE '%add_node%' AND
backend_type = 'client backend'
ORDER BY query, query_hostport DESC; ORDER BY query, query_hostport DESC;
} }