1.背景
研发同事查询electric_invoice表数据,在商用产生大量的该表的慢查询。由于是慢查询所以找DBA添加 索引。添加索引和线上慢查询同时执行导致,慢查询处于《Waiting for table metadata lock》错误中。
当时用户无法支付,支付回调慢等情况。这种情况持续30分钟左右。用户投诉也蜂拥而至。
2.读库上,show processlist 出现大量的 Waiting for table metadata lock。
数据库实例是1个主库,3个读库。主库dml操作将同步到读库。事务走主库,查询走读库。
3.慢查询在读库,索引执行在主库。主库执行成功。读库上,同步索引与数据库慢查询进行冲突。查询将产生Waiting for table metadata lock。DBA主库上执行索引添加后,静等同步到从库。但是该表的慢查询不断。
4.假设Mysql,在查询的时候,发现索引正在建立,会不会等待索引建立完毕后开始使用索引,进行查询。如果不用索引则数据上查询遍历即可。
5.假设Mysql,在表上执行ddl操作的时候,所有读和写均应该停止。如果这个表的记录数很大,大到几千万级别,索引添加这个操作需要一定时间,但是也不会超过5分钟吧。
6.表上执行索引的时候,如果有事务,那么主库上执行也会受影响,DBA会执行的第一时间将发现危险。所以主库执行索引是没问题。
7.这次慢查询产生是从读库产生的,所以关闭慢查询产生的读库实例3。慢查询没有了。同时关闭其他2个读库。读库同步主库的索引完成以后,接口应用的查询。不会再查询出现《Waiting for table metadata lock》错误。