我有一个超过160百万条目的表,它有一个错误的表引擎,所以我要改变引擎.
当我这样做而没有任何准备时,由于我的缓冲区大小,我得到一个错误,因为行锁太多
mysql> ALTER TABLE foobar ENGINE=MyISAM;
ERROR 1206 (HY000): The total number of locks exceeds the lock table size
我现在想要在此操作之前锁定整个表,然后解锁整个表.
mysql> LOCK TABLES foobar WRITE;
我的问题:mysql服务器是否注意到表锁已经处于活动状态并跳过行锁或让它锁定表,现在还会再次锁定每一行,我将再次遇到相同的错误?
我也开放任何其他sugestions如何以最快的方式改变这样一个大(和更大)表的引擎:)
解决方法:
你可以运行一个实验:
在第一次运行中:
mysql> LOCK TABLE foobar WRITE;
mysql> ALTER TABLE foobar ENGINE=MyISAM;
在第二个会话中(即打开第二个终端窗口),运行:
mysql> SHOW ENGINE INNODB STATUS\G
在TRANSACTIONS部分中,您将找到正在进行的ALTER线程:
---TRANSACTION 69638, ACTIVE 45 sec fetching rows
mysql tables in use 1, locked 1
14626 lock struct(s), heap size 1898936, 5145657 row lock(s)
哇!尽管LOCK TABLE有效,它仍会创建许多单独的行锁.
(这只是一个例子;当ALTER TABLE在你的表中工作时,你会看到行锁的数量随着时间的推移而增加.)
因此,您需要为大量行锁保证空间.
https://dev.mysql.com/doc/refman/5.6/en/innodb-error-codes.html说:
1206 (ER_LOCK_TABLE_FULL)
The total number of locks exceeds the amount of memory InnoDB devotes to managing locks. To avoid this error, increase the value of
innodb_buffer_pool_size
. Within an individual application, a workaround may be to break a large operation into smaller pieces. For example, if the error occurs for a largeINSERT
, perform several smallerINSERT
operations.
(强调我的)
另请阅读How much memory Innodb locks really take?
Innodb row level locks are implemented by having special lock table, located in the buffer pool where small record allocated for each hash and for each row locked on that page bit can be set. This in theory can give overhead as low as few bits per row.
因此锁定1.6亿行需要锁表中大约60-80MB的空间.您的缓冲池可能太小而无法容纳.
在MySQL 5.1.27及更早版本中,InnoDB缓冲池的默认大小仅为8MB. MySQL 5.1.28中的默认值增加到128MB.
你的评论:
every tool does its job ey