久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Innodb中為什么lock in share mode在show engine看不到行鎖信息

153次閱讀
沒有評論

共計 7279 個字符,預計需要花費 19 分鐘才能閱讀完成。

這篇文章主要介紹“Innodb 中為什么 lock in share mode 在 show engine 看不到行鎖信息”,在日常操作中,相信很多人在 Innodb 中為什么 lock in share mode 在 show engine 看不到行鎖信息問題上存在疑惑,丸趣 TV 小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Innodb 中為什么 lock in share mode 在 show engine 看不到行鎖信息”的疑惑有所幫助!接下來,請跟著丸趣 TV 小編一起來學習吧!

一、問題提出

不知道有沒有朋友和我一樣用 lock in share mode 做加鎖實驗,但是卻在 show engine innodb status 中看不到加鎖信息,今天剛好有朋友在問 @在樹枝上吹風,今天就做了一下簡單的 debug,因為我也挺納悶的。(我喜歡多問一個為什么也挺累的)
問題如下:
首先我開啟了我的打印行鎖參數,讓加鎖輸出到日志中

mysql  show variables like  %gaopeng% 
+--------------------------------+-------+| Variable_name | Value |
+--------------------------------+-------+
| gaopeng_mdl_detail | OFF || innodb_gaopeng_row_lock_detail | ON |
+--------------------------------+-------+

然后跑如下語句

mysql  show create table t \G
*************************** 1. row *************************** Table: t
Create Table: CREATE TABLE `t` ( `id` int(11) NOT NULL, `c` int(11) DEFAULT NULL, `d` int(11) DEFAULT NULL,
 PRIMARY KEY (`id`),
 KEY `c` (`c`)
) ENGINE=InnoDB DEFAULT CHARSET=utf81 row in set (0.00 sec)
mysql  select * from t;
+----+------+------+| id | c | d |+----+------+------+| 0 | 0 | 0 || 5 | 5 | 5 || 10 | 10 | 10 || 15 | 15 | 15 || 20 | 20 | 20 || 25 | 25 | 25 |+----+------+------+6 rows in set (0.00 sec)
mysql  begin;
Query OK, 0 rows affected (0.01 sec)
mysql  select * from t where id=0 lock in share mode;
+----+------+------+| id | c | d |+----+------+------+| 0 | 0 | 0 |+----+------+------+1 row in set (4.21 sec)

按理說這個時候應該在主鍵 ID= 0 這一行上了 LOCK_S,但是 show engine innodb 卻看不到加鎖信息如下:

------------
TRANSACTIONS
------------
Trx id counter 241482
Purge done for trx s n:o   241482 undo n:o   0 state: running but idle
History list length 182
Total number of lock structs in row lock hash table 1
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 422211785606640, not started
0 lock struct(s), heap size 1160, 0 row lock(s)
---TRANSACTION 422211785605248, not started
0 lock struct(s), heap size 1160, 0 row lock(s)
--------
FILE I/O
--------

根本看不到加鎖信息。但是我的日志中卻有輸出如下:

2019-03-20T14:37:41.980845+08:00 10 [Note] InnoDB: TRX ID:(0) table:test/t index:PRIMARY space_id: 95 page_id:3 heap_no:2 row lock mode:LOCK_S|LOCK_NOT_GAP|
PHYSICAL RECORD: n_fields 5; compact format; info bits 0
 0: len 4; hex 80000000; asc ;;
 1: len 6; hex 00000003676a; asc gj;;
 2: len 7; hex d8000000330110; asc 3 ;;
 3: len 4; hex 80000000; asc ;;
 4: len 4; hex 80000000; asc ;;

因此我基本斷定加鎖肯定是做了的,但是為什么沒有輸出呢?

二、分析

我開始懷疑是否是提前釋放了或者是打印的時候過濾掉了?后來發現都不是。看了到了一個 TRX_ID 為 422211785605248,這是只讀事物的 TRX_ID 的形式,會不是因為應打印的時候只會打印讀寫的事物的鎖結構信息,因為 Innodb 中讀寫事物有一個獨立的鏈表,如果只打印這個鏈表上的信息就會出現這個問題。接著我做了一個事物先做了一個 delete 操作然后做 lock in share mode 語句可以看到 LOCK_S 結構就可以看到了,如下:

mysql  begin;
Query OK, 0 rows affected (2.43 sec)
mysql  delete from t2 limit 1; ## 這個語句我就顯示的開始了一個讀寫事物 Query OK, 1 row affected (3.53 sec)
mysql  select * from t where id=0 lock in share mode; 
+----+------+------+| id | c | d |+----+------+------+| 0 | 0 | 0 |+----+------+------+1 row in set (2.98 sec)
mysql

再來看看

---TRANSACTION 422211785606640, not started0 lock struct(s), heap size 1160, 0 row lock(s)
---TRANSACTION 422211785605248, not started0 lock struct(s), heap size 1160, 0 row lock(s)
---TRANSACTION 241482, ACTIVE 85 sec4 lock struct(s), heap size 1160, 2 row lock(s), undo log entries 1MySQL thread id 10, OS thread handle 140737153423104, query id 391 localhost root
TABLE LOCK table `test`.`t2` trx id 241482 lock mode IX
RECORD LOCKS space id 33 page no 19 n bits 624 index GEN_CLUST_INDEX of table `test`.`t2` trx id 241482 lock_mode X(LOCK_X) locks rec but not gap(LOCK_REC_NOT_GAP)
Record lock, heap no 447 PHYSICAL RECORD: n_fields 4; compact format; info bits 32
 0: len 6; hex 00000000451d; asc E ;; 1: len 6; hex 00000003af4a; asc J;; 2: len 7; hex 3c000000453040; asc   E0@;; 3: len 4; hex 80000001; asc ;;
TABLE LOCK table `test`.`t` trx id 241482 lock mode IS
RECORD LOCKS space id 95 page no 3 n bits 80 index PRIMARY of table `test`.`t` trx id 241482 lock mode S(LOCK_S) locks rec but not gap(LOCK_REC_NOT_GAP)
Record lock, heap no 2 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
 0: len 4; hex 80000000; asc ;; 1: len 6; hex 00000003676a; asc gj;; 2: len 7; hex d8000000330110; asc 3 ;; 3: len 4; hex 80000000; asc ;; 4: len 4; hex 80000000; asc ;;

我們看到了 lock mode S(LOCK_S) locks rec but not gap(LOCK_REC_NOT_GAP) 的信息看來沒有問題,猜測是實驗是一樣的,但是還是要源碼驗證一下。

三、源碼驗證 1、打印函數 lock_print_info_all_transactions

/*********************************************************************//**
Prints info of locks for each transaction. This function assumes that the
caller holds the lock mutex and more importantly it will release the lock
mutex on behalf of the caller. (This should be fixed in the future). */voidlock_print_info_all_transactions(/*=============================*/
 FILE* file) /*!  in/out: file where to print */{ ut_ad(lock_mutex_own()); fprintf(file,  LIST OF TRANSACTIONS FOR EACH SESSION:\n 
 mutex_enter(trx_sys- mutex); /* First print info on non-active transactions */
 /* NOTE: information of auto-commit non-locking read-only
 transactions will be omitted here. The information will be
 available from INFORMATION_SCHEMA.INNODB_TRX. */
 PrintNotStarted print_not_started(file);// 建立一個結構體,目的是做 not start  事物的打印
 ut_list_map(trx_sys- mysql_trx_list, print_not_started); // 這個地方打印出那些事物狀態是 no start 的事物,但是這里存在一個問題,等會看代碼在看。mysql_trx_list 是全事物。 const trx_t* trx;
 TrxListIterator trx_iter; // 這個迭代器是 trx_sys- rw_trx_list  這個鏈表的迭代器
 const trx_t* prev_trx = 0; /* Control whether a block should be fetched from the buffer pool. */
 bool load_block = true; bool monitor = srv_print_innodb_lock_monitor   (srv_show_locks_held != 0); while ((trx = trx_iter.current()) != 0) { // 通過迭代器進行迭代  ,顯然這里不會有只讀事物的信息。 check_trx_state(trx); if (trx != prev_trx) { lock_trx_print_wait_and_mvcc_state(file, trx);
 prev_trx = trx; /* The transaction that read in the page is no
 longer the one that read the page in. We need to
 force a page read. */
 load_block = true;
 } /* If we need to print the locked record contents then we
 need to fetch the containing block from the buffer pool. */
 if (monitor) { /* Print the locks owned by the current transaction. */
 TrxLockIterator  lock_iter = trx_iter.lock_iter(); if (!lock_trx_print_locks( file, trx, lock_iter, load_block)) { /* Resync trx_iter, the trx_sys- mutex and
 the lock mutex were released. A page was
 successfully read in. We need to print its
 contents on the next call to
 lock_trx_print_locks(). On the next call to
 lock_trx_print_locks() we should simply print
 the contents of the page just read in.*/
 load_block = false; continue;
 }
 }
 load_block = true; /* All record lock details were printed without fetching
 a page from disk, or we didn t need to print the detail. */
 trx_iter.next();
 }
 lock_mutex_exit();
 mutex_exit(trx_sys- mutex);
 ut_ad(lock_validate());
}

這個函數是調用的邏輯。

結構體 PrintNotStarted 括號重載

void operator()(const trx_t* trx)
 { ut_ad(trx- in_mysql_trx_list);
 ut_ad(mutex_own( trx_sys- mutex)); /* See state transitions and locking rules in trx0trx.h */
 if (trx_state_eq(trx, TRX_STATE_NOT_STARTED)) {// 這里我們發現只有狀態為 TRX_STATE_NOT_STARTED 才會進行輸出
 fputs(--- , m_file);
 trx_print_latched(m_file, trx, 600);
 }
 }

我們這里可以看到只有狀態為 TRX_STATE_NOT_STARTED 才會輸出為 not start 狀態。

TrxListIterator 迭代器初始化代碼

 TrxListIterator() : m_index()
 { /* We iterate over the RW trx list first. */
 m_trx_list =  trx_sys- rw_trx_list;
 }

我們這里可以看到只有讀寫事物才會進行鎖結構的輸出。

到此,關于“Innodb 中為什么 lock in share mode 在 show engine 看不到行鎖信息”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注丸趣 TV 網站,丸趣 TV 小編會繼續努力為大家帶來更多實用的文章!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-26發表,共計7279字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 朝阳市| 黔西县| 上思县| 荥经县| 太仆寺旗| 临武县| 舟曲县| 陵水| 台山市| 盐城市| 吉木乃县| 三河市| 武定县| 新和县| 合山市| 巨野县| 武邑县| 大邑县| 平谷区| 西昌市| 繁峙县| 闽清县| 华池县| 望江县| 神农架林区| 贺州市| 板桥市| 长顺县| 志丹县| 赞皇县| 吴江市| 中方县| 崇州市| 吴旗县| 韶山市| 应用必备| 时尚| 太仓市| 武胜县| 呼玛县| 都兰县|