简体   繁体   English

MySQL InnoDB 挂起等待表级锁

[英]MySQL InnoDB hangs on waiting for table-level locks

I have a big production web-application (Glassfish 3.1 + MySQL 5.5).我有一个大型生产网络应用程序(Glassfish 3.1 + MySQL 5.5)。 All tables are InnoDB.所有表都是 InnoDB。 Once per several days application totally hangs.每几天一次应用程序完全挂起。 SHOW FULL PROCESSLIST shows many simple insert or update queries on different tables but all having status SHOW FULL PROCESSLIST在不同的表上显示许多简单的插入或更新查询,但都具有状态

Waiting for table level lock等待表级锁

Examples:例子:

update user<br>
set user.hasnewmessages = NAME_CONST('in_flag',_binary'\0' COLLATE 'binary')
where user.id = NAME_CONST('in_uid',66381)

insert into exchanges_itempacks
set packid = NAME_CONST('in_packId',332149), type = NAME_CONST('in_type',1), itemid = NAME_CONST('in_itemId',23710872)

Queries with the longest 'Time' are waiting for the table-level lock too.具有最长“时间”的查询也在等待表级锁。 Please help to figure out why MySQL tries to get level lock and what can be locking all these tables.请帮助弄清楚为什么 MySQL 试图获得级别锁定以及什么可以锁定所有这些表。 All articles about the InnoDB locking say this engine uses no table locking if you don't force it to do so.所有关于 InnoDB 锁定的文章都说如果你不强制它这样做,这个引擎不使用表锁定。

My my.cnf has this:我的my.cnf有这个:

innodb_flush_log_at_trx_commit = 0
innodb_support_xa = 0
innodb_locks_unsafe_for_binlog = 1
innodb_autoinc_lock_mode=2

Binary log is off.二进制日志已关闭。 I have no "LOCK TABLES" or other explicit locking commands at all.我根本没有“LOCK TABLES”或其他显式锁定命令。 Transactions are READ_UNCOMMITED .交易是READ_UNCOMMITED

SHOW ENGINE INNODB STATUS output: http://avatar-studio.ru:8080/ph/imonout.txt SHOW ENGINE INNODB STATUS output: http://avatar-studio.ru:8080/ph/imonout.txt

Are you using MSQLDump to backup your database while it is still being accessed by your application?您是否在应用程序仍在访问数据库时使用 MSQLDump 备份数据库? This could cause that behaviour.这可能会导致这种行为。

I think there are some situations when MySQL does a full table lock (ie using auto-inc).我认为在某些情况下,MySQL 会执行全表锁定(即使用 auto-inc)。 I found a link which may help you: http://mysqldatabaseadministration.blogspot.com/2007/06/innodb-table-locks.html我找到了一个可以帮助你的链接: http://mysqldatabaseadministration.blogspot.com/2007/06/innodb-table-locks.html

Also review java persistence code having all con's commited/rollbacked and closed.另请查看 java 持久性代码,其中所有 con 的提交/回滚和关闭。 (Closing always in finally block.) (总是在 finally 块中关闭。)

Try setting innodb_table_locks=0 in MySQL configuration.尝试在 MySQL 配置中设置innodb_table_locks=0 http://dev.mysql.com/doc/refman/5.0/en/innodb-parameters.html#sysvar_innodb_table_locks http://dev.mysql.com/doc/refman/5.0/en/innodb-parameters.html#sysvar_innodb_table_locks

Just a few ideas...只是一些想法...

I see you havily use NAME_CONST in your code.我看到您在代码中频繁使用 NAME_CONST。 Just try not to use it.尽量不要使用它。 You know, mysql can be sometimes buggy (I also found several bugs), so I recommend don't rely on features which are not so common / well tested.你知道,mysql 有时可能会出现错误(我也发现了几个错误),所以我建议不要依赖不太常见/经过良好测试的功能。 It is related to column names, so maybe it locks something?它与列名有关,所以也许它锁定了一些东西? Well it should't if it affects only the result, but who knows?好吧,如果它只影响结果,它不应该,但谁知道呢? This is suspicious.这是可疑的。 Moreover, this is marked as a function for internal use only.此外,这被标记为 function 仅供内部使用。

This may seem simple, but you don't have a long-running select statement that is possibly locking out updates and inserts?这可能看起来很简单,但是您没有可能锁定更新和插入的长期运行的 select 语句? There's no query that's actually running and not locked?没有实际运行且未锁定的查询?

Have you considered using MyISAM instead of InnoDB?您是否考虑过使用 MyISAM 代替 InnoDB?

If you are not utilizing any transactional features, MyISAM might make more sense.如果您没有使用任何事务功能,MyISAM 可能更有意义。 Its simpler, easier to optimize, and since it doesn't have sophisticated transactional capabilities, easier to configure in your my.cnf.它更简单,更易于优化,并且由于它没有复杂的事务功能,因此更易于在您的 my.cnf 中进行配置。

Also, depending on the type of db load your app creates, MyISAM might be more appropriate.此外,根据您的应用程序创建的数据库负载类型,MyISAM 可能更合适。 I prefer MyISAM for read-heavy applications, again, it's easier to configure and understand.我更喜欢 MyISAM 用于读取繁重的应用程序,同样,它更易于配置和理解。

Other suggestions:其他建议:

  • It might be a good idea to find a way to not use NAME_CONST in your SQL .找到一种不在 SQL 中使用 NAME_CONST 的方法可能是个好主意。 "This function was added in MySQL 5.0.12. It is for internal use only." “此 function 是在 MySQL 5.0.12 中添加的。仅供内部使用。” When the documentation of an open source product says this, its probably a good idea to heed it's advise.当开源产品的文档这样说时,听从它的建议可能是个好主意。

  • By default, MySQL stores all InnoDB tables & schemas data in 1 enormous file, there could be some kind of OS level locking on that particular file that propogates to MySQL that prevents all table access.默认情况下,MySQL 将所有 InnoDB 表和模式数据存储在 1 个巨大的文件中,该特定文件上可能存在某种操作系统级别的锁定,该特定文件会传播到 MySQL,从而阻止所有表访问。 By using the innodb_file_per_table option, you may eliminate that potential issue.通过使用innodb_file_per_table选项,您可以消除该潜在问题。 This also makes MySQL more space efficient.这也让 MySQL 更节省空间。

in this case you have to create several different database table with same column each other and do not inset more then 3000 row per table, in this case if you want to enter more data into table you have to create another dynamic table(generate table using code) and insert new data into this table and access data from that table.在这种情况下,您必须创建几个具有相同列的不同数据库表,并且每个表不要插入超过 3000 行,在这种情况下,如果您想在表中输入更多数据,您必须创建另一个动态表(使用生成表代码)并将新数据插入此表并访问该表中的数据。 in your condition if more and more table will have to generate then you have to create new database.在您的情况下,如果必须生成越来越多的表,那么您必须创建新数据库。

i think this tip will help you to design your database more carefully and solve error.我认为这个技巧将帮助您更仔细地设计数据库并解决错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM