【故障公告】今年第五次:数据库服务器 CPU 100%
会员救园,故障添乱,今天凌晨 04:06~05:40 期间,园子的数据服务器再次出现 CPU 100% 故障,由此给您带来麻烦,请您谅解。
这是今年的第5次故障,第1次发生于2023年3月26日,第2次发生于2023年8月19日,第3次与第4次发生于2023年8月31日。
这次由于出现在凌晨,发现比较晚,发现故障后,通过重启数据库实例恢复正常。
园子的数据库服务器使用的是阿里云 RDS SQL Server2016 标准版,故障恢复后,我们通过阿里云 RDS 控制台的「性能优化」发现故障期间占用 CPU 最多的 SQL 语句
SELECT TOP @__p_1 [b].[TagName] AS [Name], [b].[TagID] AS [Id], [b].[UseCount], [b].[PrivateUseCount], [b].[BlogId]
, [b].[Order]
FROM [blog_Tag] [b]
WHERE [b].[BlogId] = @__blogId_0
AND ([b].[PrivateUseCount] > ?
OR [b].[UseCount] > ?)
ORDER BY CASE
WHEN [b].[Order] IS NULL THEN ?
ELSE ?
END, [b].[Order], [b].[UseCount] DESC
阿里云 RDS 控制台给出的分析提示:
数据类型隐式转化:可能会导致CPU / IOPS飙高,建议保持数据类型一致
我们针对这个 SQL 语句进行了优化,改为在内存中针对 Order
字段进行排序,优化的 SQL 语句
SELECT TOP(@__p_1) [b].[TagName] AS [Name], [b].[TagID] AS [Id], [b].[UseCount], [b].[PrivateUseCount], [b].[BlogId], [b].[Order]
FROM [blog_Tag] AS [b]
WHERE [b].[BlogId] = @__blogId_0 AND ([b].[PrivateUseCount] > 0 OR [b].[UseCount] > 0)
ORDER BY [b].[UseCount] DESC
注:SQL 语句是 EF Core 生成,我们优化的是 LINQ 代码。
前两次故障期间占用 CPU 最多的是一个存储过程,在故障后的优化中给那个存储过程加了 WITH RECOMPILE
参数,这次故障期间没有出现 CPU 占用高的问题。