SQLServer 企业版无法使用所有 CPU 内核
问题现象:
SqlServer不能使用操作系统CPU最大内核数,无法发挥服务器最佳性能,计算资源闲置浪费。
问题原因:
因从SqlServer 2012之后的版本,企业版本分为 Entetprise CAL Edition 和 Entetprise Core Edition,其中Entetprise CAL Edition 许可限制SqlServer只能使用物理CPU 20核数,逻辑处理器最大为40,Entetprise Core Edition版本则是无限制操作系统最大的内核数。
按 SQL Server 版本划分的计算能力限制 - SQL Server | Microsoft Docs
具体说明,可参考上述微软官方KB
适用范围:
美宜佳所有相关SqlServer 2012以上版本的数据库。
适用版本:
SqlServer 2012 以上的Entetprise Edition, 注意:SqlServer 2012以下版本不受影响。
如何查询CPU最大核数和SQLServer使用最大内核数?
查看正在使用的CPU逻辑处理器
use master
select * from sys.dm_os_schedulers where is_online=1 and status='VISIBLE ONLINE'
查看无法使用的CPU逻辑处理器
use master
select * from sys.dm_os_schedulers where is_online=0
或是通过Windows任务管理器--性能--进行查看当前CPU内核数。
问题解决方法
进行SqlServer序列号更换,升级为SqlServer Entetprise Core Edition
重要注意事项:升级时SQLSERVE服务要处于运行状态。
升级前需要关闭数据库相应的活动会话,包含前端程序,数据库作业,确保没有活动事务和活动会话正在进行,因为升级过程会重启SQLSERVER数次,以防止数据库出现实例恢复,增加风险,整机升级过程在10分钟以内。
具体升级步骤:
- 加载SqlServer安装镜像包,要注意对应相应的版本
- 打开CMD,cd 目录,切换到虚拟光驱盘,运行以下命令进行版本升级。
Setup.exe /q /ACTION=editionupgrade /INSTANCENAME=MSSQLSERVER /PID="TBR8B-BXC4Y-298NV-PYTBY-G3BCP" /IACCEPTSQLSERVERLICENSETERMS
其中 /INSTANCENAME 为SQLSERVER实例名,一般默认为MSSQLSERVER
PID则为需要升级的序列号,进行相应的替换即可。
3.升级完成后,可再次通过上述SQL查询可用的处理器,正常情况下可以看到所有的逻辑处理器都为'VISIBLE ONLINE' 状态,也可以通过select @@version进行查看当前数据库版本
4. 检查数据库运行状态和前端程序是否正常运行。
清理无法删除的作业
USE [msdb]
DECLARE @job_name VARCHAR(100)
SET @job_name = N'backup_diff.Subplan_1' -- SELECT * FROM sysjobs_view; 可以通过这句查询作业名称,直接拷过来,避免手动输错
--注:jobName为维护计划对应的jobName
--删除在计划里面的日志
DELETE
sysmaintplan_log
FROM
sysmaintplan_subplans AS subplans
INNER JOIN sysjobs_view AS syjobs ON subplans.job_id = syjobs.job_id
INNER JOIN sysmaintplan_log ON subplans.subplan_id =sysmaintplan_log.subplan_id
WHERE
(syjobs.name = @job_name)
--删除代理的作业
DELETE
sysjobschedules FROM sysjobs_view v
INNER JOIN sysjobschedules o ON v.job_id=o.job_id
WHERE
v.name=@job_name
--删除子计划
DELETE
sysmaintplan_subplans
FROM
sysmaintplan_subplans AS subplans
INNER JOIN sysjobs_view AS syjobs ON subplans.job_id = syjobs.job_id
WHERE
(syjobs.name = @job_name)
--删除作业
DELETE FROM msdb.dbo.sysjobs_view WHERE name = @job_name
SELECT * FROM sysjobs_view