分析MySQL中FTWRL一個(gè)奇怪的堵塞現(xiàn)象

本篇內(nèi)容介紹了“分析MySQL中FTWRL一個(gè)奇怪的堵塞現(xiàn)象”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站服務(wù)團(tuán)隊(duì)是一支充滿著熱情的團(tuán)隊(duì),執(zhí)著、敏銳、追求更好,是創(chuàng)新互聯(lián)的標(biāo)準(zhǔn)與要求,同時(shí)竭誠(chéng)為客戶提供服務(wù)是我們的理念。創(chuàng)新互聯(lián)公司把每個(gè)網(wǎng)站當(dāng)做一個(gè)產(chǎn)品來開發(fā),精雕細(xì)琢,追求一名工匠心中的細(xì)致,我們更用心!

一、兩個(gè)不同的現(xiàn)象

首先建立一張有幾條數(shù)據(jù)的表就可以了,我這里是baguait1表了。

  • 案例1
SESSION1SESSION2SESSION3
步驟1:select sleep(1000) from baguait1 for update;


步驟2:flush table with read lock;堵塞


步驟3:kill session2


步驟4:select * from baguait1 limit 1;成功

步驟2 “flush table with read lock;”操作等待狀態(tài)為“Waiting for global read lock”,如下:

mysql> select Id,State,Info   from information_schema.processlist  where command<>'sleep';
+----+------------------------------+------------------------------------------------------------------------------------+
| Id | State                        | Info                                                                               |
+----+------------------------------+------------------------------------------------------------------------------------+
|  1 | Waiting on empty queue       | NULL                                                                               |
| 18 | Waiting for global read lock | flush table with read lock                                                         |
|  3 | User sleep                   | select sleep(1000) from baguait1 for update                                        |
|  6 | executing                    | select Id,State,Info   from information_schema.processlist  where command<>'sleep' |
+----+------------------------------+------------------------------------------------------------------------------------+
  • 案例2

這里比較奇怪了,實(shí)際上我很久以前就遇到過和測(cè)試過但是沒有仔細(xì)研究過,這次剛好詳細(xì)看看。

SESSION1SESSION2SESSION3
步驟1:select sleep(1000) from baguait1


步驟2:flush table with read lock;堵塞


步驟3:kill session2


步驟4:select * from baguait1 limit 1;堵塞

步驟2  “flush table with read lock;”操作等待狀態(tài)為 “Waiting for table flush”,狀態(tài)如下:

mysql> select Id,State,Info   from information_schema.processlist  where command<>'sleep';
+----+-------------------------+------------------------------------------------------------------------------------+
| Id | State                   | Info                                                                               |
+----+-------------------------+------------------------------------------------------------------------------------+
|  1 | Waiting on empty queue  | NULL                                                                               |
| 26 | User sleep              | select sleep(1000) from baguait1                                                   |
| 23 | Waiting for table flush | flush table with read lock                                                         |
|  6 | executing               | select Id,State,Info   from information_schema.processlist  where command<>'sleep' |
+----+-------------------------+------------------------------------------------------------------------------------+

步驟4  “select * from testmts.baguait1 limit 1”操作等待狀態(tài)為 “Waiting for table flush”,這個(gè)想象看起來非常奇怪沒有任何特殊的其他操作,select居然堵塞了。

mysql> select Id,State,Info   from information_schema.processlist  where command<>'sleep';
+----+-------------------------+------------------------------------------------------------------------------------+
| Id | State                   | Info                                                                               |
+----+-------------------------+------------------------------------------------------------------------------------+
|  1 | Waiting on empty queue  | NULL                                                                               |
| 26 | User sleep              | select sleep(1000) from baguait1                                                   |
| 27 | executing               | select Id,State,Info   from information_schema.processlist  where command<>'sleep' |
|  6 | Waiting for table flush | select * from testmts.baguait1 limit 1                                             |
+----+-------------------------+------------------------------------------------------------------------------------+

如果仔細(xì)對(duì)比兩個(gè)案例實(shí)際上區(qū)別僅僅在于 步驟1中的select 語句是否加了for update,案例2中我們發(fā)現(xiàn)即便我們將“flush table with read lock;”會(huì)話KILL掉也會(huì)堵塞隨后的關(guān)于本表上全部操作(包括select),這個(gè)等待實(shí)際上會(huì)持續(xù)到步驟1的sleep操作完成過后。

對(duì)于線上數(shù)據(jù)庫(kù)的話,如果在長(zhǎng)時(shí)間的select大表期間執(zhí)行“flush table with read lock;”就會(huì)出現(xiàn)這種情況,這種情況會(huì)造成全部關(guān)于本表的操作等待,即便你發(fā)現(xiàn)后殺掉了FTWRL會(huì)話也無濟(jì)于事,等待會(huì)持續(xù)到select操作完成后,除非你KILL掉長(zhǎng)時(shí)間的select操作。

為什么會(huì)出現(xiàn)這種情況呢?我們接下來慢慢分析。

二、sleep 函數(shù)生效點(diǎn)

關(guān)于本案例中我使用sleep函數(shù)來代替select 大表操作做為測(cè)試,在這里這個(gè)代替是成立的。為什么成立呢我們來看一下sleep函數(shù)的生效點(diǎn)如下:

T@3: | | | | | | | | >evaluate_join_record
T@3: | | | | | | | | | enter: join: 0x7ffee0007350 join_tab index: 0 table: tii cond: 0x0
T@3: | | | | | | | | | counts: evaluate_join_record join->examined_rows++: 1
T@3: | | | | | | | | | >end_send
T@3: | | | | | | | | | | >Query_result_send::send_data
T@3: | | | | | | | | | | | >send_result_set_row
T@3: | | | | | | | | | | | | >THD::enter_cond
T@3: | | | | | | | | | | | | | THD::enter_stage: 'User sleep' /mysqldata/percona-server-locks-detail-5.7.22/sql/item_func.cc:6057
T@3: | | | | | | | | | | | | | >PROFILING::status_change
T@3: | | | | | | | | | | | | | <PROFILING::status_change 384
T@3: | | | | | | | | | | | | <THD::enter_cond 3405

這里看出sleep的生效點(diǎn)實(shí)際上每次Innodb層返回一行數(shù)據(jù)經(jīng)過where條件判斷后,再觸發(fā)sleep函數(shù),也就是每行經(jīng)過where條件過濾的數(shù)據(jù)在發(fā)送給客戶端之前都會(huì)進(jìn)行一次sleep操作。這個(gè)時(shí)候?qū)嶋H上該打開表的和該上MDL LOCK的都已經(jīng)完成了,因此使用sleep函數(shù)來模擬大表select操作導(dǎo)致的FTWRL堵塞是可以的。

三、FTWRL做了什么工作

實(shí)際上這部分我們可以在函數(shù)mysql_execute_command尋找case SQLCOM_FLUSH 的部分,實(shí)際上主要調(diào)用函數(shù)為reload_acl_and_cache,其中核心部分為:

if (thd->global_read_lock.lock_global_read_lock(thd))//加 MDL GLOBAL 級(jí)別S鎖
    return 1;                               // Killed
      if (close_cached_tables(thd, tables, //關(guān)閉表操作釋放 share 和 cache
                              ((options & REFRESH_FAST) ?  FALSE : TRUE),
                              thd->variables.lock_wait_timeout)) //等待時(shí)間受lock_wait_timeout影響
      {
        /*
          NOTE: my_error() has been already called by reopen_tables() within
          close_cached_tables().
        */
        result= 1;
      }
      if (thd->global_read_lock.make_global_read_lock_block_commit(thd)) // MDL COMMIT 鎖
      {
        /* Don't leave things in a half-locked state */
        thd->global_read_lock.unlock_global_read_lock(thd);
        return 1;
      }

更具體的關(guān)閉表的操作和釋放table緩存的部分包含在函數(shù)close_cached_tables中,我就不詳細(xì)寫了。但是我們需要明白table緩存實(shí)際上包含兩個(gè)部分:

  • table cache define:每一個(gè)表第一次打開的時(shí)候都會(huì)建立一個(gè)靜態(tài)的表定義結(jié)構(gòu)內(nèi)存,當(dāng)多個(gè)會(huì)話同時(shí)訪問同一個(gè)表的時(shí)候,從這里拷貝成相應(yīng)的instance供會(huì)話自己使用。由參數(shù)table_definition_cache定義大小,由狀態(tài)值Open_table_definitions查看當(dāng)前使用的個(gè)數(shù)。對(duì)應(yīng)函數(shù)get_table_share。

  • table cache instance:同上所述,這是會(huì)話實(shí)際使用的表定義結(jié)構(gòu)是一個(gè)instance。由參數(shù)table_open_cache定義大小,由狀態(tài)值Open_tables查看當(dāng)前使用的個(gè)數(shù)。對(duì)應(yīng)函數(shù)open_table_from_share。

這里我統(tǒng)稱為table緩存,好了下面是我總結(jié)的FTWRl的大概步驟:

第一步:加MDL LOCK類型為GLOBAL 級(jí)別為S。如果出現(xiàn)等待狀態(tài)為‘Waiting for global read lock’。注意select語句不會(huì)上GLOBAL級(jí)別上鎖,但是DML/DDL/FOR UPDATE語句會(huì)上GLOBAL級(jí)別的IX鎖,IX鎖和S鎖不兼容會(huì)出現(xiàn)這種等待。下面是這個(gè)兼容矩陣:

          | Type of active   |
  Request |   scoped lock    |
   type   | IS(*)  IX   S  X |
 ---------+------------------+
 IS       |  +      +   +  + |
 IX       |  +      +   -  - |
 S        |  +      -   +  - |
 X        |  +      -   -  - |

第二步:推進(jìn)全局表緩存版本。源碼中就是一個(gè)全局變量 refresh_version++。
第三步:釋放沒有使用的table 緩存??勺孕袇⒖己瘮?shù)close_cached_tables函數(shù)。
第四步:判斷是否有正在占用的table緩存,如果有則等待,等待占用者釋放。等待狀態(tài)為’Waiting for table flush’。這一步會(huì)去判斷table緩存的版本和全局表緩存版本是否匹配,如果不匹配則等待如下:

for (uint idx=0 ; idx < table_def_cache.records ; idx++) 
      {
        share= (TABLE_SHARE*) my_hash_element(&table_def_cache, idx); //尋找整個(gè) table cache shared hash結(jié)構(gòu)
        if (share->has_old_version()) //如果版本 和 當(dāng)前 的 refresh_version 版本不一致
        {
          found= TRUE;
          break; //跳出第一層查找 是否有老版本 存在
        }
      }
...
if (found)//如果找到老版本,需要等待
    {
      /*
        The method below temporarily unlocks LOCK_open and frees
        share's memory.
      */
      if (share->wait_for_old_version(thd, &abstime,
                                    MDL_wait_for_subgraph::DEADLOCK_WEIGHT_DDL))
      {
        mysql_mutex_unlock(&LOCK_open);
        result= TRUE;
        goto err_with_reopen;
      }
    }

而等待的結(jié)束就是占用的table緩存的占用者釋放,這個(gè)釋放操作存在于函數(shù)close_thread_table中,如下:

if (table->s->has_old_version() || table->needs_reopen() ||
      table_def_shutdown_in_progress)
  {
    tc->remove_table(table);//關(guān)閉 table cache instance
    mysql_mutex_lock(&LOCK_open);
    intern_close_table(table);//去掉 table cache define
    mysql_mutex_unlock(&LOCK_open);
  }

最終會(huì)調(diào)用函數(shù)MDL_wait::set_status將FTWRL喚醒,也就是說對(duì)于正在占用的table緩存釋放者不是FTWRL會(huì)話而是占用者自己。不管怎么樣最終整個(gè)table緩存將會(huì)被清空,如果經(jīng)過FTWRL后去查看Open_table_definitions和Open_tables將會(huì)發(fā)現(xiàn)重新計(jì)數(shù)了。下面是喚醒函數(shù)的代碼,也很明顯:

bool MDL_wait::set_status(enum_wait_status status_arg) open_table
{
  bool was_occupied= TRUE;
  mysql_mutex_lock(&m_LOCK_wait_status);
  if (m_wait_status == EMPTY)
  {
    was_occupied= FALSE;
    m_wait_status= status_arg;
    mysql_cond_signal(&m_COND_wait_status);//喚醒
  }
  mysql_mutex_unlock(&m_LOCK_wait_status);//解鎖
  return was_occupied;
}

第五步:加MDL LOCK類型COMMIT 級(jí)別為S。如果出現(xiàn)等待狀態(tài)為‘Waiting for commit lock’。如果有大事務(wù)的提交很可能出現(xiàn)這種等待。

四、案例1解析

步驟1 我們使用select for update語句,這個(gè)語句會(huì)加GLOBAL級(jí)別的IX鎖,持續(xù)到語句結(jié)束(注意實(shí)際上還會(huì)加對(duì)象級(jí)別的MDL_SHARED_WRITE(SW)鎖持續(xù)到事務(wù)結(jié)束,和FTWRL無關(guān)不做描述)

步驟2 我們使用FTWRL語句,根據(jù)上面的分析需要獲取GLOBAL級(jí)別的S鎖,不兼容,因此出現(xiàn)了等待‘Waiting for global read lock’

步驟3 我們KILL掉了FTWRL會(huì)話,這種情況下會(huì)話退出,F(xiàn)TWRL就像沒有執(zhí)行過一樣不會(huì)有任何影響,因?yàn)樗诘谝徊骄投氯恕?/p>

步驟4 我們的select操作不會(huì)受到任何影響

五、案例2解析

步驟1 我們使用select 語句,這個(gè)語句不會(huì)在GLOBAL級(jí)別上任何的鎖(注意實(shí)際上還會(huì)加對(duì)象級(jí)別的MDL_SHARED_READ(SR)鎖持續(xù)到事務(wù)結(jié)束,和FTWRL無關(guān)不做描述)

步驟2 我們使用FTWRL語句,根據(jù)上面的分析我們發(fā)現(xiàn)FTWRL語句可以獲取了GLOBAL 級(jí)別的S鎖,因?yàn)閱渭兊膕elect 語句不會(huì)在GLOBAL級(jí)別上任何鎖。同時(shí)會(huì)將全局表緩存版本推進(jìn)然后釋放掉沒有使用的table 緩存,但是在第四步中會(huì)發(fā)現(xiàn)baguait1的表緩存正在被占用,因此出現(xiàn)了等待,等待狀態(tài)為’Waiting for table flush’。

步驟3 我們KILL掉了FTWRL會(huì)話,這種情況下雖然GLOBAL 級(jí)別的S鎖會(huì)釋放,但是全局表緩存版本已經(jīng)推進(jìn)了,同時(shí)沒有使用的table 緩存已經(jīng)釋放掉了。

步驟4 再次執(zhí)行一個(gè)baguait1表上的select 查詢操作,這個(gè)時(shí)候在打開表的時(shí)候會(huì)去判斷是否table緩存的版本和全局表緩存版本匹配如果不匹配進(jìn)入等待,等待為‘Waiting for table flush’,下面是這個(gè)判斷:

if (share->has_old_version())
    {
      /*
        We already have an MDL lock. But we have encountered an old
        version of table in the table definition cache which is possible
        when someone changes the table version directly in the cache
        without acquiring a metadata lock (e.g. this can happen during
        "rolling" FLUSH TABLE(S)).
        Release our reference to share, wait until old version of
        share goes away and then try to get new version of table share.
      */
      release_table_share(share);
     ...
      wait_result= tdc_wait_for_old_version(thd, table_list->db,
                                            table_list->table_name,
                                            ot_ctx->get_timeout(),
                                            deadlock_weight);

整個(gè)等待操作和FTWRL一樣,會(huì)等待占用者釋放table緩存后才會(huì)醒來繼續(xù)。

因此后續(xù)本表的所有select/DML/DDL都會(huì)堵塞,代價(jià)極高,即便KILL掉FTWRL會(huì)話也無用。

六、FTWRL堵塞和被堵塞的簡(jiǎn)單總結(jié)

(1)被什么堵塞
  • 長(zhǎng)時(shí)間的DDL\DML\FOR UPDATE堵塞FTWRL,因?yàn)镕TWRL需要獲取 GLOBAL的S鎖,而這些語句都會(huì)對(duì)GLOBAL持有IX(MDL_INTENTION_EXCLUSIVE)鎖,根據(jù)兼容矩陣不兼容。等待為:Waiting for global read lock 。本文的案例1就是這種情況。

  • 長(zhǎng)時(shí)間的select堵塞FTWRL, 因?yàn)镕TWRL會(huì)釋放所有空閑的table緩存,如果有占用者占用某些table緩存,則會(huì)等待占用者自己釋放這些table緩存。等待為:Waiting for table flush 。本文的案例2就是這種情況,會(huì)堵塞隨后關(guān)于本表的任何語句,即便KILL FTWRL會(huì)話也不行,除非KILL掉長(zhǎng)時(shí)間的select操作才行。實(shí)際上flush table也會(huì)存在這種堵塞情況。

  • 長(zhǎng)時(shí)間的commit(如大事務(wù)提交)也會(huì)堵塞FTWRL,因?yàn)镕TWRL需要獲取COMMIT的S鎖,而commit語句會(huì)對(duì)commit持有IX(MDL_INTENTION_EXCLUSIVE)鎖,根據(jù)兼容矩陣不兼容。

(2)堵塞什么
  • FTWRL會(huì)堵塞DDL\DML\FOR UPDATE操作,堵塞點(diǎn)為 GLOBAL級(jí)別 的S鎖,等待為:Waiting for global read lock 。

  • FTWRL會(huì)堵塞commit操作,堵塞點(diǎn)為COMMIT的S鎖,等待為Waiting for commit lock 。

  • FTWRL不會(huì)堵塞select操作,因?yàn)閟elect不會(huì)在GLOBAL級(jí)別上鎖。

最后提醒一下很多備份工具都要執(zhí)行FTWRL操作,一定要注意它的堵塞場(chǎng)景和特殊場(chǎng)景。


備注棧幀和斷點(diǎn):

(1)使用的斷點(diǎn)

  • MDL_context::acquire_lock 獲取DML LOCK

  • open_table_from_share 獲取table cache instance

  • alloc_table_share 分配table define(share)

  • get_table_share 獲取table define(share)

  • close_cached_tables flush table關(guān)閉全部table cache instance 和table define

  • reload_acl_and_cache flush with read lock 進(jìn)行MDL LOCK加鎖為GLOBAL TYPE:S ,同時(shí)調(diào)用close_cached_tables 同時(shí)獲取COMMIT級(jí)別 TYPE S

  • MDL_wait::set_status 喚醒操作

  • close_thread_table 占用者判斷釋放

  • my_hash_delete hash刪除操作,從table cache instance 和table define中釋放table緩存都是需要調(diào)用這個(gè)刪除操作的。

(2)FTWRL堵塞棧幀由于select堵塞棧幀:

(gdb) bt
#0  0x00007ffff7bd3a5e in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x000000000192027b in native_cond_timedwait (cond=0x7ffedc007c78, mutex=0x7ffedc007c30, abstime=0x7fffec5bbb90)
    at /mysqldata/percona-server-locks-detail-5.7.22/include/thr_cond.h:129
#2  0x00000000019205ea in safe_cond_timedwait (cond=0x7ffedc007c78, mp=0x7ffedc007c08, abstime=0x7fffec5bbb90, 
    file=0x204cdd0 "/mysqldata/percona-server-locks-detail-5.7.22/sql/mdl.cc", line=1899) at /mysqldata/percona-server-locks-detail-5.7.22/mysys/thr_cond.c:88
#3  0x00000000014b9f21 in my_cond_timedwait (cond=0x7ffedc007c78, mp=0x7ffedc007c08, abstime=0x7fffec5bbb90, 
    file=0x204cdd0 "/mysqldata/percona-server-locks-detail-5.7.22/sql/mdl.cc", line=1899) at /mysqldata/percona-server-locks-detail-5.7.22/include/thr_cond.h:180
#4  0x00000000014ba484 in inline_mysql_cond_timedwait (that=0x7ffedc007c78, mutex=0x7ffedc007c08, abstime=0x7fffec5bbb90, 
    src_file=0x204cdd0 "/mysqldata/percona-server-locks-detail-5.7.22/sql/mdl.cc", src_line=1899)
    at /mysqldata/percona-server-locks-detail-5.7.22/include/mysql/psi/mysql_thread.h:1229
#5  0x00000000014bb702 in MDL_wait::timed_wait (this=0x7ffedc007c08, owner=0x7ffedc007b70, abs_timeout=0x7fffec5bbb90, set_status_on_timeout=true, 
    wait_state_name=0x2d897b0) at /mysqldata/percona-server-locks-detail-5.7.22/sql/mdl.cc:1899
#6  0x00000000016cdb30 in TABLE_SHARE::wait_for_old_version (this=0x7ffee0a4fc30, thd=0x7ffedc007b70, abstime=0x7fffec5bbb90, deadlock_weight=100)
    at /mysqldata/percona-server-locks-detail-5.7.22/sql/table.cc:4717
#7  0x000000000153829b in close_cached_tables (thd=0x7ffedc007b70, tables=0x0, wait_for_refresh=true, timeout=31536000)
    at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_base.cc:1291
#8  0x00000000016123ec in reload_acl_and_cache (thd=0x7ffedc007b70, options=16388, tables=0x0, write_to_binlog=0x7fffec5bc9dc)
    at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_reload.cc:224
#9  0x00000000015cee9c in mysql_execute_command (thd=0x7ffedc007b70, first_level=true) at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:4433
#10 0x00000000015d2fde in mysql_parse (thd=0x7ffedc007b70, parser_state=0x7fffec5bd600) at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:5901
#11 0x00000000015c6b72 in dispatch_command (thd=0x7ffedc007b70, com_data=0x7fffec5bdd70, command=COM_QUERY)
    at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:1490

(3)殺點(diǎn)FTWRL會(huì)話后其他select操作等待棧幀:

#0  MDL_wait::timed_wait (this=0x7ffee8008298, owner=0x7ffee8008200, abs_timeout=0x7fffec58a600, set_status_on_timeout=true, wait_state_name=0x2d897b0)
    at /mysqldata/percona-server-locks-detail-5.7.22/sql/mdl.cc:1888
#1  0x00000000016cdb30 in TABLE_SHARE::wait_for_old_version (this=0x7ffee0011620, thd=0x7ffee8008200, abstime=0x7fffec58a600, deadlock_weight=0)
    at /mysqldata/percona-server-locks-detail-5.7.22/sql/table.cc:4717
#2  0x000000000153b6ba in tdc_wait_for_old_version (thd=0x7ffee8008200, db=0x7ffee80014a0 "testmts", table_name=0x7ffee80014a8 "tii", wait_timeout=31536000, 
    deadlock_weight=0) at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_base.cc:2957
#3  0x000000000153ca97 in open_table (thd=0x7ffee8008200, table_list=0x7ffee8001708, ot_ctx=0x7fffec58aab0)
    at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_base.cc:3548
#4  0x000000000153f904 in open_and_process_table (thd=0x7ffee8008200, lex=0x7ffee800a830, tables=0x7ffee8001708, counter=0x7ffee800a8f0, flags=0, 
    prelocking_strategy=0x7fffec58abe0, has_prelocking_list=false, ot_ctx=0x7fffec58aab0) at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_base.cc:5213
#5  0x0000000001540a58 in open_tables (thd=0x7ffee8008200, start=0x7fffec58aba0, counter=0x7ffee800a8f0, flags=0, prelocking_strategy=0x7fffec58abe0)
    at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_base.cc:5831
#6  0x0000000001541e93 in open_tables_for_query (thd=0x7ffee8008200, tables=0x7ffee8001708, flags=0)
    at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_base.cc:6606
#7  0x00000000015d1dca in execute_sqlcom_select (thd=0x7ffee8008200, all_tables=0x7ffee8001708) at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:5416
#8  0x00000000015ca380 in mysql_execute_command (thd=0x7ffee8008200, first_level=true) at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:2939
#9  0x00000000015d2fde in mysql_parse (thd=0x7ffee8008200, parser_state=0x7fffec58c600) at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:5901
#10 0x00000000015c6b72 in dispatch_command (thd=0x7ffee8008200, com_data=0x7fffec58cd70, command=COM_QUERY)
    at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:1490

(4)占用者釋放喚醒FTWRL棧幀:

Breakpoint 3, MDL_wait::set_status (this=0x7ffedc000c78, status_arg=MDL_wait::GRANTED) at /mysqldata/percona-server-locks-detail-5.7.22/sql/mdl.cc:1832
1832      bool was_occupied= TRUE;
(gdb) bt
#0  MDL_wait::set_status (this=0x7ffedc000c78, status_arg=MDL_wait::GRANTED) at /mysqldata/percona-server-locks-detail-5.7.22/sql/mdl.cc:1832
#1  0x00000000016c2483 in free_table_share (share=0x7ffee0011620) at /mysqldata/percona-server-locks-detail-5.7.22/sql/table.cc:607
#2  0x0000000001536a22 in table_def_free_entry (share=0x7ffee0011620) at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_base.cc:524
#3  0x00000000018fd7aa in my_hash_delete (hash=0x2e4cfe0, record=0x7ffee0011620 "\002") at /mysqldata/percona-server-locks-detail-5.7.22/mysys/hash.c:625
#4  0x0000000001537673 in release_table_share (share=0x7ffee0011620) at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_base.cc:949
#5  0x00000000016cad10 in closefrm (table=0x7ffee000f280, free_share=true) at /mysqldata/percona-server-locks-detail-5.7.22/sql/table.cc:3597
#6  0x0000000001537d0e in intern_close_table (table=0x7ffee000f280) at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_base.cc:1109
#7  0x0000000001539054 in close_thread_table (thd=0x7ffee0000c00, table_ptr=0x7ffee0000c68) at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_base.cc:1780
#8  0x00000000015385fe in close_open_tables (thd=0x7ffee0000c00) at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_base.cc:1443
#9  0x0000000001538d4a in close_thread_tables (thd=0x7ffee0000c00) at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_base.cc:1722
#10 0x00000000015d19bc in mysql_execute_command (thd=0x7ffee0000c00, first_level=true) at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:5307
#11 0x00000000015d2fde in mysql_parse (thd=0x7ffee0000c00, parser_state=0x7fffec5ee600) at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:5901
#12 0x00000000015c6b72 in dispatch_command (thd=0x7ffee0000c00, com_data=0x7fffec5eed70, command=COM_QUERY)
    at /mysqldata/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:1490

“分析MySQL中FTWRL一個(gè)奇怪的堵塞現(xiàn)象”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

本文標(biāo)題:分析MySQL中FTWRL一個(gè)奇怪的堵塞現(xiàn)象
文章源于:http://muchs.cn/article38/iidspp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司搜索引擎優(yōu)化、網(wǎng)站內(nèi)鏈、電子商務(wù)全網(wǎng)營(yíng)銷推廣、ChatGPT

廣告

聲明:本網(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)

手機(jī)網(wǎng)站建設(shè)