| -- Check if retry logic handles errors correctly. The retry logic had |
| -- a bug where error state wasn't cleaned up correctly during retries, |
| -- leading to PANIC due to ERRORDATA_STACK_SIZE exeeded. |
| -- Set a fault on one of the QEs such that an error is raised exactly |
| -- 10 times at the beginning of 2nd phase of 2PC. |
| -- ERRORDATA_STACK_SIZE is defined as 10. By erroring out 10 times, |
| -- the error handling logic in QD gets invoked 10 times. If error |
| -- state is not cleaned up before each retry, it is suffice to return |
| -- an error 10 times to hit the above mentioned PANIC. |
| |
| -- |
| -- COMMIT_PREPARED |
| -- |
| select gp_inject_fault('finish_prepared_start_of_function', 'error', '', '', '', 1, 10, 0, dbid) |
| from gp_segment_configuration where role = 'p' and status = 'u' and content = 1; |
| begin; |
| create table dtm_retry_table (a int) distributed by (a); |
| -- Expected behavior is QD makes 11 attempts to commit and the last |
| -- one succeeds. |
| end; |
| -- Reset all faults. |
| select gp_inject_fault_infinite('all', 'reset', dbid) from gp_segment_configuration; |
| -- Verify that the table got created properly on all segments. |
| insert into dtm_retry_table select * from generate_series(1,12); |
| |
| -- |
| -- ABORT_SOME_PREPARED |
| -- |
| -- Let content 0 primary error out during prepare. This leads to |
| -- abort_some_prepared broadcast in 2nd phase. |
| select gp_inject_fault('start_prepare', 'error', dbid) |
| from gp_segment_configuration where role = 'p' and status = 'u' and content = 0; |
| -- Let content 1 primary, which had successfully prepared the |
| -- transaction, report error 10 times upon receiving |
| -- abort_some_prepared request. |
| select gp_inject_fault('finish_prepared_start_of_function', 'error', '', '', '', 1, 10, 0, dbid) |
| from gp_segment_configuration where role = 'p' and status = 'u' and content = 1; |
| begin; |
| truncate table dtm_retry_table; |
| -- Expected behavior: QD's 11th attempt to broadcast |
| -- abort_some_prepared message succeeds. |
| end; |
| -- Verify that the table wasn't truncated due to prevous transaction |
| -- being aborted. |
| select count(*) = 12 from dtm_retry_table; |
| |
| -- Reset all faults. |
| select gp_inject_fault_infinite('all', 'reset', dbid) from gp_segment_configuration; |
| |
| -- |
| -- ABORT_PREPARED |
| -- |
| -- After successful prepare, QD should error out, leading to |
| -- abort_prepared broadcast in 2nd phase. |
| select gp_inject_fault('dtm_broadcast_prepare', 'error', dbid) |
| from gp_segment_configuration where role = 'p' and content = -1; |
| -- Let content 0 primary error out 10 times during second phase. |
| select gp_inject_fault('finish_prepared_start_of_function', 'error', '', '', '', 1, 10, 0, dbid) |
| from gp_segment_configuration where role = 'p' and status = 'u' and content = 0; |
| begin; |
| truncate table dtm_retry_table; |
| -- Expected behavior: QD's 11th attempt to broadcast |
| -- abort_prepared message succeeds. |
| end; |
| -- Verify that the table wasn't truncated due to prevous transaction |
| -- being aborted. |
| select count(*) = 12 from dtm_retry_table; |
| |
| -- Reset all faults. |
| select gp_inject_fault_infinite('all', 'reset', dbid) from gp_segment_configuration; |