MySQL 在併發場景下的問題及解決思路

2021-09-13 19:52:31 字數 1507 閱讀 9790

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字段長度,語句被阻塞。按照慣例,我們檢查一下當前程序:

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

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

2、檢視官方文件,確認要做的表修改可以和dml併發,不會阻塞線上業務;

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

高併發場景下的快取常見的問題

當資料時效性要求很高時,需要保證快取中的資料與資料庫中的保持一致,而且需要保證快取節點和副本中的資料也保持一致,不能出現差異現象。這就比較依賴快取的過期和更新策略。一般會在資料發生更改的時,主動更新快取中的資料或者移除對應的快取。快取過期後將嘗試從後端資料庫獲取資料,這是乙個看似合理的流程。但是,在...

高併發場景下快取的常見問題

1快取一致性問題 當資料時效性要求很高時,需要保證快取中的資料與資料庫中的保持一致,而且需要保證快取節點和副本中的資料也保持一致,不能出現差異現象。這就比較依賴快取的過期和更新策略。一般會在資料發生更改的時,主動更新快取中的資料或者移除對應的快取。2快取併發問題 快取過期後將嘗試從後端資料庫獲取資料...

kafka在高併發場景下的解決方案

在我們現在開發的專案中,經常會用到kafka訊息中介軟體。一般情況下,單執行緒 單分割槽 的配置已經可以滿足需求,但是在某些大資料和資料併發量要求較高的應用場景下經常會遇到訊息來不及處理,出現訊息積壓的情況。因此,該文章主要針對這種應用場景提供了乙個多執行緒消費的解決方案 自己在平時使用kafka訊...