MYSQL刪除視圖時視圖被lock的解決方案
背景
mysql 8.0 刪除視圖時 DROP VIEW dev_licos_kmlc_yt.view_pro_product_distribution_cathode_copper_details_v2 報錯? Waiting for table metadata lock
解決方案
你在 MySQL 8.0 中執(zhí)行 DROP VIEW 時遇到 “Waiting for table metadata lock” 錯誤,說明該視圖(或其依賴的表)當前被其他會話持有元數(shù)據(jù)鎖(metadata lock),導(dǎo)致你的 DROP 操作被阻塞。
原因分析
在 MySQL 中,任何對表結(jié)構(gòu)或視圖的操作(如 DROP、ALTER、CREATE)都需要獲取元數(shù)據(jù)鎖(MDL) 。如果另一個會話正在:
- 執(zhí)行一個長時間運行的查詢(SELECT/INSERT/UPDATE/DELETE)涉及該視圖或其基表;
- 開啟了一個事務(wù)但未提交,并且事務(wù)中使用了該視圖或相關(guān)表;
- 正在執(zhí)行 DDL(如 ALTER TABLE)等操作;
那么你的 DROP VIEW 就會一直等待,直到那個會話釋放鎖。
注意:即使視圖本身不包含數(shù)據(jù),只要它引用的基表被鎖定,DROP VIEW 也會被阻塞。
解決方法
1.查找阻塞的會話
登錄 MySQL,執(zhí)行以下語句查看當前元數(shù)據(jù)鎖等待情況:
SELECT * FROM performance_schema.metadata_locks WHERE OBJECT_SCHEMA = 'dev_licos_kmlc_yt' AND OBJECT_NAME = 'view_pro_product_distribution_cathode_copper_details_v2';
或者更通用的方式:查看所有等待或持有 MDL 的線程:
SELECT
r.trx_id waiting_trx_id,
r.trx_mysql_thread_id waiting_thread,
r.trx_query waiting_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;
注意:上面這個查的是 InnoDB 行鎖,不一定適用于元數(shù)據(jù)鎖。更準確的是用 performance_schema:
-- 啟用 performance_schema(默認已啟用)
SELECT
pl.processlist_id AS blocked_pid,
pl.info AS blocked_sql,
ml.lock_type,
ml.lock_status,
ml.owner_thread_id
FROM
performance_schema.metadata_locks ml
JOIN
performance_schema.threads t ON ml.owner_thread_id = t.thread_id
JOIN
information_schema.processlist pl ON t.processlist_id = pl.id
WHERE
ml.object_schema = 'dev_licos_kmlc_yt'
AND ml.object_name = 'view_pro_product_distribution_cathode_copper_details_v2'
AND ml.lock_status = 'PENDING';
也可以直接看誰持有該對象的鎖:
SELECT
pl.id AS process_id,
pl.user,
pl.host,
pl.db,
pl.command,
pl.time AS duration_seconds,
pl.state,
pl.info AS current_sql
FROM
performance_schema.metadata_locks ml
JOIN
performance_schema.threads t ON ml.owner_thread_id = t.thread_id
JOIN
information_schema.processlist pl ON t.processlist_id = pl.id
WHERE
ml.object_schema = 'dev_licos_kmlc_yt'
AND ml.object_name = 'view_pro_product_distribution_cathode_copper_details_v2'
AND ml.lock_status = 'GRANTED';
2.終止阻塞的會話
找到阻塞的 process_id(即 pl.id),然后 kill 它:
KILL <process_id>;
例如:
KILL 12345;
謹慎操作!確保該會話可以被安全終止(比如是空閑連接、測試查詢等)。
3.預(yù)防措施
- 避免在業(yè)務(wù)高峰期執(zhí)行 DDL(包括 DROP VIEW)。
- 確保應(yīng)用中的事務(wù)及時提交,不要長時間開啟事務(wù)。
- 對于只讀查詢,盡量使用短連接或設(shè)置
autocommit=1。 - 監(jiān)控長時間運行的查詢:
SHOW PROCESSLIST;
補充說明
- 視圖本身不存儲數(shù)據(jù),但 MySQL 在 DROP VIEW 時仍需檢查其定義和依賴關(guān)系,因此需要對基表加共享元數(shù)據(jù)鎖。
- 即使視圖未被直接使用,只要其基表被某個會話鎖定,DROP VIEW 也可能被阻塞。
總結(jié)
你遇到的問題是典型的 元數(shù)據(jù)鎖等待。解決步驟:
- 使用
performance_schema.metadata_locks找出誰持有了鎖; - 通過
information_schema.processlist找到對應(yīng)會話 ID; - 必要時
KILL阻塞會話; - 再次執(zhí)行
DROP VIEW。
我使用的的是這個語句:
SELECT
pl.id AS process_id,
pl.user,
pl.host,
pl.db,
pl.command,
pl.time AS duration_seconds,
pl.state,
pl.info AS current_sql
FROM
performance_schema.metadata_locks ml
JOIN
performance_schema.threads t ON ml.owner_thread_id = t.thread_id
JOIN
information_schema.processlist pl ON t.processlist_id = pl.id
WHERE
ml.object_schema = 'dev_licos_kmlc_yt'
AND ml.object_name = 'view_pro_product_distribution_cathode_copper_details_v2'
AND ml.lock_status = 'GRANTED';
然后查詢出process_id,最終使用kill把阻塞會話殺掉,問題解決。
以上就是MYSQL刪除視圖時視圖被lock的解決方案的詳細內(nèi)容,更多關(guān)于MYSQL刪除視圖時視圖被lock的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
MySQL數(shù)據(jù)庫中刪除重復(fù)記錄簡單步驟
這篇文章主要給大家介紹了關(guān)于MySQL數(shù)據(jù)庫中刪除重復(fù)記錄的相關(guān)資料,在使用數(shù)據(jù)庫時,出現(xiàn)重復(fù)數(shù)據(jù)是常有的情況,但有些情況是允許數(shù)據(jù)重復(fù)的,而有些情況是不允許的,當出現(xiàn)不允許的情況,我們就需要對重復(fù)數(shù)據(jù)進行刪除處理,需要的朋友可以參考下2023-08-08
淺談訂單重構(gòu)之 MySQL 分庫分表實戰(zhàn)篇
這篇文章主要介紹了 MySQL 分庫分表方法的相關(guān)資料,需要的朋友可以參考下面文章內(nèi)容,希望能幫助到你2021-09-09
Mysql中DATEDIFF函數(shù)的基礎(chǔ)語法及練習(xí)案例
Datediff函數(shù),最大的作用就是計算日期差,能計算兩個格式相同的日期之間的差值,下面這篇文章主要給大家介紹了關(guān)于Mysql中DATEDIFF函數(shù)的基礎(chǔ)語法及練習(xí)案例?的相關(guān)資料,需要的朋友可以參考下2022-09-09
解決Node.js mysql客戶端不支持認證協(xié)議引發(fā)的問題
這篇文章主要介紹了解決Node.js mysql客戶端不支持認證協(xié)議引發(fā)的問題,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,,需要的朋友可以參考下2019-06-06

