欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SqlServer如何通过SQL语句获取处理器(CPU)、内存(Memory)、磁盘(Disk)以及操作系统相关信息

程序员文章站 2022-11-20 13:09:34
在sql server中如何通过sql语句获取服务器硬件和系统信息呢?下面介绍一下如何通过sql语句获取处理器(cpu)、内存(memory)、磁盘(disk)以及操作系统...

在sql server中如何通过sql语句获取服务器硬件和系统信息呢?下面介绍一下如何通过sql语句获取处理器(cpu)、内存(memory)、磁盘(disk)以及操作系统相关信息。如有不足和遗漏,敬请补充。谢谢!

一:查看数据库服务器cpu的信息

---sql 1:获取数据库服务器的cpu型号

exec xp_instance_regread 
  'hkey_local_machine',
  'hardware\description\system\centralprocessor\0',
  'processornamestring';

---sql 2:获取数据库服务器cpu核数等信息(只适用于sql 2005以及以上版本数据库)

/*************************************************************************************
--cpu_count        :指定系统中的逻辑 cpu 数
--hyperthread_ratio    :指定一个物理处理器包公开的逻辑内核数与物理内核数的比.虚拟机
--             中可以表示每个虚拟插槽的核数。虚拟中[physical cpu count]其实
--             表示虚拟插槽数
*************************************************************************************/
select s.cpu_count            as [loggic cpu count]
   ,s.hyperthread_ratio        as [hyperthread ratio]
   ,s.cpu_count/s.hyperthread_ratio as [physical cpu count] 
from sys.dm_os_sys_info s option (recompile);

---sql 3:获取数据库服务器cpu核数(适用于所有版本)

create table #temptable
  (
   [index] varchar(2000) ,
   [name] varchar(2000) ,
   [internal_value] varchar(2000) ,
   [character_value] varchar(2000)
  );
insert into #temptable
    exec xp_msver;
select internal_value as virtualcpucount
from  #temptable
where  name = 'processorcount';
drop table #temptable;
go

---sql 4:在老外博客中看到一个计算cpu相关信息的sql,不过虚拟机计算有点小问题,我修改了一下。

declare @xp_msver table (
  [idx] [int] null
  ,[c_name] [varchar](100) null
  ,[int_val] [float] null
  ,[c_val] [varchar](128) null
  )
insert into @xp_msver
exec ('[master]..[xp_msver]');;
with [processorinfo]
as (
  select ([cpu_count] / [hyperthread_ratio]) as [number_of_physical_cpus]
    ,case 
      when hyperthread_ratio = cpu_count
        then cpu_count
      else (([cpu_count] - [hyperthread_ratio]) / ([cpu_count] / [hyperthread_ratio]))
      end as [number_of_cores_per_cpu]
    ,case 
      when hyperthread_ratio = cpu_count
        then cpu_count
      else ([cpu_count] / [hyperthread_ratio]) * (([cpu_count] - [hyperthread_ratio]) / ([cpu_count] / [hyperthread_ratio]))
      end as [total_number_of_cores]
    ,[cpu_count] as [number_of_virtual_cpus]
    ,(
      select [c_val]
      from @xp_msver
      where [c_name] = 'platform'
      ) as [cpu_category]
  from [sys].[dm_os_sys_info]
  )
select [number_of_physical_cpus]
  ,[number_of_cores_per_cpu]
  ,[total_number_of_cores]
  ,[number_of_virtual_cpus]
  ,ltrim(right([cpu_category], charindex('x', [cpu_category]) - 1)) as [cpu_category]
from [processorinfo]
---查看虚拟机cpu信息
declare @xp_msver table (
  [idx] [int] null
  ,[c_name] [varchar](100) null
  ,[int_val] [float] null
  ,[c_val] [varchar](128) null
  )
insert into @xp_msver
exec ('[master]..[xp_msver]');;
with [processorinfo]
as (
  select ([cpu_count] / [hyperthread_ratio]) as [number_of_physical_cpus]
    ,[hyperthread_ratio] as [number_of_cores_per_cpu]
    ,[cpu_count] as [total_number_of_cores]
    ,[cpu_count] as [number_of_virtual_cpus]
    ,(
      select [c_val]
      from @xp_msver
      where [c_name] = 'platform'
      ) as [cpu_category]
  from [sys].[dm_os_sys_info]
  )
select [number_of_physical_cpus]
  ,[number_of_cores_per_cpu]
  ,[total_number_of_cores]
  ,[number_of_virtual_cpus]
  ,ltrim(right([cpu_category], charindex('x', [cpu_category]) - 1)) as [cpu_category]
from [processorinfo]

二:查看数据库服务器内存的信息

能否通过sql语句获取服务器的物理内存大小?内存条型号?虚拟内存大小?内存使用情况? 目前我所知道的只能通过sql语句获取服务器物理内存大小,内存的使用情况。 至于内存条型号,系统虚拟内存大小,暂时好像还无法通过sql语句获取。

查看服务器的物理内存情况

    如下所示,从sys.dm_os_sys_info里面获取的physical_memory_in_bytes 或physical_memory_kb 的值总是低于实际物理内存。暂时不清楚具体原因(还未查到相关资料),所以计算大小有出入,要获取实际的物理内存,就必须借助ceiling函数。

 

--sql 1:获取数据库服务器物理内存数(适用于所有版本)

 create table #temptable
  (
   [index] varchar(2000) ,
   [name] varchar(2000) ,
   [internal_value] varchar(2000) ,
   [character_value] varchar(2000)
  );
insert into #temptable
    exec xp_msver;
select internal_value/1024 as physicalmemory
from  #temptable
where  name = 'physicalmemory';
drop table #temptable;
go

---sql 2:适用于sql server 2005、sql server 2008

 select ceiling(physical_memory_in_bytes*1.0/1024/1024/1024)  as [physical memory size]
from sys.dm_os_sys_info option (recompile) 
select physical_memory_in_bytes*1.0/1024/1024/1024
  ,  physical_memory_in_bytes as [physical memory size]
from sys.dm_os_sys_info option (recompile)

---sql 3:适用于sql server 2012 到 sql server 2014

 select ceiling(physical_memory_kb*1.0/1024/1024) as [physical memory size]
from sys.dm_os_sys_info option (recompile);

---sql 4:适用于sql server 2008以及以上的版本:查看物理内存大小,已经使用的物理内存以及还剩下的物理内存。

select ceiling(total_physical_memory_kb * 1.0 / 1024 / 1024)  as [physical memory size] 
    ,cast(available_physical_memory_kb * 1.0 / 1024 / 1024 
                       as decimal(8, 4)) as [unused physical memory]
    ,cast(( total_physical_memory_kb - available_physical_memory_kb ) * 1.0
    / 1024 / 1024 as decimal(8, 4))              as [used physical memory]
    ,cast(system_cache_kb*1.0 / 1024/1024 as decimal(8, 4)) as [system cache size]
from  sys.dm_os_sys_memory

三:查看数据库服务器硬盘的信息

如下所示,我们可以通过下面脚本获取服务器的各个磁盘的使用情况。但是无法获取磁盘的型号、转速之类的信息。

set nocount on 
declare @result   int;
declare @objectinfo   int;
declare @driveinfo   char(1);
declare @totalsize   varchar(20);
declare @outdrive   int;
declare @unitmb   bigint;
declare @freerat   float;
set @unitmb = 1048576;
--创建临时表保存服务器磁盘容量信息
create table #diskcapacity
(
[diskcd]   char(1) ,
freesize   int   ,
totalsize   int  
);
insert #diskcapacity([diskcd], freesize ) 
exec master.dbo.xp_fixeddrives;
exec sp_configure 'show advanced options', 1
reconfigure with override;
exec sp_configure 'ole automation procedures', 1;
reconfigure with override;
exec @result = master.sys.sp_oacreate 'scripting.filesystemobject',@objectinfo out;
declare cr_diskinfo cursor local fast_forward
for 
select diskcd from #diskcapacity
order by diskcd
open cr_diskinfo;
fetch next from cr_diskinfo into @driveinfo
while @@fetch_status=0
begin
exec @result = sp_oamethod @objectinfo,'getdrive', @outdrive out, @driveinfo
exec @result = sp_oagetproperty @outdrive,'totalsize', @totalsize out
update #diskcapacity
set totalsize=@totalsize/@unitmb
where diskcd=@driveinfo
fetch next from cr_diskinfo into @driveinfo
end
close cr_diskinfo
deallocate cr_diskinfo;
exec @result=sp_oadestroy @objectinfo
exec sp_configure 'show advanced options', 1
reconfigure with override;
exec sp_configure 'ole automation procedures', 0;
reconfigure with override;
exec sp_configure 'show advanced options', 0
reconfigure with override;
select diskcd   as [drive cd]   , 
  str(totalsize*1.0/1024,6,2)   as [total size(gb)] ,
  str((totalsize - freesize)*1.0/1024,6,2)   as [used space(gb)] ,
  str(freesize*1.0/1024,6,2)   as [free space(gb)] ,
  str(( totalsize - freesize)*1.0/(totalsize)* 100.0,6,2) as [used rate(%)]  ,
  str(( freesize * 1.0/ ( totalsize ) ) * 100.0,6,2)    as [free rate(%)]
from #diskcapacity;
drop table #diskcapacity;

四:查看操作系统信息

  通过下面sql语句,我们可以查看操作系统版本、补丁、语言等信息

--创建临时表保存语言版本信息
create table #language
(
[languagedtl]      nvarchar(64) ,
[os_language_version]  int
);
insert into #language
select 'english - united states'       ,1033 union all
select 'english - united kingdom'       ,2057 union all
select 'chinese - people''s *',2052 union all
select 'chinese - singapore'         ,4100 union all
select 'chinese - *'           ,1028 union all
select 'chinese - * sar'       ,3076 union all
select 'chinese - macao sar'         ,5124;
with systemversion(systeminfo,releaseno)
as
(
select 'windows 10' ,
    '10.0*'
union all
select 'windows server 2016 technical preview' ,
    '10.0*'
union all
select 'windows 8.1' ,
    '6.3*'
union all
select 'windows server 2012 r2' ,
    '6.3'
union all
select 'windows 8' ,
    '6.2'
union all
select 'windows server 2012' ,
    '6.2'
union all
select 'windows 7' ,
    '6.1'
union all
select 'windows server 2008 r2' ,
    '6.1'
union all
select 'windows server 2008' ,
    '6.0'
union all
select 'windows vista' ,
    '6.0'
union all
select 'windows server 2003 r2' ,
    '5.2'
union all
select 'windows server 2003' ,
    '5.2'
union all
select 'windows xp 64-bit edition' ,
    '5.2'
union all
select 'windows xp' ,
    '5.1'
union all
select 'windows 2000' ,
    '5.0'
)    
select s.systeminfo 
   ,w.windows_service_pack_level
   ,l.languagedtl
from sys.dm_os_windows_info w
inner join systemversion s on w.windows_release=s.releaseno
inner join #language l on l.os_language_version = w.os_language_version;
drop table #language;

注意:

  1:如上所示,临时表#language的数据此处只列了几条常用的数据,如需全部数据,参考https://msdn.microsoft.com/zh-cn/goglobal/bb964664.aspx自行补充。

  2:操作系统的版本信息的数据来源于https://msdn.microsoft.com/zh-cn/library/ms724832(vs.85).aspx

有可能出现不同操作系统具有相同version number值,例如windows 7 和windows server 2008 r2的version numberd都为6.1。导致下面查询结果出现多条记录(如下所示)。一般要酌情判断(如果生产服务器都为windows服务器,可以剔除windows xp、windows 7这类数据)。

ps:使用sql语句获得服务器名称和ip地址

使用sql语句获得服务器名称和ip地址   获取服务器名称: 

select serverproperty('machinename')
select @@servername
select host_name()

获取ip地址可以使用xp_cmdshell执行ipconfig命令:

--开启xp_cmdshell 
exec sp_configure'show advanced options', 1 
reconfigure with override 
exec sp_configure'xp_cmdshell', 1 
reconfigure with override 
exec sp_configure'show advanced options', 0 
reconfigure with override 
go 
begin 
declare @ipline varchar(200) 
declare @pos int 
declare @ip varchar(40) 
set nocount on 
set @ip = null 
  if object_id('tempdb..#temp') is not null drop table #temp 
  create table #temp(ipline varchar(200)) 
  insert #temp exec master..xp_cmdshell'ipconfig' 
  select @ipline = ipline 
  from #temp 
  where upper(ipline) like '%ipv4 地址%'--这里需要注意一下,系统不同这里的匹配值就不同 
  if @ipline is not null 
  begin 
    set @pos = charindex(':',@ipline,1); 
    set @ip = rtrim(ltrim(substring(@ipline , 
    @pos + 1 , 
    len(@ipline) - @pos))) 
  end 
  select distinct(rtrim(ltrim(substring(@ipline , 
  @pos + 1 , 
  len(@ipline) - @pos)))) as ipaddress from #temp 
drop table #temp 
set nocount off 
end 
go 

但是很多情况下由于安全问题是不允许使用xp_cmdshell,可以通过查询sys.dm_exec_connections : 

select servername = convert(nvarchar(128),serverproperty('servername')) 
,local_net_address as 'ipaddressofsqlserver'
,client_net_address as 'clientipaddress'
 from sys.dm_exec_connections where session_id = @@spid