MySQL常問鎖的面試題

2021-10-11 10:02:33 字數 2701 閱讀 9560

鎖(lock)在多人處理同乙個資料的時候,保證每次只有乙個人可以操作。mysql提供了頁鎖(全域性鎖)、行鎖、表鎖。其中innodb採用的是行鎖和表鎖,myisam只支援表鎖。

是指二個或者二個以上的程序在執行時候,因為爭奪資源造成相互等待的現象,程序一直處於等待中,無法得到釋放,這種狀態就叫做死鎖,

批量入庫,存在則更新,不存在則插入,insert into tab(xx,xx) on duplicate key update xx=『xx』。

1:通過innodblockwait_timeout來設定超時時間,一直等待直到超時

2:發起死鎖檢測,發現死鎖之後,主動回滾死鎖中的事務,不需要其他事務繼續

為了在單個innodb表上執行多個併發寫入操作時避免死鎖,可以在事務開始時,通過為預期要修改行,使用select …for update語句來獲取必要的鎖,即使這些行的更改語句是在之後才執行的

在事務中,如果要更新記錄,應該直接申請足夠級別的鎖,即排他鎖,而不應先申請共享鎖,更新時在申請排他鎖。因為這時候當使用者在申請排他鎖時,其他事務可能又已經獲得了相同記錄的共享鎖,

如果事務需要修改或鎖定多個表,則應在每個事務中以相同的順序使用加鎖語句。在應用中,如果不同的程式會併發獲取多個表,應盡量約定以相同的順序來訪問表,這樣可以大大降低產生死鎖的機會。

通過 select …lock in share mode獲取行的讀鎖後,如果當前事務在需要對該記錄進行更新操作,則很有可能造成死鎖;

改變事務隔離級別

innodb預設是使用設定死鎖時間來讓死鎖超時的策略,預設innodblockwait_timeout設定的時長是50s

設定innodbdeadlockdetect設定為on可以主動檢測死鎖,在innodb中這個值預設就是on開啟的狀態

全域性鎖就是對整個資料庫例項加鎖,它的典型使用場景就是做全庫邏輯備份,這個命令可以使用整個庫處於唯讀狀態,使用該命令之後,資料更新語句,資料定義語句,更新類事務的提交語句等操作都會被阻塞。

如果在主庫備份,在備份期間不能更新,業務停止,所以更新業務會處於等待狀態

如果在從庫備份,在備份期間不能執行主庫同步的binlog,導致主從延遲

如果使用全域性鎖進行邏輯備份都會讓整個庫成為唯讀狀態,解決辦法需要使用mysqldump時,使用引數-single-transaction就會在匯入資料之前啟動乙個事務來保證資料的一致性,並且這個過程是支援資料更細操作的。

共享鎖是讀取操作建立的鎖。其他使用者可以併發讀取資料,但是任何事務都不能對資料進行修改(獲取資料上的排他鎖),直到已釋放所有共享鎖。當如果事務對讀鎖進行修改操作,很可能會操作死鎖。

排他鎖又稱寫鎖

事務對某一行加上排他鎖,只能這個事務對其進行讀寫操作,在事務結束以前,其他事務不能對其進行加任何鎖,其他程序可以讀取,但是不能進行寫操作,需要等待釋放以後。排他鎖是悲觀鎖的一種實現。

事務1對資料物件a加上排他鎖,事務1可以讀寫a,其他事務就不能在對a進行任何加鎖操作,直到事務1釋放a上的鎖,這保證其他事務在事務1釋放a上的鎖之前不能在讀取和修改a,排他鎖會阻塞所有的排他鎖和共享鎖。

悲觀鎖:每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料都會block直到它拿到鎖。因此,悲觀鎖需要耗時比較的多,跟樂觀鎖比較,悲觀鎖是有資料庫自己實現的,用的時候我們直接呼叫資料的相關語句就可以

悲觀鎖涉及到的另另兩個鎖,他們是共享鎖和排他鎖,共享鎖和排他鎖時悲觀鎖的不同的實現,屬於悲觀鎖的範疇。

樂觀鎖是用資料版本記錄機制實現,這是樂觀鎖最常用的方式,所謂的資料版本,為資料增加乙個版本號的字段,一般是通過為資料表增加乙個資料型別的version欄位實現,當讀取資料時,將把二十年欄位的值一同讀取出來,資料每次更新都需要對version值加一,在我們提交更新的時候,判斷資料表對應記錄的當前版本資訊與第一次取出來的version值進行對比,如果資料庫的表當前版本號魚取出來的version值相等,則給與更新否則認為過期資料不給與更新。

樂觀鎖雖然叫鎖其實在使用的時候是沒有加鎖,所以執行效能高。缺點:會產生aba的問題,aba問題指的是有乙個變數v初次讀取的時候是a值,並且在準備賦值的時候檢查到他的值還是為a值,會誤認為沒有被修改做為正常的執行修改操作,實際上這段時間他的值可能被修改為其他值,之後又被修改為a值,

1.record lock—單個行記錄上的鎖

2.gap lock — 間隙鎖,鎖定乙個氛圍,不包括記錄本身

3.next-key lock–鎖定乙個範圍,包含記錄本身

行鎖是mysql中粒度最小的一種鎖,innodb的行鎖有共享鎖和排他鎖兩種,共享鎖允許事務讀一行記錄,不允許任何執行緒對行記錄進行修改操作,排他鎖允許當前事務刪除或者更新一行記錄,其他執行緒不能操作該記錄。

使用較低的隔離級別

設計索引,盡量使用索引去訪問資料,加鎖更加精確,從而減少鎖衝突

選擇合理的事務大小,

給記錄顯示加鎖時,最好一次性請求足夠級別的鎖。列如,修改資料的話,最好申請排他鎖,而不是先申請共享鎖,修改時在申請排他鎖,這樣會導致死鎖

不同的程式訪問一組表的時候,應盡量約定乙個相同的順序訪問各表,對於乙個表而言,盡可能的固定順序的獲取表中的行。這樣大大的減少死鎖的機會。

盡量使用相等條件訪問資料,這樣可以避免間隙鎖對併發插入的影響

不要申請超過實際需要的鎖級別

資料查詢的時候不是必要,不要使用加鎖。mysql的mvcc可以實現事務中的查詢不用加鎖,優化事務效能:mvcc只在committed read(讀提交)和 repeatable read (可重複讀)兩種隔離級別

對於特定的事務,可以使用表鎖來提高處理速度活著減少死鎖的可能。

HashMap常問的面試題

來看看hashmap經常被問的問題 1 hashmap特性?2 hashmap與hashtable區別?3 hashmap執行緒不安全實際會如何體現?4 hashmap如何變成執行緒安全?5 hashmap的資料結構是什麼?6.1 我們可以使用自定義的物件作為鍵嗎?7 hashmap初始化傳入的容量...

web專案常問面試題

1 語意化標籤 利於搜尋引擎收錄 也提高了 閱讀性 2 減少標籤的巢狀 利於渲染引擎的加速渲染 3 把script標籤移到html檔案末尾,因為js會阻塞後面的頁面的顯示 4 減少iframe的使用,因為iframe會增加一條http請求,阻止頁面載入,即使內容為空,載入也需要時間 6 html結構...

企業面試題 最常問的MySQL面試題集合(三)

延伸 對使用者而言,分割槽表是乙個獨立的邏輯表,但是底層mysql將其分成了多個物理子表,這對使用者來說是透明的,每乙個分割槽表都會使用乙個獨立的表檔案。如圖所示 mysql將表分成多個物理字表,但php客戶端並無感知,仍然認為操作的是乙個表。建立表時使用partition by子句定義每個分割槽存...