WaitType:ASYNC
项目组有一个数据库备份的Job运行异常,该Job将备份数据存储到remote server上,平时5个小时就能完成的备份操作,现在运行19个小时还没有完成,backup命令的Wait type是 ASYNC_IO_COMPLETION:

根据MSDN 官方文档的定义:Occurs when a task is waiting for asynchronous I/O operations to finish.
该等待类型表示:Task在等待异步IO操作的完成。进程申请了一个IO操作,但是系统(Disk/Network)不能立即完成该IO请求,因此该进程进入等待状态,等待Async IO完成。
查看SQL Server的Error Log,发现大量IO请求超时的记录,从File 的路径 [D:\xxx\yyy.ndf] 上看到,IO 请求是发送给Local Server,说明SQL Server发出的IO请求,Local Server的Disk不能及时完成:
SQL Server has encountered 1 occurrence(s) of I/O requests taking longer than 15 seconds to complete on file [D:\xxx\yyy.ndf] in database [database_name] (8). The OS file handle is 0x00000000000010E4. The offset of the latest long I/O is: 0x00000482f60000
出现长时间的ASYNC_IO_COMPLETION 等待的原因可能是:
- 同时有其他Application在进行大量的IO操作,导致用来存储备份数据的Disk特别忙,备份操作必须等待Disk IO完成。
- 如果备份数据存储到remote server上,那么可能是network被其他application占用,导致用于传输备份数据的带宽变小。
我看到的这个异常的备份操作,是将备份数据存储到远程Server上,打开ResouceMonitor(点击Windows+R,输入resmon),发现Disk Activity是2MB-4MB之间,而Network Activity在18MB-46MB之间,如图:


这说明,Remote Server的network相对比较忙,网络传输很可能是导致备份操作长时间运行的root cause。但是,从SQL Server的Error Log中得知,是本地Disk的不能及时响应IO请求。
由于备份操作已经结束,没有办法查看Local Server的Disk IO和 Network Activity,而此时,Remote Server上的Disk Activity 和 Network Activity 十分平静,都在几百KB水平上,间接说明Remote Server不是backup操作等待异步IO操作完成的root cause,Local Server的Disk IO是瓶颈。
分析Disk IO的性能,最好的方法是分析Performance Counter。打开Local Server的Performance Monitor(点击Windows+R,输入perfmon),没有记录Data Collection,这样没有办法进行深入的分析了,下次遇到时,继续分析。
总之:在数据库备份或还原的过程中,出现长时间的ASYNC_IO_COMPLETION 等待,表示backup/restore操作正在等待获取IO资源,导致backup/restore 进程处于挂起状态(suspended),只有获取到IO资源,该操作才会继续进行下去。
在执行长时间的IO密集的操作时,SQL Server进程经常会发生ASYNC_IO_COMPLETION等待,同时会在Error Log中记录 “I/O requests are taking longer than 15 seconds to complete” 消息,IO密集的操作主要有:backup/restore操作,新建一个大的数据库文件,和数据库文件增长。长时间执行IO密集操作,本来就需要大量的IO才能完成,但是,长时间处于ASYNC_IO_COMPLETION 等待,在很大程度上,表明IO是系统的瓶颈,Disk的读写能力或Network的传输能力是系统的短板。
Appendix:使用以下脚本查看备份操作的等待类型,已经完成的百分比,对于预估的剩余时间,只是个预估值,不可信。

select r.session_id,
r.blocking_session_id as blocking,
r.wait_type as Current_Wait_Type,
r.wait_time/1000/60/60 as wait_h,
r.status,
r.command,
r.total_elapsed_time/1000/60/60 as total_h,
r.percent_complete,
r.estimated_completion_time/1000/60/60 as estimated_h
from sys.dm_exec_requests r
outer APPLY sys.dm_exec_sql_text(r.sql_handle) as st
where (r.wait_type<>'MISCELLANEOUS' or r.wait_type is null)
and r.session_id>50
and r.session_id<>@@spid

推荐阅读《ASYNC_IO_COMPLETION Wait type》:
- Adding additional IO bandwidth.
- Balancing IO across other drives.
- Reducing IO with appropriate indexing.
- Check for bad query plans.
- Check for memory pressure
参考文档:
WaitType:ASYNC的更多相关文章
- EntityFramework 如何进行异步化(关键词:async·await·SaveChangesAsync·ToListAsync)
应用程序为什么要异步化?关于这个原因就不多说了,至于现有项目中代码异步化改进,可以参考:实际案例:在现有代码中通过async/await实现并行 这篇博文内容针对的是,EntityFramework ...
- ES7前端异步玩法:async/await理解
在最新的ES7(ES2017)中提出的前端异步特性:async.await. 什么是async.await? async顾名思义是"异步"的意思,async用于声明一个函数是异步的 ...
- python3.7新增关键字:async、await;带来和kafka-python==1.4.2的兼容性问题
python3.7新增关键字:async.await: kafka-python==1.4.2用到了关键字async,由此带来兼容性问题 解决方案: 升级kafka-python==1.4.4 使用p ...
- C++11并发编程:async,future,packaged_task,promise
一:async std::async:用于创建异步任务,可以代替创建线程,函数原型:async(std::launch::async | std::launch::deferred, f, args. ...
- ES7前端异步玩法:async/await理解 js原生API妙用(一)
ES7前端异步玩法:async/await理解 在最新的ES7(ES2017)中提出的前端异步特性:async.await. 什么是async.await? async顾名思义是“异步”的意思,a ...
- C#线程学习笔记十:async & await入门三
一.Task.Yield Task.Yield简单来说就是创建时就已经完成的Task,或者说执行时间为0的Task,或者说是空任务,也就是在创建时就将Task的IsCompeted值设置为0. 我们知 ...
- 深入理解协程(三):async/await实现异步协程
原创不易,转载请联系作者 深入理解协程分为三部分进行讲解: 协程的引入 yield from实现异步协程 async/await实现异步协程 本篇为深入理解协程系列文章的最后一篇. 从本篇你将了解到: ...
- 深入理解协程(四):async/await异步爬虫实战
本文目录: 同步方式爬取博客标题 async/await异步爬取博客标题 本片为深入理解协程系列文章的补充. 你将会在从本文中了解到:async/await如何运用的实际的爬虫中. 案例 从CSDN上 ...
- [每日一题]面试官问:Async/Await 如何通过同步的方式实现异步?
关注「松宝写代码」,精选好文,每日一题 时间永远是自己的 每分每秒也都是为自己的将来铺垫和增值 作者:saucxs | songEagle 一.前言 2020.12.23 日刚立的 flag,每日一 ...
随机推荐
- JAVA 基础编程练习题36 【程序 36 移动位置】
36 [程序 36 移动位置] 题目:有 n 个整数,使其前面各数顺序向后移 m 个位置,最后 m 个数变成最前面的 m 个数 package cskaoyan; public class cskao ...
- Delphi 中自定义异常及异常处理的一般方法
delphi中异常定义如下: TCustomException = class(Exception) private public constructor ...
- ElasticSearch——集群搭建
1.准备 1.1.组件 JDK:1.8版本及以上: ElasticSearch:6.2.4版本: 1.2.服务器 3台服务器 2.安装 2.1.下载解压 wget https://artifacts. ...
- 实现多个JSP页面共用一个菜单
1.首先将菜单栏代码独立为一个jsp页面 例如 <%@ page language="java" contentType="text/html; charset=U ...
- 彻底搞定Javascript事件循环
参考链接:https://juejin.im/post/5dca8a8be51d45227239abc4?utm_medium=hao.caibaojian.com&utm_source=ha ...
- CentOS 7.5在线安装Docker 18.09.3
1.安装依赖包 yum -y install yum-utils device-mapper-persistent-data lvm2 2.安装docker yum-config-manager -- ...
- JavaSE基础(九)--Java二进制运算
Java二进制运算 Java二进制表示法 首先了解下二进制,二进制是相对十进制而言的,当然还有八进制,十六进制等等,我们常用的都是十进制,计算机用的都是二进制,而符号表示常用十六进制. 二进制就是只有 ...
- Python基础总结之第八天开始【while循环以及for循环,循环嵌套等循环相关的知识点】(新手可相互督促)
ennnnn,年薪20万的梦想是不是又进了一步: 循环,什么是循环,循环就是电池有电,手机屏幕可以循环一整天的使用:循环就是地球不毁灭,太阳日复一日的出现...... 不接受反驳,谢谢!~ 只要条件满 ...
- 记录一次hadoop2.8.4版本RM接入zk ha问题
背景: 公司将线上hadoop RM接入ZK 实现高可用 但ZK Znode 默认存储1M,当存储数据量大时候可能导致线上业务的崩溃 处理方案如下: 1,修改ZK配置 增加默认存储上限 2,修改RM数 ...
- 【转载】MyBatis批量插入数据(insert)
介绍:MyBatis批量插入数据,原理就是在xml文件中添加 foreach 语句,然后MyBatis自动在values后面添加多个括号: XML文件如下: <?xml version=&quo ...