当前位置:首页 > 问答 > 正文

说说Oracle数据库里那个异步IO到底是咋回事,简单介绍下原理和应用

说到Oracle数据库里的异步I/O,咱们可以把它想象成一个特别能干的餐厅服务员,你想弄懂它,先得知道它的反面——同步I/O是个什么样的。

(来源:基于Oracle官方文档中关于I/O模型的对比描述)

想象一下你去一家餐厅,只有一个服务员,你点完菜(这相当于数据库发出一个读取数据的请求),这个服务员就什么都不干了,直接跑到厨房门口,死死地盯着厨师,直到你的菜做好,他端上来给你,然后才去服务下一桌客人,这个过程中,服务员大部分时间都在“等待”,他的劳动力被白白浪费了,这就是同步I/O,数据库进程发起一个读或写磁盘的请求后,它自己就被“挂起”了,什么事也干不了,必须傻傻地等着慢吞吞的磁盘硬件把活儿干完,把数据送回来,它才能继续处理后续的工作,如果同时有很多客人点菜,餐厅就会排起长队,响应非常慢。

异步I/O就厉害了,这个服务员变了身,他变成了一个手里拿着对讲机、脚下踩着风火轮的超级服务员,你点完菜,他不用自己去厨房门口等,他用对讲机告诉厨房:“A桌要一份红烧肉!”(这相当于数据库向操作系统提交一个I/O请求),然后他根本不等回信,扭头就去B桌点菜、给C桌结账了,厨房做好菜后,会通过对讲机通知他:“A桌的菜好了。”服务员在忙完手头一点小事后,或者在他固定的巡查路线上,顺手就把菜给A桌端上去了,你看,这个服务员(数据库进程)的劳动力被充分利用了,他等待的时间被压缩到了极致,整个餐厅的吞吐量(单位时间内服务的客人数)大大提升。

说说Oracle数据库里那个异步IO到底是咋回事,简单介绍下原理和应用

(来源:Oracle性能优化相关书籍和文章中对AIO优势的普遍阐释)

把这个道理套回Oracle数据库上,具体是怎么运作的呢?

原理其实不复杂:

说说Oracle数据库里那个异步IO到底是咋回事,简单介绍下原理和应用

  1. 发起请求,然后放手: 当Oracle需要从磁盘读取一个数据块,或者要把内存中修改过的数据块写回磁盘时,如果启用了异步I/O,它不会自己傻等,它会向操作系统内核发出一个I/O请求,说:“嘿,帮我把这个数据读进来/写出去”,然后这个Oracle进程立刻就自由了,它可以马上去处理CPU计算、解析SQL、或者在内存中处理其他已经读上来的数据块。
  2. 操作系统接手: 操作系统内核有一个专门的机制来处理这些I/O请求队列,它负责与磁盘驱动器等硬件打交道,管理实际的读写操作,这个活由操作系统来干效率很高,因为它更底层,能更好地调度硬件资源。
  3. 通知完成: 当操作系统完成这个I/O操作后,它会通过一种机制(比如回调函数或者设置一个状态标志)通知Oracle:“你之前交代的那个活儿,我干完了啊。” Oracle进程在后续的某个时间点(比如它下次需要检查I/O状态时)会收到这个通知,然后就知道数据已经准备就绪了。

这个过程的关键在于“解耦”,把“发出请求”和“等待完成”这两件事分开了,数据库进程不用被I/O这种慢速操作阻塞,可以持续不断地让CPU忙起来,从而极大地提高了数据库的并发处理能力和整体吞吐量。

那这个厉害的功能,具体用在哪些地方呢?

(来源:Oracle管理手册中关于关键后台进程和特性的说明)

说说Oracle数据库里那个异步IO到底是咋回事,简单介绍下原理和应用

  1. DBWR(数据库写入器)进程: 这是异步I/O的最大受益者,DBWR负责将内存中脏数据块(被修改过的数据)写回数据文件,这是个非常繁重的I/O任务,如果使用同步I/O,DBWR写一个数据块就要等一次磁盘,速度会非常慢,进而可能导致“自由缓冲区等待”之类的性能问题,因为内存中没有空闲块给新数据用了,而启用异步I/O后,DBWR可以一次性向操作系统提交一大批写请求,然后就可以稍微休息一下,或者继续准备下一批要写的数据块,操作系统会并行地、尽可能快地将这批数据写入磁盘,这就像服务员一次性给厨房下了10个菜的订单,而不是跑10次厨房,效率天差地别。

  2. 直接路径操作: 比如像CREATE TABLE ... AS SELECT(CTAS)这种大量数据加载的操作,或者使用/*+ APPEND */提示的INSERT语句,以及索引重建等,这些操作为了追求速度,会绕过内存中的数据缓存区,直接读写磁盘,如果使用异步I/O,这些操作可以同时发起多个读写请求,让磁盘系统保持满负荷运转,从而最快速度完成大量数据的搬运。

  3. RMAN(恢复管理器)备份: 当你用RMAN备份数据库时,需要读取大量的数据文件,启用异步I/O可以让RMAN进程最大限度地榨取磁盘的读取带宽,它不停地发出读请求,而不用等上一个读完再读下一个,使得备份速度显著提升,恢复的时候也是同样的道理。

  4. 重做日志写入: 虽然关键的LGWR(日志写入器)进程为了保证事务的持久性,其写入模式有特殊要求(通常要求强制写入磁盘),但在一些平台和配置下,也能从异步I/O技术中获益,优化其写入性能。

需要注意的一点是: 异步I/O虽然好,但它并不是一个你开了就万事大吉的魔法开关,它的效果严重依赖于底层的操作系统和硬件是否支持,好在现在主流的操作系统(如Linux、AIX、Solaris等)都对异步I/O有很好的支持,在Linux上,Oracle甚至可以用一种叫做“Linux原生异步I/O”的模式,以获得更好的性能,数据库管理员通常需要在初始化参数文件中设置DISK_ASYNCH_IO等参数来启用和调控它。

Oracle数据库的异步I/O就是一个“会喊人帮忙”的聪明机制,它把最耗时的“跑腿”活儿外包给操作系统,自己则专注于更擅长的“脑力劳动”(数据处理),通过这种分工协作,避免了“CPU等I/O”的尴尬局面,让整个数据库系统跑得更快、更流畅,这在处理高并发、大数据量的现代业务场景中,是一项至关重要的基础性能优化技术。