Mysql 内存表获得很多锁

Mr.*_*oon 4 mysql innodb optimization memory

在我的网站上,我在一个简单的 mysql 表中记录每个综合浏览量(日期、IP、引用、页面等)。

该表具有以下活动:

  • SELECT每分钟1个
  • DELETE每分钟1个
  • 没有UPDATE查询
  • 很多INSERTS(大约每秒 300 个)。

该表永远不会大于 200MB。

今天,我将这个表从 InnoDB 表更改为 MEMORY 表,这对我来说是有意义的,以防止不必要的硬盘 IO。我还每分钟修剪一次这张桌子,以确保它永远不会变得太大。而且这个信息不是很重要,所以在 MySQL 重启时删除它并不重要。

——

性能方面,一切都运行良好。但是我注意到在运行 tuning-primer 时,使用 MEMORY 表时我的当前锁定等待率非常高。

Current Lock Wait ratio = 1 : 561
Run Code Online (Sandbox Code Playgroud)

如果我将此表更改为 InnoDB,则比率为:

Current Lock Wait ratio = 0 : 78600946
Run Code Online (Sandbox Code Playgroud)

我的问题:我应该担心这个锁定等待率吗?有什么我可以改变我的配置来改进的东西,以便使用 MEMORY 表的锁定等待率不会那么高?

Rol*_*DBA 8

关于使用MEMORY 存储引擎,您必须牢记两个主要方面

方面#1

MEMORY 表的行为类似于 MyISAM 表,因为它在执行 INSERT、UPDATE 和 DELETE 时执行全表锁定(MySQL 文档说锁定粒度:表)。如果高锁定率会阻碍您的 I/O 性能,我会非常担心。如果每秒有 300 个 INSERT 到达此表,您可以完全确信每秒将有 300 个完整的表锁。

方面#2

无论你加载多少数据到 MEMORY 表中,mysqld 总是会联系 MEMORY 表的 .frm 文件以在查询解析之前验证该表的存在。尽管 .frm 不是一个大文件,但它会产生非常少量的磁盘 I/O。对 MEMORY 表的数千次甚至数百次查询可以揭示显着的,甚至是大量的磁盘 I/O。

由于 MEMORY 存储引擎就是这种情况,因此您还必须避免使用MyISAM,因为它具有相同的锁定粒度(Full Table Locking)。

这是我的建议

推荐#1

清理 InnoDB 使其启用 innodb_file_per_table

推荐#2

使用大型 InnoDB 缓冲池

由于表是200MB,你可以把InnoDB Buffer Pool做大5倍(需要重启)

[mysqld]
innodb_buffer_pool_size=1G
Run Code Online (Sandbox Code Playgroud)

推荐#3

升级到 MySQL 5.5 以便为 InnoDB 使用多个 CPU 的多线程读取和写入。如果您有 InnoDB 5.1.38+ 并且正在使用 InnoDB 插件,那么为 InnoDB 使用多个 CPU 的相同选项已经存在。

推荐#4

常识告诉我建议将表转回 InnoDB