MySQL及線程關于鎖的面試題

目錄

1.了解過 MySQL 死鎖問題嗎?

2.什么是線程死鎖?死鎖相關面試題

2.1 什么是死鎖:

2.2 形成死鎖的四個必要條件是什么?

2.3 如何避免線程死鎖?

3. MySQL 怎么排查死鎖問題?

4.Java線上死鎖問題如何排查

5. 詳細說一下 MySQL 數據庫中鎖的分類(重要)

6.MySQL行級鎖的原理是什么

7. 行鎖什么時候會退化成表鎖


1.了解過 MySQL 死鎖問題嗎?

分析:

解釋 MySQL 死鎖是如何發生的。

  • 回答:了解過。
  • 在并發事務中、當兩個事務出現循環資源依賴、這兩個事務都在等待別的事務釋放資源時、就會導致這兩個事務都進入無限等待的狀態、這時候就發生了死鎖

2.什么是線程死鎖?死鎖相關面試題

2.1 什么是死鎖

  • 死鎖是指兩個或兩個以上的進程(線程)在執行過程中、由于競爭資源而造成的一種阻塞的現象、若無外力作用、它們都將無法推進下去。此時稱系統處于死鎖狀態或系統產生了死鎖、這些永遠在互相等待的進程(線程)稱為死鎖進程(線程)。
  • 多個線程同時被阻塞、它們中的一個或者全部都在等待某個資源被釋放。由于線程被無限期地阻塞、因此程序不可能正常終止。

2.2 形成死鎖的四個必要條件是什么?

  • 互斥條件:在一段時間內某資源只由一個進程占用。如果此時還有其它進程請求資源、就只能等待、直至占有資源的進程用畢釋放。
  • 占有且等待條件:指進程已經保持至少一個資源、但又提出了新的資源請求、而該資源已被其它進程占有、此時請求進程阻塞、但又對自己已獲得的其它資源保持不放。
  • 不可搶占條件:別人已經占有了某項資源、你不能因為自己也需要該資源、就去把別人的資源搶過來。
  • 循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關系。
  • (比如一個進程集合、A在等B、B在等C、C在等A)

總結:

產生死鎖的四個必要條件:

  • 互斥條件:多個線程不能同時使用一個資源
  • 持有并等待條件:線程A在等待資源2的同時并不會釋放自己已經持有的資源1
  • 不可剝奪條件:在自己使用之前不能被其他線程獲取
  • 循環等待條件:兩個線程獲取資源的順序構成了環形鏈

2.3 如何避免線程死鎖

我們只要破壞產生死鎖的四個條件中的其中一個就可以了。

  • 破壞互斥條件:這個條件我們沒有辦法破壞、因為我們用鎖本來就是想讓他們互斥的(臨界資源需要互斥訪問)。
  • 破壞請求與保持條件:一次性申請所有的資源
  • 破壞不剝奪條件:占用部分資源的線程進一步申請其他資源時、如果申請不到、可以主動釋放它占有的資源。
  • 破壞循環等待條件:靠按序申請資源來預防、按某一順序申請資源、釋放資源則反序釋放。破壞循環等待條件。

3. MySQL 怎么排查死鎖問題?

分析:獲取死鎖日志、分析死鎖日志

參考面試回答:

  • 在遇到線上死鎖問題時、我們應該第一時間獲取相關的死鎖日志。
  • 我們可以通過 show engine innodb status 命令來獲取死鎖信息。
  • 然后就分析死鎖日志。死鎖日志通常分為兩部分、上半部分說明了事務1在等待什么鎖、下半部分說明了事務2當前持有的鎖和等待的鎖。
  • 通過閱讀死鎖日志、我們可以清楚地知道兩個事務形成了怎樣的循環等待、然后根據當前各個事務執行的SQL分析出加鎖類型以及順序、逆向推斷出如何形成循環等待、這樣就能找到死鎖產生的原因了

4.Java線上死鎖問題如何排查

發生死鎖的場景

循環等待 (Circular Wait): 這是最經典的死鎖場景。也就是嵌套鎖

  • 線程 A 持有鎖 1、并嘗試獲取鎖 2。

  • 線程 B 持有鎖 2、并嘗試獲取鎖 1。

  • 結果:線程 A 和線程 B 都在等待對方釋放鎖、導致永久阻塞。

競爭不可剝奪資源:

兩個進程都需要打印機和掃描儀。進程A先獲得了打印機\進程B先獲得了掃描儀。然后進程A請求掃描儀

進程B請求打印機 由于打印機和掃描儀都是不可剝奪的 兩個進程都無法獲得對方需要的資源 導致死鎖。

可以簡單概括如下:

  1. 識別死鎖發生的現象: 確定應用是否表現出死鎖的癥狀、如線程長時間處于阻塞狀態。

  2. 獲取線程堆棧信息: 通過工具(如 jstack)獲取JVM線程堆棧、分析各線程的狀態、尤其關注等待鎖的線程。jstack + threaddump.txt、收集線程堆棧信息、threaddump.txt文件。

  3. 分析代碼: 檢查線程堆棧中的棧幀,定位發生死鎖的代碼區域。重點關注可能導致鎖定的同步塊或方法。在上一步生成的堆棧文件中查找deadlockwaiting to locklock等有指向死鎖的信息、確定代碼中出現死鎖的位置。

  4. 優化代碼邏輯: 修復導致死鎖的代碼塊,一般可以采用減少鎖的粒度,使用非阻塞算法,或者重構為無鎖設計。使用 ReentrantLocktryLock() 等機制避免長期持有鎖等方式。

  5. 監控和測試: 持續監控應用運行時的線程情況,尤其是在高并發場景下。通過壓力測試和代碼審計盡早發現潛在的死鎖問題。

面試回答:

  • 首先就是命令 jps 查看進程ID
  • 然后將進程ID對應的程序線程日志收集到文本中 方便后續分析
  • jstack -l 24360 > .wy.txt
  • 然后分析進程堆棧信息
  • 打開 文件、搜索 deadlocklock waiting tolocked 關鍵字、以定位死鎖或阻塞線程
  • 然后優化代碼邏輯

5. 詳細說一下 MySQL 數據庫中鎖的分類(重要)

分析:

  • 全局鎖:通過 flush tables with read lock 語句會將整個數據庫就處于只讀狀態了、這時其他線程執行以下操作、增刪改或者表結構修改都會阻塞。全局鎖主要應用于做全庫邏輯備份、這樣在備份數據庫期間,不會因為數據或表結構的更新、而出現備份文件的數據與預期的不一樣。

  • 表級鎖:MySQL 里面表級別的鎖有這幾種:

    • 表鎖:通過 lock tables 語句可以對表加表鎖、表鎖除了會限制別的線程的讀寫外、也會限制本線程接下來的讀寫操作。

    • 元數據鎖:當我們對數據庫表進行操作時、會自動給這個表加上 MDL、對一張表進行 CRUD 操作時、加的是 MDL 讀鎖、對一張表做結構變更操作的時候、加的是 MDL 寫鎖、MDL 是為了保證當用戶對表執行 CRUD 操作時、防止其他線程對這個表結構做了變更。

    • 意向鎖:當執行插入、更新、刪除操作、需要先對表加上「意向獨占鎖」、然后對該記錄加獨占鎖。意向鎖的目的是為了快速判斷表里是否有記錄被加鎖。

  • 行級鎖:InnoDB 引擎是支持行級鎖的、而 MyISAM 引擎并不支持行級鎖。

    • 記錄鎖:鎖住的是一條記錄。而且記錄鎖是有 S 鎖和 X 鎖之分的、滿足讀寫互斥、寫寫互斥

    • 間隙鎖:只存在于可重復讀隔離級別、目的是為了解決可重復讀隔離級別下幻讀的現象。

    • Next-Key Lock 稱為臨鍵鎖、是 Record Lock + Gap Lock 的組合、鎖定一個范圍、并且鎖定記錄本身。

    • 插入意向鎖、當插入位置的下一條記錄有間隙鎖、那么就會生成插入意向鎖、然后進入阻塞狀態

根據鎖粒度的不同、MySQL 的鎖可以分為全局鎖、表級鎖、行級鎖。

  • 我們熟悉的是表級鎖和行級鎖

    • 比如我們對一張表結構進行修改的時候

    • MySQL 就會對這張表加一個元數據鎖、元數據鎖是屬于表級鎖的。

  • 行級鎖目前只有 InnoDB 存儲引擎實現了、MyISAM 存儲引擎是不支持行級鎖的、只有表鎖。

    • InnoDB 存儲引擎實現的行級鎖主要有記錄鎖、間隙鎖、臨鍵鎖、插入意向鎖這些

  • 當我們對表記錄進行 select for update、或者增刪改的時候、都會對記錄加行級鎖。

  • mysql的鎖機制是數據庫引擎鎖的鎖機制

  • 間隙鎖只在某些情況下才加:為了防止幻讀

    • 當前事務隔離級別是可重復隔離級別(MySQL默認)

    • 查詢使用了 FOR UPDATE 或 LOCK IN SHARE MODE

    • 查詢條件涉及范圍查詢非唯一索引

    • 在數據庫使用非唯一索引時、系統會使用間隙鎖來防止其他事務在當前范圍內插入新記錄、確保當前事務的操作是可重復讀的。這是為了防止幻讀現象(Phantom Read)、即一個事務在讀取數據時、另一個事務可能插入了新的數據、使得前一個事務讀取的數據不一致。

    • 間隙鎖會鎖住一個范圍的空白地帶、這樣即使在該范圍內沒有記錄、其他事務也不能插入新的記錄、從而避免了出現不一致的數據讀取。

6.MySQL行級鎖的原理是什么

??行級鎖是 MySQL 在存儲引擎層(如 InnoDB)實現的、鎖定的是表中某一行數據

??首先行鎖分為:

  • 記錄鎖:鎖住單個記錄

  • 間隙鎖:這種鎖鎖定的是索引記錄之間的“間隙”,但不包括記錄本身。例如如果索引上有值 10 和 20、間隙鎖可以鎖定 (10, 20) 這個開區間。它的主要目的是防止其他事務在這個間隙中插入新的記錄、從而避免幻讀問題。間隙鎖只在可重復讀(Repeatable Read)或更高的隔離級別下才生效。

  • Next-Key Lock 稱為臨鍵鎖、是 Record Lock + Gap Lock 的組合、鎖定一個范圍、并且鎖定記錄本身。用于防止幻讀、默認用于可重復度隔離級別。Next-Key Lock 是 InnoDB 在可重復讀隔離級別下解決幻讀問題的主要方式、是其默認的行鎖算法

實現原理:

1. 實現原理核心 —— 依賴索引:

InnoDB 的行級鎖是通過給索引項加鎖來實現的。這意味著當 InnoDB 更新、刪除或(在某些情況下)查詢一行數據、它實際上是在這條記錄對應的索引條目上施加鎖。

一句話總結就是:

如果 SQL 語句的操作能夠利用到索引(尤其是唯一索引或主鍵索引)、InnoDB 就會使用行級鎖。

2. 行鎖什么時候會退化成表鎖

如果 SQL 語句的條件沒有命中任何索引、導致需要進行全表掃描、那么 InnoDB 通常會退化為對整個表加鎖(表級鎖)、或者鎖定所有掃描過的行、這會極大地降低并發性能。

行鎖分為:

  • 記錄鎖:鎖住單個記錄
  • 間隙鎖:這種鎖鎖定的是索引記錄之間的“間隙”,但不包括記錄本身。例如如果索引上有值 10 和 20、間隙鎖可以鎖定 (10, 20) 這個開區間。它的主要目的是防止其他事務在這個間隙中插入新的記錄、從而避免幻讀問題。間隙鎖只在可重復讀(Repeatable Read)或更高的隔離級別下才生效。
  • Next-Key Lock 稱為臨鍵鎖、是 Record Lock + Gap Lock 的組合、鎖定一個范圍、并且鎖定記錄本身。用于防止幻讀、默認用于可重復度隔離級別。Next-Key Lock 是 InnoDB 在可重復讀隔離級別下解決幻讀問題的主要方式、是其默認的行鎖算法

行鎖的模式 (并發控制):

  • 當一個事務獲取了某行的鎖后、這個鎖會有不同的模式、決定了其他事務能否以及如何訪問這行數據:
  • 共享鎖 (S Lock): 允許多個事務同時讀取同一行數據。一個事務獲取了某行的S鎖后、其他事務也可以獲取該行的S鎖來讀取、但任何事務都不能獲取該行的排它鎖來進行修改、直到所有S鎖被釋放。通常通過 SELECT ... LOCK IN SHARE MODE 獲取。
  • 排它鎖 (X Lock): 如果一個事務獲取了某行的X鎖、那么其他任何事務都不能再獲取該行的S鎖或X鎖、直到第一個事務釋放X鎖。這意味著獲取X鎖的事務可以獨占地讀取和修改這行數據。通常通過 SELECT ... FOR UPDATE、或者在 INSERTUPDATEDELETE 操作中隱式獲取。

加鎖方式是:

  • 執行如 SELECT ... FOR UPDATE、UPDATE、DELETE 語句時、InnoDB 會為匹配行加排它鎖

  • SELECT ... LOCK IN SHARE MODE 則會加共享鎖

7. 行鎖什么時候會退化成表鎖

一句話面試回答:

  • 如果 SQL 語句的條件沒有命中任何索引、導致需要進行全表掃描

  • 那么 InnoDB 通常會退化為對整個表加鎖(表級鎖)、或者鎖定所有掃描過的、,這會極大地降低并發性能

分析:

  • InnoDB 行鎖的基礎:鎖定索引記錄。我們首先要記住、InnoDB 實現行級鎖的機制是在索引記錄上加鎖。當我們說鎖住某一行時、InnoDB 實際上是在這一行數據對應的索引條目上施加了鎖。

  • 無索引時的全表掃描

    • 如果一個 UPDATEDELETE 語句的 WHERE 子句中的列沒有建立索引、或者優化器因為某種原因(比如索引選擇性不高、數據量小等)決定不使用索引、那么 InnoDB 為了找到符合條件的行、就必須逐行掃描整個表的數據。

  • 全表掃描時的加鎖行為

    • InnoDB 的行為通常是:它會在掃描過程中、對它訪問到的每一行數據都嘗試加上行級鎖(通常是排他鎖 X Lock)。

    • 即使某一行最終不符合 WHERE 條件、在它被掃描和判斷的過程中、也可能被短暫地加鎖。對于最終符合條件的行、鎖會一直持有直到事務提交或回滾。

  • 退化成表鎖的實際效果

    • 當 InnoDB 對全表掃描過程中接觸到的幾乎所有行都加上了行級鎖時、盡管從機制上講仍然是多個行鎖,但其最終效果就非常類似于對整個表加了一個表鎖。

    • 這是因為:如果一個事務鎖住了表中的大部分或所有、,其他需要訪問這些行(即使是不同的行)的事務都會被阻塞,等待這些行鎖被釋放。此時并發性會急劇下降、就好像整個表被鎖住了一樣。

  • 為什么不直接用一個表鎖

    • InnoDB 的設計是盡可能提供細粒度的并發控制。即使是全表掃描、它也是在行級別上進行判斷和加鎖、這在某些特定情況下

    • (例如如果掃描的表非常小、或者符合條件的行很快被找到并鎖定而、其他行的鎖能快速釋放)可能仍然比一個粗暴的表鎖要好一點點、或者至少在內部機制上保持一致性。但對于用戶感知到的并發性能而言、效果往往等同于表鎖

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/904977.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/904977.shtml
英文地址,請注明出處:http://en.pswp.cn/news/904977.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Reality Capture 】Reality Capture1.5中文版安裝教程(附安裝包下載)

文章目錄 一、Reality Capture1.5中文版安裝教程二、拷貝中文補丁三、Reality Capture1.5中文版下載地址一、Reality Capture1.5中文版安裝教程 1. Reality Capture v1.4.0漢化版安裝包下載并解壓 2. 運行EpicInstaller-15.17.1-4a91a118786f4c2aa3c0093b23f83863.msi 3. 更改…

SVG數據可視化設計(AI)完全工作流解讀|計育韜

AI 的 SVG 創作極限在哪里?絕不是那些初級的流程圖生成和粗糙的商業模型設計。以下是由我們 JZ Creative Studio 通過 Claude 和 Deepseek 開展的專業級 SVG Data Visualization 創作,應廣大讀者強烈要求,專程直播講授了一期 AI 工作流分享。…

not a genuine st device abort connection的問題

1.魔法棒里面電機Settings 2.然后在Other里面把Enabled的鉤子去掉

uv簡單使用

通過uv創建項目和虛擬環境 初始化項目 uv init --package my-project 初始化一個名為 my-project 的新項目,并生成必要的文件結構。 創建虛擬環境 uv venv .venv 激活虛擬環境 # For Windows .venv\Scripts\activate# For macOS/Linux source .venv/bin/acti…

測試左移系列-產品經理實戰-實戰認知1

課程:B站大學 記錄產品經理實戰項目系統性學習,從產品思維,用戶畫像,用戶體驗,增長數據驅動等不同方向理解產品,從0到1去理解產品從需求到落地的全過程,測試左移方向(靠近需求、設計…

從需求到用例的AI路徑:準確率與挑戰

用工作流生成測試用例和自動化測試腳本! 引言:用例的黃金起點 在軟件工程中,“測試用例”是連接需求理解與質量保障之間的關鍵橋梁。一份高質量的測試用例,不僅是驗證功能實現是否符合需求的工具,更是產品風險感知、用…

大語言模型中的“溫度”參數到底是什么?如何正確設置?

近年來,市面上涌現了大量調用大模型的工具,如 Dify、Cherry Studio 等開源或自研平臺,幾乎都提供了 “溫度”(Temperature) 選項。然而,很多人在使用時并不清楚該如何選擇合適的溫度值。 今天,…

如何刪除網上下載的資源后面的文字

這是我在愛給網上下載的音效資源,但是發現資源后面跟了一大段無關緊要的文本,但是修改資源名稱后還是有。解決辦法是打開屬性然后刪掉資源的標簽即可。

hot100-子串-JS

一、560.和為k的子串 560. 和為 K 的子數組 提示 給你一個整數數組 nums 和一個整數 k ,請你統計并返回 該數組中和為 k 的子數組的個數 。 子數組是數組中元素的連續非空序列。 示例 1: 輸入:nums [1,1,1], k 2 輸出:2示例 2…

01背包類問題

文章目錄 [模版]01背包1. 第一問: 背包不一定能裝滿(1) 狀態表示(2) 狀態轉移方程(3) 初始化(4) 填表順序(5) 返回值 2. 第二問: 背包恰好裝滿3. 空間優化 416.分割等和子集1. 狀態表示2. 狀態轉移方程3. 初始化4. 填表順序5. 返回值 [494. 目標和](https://leetcode.cn/proble…

解鎖 DevOps 新境界 :使用 Flux 進行 GitOps 現場演示 – 自動化您的 Kubernetes 部署

前言 GitOps 是實現持續部署的云原生方式。它的名字來源于標準且占主導地位的版本控制系統 Git。GitOps 的 Git 在某種程度上類似于 Kubernetes 的 etcd,但更進一步,因為 etcd 本身不保存版本歷史記錄。毋庸置疑,任何源代碼管理服務&#xf…

將Docker鏡像變為可執行文件?體驗docker2exe帶來的便捷!

在現代軟件開發中,容器化技術極大地改變了應用程序部署和管理的方式。Docker,作為領先的容器化平臺,已經成為開發者不可或缺的工具。然而,對于不熟悉Docker的用戶來說,接觸和運行Docker鏡像可能會是一個復雜的過程。為了解決這一問題,docker2exe項目應運而生。它提供了一…

IBM BAW(原BPM升級版)使用教程第八講

續前篇! 一、流程開發功能模塊使用邏輯和順序 前面我們已經對 流程、用戶界面、公開的自動化服務、服務、事件、團隊、數據、性能、文件各個模塊進行了詳細講解,現在統一進行全面統一講解。 在 IBM Business Automation Workflow (BAW) 中,…

針對共享內存和上述windows消息機制 在C++ 和qt之間的案例 進行詳細舉例說明

針對共享內存和上述windows消息機制 在C++ 和qt之間的案例 進行詳細舉例說明 以下是關于在 C++ 和 Qt 中使用共享內存(QSharedMemory)和 Windows 消息機制(SendMessage / PostMessage)進行跨線程或跨進程通信的詳細示例。 ?? 使用 QSharedMemory 進行進程間通信(Qt 示例…

jetson orin nano super AI模型部署之路(十)使用frp配置內網穿透,隨時隨地ssh到機器

為什么要內網穿透? 我們使用jetson設備時,一般都是在局域網內的電腦去ssh局域網內的jetson設備,但是這種ssh或者VNC僅限于局域網之間的設備。 如果你出差了,或者不在jetson設備的局域網內,想再去ssh或者VNC我們的jet…

VScode密鑰(公鑰,私鑰)實現免密登錄【很細,很全,附帶一些沒免密登錄成功的一些解決方法】

一、 生成SSH密鑰對 ssh-keygen 或者 ssh-keygen -t rsa -b 4096區別:-t rsa可以明確表示生成的是 RSA 類型的密鑰-b參數將密鑰長度設置為 4096 位默認:2048 位密鑰不指定-t參數,ssh -keygen默認也可能生成 RSA 密鑰【確保本機安裝ssh&#…

解釋器和基于規則的系統比較

解釋器(Interpreter)和基于規則的系統(Rule-Based System)是兩種不同的軟件架構風格,分別適用于不同的應用場景。它們在設計理念、執行機制和適用領域上有顯著差異。以下是它們的核心對比: 1. 解釋器&#…

DB4S:一個開源跨平臺的SQLite數據庫管理工具

DB Browser for SQLite(DB4S)是一款開源、跨平臺的 SQLite 數據庫管理工具,用于創建、瀏覽和編輯 SQLite 以及 SQLCipher 數據庫文件。 功能特性 DB4S 提供了一個電子表格風格的數據庫管理界面,以及一個 SQL 查詢工具。DB4S 支持…

printf調試時候正常,運行時打印不出來

問題是在添加了 printf 功能后,程序獨立運行時無法正常打印輸出,而調試模式下正常。這表明問題可能與 printf 的重定向實現、標準庫配置、或編譯器相關設置有關。 解決: 原來是使用 Keil/IAR,printf可能需要啟用 MicroLIB 或正確…

輕松制作高質量視頻,實時生成神器LTX-Video重磅登場!

探索LTX-Video:實時視頻生成跨越新高度 在如今這個視覺內容主導的數字時代,視頻生成成為推動創意表達的關鍵。而今天,我們將帶您深入探索LTX-Video,一個強大的開源項目,致力于通過尖端技術將視頻生成提升到一個全新的…