zoukankan      html  css  js  c++  java
  • 【监控实践】【3.4】使用DMV和函数监控数据库状态和资源使用

    0.类别DMV

    官网:https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2005/ms189741(v=sql.90)

    • dm_db_*:数据库和数据库对象
    • dm_exec_*:执行用户代码和关联的连接
    • dm_os_*:内存、锁定和时间安排
    • dm_tran_*:事务和隔离
    • dm_io_*:网络和磁盘的输入/输出

    0.1.最常用DMV

      参考:https://www.cnblogs.com/gered/p/9239996.html

    --一些核心DMV

    select
    * from test.sys.dm_tran_locks --库级别:查看该库锁情况 select * from master.sys.dm_os_performance_counters --实例级别:启动后的累计性能计数器 select * from master.sys.dm_os_wait_stats --实例级别:查看当前所有等待统计 select * from master.sys.dm_os_waiting_tasks --实例级别:查看当前所有等待的进程任务情况 select * from master.sys.dm_exec_requests --实例级别:查看当前所有的请求信息 select * from master.sys.dm_exec_sessions --实例级别:查看当前所有的登陆会话信息 select * from master.sys.dm_exec_connections --实例级别:查看当前所有的连接信息 select * from master.sys.sysprocesses --实例级别:查看当前所有的连接进程 select * from master.sys.dm_exec_query_stats --实例级别:查看执行计划/缓存,以此可以查看过去一段时间的慢SQL cross apply sys.dm_exec_sql_text(sql_handle) --一般用这个函数来解析sql语句 exec sp_who --查看实例登陆情况系统sp exec sp_who2 'sa' --查看制定用户登录情况 exec sp_lock --查看实例锁情况

    【1】一些常用的实践

    【1.1】查看当前实例运行进程

    -- 核心DMV、函数、系统SP:
    /*
      所有进程请求:sys.dm_exec_requests
      所有进程与连接:sys.sysprocesses
      系统函数,查看sql:
    sys.[dm_exec_sql_text] --根据sql_handle
      dbcc命令,查看进程sql:dbcc inputbuffer(spid/session_id)
      系统函数,查看执行计划:sys.dm_exec_query_plan --根据plan_handle
      查看短期内执行计划状态:dm_exec_query_stats
      查看数据库信息:sys.databases
    */

    select db_name(r.database_id) db_name,status,start_time,command,percent_complete,wait_type,text as parent_query, substring(s.text,r.statement_start_offset/2, (case when r.statement_end_offset = -1 then len(convert(nvarchar(max), s.text)) * 2 else r.statement_end_offset end - r.statement_start_offset)/2) as query_text, session_id,blocking_session_id from sys.dm_exec_requests r cross apply sys.dm_exec_sql_text(r.sql_handle) s

    -- 相关查询
    --详细版
    SELECT TOP 10
    [cpu_time],
    [session_id],
    [request_id],
    [start_time] AS '开始时间',
    [status] AS '状态',
    [command] AS '命令',
    dest.[text] AS 'sql语句', 
    DB_NAME([database_id]) AS '数据库名',
    [blocking_session_id] AS '正在阻塞其他会话的会话ID',
    [wait_type] AS '等待资源类型',
    [wait_time] AS '等待时间',
    [wait_resource] AS '等待的资源',
    [reads] AS '物理读次数',
    [writes] AS '写次数',
    [logical_reads] AS '逻辑读次数',
    [row_count] AS '返回结果行数'
    FROM sys.[dm_exec_requests] AS der 
    CROSS APPLY 
    sys.[dm_exec_sql_text](der.[sql_handle]) AS dest 
     
    ORDER BY [cpu_time] DESC
    
    --相关查阅
    SELECT  spid,
                start_time,
                [Database] = DB_NAME(sp.dbid) ,
                command,
                [User] = nt_username ,
                [Status] = er.status ,
                [Wait] = wait_type ,
                [Individual Query] = SUBSTRING(qt.text,
                                               er.statement_start_offset / 2,
                                               ( CASE WHEN er.statement_end_offset = -1
                                                      THEN LEN(CONVERT(NVARCHAR(MAX), qt.text))
                                                           * 2
                                                      ELSE er.statement_end_offset
                                                 END - er.statement_start_offset )
                                               / 2) ,
                [Parent Query] = qt.text ,
                Program = program_name ,
                hostname ,
                nt_domain ,
    [Spid] = session_id ,
    blocking_session_id
    FROM sys.dm_exec_requests er INNER JOIN sys.sysprocesses sp ON er.session_id = sp.spid CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) AS qt 
    WHERE session_id > 50 -- Ignore system spids. 
    AND session_id NOT IN ( @@SPID ) -- Ignore this current statement. ORDER BY 1
    
    --查看所有SQL正在执行的进度详情
    SELECT
    r.session_id ,
    DB_NAME(qt.[dbid]) AS [DatabaseName] ,
    r.start_time,
    r.[status],
    r.blocking_session_id,
    SUBSTRING(qt.[text], r.statement_start_offset / 2,
    ( CASE WHEN r.statement_end_offset = -1
    THEN LEN(CONVERT(NVARCHAR(MAX), qt.[text])) * 2
    ELSE r.statement_end_offset
    END - r.statement_start_offset ) / 2) AS [statement] ,
    r.wait_type,
    r.wait_time,
    r.wait_resource,
    r.cpu_time ,
    r.total_elapsed_time / 60000 AS[elapsed_minutes],
    r.reads ,
    r.writes ,
    r.logical_reads,
    s.host_name,s.program_name
    FROM sys.dm_exec_requests AS r
    join sys.dm_exec_sessions s on r.session_id = s.session_id
    CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS qt
    WHERE r.session_id > 50
    ORDER BY 1
    
     
    
     
    
    ---SQL Server查询正在执行的SQL语句及执行计划
    select ds.session_id,dr.start_time,db_name(dr.database_id),dr.blocking_session_id,ds.host_name,
    ds.program_name,ds.host_process_id,ds.login_name,dr.status,
    dr.command,dr.wait_type,dr.wait_time,dr.open_transaction_count,
    dr.percent_complete,dr.estimated_completion_time,dr.row_count,
    SUBSTRING(st.text, (dr.statement_start_offset/2)+1, 
    ((CASE dr.statement_end_offset
    WHEN -1 THEN DATALENGTH(st.text)
    ELSE dr.statement_end_offset
    END - dr.statement_start_offset)/2) + 1) AS statement_text,
    st.text as full_text,
    qp.query_plan
    from sys.dm_exec_sessions ds,sys.dm_exec_requests dr--,sys.dm_exec_query_stats qs
    CROSS APPLY sys.dm_exec_sql_text(dr.sql_handle) AS st 
    CROSS APPLY sys.dm_exec_query_plan(dr.plan_handle) as qp
    where ds.session_id>50
    and dr.session_id<>@@spid
    and ds.session_id=dr.session_id
    --and dr.sql_handle=qs.sql_handle
    and dr.database_id>4
    
    -- 2008R2以下版本 想要看图形界面,直接复制内容,重命名为.sqlplan
    
     
    
    --查看阻塞与被阻塞语句
    
    SELECT R.session_id AS BlockedSessionID , 
    S.session_id AS BlockingSessionID , 
    Q1.text AS BlockedSession_TSQL , 
    Q2.text AS BlockingSession_TSQL , 
    C1.most_recent_sql_handle AS BlockedSession_SQLHandle , 
    C2.most_recent_sql_handle AS BlockingSession_SQLHandle , 
    S.original_login_name AS BlockingSession_LoginName , 
    S.program_name AS BlockingSession_ApplicationName , 
    S.host_name AS BlockingSession_HostName 
    FROM sys.dm_exec_requests AS R 
    INNER JOIN sys.dm_exec_sessions AS S ON R.blocking_session_id = S.session_id 
    INNER JOIN sys.dm_exec_connections AS C1 ON R.session_id = C1.most_recent_session_id 
    INNER JOIN sys.dm_exec_connections AS C2 ON S.session_id = C2.most_recent_session_id 
    CROSS APPLY sys.dm_exec_sql_text(C1.most_recent_sql_handle) AS Q1 
    CROSS APPLY sys.dm_exec_sql_text(C2.most_recent_sql_handle) AS Q2
    查看当前实例正在运行的SQL进程与阻塞情况

    【1.2】查看当前实例锁信息

    -- 核心DMV:
    /*
      参考联机丛书:https://docs.microsoft.com/zh-cn/sql/relational-databases/system-dynamic-management-views/sys-dm-tran-locks-transact-sql?view=sql-server-2017
      查看锁信息DMV:sys.dm_tran_locks
      锁视图:sp_lock
    */
    SELECT l.resource_type, l.resource_associated_entity_id
     ,OBJECT_NAME(sp.OBJECT_ID) AS ObjectName
     ,l.request_status, l.request_mode,request_session_id
     ,l.resource_description
     FROM sys.dm_tran_locks l
     LEFT JOIN sys.partitions sp
      ON sp.hobt_id = l.resource_associated_entity_id
     WHERE l.resource_database_id = DB_ID()

    【1.3】查看当前实例阻塞信息

    /* 
      等待任务:sys.dm_os_waiting_tasks
      锁拥有者信息:t1.lock_owner_address
      系统分区信息:sys.partitions
    */

    SELECT
    t1.resource_type ,db_name(t1.resource_database_id) as db_name ,t1.resource_associated_entity_id ,OBJECT_NAME(sp.OBJECT_ID) AS ObjectName ,t1.request_mode ,t1.request_session_id ,t2.blocking_session_id FROM sys.dm_tran_locks as t1 JOIN sys.dm_os_waiting_tasks as t2 ON t1.lock_owner_address = t2.resource_address LEFT JOIN sys.partitions sp ON sp.hobt_id = t1.resource_associated_entity_id

    【1.4】查看索引使用率

    索引相关优化参考另一篇博文:https://www.cnblogs.com/gered/p/11044571.html

    /*
      查看数据库信息:sys.databases
      查看索引使用率:sys.dm_db_index_usage_stats
      查看所有索引:sys.indexes
      查看数据库所有对象:sys.all_objects , sysobjects
    */
    SELECT
      sd.name AS DatabaseName
     ,so.name AS ObjectName
     ,si.name AS IndexName
     ,diu.user_seeks
     ,diu.user_scans
     ,diu.user_lookups
     ,diu.user_updates
     ,diu.last_user_seek
     ,diu.last_user_scan
     ,diu.last_user_lookup
     ,diu.last_user_update
     ,GETDATE() AS StatusDate
     FROM sys.dm_db_index_usage_stats  diu
     JOIN sys.indexes si
       ON diu.object_id = si.object_id
      AND diu.index_id = si.index_id
     JOIN sys.all_objects so
       ON so.object_id = si.object_id
     JOIN sys.databases sd
       ON sd.database_id = diu.database_id
     WHERE is_ms_shipped <> 1
       AND diu.database_id = DB_ID()

    【1.5】没有使用的索引

    --------------------------------------------------------------------------
     --This will store the indexes which are not used.
     
    /*
    IF OBJECT_ID('dbo.NotUsedIndexes') IS NULL CREATE TABLE dbo.NotUsedIndexes ( IndexName sysname NULL ,ObjectName sysname NOT NULL ,StatusDate datetime NOT NULL ,DatabaseName sysname NOT NULL ) ----Below query will give you index which are NOT used per table in a database. INSERT dbo.NotUsedIndexes ( IndexName ,ObjectName ,StatusDate ,DatabaseName )
    */
    SELECT si.name AS IndexName ,so.name AS ObjectName ,GETDATE() AS StatusDate ,DB_NAME() FROM sys.indexes si JOIN sys.all_objects so ON so.object_id = si.object_id WHERE si.index_id NOT IN (SELECT index_id FROM sys.dm_db_index_usage_stats diu WHERE si.object_id = diu.object_id AND si.index_id = diu.index_id ) AND so.is_ms_shipped <> 1 -- select * from NotUsedIndexes

    【1.6】查看等待内存授权的数据(2005不可用,2012及以上)

    SELECT
    es.session_id AS SPID
    ,es.login_name
    ,es.host_name
    ,es.program_name, es.status AS Session_Status
    ,mg.requested_memory_kb
    ,DATEDIFF(mi, mg.request_time
    , GETDATE()) AS [WaitingSince-InMins]
    FROM sys.dm_exec_query_memory_grants mg
    JOIN sys.dm_exec_sessions es
    ON es.session_id = mg.session_id
    WHERE mg.grant_time IS NULL
    ORDER BY mg.request_time

    【1.7】查看实例连接信息

    详细参考:如何在SqlServer中获取前端连接的IP地址,计算机名等信息

    /*
    
      连接执行会话信息:Sys.dm_exec_Sessions
    
      每个连接的详细信息:Sys.dm_exec_connections
    
    */  
    
    SELECT login_name
    , count(session_id) as session_count
    FROM sys.dm_exec_sessions
    GROUP BY login_name

    【1.8】查看文件组信息

    -- Find the total size of each Filegroup
     select data_space_id, (sum(size)*8)/1000 as total_size_MB
     into #filegroups
     from sys.database_files
     group by data_space_id
     order by data_space_id
     
     -- FInd how much we have allocated in each FG
     select ds.name, au.data_space_id
     , (sum(au.total_pages) * 8)/1000 as Allocated_MB
     , (sum(au.used_pages) * 8)/1000 as used_MB
     , (sum(au.data_pages) * 8)/1000 as Data_MB
     , ((sum(au.total_pages) -  sum(au.used_pages) ) * 8 )/1000 as Free_MB
     into #Allocations
     from sys.allocation_units as au inner join sys.data_spaces as ds
         on au.data_space_id = ds.data_space_id
     group by ds.name, au.data_space_id
     order by au.data_space_id
     -- Bring it all together
     select f.data_space_id
     , a.name
     , f.total_size_MB
     , a.allocated_MB
     , f.total_size_MB - a.allocated_MB as free_in_fg_MB
     , a.used_MB
     , a.data_MB
     , a.Free_MB
     from #filegroups as f inner join #allocations as a
     on f.data_space_id = a.data_space_id
     order by f.data_space_id
     
     drop table #allocations
     drop table #filegroups

    【1.9】查看每个数据库的内存缓存

    --查看每个数据库缓存大小
    SELECT  COUNT(*) * 8 / 1024 AS 'Cached Size (MB)' ,
            CASE database_id
              WHEN 32767 THEN 'ResourceDb'
              ELSE DB_NAME(database_id)
            END AS 'Database'
    FROM    sys.dm_os_buffer_descriptors
    GROUP BY DB_NAME(database_id) ,
            database_id
    ORDER BY 'Cached Size (MB)' DESC

    【1.10】CPU、重编译

    https://www.cnblogs.com/gered/p/9961370.html

    同类参考文件(必看)

    sql server使用DMV排查系统异常   

    核心DMV

    select * from test.sys.dm_tran_locks --库级别:查看该库锁情况
    select * from master.sys.dm_os_performance_counters --实例级别:启动后的累计性能计数器
    select * from master.sys.dm_os_wait_stats --实例级别:查看当前所有等待统计
    select * from master.sys.dm_os_waiting_tasks --实例级别:查看当前所有等待的进程任务情况
    select * from master.sys.dm_exec_requests    --实例级别:查看当前所有的请求信息
    select * from master.sys.dm_exec_sessions     --实例级别:查看当前所有的登陆会话信息
    select * from master.sys.dm_exec_connections --实例级别:查看当前所有的连接信息
    select * from master.sys.sysprocesses         --实例级别:查看当前所有的连接进程
    select * from master.sys.dm_exec_query_stats --实例级别:查看执行计划/缓存,以此可以查看过去一段时间的慢SQL
    cross apply sys.dm_exec_sql_text(sql_handle) --一般用这个函数来解析sql语句 
    
    
    exec sp_who        --查看实例登陆情况系统sp
    exec sp_who2 'sa'  --查看制定用户登录情况
    exec sp_lock       --查看实例锁情况
  • 相关阅读:
    Java学习笔记-Lambda表达式
    Java学习笔记-枚举类
    Java学习笔记-枚举类
    Java学习笔记-包装类
    js 递归 汉诺塔的例子
    js 用 hasOwnProperty() 判定属性是来自该对象成员,还是原型链
    正则,js函数math()提取混乱字符串中多个字符串内容
    封装好的cookie的三个常用函数 cookie的添加、删除、提取操作函数
    解决ie6下png背景不能透明bug
    ie6下标签定义的高失效,显示的高不受设定的height值影响
  • 原文地址:https://www.cnblogs.com/gered/p/11338221.html
Copyright © 2011-2022 走看看