MySQL數(shù)據(jù)庫創(chuàng)建線程的相關(guān)操作詳解
MySQL數(shù)據(jù)庫創(chuàng)建線程的相關(guān)操作是本文我們主要要介紹的內(nèi)容,MySQL數(shù)據(jù)庫中,為了提高系統(tǒng)效率,減少頻繁創(chuàng)建線程和中止線程的系統(tǒng)消耗,MySQL使用了線程緩沖區(qū)的概念,即如果一個(gè)連接斷開,則并不銷毀承載其的線程,而是將此線程放入線程緩沖區(qū),并處于掛起狀態(tài),當(dāng)下一個(gè)新的Connection到來時(shí),首先去線程緩沖區(qū)去查找是否有空閑的線程,如果有,則使用之,如果沒有則新建線程。
1.線程創(chuàng)建函數(shù)
大家知道,Mysql現(xiàn)在是插件式的存儲(chǔ)引擎,只要實(shí)現(xiàn)規(guī)定的接口,就可實(shí)現(xiàn)自己的存儲(chǔ)引擎。故Mysql的線程創(chuàng)建除了出現(xiàn)在主服務(wù)器框架外,存儲(chǔ)引擎也可能會(huì)進(jìn)行線程的創(chuàng)建。通過設(shè)置斷點(diǎn),在我調(diào)試的版本中,發(fā)現(xiàn)了兩個(gè)創(chuàng)建線程的函數(shù)。
pthread_create:Mysql自用的創(chuàng)建線程函數(shù)
os_thread_create:存儲(chǔ)引擎innobase的創(chuàng)建線程的函數(shù)
os_thread_create是存儲(chǔ)引擎innobase的線程函數(shù),先擱淺不研究了,重點(diǎn)看下pthread_create,首先看下其源碼。
- int pthread_create(pthread_t *thread_id, pthread_attr_t *attr,
- pthread_handler func, void *param)
- {
- HANDLE hThread;
- struct pthread_map *map;
- DBUG_ENTER("pthread_create");
- if (!(map=malloc(sizeof(*map))))
- DBUG_RETURN(-1);
- map->funcfunc=func; map->paramparam=param;
- pthread_mutex_lock(&THR_LOCK_thread);
- #ifdef __BORLANDC__
- hThread=(HANDLE)_beginthread((void(_USERENTRY *)(void *)) pthread_start,
- attr->dwStackSize ? attr->dwStackSize :
- 65535, (void*) map);
- #else
- hThread=(HANDLE)_beginthread((void( __cdecl *)(void *)) pthread_start, attr->dwStackSize ? attr->dwStackSize : 65535, (void*) map);
- #endif
- DBUG_PRINT("info", ("hThread=%lu",(long) hThread));
- *thread_id=map->pthreadself=hThread;
- pthread_mutex_unlock(&THR_LOCK_thread);
- if (hThread == (HANDLE) -1)
- {
- int error=errno;
- DBUG_PRINT("error",
- ("Can't create thread to handle request (error %d)",error));
- DBUG_RETURN(error ? error : -1);
- }
- VOID(SetThreadPriority(hThread, attr->priority)) ;
- DBUG_RETURN(0);
- }
上面代碼首先構(gòu)造了一個(gè)map結(jié)構(gòu)體,成員分別是函數(shù)地址和傳入?yún)?shù)。然后調(diào)用操作系統(tǒng)的接口,_beginthread,但是執(zhí)行函數(shù)并不是傳入的函數(shù)——func,而是pthread_start,參數(shù)為map。繼續(xù)跟蹤pthread_start。
- pthread_handler_t pthread_start(void *param)
- {
- pthread_handler
- func=((struct pthread_map *) param)->func
- void *func_param=((struct pthread_map *) param)->param;
- my_thread_init(); /* Will always succeed in windows */
- pthread_mutex_lock(&THR_LOCK_thread); /* Wait for beginthread to return */
- win_pthread_self=((struct pthread_map *) param)->pthreadself;
- pthread_mutex_unlock(&THR_LOCK_thread);
- free((char*) param); /* Free param from create */
- pthread_exit((void*) (*func)(func_param));
- return 0; /* Safety */
- }
可以看出,pthread_start中調(diào)用了map的func元素,作為真正執(zhí)行的函數(shù)體。OK,創(chuàng)建線程的函數(shù)跟蹤到此!
2.服務(wù)器啟動(dòng)時(shí)創(chuàng)建了哪些函數(shù)?
通過在兩個(gè)創(chuàng)建線程的地方設(shè)置斷點(diǎn),總結(jié)了下,在服務(wù)器啟動(dòng)時(shí),創(chuàng)建了如下的線程。
pthread_create創(chuàng)建的線程:
創(chuàng)建線程函數(shù) | 線程執(zhí)行函數(shù) |
create_shutdown_thread |
handle_shutdown |
start_handle_manager |
handle_manager |
handle_connections_methods |
handle_connections_sockets |
innobase的os_thread_create創(chuàng)建的線程:
創(chuàng)建線程函數(shù) | 線程執(zhí)行函數(shù) |
innobase_start_or_create_for_mysql |
io_handler_thread(4個(gè)) |
recv_recovery_from_checkpoint_finish |
trx_rollback_or_clean_all_without_sess |
innobase_start_or_create_for_mysql |
srv_lock_timeout_thread |
srv_error_monitor_thread |
|
srv_monitor_thread |
|
srv_master_thread |
還可以在調(diào)試過程中,通過暫停來看此時(shí)服務(wù)器中的線程,如下圖:
關(guān)于MySQL數(shù)據(jù)庫創(chuàng)建線程的相關(guān)知識(shí)就介紹到這里了,希望本次的介紹能夠?qū)δ兴斋@!
【編輯推薦】






