1
Livid MOD 服务器内存不够。
|
2
fire9 2014-01-09 13:07:36 +08:00
140109 11:26:10 InnoDB: Initializing buffer pool, size = 180.0M 如果你用innodb 这个值简直就不可想象啊!
|
4
guoqiao OP @fire9 太少了吗, 能否说详细点? 因为之前经常出现因为内存不足导致数据库 crash 后无法恢复的情况, 于是我就把这个值调小了. 我用 mysqltunner 检测了下, 貌似这项提示是 OK 的.
|
5
cloud107202 2014-01-09 14:17:51 +08:00
曾遇到过类似的情况,对mysql不是很懂,把当时的步骤总结一下,希望帮到楼主:
环境:512M内存的vps,mysql 5.6,搭了wordpress 问题:mysql能启动,wordpress一被访问,数据库就crash 尝试1:将innodb_buffer_pool_size=128M 改为5M,wp可以访问了,只是坚持不了多久还会down 尝试2: 调整以下参数至: performance_schema_max_table_instances=600 table_definition_cache=400 table_open_cache=256 这时mysql启动后内存就只占用40–60M内存了 以下是5.6默认的设置,会占用至少400M的内存,可能是导致crash的原因 performance_schema_max_table_instances 12500 table_definition_cache 1400 table_open_cache 2000 尝试3:经过尝试2后,问题解决了。但一个月后随着文章的增多,数据库又crash掉,直接动态扩展了vps内存到1G 问题彻底解决 综上感觉内存不足是最可能的主因 |
6
timchou 2014-01-09 14:19:44 +08:00
第一感觉是内存不够,但是感觉你bp设的也不大的。。
贴下完整的mysql error log吧。top命令,按M,查看各个进程内存使用情况。 |
7
guoqiao OP @timchou
========================= 完整的 error.log: https://dl.dropboxusercontent.com/u/55214241/error.log 说明: 这台 linode 上还给一个同学跑了个 discuzz 论坛, 日志中可以看到ultrax相关的表 crash 了: 140109 8:24:35 [ERROR] /usr/sbin/mysqld: Table './ultrax/pre_forum_promotion' is marked as crashed and should be repaired 开始我怀疑是这个discuzz 导致的. 但我把它关掉观察了一段时间, 数据库还是会不断崩溃, 所以和这个关系不大. 而且,在有这个 discuzz 之前,我也会经常收到出错邮件. ========================= 完整的 my.cnf: https://dl.dropboxusercontent.com/u/55214241/my.cnf ========================= htop 的内存占用截图: https://dl.dropboxusercontent.com/u/55214241/htop.png |
8
fire9 2014-01-09 15:48:56 +08:00
@guoqiao 如果你的表用的innodb存储引擎,你需要调整innodb buffer size的大小。你贴一下你的my.cnf文件内容吧。这个肯定只配置问题。
|
9
mahone3297 2014-01-09 16:05:52 +08:00
@guoqiao htop里,mysqld进程那么多?
另外,我个人觉得,vps 1g,可能 innodb_buffer_pool_size 值可以调的小点。比如32M? 虽然你有1g内仓,然后innodb_buffer_pool_size =128M,但是其他也有内仓分配,比如 key_buffer = 64M query_cache_size = 64M tmp_table_size = 250M 总共加起来就不少了。另外你的服务器也不止mysql,还有别的服务要占内存。 以上只是我个人推测。。。 |
10
VYSE 2014-01-09 16:43:38 +08:00
https://tools.percona.com/wizard
看其他进程是不是突然占满剩余MEMORY,导致mysqld overcommit |
12
aisensiy 2014-01-09 18:34:43 +08:00
明显是内存不够呀...你 top 下看看还有什么东西特别占内存吧
|
13
guoqiao OP |
14
guoqiao OP @mahone3297
1. htop 中, mysql 的进程有20多个, 我也不太明白这个是由哪个参数决定的 2. innodb_buffer_pool_size 之所有设置成这么多, 是因为我用mysqltuner这个工具测试了一下我的配置, 结果如下: -------- Performance Metrics ------------------------------------------------- [--] Up for: 27m 23s (19K q [11.997 qps], 941 conn, TX: 48M, RX: 4M) [--] Reads / Writes: 96% / 4% [--] Total buffers: 344.0M global + 2.7M per thread (20 max threads) [OK] Maximum possible memory usage: 397.8M (40% of installed RAM) [OK] Slow queries: 0% (11/19K) [OK] Highest usage of available connections: 35% (7/20) [OK] Key buffer size / total MyISAM indexes: 64.0M/1.5M [OK] Key buffer hit rate: 100.0% (456K cached / 7 reads) [OK] Query cache efficiency: 40.7% (6K cached / 15K selects) [OK] Query cache prunes per day: 0 [OK] Sorts requiring temporary tables: 0% (0 temp sorts / 1K sorts) [OK] Temporary tables created on disk: 23% (191 on disk / 827 total) [OK] Thread cache hit rate: 99% (7 created / 941 connections) [OK] Table cache hit rate: 25% (450 open / 1K opened) [OK] Open file limit used: 62% (641/1K) [OK] Table locks acquired immediately: 100% (10K immediate / 10K locks) [OK] InnoDB data size / buffer pool: 146.0M/180.0M 这里面最后一条,提到我的数据库大小是146M, 而我的 buffer size 要比这个大才行. 因此我才设置为180M. 如果设置成小于146M 的值, 数据库 crash 之后, 就会分配内存失败, 起不来. 3. 其他的几个参数, 我也是根据 mysqltuner 的建议修改的. |
15
guoqiao OP @VYSE 从 htop 的显示看, 整个系统的内存确实几乎耗尽. 但其中, mysql 占了12%左右, django 占了4%左右, 其他都很少. 不知道问题出在哪里.
|
16
guoqiao OP @Maslino 我前面的回复里说了, 这个 linode 上还有个 discuzz, 我也注意到它的表崩溃了. 我有几天关掉了这个 discuzz, 但是问题还在. 可见不是它的问题. 而且,就算修复了崩溃的表, 过不多久, 这些表又崩溃了.所以我懒得管它了.
|
19
mahone3297 2014-01-09 20:23:14 +08:00
@guoqiao htop虽然显示20多进程,但是内存的占用并不是每个都那么多, 是总共12%左右.
1. 如何看出是总共12%? 我觉得是单个10。9%,然后20个就是200%吧。。。 free -m 结果看下? 2. 为什么我看到我服务器上只有一个mysqld进程,你为什么会那么多?大家为什么对这个没疑问?大家都是那么多进程的? 3. mysql配置参数,看你的意思,都是根据 mysqltuner 这个工具来配置的。这个工具有考虑到你其他情况吗(比如你开了discuz)?他的这个测试的前提条件是不是这个服务器只跑mysql呢(事实上你还跑了其他,比如web server)? 4. 这里面最后一条,提到我的数据库大小是146M, 而我的 buffer size 要比这个大才行. 因此我才设置为180M. 如果设置成小于146M 的值, 数据库 crash 之后, 就会分配内存失败, 起不来. 按你的说法,buffer_pool必须比数据库大。。。那假如我10g的数据库,我buffer_pool要开到10g吗? ps:我在我这边线上环境,buffer_pool只开了128m,我的db size肯定大雨128m(事实上是10多g)。当然,我没说我的buffer_pool配置的正确,因为我看网上都说要配置的比较大。但至少我这边运行的还好,也没出什么问题,至少没crash。当然,我这边也不是什么高并发的查询。 以上仅供参考。。。 |
20
pubby 2014-01-09 20:40:49 +08:00
swap 都这样了,这db性能还能忍受的啊
同一机房再买个vps单独跑mysql算了 |
21
Livid MOD 你的表是 InnoDB 还是 MyISAM 的?InnoDB 的话是不需要开 key_buffer 的。
|
22
liushuaikobe 2014-01-09 21:00:55 +08:00
我突然想到知乎也时不时的500。刷新一下就好了。。
|
23
VYSE 2014-01-09 22:07:40 +08:00
@guoqiao 那个htop里mysqld可能共享memory,不是累加的。按照你说的来看,mysqld和django并没有占多少内存。
你能top -> shift-f ->n 列出占用大户么? |
26
guoqiao OP 1. 我截图里当时是10.9%, 总共也是这么多. 内存怎么可能用到200%呢...
2. 我用的是 htop 命令查看的, 它是更高级的 top, 会显示子进程. 你如果用 top 看,只会看到主进程. 3. mysqltuner 可以根据你的机器配置以及过去24小时的运行情况, 给你的 mysql "体检". 4. 如果访问量不高, 不会有问题吧. 但是设置成比数据库大, 是确保安全的做法. |
27
guoqiao OP @mahone3297 上一条是回复给你的.
|
30
guoqiao OP |
31
arbeitandy 2014-01-10 07:40:37 +08:00 via Android
* 看 errorlog,不是mysql自己的問題。似系統無法分配足夠內存,oom機制殺掉了mysql進程,可以檢查 系統日誌 syslog
參考 http://dba.stackexchange.com/questions/25077/mysql-innodb-crash-post-mortem 在 crash 時也許有其它進程快速佔用了比計劃多得多的內存 (比如python, php都是潛在的內存大戶,如果還有文件io操作。。) * 順便建議mysqltuner 的測試要啟動一段時間後再進行 Up for: 27m 23s 這時可能cache沒warmup,hit rate會偏低。不過僅僅看數字這份my.cnf沒受這個影響。 * http://dba.stackexchange.com/questions/25165/intermittent-mysql-crashes-with-error-fatal-error-cannot-allocate-memory-for-t 這裡還有個比較長比較全面討論低配機器的mysql配置檢查。 * 如果短期訪問量不會增加,又沒有慢速查詢,my.cnf裡 max_connections可以再降低點。 |
32
guoqiao OP @arbeitandy 哇,都是干货啊, 多谢:)
|
33
VYSE 2014-01-10 11:09:47 +08:00
@guoqiao OK, MEM占有也就前几个进程累加起来的,剩余的多数都被内核申请为磁盘CACHE了,所以top上面有个used mem已经满了的假象。
可能需要观察到CRASH那一刻,各个进程的情况,个人觉得你可以限制php和python的实例创建上限。 |
34
guoqiao OP @arbeitandy @VYSE
多谢二位, 你们的分析引导我找到了问题所在. 我的网站上有几个实时统计的页面, 需要联合查询大量数据, 每次查询都好慢. 由于太卡, 我用的不多, 也一直没太在意. 今天早上特地看了下,每次点击统计页面, mysql 某个进程的 CPU 就会彪到100%多, 整个服务器都很卡顿. 应该就是它导致了 mysql 崩溃. 我去掉了统计页面, 今天观察了一天, 目前为止没有再收到任何 mysql 错误. 现在想来, 这几个页面因为很卡,所以我自己很少点, 都被我遗忘了. 我想点过的用户也不想点第二次. 但是每次有新用户进来, 他可能在无意识的情况下随手点了它, 这就导致 mysql 崩溃. 根据我目前网站上的用户数, 我每天收到的出错邮件次数, 也差不多符合这个假设. 当然,目前观察的时间还太短,不能下结论. 但是也应该差不多. 这个问题一度让我怀疑 mysql 的性能, 现在看来, 问题出在我自己的不当查询上面. 惭愧. |
35
fire9 2014-01-11 03:01:15 +08:00
@guoqiao,这个配置需要根据你目前机器的资源和产品的应用来做调整,我简单的看了一下,这个配置文件不是很好,default-storage-engine = innodb
事例几个需要优化 innodb_buffer_pool_size = 180M #通常为物理内存的50%,或者70-80% tmp_table_size = 250M max_heap_table_size = 20M #这两个选项的值最好是相等的。 只有cpu太高,那就要优化SQL了,另外估计你代码的严谨度不够,比如一些地方需要做合并请求,总不能点一次查询一次。 如果需要额外的付费的服务,请联系我哈! |