发生data file init write的等待是数据文件正在发生扩展,在11g中,这往往和SMCO和Wnnn进程的自动预扩展有关。
在生产环境中,如果在生产高峰期出现预扩展,可能会造成短暂的hang住,或者CPU突然的升高,或者查询dba_free_space的hang住。但是,预扩展这个功能是否好处大于坏处,是否需要关闭,我们用一些测试数据来说明。
在测试库测试了load大量数据到表中,触发SMCO进行自动预扩展,在测试中发现如下:
(1)开启预扩展时(即设置_enable_space_preallocation为默认值3),表空间在接近100%进行扩展,扩展的大小为当时表空间大小的5%。该行为收隐含参数_kttext_warning影响,默认值为5.(详见Doc ID 1459097.1),因此如果原来的表空间越大,那么预扩展的空间就越大,需要的时间也越长。处于data file init write的等待时间也越长。
(2)关于Wnnn进程会造成CPU的突然升高,是Bug 13871316 Wnnn space background process may be periodically CPU bound。但是是否hit中bug还是需要看其pstack和errorstack,看是否有和bug相关的call stack:ktslfsum_cfs<-ktslfsum<-ktslj_check_freespa<-ktslj_segextce<-ktsj_execute_task。做pstack和errorstack的方法见下: (2.1)用循环语句pstack wnnn进程,如Wnnn进程号为19750:
1 2 3 4 5 6 |
while true do echo "======`date`======" >>/tmp/pstack_19750.log pstack 19750 >>/tmp/pstack_19750.log sleep 3 done |
(2.2)errorstack方法:
1 2 3 4 5 |
SQL> setospid 19750 Oracle pid: 75, Unix process pid: 19750, image: oracle@z4as2020 (W001) SQL> oradebug dump errorstack 3 Statement processed. SQL> oradebug tracefile_name |
(3)在我的测试中,由于没有hit BUG 13871316,所以几乎没有看到Wnnn处于data file init write时,对CPU的影响。如下: 处于data file init write的时间:
我们叠加上CPU的趋势,可以看到,在出现Data file init write的时候,绿色的CPU几乎没有受到影响,没有随着Data file init write的出现而出现CPU高峰。
并且观察Wnnn进程的sesstat,”CPU used by this session”在Data file init write也没有看到变化。
(4)对比开启预扩展和关闭预扩展,循环插入100次(插入过程中无预扩展),开启预扩展的时间的插入效率比关闭的高:
(4.1)开启预扩展:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
--平均时间为51.1秒 PL/SQL procedure successfully completed Executed in 43.54 seconds 11:28:20 SQL> 11:28:43 SQL> PL/SQL procedure successfully completed Executed in 56.941 seconds 11:29:43 SQL> 11:37:07 SQL> PL/SQL procedure successfully completed Executed in 48.22 seconds 11:37:58 SQL> 11:38:48 SQL> PL/SQL procedure successfully completed Executed in 55.802 seconds 11:39:45 SQL> |
(4.2)关闭预扩展:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
--平均时间为81.2秒 PL/SQL procedure successfully completed Executed in 76.753 seconds 11:53:37 SQL> PL/SQL procedure successfully completed Executed in 91.745 seconds 11:55:47 SQL> 11:57:58 SQL> 13:29:13 SQL> / PL/SQL procedure successfully completed Executed in 69.062 seconds 13:30:24 SQL> 13:30:38 SQL> / PL/SQL procedure successfully completed Executed in 87.439 seconds 13:32:06 SQL> |
(5)对比开启预扩展和关闭预扩展,循环插入1000次,那么insert过程中伴随预扩展的进行,则开启和关闭之间的差距不大。
(5.1)开启预扩展:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
--平均时间1220.9秒 PL/SQL procedure successfully completed Executed in 1034.599 seconds (注:期间还有遇到1次init write) 14:33:09 SQL> 14:36:28 SQL> PL/SQL procedure successfully completed Executed in 1407.175 seconds (注:期间还有遇到init write 2次) 14:59:58 SQL> |
(5.2)关闭预扩展:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
--平均时间983.1秒 13:33:04 SQL> PL/SQL procedure successfully completed Executed in 902.341 seconds 13:48:14 SQL> 13:50:06 SQL> PL/SQL procedure successfully completed Executed in 1063.849 seconds 14:08:05 SQL> |
Oracle在11g推出空间预扩展的功能,是在很大程度上能减轻空间分配争用的问题,对提高效率有好处,建议保留使用该空间预扩展的功能,不设置_enable_space_preallocation为0。因为对于这个新功能带来的好处,是大大多于缺点的。