数据库的作用就是实现对数据的管理和查询。任何一个数据库系统,必然存在对数据的大量读或者写或者两中操作都大量存在。IO问题也往往是导致数据库性能问题的重要原因。在这篇文章中,主要帮助大家在理解Oracle的读写操作机制的基础上,灵活解决遇到的各种常见的IO问题。

1         Oracle中IO的产生
IO当然包括了读、写两部分,先介绍Oracle中写操作的产生。
1.1      写
介绍写操作之前,先简单的看下Oracle的物理结构:oracle的物理文件包括以下三种文件:控制文件(Control Files)、重做日志文件(Redo Log Files)、数据文件(datafiles)。而数据文件中,根据功能的不同,还可以分为系统数据文件、临时空间文件、回滚段文件和用户数据文件。另外,如果数据库的Archive Log模式被激活,还存在归档日志文件。Oracle的IO产生,就是对这些文件的数据读、写操作。下面再详细看下几种主要写操作的产生及其过程。
1.1.1      控制文件
控制文件中记录了整个数据库的物理结构信息,如数据库名字、数据文件及日志文件名字和位置、事件戳信息等等。任何数据库的结构变化(如果创建新的数据文件)都会引起Oracle修改控制文件。同时控制文件还记录系统和各个数据文件的SCN(System Change Number,关于SCN可以参见文章《Oracle SCN机制详解》)信息,以用于数据恢复,因此数据文件上的SCN变化后,Oracle也会相应修改控制文件上的SCN信息。
1.1.2      用户数据修改
由于内存的读写效率比磁盘的读写效率高万倍,因此,为了降低IO wait,oracle会将数据cache在内存(Buffer Cache,对Buffer Cache的详细介绍可以参见《Oracle内存全面分析》)中,对数据的读写尽量在内存中完成。当Buffer Cache中的数据缓存块被修改过了,它就被标记为“脏”数据。根据LRU(Least Recently Used)算法,如果一个数据块最近很少被使用,它就称为“冷”数据块。进程DBWn(系统中可以存在多个DBW进程,n为序号)负责将“冷”的“脏”数据写入数据文件中去。DBWn进程会在以下两种情况下将“脏”数据写入磁盘中去:
  • 当服务进程扫描一定数量(阀值)的Buffer Cache后还没有找到干净、可重用的缓存块后,它会通知DBWn进程将“脏”数据写入文件中去,以释放出空闲缓存;
  • 当发生检查点(Checkpoint)时。
1.1.3      Redo Log
在非直接写(Direct Write)的情况下,事务中的写操作都会产生Redo Log,作为数据块异常关闭时的恢复记录。同样,和写用户数据类似,Redo Log也不会被直接写入Redo Log文件,而是先写入Log Buffer中。
Log Buffer是一个可以循环重用的缓存区。LGWR进程负责将Log Buffer中的记录写入Redo Log File中去。一旦Log Buffer中的条目被写入了Redo Log文件中,就可以被重用了。
为了保证事务尽快获得Log Buffer,LGWR进程一般会尽快将Log Buffer中的数据写入Redo Log文件中去。在以下几种情况下,LGWR回将一个连续的Log Buffer写入Redo Log文件中去:
  • 当一个事务提交(COMMIT)时;
  • 每3秒钟写一次Log Buffer;
  • 当Log Buffer到达1/3满时;
  • 当DBWn进程将“脏”数据写入磁盘时;
1.1.4      Archive Log
当据库的Archive Log模式被激活后,所有Redo Log数据都会被写入Archive Log文件中以便日后进行恢复。当发生日志组切换时,ARCn(Archive进程,可以存在多个)进程就会Redo Log文件拷贝到指定存储目录中去,成为Archive Log文件。
1.1.5      临时表空间
当Oracle在执行一些SQL时,会需要一些临时空间来存储执行语句时产生的中间数据。这些临时空间由Oracle从指定的临时表空间中分配给进程。主要有三种情况会占用临时空间:临时表/索引操作、排序和临时LOB操作。
  • 临时表/索引
在会话中,当第一次对临时表进行INSERT(包括CTAS)时,Oracle会从临时表空间中为临时表及其索引分配临时空间一存储数据。
  • 排序
任何会使用到排序的操作,包括JOIN、创建(重建)INDEX、ORDER BY、聚合计算(GROUP BY)以及统计数据收集,都可能使用到临时表空间。
排序操作首先会选择在内存中的Sort Area进行(Sort In Memory),一旦Sort Area不足,则会使用临时空间进行排序操作(Sort In Disk)。看以下例子:
SQL> alter session set sort_area_size = 10000000;
 
Session altered.
 
SQL> select owner, object_name from t_test1
  2  order by object_id;
 
47582 rows selected.
 
Execution Plan
----------------------------------------------------------
Plan hash value: 1312425564
 
------------------------------------------------------------------------------
| Id  | Operation          | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |         | 47582 |  1486K|   155   (4)| 00:00:02 |
|   1 |  SORT ORDER BY     |         | 47582 |  1486K|   155   (4)| 00:00:02 |
|   2 |   TABLE ACCESS FULL| T_TEST1 | 47582 |  1486K|   150   (1)| 00:00:02 |
------------------------------------------------------------------------------
 
 
Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
        658  consistent gets
          0  physical reads
          0  redo size
    1566184  bytes sent via SQL*Net to client
      35277  bytes received via SQL*Net from client
       3174  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
      47582  rows processed
 
SQL> alter session set sort_area_size = 10000;
 
Session altered.
 
SQL> select owner, object_name from t_test1
  2  order by object_id;
 
47582 rows selected.
 
Execution Plan
----------------------------------------------------------
Plan hash value: 1312425564
 
--------------------------------------------------------------------------------
| Id  | Operation          | Name    | Rows  | Bytes |TempSpc| Cost (%CPU)| Time|
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |         | 47582 |  1486K|       |  1251   (1)| 00:0
0:16 |
|   1 |  SORT ORDER BY     |         | 47582 |  1486K|  4136K|  1251   (1)| 00:0
0:16 |
|   2 |   TABLE ACCESS FULL| T_TEST1 | 47582 |  1486K|       |   150   (1)| 00:0
0:02 |
 
---------------------------------------------------------------------------------
 
Statistics
----------------------------------------------------------
          6  recursive calls
         20  db block gets
        658  consistent gets
        629  physical reads
          0  redo size
    1566184  bytes sent via SQL*Net to client
      35277  bytes received via SQL*Net from client
       3174  SQL*Net roundtrips to/from client
          0  sorts (memory)
          1  sorts (disk)
      47582  rows processed 
  • 临时LOB对象
LOB对象包括BLOB、CLOB、NCLOB、和BFILE。在PLSQL程序块中,如果定义了LOB变量,则这些LOB变量就是临时LOB对象。临时LOB对象被创建在临时表空间上,直到LOB数据被释放,或者会话结束。
1.1.6      回滚段
我们知道,一个事务在未被提交前,其做的任何修改都是可以被回滚(Rollback)的。这些回滚数据就被放到回滚段(Rollback Segment)上。此外,一致性读(Read Consistency)、数据库恢复(Recover)都会用到回滚段。
任何数据块的修改都会被记录在回滚段中,甚至Redo Log也会产生回滚记录。当任何一个非只读(只有查询)的事务开始时,oracle会自动为其指定下一个可用的回滚段。事务中任何数据变化都被写入回滚段中。如果事务回滚,oracle根据回滚段中的回滚记录将buffer cache中的“脏”数据恢复,释放回滚段空间。当事务被提交,由于要保证一致性读,oracle并不会立即释放回滚段中的数据,而是会保留一段时间。
1.1.7      Direct-Path Insert
这里,我们还要介绍一种特殊的写操作——Direct-Path Insert(直接路径插入)。Direct-Path Insert通过直接在表中已存在的数据后面添加数据,直接将数据写入数据文件中,而忽略掉了Buffer Cache。
我们前面提到,为了能在意外时恢复数据,每一个数据修改都会被记录到Redo Log中。然而,由于Redo Log需要写入到物理文件中去,是一个比较消耗性能的操作。为了提高性能,我们在批量写入数据时就可以通过Direct-Path Insert的指定NOLOGING的方式来避免写Redo Log。
有多种方法可以指定Direct-Path Insert:CTAS(CREATE TABLE AS SELECT);SQL*Loader指定Direct参数;在语句中指定APPEND提示。

转载于:https://blog.51cto.com/524911/865785

Oracle IO问题解析(一)相关推荐

  1. oracle 频繁io,Oracle IO问题解析

    3.2.2 db file scattered read 这是另外一个常见的引起数据库IO性能问题的等待事件.它通常发生在Oracle将"多数据块"读取到Buffer Cache中 ...

  2. 什么影响oracle io,Oracle IO问题解析

    3.2 数据文件相关的IO事件 数据库系统中的大多数的IO请求都是针对数据文件的.因此大多数情况下,与数据文件相关的IO事件是引起系统IO性能的主要原因.这些事件也是我们文章需要重点介绍的事件.下面分 ...

  3. 《Oracle SQL疑难解析》——1.6 批量地从一个表中复制数据到另一个表

    本节书摘来自异步社区出版社<Oracle SQL疑难解析>一书中的第1章,第1.6节,作者: [美]Grant Allen , Bob Bryla , Darl Kuhn,更多章节内容可以 ...

  4. Oracle中SQL解析的流程

    Oracle中SQL解析的主要流程: 我们说的游标概念比较复杂,它可以是客户端程序中的游标,服务进程中的私有游标,以及服务器端共享池里的共享游标.假设一个游标被打开了,一般来说它的共享游标信息(包括执 ...

  5. 手机IO workload解析

    背景 工作中常有些这样需求,需要分析zip解压缩,androbench和应用安装等存储应用场景在不同版本,不同平台的性能差异,并且需要对这些场景做性能优化. 想要做好这些需求工作,首先得对这些场景下的 ...

  6. 【Oracle】硬解析、软解析和软软解析

    [Oracle]硬解析.软解析和软软解析 前言   在 Oracle 中,每条 SQL 语句在执行之前都需要经过解析(Parse),根据解析的过程可以分为 3 种类型:硬解析(Hard Parse). ...

  7. oracle宽字节注入,《Oracle 稽核方式解析 [audit]》

    摘要:<Oracle 稽核方式解析 [audit]> 以下是参考网络上文档后写下,若有错误还请指教,谢谢. ---------------------------------------- ...

  8. Oracle查看硬解析

    ORACLE硬解析分析 前言 ORACLE的硬解析和软解析 AWR报告中的硬解析 通过ORACLE视图判断硬解析 关于version count 前言 工作中ORACLE使用的越多,发现对ORACLE ...

  9. 详解ORACLE数据库硬解析、软解析、软软解析

    概述 TOM大叔的调优书中说过一句话,大概意思就是:如果有人让我写本怎样让ORACLE性能最慢的书的话我会将取消绑定变量(bind variable)做为书的第一章和最后一章,可见绑定变量的重要性.而 ...

最新文章

  1. js中push和pop的用法
  2. jQuer or js 插件aptana studio 3.4.0)教你玩转eclipse配置(全世
  3. Python快速学习10: 循环的对象及设计 (生活的规律)
  4. call of overloaded 'round(float)' is ambiguous
  5. GGNN(Gated Graph Sequence Neural Networks)
  6. Android7.0 PowerManagerService亮灭屏分析(三)
  7. 彻底弄懂dalvik字节码【三】
  8. 在robotframework中连接数据库进行操作
  9. ArcGIS中数据存放相对路径和绝对路径的区别
  10. Java 字节和字符流的读写+Buffered
  11. 05-类--+-号使用
  12. Pytorch使用记录
  13. Atamai 手术导航软件开发包
  14. Python 学习笔记 - 不断更新!
  15. Linux下常用组的权限特点,Linux中的用户与用户组
  16. HDU 4939 DP
  17. 计算机的收获初一作文,收获的作文(精选8篇)
  18. 什么是TypeScript?本文介绍TypeScript基本用法和语法。
  19. 最新韩小韩二次元高清图库api开源PHP网站源码
  20. 杰里之AC695N/AC696N 蓝牙耳机PCB LAYOUT 说明【篇3】

热门文章

  1. 如何在Python中注释掉一段代码[重复]
  2. 如何列出所有用户的所有cron作业?
  3. JavaScript中的(内置)方式来检查字符串是否为有效数字
  4. mybatis动态sql传ist集合參与传数组参数
  5. IntelliJ IDEA中使用git
  6. python翻译matlab,如何在python3中翻译MATLAB单元?
  7. 四轮驱动移动机器人(SSMR)与两轮差速驱动机器人、car-like robot的对比分析
  8. mysql使用了索引还是慢,`MySQL GROUP BY使用索引时速度较慢
  9. 下载并安装Redis教程
  10. C++11在加入<thread>头文件后Socket服务器接收不到消息