1. 程式人生 > 資料庫 >MySQL鎖表解決方法(轉)

MySQL鎖表解決方法(轉)

MySQL鎖表解決方法(轉)

xxmzhumeng 2014-07-16 18:32:47 82945 收藏 9
MySQL鎖表解決方法
一、我的處理過程
1、查程序,主要是查詢被鎖表的那個程序的ID

SHOW PROCESSLIST;
2、kill掉鎖表的程序ID

KILL 10866;//後面的數字即時程序的ID

網上找了些資料,瞭解了一下,先分享一下:

二、mysql的鎖表問題
SHOW PROCESSLIST檢視資料庫中表的狀態,是否被鎖;
kill id //殺掉被鎖的表

set autocommit=0;
select * from t1 where uid=’xxxx’ for update //在有索引(例如uid)的情況下是行鎖,否則是表鎖
insert into t1 values(1,’xxxxx’);
commit;

lock tables t1 write|read;
insert into t1 values(2,’xxxxx’); //只有insert
unlock tables;

2 《輕鬆掌握MySQL資料庫鎖機制的相關原理》

MySQL 5.1支援對MyISAM和MEMORY表進行表級鎖定,對BDB表進行頁級鎖定,對InnoDB 表進行行級鎖定。在許多情況下,可以根據培訓猜測應用程式使用哪類鎖定型別最好,但一般很難說出某個給出的鎖型別就比另一個好。一切取決於應用程式,應用程式的不同部分可能需要不同的鎖型別。為了確定是否想要使用行級鎖定的儲存引擎,應看看應用程式做什麼並且混合使用什麼樣的選擇和更新語句。例如,大多數Web應用程式執行許多選擇,而很少進行刪除,只對關鍵字的值進行更新,並且只插入少量具體的表。基本MySQL MyISAM設定已經調節得很好。

在MySQL中對於使用表級鎖定的儲存引擎,表鎖定時不會死鎖的。這通過總是在一個查詢開始時立即請求所有必要的鎖定並且總是以同樣的順序鎖定表來管理。

對WRITE,MySQL使用的表鎖定方法原理如下:

◆ 如果在表上沒有鎖,在它上面放一個寫鎖。
◆否則,把鎖定請求放在寫鎖定佇列中。

對READ,MySQL使用的鎖定方法原理如下:

◆如果在表上沒有寫鎖定,把一個讀鎖定放在它上面。
◆否則,把鎖請求放在讀鎖定佇列中。

當一個鎖定被釋放時,鎖定可被寫鎖定佇列中的執行緒得到,然後是讀鎖定佇列中的執行緒。

這意味著,如果你在一個表上有許多更新,SELECT語句將等待直到沒有更多的更新。

如果INSERT 語句不衝突,可以自由為MyISAM 表混合並行的INSERT 和SELECT 語句而不需要鎖定。

InnoDB 使用行鎖定,BDB 使用頁鎖定。對於這兩種儲存引擎,都可能存在死鎖。這是因為,在SQL語句處理期間,InnoDB 自動獲得行鎖定,BDB 獲得頁鎖定,而不是在事務啟動時獲得。

行級鎖定的優點:

· 當在許多執行緒中訪問不同的行時只存在少量鎖定衝突。
· 回滾時只有少量的更改。
· 可以長時間鎖定單一的行。

行級鎖定的缺點:

· 比頁級或表級鎖定佔用更多的記憶體。
· 當在表的大部分中使用時,比頁級或表級鎖定速度慢,因為你必須獲取更多的鎖。
· 如果你在大部分資料上經常進行 GROUP BY 操作或者必須經常掃描整個表,比其它鎖定明顯慢很多。
· 用高級別鎖定,通過支援不同的型別鎖定,你也可以很容易地調節應用程式,因為其鎖成本小於行級鎖定。

在以下情況下,表鎖定優先於頁級或行級鎖定:

· 表的大部分語句用於讀取。
· 對嚴格的關鍵字進行讀取和更新,你可以更新或刪除可以用單一的讀取的關鍵字來提取的一行:
• UPDATE tbl_name SET column = value WHERE unique_key_col = key_value ;
• DELETE FROM tbl_name WHERE unique_key_col = key_value ;
· SELECT 結合並行的INSERT 語句,並且只有很少的UPDATE或 DELETE 語句。
· 在整個表上有許多掃描或 GROUP BY 操作,沒有任何寫操作。
不同於行級或頁級鎖定的選項:
· 版本(例如,為並行的插入在MySQL中使用的技術),其中可以一個寫操作,同時有許多讀取操作。這明資料庫或表支援資料依賴的不同檢視,取決於訪問何時開始。其它共同的術語是“時間跟蹤”、“寫複製”或者“按需複製”。
· 按需複製在許多情況下優先於頁級或行級鎖定。然而,在最壞的情況下,它可能比使用常規鎖定使用多的記憶體。
· 除了行級鎖定外,你可以使用應用程式級鎖定,例如在MySQL中使用GET_LOCK()和RELEASE_LOCK()。這些是建議性鎖定,它們只能在執行良好的應用程式中工作。
為達到最高鎖定速度,除InnoDB 和BDB 之外,對所有儲存引擎,MySQL使用表鎖定(而不是頁、行或者列鎖定)。對於InnoDB 和BDB 表,如果你用LOCK TABLES顯式鎖定表,MySQL只使用表鎖定;如果你不使用LOCK TABLES,因為 InnoDB 使用自動行級鎖定而BDB 使用頁級鎖定來保證事務隔離。

但是對於大表,對於大多數應用程式,表鎖定比行鎖定更好,但存在部分缺陷。表鎖定使許多執行緒同時從一個表中進行讀取操作,但如果一個執行緒想要對錶進行寫操作,它必須首先獲得獨佔訪問。更新期間,所有其它想要訪問該表的執行緒必須等待直到更新完成。

表更新通常情況認為比表檢索更重要,因此給予它們更高的優先順序。這應確保更新一個表的活動不能“餓死”,即使該表上有很繁重的SELECT 活動。

表鎖定在這種情況下會造成問題,例如當執行緒正等待,因為硬碟已滿並且線上程可以處理之前必須有空閒空間。在這種情況下,所有想要訪問出現問題的表的執行緒也被設定成等待狀態,直到有更多的硬碟空間可用。

表鎖定在下面的情況下也存在問題:

· 一個客戶發出長時間執行的查詢。
· 然後,另一個客戶對同一個表進行更新。該客戶必須等待直到SELECT完成。
· 另一個客戶對同一個表上發出了另一個 SELECT 語句。因為UPDATE比 SELECT 優先順序高,該SELECT 語句等待UPDATE完成,並且等待第1個 SELECT 完成。

下面描述了一些方法來避免或減少表鎖定造成的競爭:

· 試圖使 SELECT 語句執行得更快。可能必須建立一些摘要(summary)表做到這點。
· 用–low-priority-updates啟動mysqld。這將給所有更新(修改)一個表的語句以比SELECT語句低的優先順序。在這種情況下,在先前情形的第2個SELECT語句將在UPDATE語句前執行,而不需要等候第1個 SELECT 完成。
· 可以使用SET_UPDATES=1語句指定具體連線中的所有更新應使用低優先順序。
· 可以用LOW_PRIORITY屬性給與一個特定的INSERT、UPDATE或DELETE語句較低優先順序。
· 可以用HIGH_PRIORITY屬性給與一個特定的SELECT語句較高優先順序。
· 為max_write_lock_count系統變數指定一個低值來啟動mysqld來強制MySQL在具體數量的插入完成後臨時提高所有等待一個表的SELECT 語句的優先順序。這樣允許在一定數量的WRITE鎖定後給出READ鎖定。
· 如果你有關於INSERT結合SELECT的問題,切換到使用新的MyISAM表,因為它們支援併發的SELECT和INSERT。
· 如果你對同一個表混合插入和刪除,INSERT DELAYED將會有很大的幫助。
· 如果你對同一個表混合使用 SELECT 和DELETE 語句出現問題,DELETE 的LIMIT 選項可以有所幫助。
· 對 SELECT 語句使用SQL_BUFFER_RESULT可以幫助使表鎖定時間變短。
· 可以更改mysys/thr_lock.c中的鎖程式碼以使用單一的佇列。在這種情況下,寫鎖定和讀鎖定將具有相同的優先順序,對一些應用程式會有幫助。

這裡是一些MySQL中表鎖定相關的技巧:

· 如果不混合更新與需要在同一個表中檢查許多行的選擇,可以進行並行操作。
· 可以使用 LOCK TABLES 來提高速度,因為在一個鎖定中進行許多更新比沒有鎖定的更新要快得多。將表中的內容切分為幾個表也可以有所幫助。
· 如果在MySQL中表鎖定時遇到速度問題,可以將錶轉換為 InnoDB 或BDB 表來提高效能
你對人生迷茫嗎? 那就背起行囊,起步遠行吧

本篇轉自:http://www.cnblogs.com/daxian2012/archive/2012/09/04/mysql.html

三、鎖表的機制
為了給高併發情況下的mysql進行更好的優化,有必要了解一下mysql查詢更新時的鎖表機制。

一、概述

MySQL有三種鎖的級別:頁級、表級、行級。

MyISAM和MEMORY儲存引擎採用的是表級鎖(table-level locking);BDB儲存引擎採用的是頁面鎖(page-level
locking),但也支援表級鎖;InnoDB儲存引擎既支援行級鎖(row-level locking),也支援表級鎖,但預設情況下是採用行級鎖。

MySQL這3種鎖的特性可大致歸納如下:

表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖衝突的概率最高,併發度最低。
行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高。
頁面鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度一般。

二、MyISAM表鎖

MyISAM儲存引擎只支援表鎖,是現在用得最多的儲存引擎。

1、查詢表級鎖爭用情況

可以通過檢查table_locks_waited和table_locks_immediate狀態變數來分析系統上的表鎖定爭奪:
mysql> show status like ‘table%’;
+———————–+———-+
| Variable_name | Value |
+———————–+———-+
| Table_locks_immediate | 76939364 |
| Table_locks_waited | 305089 |
+———————–+———-+
2 rows in set (0.00 sec)Table_locks_waited的值比較高,說明存在著較嚴重的表級鎖爭用情況。

2、MySQL表級鎖的鎖模式

MySQL的表級鎖有兩種模式:表共享讀鎖(Table Read Lock)和表獨佔寫鎖(Table Write
Lock)。MyISAM在執行查詢語句(SELECT)前,會自動給涉及的所有表加讀鎖,在執行更新操作(UPDATE、DELETE、INSERT等)前,會自動給涉及的表加寫鎖。

所以對MyISAM表進行操作,會有以下情況:

a、對MyISAM表的讀操作(加讀鎖),不會阻塞其他程序對同一表的讀請求,但會阻塞對同一表的寫請求。只有當讀鎖釋放後,才會執行其它程序的寫操作。
b、對MyISAM表的寫操作(加寫鎖),會阻塞其他程序對同一表的讀和寫操作,只有當寫鎖釋放後,才會執行其它程序的讀寫操作。

下面通過例子來進行驗證以上觀點。資料表gz_phone裡有二百多萬資料,欄位id,phone,ua,day。現在同時用多個客戶端同時對該表進行操作分析。

a、當我用客戶端1進行一個比較長時間的讀操作時,分別用客戶端2進行讀和寫操作:

client1:
mysql>select count(*) from gz_phone group by ua;
75508 rows in set (3 min 15.87 sec) client2:
select id,phone from gz_phone limit 1000,10;
+——+——-+
| id | phone |
+——+——-+
| 1001 | 2222 |
| 1002 | 2222 |
| 1003 | 2222 |
| 1004 | 2222 |
| 1005 | 2222 |
| 1006 | 2222 |
| 1007 | 2222 |
| 1008 | 2222 |
| 1009 | 2222 |
| 1010 | 2222 |
+——+——-+
10 rows in set (0.01 sec)
mysql> update gz_phone set phone=’11111111111′where id=1001;
Query OK, 0 rows affected (2 min 57.88 sec)
Rows matched: 1 Changed: 0 Warnings: 0

說明當資料表有一個讀鎖時,其它程序的查詢操作可以馬上執行,但更新操作需等待讀鎖釋放後才會執行。

b、當用客戶端1進行一個較長時間的更新操作時,用客戶端2,3分別進行讀寫操作:

client1:
mysql> update gz_phone set phone=’11111111111′;
Query OK, 1671823 rows affected (3 min 4.03 sec)
Rows matched: 2212070 Changed: 1671823 Warnings: 0 client2:
mysql> select id,phone,ua,day from gz_phone limit 10;
+—-+——-+——————-+————+
| id | phone | ua | day |
+—-+——-+——————-+————+
| 1 | 2222 | SonyEricssonK310c | 2007-12-19 |
| 2 | 2222 | SonyEricssonK750c | 2007-12-19 |
| 3 | 2222 | MAUI WAP Browser | 2007-12-19 |
| 4 | 2222 | Nokia3108 | 2007-12-19 |
| 5 | 2222 | LENOVO-I750 | 2007-12-19 |
| 6 | 2222 | BIRD_D636 | 2007-12-19 |
| 7 | 2222 | SonyEricssonS500c | 2007-12-19 |
| 8 | 2222 | SAMSUNG-SGH-E258 | 2007-12-19 |
| 9 | 2222 | NokiaN73-1 | 2007-12-19 |
| 10 | 2222 | Nokia2610 | 2007-12-19 |
+—-+——-+——————-+————+
10 rows in set (2 min 58.56 sec) client3:
mysql> update gz_phone set phone=’55555′where id=1;
Query OK, 1 row affected (3 min 50.16 sec)
Rows matched: 1 Changed: 1 Warnings: 0

說明當資料表有一個寫鎖時,其它程序的讀寫操作都需等待讀鎖釋放後才會執行。

3、併發插入

原則上資料表有一個讀鎖時,其它程序無法對此表進行更新操作,但在一定條件下,MyISAM表也支援查詢和插入操作的併發進行。

MyISAM儲存引擎有一個系統變數concurrent_insert,專門用以控制其併發插入的行為,其值分別可以為0、1或2。

a、當concurrent_insert設定為0時,不允許併發插入。
b、當concurrent_insert設定為1時,如果MyISAM表中沒有空洞(即表的中間沒有被刪除的行),MyISAM允許在一個程序讀表的同時,另一個程序從表尾插入記錄。這也是MySQL的預設設定。
c、當concurrent_insert設定為2時,無論MyISAM表中有沒有空洞,都允許在表尾併發插入記錄。

4、MyISAM的鎖排程

由於MySQL認為寫請求一般比讀請求要重要,所以如果有讀寫請求同時進行的話,MYSQL將會優先執行寫操作。這樣MyISAM表在進行大量的更新操作時(特別是更新的欄位中存在索引的情況下),會造成查詢操作很難獲得讀鎖,從而導致查詢阻塞。

我們可以通過一些設定來調節MyISAM的排程行為:

a、通過指定啟動引數low-priority-updates,使MyISAM引擎預設給予讀請求以優先的權利。
b、通過執行命令SET LOW_PRIORITY_UPDATES=1,使該連線發出的更新請求優先順序降低。
c、通過指定INSERT、UPDATE、DELETE語句的LOW_PRIORITY屬性,降低該語句的優先順序。

上面3種方法都是要麼更新優先,要麼查詢優先的方法。這裡要說明的就是,不要盲目的給mysql設定為讀優先,因為一些需要長時間執行的查詢操作,也會使寫程序“餓死”。只有根據你的實際情況,來決定設定哪種操作優先。這些方法還是沒有從根本上同時解決查詢和更新的問題。

在一個有大資料量高並發表的mysql裡,我們還可採用另一種策略來進行優化,那就是通過mysql主從(讀寫)分離來實現負載均衡,這樣可避免優先哪一種操作從而可能導致另一種操作的堵塞。下面將用一個篇幅來說明mysql的讀寫分離技術

本篇轉自:http://www.2cto.com/database/201202/120824.html@

歡迎使用Markdown編輯器

你好! 這是你第一次使用 Markdown編輯器 所展示的歡迎頁。如果你想學習如何使用Markdown編輯器, 可以仔細閱讀這篇文章,瞭解一下Markdown的基本語法知識。

新的改變

我們對Markdown編輯器進行了一些功能拓展與語法支援,除了標準的Markdown編輯器功能,我們增加了如下幾點新功能,幫助你用它寫部落格:

  1. 全新的介面設計 ,將會帶來全新的寫作體驗;
  2. 在創作中心設定你喜愛的程式碼高亮樣式,Markdown 將程式碼片顯示選擇的高亮樣式 進行展示;
  3. 增加了 圖片拖拽 功能,你可以將本地的圖片直接拖拽到編輯區域直接展示;
  4. 全新的 KaTeX數學公式 語法;
  5. 增加了支援甘特圖的mermaid語法 功能;
  6. 增加了 多螢幕編輯 Markdown文章功能;
  7. 增加了 焦點寫作模式、預覽模式、簡潔寫作模式、左右區域同步滾輪設定 等功能,功能按鈕位於編輯區域與預覽區域中間;
  8. 增加了 檢查列表 功能。

功能快捷鍵

撤銷:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜體:Ctrl/Command + I
標題:Ctrl/Command + Shift + H
無序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
檢查列表:Ctrl/Command + Shift + C
插入程式碼:Ctrl/Command + Shift + K
插入連結:Ctrl/Command + Shift + L
插入圖片:Ctrl/Command + Shift + G
查詢:Ctrl/Command + F
替換:Ctrl/Command + G

合理的建立標題,有助於目錄的生成

直接輸入1次#,並按下space後,將生成1級標題。
輸入2次#,並按下space後,將生成2級標題。
以此類推,我們支援6級標題。有助於使用TOC語法後生成一個完美的目錄。

如何改變文字的樣式

強調文字 強調文字

加粗文字 加粗文字

標記文字

刪除文字

引用文字

H2O is是液體。

210 運算結果是 1024.

插入連結與圖片

連結: .

圖片: Alt

帶尺寸的圖片: Alt

居中的圖片: Alt

居中並且帶尺寸的圖片: Alt

當然,我們為了讓使用者更加便捷,我們增加了圖片拖拽功能。

如何插入一段漂亮的程式碼片

去頁面,選擇一款你喜歡的程式碼片高亮樣式,下面展示同樣高亮的 程式碼片.

// An highlighted block
var foo = 'bar';

生成一個適合你的列表

  • 專案
    • 專案
      • 專案
  1. 專案1
  2. 專案2
  3. 專案3
  • 計劃任務
  • 完成任務

建立一個表格

一個簡單的表格是這麼建立的:

專案Value
電腦$1600
手機$12
導管$1

設定內容居中、居左、居右

使用:---------:居中
使用:----------居左
使用----------:居右

第一列第二列第三列
第一列文字居中第二列文字居右第三列文字居左

SmartyPants

SmartyPants將ASCII標點字元轉換為“智慧”印刷標點HTML實體。例如:

TYPEASCIIHTML
Single backticks'Isn't this fun?'‘Isn’t this fun?’
Quotes"Isn't this fun?"“Isn’t this fun?”
Dashes-- is en-dash, --- is em-dash– is en-dash, — is em-dash

建立一個自定義列表

Markdown
Text-to- HTML conversion tool
Authors
John
Luke

如何建立一個註腳

一個具有註腳的文字。

註釋也是必不可少的

Markdown將文字轉換為 HTML

KaTeX數學公式

您可以使用渲染LaTeX數學表示式 :

Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n−1)!∀n∈N 是通過尤拉積分

Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t   . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=∫0∞​tz−1e−tdt.

你可以找到更多關於的資訊 LaTeX 數學表示式.

新的甘特圖功能,豐富你的文章

Mon 06 Mon 13 Mon 20 已完成 進行中 計劃一 計劃二 現有任務 Adding GANTT diagram functionality to mermaid
  • 關於 甘特圖 語法,參考 ,

UML 圖表

可以使用UML圖表進行渲染。 . 例如下面產生的一個序列圖:

張三 李四 王五 你好!李四, 最近怎麼樣? 你最近怎麼樣,王五? 我很好,謝謝! 我很好,謝謝! 李四想了很長時間, 文字太長了 不適合放在一行. 打量著王五... 很好... 王五, 你怎麼樣? 張三 李四 王五

這將產生一個流程圖。:

連結 長方形 圓角長方形 菱形
  • 關於 Mermaid 語法,參考 ,

FLowchart流程圖

我們依舊會支援flowchart的流程圖:

Created with Raphaël 2.2.0 開始 我的操作 確認? 結束 yes no
  • 關於 Flowchart流程圖 語法,參考 .

匯出與匯入

匯出

如果你想嘗試使用此編輯器, 你可以在此篇文章任意編輯。當你完成了一篇文章的寫作, 在上方工具欄找到 文章匯出 ,生成一個.md檔案或者.html檔案進行本地儲存。

匯入

如果你想載入一篇你寫過的.md檔案,在上方工具欄可以選擇匯入功能進行對應副檔名的檔案匯入,
繼續你的創作。


  1. 註腳的解釋