DBWR 数据库写入进程
前言
在讲DBWR进程之前,简单介绍下working set。
即working set=LRU+LRUW。LRU和LRUW总是成对出现。LRU指的是替换列,主要分为主列和辅助列。主列指的是已使用的缓冲区列,以hot区域和cold区域区分管理。LRUW指的是记录列。也分为主列和辅助列。主列主要指的是已修改的缓冲区列。辅助列指的是当前DBWR写入中的缓冲区列。
一句话说明
DBWR (Database Writer)进程负责将dirty list(脏数据表)从数据缓存(database block buffer)写回磁盘;
该进程主要有以下几个作用
1.管理数据缓冲区,以便用户进程总能找到空闲的缓冲区
2.将所有修改的缓冲区数据写入数据文件
3.使用LRU算法,通过延迟写,将最近使用过的块保留在内存,优化IO读写
运行机制介绍
当一个事务修改数据块中的数据以后,不需要立即将数据块写回磁盘。由于Oracle所采用的先进机制,修改后的数据可以不用立即写回,并且即使出现故障也不会丢失。因此,DBWR可以采取更有效写回方式,而不用再事务提交完之后立即写回。DBWR通常定时写回数据,除非数据缓冲区需要清空或已满。
工作过程如下
-
当用户进程产生之后,服务器查找内存缓冲区是否存在用户进程所需要的数据;
-
如果内存中没有,则服务器进程从内存中将数据文件读取出来,此时,服务器进程会首先从LRU中查找是否有存放数据的空闲块
-
如果LRU没有空闲块,则将LRU中的dirty数据块迁入dirty list(脏数据表)
-
如果dirty list超长,服务器进程将会通知DBWn进程将数据写入磁盘,刷新缓冲区。
-
当LRU中有空闲块后,服务器进程从磁盘的数据文件中读取数据并存放到存放到数据缓冲区中。
数据写回时,采用了最近最少使用原则(least-recently-used).对于支持异步I/O的系统,只需使用一个DBWR进程即可,对不支持异步IO的
可以通过增加DBWR的个数来提升效率。所以有些时候称作有些地方也写作DBWn。
允许DBWn进程个数由参数db_writer_processes决定,可以使用Show parameter语句查看该参数信息,最多启动20个。DBW0-DBW9,以及DBWa-DBWj。
DBWR触发条件
1. 产生检查点,DBWR会将dirty的缓存写到磁盘。
2. 脏数据缓冲区达到阀值 默认 10%
3.扫描整个data buffer个数阈值(由隐藏参数:_db_block_max_scan_pct,代表已经扫描的buffer header的个数占整个LRU链表上buffer header总数的百分比),data buffer 中包含脏的和未脏的优先写脏数据列表 再写未脏块
4. timeout 超时,如果DBWR没事做会被每三秒唤醒一次去巡检 写不写不一定
5. 表级别的truncate或drop也会触发数据写
6. 修改表空间的read only
7. 数据文件或表空间的offline (离线)
8. 热备份 begin backup 命令
其中1:检查点这个触发条件下:
由CKPT 通知DBWR 去写,每次告诉DBWR 写到队列的什么地方,与主机的I/O效率有关,也就是CKPT 是监工,向 DBWR 提交任务, DBWR 即为劳力。
其中3的触发过程如下:
当进程在辅助LRU链表和主LRU链表上扫描以查找可以覆盖的buffer header(空闲缓冲区)时,如果已经扫描的buffer header的数量到达一定的限度(由隐藏参数:_db_block_max_scan_pct决定)时,触发DBWR进程。 _db_block_max_scan_pct表示已经扫描的buffer header的个数占整个LRU链表上buffer header总数的百分比。通过DBWR保证拥有空闲缓冲区为止,这时,搜索可用buffer header的进程挂起,在v$session_wait中表现为等待“free buffer wait”事件,同时增加v$sysstat中的“dirty buffers inspected”和“DBWR make free requests”的值。
其他注意点
1、新增的DBWn不能在单处理器中使用,对于数量,每8个CPU可以至少利用一个DBWR进程,如果是处理器组,那么有多少个处理器组,就应该有多少个DBWR进程。
2、DBWR是批量(多块)写入,以提高性能。块的数量在不同的操作系统有不同的设置。
3、Oracle 有多种缓冲池(buffer pool),各缓冲池分别使用不同的锁存器:
4、锁存器的数量和DBWR数,CPU数量有关,若DBWR数小于4个,则创建4*CPU_COUNTlru个锁存器;若DBWR数大于4,则创建DB_WRITER_PROCESSED*CPU_COUNT个锁存器。
操作层面
1、通过以下视图可以看到DBWR进程写出block的触发条件
SQL> select name,value from v$sysstat where name like 'DBWR%';