enq: TC - contention等待事件的分析过程

2020-12-14 00:00:00 索引 用户 扫描 进程 找个



业务SQL得top event为 enq: TC - contention 和CPU + Wait for CPU,而这两个操作都跟全表扫描有关
再TOPsession里,有个两个等待一个是业务用户得CPU + Wait for CPU,一个是sys用户得db file async I/O submit
而找个等待对应的program 是DBWR进程,四个DBWR进程都发生改等待事件。
而事件enq: TC - contention的阻塞进程为sys用户的CKPT进程,根据enq: TC - contention的含义,分析到这里问题比较明了了,业务SQL的全表扫描
导致直接路径读,此时需要一致读,而由于SQL涉及表有大量DML(数据变更)不断需要产生检查点去写磁盘,而找个写由于事件db file async I/O submit
所阻塞,后事件db file async I/O submit的发生在11.2.0.4中需要设置参数
alter system set filesystemio_options=asynch scope=spfile; <<<<重启数据库生效

如下文档需要参考
Bug 9649885 – DB FILE ASYNC I/O SUBMIT EVENT NOT TRACKED WHEN DISK_ASYCH_IO = TRUE
when DISK_ASYNCH_IO=TRUE, the wait event ‘db file async I/O submit’ is posted even if the IO calls cannot be performed asynchronously and this is the current behavior.
The tests show the following behavior:
disk_asynch_io filesystemio_options strace DBWR AIO DBWR waits
FALSE NONE pwrite64 NO db file parallel write
FALSE ASYNCH pwrite64 NOdb file parallel write
TRUE ASYNCH io_submit/YES db file parallel write
io_getevents
TRUE NONE pwrite64 NO db file async I/O submit
从metalink 文档来看,即使disk_asynch_io参数设置为true,操作系统本身也支持AIO;也并不代表oracle就能进行AIO操作。可以看到,还必须设置filesystem_options参数,找个参数可以加快dbwr的速度,也就减少TC的等待,从而用户SQL执行更快。
另一个方法是关闭直接路径读,走buffer_cache,这样对逻辑读有影响,可能会拉高IO,其他用户数据被age out.这个还是根据具体情况选择。
alter system set event= ’10949 trace name context forever, level 1′ scope=spfile;
alter system set "_serial_direct_read"=false scope=spfile;
但是这里核心问题还是解决为啥之前的走索引的
SQL这次走了全表扫描,后续我们发现这个字段b.id = a.MANIFEST_APPLY后者应该走索引,因为b.id是主键,每次返回一个值,而a.MANIFEST_APPLY数据分布也适合走索引,但是经过查询改字段a.MANIFEST_APPLY 平均列长为45,超过了32,去掉直方图可以解决不走索引的问题,这个问题在之前文章中写过,感兴趣可以前翻下。

总结:
1 优方法,避免全表扫描,去掉直方图。
2 调整filesystem_options开启异步IO。
3 关闭直接路径读取
个方案好,对其他SQL影响小。

相关文章