Commit 8f603bcb authored by Sergey Vojtovich's avatar Sergey Vojtovich

MDEV-7952 - clock_gettime() takes 0.24% in OLTP RO

Initialize abs_timeout when it is about to be used. This saves one my_hrtime()
call on hot path (when we acquire MDL lock without waiting).

When filling I_S.PROCESSLIST use THD::start_utime/THD::utime_after_query instead
of THD::start_time. This allows us to save 2 clock_gettime() calls.

Overhead change:
__clock_gettime   0.13% -> 0.11% (122 -> 76 calls per OLTP RO transaction)
my_interval_timer 0.07% -> 0.06%
my_hrtime         0.04% -> 0.01%
parent 2bc6e29a
...@@ -1972,14 +1972,10 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout) ...@@ -1972,14 +1972,10 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout)
{ {
MDL_lock *lock; MDL_lock *lock;
MDL_ticket *ticket; MDL_ticket *ticket;
struct timespec abs_timeout;
MDL_wait::enum_wait_status wait_status; MDL_wait::enum_wait_status wait_status;
DBUG_ENTER("MDL_context::acquire_lock"); DBUG_ENTER("MDL_context::acquire_lock");
DBUG_PRINT("enter", ("lock_type: %d", mdl_request->type)); DBUG_PRINT("enter", ("lock_type: %d", mdl_request->type));
/* Do some work outside the critical section. */
set_timespec(abs_timeout, lock_wait_timeout);
if (try_acquire_lock_impl(mdl_request, &ticket)) if (try_acquire_lock_impl(mdl_request, &ticket))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
...@@ -2028,7 +2024,8 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout) ...@@ -2028,7 +2024,8 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout)
find_deadlock(); find_deadlock();
struct timespec abs_shortwait; struct timespec abs_timeout, abs_shortwait;
set_timespec(abs_timeout, lock_wait_timeout);
set_timespec(abs_shortwait, 1); set_timespec(abs_shortwait, 1);
wait_status= MDL_wait::EMPTY; wait_status= MDL_wait::EMPTY;
......
...@@ -947,7 +947,7 @@ THD::THD(bool is_wsrep_applier) ...@@ -947,7 +947,7 @@ THD::THD(bool is_wsrep_applier)
// Must be reset to handle error with THD's created for init of mysqld // Must be reset to handle error with THD's created for init of mysqld
lex->current_select= 0; lex->current_select= 0;
user_time.val= start_time= start_time_sec_part= 0; user_time.val= start_time= start_time_sec_part= 0;
start_utime= prior_thr_create_utime= 0L; start_utime= utime_after_query= prior_thr_create_utime= 0L;
utime_after_lock= 0L; utime_after_lock= 0L;
progress.arena= 0; progress.arena= 0;
progress.report_to_client= 0; progress.report_to_client= 0;
......
...@@ -1943,7 +1943,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1943,7 +1943,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->m_statement_psi= NULL; thd->m_statement_psi= NULL;
thd->m_digest= NULL; thd->m_digest= NULL;
thd->set_time();
dec_thread_running(); dec_thread_running();
thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
......
...@@ -2301,7 +2301,7 @@ public: ...@@ -2301,7 +2301,7 @@ public:
{ TRASH(ptr, size); } { TRASH(ptr, size); }
ulong thread_id; ulong thread_id;
time_t start_time; ulonglong start_time;
uint command; uint command;
const char *user,*host,*db,*proc_info,*state_info; const char *user,*host,*db,*proc_info,*state_info;
CSET_STRING query_string; CSET_STRING query_string;
...@@ -2432,7 +2432,10 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) ...@@ -2432,7 +2432,10 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
} }
else else
thd_info->progress= 0.0; thd_info->progress= 0.0;
thd_info->start_time= tmp->start_time; thd_info->start_time= tmp->start_utime;
ulonglong utime_after_query_snapshot= tmp->utime_after_query;
if (thd_info->start_time < utime_after_query_snapshot)
thd_info->start_time= utime_after_query_snapshot; // COM_SLEEP
mysql_mutex_unlock(&tmp->LOCK_thd_data); mysql_mutex_unlock(&tmp->LOCK_thd_data);
thread_infos.append(thd_info); thread_infos.append(thd_info);
} }
...@@ -2440,7 +2443,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) ...@@ -2440,7 +2443,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
mysql_mutex_unlock(&LOCK_thread_count); mysql_mutex_unlock(&LOCK_thread_count);
thread_info *thd_info; thread_info *thd_info;
time_t now= my_time(0); ulonglong now= microsecond_interval_timer();
char buff[20]; // For progress char buff[20]; // For progress
String store_buffer(buff, sizeof(buff), system_charset_info); String store_buffer(buff, sizeof(buff), system_charset_info);
...@@ -2455,8 +2458,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) ...@@ -2455,8 +2458,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
protocol->store(thd_info->proc_info, system_charset_info); protocol->store(thd_info->proc_info, system_charset_info);
else else
protocol->store(command_name[thd_info->command].str, system_charset_info); protocol->store(command_name[thd_info->command].str, system_charset_info);
if (thd_info->start_time) if (thd_info->start_time && now > thd_info->start_time)
protocol->store_long ((longlong) (now - thd_info->start_time)); protocol->store_long(now - thd_info->start_time);
else else
protocol->store_null(); protocol->store_null();
protocol->store(thd_info->state_info, system_charset_info); protocol->store(thd_info->state_info, system_charset_info);
...@@ -2730,7 +2733,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) ...@@ -2730,7 +2733,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
TABLE *table= tables->table; TABLE *table= tables->table;
CHARSET_INFO *cs= system_charset_info; CHARSET_INFO *cs= system_charset_info;
char *user; char *user;
my_hrtime_t unow= my_hrtime(); ulonglong unow= microsecond_interval_timer();
DBUG_ENTER("fill_schema_processlist"); DBUG_ENTER("fill_schema_processlist");
DEBUG_SYNC(thd,"fill_schema_processlist_after_unow"); DEBUG_SYNC(thd,"fill_schema_processlist_after_unow");
...@@ -2793,9 +2796,12 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) ...@@ -2793,9 +2796,12 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
table->field[4]->store(command_name[tmp->get_command()].str, table->field[4]->store(command_name[tmp->get_command()].str,
command_name[tmp->get_command()].length, cs); command_name[tmp->get_command()].length, cs);
/* MYSQL_TIME */ /* MYSQL_TIME */
ulonglong start_utime= tmp->start_time * HRTIME_RESOLUTION + tmp->start_time_sec_part; ulonglong utime= tmp->start_utime;
ulonglong utime= start_utime && start_utime < unow.val ulonglong utime_after_query_snapshot= tmp->utime_after_query;
? unow.val - start_utime : 0; if (utime < utime_after_query_snapshot)
utime= utime_after_query_snapshot; // COM_SLEEP
utime= utime && utime < unow ? unow - utime : 0;
table->field[5]->store(utime / HRTIME_RESOLUTION, TRUE); table->field[5]->store(utime / HRTIME_RESOLUTION, TRUE);
/* STATE */ /* STATE */
if ((val= thread_state_info(tmp))) if ((val= thread_state_info(tmp)))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment