当前位置: 代码网 > it编程>数据库>Mysql > MYSQL删除视图时视图被lock的解决方案

MYSQL删除视图时视图被lock的解决方案

2026年01月14日 Mysql 我要评论
背景mysql 8.0 删除视图时 drop view dev_licos_kmlc_yt.view_pro_product_distribution_cathode_copper_details_v

背景

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 中执行 drop view 时遇到 “waiting for table metadata lock” 错误,说明该视图(或其依赖的表)当前被其他会话持有元数据锁(metadata lock),导致你的 drop 操作被阻塞。

原因分析

在 mysql 中,任何对表结构或视图的操作(如 drop、alter、create)都需要获取元数据锁(mdl) 。如果另一个会话正在:

  • 执行一个长时间运行的查询(select/insert/update/delete)涉及该视图或其基表;
  • 开启了一个事务但未提交,并且事务中使用了该视图或相关表;
  • 正在执行 ddl(如 alter table)等操作;

那么你的 drop view 就会一直等待,直到那个会话释放锁。

注意:即使视图本身不包含数据,只要它引用的基表被锁定,drop view 也会被阻塞。

解决方法

1.查找阻塞的会话

登录 mysql,执行以下语句查看当前元数据锁等待情况:

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 行锁,不一定适用于元数据锁。更准确的是用 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.预防措施

  • 避免在业务高峰期执行 ddl(包括 drop view)。
  • 确保应用中的事务及时提交,不要长时间开启事务。
  • 对于只读查询,尽量使用短连接或设置 autocommit=1
  • 监控长时间运行的查询:show processlist;

补充说明

  • 视图本身不存储数据,但 mysql 在 drop view 时仍需检查其定义和依赖关系,因此需要对基表加共享元数据锁。
  • 即使视图未被直接使用,只要其基表被某个会话锁定,drop view 也可能被阻塞。

总结

你遇到的问题是典型的 元数据锁等待。解决步骤:

  1. 使用 performance_schema.metadata_locks 找出谁持有了锁;
  2. 通过 information_schema.processlist 找到对应会话 id;
  3. 必要时 kill 阻塞会话;
  4. 再次执行 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的解决方案的详细内容,更多关于mysql删除视图时视图被lock的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com