显示 metadata lock 信息的 mysql 插件

有一回碰上在 mysql 5.5 中,一些表没法执行 DDL ,会一直被阻塞住。show processlist 会看到

mysql> show full processlist;
+----+------+-----------------+------+---------+------+---------------------------------+-----------------------+
| Id | User | Host            | db   | Command | Time | State                           | Info                  |
+----+------+-----------------+------+---------+------+---------------------------------+-----------------------+
...
|  6 | root | localhost:56841 | test | Query   |    0 | init                            | show full processlist |
|  7 | root | localhost:56843 | test | Query   |   13 | Waiting for table metadata lock | rename table u to uu  |
...
+----+------+-----------------+------+---------+------+---------------------------------+-----------------------+

可以看出,是被一个 metadata lock 阻塞住了。但是从 process list 里是没法看出是哪个线程持有了这个锁。用别的方式,也只能得到通过 lock table 方式获取的锁或 innodb 事务的信息。对于一些比较隐蔽的方式,比如

mysql> begin;
mysql> select * from test.u;

这样也同样会获取 metadata lock 。在 autocommit 为 0 的时候,没有显式 begin 也是如此。这类情况没法从任何途径获取究竟是谁上了锁。

于是我就试着做了一个 mysql 的 information schema 插件。 https://github.com/xiezhenye/mysql-plugin-mdl-info 安装后,只要 select * from information_schema.MDL_INFO 就可以获取到所有 metadata lock ,也就是 mdl 的信息。

mysql> select * from information_schema.MDL_INFO;
+-----------+-------------+---------------------+-----------+----------+------+
| THREAD_ID | DURATION    | TYPE                | NAMESPACE | DATABASE | NAME |
+-----------+-------------+---------------------+-----------+----------+------+
|         7 | STATEMENT   | INTENTION_EXCLUSIVE | GLOBAL    |          |      |
|         7 | TRANSACTION | SHARED_WRITE        | TABLE     | test     | t    |
+-----------+-------------+---------------------+-----------+----------+------+
2 rows in set (0.00 sec)

在写这个插件的时候,发现 mysql 把 mdl lock 的信息封装的相当严密,即使是写插件也没法用常规途径获取。只好用了一些很恶心的技巧。如果各位有碰到类似的问题,也可以先在测试环境试试。

6 thoughts on “显示 metadata lock 信息的 mysql 插件

  1. 黄华亮

    您好!我安装mysql-plugin-mdl-locks 时报错如下:
    [root@MYSQL-YZH-6241 mysql-5.5.36]# cmake . -DBUILD_CONFIG=mysql_release
    CMake Error: The source directory “/export/servers/app/mysql-5.5.36” does not appear to contain CMakeLists.txt.
    Specify –help for usage, or press the help button on the CMake GUI.

    求指教!!!谢谢!

    Reply
      1. 神仙 Post author

        现在带了一个构建脚本 scripts/build_for.sh 。可以自动下载源代码包编译。

        Reply
        1. 风暴

          在mysql 5.6.16 版本下安装报错:
          mysql> INSTALL PLUGIN MDL_LOCKS SONAME ‘mdl_info.so’;
          ERROR 1126 (HY000): Can’t open shared library ‘/home/mysql/mysql/lib/plugin/mdl_info.so’ (errno: 2 /home/mysql/mysql/lib/plugin/mdl_info.so: undefined symbol: my_pthread_fastmutex_init)

          Reply
          1. 神仙 Post author

            如果你的mysql是以源代码编译出的debug版本,那编译插件的时候不要加 -DBUILD_CONFIG=mysql_release

  2. 风暴

    非常感谢老师您的解答,目前已正常安装。
    不过:
    mysql> INSTALL PLUGIN MDL_info SONAME ‘mdl_info.so’;plugin名字需要指定为MDL_INFO,而非文档中的MDL_LOCKS,因为cmakelists.txt里面的是MDL_INFO

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *