2016-12-09 3 views
3

Мой не очень большой стол висит над командой ALTER. Что бы это могло быть?MySQL зависает на ALTER TABLE

Только 150 тыс. Рядов, 42 поля 142 МБайт. Устройство хранения 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.

PROCESSLIST тогда следующим образом:

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 
============================ 

Любые указатели для дальнейшего исследования, для обхода этой проблемы и решения будут оценены!

+0

См. Http://stackoverflow.com/a/13155778/166339 – Asaph

+0

Я не уверен в MariaDB, но я знаю, что MySQL должен воссоздать всю таблицу, когда вы делаете большинство 'ALTER's; индексы не будут иметь значения. Если что-то еще обращается к таблице или удерживает на ней блокировку, например, незафиксированную транзакцию, то, что связало выше, что Асаф должен был найти, поможет вам ее найти. – Uueerdo

+0

@Asaph @Uueerdo Спасибо за ваши комментарии, я отредактировал вопрос, чтобы включить эти предложения. Никакие другие процессы не выполняются или не блокируются в таблице, 'show process list;' также отражают это или могут быть скрыты где-то в другом месте? – Bastiaan

ответ

0

Блокировка метаданных является неявной (с точки зрения пользователя) блокировкой, которая предотвращает DDL против таблицы, поскольку что-то еще нуждается в том, чтобы таблица оставалась в ее текущей форме. В этом случае это транзакция, которая была оставлена.

Задача 1: Ваш альтер будет успешным, если вы убиваете соединение на резьбе 274226.

mysql> KILL 274226; 

Проблема здесь, как указано information_schema.innodb_trx, что этот поток оставил сделку работает в течение нескольких часов и мы можем заключить, что эта таблица была указана этой транзакцией. Таблица не может быть изменена, пока никакие транзакции не будут иметь вид 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: найти ошибку или ошибку, оставившие эту транзакцию. В реальном приложении, оставляя транзакции, потенциально могут стать намного более сложными.