MYSQL 8 从metadata开始到如何获得语句由于获取锁失败的错误

本文探讨了MySQL中的元数据锁(metadatalock)及其在管理数据一致性中的作用,涉及创建删除索引、修改表结构等操作时的锁机制。通过查询信息_schema表可以发现长时间等待的事务,并通过特定SQL语句进行kill操作。此外,还提到了MySQL8.0后的prepare事务处理及错误日志在performance_schema中的记录,帮助用户监控和排查错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

3392b86ed38349494f9ed6c812568154.png

最近有同学提出,你的文字还OK,就是排版有问题,嗯,的确。我的排版的确是很烂,我也想改变,可能基于工作中的时间问题,以及学习的速度,让我实在是没有能力在排版上下功夫。希望哪位好心的同学,可以给我一个方法来提高排版,并且不要花太多的心思在这里面,谢谢。

接着上期,metadata lock 到底是一个什么东西,首先metadata lock 是MYSQL 来管理一致性访问以及确认数据一致性所做得一个工作。metadata lock不光是应用于表的层面,同时也应用于schema, triiger,scheduled,function等层面。

Metadata锁的意义在于MYSQL 不会随便让数据写入到metadata 中,他要做的是维护数据在表中的一致性,举例当有表的操作在修改 metadata 中的数据的情况下,未提交的事务,或者是回滚的事务都需要等待metadata lock中的锁释放后,才能进行后续的工作。

那么接下来的问题是,metadata lock的锁会在什么时候在MYSQL 中工作的问题,

1  创建或删除索引

2  修改表结构

3  在对表进行optimize table , repair table ,delete table , table lock 生效时,这些都触发了metadata lock

select concat('kill ',i.trx_mysql_thread_id,';') 

from information_schema.innodb_trx i,   

(select  id, time      

from  information_schema.processlist      

where    time = (select  max(time)             

 from   information_schema.processlist              

where  state = 'Waiting for table metadata lock'                      

and substring(info, 1, 5) in ('alter' , 'optim', 'repai', 'lock ', 'drop ', 'creat'))) p   

where timestampdiff(second, i.trx_started, now()) > p.time   and i.trx_mysql_thread_id  not in (connection_id(),p.id);

通过这个方式可以将长时间等待metadata lock 不工作的事务从数据库中找出来, 并产生一个kill 的语句。

那么下面有一个问题,如果对一个表的锁定的解锁顺序是如何的,当我们针对一个表进行了 X锁的加持,后面我们先进行了一个插入的操作,然后在进行对表的rename的操作, 此时真正的顺序应该是

1   X 锁定标

2   INSERT 

3   RENAME

————————

1  解除X锁

2  RENAME 

3  INSERT 

另外在MYSQL 8.013后MYSQL prepare 事务的问题,在客户端和数据库失联的情况下,用户的prepare状态会被保持直到XA_COMMIT 或者 XA_ROLLBACK

除了这个问题以外,就是关于如何发现曾经MYSQL 发生过错误,一般的情况MYSQL 5.X我们都是去找到ERROR LOG ,里面去找寻可能发生的信息,但是MYSQL 8 我们在performance_schema 中已经有了 events_errors 系列,这些表可以让你从各个层面来了解MYSQL 在最近都发生过什么错误。

1  event_error_summary_global_by_error

通过这个表,我们查看这个表可以记录的错误的种类有 5017种

select count(distinct error_name) from performance_schema.events_errors_summary_global_by_error;

3fac3f8a58213a9041d94b51f156376a.png

select * from performance_schema.events_errors_summary_global_by_error where error_name IN  ('ER_LOCK_WAIT_TIMEOUT','ER_LOCK_DEADLOCK','ER_LOCK_TABLE_FULL')\G

ac57bb2ef16e2e5dd78bef2e387e44de.png

在这个表里面分别有三个记录与我们日常所有关的方向,

'ER_LOCK_WAIT_TIMEOUT',   发生过程序block的情况

'ER_LOCK_DEADLOCK',          发生过程序死锁的情况

'ER_LOCK_TABLE_FULL'          发生过全表扫描的情况

select * from events_errors_summary_by_user_by_error where last_seen is not null;    以上的这个表,主要是从访问数据库的用户的角度来出发,查看这个用户曾经发生过什么样的错误,我们可以改写一下这个查询的语句,来更精确的对这个账号发生过什么错误进行判断。

00ef3abe3e0f7ef9e6bbc4e92a862b3b.png

select USER,ERROR_NAME,last_seen,sum_error_raised from events_errors_summary_by_user_by_error where SUM_ERROR_RAISED > 0 and error_name in ('ER_LOCK_WAIT_TIMEOUT','ER_LOCK_DEADLOCK','ER_LOCK_TABLE_FULL');

dc91974bec9024a99ae84c3313a374b9.png


上面的语句可以发现你最后一次产生查询问题的账号以及问题的原因,和发生的次数的递增,这里可以做定期的信息收集,然后对比同一个时期的信息差,来发现更多的问题。

30b40c7fe5ec64157b819b0928ab2fe8.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值