diff --git a/src/gausskernel/process/postmaster/bgworker.cpp b/src/gausskernel/process/postmaster/bgworker.cpp index 898268537..5ab41aa01 100644 --- a/src/gausskernel/process/postmaster/bgworker.cpp +++ b/src/gausskernel/process/postmaster/bgworker.cpp @@ -645,9 +645,11 @@ static void bgworker_quickdie(SIGNAL_ARGS) static void bgworker_die(SIGNAL_ARGS) { (void)gs_signal_setmask(&t_thrd.libpq_cxt.BlockSig, NULL); - + t_thrd.bgworker_cxt.worker_shutdown_requested = true; t_thrd.postgres_cxt.whereToSendOutput = DestNone; - ereport(FATAL, + if (t_thrd.proc) + SetLatch(&t_thrd.proc->procLatch); + ereport(WARNING, (errcode(ERRCODE_ADMIN_SHUTDOWN), errmsg("terminating background worker \"%s\" due to administrator command", t_thrd.bgworker_cxt.my_bgworker_entry->bgw_type))); @@ -709,7 +711,7 @@ void StartBackgroundWorker(void* bgWorkerSlotShmAddr) } t_thrd.bgworker_cxt.is_background_worker = true; - + t_thrd.bgworker_cxt.worker_shutdown_requested = false; /* Identify myself via ps */ init_ps_display(worker->bgw_name, "", "", ""); diff --git a/src/gausskernel/process/postmaster/postmaster.cpp b/src/gausskernel/process/postmaster/postmaster.cpp index 64fac6422..7fd370291 100755 --- a/src/gausskernel/process/postmaster/postmaster.cpp +++ b/src/gausskernel/process/postmaster/postmaster.cpp @@ -10483,6 +10483,7 @@ int GaussDbThreadMain(knl_thread_arg* arg) case BACKGROUND_WORKER: { t_thrd.bgworker_cxt.is_background_worker = true; + t_thrd.bgworker_cxt.worker_shutdown_requested = false; InitProcessAndShareMemory(); StartBackgroundWorker(arg->payload); proc_exit(0); diff --git a/src/gausskernel/process/tcop/autonomous.cpp b/src/gausskernel/process/tcop/autonomous.cpp index 282e0d3a7..dbbfbf3fb 100644 --- a/src/gausskernel/process/tcop/autonomous.cpp +++ b/src/gausskernel/process/tcop/autonomous.cpp @@ -742,7 +742,7 @@ void autonomous_worker_main(Datum main_arg) break; } } - while (msgtype != 'X'); + while ((msgtype != 'X') && !(t_thrd.bgworker_cxt.worker_shutdown_requested)); } static void shm_mq_receive_stringinfo(shm_mq_handle *qh, StringInfoData *msg) diff --git a/src/gausskernel/process/threadpool/knl_thread.cpp b/src/gausskernel/process/threadpool/knl_thread.cpp index 337d94e7c..0c147becb 100755 --- a/src/gausskernel/process/threadpool/knl_thread.cpp +++ b/src/gausskernel/process/threadpool/knl_thread.cpp @@ -1421,6 +1421,7 @@ void knl_t_bgworker_init(knl_t_bgworker_context* bgworker_cxt) bgworker_cxt->background_worker_data = NULL; bgworker_cxt->my_bgworker_entry = NULL; bgworker_cxt->is_background_worker = false; + bgworker_cxt->worker_shutdown_requested = false; bgworker_cxt->background_worker_list = SLIST_STATIC_INIT(background_worker_list); bgworker_cxt->ParallelMessagePending = false; bgworker_cxt->InitializingParallelWorker = false; diff --git a/src/gausskernel/storage/ipc/shm_mq.cpp b/src/gausskernel/storage/ipc/shm_mq.cpp index 9daa949d5..623e4d3b2 100644 --- a/src/gausskernel/storage/ipc/shm_mq.cpp +++ b/src/gausskernel/storage/ipc/shm_mq.cpp @@ -1017,6 +1017,8 @@ static shm_mq_result shm_mq_receive_bytes(shm_mq_handle *mqh, Size bytes_needed, /* An interrupt may have occurred while we were waiting. */ CHECK_FOR_INTERRUPTS(); + if (t_thrd.bgworker_cxt.worker_shutdown_requested) + return SHM_MQ_DETACHED; } } diff --git a/src/include/knl/knl_thread.h b/src/include/knl/knl_thread.h index e9f58d0cb..4aef1127c 100644 --- a/src/include/knl/knl_thread.h +++ b/src/include/knl/knl_thread.h @@ -2747,6 +2747,7 @@ typedef struct knl_t_bgworker_context { BackgroundWorkerArray *background_worker_data; BackgroundWorker *my_bgworker_entry; bool is_background_worker; + bool worker_shutdown_requested; /* * The postmaster's list of registered background workers, in private memory. */ diff --git a/src/test/regress/expected/autonomous_transaction.out b/src/test/regress/expected/autonomous_transaction.out index 859fd3fab..89548a4b8 100755 --- a/src/test/regress/expected/autonomous_transaction.out +++ b/src/test/regress/expected/autonomous_transaction.out @@ -16,24 +16,24 @@ return i; end; $$; select at_test2(15); - at_test2 + at_test2 ---------- 15 (1 row) select * from at_tb2; - id | val + id | val ----+----- (0 rows) select at_test2(5); - at_test2 + at_test2 ---------- 5 (1 row) select * from at_tb2; - id | val + id | val ----+----------- 1 | before s1 (1 row) @@ -55,13 +55,13 @@ BEGIN end; / call at_test3(6); - at_test3 + at_test3 ---------- - + (1 row) select * from at_tb2; - id | val + id | val ----+----------- 1 | before s1 2 | after s1 @@ -79,13 +79,13 @@ BEGIN end; / select at_test4(6); - at_test4 + at_test4 ---------- - + (1 row) select * from at_tb2; - id | val + id | val ----+----------- 3 | klk 1 | before s1 @@ -93,6 +93,46 @@ select * from at_tb2; 4 | klk (4 rows) +truncate table at_tb2; +create or replace procedure at_test5(i int) +AS +DECLARE + PRAGMA AUTONOMOUS_TRANSACTION; +BEGIN + insert into at_tb2 values(3, 'klk'); + commit; +end; +/ +select at_test5(6); +ERROR: there is no transaction in progress +CONTEXT: PL/pgSQL function at_test5(integer) line 6 at COMMIT +referenced column: at_test5 +select * from at_tb2; + id | val +----+----- + 3 | klk +(1 row) + +truncate table at_tb2; +create or replace procedure at_test6(i int) +AS +DECLARE + PRAGMA AUTONOMOUS_TRANSACTION; +BEGIN + insert into at_tb2 values(3, 'klk'); + rollback; +end; +/ +select at_test6(6); +ERROR: there is no transaction in progress +CONTEXT: PL/pgSQL function at_test6(integer) line 6 at ROLLBACK +referenced column: at_test6 +select * from at_tb2; + id | val +----+----- + 3 | klk +(1 row) + truncate table at_tb2; DECLARE begin @@ -101,7 +141,7 @@ PERFORM at_test3(6); end; / select * from at_tb2; - id | val + id | val ----+----------- 1 | begin 1 | before s1 @@ -112,19 +152,19 @@ truncate table at_tb2; begin; insert into at_tb2 values(1, 'begin'); select * from at_tb2; - id | val + id | val ----+------- 1 | begin (1 row) call at_test3(6); - at_test3 + at_test3 ---------- - + (1 row) select * from at_tb2; - id | val + id | val ----+----------- 1 | begin 1 | before s1 @@ -133,7 +173,7 @@ select * from at_tb2; rollback; select * from at_tb2; - id | val + id | val ----+----------- 1 | before s1 2 | after s1 @@ -158,19 +198,19 @@ truncate table at_test1; begin; insert into at_test1 values(1); select * from at_test1; - a + a --- 1 (1 row) call autonomous_test(); - autonomous_test + autonomous_test ----------------- - + (1 row) select * from at_test1; - a + a --- 1 0 @@ -182,7 +222,7 @@ select * from at_test1; rollback; select * from at_test1; - a + a --- 0 2 @@ -211,19 +251,19 @@ truncate table at_test1; begin; insert into at_test1 values(20); select * from at_test1; - a + a ---- 20 (1 row) select autonomous_test2(); - autonomous_test2 + autonomous_test2 ------------------ 42 (1 row) select * from at_test1; - a + a ---- 20 0 @@ -235,7 +275,7 @@ select * from at_test1; rollback; select * from at_test1; - a + a --- 0 2 @@ -264,19 +304,19 @@ truncate table at_test1; begin; insert into at_test1 values(30); select * from at_test1; - a + a ---- 30 (1 row) select autonomous_test3(); - autonomous_test3 + autonomous_test3 ---------------------- autonomous_test3 end (1 row) select * from at_test1; - a + a ---- 30 0 @@ -288,7 +328,7 @@ select * from at_test1; rollback; select * from at_test1; - a + a --- 0 2 @@ -315,13 +355,13 @@ BEGIN END; $$; select autonomous_cp(); - autonomous_cp + autonomous_cp --------------- 42 (1 row) select * from cp_test3; - a | b + a | b ---+--- 1 | a 2 | b @@ -347,5 +387,5 @@ EXECUTE PROCEDURE tri_insert_test2_func(); insert into tg_test1 values(1,'a','2020-08-13 09:00:00', 1); ERROR: Un-support feature DETAIL: Trigger doesnot support autonomous transaction -CONTEXT: PL/pgSQL function tri_insert_test2_func() line 4 at statement block - +CONTEXT: PL/pgSQL function tri_insert_test2_func() line 4 at statement block + diff --git a/src/test/regress/sql/autonomous_transaction.sql b/src/test/regress/sql/autonomous_transaction.sql index e6593513a..da1859c26 100755 --- a/src/test/regress/sql/autonomous_transaction.sql +++ b/src/test/regress/sql/autonomous_transaction.sql @@ -53,6 +53,32 @@ end; select at_test4(6); select * from at_tb2; +truncate table at_tb2; +create or replace procedure at_test5(i int) +AS +DECLARE + PRAGMA AUTONOMOUS_TRANSACTION; +BEGIN + insert into at_tb2 values(3, 'klk'); + commit; +end; +/ +select at_test5(6); +select * from at_tb2; + +truncate table at_tb2; +create or replace procedure at_test6(i int) +AS +DECLARE + PRAGMA AUTONOMOUS_TRANSACTION; +BEGIN + insert into at_tb2 values(3, 'klk'); + rollback; +end; +/ +select at_test6(6); +select * from at_tb2; + truncate table at_tb2; DECLARE begin