MySQL挂在ALTER TABLE上

时间:2016-12-09 00:34:43

标签: mysql mariadb

我的不太大的表挂在ALTER命令上。它可能是什么?

仅150k行,42个字段总计142 MByte。 InnoDB存储引擎和服务器版本:5.5.44-MariaDB MariaDB Server。 1个字段,' slotindex',是主键:bigint(20)和BTREE类型。

命令:

    MariaDB [mydb]> ALTER TABLE `runs` CHANGE `p_w_trans_x` `p_w_tran_x` FLOAT NOT NULL;
    Stage: 1 of 2 'copy to tmp table'   65.7% of stage done
    Stage: 2 of 2 'Enabling keys'      0% of stage done

在这个阶段2将永远完全挂起。

进程列表如下:

MariaDB [(none)]> show full processlist;
+--------+------+-----------------+-----------+---------+-------+---------------------------------+---------------------------------------------------------------------+----------+
| Id     | User | Host            | db        | Command | Time  | State                           | Info                                                                | Progress |
+--------+------+-----------------+-----------+---------+-------+---------------------------------+---------------------------------------------------------------------+----------+
| 274226 | root | localhost:45423 | edc_proxy | Sleep   | 16043 |                                 | NULL                                                                |    0.000 |
| 274319 | root | localhost       | myDB      | Query   |    99 | Waiting for table metadata lock | ALTER TABLE `runs` CHANGE `p_w_trans_x` `p_w_tran_x` FLOAT NOT NULL |    0.000 |
| 274416 | root | localhost       | NULL      | Query   |     0 | NULL                            | show full processlist                                               |    0.000 |
+--------+------+-----------------+-----------+---------+-------+---------------------------------+---------------------------------------------------------------------+----------+

这个answer建议检查information_schema表,而不是那里:

MariaDB [INFORMATION_SCHEMA]> SELECT * FROM INNODB_LOCK_WAITS;
Empty set (0.00 sec)

MariaDB [INFORMATION_SCHEMA]> SELECT * FROM INNODB_LOCKS ;
Empty set (0.00 sec)

MariaDB [INFORMATION_SCHEMA]> SELECT * FROM INNODB_TRX;
+----------+-----------+---------------------+-----------------------+------------------+------------+---------------------+-----------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+
| trx_id   | trx_state | trx_started         | trx_requested_lock_id | trx_wait_started | trx_weight | trx_mysql_thread_id | trx_query | trx_operation_state | trx_tables_in_use | trx_tables_locked | trx_lock_structs | trx_lock_memory_bytes | trx_rows_locked | trx_rows_modified | trx_concurrency_tickets | trx_isolation_level | trx_unique_checks | trx_foreign_key_checks | trx_last_foreign_key_error | trx_adaptive_hash_latched | trx_adaptive_hash_timeout |
+----------+-----------+---------------------+-----------------------+------------------+------------+---------------------+-----------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+
| 83A8B36E | RUNNING   | 2016-12-08 11:13:02 | NULL                  | NULL             |          0 |              274226 | NULL      | NULL                |                 0 |                 0 |                0 |                   376 |               0 |                 0 |                       0 | REPEATABLE READ     |                 1 |                      1 | NULL                       |                         0 |                     10000 |
+----------+-----------+---------------------+-----------------------+------------------+------------+---------------------+-----------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+
1 row in set (0.00 sec)

来自show engine innodb status;的交易部分:

------------
TRANSACTIONS
------------
Trx id counter 83A8F071
Purge done for trx's n:o < 83A8CA86 undo n:o < 0
History list length 1490
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0, not started
MySQL thread id 274543, OS thread handle 0x7fbb863e6700, query id 85356480 localhost root
show engine innodb status
---TRANSACTION 83A8EB07, not started
mysql tables in use 1, locked 2
MySQL thread id 274542, OS thread handle 0x7fbb843f6700, query id 85354935 localhost root Waiting for table metadata lock
ALTER TABLE `runs` CHANGE `p_w_trans_x` `p_w_tran_x` FLOAT NOT NULL
---TRANSACTION 83A8B36E, ACTIVE 24627 sec
MySQL thread id 274226, OS thread handle 0x7fbb845f5700, query id 85337236 localhost 127.0.0.1 root
Trx read view will not see trx with id >= 83A8B36F, sees < 83A8B36D
----------------------------
END OF INNODB MONITOR OUTPUT
============================

任何有关进一步调查,绕过问题和解决问题的建议都表示赞赏!

2 个答案:

答案 0 :(得分:2)

元数据锁是一种隐式(从用户角度来看)锁定,可防止DDL对表进行操作,因为其他东西需要表保留其当前形式。在这种情况下,它是一个已经运行的事务。

任务1:如果您在线程274226上终止连接,则您的alter将成功。

mysql> KILL 274226;

这里的问题,如information_schema.innodb_trx所示,是这个线程已经运行了几个小时的事务,我们可以推断该表已被该事务引用。在没有transactiom仍然具有MVCC视图或涉及该表的任何锁定之前,不能更改表。此事务包含一个视图,我们可以再次推断可能影响此表,如最后一行所示:

--TRANSACTION 83A8B36E, ACTIVE 24627 sec
MySQL thread id 274226, OS thread handle 0x7fbb845f5700, query id 85337236 localhost 127.0.0.1 root
Trx read view will not see trx with id >= 83A8B36F, sees < 83A8B36D

请注意,Sleep不是真正的命令,在此上下文中,它只是任何空闲连接的占位符状态。所有连接都在做某事,在这种情况下,“某事”正在休眠 - 换句话说,空闲并等待另一个查询。但是空闲连接仍然是一个连接,如果你的代码(或查询浏览器工具)让事务运行,它就会继续运行。

任务2:找到导致该事务运行的错误或错误。在实时应用程序中,让正在运行的事务可能会造成更大的混乱。

答案 1 :(得分:0)

我遇到了一个与表锁非常相似的问题,但最终它变成了 MySQL Workbench。 MySQL Workbench 中的任何 RENAME TABLEALTER TABLE 命令都只会要求元锁定。我登录到服务器并能够执行这些类型的查询没问题。当前版本的 Workbench 是 8.0.22

我已经筛选了所有这些查询,当它们没有显示任何问题时,我完全被难住了:

SHOW OPEN TABLES;

SHOW ENGINE inndodb STATUS;

SELECT * FROM INNODB_LOCK_WAITS;

SELECT * FROM INNODB_LOCKS;

SELECT * FROM INNODB_TRX;

SHOW FULL PROCESSLIST;