Searchingrowsforupdate狀態(tài)初探

一、背景說明

企業(yè)官網(wǎng)是企業(yè)形象的一張重要名片。成都創(chuàng)新互聯(lián)的成都官網(wǎng)定制服務(wù),能夠?qū)⒊啥季W(wǎng)頁設(shè)計(jì)與企業(yè)的實(shí)力&公信力、產(chǎn)品服務(wù)優(yōu)勢(shì)、文化價(jià)值觀等有機(jī)結(jié)合,把握企業(yè)的獨(dú)特之處,突出重點(diǎn)核心內(nèi)容,并以恰如其分的設(shè)計(jì)風(fēng)格,抓住目標(biāo)用戶的關(guān)注點(diǎn)和興趣點(diǎn),幫助企業(yè)塑造好第一印象,成都全網(wǎng)營銷推廣展現(xiàn)公司實(shí)力。成都官網(wǎng)定制,為你解決成都創(chuàng)新互聯(lián)網(wǎng)營銷解決方案。

最近有位朋友咨詢說為何如此多線程處于Searching rows for update,當(dāng)時(shí)看到這個(gè)狀態(tài)的第一反應(yīng)就是鎖,這里暫且拋開鎖不談,談一談為何出現(xiàn)Searching rows for update

二、實(shí)驗(yàn)環(huán)境:

root@MySQLdb 10:15: [xucl]> show create table test1\G

*************************** 1. row ***************************

Table: test1

Create Table: CREATE TABLE `test1` (

`a` int(11) NOT NULL,

`b` varchar(20) DEFAULT NULL,

PRIMARY KEY (`a`),

KEY `b` (`b`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

1 row in set (0.00 sec)

root@mysqldb 10:15: [xucl]> select * from test1;

+---+------+

| a | b |

+---+------+

| 2 | b |

| 3 | c |

| 1 | ccc |

+---+------+

3 rows in set (0.00 sec)

大概出現(xiàn)的狀態(tài)如下所示:

Searching rows for update狀態(tài)初探

三、初探過程

簡單做了pstack,其中id=2的線程堆棧如下:

從堆棧很明顯可以看出,該線程處于鎖等待的狀態(tài),但為何處于Searching rows for update并沒有給出明確暗示,可以看到調(diào)用的順序是

mysql_parse

mysql_execute_command

Sql_cmd_update::execute_command

mysql_update

...

ha_innobase::index_read

...

lock_wait_suspend_thread

...

廢話不多說,咱們直接從mysql_update切入,該入口函數(shù)位置在sql_update.cc

bool mysql_update(THD *thd,

List &fields,

List &values,

ha_rows limit,

enum enum_duplicates handle_duplicates,

ha_rows *found_return, ha_rows *updated_return)

{

...

if (used_key_is_modified || order)

{

/*

When we get here, we have one of the following options:

A. used_index == MAX_KEY

This means we should use full table scan, and start it with

init_read_record call

B. used_index != MAX_KEY

B.1 quick select is used, start the scan with init_read_record

B.2 quick select is not used, this is full index scan (with LIMIT)

Full index scan must be started with init_read_record_idx

*/

if (used_index == MAX_KEY || (qep_tab.quick()))

error= init_read_record(&info, thd, NULL, &qep_tab, 0, 1, FALSE);

else

error= init_read_record_idx(&info, thd, table, 1, used_index, reverse);

if (error)

goto exit_without_my_ok;

THD_STAGE_INFO(thd, stage_searching_rows_for_update);

ha_rows tmp_limit= limit;

}

...

debug結(jié)果如下:

Searching rows for update狀態(tài)初探

這里判斷條件為used_index是否等于MAX_KEY,其中MAX_KEY為常量,used_index的定義如下:

used_index= get_index_for_order(order, &qep_tab, limit, &need_sort, &reverse);

這里的判斷就比較復(fù)雜了,本人水平有限,暫時(shí)未深入理解優(yōu)化器的部分,也不展開說明,源碼位置在sql_select.cc,有興趣的同學(xué)可以深入研究一下

函數(shù)is_key_used定義如下:無錫看婦科的醫(yī)院 http://www.ytsgfk120.com/

bool is_key_used(TABLE *table, uint idx, const MY_BITMAP *fields)

{

bitmap_clear_all(&table->tmp_set); //清空tmp_set位圖

table->mark_columns_used_by_index_no_reset(idx, &table->tmp_set); //這里設(shè)置位圖

const bool overlapping= bitmap_is_overlapping(&table->tmp_set, fields); //比較索引位置和修改位置是否重合

// Clear tmp_set so it can be used elsewhere

bitmap_clear_all(&table->tmp_set);

if (overlapping)

return 1; //如果重合返回1

...

Searching rows for update狀態(tài)初探

看到debug的結(jié)果變量,used_key_is_modified為true,那么進(jìn)入如下判斷

Searching rows for update狀態(tài)初探

然后就進(jìn)入stage_searching_rows_for_update狀態(tài),也就是我們一開始在show processlist中看到的狀態(tài)

Searching rows for update狀態(tài)初探

而如果我們修改的是其他字段,那么進(jìn)入的狀態(tài)便是Updating,對(duì)應(yīng)的源碼為

if (used_key_is_modified || order)

{

...

}

...

thd->count_cuted_fields= CHECK_FIELD_WARN;

thd->cuted_fields=0L;

THD_STAGE_INFO(thd, stage_updating);

...

廢話不多說,我們來測(cè)試驗(yàn)證一下THD_STAGE_INFO(thd, stage_updating);處打上斷點(diǎn),然后更新數(shù)據(jù)

Searching rows for update狀態(tài)初探

實(shí)驗(yàn)結(jié)果符合預(yù)期

其他測(cè)試結(jié)果:

case結(jié)果

update主鍵直接進(jìn)入stage_updating

update唯一索引直接進(jìn)入stage_updating

update普通二級(jí)索引+limit進(jìn)入stage_searching_rows_for_update,完成后進(jìn)入stage_updating

四、總結(jié)

最后總結(jié)一下:

Searching rows for update狀態(tài)出現(xiàn)的要求比較嚴(yán)格,當(dāng)進(jìn)行數(shù)據(jù)更新時(shí),如果更新的字段為當(dāng)前執(zhí)行計(jì)劃用到的索引,并且該索引屬于普通二級(jí)索引(不能是主鍵也不能是唯一索引),那么就會(huì)出現(xiàn)Searching rows for update狀態(tài),正因?yàn)槌霈F(xiàn)了鎖等待,所以能看到這種狀態(tài)

如果不是,那么直接進(jìn)入U(xiǎn)pdating狀態(tài),這個(gè)狀態(tài)也就是我們經(jīng)??吹降臓顟B(tài)

出現(xiàn)如上兩種狀態(tài)并且持續(xù)時(shí)間長,并不是造成數(shù)據(jù)庫性能下降的根本原因,而應(yīng)該考慮其他原因,如本案例中的鎖等待問題

文章標(biāo)題:Searchingrowsforupdate狀態(tài)初探
瀏覽地址:http://bm7419.com/article10/jddddo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站收錄、網(wǎng)站策劃、商城網(wǎng)站響應(yīng)式網(wǎng)站、微信公眾號(hào)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

營銷型網(wǎng)站建設(shè)