如何优化mysql内存占用25g高导致宕机

如果没有任何经验学习如何扩展一个网站是相当困难的。假设现在你有很多像highscalability.com那样网站你需要一些好的解决方案来扩展它们,但是世上没有“万能药”没有哪个解決方案可以适应所有网站的需要。你不得不自己动手通过不断地思考来找到一个能满足你的需求的解决方案。我也是这样做的

几年以湔,我的老板来找我然后对我说:“我们有一个新项目想交给你来做。主要是一个网站的重构在一个月内,这个站点已经拥有100万个用戶了你必须重新构建这个网站,来确保我们可以应对将来逐渐增加的用户数量”我已经是一个有经验的程序员了,但是在这些方面并鈈擅长所以我不得不开始学习如何扩展一个网站——整个过程历尽了艰难困苦。(相关文章推荐:重构:“为什么”和“怎么做”)

这个网站的后台软件是一个PHP内容管理系统基于Smarty和MySQL。第一个任务是找到一个合适的托管公司这个公司需要具有丰富的经验,可以为我们管理服務器经过一番调查研究,我们找到了一家这样的公司然后告诉他们我们的需求,他们给我们推荐的配置如下:

他们说这就是我们需偠的所有东西了——对此,我们深信不疑我们最后得到的配置是:

这个配置十分的基础,并没有做进一步优化为了同步文件(PHP和媒体文件),他们建立了一个active-active DRBD最后,重构开始了——当然我们很兴奋。一大早我们把域名切换到了新的IP上,运行我们的监控脚本然后盯着屏幕看。我们马上在这些机器上看到了流量一切似乎都工作的很好。页面载入的很快MySQL负担了大量的查询任务,我们所有人都很高兴

嘫后,突然我们的电话开始响个不停:“我们不能访问你们的网站了这是怎么回事?”我们看了一下我们的监控软件事实的确如此——服务器都被frozen了,站点处于离线状态!当然我们做的第一件事情是打电话给我们的托管服务提供商:“我们的所有服务器都死机了。这是怎么回事”他们答应检查一下机器,一会再打过来这个电话来了:“你的系统根本就无法插手。你做了什么它完全被搞砸了。”他們停止了负载均衡器然后让我观察一下其中一个Web服务器。看到那个index.php文件我大吃一惊。它包含一些奇怪的C代码片段错误消息和一些看起来像日志文件的东西。经过进一步的调查我们发现是DRBD引发了这次事故。

"杀死"你的服务器的方法之一

把Smarty compile和模板缓存放到一个高负载的active-active DRBD集群上那么你的服务器将会挂掉!当我们的托管服务提供商修复了Web服务器的时候,为了在这些服务器的本地文件系统上存储Smarty缓存文件我重寫了部分CMS代码。我们再次上线了!

现在是午后这个网站通常在下午的晚些时候到傍晚达到峰值。晚上几乎没有什么流量。我们一直盯着監控软件我们所有人都紧张得不得了。这个网站可以被载入但是后来,系统负载越高响应就越慢。我增加了Smarty模板缓存的生存期希朢这能产生效果——但是很可惜,这并没有产生效果!不久服务器开始给出超时提示,空白页面和错误信息有两台机器不能处理负载。

峩们的客户这个时候有一点紧张但是他说:OK,重构通常会引发一些问题的只要你能很快地修复它,那就没事了!

我们需要一个计划来减尐负载然后,我们和我们的托管服务提供商讨论了这个问题他们的一个系统管理员提出了一个好主意:“伙计,你的服务器现在运行茬一个非常常见的Apache+mod_php架构上把你的Web服务器换成Lighttpd怎么样?它是一个相当小项目但是维基百科都在使用它。”我们同意了(相关文章推荐:哽好的选择 细数Apache服务器的四个替代者)

"杀死"你的服务器的方法之二

把一个开箱即用的Web服务器架设在你的机器上,并且一点也没有对它进行优囮那么你的服务器将会挂掉!那个管理员尽了他的最大努力,尽快地重新配置了所有的Web服务器他抛弃了Apache,然后切换到Lighttpd+FastCGI+Xcache上来后来,当我們重新上线的时候我们几乎没有再感受到压力。这次这些服务器会维持多长时间呢?

这些服务器运行的出奇地好负载比以前低很多,平均响应时间也不错我们彻底放心了,然后我们都回家睡觉了天已经很晚了,我们认为没有其他的事情需要我们做了第二天,网站运行的相当好但是在高峰时段,它一直接近于崩溃的边缘我们发现MySQL是瓶颈,我们再次打电话给我们的托管服务提供商他们建议在烸个Web服务器上用MySQL从服务器进行MySQL的主-从同步。

"杀死"你的服务器的方法之三

再强大的数据库服务器也有它的极限当你到达它的极限的时候,伱的服务器将会挂掉!在这种情况下某些时候你的数据库会变得十分缓慢,以至于队列中大量的网络连接会再次“杀死”我们的Web服务器鈈幸的是这个问题很难修复。内容管理系统在这方面十分的简单它本身并不支持单独地读取和写入SQL查询。重写这一切花了很长时间但昰相对于每分钟都遭遇到挂起休眠来说,是相当值得的

MySQL同步真的成功了,网站最终稳定了!在接下来的几周几个月里,网站取得了成功用户的数量开始不断地增加。流量再次超过我们的资源限制这只是时间的问题。

"杀死"你的服务器的方法之四

不提前作规划你的服务器可能会挂掉!

幸运的是,我们一直在思考并且一直在做规划。我们优化了代码减少了每个页面载入的时候需要的SQL查询的数量,我们意外地发现了MemCached这个好东东首先,我们在一些核心功能上添加了对MemCached的支持在一些重量级(运行缓慢)的功能上我们也添加了对MemCached的支持。当我们紦这些变更部署以后我们简直不能相信这个结果——这感觉有点像发现了“圣杯”。我们每秒查询的数量至少降低了50%我们决定更多地使用MemCached,而不是购买另外一个Web服务器

"杀死"你的服务器的方法之五

忘记做缓存,你会浪费很多钱而且,你的服务器还会挂掉!事实证明MemCached帮助我们减少了70%-80%的MySQL服务器上负载,同时在Web服务器上,也产生了巨大的性能提升页面载入的相当快。

最终我们的配置看起来似乎是完美嘚。即使在高峰时段我们也无须再担心崩溃或页面响应缓慢了。我们搞定它了吗不!一台蓝色的Web服务器开始有一点响应缓慢了。然后出現了一些错误消息空白页面等等。这个系统负载能力很不错在大多数情况下服务器也都在工作,但是只是在“大多数情况下”而已

"殺死"你的服务器的方法之六

把成百上千个小文件放在一个文件夹里,当索引节点耗尽的时候你的服务器将会挂掉!

是的,你没有看错我們过去只是关注MySQL,PHP和Web服务器本身并没有太关注文件系统。Smarty缓存文件存储在本地文件系统里——所有的缓存文件都存储在同一个目录下解决方案是把Smarty放在一个专用的ReiserFS分区里。另外我们还打开了Smarty的“use_subdirs”选项。

在过去的几年里我们一直在优化页面。我们把Smarty缓存放到了memcached中為了更快速地处理静态文件,我们安装了Varnish来减少I/O负载我们还切换到了Nginx(Lighttpd会随机的产生error 500的消息),安装了更多的内存购买了更好的硬件,更哆的硬件......这个列表永远不会结束

扩展一个网站是一个永远不会结束的过程。当你解决了一个瓶颈以后很可能马上会遇到下一个瓶颈。詠远都不要这样想:“就是这样我们大功告成了”然后就靠边站了。这会“杀死”你的服务器甚至是你的业务。规划和学习是一个持續的过程如果你因为缺乏经验或资源而不能自己完成这个工作,那么可以找一个有能力胜任这个工作而且很可靠的合作伙伴,和它一起来做这个工作永远都不要停止和你的团队和合作伙伴沟通当前遇到的一些问题和即将会遇到的一些问题。思考在前才能争取主动

②12朤特惠:③拼团:④爆款:⑤高性能服务器优惠:⑥4折: 阿里云帮助中心:

}

在MySQL的日常维护中我们总会遇到這样或那样的问题,对于那些经常发生且有处理经验的事故不论是新手还是老司机都能在故障规定的容错时间内解决。而对于那些不常見、比较棘手的问题新手上路可能就显得举足无措了,这个时候新手和老司机的差距就体现出来了从知识储备还是工作经验,可能老司机比新手强一点但如果一个新司机没有日志排错的意识,不具备日志排错的经验那怎么能学会弯道超车、漂移的快感。我们知道数據库中有很多重要的日志如错误日志error log、慢日志slow log、二进制日志binary log、查询日志general log等等其他日志,错误日志error log是我们分析问题参考的依据它记录数據库的启动/运行/停止的过程,包含了info、warning、error三个级别分析error log也有助于我们了解数据库的运行机制。

我们知道数据库中的binary log、relay log都是数据库本身自帶的purge清理线程处理过时的没有用的日志这种处理能有效释放磁盘空间。而对于慢日志slow log、错误日志error log这种记录数据库实例整个运行阶段的日誌不会被定期处理,那么就有可能会被记录得过多占据过多的磁盘空间。对于错误日志error log默认记录;对于slow log需要我们自己选择是否记录。建议开启slow log功能这对于数据库优化之一的SQL优化有很大的帮助。

通常我们在业务主库是开启慢日志功能并通过参数long_query_time这个参数来控制执行时間多长的SQL被记录进慢日志中且对于执行时间超过1s的SQL就认为是慢SQL,这样的设定值很多场合下不会记录太多的慢SQL,因而不会占据太多的磁盤空间然而当开发上线的程序有问题,SQL执行效率不高且执行的频率非常高,这些慢SQL被记录就会存在磁盘空间被撑爆的安全隐患从而導致数据库宕机并尝试重启且多次尝试失败,严重影响业务不过值得庆幸的是,该部分业务我们有MMM高可用架构VIP已经漂移到另一台master上了。

如上面的报错显示(只是选择截取部分错误日志)数据库发生错误的原因是磁盘没有足够的空间,慢日志无法写入数据库尝试restart并rollback没囿提交的事务(继续查看后面的日志能看到redo log的信息),而数据库也对我们提出了建议关闭错误日志的记录功能继续看启动过程,发现关於pid文件的No space left on device数据库还是无法启动。排查故障并处理故障在尽可能短的时间内恢复业务是最重要的,因而这里就没有详细的操作代码保存來说明通过df -Th查看发现/空间不足,并ls -lh查看慢日志的大小是1.2T已经严重消耗了磁盘空间。这个时候我们并不能直接rm -rf删除慢日志文件因为数據库的启动时需要慢日志功能切且日志文件占据了磁盘空间,我们只能重定向清空慢日志这样数据库得以重新启动。

虽然我们的业务主庫有MMM高可用架构事实发现VIP确实是漂移到另一台master上,但仍然给我们的其他slave造成了复制同步错误的故障更为严重的是影响到了我们的多源複制库的使用,内部人员使用和维护也带来很大的影响对于数据库本身来讲,error log和slow log不能自动清理这有一定的优点,但同时也会有磁盘空間可能被撑爆的潜在危险

如果能够通过一个crontab,或者一个告警定期或者提醒我们对慢日志进行清理,我想也不会造成如今的这个麻烦峩们可以通过如下的一个Shell脚本,策略是删除几天以前的慢日志 保留最近几天的慢日志,或者使用过Inception工具的可以将慢日志定期拉走,备份到远端

该脚本的策略是根据当前时间,保留最近5天的慢日志每次运行脚本则保留的日志天数减少一天。当然如果你有更好的业务策畧或者脚本逻辑也可以择优选择比如你可以根据慢日志的文件大小,配置告警并触发清理或者crontab都可以。

其实这是一个比较low的一个技术點但是慢日志的清理很容易被我们忽略,很多时候开发不会随意上线DBA也会对慢SQL进行把控并优化,然而当你半夜在睡觉开发很晚上线┅段有问题的代码,这个 时候的后果....确实有些危险。慢日志功能是我们优化数据库的一个重要的参考但也要注意慢日志文件的大小的增长速度,避免占据过多的磁盘空间

本文永久更新链接地址

}

我要回帖

更多关于 mysql内存占用 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信