AutoGrowth 对数据库性能的影响
这段时间在对我们的棋牌系统做压力测试,模拟3000用户同时在线的状况。在这种情况下,数据库服务器的cpu消耗仅为2%左右(cpu是2*至强4核),内存占用1.8G(物理内存共有4G),大概平均每秒钟向数据库中插入40多条记录(三个表,包括游戏主从记录、利润记录等),还有数十次的select和update。另外,数据库中游戏记录表和利润记录这两个表的现有数据量都有1700万左右,当前数据库的总大小为37G。
在如此的情况下运行,cpu是比较平稳的,内存也很平稳,但是每当运行了11到14个小时左右的时候,系统就会产生很多Insert的Timeout日志。为此,我将命令执行的超时由30s改成60s,问题依旧存在。然后,我通过Profiler进行跟踪,发现每次Insert Timeout时,都会有大量的Audit login和Audit logout出现,我猜想,是不是到达高峰期的时候,由于很多局游戏同时结束而导致数据库连接不够用,于是,我将数据库连接池的MaxPoolSize由默认的100改成300,然后再次运行测试,十几个小时后,又出现了同样的问题。
看来,问题在于每隔一段时间,数据库就会执行一次耗时的动作,在这段时间,数据库提供给外部使用的性能就会急剧下降,从而导致Insert timeout。那么数据库每隔一段时间在执行什么动作了?备份?不可能,测试站上我们没有启用定时备份机制。最后终于发现,原来根源在于数据库空间的AutoGrowth,我们的数据库空间增长方案使用了默认的AutoGrowth,每次增长10%,当数据库发现余留空间不够时,它会自动申请磁盘空间,而这个过程是会影响到数据库的使用性能的,正是在这段时间,我们的Insert出现timeout了。
知道了问题根源,我们便试试禁用自动增长,然后一次性分配给数据库一个很大的空间,结果系统一直运行非常平稳和正常。我们可以使用系统存储过程sp_spaceused来查看数据库的空间使用状况。
对于那些可以定期停止运行来维护的系统,可以使用这种一次性分配大空间的方案来避免中途因为出现AutoGrowth而导致性能下降的情况,因为每次维护的时候,我们可以转移数据、或增加硬盘、或再次分配更大的空间等操作。
但是,如果是对于需要持续(比如365*24不间断)在高负载(比如CPU平均80%以上)下运行的数据库(并且不能出现任何timeout),该如解决空间增长问题了?望有经验朋友指点一二 :)
注:这只是我们一个初步的压力测试,Partition可以增加磁盘的IO吞吐量,肯定是要做的,而这次测试我要达到的目的是3000用户每天24小时都在线,所以没有所谓系统不忙的时候,这也是文章最后一个问题的基本假设。另外,如果真的是3000用户每天24小时在线,那么不到2个星期将跑满40g数据,而这40G数据当然是活跃的。我们已经通过缓存服务器、write-read分离(Master-Slave)等措施来减轻数据库的负担。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构