diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index f2486c782087b49f0fef563231350b3a10ac61c3..34c50649229a941905f1aab1a01e94ca4b22164e 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -183,7 +183,6 @@ typedef struct TransactionStateData bool startedInRecovery; /* did we start in recovery? */ bool didLogXid; /* has xid been included in WAL record? */ bool executorSaysXactDoesWrites; /* GP executor says xact does writes */ - bool xactUsesReaders; /* signal readers to cancel query execution before abort */ struct TransactionStateData *parent; /* back link to parent */ struct TransactionStateData *fastLink; /* back link to jump to parent for efficient search */ @@ -221,7 +220,6 @@ static TransactionStateData TopTransactionStateData = { false, /* startedInRecovery */ false, /* didLogXid */ false, /* executorSaysXactDoesWrites */ - false, /* xactUsesReaders */ NULL /* link to parent state block */ }; @@ -3231,7 +3229,6 @@ AbortTransaction(void) AtAbort_Notify(); AtEOXact_RelationMap(false); AtAbort_Twophase(); - AtAbort_Readers(); /* * Advertise the fact that we aborted in pg_clog (assuming that we got as @@ -5872,30 +5869,6 @@ xactGetCommittedChildren(TransactionId **ptr) return s->nChildXids; } -/* - * Mark this transaction as using QE reader. This is used during abort to - * signal readers to cancel query execution before marking this transaction - * aborted. - */ -void -SetCurrentTransactionUsesReaders(void) -{ - Assert(Gp_is_writer); - CurrentTransactionState->xactUsesReaders = true; -} - -bool -GetCurrentTransactionUsesReaders(void) -{ - return CurrentTransactionState->xactUsesReaders; -} - -void -ResetCurrentTransactionUsesReaders(void) -{ - CurrentTransactionState->xactUsesReaders = false; -} - /* * XLOG support routines */ diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 20528cfe0fc5e8771b0b17501d2a9a8a87d5e564..6dc456d3ae49ec9562d6541b1d00fd9f94bb9ca0 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -4185,6 +4185,7 @@ PostmasterStateMachine(void) } } + /* * Send a signal to a postmaster child process * diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 7b0f8d867881ea71753824898895c2bbc5da6b1e..665bfaae69cd734e7e92ec6f4c64a8bfe54aa6da 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -1548,7 +1548,6 @@ updateSharedLocalSnapshot(DtxContextInfo *dtxContextInfo, Snapshot snapshot, cha SharedLocalSnapshotSlot->QDxid = dtxContextInfo->distributedXid; SharedLocalSnapshotSlot->ready = true; - SharedLocalSnapshotSlot->writerSentCancel = false; SharedLocalSnapshotSlot->segmateSync = dtxContextInfo->segmateSync; @@ -4864,40 +4863,6 @@ ListAllGxid(void) return gxids; } -void -CancelMyReaders(void) -{ - int numProcs; - int i; - int pid_index = 0; - ProcArrayStruct *arrayP = procArray; - - pid_t *reader_pids = (pid_t *) palloc(arrayP->maxProcs * sizeof(pid_t)); - - Assert(Gp_is_writer); - - LWLockAcquire(ProcArrayLock, LW_SHARED); - numProcs = arrayP->numProcs; - for (i = 0; i < numProcs; i++) - { - volatile PGPROC *proc = &allProcs[arrayP->pgprocnos[i]]; - if (proc->mppSessionId == MyProc->mppSessionId && - proc->pid != MyProcPid) - { - Assert(!proc->mppIsWriter); - Assert(proc->databaseId == MyDatabaseId); - reader_pids[pid_index++] = proc->pid; - } - } - LWLockRelease(ProcArrayLock); - - while (--pid_index >= 0) - { - kill(reader_pids[pid_index], SIGINT); /* ignore error */ - SIMPLE_FAULT_INJECTOR(CancelledReaderDuringAbort); - } -} - /* * This function returns the corresponding process id given by a * DistributedTransaction Id. diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 92ccd663160633c47571e046b940830dc6f7c803..f9120678de22919e4731060b7bded01ab3d6e621 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -94,7 +94,6 @@ #include "cdb/cdbgang.h" #include "cdb/ml_ipc.h" #include "utils/guc.h" -#include "utils/sharedsnapshot.h" #include "access/twophase.h" #include "postmaster/backoff.h" #include "utils/resource_manager.h" @@ -237,7 +236,6 @@ static bool RecoveryConflictRetryable = true; static ProcSignalReason RecoveryConflictReason; static DtxContextInfo TempDtxContextInfo = DtxContextInfo_StaticInit; -static bool HandlingWriterCancelRequest = false; extern void CheckForQDMirroringWork(void); @@ -1054,7 +1052,7 @@ exec_mpp_query(const char *query_string, QueryDispatchDesc *ddesc = NULL; CmdType commandType = CMD_UNKNOWN; SliceTable *sliceTable = NULL; - Slice *currentSlice = NULL; + Slice *slice = NULL; ParamListInfo paramLI = NULL; Assert(Gp_role == GP_ROLE_EXECUTE); @@ -1148,14 +1146,14 @@ exec_mpp_query(const char *query_string, /* Identify slice to execute */ foreach(lc, sliceTable->slices) { - currentSlice = (Slice *)lfirst(lc); - if (bms_is_member(qe_identifier, currentSlice->processesMap)) + slice = (Slice *)lfirst(lc); + if (bms_is_member(qe_identifier, slice->processesMap)) break; } - sliceTable->localSlice = currentSlice->sliceIndex; + sliceTable->localSlice = slice->sliceIndex; - Assert(IsA(currentSlice, Slice)); + Assert(IsA(slice, Slice)); /* Set global sliceid variable for elog. */ currentSliceId = sliceTable->localSlice; @@ -1187,10 +1185,10 @@ exec_mpp_query(const char *query_string, commandType = plan->commandType; } - if ( currentSlice ) + if ( slice ) { /* Non root slices don't need update privileges. */ - if (sliceTable->localSlice != currentSlice->rootIndex) + if (sliceTable->localSlice != slice->rootIndex) { ListCell *rtcell; RangeTblEntry *rte; @@ -1306,21 +1304,6 @@ exec_mpp_query(const char *query_string, /* Make sure we are in a transaction command */ start_xact_command(); - /* - * In a query plan there can be at the most one writer that executes - * the root slice. All other slices are executed by readers. If - * readers exist in our plan, we capture that information in the - * transaction state, to be used later during abort. In case of a - * read-only command, no slice should have gangType as PRIMARY_WRITER. - * We can skip the overhead of walking through proc array during abort - * if the command is read-only. - */ - if (sliceTable && list_length(sliceTable->slices) > 1 && Gp_is_writer && - currentSlice->gangType == GANGTYPE_PRIMARY_WRITER) - SetCurrentTransactionUsesReaders(); - else - ResetCurrentTransactionUsesReaders(); - /* If we got a cancel signal in parsing or prior command, quit */ CHECK_FOR_INTERRUPTS(); @@ -3888,23 +3871,9 @@ ProcessInterrupts(const char* filename, int lineno) DisableCatchupInterrupt(); if (Gp_role == GP_ROLE_EXECUTE) - { - HandlingWriterCancelRequest = - !Gp_is_writer && SharedLocalSnapshotSlot && - SharedLocalSnapshotSlot->writerSentCancel; - /* - * Do not send the error message back to QD if the writer - * asked us to cancel the query. Otherwise, if QD receives - * "canceling MPP operation" error before the error reported - * by the writer, the writer's error will not be reported to - * the client. - */ - if (HandlingWriterCancelRequest) - whereToSendOutput = DestNone; ereport(ERROR, (errcode(ERRCODE_GP_OPERATION_CANCELED), errmsg("canceling MPP operation"))); - } else if (HasCancelMessage()) { char *buffer = palloc0(MAX_CANCEL_MSG); @@ -4998,16 +4967,6 @@ PostgresMain(int argc, char *argv[], /* Report the error to the client and/or server log */ EmitErrorReport(); - if (HandlingWriterCancelRequest) - { - /* - * Restore CommandDest so that any error from now on will be - * delivered back to QD. - */ - Assert(!Gp_is_writer); - whereToSendOutput = DestRemote; - HandlingWriterCancelRequest = false; - } /* * Make sure debug_query_string gets reset before we possibly clobber diff --git a/src/backend/utils/time/sharedsnapshot.c b/src/backend/utils/time/sharedsnapshot.c index caead760663d86b28ab6fc94221d3ac6051c7aec..0cd2641e043a5c18d1fc421b30e742e1ed4af1a6 100644 --- a/src/backend/utils/time/sharedsnapshot.c +++ b/src/backend/utils/time/sharedsnapshot.c @@ -942,26 +942,3 @@ LogDistributedSnapshotInfo(Snapshot snapshot, const char *prefix) elog(LOG, "%s", buf.data); pfree(buf.data); } - -/* - * QE writer must let other QE readers participating in the same transaction - * know that the transaction must be canceled. This reduces the window - * between a transaction being marked as aborted by the QE writer and QE - * readers cancel executing part of the transaction / plan. - */ -void -AtAbort_Readers(void) -{ - /* - * Walk the procArray only if the current transaction made any writes and - * there are readers - */ - if (Gp_is_writer && TransactionIdIsValid(GetCurrentTransactionIdIfAny()) && - GetCurrentTransactionUsesReaders()) - { - Assert(SharedLocalSnapshotSlot != NULL); - SharedLocalSnapshotSlot->writerSentCancel = true; - CancelMyReaders(); - } - /* TODO: how to ensure that the readers have acted upon the signal? */ -} diff --git a/src/include/access/xact.h b/src/include/access/xact.h index 607d659b16b00ded5a711840afedd5ba22502496..6af4e534091d499fde799c4dbf52de063e055261 100644 --- a/src/include/access/xact.h +++ b/src/include/access/xact.h @@ -292,9 +292,6 @@ extern void UnregisterSubXactCallback(SubXactCallback callback, void *arg); extern void RecordDistributedForgetCommitted(struct TMGXACT_LOG *gxact_log); extern int xactGetCommittedChildren(TransactionId **ptr); -extern void SetCurrentTransactionUsesReaders(void); -extern bool GetCurrentTransactionUsesReaders(void); -extern void ResetCurrentTransactionUsesReaders(void); extern void xact_redo(XLogRecPtr beginLoc, XLogRecPtr lsn, XLogRecord *record); extern void xact_desc(StringInfo buf, XLogRecord *record); diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h index 092690c12a51b52aabe86f124ff74c56d6a96495..fcb2418f61695ce047f9deda6f4f2d519322696d 100644 --- a/src/include/storage/procarray.h +++ b/src/include/storage/procarray.h @@ -96,7 +96,6 @@ extern void GetSlotTableDebugInfo(void **snapshotArray, int *maxSlots); extern void getDtxCheckPointInfo(char **result, int *result_size); extern List *ListAllGxid(void); -extern void CancelMyReaders(void); extern int GetPidByGxid(DistributedTransactionId gxid); extern void ProcArraySetReplicationSlotXmin(TransactionId xmin, diff --git a/src/include/utils/faultinjector_lists.h b/src/include/utils/faultinjector_lists.h index b7d3daf32e6be857e6b515cb8ff2de9e455fd0bb..af9b5b5dec280734d6d2445e80f0774b939f2718 100644 --- a/src/include/utils/faultinjector_lists.h +++ b/src/include/utils/faultinjector_lists.h @@ -255,8 +255,6 @@ FI_IDENT(CreateGangInProgress, "create_gang_in_progress") FI_IDENT(DecreaseToastMaxChunkSize, "decrease_toast_max_chunk_size") /* inject fault to let cleanupGang return false */ FI_IDENT(CleanupQE, "cleanup_qe") -/* inject fault after a writer has cancelled a reader during abort transaction */ -FI_IDENT(CancelledReaderDuringAbort, "cancelled_reader_during_abort") #endif /* diff --git a/src/include/utils/sharedsnapshot.h b/src/include/utils/sharedsnapshot.h index 7b3a371e8f41f265411fd9a0780171c2b841aa16..85ae3e80a7e9127c42bf3c3ae04bd4d4f5c08ddc 100644 --- a/src/include/utils/sharedsnapshot.h +++ b/src/include/utils/sharedsnapshot.h @@ -36,7 +36,6 @@ typedef struct SharedSnapshotSlot ComboCidKeyData combocids[MaxComboCids]; SnapshotData snapshot; LWLockId slotLock; - bool writerSentCancel; } SharedSnapshotSlot; extern volatile SharedSnapshotSlot *SharedLocalSnapshotSlot; @@ -54,7 +53,6 @@ extern void dumpSharedLocalSnapshot_forCursor(void); extern void readSharedLocalSnapshot_forCursor(Snapshot snapshot); extern void AtEOXact_SharedSnapshot(void); -extern void AtAbort_Readers(void); #define NUM_SHARED_SNAPSHOT_SLOTS (2 * max_prepared_xacts) diff --git a/src/test/regress/expected/writer_aborts_reader.out b/src/test/regress/expected/writer_aborts_reader.out deleted file mode 100644 index c50fc3e6af0b5a5b09ac6a60dd596303040648bb..0000000000000000000000000000000000000000 --- a/src/test/regress/expected/writer_aborts_reader.out +++ /dev/null @@ -1,165 +0,0 @@ --- Tests to validate that in a multi-slice query a QE writer signals QE readers --- to cancel query execution before marking the transaction as aborted. --- The tests make use of a "skip" fault to determine if the control reached a --- specific location of interest. In this case, the location of the fault --- "cancelled_reader_during_abort" is right after a writer sends SIGINT to --- corresponding readers. -CREATE EXTENSION IF NOT EXISTS gp_inject_fault; -create table writer_aborts_before_reader_a(i int, j int) distributed by (i); -alter table writer_aborts_before_reader_a add constraint check_j check (j > 0); -insert into writer_aborts_before_reader_a select 4,i from generate_series(1,12) i; -create table writer_aborts_before_reader_b (like writer_aborts_before_reader_a) distributed by (i); -insert into writer_aborts_before_reader_b select * from writer_aborts_before_reader_a; --- first test: one writer with one or more readers -select gp_inject_fault('cancelled_reader_during_abort', 'skip', dbid) from -gp_segment_configuration where role = 'p' and content = 0; -NOTICE: Success: (seg0 127.0.0.1:25432 pid=51789) - gp_inject_fault ------------------ - t -(1 row) - -begin; --- Make a write in this transaction so that a TransactionId will be assigned. -insert into writer_aborts_before_reader_a values (4, 4); --- This multi-slice update is aborted because QE writer encounters constraint --- failure. The writer must send cancel signal to the readers before aborting the --- transaction. The fault, therefore, is expected to hit at least once. -update writer_aborts_before_reader_a set j = -1 from writer_aborts_before_reader_b; -ERROR: new row for relation "writer_aborts_before_reader_a" violates check constraint "check_j" (seg0 127.0.0.1:25432 pid=51789) -DETAIL: Failing row contains (4, -1). -end; -select gp_wait_until_triggered_fault('cancelled_reader_during_abort', 1, dbid) from -gp_segment_configuration where role = 'p' and content = 0; -NOTICE: Success: (seg0 127.0.0.1:25432 pid=51789) - gp_wait_until_triggered_fault -------------------------------- - t -(1 row) - -select gp_inject_fault('cancelled_reader_during_abort', 'reset', dbid) from -gp_segment_configuration where role = 'p' and content = 0; -NOTICE: Success: (seg0 127.0.0.1:25432 pid=51789) - gp_inject_fault ------------------ - t -(1 row) - --- second test: one writer with no readers -select gp_inject_fault('cancelled_reader_during_abort', 'skip', dbid) from -gp_segment_configuration where role = 'p' and content = 0; -NOTICE: Success: (seg0 127.0.0.1:25432 pid=51789) - gp_inject_fault ------------------ - t -(1 row) - -begin; --- Make a write in this transaction so that a TransactionId will be assigned. -insert into writer_aborts_before_reader_a values (4, 4); --- No reader gangs. This is a single slice update. The writer aborts the --- transaction because of constraint failure. -update writer_aborts_before_reader_a set j = -1; -ERROR: new row for relation "writer_aborts_before_reader_a" violates check constraint "check_j" (seg0 127.0.0.1:25432 pid=51789) -DETAIL: Failing row contains (4, -1). -end; --- The writer from the previous update statement is not expceted to walk the --- proc array and look for readers because that was a single-slice statement. --- Therefore, hit count for the fault should be 0. -select gp_inject_fault('cancelled_reader_during_abort', 'status', dbid) from -gp_segment_configuration where role = 'p' and content = 0; -NOTICE: Success: fault name:'cancelled_reader_during_abort' fault type:'skip' ddl statement:'' database name:'' table name:'' start occurrence:'1' end occurrence:'1' extra arg:'0' fault injection state:'set' num times hit:'0' (seg0 127.0.0.1:25432 pid=51789) - gp_inject_fault ------------------ - t -(1 row) - -select gp_inject_fault('cancelled_reader_during_abort', 'reset', dbid) from -gp_segment_configuration where role = 'p' and content = 0; -NOTICE: Success: (seg0 127.0.0.1:25432 pid=51789) - gp_inject_fault ------------------ - t -(1 row) - --- third test: writer and reader, but the transaction does not write -select gp_inject_fault('cancelled_reader_during_abort', 'skip', dbid) from -gp_segment_configuration where role = 'p' and content = 0; -NOTICE: Success: (seg0 127.0.0.1:25432 pid=51789) - gp_inject_fault ------------------ - t -(1 row) - -begin; --- This is a non-colocated join, with two slices. -select count(*) from writer_aborts_before_reader_a, writer_aborts_before_reader_b -where writer_aborts_before_reader_a.i = writer_aborts_before_reader_b.j; - count -------- - 12 -(1 row) - -abort; --- The previous abort should cause the QE writer to go through abort workflow. --- But the writer should not walk the proc array and look for readers because the --- transaction did not make any writes. Therefore, the fault status is expected --- to return hit count as 0. -select gp_inject_fault('cancelled_reader_during_abort', 'status', dbid) from -gp_segment_configuration where role = 'p' and content = 0; -NOTICE: Success: fault name:'cancelled_reader_during_abort' fault type:'skip' ddl statement:'' database name:'' table name:'' start occurrence:'1' end occurrence:'1' extra arg:'0' fault injection state:'set' num times hit:'0' (seg0 127.0.0.1:25432 pid=51789) - gp_inject_fault ------------------ - t -(1 row) - -select gp_inject_fault('cancelled_reader_during_abort', 'reset', dbid) from -gp_segment_configuration where role = 'p' and content = 0; -NOTICE: Success: (seg0 127.0.0.1:25432 pid=51789) - gp_inject_fault ------------------ - t -(1 row) - --- fourth test: the transaction does write but the last command before --- abort is read-only -select gp_inject_fault('cancelled_reader_during_abort', 'skip', dbid) from -gp_segment_configuration where role = 'p' and content = 0; -NOTICE: Success: (seg0 127.0.1.1:25432 pid=1390) - gp_inject_fault ------------------ - t -(1 row) - -begin; --- Make a write in this transaction so that a TransactionId will be assigned. -insert into writer_aborts_before_reader_a values (4, 4); --- Both the slices in this query plan have gangType PRIMARY_READER -select count(*) from writer_aborts_before_reader_a, writer_aborts_before_reader_b -where writer_aborts_before_reader_a.i = writer_aborts_before_reader_b.j; - count -------- - 13 -(1 row) - -abort; --- QE writer should not walk through proc array during abort to look --- for readers because none of the slices in the last command had --- gangType PRIMARY_WRITER. Hit count reported by the status should --- therefore be 0. -select gp_inject_fault('cancelled_reader_during_abort', 'status', dbid) from -gp_segment_configuration where role = 'p' and content = 0; -NOTICE: Success: fault name:'cancelled_reader_during_abort' fault type:'skip' ddl statement:'' database name:'' table name:'' start occurrence:'1' end occurrence:'1' extra arg:'0' fault injection state:'set' num times hit:'0' (seg0 127.0.1.1:25432 pid=1390) - gp_inject_fault ------------------ - t -(1 row) - -select gp_inject_fault('cancelled_reader_during_abort', 'reset', dbid) from -gp_segment_configuration where role = 'p' and content = 0; -NOTICE: Success: (seg0 127.0.1.1:25432 pid=1390) - gp_inject_fault ------------------ - t -(1 row) - diff --git a/src/test/regress/greenplum_schedule b/src/test/regress/greenplum_schedule index b5c9c934ca731984a7b0b061ab16dccad8077d4e..c9fcc5e7866306de41769baaaf4ad3c815998ca4 100755 --- a/src/test/regress/greenplum_schedule +++ b/src/test/regress/greenplum_schedule @@ -136,7 +136,7 @@ test: catalog test: bfv_catalog bfv_index bfv_olap bfv_aggregate bfv_partition bfv_partition_plans DML_over_joins gporca bfv_statistic # NOTE: gporca_faults uses gp_fault_injector - so do not add to a parallel group test: gporca_faults - + test: aggregate_with_groupingsets test: nested_case_null sort bb_mpph @@ -242,10 +242,4 @@ test: autovacuum-template0 # Online expand introduce the partial tables, check them if they can run correctly test: gangsize -# This test uses fault injectors in abort transaction workflow. It -# may be run in parallel with other tests as long as they don't abort -# a transaction where mult-slice query was executed and the writer was -# assigned a transaction ID. -test: writer_aborts_reader - # end of tests diff --git a/src/test/regress/sql/writer_aborts_reader.sql b/src/test/regress/sql/writer_aborts_reader.sql deleted file mode 100644 index 53c0e290ca6554e6a93a1dc9b2e892c09b107fd9..0000000000000000000000000000000000000000 --- a/src/test/regress/sql/writer_aborts_reader.sql +++ /dev/null @@ -1,97 +0,0 @@ --- Tests to validate that in a multi-slice query a QE writer signals QE readers --- to cancel query execution before marking the transaction as aborted. --- The tests make use of a "skip" fault to determine if the control reached a --- specific location of interest. In this case, the location of the fault --- "cancelled_reader_during_abort" is right after a writer sends SIGINT to --- corresponding readers. - -CREATE EXTENSION IF NOT EXISTS gp_inject_fault; -create table writer_aborts_before_reader_a(i int, j int) distributed by (i); -alter table writer_aborts_before_reader_a add constraint check_j check (j > 0); -insert into writer_aborts_before_reader_a select 4,i from generate_series(1,12) i; - -create table writer_aborts_before_reader_b (like writer_aborts_before_reader_a) distributed by (i); -insert into writer_aborts_before_reader_b select * from writer_aborts_before_reader_a; - --- first test: one writer with one or more readers -select gp_inject_fault('cancelled_reader_during_abort', 'skip', dbid) from -gp_segment_configuration where role = 'p' and content = 0; - -begin; --- Make a write in this transaction so that a TransactionId will be assigned. -insert into writer_aborts_before_reader_a values (4, 4); --- This multi-slice update is aborted because QE writer encounters constraint --- failure. The writer must send cancel signal to the readers before aborting the --- transaction. The fault, therefore, is expected to hit at least once. -update writer_aborts_before_reader_a set j = -1 from writer_aborts_before_reader_b; -end; - -select gp_wait_until_triggered_fault('cancelled_reader_during_abort', 1, dbid) from -gp_segment_configuration where role = 'p' and content = 0; - -select gp_inject_fault('cancelled_reader_during_abort', 'reset', dbid) from -gp_segment_configuration where role = 'p' and content = 0; - --- second test: one writer with no readers -select gp_inject_fault('cancelled_reader_during_abort', 'skip', dbid) from -gp_segment_configuration where role = 'p' and content = 0; - -begin; --- Make a write in this transaction so that a TransactionId will be assigned. -insert into writer_aborts_before_reader_a values (4, 4); --- No reader gangs. This is a single slice update. The writer aborts the --- transaction because of constraint failure. -update writer_aborts_before_reader_a set j = -1; -end; - --- The writer from the previous update statement is not expceted to walk the --- proc array and look for readers because that was a single-slice statement. --- Therefore, hit count for the fault should be 0. -select gp_inject_fault('cancelled_reader_during_abort', 'status', dbid) from -gp_segment_configuration where role = 'p' and content = 0; - -select gp_inject_fault('cancelled_reader_during_abort', 'reset', dbid) from -gp_segment_configuration where role = 'p' and content = 0; - --- third test: writer and reader, but the transaction does not write -select gp_inject_fault('cancelled_reader_during_abort', 'skip', dbid) from -gp_segment_configuration where role = 'p' and content = 0; - -begin; --- This is a non-colocated join, with two slices. -select count(*) from writer_aborts_before_reader_a, writer_aborts_before_reader_b -where writer_aborts_before_reader_a.i = writer_aborts_before_reader_b.j; -abort; - --- The previous abort should cause the QE writer to go through abort workflow. --- But the writer should not walk the proc array and look for readers because the --- transaction did not make any writes. Therefore, the fault status is expected --- to return hit count as 0. -select gp_inject_fault('cancelled_reader_during_abort', 'status', dbid) from -gp_segment_configuration where role = 'p' and content = 0; - -select gp_inject_fault('cancelled_reader_during_abort', 'reset', dbid) from -gp_segment_configuration where role = 'p' and content = 0; - --- fourth test: the transaction does write but the last command before --- abort is read-only -select gp_inject_fault('cancelled_reader_during_abort', 'skip', dbid) from -gp_segment_configuration where role = 'p' and content = 0; - -begin; --- Make a write in this transaction so that a TransactionId will be assigned. -insert into writer_aborts_before_reader_a values (4, 4); --- Both the slices in this query plan have gangType PRIMARY_READER -select count(*) from writer_aborts_before_reader_a, writer_aborts_before_reader_b -where writer_aborts_before_reader_a.i = writer_aborts_before_reader_b.j; -abort; - --- QE writer should not walk through proc array during abort to look --- for readers because none of the slices in the last command had --- gangType PRIMARY_WRITER. Hit count reported by the status should --- therefore be 0. -select gp_inject_fault('cancelled_reader_during_abort', 'status', dbid) from -gp_segment_configuration where role = 'p' and content = 0; - -select gp_inject_fault('cancelled_reader_during_abort', 'reset', dbid) from -gp_segment_configuration where role = 'p' and content = 0;