Oracle数据库IO深入分析

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

1/82Oracle数据库IO深入分析数据库的作用就是实现对数据的管理和查询。任何一个数据库系统,必然存在对数据的大量读或者写或者两中操作都大量存在。IO问题也往往是导致数据库性能问题的重要原因。在这篇文章中,主要帮助大家在理解Oracle的读写操作机制的基础上,灵活解决遇到的各种常见的IO问题。1Oracle中IO的产生IO当然包括了读、写两部分,先介绍Oracle中写操作的产生。1.1写介绍写操作之前,先简单的看下Oracle的物理结构:oracle的物理文件包括以下三种文件:控制文件(ControlFiles)、重做日志文件(RedoLogFiles)、数据文件(datafiles)。而数据文件中,根据功能的不同,还可以分为系统数据文件、临时空间文件、回滚段文件和用户数据文件。另外,如果数据库的ArchiveLog模式被激活,还存在归档日志文件。Oracle的IO产生,就是对这些文件的数据读、写操作。下面再详细看下几种主要写操作的产生及其过程。1.1.1控制文件控制文件中记录了整个数据库的物理结构信息,如数据库名字、数据文件及日志文件名字和位置、事件戳信息等等。任何数据库的结构变化(如果创建新的数据文件)都会引起Oracle修改控制文件。同时控制文件还记录系统和各个数据文件的SCN(SystemChangeNumber,关于SCN可以参见文章《OracleSCN机制详解》)信息,以用于数据恢复,因此数据文件上的SCN变化后,Oracle也会相应修改控制文件上的SCN信息。1.1.2用户数据修改由于内存的读写效率比磁盘的读写效率高万倍,因此,为了降低IOwait,oracle会将数据cache在内存(BufferCache,对BufferCache的详细介绍可以参见《Oracle内存全面分析》)中,对数据的读写尽量在内存中完成。当BufferCache中的数据缓存块被修改过了,它就被标记为“脏”数据。根据LRU(LeastRecentlyUsed)算法,如果一个数据块最近很少被使用,它就称为“冷”数据块。进程DBWn(系统中可以存在多个DBW进程,n为序号)负责将“冷”的“脏”数据写入数据文件中去。DBWn进程会在以下两种情况下将“脏”数据写入磁盘中去:当服务进程扫描一定数量(阀值)的BufferCache后还没有找到干净、可重用的缓存块后,它会通知DBWn进程将“脏”数据写入文件中去,以释放出空闲缓存;当发生检查点(Checkpoint)时。1.1.3RedoLog3/82在非直接写(DirectWrite)的情况下,事务中的写操作都会产生RedoLog,作为数据块异常关闭时的恢复记录。同样,和写用户数据类似,RedoLog也不会被直接写入RedoLog文件,而是先写入LogBuffer中。LogBuffer是一个可以循环重用的缓存区。LGWR进程负责将LogBuffer中的记录写入RedoLogFile中去。一旦LogBuffer中的条目被写入了RedoLog文件中,就可以被重用了。为了保证事务尽快获得LogBuffer,LGWR进程一般会尽快将LogBuffer中的数据写入RedoLog文件中去。在以下几种情况下,LGWR回将一个连续的LogBuffer写入RedoLog文件中去:当一个事务提交(COMMIT)时;每3秒钟写一次LogBuffer;当LogBuffer到达1/3满时;当DBWn进程将“脏”数据写入磁盘时;1.1.4ArchiveLog当据库的ArchiveLog模式被激活后,所有RedoLog数据都会被写入ArchiveLog文件中以便日后进行恢复。当发生日志组切换时,ARCn(Archive进程,可以存在多个)进程就会RedoLog文件拷贝到指定存储目录中去,成为ArchiveLog文件。1.1.5临时表空间当Oracle在执行一些SQL时,会需要一些临时空间来存储执行语句时产生的中间数据。这些临时空间由Oracle从指定的临时表空间中分配给进程。主要有三种情况会占用临时空间:临时表/索引操作、排序和临时LOB操作。临时表/索引在会话中,当第一次对临时表进行INSERT(包括CTAS)时,Oracle会从临时表空间中为临时表及其索引分配临时空间一存储数据。排序任何会使用到排序的操作,包括JOIN、创建(重建)INDEX、ORDERBY、聚合计算(GROUPBY)以及统计数据收集,都可能使用到临时表空间。4/82排序操作首先会选择在内存中的SortArea进行(SortInMemory),一旦SortArea不足,则会使用临时空间进行排序操作(SortInDisk)。看以下例子:SQLaltersessionsetsort_area_size=10000000;Sessionaltered.SQLselectowner,object_namefromt_test12orderbyobject_id;47582rowsselected.ExecutionPlan----------------------------------------------------------Planhashvalue:1312425564----------------------------------------------|Id|Operation|Name|Rows|Bytes|Cost(%CPU)|Time|----------------------------------------------|0|SELECTSTATEMENT||47582|1486K|155(4)|00:00:02||1|SORTORDERBY||47582|1486K|155(4)|00:00:02||2|TABLEACCESSFULL|T_TEST1|47582|1486K|150(1)|00:00:02|----------------------------------------------5/82Statistics----------------------------------------------------------1recursivecalls0dbblockgets658consistentgets0physicalreads0redosize1566184bytessentviaSQL*Nettoclient35277bytesreceivedviaSQL*Netfromclient3174SQL*Netroundtripsto/fromclient1sorts(memory)0sorts(disk)47582rowsprocessedSQLaltersessionsetsort_area_size=10000;Sessionaltered.SQLselectowner,object_namefromt_test12orderbyobject_id;47582rowsselected.6/82ExecutionPlan----------------------------------------------------------Planhashvalue:1312425564------------------------------------------------|Id|Operation|Name|Rows|Bytes|TempSpc|Cost(%CPU)|Time|------------------------------------------------|0|SELECTSTATEMENT||47582|1486K||1251(1)|00:00:16||1|SORTORDERBY||47582|1486K|4136K|1251(1)|00:00:16||2|TABLEACCESSFULL|T_TEST1|47582|1486K||150(1)|00:00:02|-------------------------------------------------Statistics----------------------------------------------------------6recursivecalls20dbblockgets658consistentgets629physicalreads0redosize7/821566184bytessentviaSQL*Nettoclient35277bytesreceivedviaSQL*Netfromclient3174SQL*Netroundtripsto/fromclient0sorts(memory)1sorts(disk)47582rowsprocessed临时LOB对象LOB对象包括BLOB、CLOB、NCLOB、和BFILE。在PLSQL程序块中,如果定义了LOB变量,则这些LOB变量就是临时LOB对象。临时LOB对象被创建在临时表空间上,直到LOB数据被释放,或者会话结束。1.1.6回滚段我们知道,一个事务在未被提交前,其做的任何修改都是可以被回滚(Rollback)的。这些回滚数据就被放到回滚段(RollbackSegment)上。此外,一致性读(ReadConsistency)、数据库恢复(Recover)都会用到回滚段。任何数据块的修改都会被记录在回滚段中,甚至RedoLog也会产生回滚记录。当任何一个非只读(只有查询)的事务开始时,oracle会自动为其指定下一个可用的回滚段。事务中任何数据变化都被写入回滚段中。如果事务回滚,oracle根据回滚段中的回滚记录将buffercache中的“脏”数据恢复,释放回滚段空间。当事务被提交,由于要保证一致性读,oracle并不会立即释放回滚段中的数据,而是会保留一段时间。1.1.7Direct-PathInsert这里,我们还要介绍一种特殊的写操作——Direct-PathInsert(直接路径插入)。Direct-PathInsert通过直接在表中已存在的数据后面添加数据,直接将数据写入数据文件中,而忽略掉了BufferCache。我们前面提到,为了能在意外时恢复数据,每一个数据修改都会被记录到RedoLog中。然而,由于RedoLog需要写入到物理文件中去,是一个比较消耗性能的操作。为了提高性能,我们在批量写入数据时就可以通过Direct-PathInsert的指定NOLOGING的方式来避免写RedoLog。8/82有多种方法可以指定Direct-PathInsert:CTAS(CREATETABLEASSELECT);SQL*Loader指定Direct参数;在语句中指定APPEND提示。1.2读1.2.1物理读产生物理读主要有以下几种情况:第一次读取当数据块第一次被读取到,Oracle会先将其从磁盘上读入BufferCache中,并将他们放在LRU(LastRecentlyUsed)链表的MRU(MostRecentlyUsed)端。再次访问数据块时就可以直接从BufferCache中读取、修改了。看以下例子:SQLselectowner,index_namefromt_test3;2856rowsselected.ExecutionPlan----------------------------------------------------------Planhashvalue:2878488296---------------------------------------------|Id|Operation|Name|Rows|Bytes|Cost(%CPU)|Time|---------------------------------------------|0|SELECTSTATEMENT||2856|68544|22(0)|00:00:01||

1 / 82
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功