婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 分析MySQL并發下的問題及解決方法

分析MySQL并發下的問題及解決方法

熱門標簽:中科嘉智人工智能電銷機器人 上海智能外呼系統需要多少錢 銀川電銷外呼系統定制 哈爾濱crm外呼系統價格 電銷機器人好品牌門薩維l 西安400電話在哪里辦理 凱立德科技館地圖標注 甘孜電話機器人廠家 做地圖標注都需要什么工具

1、背景

對于數據庫系統來說在多用戶并發條件下提高并發性的同時又要保證數據的一致性一直是數據庫系統追求的目標,既要滿足大量并發訪問的需求又必須保證在此條件下數據的安全,為了滿足這一目標大多數數據庫通過鎖和事務機制來實現,MySQL數據庫也不例外。盡管如此我們仍然會在業務開發過程中遇到各種各樣的疑難問題,本文將以案例的方式演示常見的并發問題并分析解決思路。

2、表鎖導致的慢查詢的問題

首先我們看一個簡單案例,根據ID查詢一條用戶信息:

mysql> select * from user where id=6;

這個表的記錄總數為3條,但卻執行了13秒。

出現這種問題我們首先想到的是看看當前MySQL進程狀態:

從進程上可以看出select語句是在等待一個表鎖,那么這個表鎖又是什么查詢產生的呢?這個結果中并沒有顯示直接的關聯關系,但我們可以推測多半是那條update語句產生的(因為進程中沒有其他可疑的SQL),為了印證我們的猜測,先檢查一下user表結構:

果然user表使用了MyISAM存儲引擎,MyISAM在執行操作前會產生表鎖,操作完成再自動解鎖。如果操作是寫操作,則表鎖類型為寫鎖,如果操作是讀操作則表鎖類型為讀鎖。正如和你理解的一樣寫鎖將阻塞其他操作(包括讀和寫),這使得所有操作變為串行;而讀鎖情況下讀-讀操作可以并行,但讀-寫操作仍然是串行。以下示例演示了顯式指定了表鎖(讀鎖),讀-讀并行,讀-寫串行的情況。

顯式開啟/關閉表鎖,使用lock table user read/write; unlock tables;

session1:

session2:

可以看到會話1啟用表鎖(讀鎖)執行讀操作,這時會話2可以并行執行讀操作,但寫操作被阻塞。接著看:

session1:

session2:

當session1執行解鎖后,seesion2則立刻開始執行寫操作,即讀-寫串行。

總結:

到此我們把問題的原因基本分析清楚,總結一下——MyISAM存儲引擎執行操作時會產生表鎖,將影響其他用戶對該表的操作,如果表鎖是寫鎖,則會導致其他用戶操作串行,如果是讀鎖則其他用戶的讀操作可以并行。所以有時我們遇到某個簡單的查詢花了很長時間,看看是不是這種情況。

解決辦法:

1)、盡量不用MyISAM存儲引擎,在MySQL8.0版本中已經去掉了所有的MyISAM存儲引擎的表,推薦使用InnoDB存儲引擎。

2)、如果一定要用MyISAM存儲引擎,減少寫操作的時間;

3、線上修改表結構有哪些風險?

如果有一天業務系統需要增大一個字段長度,能否在線上直接修改呢?在回答這個問題前,我們先來看一個案例:

以上語句嘗試修改user表的name字段長度,語句被阻塞。按照慣例,我們檢查一下當前進程:

從進程可以看出alter語句在等待一個元數據鎖,而這個元數據鎖很可能是上面這條select語句引起的,事實正是如此。在執行DML(select、update、delete、insert)操作時,會對表增加一個元數據鎖,這個元數據鎖是為了保證在查詢期間表結構不會被修改,因此上面的alter語句會被阻塞。那么如果執行順序相反,先執行alter語句,再執行DML語句呢?DML語句會被阻塞嗎?例如我正在線上環境修改表結構,線上的DML語句會被阻塞嗎?答案是:不確定。

在MySQL5.6開始提供了online ddl功能,允許一些DDL語句和DML語句并發,在當前5.7版本對online ddl又有了增強,這使得大部分DDL操作可以在線進行。詳見:https://dev.mysql.com/doc/refman/5.7/en/innodb-create-index-overview.html

所以對于特定場景執行DDL過程中,DML是否會被阻塞需要視場景而定。

總結:通過這個例子我們對元數據鎖和online ddl有了一個基本的認識,如果我們在業務開發過程中有在線修改表結構的需求,可以參考以下方案:

1、盡量在業務量小的時間段進行;

2、查看官方文檔,確認要做的表修改可以和DML并發,不會阻塞線上業務;

3、推薦使用percona公司的pt-online-schema-change工具,該工具被官方的online ddl更為強大,它的基本原理是:通過insert… select…語句進行一次全量拷貝,通過觸發器記錄表結構變更過程中產生的增量,從而達到表結構變更的目的。

例如要對A表進行變更,主要步驟為:

創建目的表結構的空表,A_new;
在A表上創建觸發器,包括增、刪、改觸發器;
通過insert…select…limit N 語句分片拷貝數據到目的表
Copy完成后,將A_new表rename到A表。

4、一個死鎖問題的分析

在線上環境下死鎖的問題偶有發生,死鎖是因為兩個或多個事務相互等待對方釋放鎖,導致事務永遠無法終止的情況。為了分析問題,我們下面將模擬一個簡單死鎖的情況,然后從中總結出一些分析思路。

演示環境:MySQL5.7.20 事務隔離級別:RR

表user:

CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(300) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8

下面演示事務1、事務2工作的情況:

事務1

事務2

事務監控

T1

begin;

Query OK, 0 rows affected (0.00 sec)

begin;

Query OK, 0 rows affected (0.00 sec)

T2

select * from user where id=3 for update;

+----+------+------+
| id | name | age |
+----+------+------+
| 3 | sun | 20 |
+----+------+------+
1 row in set (0.00 sec)

select * from user where id=4 for update;

+----+------+------+
| id | name | age |
+----+------+------+
| 4 | zhou | 21 |
+----+------+------+
1 row in set (0.00 sec)

select * from information_schema.INNODB_TRX;

通過查詢元數據庫innodb事務表,監控到當前運行事務數為2,即事務1、事務2。

T3

update user set name='haha' where id=4;

因為id=4的記錄已被事務2加上行鎖,該語句將阻塞

監控到當前運行事務數為2。 T4 阻塞狀態

update user set name='hehe' where id=3;

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

id=3的記錄已被事務1加上行鎖,而本事務持有id=4的記錄行鎖,此時InnoDB存儲引擎檢查出死鎖,本事務被回滾。

事務2被回滾,事務1仍在運行中,監控當前運行事務數為1。 T5

Query OK, 1 row affected (20.91 sec)
Rows matched: 1 Changed: 1 Warnings: 0

由于事務2被回滾,原來阻塞的update語句被繼續執行。

監控當前運行事務數為1。 T6

commit;

Query OK, 0 rows affected (0.00 sec)

事務1已提交、事務2已回滾,監控當前運行事務數為0。

這是一個簡單的死鎖場景,事務1、事務2彼此等待對方釋放鎖,InnoDB存儲引擎檢測到死鎖發生,讓事務2回滾,這使得事務1不再等待事務B的鎖,從而能夠繼續執行。那么InnoDB存儲引擎是如何檢測到死鎖的呢?為了弄明白這個問題,我們先檢查此時InnoDB的狀態:

show engine innodb status\G

------------------------
LATEST DETECTED DEADLOCK
------------------------
2018-01-14 12:17:13 0x70000f1cc000
*** (1) TRANSACTION:
TRANSACTION 5120, ACTIVE 17 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s)
MySQL thread id 10, OS thread handle 123145556967424, query id 2764 localhost root updating
update user set name='haha' where id=4
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 94 page no 3 n bits 80 index PRIMARY of table `test`.`user` trx id 5120 lock_mode X locks rec but not gap waiting
Record lock, heap no 5 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
0: len 4; hex 80000004; asc ;;
1: len 6; hex 0000000013fa; asc ;;
2: len 7; hex 520000060129a6; asc R ) ;;
3: len 4; hex 68616861; asc haha;;
4: len 4; hex 80000015; asc ;;

*** (2) TRANSACTION:
TRANSACTION 5121, ACTIVE 12 sec starting index read
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 2 row lock(s)
MySQL thread id 11, OS thread handle 123145555853312, query id 2765 localhost root updating
update user set name='hehe' where id=3
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 94 page no 3 n bits 80 index PRIMARY of table `test`.`user` trx id 5121 lock_mode X locks rec but not gap
Record lock, heap no 5 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
0: len 4; hex 80000004; asc ;;
1: len 6; hex 0000000013fa; asc ;;
2: len 7; hex 520000060129a6; asc R ) ;;
3: len 4; hex 68616861; asc haha;;
4: len 4; hex 80000015; asc ;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 94 page no 3 n bits 80 index PRIMARY of table `test`.`user` trx id 5121 lock_mode X locks rec but not gap waiting
Record lock, heap no 7 PHYSICAL RECORD: n_fields 5; compact format; info bits 0
0: len 4; hex 80000003; asc ;;
1: len 6; hex 0000000013fe; asc ;;
2: len 7; hex 5500000156012f; asc U V /;;
3: len 4; hex 68656865; asc hehe;;
4: len 4; hex 80000014; asc ;;

*** WE ROLL BACK TRANSACTION (2)

InnoDB狀態有很多指標,這里我們截取死鎖相關的信息,可以看出InnoDB可以輸出最近出現的死鎖信息,其實很多死鎖監控工具也是基于此功能開發的。

在死鎖信息中,顯示了兩個事務等待鎖的相關信息(藍色代表事務1、綠色代表事務2),重點關注:WAITING FOR THIS LOCK TO BE GRANTED和HOLDS THE LOCK(S)。

WAITING FOR THIS LOCK TO BE GRANTED表示當前事務正在等待的鎖信息,從輸出結果看出事務1正在等待heap no為5的行鎖,事務2正在等待 heap no為7的行鎖;

HOLDS THE LOCK(S):表示當前事務持有的鎖信息,從輸出結果看出事務2持有heap no為5行鎖。

從輸出結果看出,最后InnoDB回滾了事務2。

那么InnoDB是如何檢查出死鎖的呢?

我們想到最簡單方法是假如一個事務正在等待一個鎖,如果等待時間超過了設定的閾值,那么該事務操作失敗,這就避免了多個事務彼此長等待的情況。參數innodb_lock_wait_timeout正是用來設置這個鎖等待時間的。

如果按照這個方法,解決死鎖是需要時間的(即等待超過innodb_lock_wait_timeout設定的閾值),這種方法稍顯被動而且影響系統性能,InnoDB存儲引擎提供一個更好的算法來解決死鎖問題,wait-for graph算法。簡單的說,當出現多個事務開始彼此等待時,啟用wait-for graph算法,該算法判定為死鎖后立即回滾其中一個事務,死鎖被解除。該方法的好處是:檢查更為主動,等待時間短。

下面是wait-for graph算法的基本原理:

為了便于理解,我們把死鎖看做4輛車彼此阻塞的場景:

4輛車看做4個事務,彼此等待對方的鎖,造成死鎖。wait-for graph算法原理是把事務作為節點,事務之間的鎖等待關系,用有向邊表示,例如事務A等待事務B的鎖,就從節點A畫一條有向邊到節點B,這樣如果A、B、C、D構成的有向圖,形成了環,則判斷為死鎖。這就是wait-for graph算法的基本原理。

總結:

1、如果我們業務開發中出現死鎖如何檢查出?剛才已經介紹了通過監控InnoDB狀態可以得出,你可以做一個小工具把死鎖的記錄收集起來,便于事后查看。

2、如果出現死鎖,業務系統應該如何應對?從上文我們可以看到當InnoDB檢查出死鎖后,對客戶端報出一個Deadlock found when trying to get lock; try restarting transaction信息,并且回滾該事務,應用端需要針對該信息,做事務重啟的工作,并保存現場日志事后做進一步分析,避免下次死鎖的產生。

5、鎖等待問題的分析

在業務開發中死鎖的出現概率較小,但鎖等待出現的概率較大,鎖等待是因為一個事務長時間占用鎖資源,而其他事務一直等待前個事務釋放鎖。

事務1

事務2

事務監控

T1

begin;

Query OK, 0 rows affected (0.00 sec)

begin;

Query OK, 0 rows affected (0.00 sec)

T2

select * from user where id=3 for update;

+----+------+------+
| id | name | age |
+----+------+------+
| 3 | sun | 20 |
+----+------+------+
1 row in set (0.00 sec)

其他查詢操作

select * from information_schema.INNODB_TRX;

通過查詢元數據庫innodb事務表,監控到當前運行事務數為2,即事務1、事務2。

T3 其他查詢操作

update user set name='hehe' where id=3;

因為id=3的記錄被事務1加上行鎖,所以該語句將阻塞(即鎖等待)

監控到當前運行事務數為2。 T4 其他查詢操作

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

鎖等待時間超過閾值,操作失敗。注意:此時事務2并沒有回滾。

監控到當前運行事務數為2。 T5 commit; 事務1已提交,事務2未提交,監控到當前運行事務數為1。

從上述可知事務1長時間持有id=3的行鎖,事務2產生鎖等待,等待時間超過innodb_lock_wait_timeout后操作中斷,但事務并沒有回滾。如果我們業務開發中遇到鎖等待,不僅會影響性能,還會給你的業務流程提出挑戰,因為你的業務端需要對鎖等待的情況做適應的邏輯處理,是重試操作還是回滾事務。

在MySQL元數據表中有對事務、鎖等待的信息進行收集,例如information_schema數據庫下的INNODB_LOCKS、INNODB_TRX、INNODB_LOCK_WAITS,你可以通過這些表觀察你的業務系統鎖等待的情況。你也可以用一下語句方便的查詢事務和鎖等待的關聯關系:

SELECT r.trx_id waiting_trx_id, r.trx_mysql_thread_id waiting_thread, r.trx_query wating_query, b.trx_id blocking_trx_id, b.trx_mysql_thread_id blocking_thread, b.trx_query blocking_query FROM information_schema.innodb_lock_waits w INNER JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_trx_id INNER JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_trx_id;

結果:

waiting_trx_id: 5132
waiting_thread: 11
wating_query: update user set name='hehe' where id=3
blocking_trx_id: 5133
blocking_thread: 10
blocking_query: NULL

總結:

1、請對你的業務系統做鎖等待的監控,這有助于你了解當前數據庫鎖情況,以及為你優化業務程序提供幫助;

2、業務系統中應該對鎖等待超時的情況做合適的邏輯判斷。

6、小結

本文通過幾個簡單的示例介紹了我們常用的幾種MySQL并發問題,并嘗試得出針對這些問題我們排查的思路。文中涉及事務、表鎖、元數據鎖、行鎖,但引起并發問題的遠遠不止這些,例如還有事務隔離級別、GAP鎖等。真實的并發問題可能多而復雜,但排查思路和方法卻是可以復用,在本文中我們使用了show processlist;show engine innodb status;以及查詢元數據表的方法來排查發現問題,如果問題涉及到了復制,還需要借助master/slave監控來協助。

您可能感興趣的文章:
  • MySQL并發更新數據時的處理方法
  • Tomcat+Mysql高并發配置優化講解
  • PHP利用Mysql鎖解決高并發的方法
  • PHP+MySQL高并發加鎖事務處理問題解決方法
  • Yii+MYSQL鎖表防止并發情況下重復數據的方法
  • MySQL中實現高性能高并發計數器方案(例如文章點擊數)
  • MySQL中SELECT+UPDATE處理并發更新問題解決方案分享
  • 利用mysql事務特性實現并發安全的自增ID示例
  • 深入mysql并發插入優化詳解
  • Mysql事務并發問題解決方案

標簽:山南 平頂山 四川 濮陽 那曲 安徽 浙江 安康

巨人網絡通訊聲明:本文標題《分析MySQL并發下的問題及解決方法》,本文關鍵詞  分析,MySQL,并發,下,的,問題,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《分析MySQL并發下的問題及解決方法》相關的同類信息!
  • 本頁收集關于分析MySQL并發下的問題及解決方法的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    欧美二区乱c少妇| 欧美亚洲免费在线一区| 色综合av在线| 日韩免费电影网站| 亚洲综合视频网| 成人综合激情网| 欧美一级夜夜爽| 亚洲综合色在线| 99精品热视频| 欧美激情在线观看视频免费| 免费成人性网站| 在线看国产一区| 国产精品久久久爽爽爽麻豆色哟哟 | 成人夜色视频网站在线观看| 日韩欧美激情一区| 亚洲国产精品久久一线不卡| 99精品国产99久久久久久白柏| 精品av综合导航| 久久91精品久久久久久秒播| 欧美老肥妇做.爰bbww| 亚洲综合一区二区精品导航| caoporm超碰国产精品| 中文一区二区在线观看| 粉嫩一区二区三区性色av| 精品欧美乱码久久久久久1区2区| 日韩综合小视频| 日韩亚洲国产中文字幕欧美| 欧美a级一区二区| 欧美一区日本一区韩国一区| 日韩在线a电影| 日韩欧美一二区| 久草精品在线观看| 欧美成人三级在线| 国产一区久久久| 久久精品人人做人人综合 | 国产亚洲va综合人人澡精品| 精品在线播放免费| 国产日韩在线不卡| 福利一区二区在线| 不卡免费追剧大全电视剧网站| 成人av网站在线观看免费| 国产精品久久夜| caoporm超碰国产精品| 一区二区三区国产精品| 激情综合网av| 欧美最猛黑人xxxxx猛交| 亚洲在线成人精品| 日韩欧美亚洲国产另类| 久久精品国产色蜜蜜麻豆| 久久日一线二线三线suv| 成人一道本在线| 亚洲一区二区三区爽爽爽爽爽| 91精品婷婷国产综合久久| 国产毛片精品视频| 亚洲与欧洲av电影| 精品久久久久久无| 99久久久久免费精品国产| 日韩高清电影一区| 中文字幕精品一区二区三区精品| 日本大香伊一区二区三区| 日韩欧美一区二区视频| 欧美人狂配大交3d怪物一区| 日韩午夜在线观看| 国产成人精品亚洲午夜麻豆| 一区二区三区中文字幕精品精品 | 亚洲精品一区二区三区99| a级精品国产片在线观看| 天天av天天翘天天综合网| 亚洲国产高清在线观看视频| 色婷婷av久久久久久久| 中国av一区二区三区| 国产又黄又大久久| 亚洲综合另类小说| 久久免费国产精品| 欧美日韩二区三区| 成人免费看片app下载| 日欧美一区二区| 亚洲日本一区二区三区| 精品播放一区二区| 7777精品伊人久久久大香线蕉的 | 日韩欧美国产小视频| 成人黄色a**站在线观看| 蜜臀精品一区二区三区在线观看| 亚洲日韩欧美一区二区在线| 久久精品欧美日韩精品| 8x8x8国产精品| 欧美亚洲国产一区在线观看网站| 国产成人精品免费一区二区| 强制捆绑调教一区二区| 亚洲高清中文字幕| 欧美视频中文字幕| 成人av电影在线| 中文字幕一区日韩精品欧美| 久久亚洲春色中文字幕久久久| 88在线观看91蜜桃国自产| 欧美网站大全在线观看| 色偷偷成人一区二区三区91 | 洋洋av久久久久久久一区| 国产精品免费aⅴ片在线观看| 从欧美一区二区三区| 韩国女主播一区| 日本一区二区综合亚洲| 日韩精品一区二区三区四区视频 | 久久99精品久久久久久动态图 | 日韩va欧美va亚洲va久久| 亚洲一区二区三区国产| 伊人色综合久久天天| 欧美日韩午夜在线| 欧美视频日韩视频在线观看| 久久电影网站中文字幕| 精品在线免费视频| 国产福利一区二区三区视频在线 | 中文字幕制服丝袜成人av | 久久久一区二区三区| 精品久久久久久久一区二区蜜臀| 精品国产电影一区二区| 亚洲精品一区二区三区99| 99视频超级精品| 一本大道av一区二区在线播放| 五月天亚洲婷婷| 奇米影视7777精品一区二区| 青娱乐精品视频| 国产一区二区三区免费| 99久久婷婷国产综合精品电影| 一本大道久久a久久综合婷婷| 欧美影院一区二区三区| 日韩一区二区在线观看视频| 精品美女在线播放| 国产精品国产三级国产aⅴ入口| **欧美大码日韩| 五月天中文字幕一区二区| 麻豆精品精品国产自在97香蕉| 国产美女视频一区| 91污在线观看| 在线成人高清不卡| 精品国产3级a| 亚洲素人一区二区| 丝袜脚交一区二区| 国产精品996| 色狠狠一区二区三区香蕉| 69久久夜色精品国产69蝌蚪网| 久久一区二区视频| 一区二区三区欧美日韩| 久久99精品久久只有精品| 91在线观看下载| 91精品国产色综合久久ai换脸 | 91玉足脚交白嫩脚丫在线播放| 欧美性大战久久久| 精品国产一区二区三区忘忧草| 成人免费一区二区三区视频| 免费成人av资源网| 色中色一区二区| 精品国偷自产国产一区| 亚洲一区二区在线观看视频| 国产一区视频在线看| 欧美日韩色综合| 国产精品久久久久久久久快鸭| 日韩vs国产vs欧美| 91福利视频久久久久| 国产色产综合色产在线视频| 亚洲国产精品一区二区尤物区| 成人午夜av在线| 精品日韩一区二区三区| 亚洲国产aⅴ天堂久久| 97国产精品videossex| 久久女同性恋中文字幕| 欧美刺激午夜性久久久久久久| 欧美日韩国产成人在线免费| 国产精品国产三级国产aⅴ无密码 国产精品国产三级国产aⅴ原创 | 717成人午夜免费福利电影| 国产精品入口麻豆九色| 韩国v欧美v日本v亚洲v| 9191成人精品久久| 亚洲永久免费视频| 色综合久久中文字幕综合网| 久久久久国产精品人| 免费成人在线播放| 欧美精品成人一区二区三区四区| 7777精品久久久大香线蕉| 亚洲精品视频自拍| 亚洲一区二区三区自拍| 91一区二区在线| 国产精品视频麻豆| 国产很黄免费观看久久| 久久久另类综合| 国产精品一区二区在线观看不卡| 日韩免费在线观看| 免费成人av在线播放| 日韩欧美一二区| 国产在线乱码一区二区三区| 日韩欧美中文字幕一区| 日韩综合小视频| 欧美成人一区二区三区| 国产一区二区在线看| 久久久久99精品国产片| 国产成人亚洲精品青草天美| 99久久婷婷国产综合精品| 亚洲日本va午夜在线影院| 99re这里只有精品首页| 亚洲综合视频在线观看|