MySQL数据库线程缓冲池工作原理解析与配置优化

您当前的位置:   首页 > 首页 > 解决方案
MySQL数据库线程缓冲池工作原理解析与配置优化
发布时间:2026-02-28 05:10:37

MySQL数据库线程缓冲池的相关知识是该篇文章我们主要要介绍的内容,MySQL数据库支持线程缓存,在多线程连接模式下,如果连接断开后,将这个线程放入空闲线程缓冲区,在下次有连接到来时,先去缓冲池中查找是否有空闲线程,有则用之,无则创建。启动时可以设置线程缓冲池的数目:Mysqld.exe --thread_cache_size=10。

在一个连接断开时,会调用cache_thread函数,将空闲的线程加入到cache中,以备后用。源码如下:

static bool cache_thread()  {  safe_mutex_assert_owner(&LOCK_thread_count);  if (  cached_thread_count < thread_cache_size &&  ! abort_loop && !kill_cached_threads)  {  /* Don't kill the thread, just put it in cache for reuse */  DBUG_PRINT("info", ("Adding thread to cache"));  cached_thread_count++;  while (!abort_loop && ! wake_thread && ! kill_cached_threads)  (void) pthread_cond_wait(&COND_thread_cache, &LOCK_thread_count);  cached_thread_count--;  if (kill_cached_threads)  pthread_cond_signal(&COND_flush_thread_cache);  if (wake_thread)  {  THD *thd;  wake_thread--;  thdthread_cache.get();  thd->thread_stack= (char*) &thd;          // For store_globals  (void) thd->store_globals();  /*  THD::mysys_var::abort is associated with physical thread rather  than with THD object. So we need to reset this flag before using  this thread for handling of new THD object/connection.  */  thd->mysys_var->abort0;  thd->thr_create_utimemy_micro_time();  threads.append(thd);  return(1);  }  }  return(0);  

上面我们的启动参数设置线程缓冲区为10,此时对应代码里面的thread_cache_size = 10,cached_thread_count记录

了此刻cache中的空闲线程数目,只有在cache未满的情况下,才会将新的空闲线程加入缓冲池中。加入到缓冲区其实就是将线

程挂起,pthread_cond_wait函数便是线程等待函数,在此函数中,会调用WaitForMultipleObjects进行事件等待。具体源码

如下:

int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,  struct timespec *abstime)  int result;  long timeout;   union ft64 now;  if( abstime != NULL )  {  GetSystemTimeAsFileTime(&now.ft);  /*  Calculate time left to abstime  - subtract start time from current time(values are in 100ns units)  - convert to millisec by dividing with 10000  */  timeout= (long)((abstime->tv.i64 - now.i64) / 10000);  /* Don't allow the timeout to be negative */  if (timeout < 0)  timeout0L;  /*  Make sure the calucated timeout does not exceed original timeout  value which could cause "wait for ever" if system time changes  */  if (timeout > abstime->max_timeout_msec)  timeoutabstime->max_timeout_msec;  }  else  {  /* No time specified; don't expire */  timeoutINFINITE;  }  /*   Block access if previous broadcast hasn't finished.  This is just for safety and should normally not  affect the total time spent in this function.  */  WaitForSingleObject(cond->broadcast_block_event, INFINITE);  EnterCriticalSection(&cond->lock_waiting);  cond->waiting++;  LeaveCriticalSection(&cond->lock_waiting);  LeaveCriticalSection(mutex);  resultWaitForMultipleObjects(2, cond->events, FALSE, timeout);  EnterCriticalSection(&cond->lock_waiting);  cond->waiting--;  if (cond->waiting == 0)  {  /*  We're the last waiter to be notified or to stop waiting, so  reset the manual event.   */  /* Close broadcast gate */  ResetEvent(cond->events[BROADCAST]);  /* Open block gate */  SetEvent(cond->broadcast_block_event);  }  LeaveCriticalSection(&cond->lock_waiting);  EnterCriticalSection(mutex);  return result == WAIT_TIMEOUT   ETIMEDOUT : 0;  

此处是等待时间,何处进行事件通知呢?我们再次来到上篇所提及的为新的连接创建线程的代码中:

void create_thread_to_handle_connection(THD *thd)  {  if (cached_thread_count > wake_thread)  {  /* Get thread from cache */  thread_cache.append(thd);  wake_thread++;  pthread_cond_signal(&COND_thread_cache);  }  Else  ...  

关于MySQL数据库线程缓冲池的相关知识就介绍到这里了,希望本次的介绍能够对您有所收获!