SQL Server排查异常慢SQL及性能

0    153    3

Tags:

👉 本文共约11749个字,系统预计阅读时间或需45分钟。

简介

作为数据库管理员,很多时候会遇到线上堵塞的情况,或者是客户与相关部门同事反馈系统出现等待。虽然整个架构各环节都有可能影响着业务系统的性能,但是他们往往首先把“矛头”指向数据库。那么,这时候你该如何处理呢?

即使很多时候不是数据库的问题,但是在数据库端进行排查,也可以间接发现引起系统慢的原因。比如,网络带宽、磁盘、连接、代码、SQL等各种问题。在问题发生的时刻,线上排查是最容易发现问题根源的。而有的时候,我们可能还没发现问题根源,就用了其他手段先解决了当下的问题,待后续再进行问题溯源。

作为数据库的管理员,我们应该知道如何在线上排查问题,或者在事件过后确认问题,以防止此类事件再次发生。在SQL Server中,大部分的问题都反映在连接和执行的SQL上,如果你知道如何查找这些连接和SQL,你就可以从中判断系统问题了。

线上堵塞如何排查?

  1. 通过监控系统或告警信息确认数据库系统是否正常运行;
  2. 通过监控系统或告警信息确认CPU、Mem、IO、带宽是否异常;
  3. 通过监控系统确认数据库实例的连接数、堵塞/死锁情况、长事务、QPS/TPS、命中率等是否异常;
  4. 通过数据库系统记录的历史运行数据,确认是否异常;
  5. 通过数据库错误日志及Windows系统日志是否报错;

以上的排查问题在事发前、中、后的基本处理方案。但是,一个平时稳定运行的系统,通常很少出现异常。除非你对操作系统或数据库实例进行了相关补丁和更改参数。如果仅仅是日常的产品升级、SQL脚本升级,在数据库中几乎都可以通过连接发现其中的问题。

首先了解几个系统DMV,用于查看当前的连接信息。

  • sys.dm_exec_connections 记录当前连接到实例的连接协议、网络信息等。
  • sys.dm_exec_sessions 记录当前连接到实例的客户端信息、配置信息、操作统计信息等。
  • sys.dm_exec_requests 记录当前正在请求的信息,如执行参数、等待信息、资源消耗信息等。
  • sys.sysprocesses 记录当前活动连接(包括正在请求)的客户端信息、等待信息、资源消耗信息等。

以上几个DMV,我们可以从中获取到以下的关键信息:

关键信息dm_exec_connectionsdm_exec_sessionsdm_exec_requestssysprocesses
sql_handle1011
plan_handle0010
Blocked Session0011
Status0111
WaittypeWait Resources0011
CPU/IO/Men/Rows1111
Running Time1111
Client info0101

其中dm_exec_requests与sysprocesses可以确认当前系统正在执行中的连接、该连接处于什么状态、是否被堵塞、堵塞类型及等待资源、执行了多长时间、消耗的资源如何、客户端信息等。这些都是非常重要关键信息,在表中都有相应的字段对应。此外,还可以通过sql_handle与sys.dm_exec_sql_text()查看最近执行的SQL语句。

首先在线查看当前数据库连接的运行情况(如通过sysprocesses查看),重点关注正在运行的连接(kpid>0)、堵塞连接(blocked>0)、未提交的连接(open_tran>0)

参考:https://www.xmmup.com/shujukudangqianhuihuachaxunhuizongdangqianxingnengwentikuaisufenxi.html#SQL_server

按这几类确认当前连接数是否过多,或在确认线程情况sys.dm_os_threads是否充足。

重点关注status与waittype,可以确定当前连接正在等待什么资源,如网络IO等待ASYNC_NETWORK_IO(说明网络堵塞、或者客户端读取大量数据)、线程等待CXPACKET(说明并发执行SQL)、日志写等待WRITELOG(说明大量数据更改、或者磁盘问题)、线程调度等待SOS_SCHEDULER_YIELD(CPU或线程不足、或是没有索引、任务耗时长等)……waittype类型几百个,从该类型的等待情况,可以间接判断问题发生在哪里。(更多等待事件说明请参考:https://www.sqlskills.com/help/waits/

有哪些异常SQL,如何确认?

  • 在线SQL(正在运行的SQL、堵塞SQL、未提交的SQL)

  • 慢SQL

  • 堵塞SQL

  • 死锁SQL

在线SQL/在线连接:通过上文中的SQL脚本,我们可以查询到正在运行的SQL、堵塞SQL、未提交的SQL,但是只能查询到系统当前时刻正在连接或运行的SQL。通过当前连接情况判断此刻堵塞的原因。线上的SQL如果出现大量堵塞,评估影响情况后,可以把堵塞的SQL连接进行kill回滚。

慢SQL:慢SQL需要跟踪收集才能发现,不可能每次都在线查询SQL去判断,且在线查询不能准确得到慢SQL的资源开销情况。通过扩展事件rpc_completed与sql_batch_completed来记录SQL的运行结果,注意添加筛选条件duration(单位为微妙)。此时慢SQL跟踪的是执行结束的SQL,只有执行结束,才能确认具体开销情况。

堵塞SQL:堵塞SQL也需要跟踪收集才能被记录。通过扩展事件blocked_process_report记录堵塞的事件。记录信息为XML格式。

死锁SQL:系统自动启用的扩展事件system_health可以捕获到死锁,只不过捕获不全且会被循环覆盖。你也可以通过跟踪标志1222或者1204进行捕获,死锁信息则记录到SQL Server 错误日志中,但这并不好筛选。可以通过扩展事件xml_deadlock_report记录死锁事件。记录信息为XML格式。

事后排查方法

我们已经通过线上排查,或者通过SQL跟踪,可以找到异常的连接和异常SQL。那么,如果问题已经结束。我们还能如何确认系统的历史运行情况呢?

本人提供Oracle(OCP、OCM)、MySQL(OCP)、PostgreSQL(PGCA、PGCE、PGCM)等数据库的培训和考证业务,私聊QQ646634621或微信db_bao,谢谢!
SQL Server排查异常慢SQL及性能后续精彩内容已被小麦苗无情隐藏,请输入验证码解锁本站所有文章!
验证码:
请先关注本站微信公众号,然后回复“验证码”,获取验证码。在微信里搜索“DB宝”或者“www_xmmup_com”或者微信扫描右侧二维码都可以关注本站微信公众号。

标签:

Avatar photo

小麦苗

学习或考证,均可联系麦老师,请加微信db_bao或QQ646634621

您可能还喜欢...

发表回复

嘿,我是小麦,需要帮助随时找我哦。
  • 18509239930
  • 个人微信

  • DB宝
  • 个人邮箱
  • 点击加入QQ群
  • 个人微店

  • 回到顶部