我注意到,当执行一个苛刻的请求时,我们的应用程序不会响应请求。运行top
似乎可以找出问题的根源:
top - 13:54:25 up 1 day, 13:43, 2 users, load average: 1.02, 0.98, 0.83
Tasks: 110 total, 1 running, 109 sleeping, 0 stopped, 0 zombie
Cpu(s): 11.9%us, 1.1%sy, 0.0%ni, 86.8%id, 0.0%wa, 0.0%hi, 0.0%si, 0.2%st
Mem: 3145728k total, 2329220k used, 816508k free, 0k buffers
Swap: 131072k total, 128164k used, 2908k free, 1585060k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
26073 mysql 20 0 397m 209m 3452 S 99.1 6.8 3:02.49 mysqld
16419 mailnull 20 0 9848 3288 2664 S 2.3 0.1 1:17.63 exim
2085 nobody 20 0 44312 10m 3436 S 1.3 0.3 4:50.98 litespeed
24727 nobody 20 0 320m 50m 41m S 0.3 1.7 0:06.86 lsphp5
26314 root 20 0 2428 1104 832 S 0.3 0.0 0:00.36 top
在我看来,mysql 占用了它所运行的整个 CPU(99.1%)。这意味着我们的一个核心被固定在 100%,而其他 7 个(七个!)处于空闲状态,处于 0%。
我理解,如果我们的表是 InnoDB,负载将分布在核心之间。这是正确的吗?
有没有什么办法可以将工作负载分配到使用 MyISAM 的表的核心之间?
我是不是完全找错了地方?虽然资源密集型查询占用了一个 CPU,但 MySQL 难道不能利用其他 CPU 来执行单独的查询吗?或者,这是否受到我们对 MyISAM 的使用限制?
答案1
您对 InnoDB 以及负载在更多核心之间分配的理解是错误的,但很接近。
MyISAM 表执行“基于表的锁定”,这意味着锁定表的任何查询必然会阻止所有需要获取锁的其他查询。
InnoDB 对大多数操作使用“基于行的锁定”,这允许不需要锁定该精确行的其他查询继续并行执行。
无论是 MyISAM 还是 InnoDB,一个单一的大型查询仍然只会使用一个核心,但是命中同一张表的多个查询应该能够在不同的核心上同时执行,只要它们没有被行级锁阻止。