【问题标题】:Waiting for table level lock on a MySQL table等待 MySQL 表上的表级锁定
【发布时间】:2014-05-13 14:49:07
【问题描述】:

最近几天,我的网站有时变得很慢。我开始尽我所能进行调查。我看到 MySQL 进程正在使用我服务器 85 - 95% 的可用内存(我是否也应该升级我的内存?)。

我检查了我的 MySQL 进程日志,我注意到一个巨大的查询列表:

等待表级锁

但我还注意到,所有这些带有“表级锁定”的查询只是与我的名为 users 的表有关的查询。

我有 20 个其他表,有不断的查询,但我没有在列表中看到它们。所以我猜问题出在 users 表上?

我想知道如何改进表,并最终解除表级锁?

我也跑了这个:

SHOW VARIABLES LIKE 'query_cache%';

这导致了:

query_cache_limit
1048576
query_cache_min_res_unit
4096
query_cache_size
33554432
query_cache_type
ON
query_cache_wlock_invalidate
OFF

请让我知道我可以做些什么来改进我的数据库/mysql。

这是进程列表:

   | 228 | db_user | localhost | db_db| Query          |    5 | Waiting for table level lock | SELECT count(*) FROM users WHERE createtime>'1396411200' OR createtime='1396411200'                  |
    | 229 | db_user | localhost | db_db| Query          |    4 | Waiting for table level lock | UPDATE users SET upline_clicks=upline_clicks+'1', upline_earnings=upline_earnings+'0.0000' WHERE use |
| 203 | db_user | localhost | db_db| Query          |    6 | Waiting for table level lock | SELECT SUM(cashedout) FROM users                                                                     |
| 204 | db_user | localhost | db_db| Query          |    4 | Waiting for table level lock | UPDATE users SET upline_clicks=upline_clicks+'1', upline_earnings=upline_earnings+'0.0000' WHERE use |
| 205 | db_user | localhost | db_db| Query          |    1 | Waiting for table level lock | SELECT * FROM users WHERE id='12055'                                                                 |
| 206 | db_user | localhost | db_db| Query          |    2 | Waiting for table level lock | SELECT * FROM users WHERE id='22530'                                                                 
| 197 | db_user | localhost | db_db| Query          |    3 | Waiting for table level lock | SELECT * FROM `users` WHERE `username` = 'ptc4life123' LIMIT 1                                       |
| 200 | db_user | localhost | db_db| Query          |    3 | Waiting for table level lock | UPDATE users SET upline_clicks=upline_clicks+'1', upline_earnings=upline_earnings+'0.0050' WHERE use |

这基本上就是所有锁定进程的样子。

【问题讨论】:

  • 开始为用户添加索引,特别是用户姓氏、部门、ID等字段......查询中经常使用的任何内容。
  • 索引?想详细说明一下吗? (对不起,我对 MySQL 还是很陌生)

标签: mysql sql innodb myisam


【解决方案1】:

在一个缓慢的时期,运行这个命令:

show processlist;

这将向您显示正在运行的实际 SQL 命令,以及在添加索引方面要查找的位置。如果可能,发布运行时间最长的 SQL。

添加索引将如下所示:

 ALTER TABLE MYTABLE ADD INDEX idx_columnname (COLUMN_NAME ASC) ;

但您要小心,不要在制作期间这样做。乍一看,您希望在用户表中的 ID 和用户名列上执行此操作。

【讨论】:

  • 请查看我更新的问题。我已经包含了一个缓慢进程的列表。
  • 太棒了。当你运行它时,这个数字是多少?从用户中选择计数(*)
  • 好的。最有可能在 10 秒内创建索引。
  • 所以我应该在“ID”和“用户名”上创建索引? ALTER TABLE users ADD INDEX id (COLUMN_NAME ASC); AND ALTER TABLE 用户添加索引用户名(COLUMN_NAME ASC);对吗?
  • 关闭。你想要这个:ALTER TABLE users ADD INDEX idx_id (ID ASC); AND ALTER TABLE users ADD INDEX idx_username (username ASC);
【解决方案2】:

检查表的存储引擎。如果可能,请更改为 Innodb,因为它只会导致行级锁定。 即使您使用的是 innodb 表,正在运行的查询也可能会强制表锁定 如果您不使用索引。

【讨论】:

  • 你能不能多解释一下“索引”。我应该如何使用它们?
  • Index 是指向数据的指针。它将是一棵二叉树(最常见),将整行作为叶节点。例如,主键是指向单行的索引。不同之处在于它将被排序,这样您就不必去进行全表扫描来获取数据。
  • 如果你没有建立索引,那么它将像整个表被锁定一样工作,因为它正在执行全表扫描而不是索引扫描。
  • 哦,好吧.. 我应该只在表格的 1 行上使用 INDEX 吗? (例如“用户 ID”)
猜你喜欢
  • 1970-01-01
  • 2011-09-05
  • 1970-01-01
  • 2017-10-29
  • 1970-01-01
  • 1970-01-01
  • 2021-04-12
  • 1970-01-01
  • 2011-01-07
相关资源
最近更新 更多