diff --git a/src/gausskernel/cbb/utils/gssignal/gs_signal.cpp b/src/gausskernel/cbb/utils/gssignal/gs_signal.cpp index 2c30f0afb..32a62ad96 100644 --- a/src/gausskernel/cbb/utils/gssignal/gs_signal.cpp +++ b/src/gausskernel/cbb/utils/gssignal/gs_signal.cpp @@ -1142,3 +1142,18 @@ gs_sigfunc gspqsignal(int signo, gs_sigfunc func) { return gs_signal_register_handler(t_thrd.signal_slot->gssignal, signo, func); } + +void gs_signal_get_timer(struct timeval* timeval) +{ + struct itimerspec restime; + /* Save rest time for future resume */ + if (timer_gettime(t_thrd.utils_cxt.sigTimerId, /* the created timer */ + &restime)) { + timeval->tv_sec = 0; + timeval->tv_usec = 0; + return; + } + timeval->tv_sec = restime.it_value.tv_sec; + timeval->tv_usec = restime.it_value.tv_nsec / 1000ULL; + return; +} diff --git a/src/gausskernel/process/tcop/postgres.cpp b/src/gausskernel/process/tcop/postgres.cpp index 7a07e7958..b364d40f8 100755 --- a/src/gausskernel/process/tcop/postgres.cpp +++ b/src/gausskernel/process/tcop/postgres.cpp @@ -3152,6 +3152,7 @@ static void exec_simple_query(const char* query_string, MessageType messageType, t_thrd.postgres_cxt.debug_query_string = NULL; t_thrd.postgres_cxt.cur_command_tag = T_Invalid; + t_thrd.storage_cxt.timer_continued = {0, 0}; /* * @hdfs @@ -5501,6 +5502,7 @@ static void exec_execute_message(const char* portal_name, long max_rows) t_thrd.postgres_cxt.debug_query_string = NULL; t_thrd.postgres_cxt.cur_command_tag = T_Invalid; + t_thrd.storage_cxt.timer_continued = {0, 0}; gstrace_exit(GS_TRC_ID_exec_execute_message); } @@ -8560,6 +8562,7 @@ int PostgresMain(int argc, char* argv[], const char* dbname, const char* usernam */ t_thrd.postgres_cxt.debug_query_string = NULL; t_thrd.postgres_cxt.cur_command_tag = T_Invalid; + t_thrd.storage_cxt.timer_continued = {0, 0}; if (u_sess->unique_sql_cxt.need_update_calls && is_unique_sql_enabled() && is_local_unique_sql()) { @@ -8719,6 +8722,7 @@ int PostgresMain(int argc, char* argv[], const char* dbname, const char* usernam u_sess->statement_cxt.executer_run_level = 0; initStringInfo(&input_message); + t_thrd.storage_cxt.timer_continued = {0, 0}; t_thrd.postgres_cxt.debug_query_string = NULL; t_thrd.postgres_cxt.cur_command_tag = T_Invalid; t_thrd.postgres_cxt.g_NoAnalyzeRelNameList = NIL; @@ -9771,6 +9775,7 @@ int PostgresMain(int argc, char* argv[], const char* dbname, const char* usernam pfree_ext(completionTag); t_thrd.postgres_cxt.debug_query_string = NULL; t_thrd.postgres_cxt.cur_command_tag = T_Invalid; + t_thrd.storage_cxt.timer_continued = {0, 0}; if (MEMORY_TRACKING_QUERY_PEAK) ereport(LOG, (errmsg("execute opfusion, peak memory %ld(kb)", (int64)(t_thrd.utils_cxt.peakedBytesInQueryLifeCycle/1024)))); diff --git a/src/gausskernel/process/threadpool/knl_thread.cpp b/src/gausskernel/process/threadpool/knl_thread.cpp index 4938f7d5f..a20b0eb61 100755 --- a/src/gausskernel/process/threadpool/knl_thread.cpp +++ b/src/gausskernel/process/threadpool/knl_thread.cpp @@ -1411,6 +1411,7 @@ static void knl_t_storage_init(knl_t_storage_context* storage_cxt) storage_cxt->lockwait_timeout_active = false; storage_cxt->deadlock_state = DS_NOT_YET_CHECKED; storage_cxt->cancel_from_timeout = false; + storage_cxt->timer_continued = {0, 0}; storage_cxt->timeout_start_time = 0; storage_cxt->statement_fin_time = 0; storage_cxt->statement_fin_time2 = 0; diff --git a/src/gausskernel/storage/lmgr/proc.cpp b/src/gausskernel/storage/lmgr/proc.cpp index 931920101..60aecb07b 100755 --- a/src/gausskernel/storage/lmgr/proc.cpp +++ b/src/gausskernel/storage/lmgr/proc.cpp @@ -2154,7 +2154,13 @@ int ProcSleep(LOCALLOCK* locallock, LockMethod lockMethodTable, bool allow_con_u int needWaitTime = Max(1000, (allow_con_update ? u_sess->attr.attr_storage.LockWaitUpdateTimeout : u_sess->attr.attr_storage.LockWaitTimeout) - u_sess->attr.attr_storage.DeadlockTimeout); if (waitSec > 0) { - needWaitTime =Max(1, (waitSec * 1000) - u_sess->attr.attr_storage.DeadlockTimeout); + if (t_thrd.storage_cxt.timer_continued.tv_sec != 0 || t_thrd.storage_cxt.timer_continued.tv_usec != 0) { + int tmpWaitTime = t_thrd.storage_cxt.timer_continued.tv_sec * 1000 + + t_thrd.storage_cxt.timer_continued.tv_usec / 1000; + needWaitTime = Max(1, tmpWaitTime - u_sess->attr.attr_storage.DeadlockTimeout); + } else { + needWaitTime =Max(1, (waitSec * 1000) - u_sess->attr.attr_storage.DeadlockTimeout); + } } if (myWaitStatus == STATUS_WAITING && u_sess->attr.attr_storage.LockWaitTimeout > 0 && @@ -2168,7 +2174,7 @@ int ProcSleep(LOCALLOCK* locallock, LockMethod lockMethodTable, bool allow_con_u /* * Disable the timer, if it's still running */ - if (!disable_sig_alarm(false)) + if (!disable_sig_alarm(false, waitSec)) ereport(FATAL, (errcode(ERRCODE_SYSTEM_ERROR), errmsg("could not disable timer for process wakeup"))); /* @@ -2844,7 +2850,7 @@ bool disable_idle_in_transaction_session_sig_alarm(void) * * Returns TRUE if okay, FALSE on failure. */ -bool disable_sig_alarm(bool is_statement_timeout) +bool disable_sig_alarm(bool is_statement_timeout, int waitSec) { /* * Always disable the interrupt if it is active; this avoids being @@ -2856,11 +2862,16 @@ bool disable_sig_alarm(bool is_statement_timeout) if (t_thrd.storage_cxt.statement_timeout_active || t_thrd.storage_cxt.deadlock_timeout_active || t_thrd.storage_cxt.lockwait_timeout_active || t_thrd.wlm_cxt.wlmalarm_timeout_active || u_sess->statement_cxt.query_plan_threshold_active) { + if (waitSec > 0) { + gs_signal_get_timer(&(t_thrd.storage_cxt.timer_continued)); + } + if (gs_signal_canceltimer()) { t_thrd.storage_cxt.statement_timeout_active = false; t_thrd.storage_cxt.cancel_from_timeout = false; t_thrd.storage_cxt.deadlock_timeout_active = false; t_thrd.storage_cxt.lockwait_timeout_active = false; + t_thrd.storage_cxt.timer_continued = {0, 0}; t_thrd.wlm_cxt.wlmalarm_timeout_active = false; u_sess->statement_cxt.query_plan_threshold_active = false; return false; diff --git a/src/include/gssignal/gs_signal.h b/src/include/gssignal/gs_signal.h index 2e932bc1c..ab1dfcd8e 100644 --- a/src/include/gssignal/gs_signal.h +++ b/src/include/gssignal/gs_signal.h @@ -173,6 +173,7 @@ extern int gs_signal_canceltimer(void); extern int gs_signal_deletetimer(void); extern void gs_signal_monitor_startup(void); +extern void gs_signal_get_timer(struct timeval* timeval); #ifdef WIN32 #define pgwin32_dispatch_queued_signals gs_signal_handle diff --git a/src/include/knl/knl_thread.h b/src/include/knl/knl_thread.h index 6b214e360..068b3e682 100755 --- a/src/include/knl/knl_thread.h +++ b/src/include/knl/knl_thread.h @@ -2800,6 +2800,7 @@ typedef struct knl_t_storage_context { volatile bool lockwait_timeout_active; volatile int deadlock_state; volatile bool cancel_from_timeout; + struct timeval timer_continued; /* timeout_start_time is set when log_lock_waits is true */ TimestampTz timeout_start_time; /* statement_fin_time is valid only if statement_timeout_active is true */ diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h index d8f840380..8a212b6d7 100755 --- a/src/include/storage/proc.h +++ b/src/include/storage/proc.h @@ -558,7 +558,7 @@ extern bool enable_query_plan_sig_alarm(int delayms); extern bool disable_session_sig_alarm(void); extern bool disable_idle_in_transaction_session_sig_alarm(void); -extern bool disable_sig_alarm(bool is_statement_timeout); +extern bool disable_sig_alarm(bool is_statement_timeout, int waitSec = 0); extern bool pause_sig_alarm(bool is_statement_timeout); extern bool resume_sig_alarm(bool is_statement_timeout); extern void handle_sig_alarm(SIGNAL_ARGS);