Oracle 学习必备手册


Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 TianleSoftware Oracle 学习手册 版本: v1.0 2011 年 5 月 6 日 说明: 在 Oracle 几年的学习中,做了很多的实验,也遇到了很多的问题, 在这个 过程中,积累了一些学习文档。也更新到了 blog 上。 因为太多,不便于查阅。 根据自己对 Oracle 的理解,把这些 blog 进行了分类,并进行了一些整理, 方便自己的查看。 这些文档中有很多内引用借鉴了前辈们的资料和 google 上的 一些信息。 如: eygle,君三思,谭怀远,陈吉平等前辈们的书籍和 blog。 感谢这些前辈们对中国 DB 事业做出的贡献。 在这里引用的内容也是完全 出于学习。 没有其他用途,如有侵犯到版权的问题,请联系我。 我将删除这些 信息。 对数据库这块也是在不断的学习,对 oracle 的理解也是在不断的变化。在这 个过程中,难免有理解错误的地方,或者内容上遗漏的,如果发现了问题,烦邮 件给我,我会虚心的学习。并更新该文档。 PS: 有些内容在排版上不太合适,因为很多也是在后期的整理中加上去的。 以后有空在调整这些内容的排版了。 2012 年 3 月 9 日 在序 今天又想起了这个文档,时隔已经快一年,这一年中我在 Blog 上又更新了 很多的文档,加上整理文档也是一件很费时间的事,所以这本学习手册,一直没 有更新,而且以前的内容,很多也有失误,做技术是一件很严谨的事,但是这本 手册,或多或少对刚入门的人来说,还是有一定的帮助,所以暂且转成转成 PDFTianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 版本,作为 Dave 学习手册的第一版本发布。 如果其中内容有误,也麻烦给我发封 email,我会及时更改这些内容。 Dave 希望能和大家在 Oracle 的路上一起进步。 Email: tianlesoftware@gmail.com Skype: tianlesoftware Blog: http://www.tianlesoftware.com http://blog.csdn.net/tianlesoftware Weibo: http://weibo.com/tianlesoftware Twitter: http://twitter.com/tianlesoftware Facebook: http://www.facebook.com/tianlesoftware Linkedin: http://cn.linkedin.com/in/tianlesoftware 目 录 TIANLESOFTWARE ORACLE 学习手册 ............................................................................................. 1 一. ORACLE 基础知识 ..................................................................................................................... 24 1.1 ORACLE OLAP 与 OLTP 介绍 ........................................................................................................ 24 1.1.1 什么是 OLTP ....................................................................................................................... 25 1.1.2 什么是 OLAP ....................................................................................................................... 26 1.1.3 在 OLAP 系统中,常使用分区技术、并行技术 .............................................................. 26 1.1.4 分开设计与优化 ................................................................................................................ 27 1.2 索引详解 ..................................................................................................................................... 28 1.2.1 索引介绍 ............................................................................................................................ 28 1.2.1.1 索引的创建语法 ......................................................................................................................... 28 1.2.1.2 索引特点..................................................................................................................................... 28 1.2.1.3 索引不足..................................................................................................................................... 29 1.2.1.4 应该建索引列的特点 ................................................................................................................. 29 1.2.1.5 不应该建索引列的特点 ............................................................................................................. 29 1.2.1.6 限制索引..................................................................................................................................... 29 1.2.1.6.1 使用不等于操作符(<>、!=) ......................................................................................... 29 1.2.1.6.2 使用 IS NULL 或 IS NOT NULL ............................................................................................ 30 1.2.1.6.3 使用函数 ............................................................................................................................ 30 1.2.1.6.4 比较不匹配的数据类型 ..................................................................................................... 30 1.2.1.7 查询索引..................................................................................................................................... 30 1.2.1.8 组合索引..................................................................................................................................... 30 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.2.1.9 ORACLE ROWID ............................................................................................................................ 31 1.2.1.10 选择性 ...................................................................................................................................... 31 1.2.1.11 群集因子(Clustering Factor) ..................................................................................................... 31 1.2.1.12 二元高度(Binary height) ........................................................................................................... 31 1.2.1.13 快速全局扫描 ........................................................................................................................... 31 1.2.1.14 跳跃式扫描 ............................................................................................................................... 31 1.2.2 索引分类 ............................................................................................................................ 32 1.2.2.1 B 树索引 (默认类型) .................................................................................................................. 32 1.2.2.2 位图索引..................................................................................................................................... 33 1.2.2.3 HASH 索引.................................................................................................................................... 35 1.2.2.4 索引组织表 ................................................................................................................................. 36 1.2.2.5 反转键索引 ................................................................................................................................. 37 1.2.2.6 基于函数的索引 ......................................................................................................................... 37 1.2.2.7 分区索引..................................................................................................................................... 38 1.2.2.7.1.本地分区索引(通常使用的索引) ....................................................................................... 38 1.2.2.7.2.全局分区索引 ..................................................................................................................... 40 1.2.2.8 位图连接索引 ............................................................................................................................. 40 1.3 分区表总结 ................................................................................................................................. 41 1.3.1. 分区表理论知识 ............................................................................................................... 41 1.3.2 普通表转分区表方法......................................................................................................... 45 1.3.2.1 插入: Insert with a subquery method ..................................................................................... 46 1.3.2.1.1 Oracle 11g 的 Interval ....................................................................................................... 46 1.3.2.1.2 Oracle 10g 版本 ............................................................................................................... 47 1.3.2.2 交换分区:Partition exchange method ..................................................................................... 48 1.3.2.3 使用在线重定义:DBMS_REDEFINITION ................................................................................... 50 1.3.2.4 使用导出导入 ............................................................................................................................. 54 1.3.2.4.1 迁移分区表的步骤 ............................................................................................................ 55 1.3.2.4.2 示例 1:使用 exp/imp ....................................................................................................... 55 1.3.2.4.3 示例 2:使用 expdp/impdp ............................................................................................... 59 1.3.3 分区表的其他操作............................................................................................................. 62 1.3.3.1 添加新的分区 ............................................................................................................................. 62 1.3.3.2 split 分区拆分 ............................................................................................................................. 64 1.3.3.3 合并分区 Merge ......................................................................................................................... 64 1.3.3.4 移动分区..................................................................................................................................... 65 1.3.3.5 Truncate 分区 ............................................................................................................................... 65 1.3.3.6 Drop 分区 ..................................................................................................................................... 66 1.3.4 分区表的索引 .................................................................................................................... 66 1.3.4.4.1 Local 本地索引 ................................................................................................................... 67 1.3.4.4.2 Global 索引 .......................................................................................................................... 68 1.3.4.4.3 索引重建问题 .................................................................................................................... 71 1.3.5 Oracle 11g 中的分区表 ...................................................................................................... 74 1.3.5.1 11g 中的分区表新特性 ............................................................................................................... 74 1.3.5.1.1 Interval Partitioning ............................................................................................................. 74 1.3.5.1.2 System Partitioning .............................................................................................................. 74 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.3.5.1.3 More Composite Partitioning ............................................................................................... 75 1.3.5.1.4 Virtual Column-Based Partitioning....................................................................................... 75 1.3.5.2 11g 虚拟列实现 按星期分区表 ............................................................................................. 76 1.3.5.3 Interval 分区 示例 ................................................................................................................... 78 1.3.5.3.1 创建按月分区的分区表 ..................................................................................................... 78 1.3.5.3.2 创建一个以天为间隔的分区表 .......................................................................................... 80 1.4 ORACLE 锁 ..................................................................................................................................... 82 1.4.1 锁(Lock) ......................................................................................................................... 82 1.4.1.1 锁的概念..................................................................................................................................... 82 1.4.1.2 锁的分类..................................................................................................................................... 83 1.4.1.2.1. 按用户与系统划分,可以分为自动锁与显示锁 ............................................................ 83 1.4.1.2.2. 按锁级别划分,可分为: 排它锁(Exclusive Locks,即 X 锁)和共享锁(Share Locks, 即 S 锁) ............................................................................................................................................ 84 1.4.1.2.3 按操作划分,可分为 DML 锁(data locks,数据锁)、DDL 锁(data dictionary lock) 和 System Locks。 ............................................................................................................................. 84 1.4.1.2.4 DML 锁 .............................................................................................................................. 84 1.4.1.2.5 DDL 锁(dictionary locks) .............................................................................................. 87 1.4.1.2.6 System Locks ..................................................................................................................... 89 1.4.2 死锁 .................................................................................................................................... 91 1.4.3 锁 和 阻塞 ........................................................................................................................ 94 1.4.3.1 相关概念..................................................................................................................................... 94 1.4.3.2 引起阻塞的几种常见情况 ......................................................................................................... 97 1.4.3.2.1 DML 语句 ......................................................................................................................... 97 1.4.3.2.2 外键没有创建索引 .......................................................................................................... 98 1.4.4 Latch 说明 ........................................................................................................................... 98 1.4.4.1 Latch ......................................................................................................................................... 98 1.4.4.2 有关 SPin 的说明 ..................................................................................................................... 99 1.4.4.3 进程获取 Latch 的过程 ............................................................................................................ 99 1.4.4.4 Latch 和 Lock ......................................................................................................................... 100 1.4.4.5 Latch 争用 ............................................................................................................................. 100 1.4.4.5.1 共享池中的 Latch 争用 .................................................................................................... 101 1.4.4.5.2 数据缓冲池 Latch 争用 .................................................................................................... 102 1.4.4.6 热块产生的原因 ..................................................................................................................... 103 1.4.4.6.1 表数据块 .......................................................................................................................... 103 1.4.4.6.2 索引数据块 ...................................................................................................................... 103 1.4.4.6.3 索引根数据块 .................................................................................................................. 104 1.4.4.6.4 段头数据块 .................................................................................................................... 104 1.4.4.7 检查 Latch 的相关 SQL .......................................................................................................... 105 1.4.4.7.1 查看造成 LATCH BUFFER CACHE CHAINS 等待事件的热快 ............................................ 105 1.4.4.7.2 查询当前数据库最繁忙的 Buffer,TCH(Touch)表示访问次数越高,热点快竞争问题就 存在 .................................................................................................................................................. 105 1.4.4.7.3 查询当前数据库最繁忙的 Buffer,结合 dba_extents 查询得到这些热点 Buffer 来自哪些 对象 .................................................................................................................................................. 106 1.4.4.7.4 如果在 Top 5 中发现 latch free 热点块事件时,可以从 V$latch_children 中查询具体的Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 子 Latch 信息 .................................................................................................................................... 106 1.4.4.7.5 获取当前持有最热点数据块的 Latch 和 buffer 信息 ..................................................... 106 1.4.4.7.6 利用前面的 SQL 可以找到这些热点 Buffer 的对象信息 ............................................... 107 1.4.4.7.7 结合 SQL 视图可以找到操作这些对象的相关 SQL,然后通过优化 SQL 减少数据的访问, 或者优化某些容易引起争用的操作(如 connect by 等操作)来减少热点块竞争 .................... 107 1.5 等待事件 ................................................................................................................................... 108 1.5.1 等待事件的相关知识....................................................................................................... 108 1.5.1.1 等待事件分类 ............................................................................................................................ 108 1.5.1.2 查看 v$event_name 视图的字段结构 ..................................................................................... 108 1.5.1.3 查看等待事件总数 ................................................................................................................... 108 1.5.1.4 查看等待事件分类情况 ........................................................................................................... 108 1.5.1.5 相关的几个视图 ....................................................................................................................... 109 1.5.2 33 个常见的等待事件 ....................................................................................................... 110 1.5.2.1 Buffer busy waits ........................................................................................................................ 110 1.5.2.2 Buffer latch .............................................................................................................................. 111 1.5.2.3 Control file parallel write ............................................................................................................ 111 1.5.2.4 Control file sequential read ........................................................................................................ 112 1.5.2.5 Db file parallel read .................................................................................................................... 112 1.5.2.6 Db file parallel write ................................................................................................................... 112 1.5.2.7 Db file scattered read ................................................................................................................. 113 1.5.2.8 Db file sequential read ............................................................................................................... 113 1.5.2.9 Db file single write ...................................................................................................................... 113 1.5.2.10 Direct path read........................................................................................................................ 114 1.5.2.11 Direct path write ...................................................................................................................... 114 1.5.2.12 Enqueue ................................................................................................................................... 114 1.5.2.13 Free buffer waits ...................................................................................................................... 117 1.5.2.14 Latch free ................................................................................................................................. 118 1.5.2.15 Library cache lock ..................................................................................................................... 119 1.5.2.16 Library cache pin ...................................................................................................................... 119 1.5.2.17 Log file parallel write ................................................................................................................ 119 1.5.2.18 Log buffer space ....................................................................................................................... 120 1.5.2.19 Log file sequential read ............................................................................................................ 120 1.5.2.20 Log file single write .................................................................................................................. 120 1.5.2.21 Log file switch(archiving needed) ............................................................................................. 120 1.5.2.22 Log file switch(checkpoint incomplete) .................................................................................... 121 1.5.2.23 Log file sync .............................................................................................................................. 121 1.5.2.24 SQL*Net break/reset to client .................................................................................................. 122 1.5.2.25 SQL*Net break/reset to dblink ................................................................................................. 122 1.5.2.26 SQL*Net message from client .................................................................................................. 122 1.5.2.27 SQL*Net message from dblink ................................................................................................. 122 1.5.2.28 SQL*Net message to client ....................................................................................................... 123 1.5.2.29 SQL*Net message to dblink ...................................................................................................... 123 1.5.2.30 SQL*Net more data from client ................................................................................................ 123 1.5.2.31 SQL*Net more data from dblink ............................................................................................... 123 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.5.2.32 SQL*Net more data to client .................................................................................................... 124 1.5.2.33 SQL*Net more data to dblink ................................................................................................... 124 1.6 存储过程 ................................................................................................................................... 124 1.6.1 Procedure 定义 ................................................................................................................. 124 1.6.1.1 定义 .......................................................................................................................................... 124 1.6.1.2 优 点 ........................................................................................................................................ 124 1.6.1.3 存储过程与函数的对比 ........................................................................................................... 125 1.6.2 存储过程使用示例........................................................................................................... 125 1.6.2.1. 存储过程格式 .......................................................................................................................... 125 1.6.2.2. 存储过程中的循环 .................................................................................................................. 127 1.6.2.2.1 for ... in ... loop 循环 ...................................................................................................... 127 1.6.2.2.2 loop 循环 ....................................................................................................................... 128 1.6.2.2.3 while 循环 ..................................................................................................................... 128 1.6.2.3. 存储过程中的判断 .................................................................................................................. 129 1.6.2.3.1 if ... elsif ... else ... 判断 .................................................................................................. 129 1.6.2.3.2 case ... when ... end case 判断 ....................................................................................... 129 1.6.2.4. 游标 ......................................................................................................................................... 129 1.6.2.4.1 Cursor 型游标(不能用于参数传递) ............................................................................... 129 1.6.2.4.2 SYS_REFCURSOR 型游标 ................................................................................................. 130 1.6.2.5. 存储过程的调试 ...................................................................................................................... 131 1.7 ORACLE 内存管理 ....................................................................................................................... 131 1.7.1 SGA .................................................................................................................................. 132 1.7.1.1 相关参数说明 ........................................................................................................................... 133 1.7.1.1.1 SGA_MAX_SIZE .................................................................................................................. 133 1.7.1.1.2 PRE_PAGE_SGA .................................................................................................................. 134 1.7.1.1.3 LOCK_SGA .......................................................................................................................... 135 1.7.1.1.4 SGA_TARGET ...................................................................................................................... 135 1.7.1.2 Database Buffer Cache ............................................................................................................... 136 1.7.1.2.1 Buffer cache 的管理 .......................................................................................................... 136 1.7.1.2.2 Buffer Cache 的重要参数配置 .......................................................................................... 138 1.7.1.3 Share Pool .................................................................................................................................. 140 1.7.1.3.1 库缓存(Library Cache) ................................................................................................. 140 1.7.1.3.2 字典缓存(Dictionary Cache) ....................................................................................... 141 1.7.1.3.3 共享池的内存管理 .......................................................................................................... 142 1.7.1.3.4 保留共享池 ...................................................................................................................... 142 1.7.1.3.5 将重要、常用对象保持(Keep)在共享池中 ............................................................... 143 1.7.1.3.6 关于 Shared Pool 的重要参数 ....................................................................................... 144 1.7.1.4 重做日志缓存(Redo Log Buffer) ......................................................................................... 144 1.7.1.5 大池(large pool) ................................................................................................................... 145 1.7.1.6 Java 池(Java Pool) ................................................................................................................. 145 1.7.1.7 流池(Streams Pool) .............................................................................................................. 145 1.7.2 PGA ................................................................................................................................. 146 1.7.2.1 PGA 的组成 ............................................................................................................................. 146 1.7.2.1.1 私有 SQL 区(Private SQL Area) .................................................................................... 147 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.7.2.1.2 游标和 SQL 区(Cursors and SQL Areas)....................................................................... 147 1.7.2.1.3 会话内存(Session Memory) ........................................................................................ 147 1.7.2.2 PGA 内存自动管理 ................................................................................................................. 148 1.7.2.3 专有服务(Dedicated Server)和共享服务(Shared Server) ........................................... 149 1.7.3 UGA (The User Global Area) ............................................................................................ 149 1.7.4 CGA (The Call Global Area) .............................................................................................. 150 1.7.5 软件代码区(Software Code Area) ............................................................................. 151 1.8 ASSM (AUTO SEGMENT SPACE MANAGEMENT) ..................................................................................... 151 1.8.1 官网说明 .......................................................................................................................... 151 1.8.1.1 Locally Managed Tablespaces ..................................................................................................... 152 1.8.1.1.1 Automatic Segment Space Management ........................................................................... 154 1.8.1.1.2 Manual Segment Space Management ............................................................................... 154 1.8.1.2 Dictionary-Managed Tablespaces ............................................................................................... 156 1.8.2 ASSM 说明 ........................................................................................................................ 157 1.8.3 相关测试 .......................................................................................................................... 158 1.9 ADDM ......................................................................................................................................... 166 1.10 SQL TUNING ADVISOR (STA) 使用 说明 ....................................................................................... 181 1.11 ASH(ACTIVE SESSION HISTORY) ................................................................................................. 187 1.12 AWR ......................................................................................................................................... 204 1.13 STATSPACK ................................................................................................................................... 209 1.14 SYSAUX 表空间 说明 .............................................................................................................. 221 1.14.1 SYSAUX 说明 ................................................................................................................... 221 1.14.2 示例 ................................................................................................................................ 224 1.14.2.1. 将 Logminer 从 SYSAUX 表空间,迁移到 users 表空间,在还原回来............................. 224 1.14.2.2 SYSAUX 不能 drop ................................................................................................................. 225 1.14.2.3 SYSAUX 不能重命名 ............................................................................................................ 225 1.14.2.3 不能将 SYSAUX 改成只读 ................................................................................................... 225 1.15 ORACLE UNDO 表空间管理 ........................................................................................................ 226 1.15.1 undo 说明 ....................................................................................................................... 226 1.15.2 Undo 表空间的两种管理方式 ....................................................................................... 226 1.15.2.1 当使用 rollback segment 时 ................................................................................................... 227 1.15.2.2 使用 Undo 表空间 ................................................................................................................. 227 1.15.3 undo_retention 和 retention guarantee 参数 .............................................................. 228 1.15.4 undo 表空间满时的处理方法........................................................................................ 230 1.15.4.1 先模拟 UNDO 表空间满的情况 ............................................................................................ 230 1.15.4.2 处理方法................................................................................................................................. 230 1.15.4.2.1 增加数据文件 ................................................................................................................ 231 1.15.4.2.2 切换 UNDO 表空间 ....................................................................................................... 231 1.15.5 undo 表空间损坏的处理方法........................................................................................ 231 1.15.5.1 方法一:使用 system segment .............................................................................................. 232 1.15.5.2 方法二:跳过损坏的 segment .............................................................................................. 232 1.16 ORACLE 表空间 创建参数 说明 .............................................................................................. 233 1.16.1 logging_clause .............................................................................................................. 234 1.16.2 permanent_tablespace_clause ..................................................................................... 234 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.16.3 extent_management_clause ......................................................................................... 234 1.16.4 BLOCKSIZE Clause .......................................................................................................... 235 1.16.5 segment_management_clause ..................................................................................... 236 1.16.6 flashback_mode_clause ................................................................................................ 237 1.17 ORACLE TABLE 创建参数 说明 .................................................................................................. 237 1.17.1 Storage 参数说明 ........................................................................................................... 238 1.17.1.1. INITIAL ..................................................................................................................................... 238 1.17.1.2. MINEXTENTS ........................................................................................................................... 239 1.17.1.3. MAXEXTENTS ........................................................................................................................... 240 1.17.1.4. PCTINCREASE ........................................................................................................................... 240 1.17.1.5. FREELISTS ................................................................................................................................ 241 1.17.1.6. FREELIST GROUPS .................................................................................................................... 241 1.17.1.7. BUFFER_POOL ......................................................................................................................... 242 1.17.1.7.1 KEEP ................................................................................................................................. 243 1.17.1.7.2 RECYCLE............................................................................................................................ 243 1.17.1.7.3 DEFAULT ........................................................................................................................... 243 1.17.2 其他参数说明 ................................................................................................................ 243 1.18 数据块 BLOCK 说明 ................................................................................................................. 246 1.18.1 Data Blocks and Operating System Blocks .................................................................... 246 1.18.2 Database Block Size....................................................................................................... 247 1.18.3 Tablespace Block Size .................................................................................................... 247 1.18.4 Data Block Format ........................................................................................................ 247 1.18.5 Data Block Overhead ..................................................................................................... 248 1.18.5.1 Block header .......................................................................................................................... 248 1.18.5.2 Table directory ...................................................................................................................... 248 1.18.5.3 Row directory ........................................................................................................................ 249 1.18.6 Row Format ................................................................................................................... 249 1.18.6.1 Row Header ........................................................................................................................... 250 1.18.6.2 Column Data .......................................................................................................................... 250 1.18.7 Rowid Format ................................................................................................................ 250 1.18.7.1 OOOOOO .................................................................................................................................. 251 1.18.7.2 FFF ............................................................................................................................................ 251 1.18.7.3 BBBBBB .................................................................................................................................... 251 1.18.7.4 RRR ........................................................................................................................................... 251 1.18.8 Data Block Compression ................................................................................................ 252 1.18.9 Space Management in Data Blocks ............................................................................... 253 1.18.9.1 Percentage of Free Space in Data Blocks ............................................................................... 253 1.18.9.2 Optimization of Free Space in Data Blocks ............................................................................ 254 1.18.9.3 Coalescing Fragmented Space ............................................................................................... 255 1.18.9.4 Reuse of Index Space ............................................................................................................. 256 1.18.9.5 Chained and Migrated Rows.................................................................................................. 258 1.19 ORACLE 字符集 ......................................................................................................................... 260 1.19.1 什么是 Oracle 字符集 .................................................................................................... 260 1.19.2 字符集的相关知识 ......................................................................................................... 261 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.19.2.1 字符集 .................................................................................................................................... 261 1.19.2.2 字符编码方案 ......................................................................................................................... 261 1.19.2.2.1 单字节编码 .................................................................................................................... 261 1.19.2.2.2 多字节编码 .................................................................................................................... 261 1.19.2.2.3 unicode 编码 ................................................................................................................... 261 1.19.2.3 字符集超级 ............................................................................................................................. 262 1.19.2.4 数据库字符集(oracle 服务器端字符集) .......................................................................... 262 1.19.2.4.1 字符集 ............................................................................................................................. 262 1.19.2.4.2 国家字符集 ..................................................................................................................... 262 1.19.2.4.3 查询字符集参数 ............................................................................................................. 262 1.19.2.4.4 修改数据库字符集 ......................................................................................................... 262 1.19.2.5 客户端字符集(NLS_LANG 参数) ....................................................................................... 263 1.19.2.5.1 客户端字符集含义 ......................................................................................................... 263 1.19.2.5.2 NLS_LANG 参数格式 ....................................................................................................... 263 1.19.2.5.3 客户端字符集设置方法 ................................................................................................. 263 1.19.2.5.4 NLS 参数查询 .................................................................................................................. 263 1.19.2.5.5 修改 NLS 参数 ................................................................................................................. 264 1.19.3 EXP/IMP 与 字符集 ....................................................................................................... 264 1.19.3.1 EXP/IMP ................................................................................................................................... 264 1.19.3.2 导出的转换过程 ...................................................................................................................... 264 1.19.3.3 导入的转换过程 ...................................................................................................................... 265 1.19.4 查看数据库字符集......................................................................................................... 265 1.19.4.1 查询 oracle server 端的字符集 .............................................................................................. 265 1.19.4.2 如何查询 dmp 文件的字符集................................................................................................ 265 1.19.4.3 查询 oracle client 端的字符集 ............................................................................................... 266 1.19.5 修改 oracle 的字符集 ..................................................................................................... 267 1.19.5.1 修改 server 端字符集(不建议使用) ...................................................................................... 267 1.19.5.2 修改 dmp 文件字符集 ........................................................................................................... 268 1.19.5.3 客户端字符集设置方法 .......................................................................................................... 268 1.20 SCN,REDOLOG 和 CHECKPOINT .................................................................................................. 269 1.20.1 Redo log 作用 .............................................................................................................. 269 1.20.2 SCN(system change number) ........................................................................................ 270 1.20.3 Checkpoint (检查点) ..................................................................................................... 272 1.20.3.1 检查点定义 ............................................................................................................................. 272 1.20.3.2 Checkpoints 相关优化参数 .................................................................................................... 274 1.20.3.2.1 FAST_START_MTTR_TARGET ............................................................................................ 274 1.20.3.2.2 LOG_CHECKPOINT_INTERVAL .......................................................................................... 274 1.20.3.2.3 LOG_CHECKPOINT_TIMEOUT........................................................................................... 275 1.20.3.2.4 log_checkpoint_to_alert .................................................................................................. 275 1.20.3.3 Checkpoint 触发条件 .............................................................................................................. 275 1.20.3.3.1 触发完全检查点 条件................................................................................................... 275 1.20.3.3.2 触发增量检查点 ............................................................................................................ 276 1.20.3.4 检查点的一些讨论 ................................................................................................................. 276 1.20.3.4.1. Commit 成功后,数据还会丢失吗? ........................................................................... 276 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.20.3.4.2. 数据库发生一次 DBWn,是否将所有 buffer cache 中的 dirty buffer 都写入,还是先 将脏队列中的数据写入? ............................................................................................................... 277 1.20.3.4.3. 关于检查点等待事件: ................................................................................................ 277 1.20.3.4.4. 检查点为什么要等待 dbwr 完成后才进行切换(log switch)? .............................. 277 1.20.3.4.5. 如果没有设置 archive log ,在检查点发生后,发生 log switch 一个轮回,log file 是 否会被覆盖掉? .............................................................................................................................. 277 1.20.3.4.6. 检查点发生时,出现日志切换,但是 dbwr 还没有写完,是否会覆盖 redo log file, 如果此时掉电,dbwr 挂起,会出现丢失数据吗? ...................................................................... 278 1.20.3.4.7. alter systen switch logfile 会触发完全检查点; 但是为什么,日志切换以后检查点只能 记录到上一次归档日志产生的时间呢?而不是现在归档日志产生的时间呢? ........................ 279 1.20.4 checkpoint 和 scn 的关系 .......................................................................................... 279 1.20.5 相关问题 ...................................................................................................................... 280 1.20.5.1 为什么储存在 CONTROL FILE 中要分为两个地方(SYSTEM CHECKPOINT SCN,DATAFILE CHECKPOINT SCN) ? ............................................................................................................................... 280 1.20.5.2 正常 shutdown database 后,SCN 会发生什么变化? ........................................................ 280 1.20.5.3 crash recovery 和 media recovery 的比较 ............................................................................. 282 1.20.5.4 RECOVERY DATABASE 两种常见问题 ...................................................................................... 282 1.21 用户 对 表空间配额(QUOTA )说明 ................................................................................... 283 1.21.1 官网的说明 ..................................................................................................................... 283 1.21.1.1 Assigning a Tablespace Quota for the User ......................................................................... 283 1.21.1.2 Restricting the Quota Limits for User Objects in a Tablespace .............................................. 284 1.21.1.3 Granting Users the UNLIMITED TABLESPACE System Privilege .............................................. 284 1.21.1.4 Listing All Tablespace Quotas ................................................................................................ 285 1.21.2 Quota 说明 ..................................................................................................................... 285 1.21.2.1. 创建用户时,指定限额 ........................................................................................................ 286 1.21.2.2.更改用户的表空间限额: ...................................................................................................... 287 1.21.2.3. 回收用户对表空间的配额: ................................................................................................... 287 1.22 ORACLE DB 服务器 系统时间修改问题 与 SCN 关系的研究 ............................................... 288 1.22.1 先做个测试 .................................................................................................................... 288 1.22.1.1 关闭 DB ................................................................................................................................... 288 1.22.1.2 修改系统时间 ......................................................................................................................... 288 1.22.1.2.1 现在时间 ........................................................................................................................ 288 1.22.1.2.2 修改时间 ........................................................................................................................ 288 1.22.1.3 启动 DB .................................................................................................................................... 288 1.22.2 修改系统时间与 SCN 关系 ........................................................................................... 289 1.23 ORACLE 10G SCHEDULER 特性 ...................................................................................................... 291 1.24 坏块小结 ................................................................................................................................. 320 1.25 ALTER DATABASE 与 ALTER TABLESPACE OFFLINE 的区别 ...................................................... 320 1.25.1 DataFile 脱机或联机的两种方法: ............................................................................... 320 1.25.1.1 ARCHIVRLOG 模式下的更改 DataFile 状态 ............................................................................. 320 1.25.1.2 在 NOARCHIVELOG 模式下使 DataFile 脱机 .......................................................................... 321 1.25.1.3 修改 TableSpace 中所有 DataFile 或 TempFile 的可用性 ..................................................... 321 1.25.2 表空间 与 数据文件 脱机的区别 ............................................................................... 322 1.25.2.1 ALTER TABLESPACE ... OFFLINE .............................................................................................. 322 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.25.2.2 ALTER DATABASE DATAFILE ... OFFLINE .................................................................................. 323 1.26 ORACLE 临时表 ......................................................................................................................... 324 1.26.1 临时表说明 .................................................................................................................... 324 1.26.2 创建临时表 .................................................................................................................... 326 1.26.2.1 Creating a Temporary Table ................................................................................................... 326 1.26.2.2 创建临时表 ........................................................................................................................... 328 1.26.2.2.1. 会话级的临时表 ........................................................................................................... 328 1.26.2.2.2 事务特有的临时表(默认类型) .................................................................................... 329 1.27 ORACLE TEMP 临时表空间 ......................................................................................................... 330 1.27.1 Temporary Tablespacs 说明 ......................................................................................... 330 1.27.2 Temp 表空间的操作 .................................................................................................... 331 1.27.3 临时表空间满时的处理方法 ....................................................................................... 333 1.27.3.1 添加数据文件 ......................................................................................................................... 333 1.27.3.2 修改数据文件大小 ................................................................................................................. 333 1.27.4 Temp 表空间过大的处理方法 .................................................................................... 333 1.27.4.1 替换 Temp 表空间 ............................................................................................................... 333 1.27.4.1.1 查看目前 Temp 表空间的信息 ................................................................................... 333 1.27.4.1.2 创建中转临时表空间 ................................................................................................... 334 1.27.4.1.3 修改 Temp2 为默认临时表空间 .................................................................................. 335 1.27.4.1.4. 删除原来临时表空间 .................................................................................................... 335 1.27.4.1.5. 重新创建临时表空间 .................................................................................................... 335 1.27.4.1.6. 重置缺省临时表空间为新建的 temp 表空间.............................................................. 335 1.27.4.1.7. 删除中转用临时表空间 ................................................................................................ 335 1.27.4.1.8 如果有必要,重新指定用户表空间为重建的临时表空间 ....................................... 335 1.27.4.2 Shrinking a Locally Managed Temporary Tablespace ............................................................. 335 1.28 控制文件 ................................................................................................................................. 336 1.28.1 Oracle 控制文件主要包含如下条目 ............................................................................. 336 1.28.2 可以通过 dump 看到 控制文件内 ............................................................................... 337 1.28.2.1 直接 dump controlfile ........................................................................................................... 337 1.28.2.2. 使用 alter database backup controlfile to filename ............................................................... 337 1.28.2.3. 使用 alter database backup controlfile to trace ..................................................................... 337 1.28.3 控制文件的重建 ............................................................................................................ 342 1.29 物化视图 ................................................................................................................................. 343 1.30 视图 ........................................................................................................................................ 343 1.31 ORACLE 参数分类 和 参数的查看方法 .................................................................................. 343 1.31.1 过时参数 和 强调参数 .................................................................................................. 344 1.31.2 隐藏参数 ........................................................................................................................ 345 1.31.3 系统当前参数 ................................................................................................................ 345 1.32 ORACLE 数据字典说明 ............................................................................................................. 346 1.32.1 官网上有关数据字典的信息 .......................................................................................... 346 Views with the Prefix DBA_ ................................................................................................................ 348 Views with the Prefix ALL_ ................................................................................................................. 349 Views with the Prefix USER_ .............................................................................................................. 349 The DUAL Table.................................................................................................................................... 350 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.32.2 数据字典 ......................................................................................................................... 350 1.32.2.1 数据字典内容包括 ................................................................................................................. 351 1.32.2.2 数据字典分为 数据字典表 和 数据字典视图 ................................................................... 351 1.32.2.2.1 数据字典表 .................................................................................................................... 351 1.32.2.2.2 数据字典视图 ................................................................................................................ 352 1.32.2.3 视图家族................................................................................................................................. 353 1.32.2.4 查看数据字典 ......................................................................................................................... 354 1.33 ORACLE 数据字典表 -- SYS.COL$ .............................................................................................. 361 1.33.1 数据字典表 SYS.COL$ 说明 ........................................................................................... 361 1.33.2 SYS.COL$ 示例 ................................................................................................................. 365 1.33.2.1 创建测试表 ............................................................................................................................. 365 1.33.2.2 从 ALL_OBJECTS 中查找对象 DAVE.MYUSER 表的 ID ............................................................ 365 1.33.2.3 根据 MYUSER 的 ID,从 SYS.COL$检索出表中列的定义信息 ............................................. 365 1.33.2.4 使用 Update 语句来进行修改 ............................................................................................... 366 1.33.2.5 重启数据库服务 ..................................................................................................................... 366 1.33.2.6 再查看 .................................................................................................................................... 366 1.34 ORACLE 动态性能视图 ............................................................................................................. 367 1.34.1 Oracle 联机文档上有关动态性能视图的内容: .......................................................... 367 1.34.2 动态性能视图 ................................................................................................................ 369 1.34.3 V$, V_$, GV$, X$ 视图说明 ...................................................................................... 370 1.34.3.1 X$ 表 .................................................................................................................................... 370 1.34.3.2 GV$ 和 V$ 同义词 ............................................................................................................... 370 1.34.3.2.1 V$ 视图 ........................................................................................................................ 370 1.34.3.2.2 GV$ 视图 ..................................................................................................................... 371 1.34.3.3 V$FIXED_VIEW_DEFINITION 视图 ........................................................................................ 371 1.34.3.4 GV_$, V_$视图 ...................................................................................................................... 374 1.34.4 20 个常用的动态性能视图 ............................................................................................. 375 1.35 ORACLE 性能相关的几个 视图 和 参数 ................................................................................. 376 1.35.1 性能视图 ......................................................................................................................... 376 1.35.1.1 V$SQL ....................................................................................................................................... 376 1.35.1.1.1 用 V$SQL 查看 SQL 内容 .............................................................................................. 376 1.35.1.1.2 用 V$SQL 查看 SQL 执行和等待时间 ........................................................................... 376 1.35.1.1.3 共享池中的 SQL ............................................................................................................. 377 1.35.1.2 V$SQL_SHARED_CURSOR ......................................................................................................... 378 1.35.1.3 V$SESSION ................................................................................................................................ 379 1.35.1.4 V$SESSTAT ................................................................................................................................ 380 1.35.1.5 V$SESSION_WAIT ..................................................................................................................... 380 1.35.2 性能参数 ........................................................................................................................ 381 1.35.2.1 CURSOR_SHARING ................................................................................................................... 381 1.35.2.1.1 cursor_sharing=exact(默认值) ................................................................................... 381 1.35.2.1.2 cursor_sharing=similar ..................................................................................................... 382 1.35.2.1.3 cursor_sharing=force ....................................................................................................... 382 1.35.2.1.4 SIMILAR 和 Force 的区别 .............................................................................................. 383 1.35.2.2 DB_FILE_MULTIBLOCK_READ_COUNT ..................................................................................... 383 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.36 ORACLE DUAL 表详解 ................................................................................................................. 384 1.36.1 官网说明 ........................................................................................................................ 384 1.36.2 DUAL 表的用途 ................................................................................................................ 384 1.36.3 关于 DUAL 表的测试与分析 .......................................................................................... 385 1.36.3.1 查看 DUAL 是什么 OBJECT ..................................................................................................... 385 1.36.3.2 DUAL 表行数 问题 .............................................................................................................. 386 1.36.3.3 Drop Dual table. ....................................................................................................................... 389 二. ORACLE 备份恢复 ................................................................................................................... 435 2.1 EXP/IMP ..................................................................................................................................... 435 2.1.1 命令帮助如下 .................................................................................................................. 436 2.1.1.1 export ......................................................................................................................................... 436 2.1.1.2 import ........................................................................................................................................ 437 2.1.2 Export ................................................................................................................................. 439 2.1.2.1. 表模式 ..................................................................................................................................... 439 2.1.2.2. 用户模式.................................................................................................................................. 439 2.1.2.3. 完全模式.................................................................................................................................. 439 2.1.3 IMPORT .............................................................................................................................. 439 2.1.3.1. 表模式 ..................................................................................................................................... 440 2.1.3.1.1 恢复备份数据的全部内容 ............................................................................................... 440 2.1.3.1.2 恢复备份数据中的指定表 ............................................................................................... 440 2.1.3.2. 用户模式.................................................................................................................................. 440 2.1.3.2.1. 恢复备份数据的全部内容 .............................................................................................. 440 2.1.3.2.2. 恢复备份数据中的指定表 .............................................................................................. 440 2.1.3.3. 完全模式.................................................................................................................................. 441 2.1.3.4. 参数说明.................................................................................................................................. 441 2.1.3.4.1. ignore 参数 ....................................................................................................................... 441 2.1.3.4.2. indexes 参数 ..................................................................................................................... 441 2.1.3.4.3 字符集转换 ...................................................................................................................... 441 2.1.3.5. IMP 常见问题及解决方法 ................................................................................................... 441 2.1.3.5.1 数据库对象已经存在..................................................................................................... 441 2.1.3.5.2 数据库对象有主外键约束 ............................................................................................. 441 2.1.3.5.3 权限不够 ........................................................................................................................ 442 2.1.3.5.4 导入大表( 大于 80M ) 时, 存储分配失败 .................................................................. 442 2.1.3.5.5 imp 和 exp 使用的字符集不同 ...................................................................................... 442 2.1.3.5.6 imp 和 exp 版本不能往上兼容 ...................................................................................... 442 2.1.4 示例 .................................................................................................................................. 442 2.1.4.1 oracle 创建表空间,创建用户 ................................................................................................. 442 2.1.4.2 表模式备份 与 恢复 ............................................................................................................... 443 2.1.4.3 用户模式备份与恢复 ............................................................................................................... 443 2.1.4.4 完全模式备份与恢复 ............................................................................................................... 443 2.2 EXPDP/IMPDP .............................................................................................................................. 444 2.2.1 官网说明 .......................................................................................................................... 444 2.1.1.1. Oracle 10g 文档如下: .......................................................................................................... 444 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 2.1.1.2. Oracle 11gR2 中文档: ........................................................................................................ 447 2.2.2 Data Pump 介绍 ............................................................................................................... 448 2.2.3 EXPDP/IMPDP 命令使用详解 ........................................................................................... 453 2.2.3.1 EXPDP 命令参数及说明 ......................................................................................................... 453 2.2.3.2 EXPDP 使用示例 .................................................................................................................... 456 2.2.3.3 IMPDP 命令参数说明 ............................................................................................................ 457 2.2.3.4 IMPDP 命令实例 .................................................................................................................... 458 2.2.4 expdp/impdp 使用示例 .................................................................................................... 458 2.2.4.1. 创建目录.................................................................................................................................. 458 2.2.4.2. 创建测试数据 .......................................................................................................................... 459 2.2.4.3. 开始测试.................................................................................................................................. 461 2.2.4.3.1 FULL=Y 全库导出 ............................................................................................................... 461 2.2.4.3.2 全库导入 .......................................................................................................................... 463 2.2.4.3.3 导出表 ............................................................................................................................ 463 2.2.4.3.4 导入表 .............................................................................................................................. 463 2.2.4.3.5 导出用户 .......................................................................................................................... 463 2.2.4.3.6 导入用户 .......................................................................................................................... 463 2.2.4.3.7 导出表空间 ...................................................................................................................... 464 2.2.4.3.8 导入表空间 ...................................................................................................................... 464 2.2.4.3.9 REMAP_SCHEMA ............................................................................................................ 464 2.2.4.3.10 REMAP_TABLESPACE ..................................................................................................... 464 2.2.4.3.11 REMAP_DATAFILE .......................................................................................................... 465 2.2.4.3.12 TRANSPORT_DATAFILES ................................................................................................ 465 2.3 EXP/IMP 与 EXPDP/IMPDP 对于 和优化事项 ............................................................................. 468 2.3.1. exp/imp 与 expdp/impdp 对比 ...................................................................................... 468 2.3.1.1 运行位置不同 ......................................................................................................................... 468 2.3.1.2 exp/imp 与 expdp/impdp 的默认模式和原理不一样 ........................................................ 468 2.3.1.2.1 exp/imp 不同模式原理 .................................................................................................... 468 2.3.1.2.2 expdp/impdp 不同模式 .................................................................................................... 469 2.3.1.3 网络和磁盘影响 ..................................................................................................................... 471 2.3.1.4 exp/imp 与 expdp/impdp 功能上的区别 ............................................................................ 471 2.3.2 使用中的优化事项........................................................................................................... 472 2.3.2.1 exp ........................................................................................................................................... 472 2.3.2.2 IMP .......................................................................................................................................... 473 2.3.2.3 Expdp/Impdp .............................................................................................................................. 474 2.4 FLASHBACK ................................................................................................................................. 476 2.4.1 闪回恢复区(Flashback Recovery Area) ............................................................................ 477 2.4.1.1. 设置闪回恢复区 ...................................................................................................................... 477 2.4.1.2 取消闪回恢复区 ..................................................................................................................... 478 2.4.1.3 闪回恢复区的内容 ................................................................................................................. 479 2.4.1.4 闪回恢复区的一些限制 ......................................................................................................... 480 2.4.1.5 闪回恢复区的空间管理 ......................................................................................................... 480 2.4.1.6 Flash Recovery Area 空间不足导致 DB 不能打开或 hang 住处理方法 ................................ 483 2.4.1.7 Flash Recovery Area 的备份 .................................................................................................. 486 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 2.4.2 Flashback Database ........................................................................................................... 487 2.4.2.1 Flashback Database 说明 .......................................................................................................... 487 2.4.2.2 Flashback Database 架构 .......................................................................................................... 487 2.4.2.3 启用 Flashback Database 步骤 ................................................................................................ 488 2.4.2.3.1. 配置 Flash Recovery Area ................................................................................................ 488 2.4.2.3.2. 启动 flashback database .................................................................................................. 488 2.4.2.4 Flashback Database 操作示例 ................................................................................................... 489 2.4.2.4.1. 检查是否启动了 flash recovery area .............................................................................. 489 2.4.2.4.2. 检查是否启用了归档...................................................................................................... 489 2.4.2.4.3. 检查是否启用了 flashback database .............................................................................. 489 2.4.2.4.4. 查询当前的 scn ............................................................................................................... 489 2.4.2.4.5. 查询当前的时间 ............................................................................................................. 489 2.4.2.4.6. 删除表 A .......................................................................................................................... 490 2.4.2.4.7. 重启 DB 到 mount .......................................................................................................... 490 2.4.2.4.8. 执行恢复:分 timestamp 或者 SCN 两种 ..................................................................... 490 2.4.2.4.9. 打开数据库 ..................................................................................................................... 491 2.4.2.5 和 Flashback Database 相关的 3 个视图 ................................................................................ 491 2.4.2.5.1. V$database ....................................................................................................................... 491 2.4.2.5.2. V$flashback_database_log ................................................................................................ 491 2.4.2.5.3. V$flashback_database_stat .............................................................................................. 492 2.4.3 Flashback Drop ................................................................................................................... 492 2.4.3.1. Tablespace Recycle Bin .............................................................................................................. 492 2.4.3.2. Flashback Drop 实例操作 ........................................................................................................ 495 2.4.4 Flashback Query ................................................................................................................. 497 2.4.4.1 Flashback Query ...................................................................................................................... 497 2.4.4.1.1 多版本读一致性 ............................................................................................................ 498 2.4.4.1.2 As of timestamp 的示例: ...................................................................................... 498 2.4.4.1.3. As of scn 示例 .................................................................................................................. 499 2.4.4.1.4 SCN 与 timestamp 关系 ............................................................................................... 500 2.4.4.1.5 Flashback Query 函数,存储过程,包,触发器等对象............................................. 501 2.4.4.2 Flashback version Query ......................................................................................................... 504 2.4.4.3 Flashback Transaction Query ................................................................................................... 507 2.4.5 Flashback Table .................................................................................................................. 508 2.4.6 Oracle Flashback Data Archive ........................................................................................... 510 2.4.6.1 Flashback Data Archive 说明 .................................................................................................. 511 2.4.6.2 Flashback Data Archive 的相关操作 ...................................................................................... 513 2.4.6.2.1 Creating a Flashback Data Archive ..................................................................................... 513 2.4.6.2.2 Altering a Flashback Data Archive ................................................................................... 516 2.4.6.2.3 Dropping a Flashback Data Archive ................................................................................. 518 2.4.6.2.4 Specifying the Default Flashback Data Archive ............................................................... 519 2.4.6.2.5 Enabling and Disabling Flashback Data Archive .............................................................. 519 2.4.6.2.6 DDL Statements on Tables Enabled for Flashback Data Archive ......................................... 521 2.4.6.3 一个用 Flashback Data Archive 恢复数据的测试 ................................................................. 523 2.5 各种故障恢复 ......................................................................................................................... 526 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 2.5.1. SPFILE 丢失 ....................................................................................................................... 526 2.5.2. Controlfile 全部丢失 ......................................................................................................... 526 2.5.3 UNDO 损坏的情况 ........................................................................................................ 526 2.5.3.1 方法一: 使用 system segment ................................................................................................. 527 2.5.3.2.方法二:跳过损坏的 segment ................................................................................................. 527 2.5.4. Redo Log File 损坏 ............................................................................................................ 528 2.5.3.1 CURRENT 情况 ....................................................................................................................... 528 2.5.3.2 非 CURRENT 情况 .................................................................................................................. 529 2.5.5. 非系统表空间损坏.......................................................................................................... 529 2.5.6. 数据文件损坏 ................................................................................................................. 530 2.5.7. 基于时间点/SCN/日志序列的不完全恢复 .................................................................... 530 2.5.7.1 基于时间点 ............................................................................................................................... 530 2.5.7.2 基于 SCN: ................................................................................................................................. 531 2.5.7.3 基于日志序列 ........................................................................................................................... 531 2.5.8. 非 catalog 下完全恢复.................................................................................................... 531 2.6 前滚(ROLL FORWORD)和回滚(ROLL BACK) .......................................................................... 532 2.6.1 什么时候需要实例恢复 ................................................................................................... 532 2.6.1.1 Clean shutdown 时 .................................................................................................................... 532 2.6.1.2 非正常 shutdown ..................................................................................................................... 533 2.6.1.3 crash recovery 顺序问题 .......................................................................................................... 533 2.6.2 Crash Recovery 过程 ......................................................................................................... 533 2.6.3 为什么数据库的实例恢复是先前滚再回滚 ................................................................... 534 三. RMAN....................................................................................................................................... 534 四. DATA GUARD ............................................................................................................................ 537 五. RAC .......................................................................................................................................... 731 5.1 集群环境下的一些特殊问题 ................................................................................................. 731 5.1.1 并发控制 .......................................................................................................................... 731 5.1.2 健忘症(Amnesia) .............................................................................................................. 731 5.1.3 脑裂(Split Brain) ................................................................................................................ 731 5.1.4 IO 隔离(Fencing) ............................................................................................................ 732 5.2 RAC 并发 ............................................................................................................................... 732 5.2.1 GRD(Global Resource Directory) ................................................................................ 733 5.3. RAC 架构 .................................................................................................................................. 733 5.3.1 SGA 的变化 ....................................................................................................................... 733 5.3.2 后台进程的变化 .............................................................................................................. 733 5.3.2.1 LMSn ....................................................................................................................................... 734 5.3.2.2 LMD ......................................................................................................................................... 734 5.3.2.3 LCK........................................................................................................................................... 734 5.3.2.4 LMON ...................................................................................................................................... 734 5.3.2.5 DIAG ........................................................................................................................................... 734 5.3.2.6 GSD ............................................................................................................................................. 734 5.3.3 文件 .................................................................................................................................. 734 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 5.3.3.1 spfile ........................................................................................................................................... 735 5.3.3.2 Redo Thread ............................................................................................................................... 735 5.3.3.3 Archived Log ............................................................................................................................... 735 1)使用 NFS ..................................................................................................................................... 735 2)实例间归档(CIA: Cross Instance Archive) ............................................................................. 736 3)使用 ASM .................................................................................................................................... 736 5.3.3.4 Undo Tablespace ........................................................................................................................ 736 5.3.4 SCN(System Change Number) ............................................................................................ 736 5.3.5 Cache Fusion,GCS,GES 关系 ........................................................................................ 736 5.4 RAC 集群 ................................................................................................................................. 737 5.4.1 Clusterware ........................................................................................................................ 737 5.4.2 Clusterware 组成 .............................................................................................................. 737 5.4.2.1 磁盘文件 ............................................................................................................................. 737 5.4.2.2 Clusterware 后台进程 ......................................................................................................... 738 5.4.3 VIP 原理和特点 ................................................................................................................ 740 5.4.4 Clusterware 的日志体系 .................................................................................................. 741 5.5 RAC FAILOVER ............................................................................................................................. 742 5.5.1.Client-Side Connect Time Failover ................................................................................... 742 5.5.2.Client-Side TAF(Transparent Application Failover) .......................................................... 743 5.5.3. Client-Side TAF 配置示例 .................................................................................................. 744 5.3.3.1 主机信息如下 ............................................................................................................................ 744 5.3.3.2 Node1 配置 ................................................................................................................................ 744 5.3.3.3 NODE2 配置 ............................................................................................................................... 745 5.3.3.4 在 node1 和 node2 的 tnsnames.ora 文件添加如下内容 ........................................................ 745 5.3.3.5 在所有节点设置 remote listener .............................................................................................. 746 5.3.3.6 在客户端设置的 tnsnames.ora 设置 TAF ................................................................................. 746 5.5.4.Service-Side TAF .............................................................................................................. 747 5.5.4.1 用 DBCA 配置 Service .............................................................................................................. 747 5.5.4.2 用 srvctl 命令配置 Service....................................................................................................... 748 5.5.4.3 配置 Service 的注意事项 ........................................................................................................ 749 5.5.5 Service-Side TAF 手工配置示例 ..................................................................................... 749 5.6 RAC LOADBALANCE ...................................................................................................................... 754 5.6.1 Connection Balancing ......................................................................................................... 754 5.6.1.1 客户端均衡(Client-Side LB) ................................................................................................. 755 5.6.1.2 服务器端均衡(Server-Side LB) ............................................................................................ 755 5.6.1.3 两种 LB 的配置方法 ................................................................................................................ 757 5.6.2 利用 Service 分散负载 ..................................................................................................... 757 5.7 RAC 启动和关闭 ..................................................................................................................... 759 5.7.1. 检查共享设备 ................................................................................................................. 759 5.7.1.1 如果使用 ocfs2 的,检查 ocfs2 状态 ..................................................................................... 759 5.7.1.2. 如果使用 raw device. .............................................................................................................. 759 5.7.1.3. 检查 ASM ................................................................................................................................. 759 5.7.2.自动启动 RAC 并检查相关进程 .................................................................................... 759 5.7.3.手动启动 RAC ................................................................................................................. 762 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 5.8 ORACLE RAC 常用维护工具和命令.......................................................................................... 764 5.8.1 节点层 ............................................................................................................................... 764 5.8.2 网络层 ............................................................................................................................... 764 5.8.3 集群层 ............................................................................................................................... 766 5.8.3.1 CRSCTL ........................................................................................................................................ 766 5.8.3.1.1 检查 CRS 状态 ................................................................................................................. 767 5.8.3.1.2 配置 CRS 栈是否自启动 ................................................................................................. 767 5.8.3.1.3 启动,停止 CRS 栈 ......................................................................................................... 768 5.8.3.1.4 查看 Votedisk 磁盘位置 .................................................................................................. 768 5.8.3.1.5 查看和修改 CRS 参数 ..................................................................................................... 768 5.8.3.1.6 跟踪 CRS 模块,提供辅助功能 ...................................................................................... 768 5.8.3.1.7 维护 Voting disk ................................................................................................................ 770 5.8.3.2 OCR 命令系列 ............................................................................................................................ 770 5.8.3.2.1 ocrdump ............................................................................................................................. 771 5.8.3.2.2 ocrcheck ............................................................................................................................. 771 5.8.3.2.3 ocrconfig ............................................................................................................................ 772 5.8.3.2.4 使用 ocrconfig 导出,导入进行备份和恢复 ................................................................. 772 5.8.3.2.5 移动 OCR 文件位置 ......................................................................................................... 774 5.8.4 应用层 .............................................................................................................................. 775 5.8.4.1 crs_stat ....................................................................................................................................... 775 5.8.4.2 onsctl .......................................................................................................................................... 777 5.8.4.2.1 ONS 配置内容 .................................................................................................................. 777 5.8.4.2.2 配置 ONS .......................................................................................................................... 778 5.8.4.2.3 onsctl 命令 ........................................................................................................................ 778 5.8.4.3 srvctl ........................................................................................................................................... 780 5.8.4.3.1 使用 config 查看配置 ....................................................................................................... 781 5.8.4.3.2 使用 add 添加对象 ......................................................................................................... 782 5.8.4.3.3 使用 enable/disable 启动,禁用对象 ............................................................................ 783 5.8.4.3.4 使用 remove 删除对象 ................................................................................................... 784 5.8.4.3.5 启动,停止对象与查看对象 ........................................................................................... 784 5.8.4.3.6 跟踪 srvctl ......................................................................................................................... 785 5.8.4.4 初始化 OCR 和 Voting Disk ...................................................................................................... 785 5.8.4.5 官网的命令说明 ....................................................................................................................... 787 5.8.4.6 crs_stat 完整显示进程名脚本 ................................................................................................. 789 六. 常用脚本............................................................................................................................... 1206 6.1 查看表空间使用率 ................................................................................................................. 1206 6.2 获取当前 TRACE 文件路径脚本 .............................................................................................. 1207 6.3 发送邮件的存储过程 ............................................................................................................. 1207 6.4 AWR 自动收集并发送邮箱 PYTHON 脚本 ............................................................................... 1216 6.4.1 准备工作 ......................................................................................................................... 1216 6.4.2 生成 AWR 报告 SQL 脚本 .............................................................................................. 1221 6.4.3 自动上传 AWR 的 Python 脚本 ..................................................................................... 1222 6.4.4 将 Python 添加到 crontab ............................................................................................. 1224 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 6.5 查看 SEGMENT 中 BLOCK 的存储信息 ...................................................................................... 1224 6.6 ORACLE 用 SQLPROMPT 修改 SQLPLUS 提示符 ........................................................................... 1227 6.6.1 方法一:使用定义的变量 ............................................................................................. 1228 6.6.2 方法二:使用 sql 语句拼接 ......................................................................................... 1229 七. 性能优化............................................................................................................................... 1242 7.1 软解析 和 硬解析 ................................................................................................................. 1242 7.1.1 SQL 解析过程 .............................................................................................................. 1242 7.1.2.解析过程详解 .............................................................................................................. 1242 7.1.2.1 语法检测................................................................................................................................. 1242 7.1.2.2 语义检查................................................................................................................................. 1242 7.1.2.3 解析(Parse) ............................................................................................................................. 1243 7.1.2.3.1 Parse 主要分为两种: .................................................................................................... 1243 7.1.2.3.2 解析的两个步骤 ............................................................................................................ 1243 7.1.2.4 执行 sql ................................................................................................................................... 1245 7.2 绑定变量 ................................................................................................................................. 1245 7.2.1 Band Variable 说明 ...................................................................................................... 1245 7.2.2.OLAP 和 OLTP 系统中的绑定变量 ............................................................................. 1246 7.2.3.Bind peaking.................................................................................................................. 1247 7.2.4 绑定变量 使用示例..................................................................................................... 1248 7.3 CBO 和 RBO ............................................................................................................................ 1250 7.3.1 RBO 基于规则的优化器 ................................................................................................. 1250 7.3.2 CBO 基于成本的优化器 .................................................................................................. 1251 7.3.2.1 CBO 说明 ................................................................................................................................. 1251 7.3.3.2 优化器模式 ............................................................................................................................. 1252 7.3.3.2.1 修改 CBO 模式的三种方法 ............................................................................................ 1252 7.3.3.2.2 查看 CBO 模式 ............................................................................................................... 1253 7.3.3.2.3 优化器模式具体说明..................................................................................................... 1253 7.3.3 optimizer_index_cost_adj 参数 ....................................................................................... 1254 7.3.4 在 CBO 下写 SQL 语句的注意事项 ................................................................................ 1254 7.4 10053 事件 .............................................................................................................................. 1256 7.4.1 10053 事件说明 ............................................................................................................. 1256 7.4.2 示例: ............................................................................................................................ 1257 7.4.3 查看生成的 trace 文件 .................................................................................................. 1258 7.5 10046 事件 .............................................................................................................................. 1264 7.5.1 10046 事件说明 ............................................................................................................. 1264 7.5.2 对当前 session 使用 10046 事件 .................................................................................. 1264 7.5.3 对其他的会话进行跟踪 .................................................................................................. 1265 7.5.3.1 用 SQL_TRACE 跟踪 ................................................................................................................ 1265 7.5.3.2 使用 10046 事件跟踪 ............................................................................................................ 1265 7.6 SQL TRACE .................................................................................................................................. 1266 7.7 统计信息 ................................................................................................................................. 1267 7.7.1. Statistic 说明 .................................................................................................................. 1267 7.7.2 统计信息的收集 .......................................................................................................... 1268 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 7.7.2.1 查看该 Job 信息 .................................................................................................................... 1268 7.2.2.2 监控参数 STATISTICS_LEVEL .................................................................................................. 1269 7.2.2.3 停用该 Job .............................................................................................................................. 1269 7.2.3.4 系统用户统计信息的收集 ...................................................................................................... 1269 7.7.3. 统计信息的存储位置.................................................................................................... 1270 7.3.3.1 表的统计信息 ......................................................................................................................... 1271 7.3.3.2 索引列的统计信息 ................................................................................................................. 1271 7.3.3.3 列的统计信息 ......................................................................................................................... 1271 7.3.3.4 测试:表只有分析了之后,num_rows 才会有值 ............................................................... 1271 7.7.4 直方图(histograms) ................................................................................................. 1272 7.7.4.1 Height-Balanced Histograms ................................................................................................. 1273 7.7.4.2 Frequency Histograms ........................................................................................................... 1274 7.7.5 DBMS_STATS 包 使用说明 ........................................................................................... 1276 7.7.5.1 DBMS_STATS 包的几个常用功能:性能的收集,设置,删除 ............................................. 1277 7.7.5.1.1 GATHER_TABLE_STATS 存储过程 ............................................................................... 1277 7.7.5.1.2 GATHER_SCHEMA_STATS 存储过程 ............................................................................ 1283 7.7.5.1.3 DBMS_STATS.GATHER_INDEX_STATS 存储过程 ........................................................... 1287 7.7.5.2 DBMS_STATS 包管理功能 ........................................................................................................ 1289 7.7.5.2.1 获取分析数据 ................................................................................................................ 1289 7.7.5.2.2 设置分析数据 ................................................................................................................ 1290 7.7.5.2.3 删除分析数据 ................................................................................................................ 1290 7.7.5.2.4 保存分析数据 ................................................................................................................ 1291 7.7.5.2.5 导入和导出分析数据..................................................................................................... 1291 7.7.5.2.6 锁定分析数据 ................................................................................................................ 1292 7.7.5.2.7 分析数据的恢复 ............................................................................................................ 1292 7.7.6 动态采样 ...................................................................................................................... 1293 7.7.6.1 什么是动态采样 ..................................................................................................................... 1293 7.7.6.2 动态采样的级别 ..................................................................................................................... 1296 7.7.6.2.1 Level 0 .............................................................................................................................. 1297 7.7.6.2.2 Level 1 .............................................................................................................................. 1297 7.7.6.2.3 Level 2 .............................................................................................................................. 1297 7.7.6.2.4 Level 3 .............................................................................................................................. 1297 7.7.6.2.5 Level 4 .............................................................................................................................. 1297 7.7.6.2.6 Level 5,6,7,8,9 ...................................................................................................... 1297 7.7.6.2.7 Level 10 ............................................................................................................................ 1297 7.7.6.3 什么时候使用动态采样 ......................................................................................................... 1297 7.8 HINT .......................................................................................................................................... 1298 7.8.1 和优化器相关的 Hint ..................................................................................................... 1300 7.8.1.1 ALL_ROWS 和 FIRST_ROWS(n) -- CBO 模式 .................................................................... 1300 7.8.1.2 RULE Hint -- RBO 模式 ....................................................................................................... 1300 7.8.2 访问路径相关的 Hint ...................................................................................................... 1301 7.8.2.1 FULL Hint .................................................................................................................................. 1301 7.8.2.2 INDEX Hint ................................................................................................................................ 1301 7.8.2.3 NO_INDEX Hint ......................................................................................................................... 1302 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 7.8.2.4 INDEX_DESC Hint ...................................................................................................................... 1302 7.8.2.5 INDEX_COMBINE Hint .............................................................................................................. 1302 7.8.2.6 INDEX_FFS Hint ........................................................................................................................ 1302 7.8.2.7 INDEX_JOIN Hint ...................................................................................................................... 1302 7.8.2.8 INDEX_SS Hint .......................................................................................................................... 1302 7.8.3 表关联顺序的 Hint .......................................................................................................... 1303 7.8.3.1 LEADING hint ............................................................................................................................ 1303 7.8.3.2 ORDERED Hint .......................................................................................................................... 1304 7.8.4 表关联操作的 Hint .......................................................................................................... 1304 7.8.4.1 USE_HASH,USE_NL,USE_MERGE hint ...................................................................................... 1304 7.8.4.2 NO_USE_HASH,NO_USE_NL,NO_USE_MERGE HINT ............................................................... 1305 7.8.5 并行执行相关的 Hint ..................................................................................................... 1305 7.8.5.1 PARALLEL HINT ......................................................................................................................... 1305 7.8.5.2 NO_PARALLEL HINT .................................................................................................................. 1306 7.8.6 其他方面的一些 Hint ...................................................................................................... 1306 7.8.6.1 APPEND HINT ........................................................................................................................... 1306 7.8.6.2 DYNAMIC_SAMPLING HINT ...................................................................................................... 1306 7.8.6.3 DRIVING_SITE HINT .................................................................................................................. 1306 7.8.6.4 CACHE HINT .............................................................................................................................. 1307 7.8.7 常见的 Hint ...................................................................................................................... 1307 7.8.7.1. /*+ALL_ROWS*/ ...................................................................................................................... 1307 7.8.7.2. /*+FIRST_ROWS*/ ................................................................................................................... 1307 7.8.7.3. /*+CHOOSE*/ .......................................................................................................................... 1307 7.8.7.4. /*+RULE*/ ............................................................................................................................... 1308 7.8.7.5. /*+FULL(TABLE)*/ .................................................................................................................... 1308 7.8.7.6. /*+ROWID(TABLE)*/ ................................................................................................................ 1308 7.8.7.7. /*+CLUSTER(TABLE)*/ ............................................................................................................. 1308 7.8.7.8. /*+INDEX(TABLE INDEX_NAME)*/ .......................................................................................... 1308 7.8.7.9. /*+INDEX_ASC(TABLE INDEX_NAME)*/ .................................................................................. 1308 7.8.7.10. /*+INDEX_COMBINE*/ .......................................................................................................... 1309 7.8.7.11. /*+INDEX_JOIN(TABLE INDEX_NAME)*/ ............................................................................... 1309 7.8.7.12. /*+INDEX_DESC(TABLE INDEX_NAME)*/ .............................................................................. 1309 7.8.7.13. /*+INDEX_FFS(TABLE INDEX_NAME)*/ ................................................................................. 1309 7.8.7.14. /*+ADD_EQUAL TABLE INDEX_NAM1,INDEX_NAM2,...*/ ..................................................... 1309 7.8.7.15. /*+USE_CONCAT*/ ................................................................................................................ 1309 7.8.7.16. /*+NO_EXPAND*/ ................................................................................................................. 1310 7.8.7.17. /*+NOWRITE*/ ...................................................................................................................... 1310 7.8.7.18. /*+REWRITE*/ ....................................................................................................................... 1310 7.8.7.19. /*+MERGE(TABLE)*/ .............................................................................................................. 1310 7.8.7.20. /*+NO_MERGE(TABLE)*/ ...................................................................................................... 1310 7.8.7.21. /*+ORDERED*/ ...................................................................................................................... 1310 7.8.7.22. /*+USE_NL(TABLE)*/ ............................................................................................................. 1310 7.8.7.23. /*+USE_MERGE(TABLE)*/ ..................................................................................................... 1311 7.8.7.24. /*+USE_HASH(TABLE)*/ ........................................................................................................ 1311 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 7.8.7.25. /*+DRIVING_SITE(TABLE)*/ ................................................................................................... 1311 7.8.7.26. /*+LEADING(TABLE)*/ ........................................................................................................... 1311 7.8.7.27. /*+CACHE(TABLE)*/ ............................................................................................................... 1311 7.8.7.28. /*+NOCACHE(TABLE)*/ ......................................................................................................... 1311 7.8.7.29. /*+APPEND*/ ........................................................................................................................ 1311 7.8.7.30. /*+NOAPPEND*/ ................................................................................................................... 1312 7.9 高水位(HIGH WATER MARK).................................................................................................. 1312 7.9.1 ORACLE 的逻辑存储管理. ............................................................................................ 1312 7.9.2. 什么是高水线(High Water Mark) ................................................................................. 1313 7.9.3. Oracle 表段中的高水位线 HWM ................................................................................... 1317 7.9.4. 修正 ORACLE 表的高水位线 ......................................................................................... 1318 7.9.5. HWM 特点 ..................................................................................................................... 1319 7.10 执行计划 ............................................................................................................................... 1320 7.10.1 查看执行计划的三种方法 ........................................................................................... 1320 7.10.1.1 设置 autotrace ...................................................................................................................... 1320 7.10.1.2 使用 SQL ............................................................................................................................... 1321 7.10.1.3 使用 Toad,PL/SQL Developer 工具 ....................................................................................... 1323 7.10.2 Cardinality(基数)/ rows ............................................................................................ 1323 7.10.3 SQL 的执行计划 ........................................................................................................... 1324 7.10.3.1 执行计划中字段解释 ........................................................................................................... 1326 7.10.3.2 谓词说明............................................................................................................................... 1326 7.10.3.3 统计信息说明 ....................................................................................................................... 1326 7.10.4 动态分析 ...................................................................................................................... 1328 7.11 索引的维护 ........................................................................................................................... 1328 7.11.1 索引扫描的 4 种类型................................................................................................... 1328 7.11.1.1 索引唯一扫描(index unique scan) ....................................................................................... 1328 7.11.1.2 索引范围扫描(index range scan) .......................................................................................... 1329 7.11.1.3 索引全扫描(index full scan) ................................................................................................. 1330 7.11.1.4 索引快速扫描(index fast full scan) ....................................................................................... 1330 7.11.2 查看系统表中的用户索引 ........................................................................................... 1336 7.11.3 索引的存储情况检查................................................................................................... 1337 7.11.4 索引的选择性 .............................................................................................................. 1337 7.11.5 确定索引的实际碎片................................................................................................... 1338 7.11.6 如果加快创建索引的时间 ........................................................................................... 1342 7.11.6.1 查看创建索引要做哪些操作 ............................................................................................... 1342 7.11.6.2 测试示例............................................................................................................................... 1343 7.11.7 Oracle 索引可以比表大 ............................................................................................... 1345 7.11.7.1 先看一段官网的说明: ....................................................................................................... 1345 7.11.7.2 测试示例............................................................................................................................... 1346 7.12 LOGMINER ................................................................................................................................. 1348 7.13 碎片 ....................................................................................................................................... 1348 7.14 多表连接与关联 ................................................................................................................... 1348 7.14.1 多表连接 ...................................................................................................................... 1348 7.14.1.1 内连接(Inner Join/Join) .................................................................................................... 1349 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 7.14.1.1.1 Inner Join ....................................................................................................................... 1349 7.14.1.1.2 内连接示例 .................................................................................................................. 1349 7.14.1.1.3 自然连接(Natural join) ................................................................................................. 1350 7.14.1.2 外连接(Outer Join) ................................................................................................................. 1351 7.14.1.2.1 左外连接(Left outer join/ left join) ......................................................................... 1352 7.14.1.2.2 右外连接(right outer join/ right join) ..................................................................... 1353 7.14.1.2.3 全外连接(full outer join/ full join) .......................................................................... 1354 7.14.1.3 自连接 ................................................................................................................................... 1355 7.14.1.4 各种连接关系图 .................................................................................................................... 1356 7.14.2 多表关联 ...................................................................................................................... 1356 7.14.2.1 NESTED LOOP ......................................................................................................................... 1358 7.14.2.2 HASH JOIN .............................................................................................................................. 1360 7.14.2.3 SORT MERGE JOIN .................................................................................................................. 1363 7.15 并行执行(PARALLEL EXECUTION) .......................................................................................... 1363 7.16 TKPROF 工具 ......................................................................................................................... 1363 7.16.1 tkprof 参数说明 ............................................................................................................ 1364 7.16.2 用 tkprof 命令查看 trace 文件 ................................................................................... 1365 7.17 SHRINK ................................................................................................................................... 1369 7.18 ................................................................................................................................................ 1370 7.19 ................................................................................................................................................ 1370 八. ORACLE ASM .......................................................................................................................... 1373 九. GOLDEN GATE ........................................................................................................................ 1373 十. 故障处理............................................................................................................................... 1373 十一. 常用操作文档 ................................................................................................................... 1373 11.1. 如何搭建一个数据库服务器平台 ...................................................................................... 1373 十二. LINUX 相关内容 ................................................................................................................ 1373 12.1 CRONTAB 定时任务 说明 ......................................................................................................... 1373 12.1.1 /etc/crontab 文件 ......................................................................................................... 1373 12.1.2 /etc/cron.deny 和 /etc/cron.allow 文件 ..................................................................... 1374 12.1.3 Crontab 使用说明 ...................................................................................................... 1374 12.1.3.1 Crontab 语法 ....................................................................................................................... 1374 12.1.3.2 Crontab 格式说明 .............................................................................................................. 1376 12.1.4 & 后台执行命令 ........................................................................................................ 1377 12.1.5 2>&1 含义 .................................................................................................................. 1378 12.1.6 2>&1 写在后面的原因 ............................................................................................... 1379 12.2 LINUX 性能监控 ...................................................................................................................... 1379 12.3 LINUX 系统 审计 脚本........................................................................................................... 1379 12.3.1 审计配置 ....................................................................................................................... 1379 12.3.2 验证 .............................................................................................................................. 1380 12.4 LINUX 前台 和 后台进程 说明 ............................................................................................. 1381 12.4.1 有关进程的几种常用方法 ............................................................................................ 1381 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 12.4.1.1 & 符号 ................................................................................................................................ 1381 12.4.1.2 Jobs 命令............................................................................................................................ 1381 12.4.1.3 fg 命令(foreground) ......................................................................................................... 1382 12.4.1.4 ctrl + z 组合键 .................................................................................................................... 1382 12.4.1.5 bg 命令(background) ..................................................................................................... 1382 12.4.1.6 结束正在运行的进程 ......................................................................................................... 1383 12.4.1.6.1 结束前台进程 .............................................................................................................. 1383 12.4.1.6.2 结束后台运行的进程................................................................................................... 1383 12.4.1.7 ps 命令 ............................................................................................................................... 1383 12.4.2 前台进程和后台进程的一点讨论 ............................................................................... 1384 十三. PYTHON 脚本 .................................................................................................................... 1430 一. Oracle 基础知识 1.1 Oracle OLAP 与 OLTP 介绍 数据处理大致可以分成两大类:联机事务处理 OLTP(on-line transaction processing)、 联机分析处理 OLAP(On-Line Analytical Processing)。 (1)OLTP 是传统的关系型数据库的主要应用,主要是基本的、日常的事务处 理,例如银行交易。OLTP 系统强调数据库内存效率,强调内存各种指标的命令 率,强调绑定变量,强调并发操作; (2)OLAP 是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持, 并且提供直观易懂的查询结果。OLAP 系统则强调数据分析,强调 SQL 执行市 场,强调磁盘 I/O,强调分区等。 OLTP 与 OLAP 之间的比较: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.1.1 什么是 OLTP OLTP,也叫联机事务处理(Online Transaction Processing),表示事务性非常 高的系统,一般都是高可用的在线系统,以小的事务以及小的查询为主,评估其 系统的时候,一般看其每秒执行的 Transaction 以及 Execute SQL 的数量。在这样 的系统中,单个数据库每秒处理的 Transaction 往往超过几百个,或者是几千个, Select 语句的执行量每秒几千甚至几万个。典型的 OLTP 系统有电子商务系统、 银行、证券等,如美国 eBay 的业务数据库,就是很典型的 OLTP 数据库。 OLTP 系统最容易出现瓶颈的地方就是 CPU 与磁盘子系统。 (1)CPU 出现瓶颈常表现在逻辑读总量与计算性函数或者是过程上,逻辑 读总量等于单个语句的逻辑读乘以执行次数,如果单个语句执行速度虽然很快, 但是执行次数非常多,那么,也可能会导致很大的逻辑读总量。设计的方法与优 化的方法就是减少单个语句的逻辑读,或者是减少它们的执行次数。另外,一些 计算型的函数,如自定义函数、decode 等的频繁使用,也会消耗大量的 CPU 时 间,造成系统的负载升高,正确的设计方法或者是优化方法,需要尽量避免计算 过程,如保存计算结果到统计表就是一个好的方法。 (2)磁盘子系统在 OLTP 环境中,它的承载能力一般取决于它的 IOPS 处理Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 能力. 因为在 OLTP 环境中,磁盘物理读一般都是 db file sequential read,也就是 单块读,但是这个读的次数非常频繁。如果频繁到磁盘子系统都不能承载其 IOPS 的时候,就会出现大的性能问题。 OLTP 比较常用的设计与优化方式为 Cache 技术与 B-tree 索引技术,Cache 决定了很多语句不需要从磁盘子系统获得数据,所以,Web cache 与 Oracle data buffer 对 OLTP 系统是很重要的。另外,在索引使用方面,语句越简单越好,这 样执行计划也稳定,而且一定要使用绑定变量,减少语句解析,尽量减少表关联, 尽量减少分布式事务,基本不使用分区技术、MV 技术、并行技术及位图索引。 因为并发量很高,批量更新时要分批快速提交,以避免阻塞的发生。 OLTP 系统是一个数据块变化非常频繁,SQL 语句提交非常频繁的系统。 对 于数据块来说,应尽可能让数据块保存在内存当中,对于 SQL 来说,尽可能使 用变量绑定技术来达到 SQL 重用,减少物理 I/O 和重复的 SQL 解析,从而极 大的改善数据库的性能。 这里影响性能除了绑定变量,还有可能是热快(hot block)。 当一个块被多 个用户同时读取时,Oracle 为了维护数据的一致性,需要使用 Latch 来串行化用 户的操作。当一个用户获得了 latch 后,其他用户就只能等待,获取这个数据块 的用户越多,等待就越明显。 这就是热快的问题。 这种热快可能是数据块,也 可能是回滚端块。 对于数据块来讲,通常是数据库的数据分布不均匀导致,如 果是索引的数据块,可以考虑创建反向所以来达到重新分布数据的目的,对于回 滚段数据块,可以适当多增加几个回滚段来避免这种争用。 1.1.2 什么是 OLAP OLAP,也叫联机分析处理(Online Analytical Processing)系统,有的时候也 叫 DSS 决策支持系统,就是我们说的数据仓库。在这样的系统中,语句的执行 量不是考核标准,因为一条语句的执行时间可能会非常长,读取的数据也非常多。 所以,在这样的系统中,考核的标准往往是磁盘子系统的吞吐量(带宽),如能 达到多少 MB/s 的流量。 磁盘子系统的吞吐量则往往取决于磁盘的个数,这个时候,Cache 基本是没 有效果的,数据库的读写类型基本上是 db file scattered read 与 direct path read/write。应尽量采用个数比较多的磁盘以及比较大的带宽,如 4Gb 的光纤接 口。 1.1.3 在 OLAP 系统中,常使用分区技术、并行技术 分区技术在 OLAP 系统中的重要性主要体现在数据库管理上,比如数据库加 载,可以通过分区交换的方式实现,备份可以通过备份分区表空间实现,删除数 据可以通过分区进行删除,至于分区在性能上的影响,它可以使得一些大表的扫 描变得很快(只扫描单个分区)。另外,如果分区结合并行的话,也可以使得整 个表的扫描会变得很快。总之,分区主要的功能是管理上的方便性,它并不能绝Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 对保证查询性能的提高,有时候分区会带来性能上的提高,有时候会降低。 并行技术除了与分区技术结合外,在 Oracle 10g 中,与 RAC 结合实现多节 点的同时扫描,效果也非常不错,可把一个任务,如 select 的全表扫描,平均地 分派到多个 RAC 的节点上去。 在 OLAP 系统中,不需要使用绑定(BIND)变量,因为整个系统的执行量 很小,分析时间对于执行时间来说,可以忽略,而且可避免出现错误的执行计划。 但是 OLAP 中可以大量使用位图索引,物化视图,对于大的事务,尽量寻求速 度上的优化,没有必要像 OLTP 要求快速提交,甚至要刻意减慢执行的速度。 绑定变量真正的用途是在 OLTP 系统中,这个系统通常有这样的特点,用户 并发数很大,用户的请求十分密集,并且这些请求的 SQL 大多数是可以重复使 用的。 对于 OLAP 系统来说,绝大多数时候数据库上运行着的是报表作业,执行基 本上是聚合类的 SQL 操作,比如 group by,这时候,把优化器模式设置为 all_rows 是恰当的。 而对于一些分页操作比较多的网站类数据库,设置为 first_rows 会更 好一些。 但有时候对于 OLAP 系统,我们又有分页的情况下,我们可以考虑在 每条 SQL 中用 hint。 如: Select /*+first_rows(10) */ a.* from table a; 1.1.4 分开设计与优化 在设计上要特别注意,如在高可用的 OLTP 环境中,不要盲目地把 OLAP 的 技术拿过来用。 如分区技术,假设不是大范围地使用分区关键字,而采用其它的字段作为 where 条件,那么,如果是本地索引,将不得不扫描多个索引,而性能变得更为 低下。如果是全局索引,又失去分区的意义。 并行技术也是如此,一般在完成大型任务时才使用,如在实际生活中,翻译 一本书,可以先安排多个人,每个人翻译不同的章节,这样可以提高翻译速度。 如果只是翻译一页书,也去分配不同的人翻译不同的行,再组合起来,就没必要 了,因为在分配工作的时间里,一个人或许早就翻译完了。 位图索引也是一样,如果用在 OLTP 环境中,很容易造成阻塞与死锁。但是, 在 OLAP 环境中,可能会因为其特有的特性,提高 OLAP 的查询速度。MV 也是 基本一样,包括触发器等,在 DML 频繁的 OLTP 系统上,很容易成为瓶颈,甚 至是 Library Cache 等待,而在 OLAP 环境上,则可能会因为使用恰当而提高查 询速度。 对于 OLAP 系统,在内存上可优化的余地很小,增加 CPU 处理速度和磁盘 I/O 速度是最直接的提高数据库性能的方法,当然这也意味着系统成本的增加。 比如我们要对几亿条或者几十亿条数据进行聚合处理,这种海量的数据,全 部放在内存中操作是很难的,同时也没有必要,因为这些数据快很少重用,缓存 起来也没有实际意义,而且还会造成物理 I/O 相当大。 所以这种系统的瓶颈往 往是磁盘 I/O 上面的。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 对于 OLAP 系统,SQL 的优化非常重要,因为它的数据量很大,做全表扫 描和索引对性能上来说差异是非常大的。 1.2 索引详解 1.2.1 索引介绍 1.2.1.1 索引的创建语法 CREATE UNIUQE | BITMAP INDEX . ON . ( | ASC | DESC, | ASC | DESC,...) TABLESPACE STORAGE LOGGING | NOLOGGING COMPUTE STATISTICS NOCOMPRESS | COMPRESS NOSORT | REVERSE PARTITION | GLOBAL PARTITION 相关说明 1) UNIQUE | BITMAP:指定 UNIQUE 为唯一值索引,BITMAP 为位图索引,省略为 B-Tree 索引。 2) | ASC | DESC:可以对多列进行联合索引,当为 expression 时即―基于函数的索引‖ 3)TABLESPACE:指定存放索引的表空间(索引和原表不在一个表空间时效率更高) 4)STORAGE:可进一步设置表空间的存储参数 5)LOGGING | NOLOGGING:是否对索引产生重做日志(对大表尽量使用 NOLOGGING 来减少占用空间并提高效率) 6)COMPUTE STATISTICS:创建新索引时收集统计信息 7)NOCOMPRESS | COMPRESS:是否使用―键压缩‖(使用键压缩可以删除一个键列 中出现的重复值) 8)NOSORT | REVERSE:NOSORT 表示与表中相同的顺序创建索引,REVERSE 表示相 反顺序存储索引值 9)PARTITION | NOPARTITION:可以在分区表和未分区表上对创建的索引进行分区 1.2.1.2 索引特点 第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。 第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。 第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。 1.2.1.3 索引不足 第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。 第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空 间,如果要建立聚簇索引,那么需要的空间就会更大。 第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了 数据的维护速度。 1.2.1.4 应该建索引列的特点 1)在经常需要搜索的列上,可以加快搜索的速度; 2)在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构; 3)在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度; 4)在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连 续的; 5)在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序, 加快排序查询时间; 6)在经常使用在 WHERE 子句中的列上面创建索引,加快条件的判断速度。 1.2.1.5 不应该建索引列的特点 第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很 少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降 低了系统的维护速度和增大了空间需求。 第二,对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少, 例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需 要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。 第三,对于那些定义为 blob 数据类型的列不应该增加索引。这是因为,这些列的数据量要 么相当大,要么取值很少。 第四,当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能 是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会 提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。 1.2.1.6 限制索引 限制索引是一些没有经验的开发人员经常犯的错误之一。在 SQL 中有很多陷阱会使一 些索引无法使用。下面讨论一些常见的问题: 1.2.1.6.1 使用不等于操作符(<>、!=) 下面的查询即使在 cust_rating 列有一个索引,查询语句仍然执行一次全表扫描。 select cust_Id,cust_name from customers where cust_rating <> 'aa'; 把上面的语句改成如下的查询语句,这样,在采用基于规则的优化器而不是基于代价的 优化器(更智能)时,将会使用索引。 select cust_Id,cust_name from customers where cust_rating < 'aa' or cust_rating > 'aa'; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 特别注意:通过把不等于操作符改成 OR 条件,就可以使用索引,以避免全表扫描。 1.2.1.6.2 使用 IS NULL 或 IS NOT NULL 使用 IS NULL 或 IS NOT NULL 同样会限制索引的使用。因为 NULL 值并没有被定义。 在 SQL 语句中使用 NULL 会有很多的麻烦。因此建议开发人员在建表时,把需要索引的列 设成 NOT NULL。如果被索引的列在某些行中存在 NULL 值,就不会使用这个索引(除非 索引是一个位图索引,关于位图索引在稍后在详细讨论)。 1.2.1.6.3 使用函数 如果不使用基于函数的索引,那么在 SQL 语句的 WHERE 子句中对存在索引的列使用 函数时,会使优化器忽略掉这些索引。 下面的查询不会使用索引(只要它不是基于函数的 索引) select empno,ename,deptno from emp where trunc(hiredate)='01-MAY-81'; 把上面的语句改成下面的语句,这样就可以通过索引进行查找。 select empno,ename,deptno from emp where hiredate<(to_date('01-MAY-81')+0.9999); 1.2.1.6.4 比较不匹配的数据类型 也是比较难于发现的性能问题之一。 注意下面查询的例子,account_number 是一个 VARCHAR2 类型,在 account_number 字段上有索引。 下面的语句将执行全表扫描: select bank_name,address,city,state,zip from banks where account_number = 990354; Oracle 可以自动把 where 子句变成 to_number(account_number)=990354,这样就限 制了索引的使用,改成下面的查询就可以使用索引: select bank_name,address,city,state,zip from banks where account_number ='990354'; 特别注意:不匹配的数据类型之间比较会让 Oracle 自动限制索引的使用,即便对这个查 询执行 Explain Plan 也不能让您明白为什么做了一次―全表扫描‖。 1.2.1.7 查询索引 查询 DBA_INDEXES 视图可得到表中所有索引的列表,注意只能通过 USER_INDEXES 的方法来检索模式(schema)的索引。访问 USER_IND_COLUMNS 视图 可得到一个给定表中被索引的特定列。 1.2.1.8 组合索引 当某个索引包含有多个已索引的列时,称这个索引为组合(concatented)索引。在 Oracle9i 引入跳跃式扫描的索引访问方法之前,查询只能在有限条件下使用该索引。比如: 表 emp 有一个组合索引键,该索引包含了 empno、 ename 和 deptno。在 Oracle9i 之前 除非在 where 之句中对第一列(empno)指定一个值,否则就不能使用这个索引键进行一 次范围扫描。 特别注意:在 Oracle9i 之前,只有在使用到索引的前导索引时才可以使用组合索引! Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.2.1.9 ORACLE ROWID 通过每个行的 ROWID,索引 Oracle 提供了访问单行数据的能力。ROWID 其实就是直 接指向单独行的线路图。如果想检查重复值或是其他对 ROWID 本身的引用,可以在任何表 中使用和指定 rowid 列。 1.2.1.10 选择性 使用 USER_INDEXES 视图,该视图中显示了一个 distinct_keys 列。比较一下唯一键的 数量和表中的行数,就可以判断索引的选择性。选择性越高,索引返回的数据就越少。 1.2.1.11 群集因子(Clustering Factor) Clustering Factor 位于 USER_INDEXES 视图中。该列反映了数据相对于已建索引的列 是否显得有序。如果 Clustering Factor 列的值接近于索引中的树叶块(leaf block)的数目,表 中的数据就越有序。如果它的值接近于表中的行数,则表中的数据就不是很有序。 1.2.1.12 二元高度(Binary height) 索引的二元高度对把 ROWID 返回给用户进程时所要求的 I/O 量起到关键作用。在对一个 索引进行分析后,可以通过查询 DBA_INDEXES 的 Blevel 列查看它的二元高度。二元高度 主要随着表的大小以及被索引的列中值的范围的狭窄程度而变化。索引上如果有大量被删除 的行,它的二元高度也会增加。更新索引列也类似于删除操作,因为它增加了已删除键的数 目。重建索引可能会降低二元高度。 1.2.1.13 快速全局扫描 从 Oracle7.3 后就可以使用快速全局扫描(Fast Full Scan)这个选项。这个选项允许 Oracle 执行一个全局索引扫描操作。快速全局扫描读取 B-Tree 索引上所有树叶块。初始化文件中 的 DB_FILE_MULTIBLOCK_READ_COUNT 参数可以控制同时被读取的块的数目。 1.2.1.14 跳跃式扫描 从 Oracle9i 开始,索引跳跃式扫描特性可以允许优化器使用组合索引,即便索引的前导 列没有出现在 WHERE 子句中。索引跳跃式扫描比全索引扫描要快的多。 下面的比较他们的区别: SQL> set timing on SQL> create index TT_index on TT(teamid,areacode); 索引已创建。 已用时间: 00: 02: 03.93 SQL> select count(areacode) from tt; COUNT(AREACODE) --------------- 7230369 已用时间: 00: 00: 08.31 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL> select /*+ index(tt TT_index )*/ count(areacode) from tt; COUNT(AREACODE) --------------- 7230369 已用时间: 00: 00: 07.37 1.2.2 索引分类 Oracle 提供了大量索引选项。知道在给定条件下使用哪个选项对于一个应用 程序的性能来说非常重要。一个错误的选择可能会引发死锁,并导致数据库性能 急剧下降或进程终止。而如果做出正确的选择,则可以合理使用资源,使那些已 经运行了几个小时甚至几天的进程在几分钟得以完成,这样会使您立刻成为一位 英雄。下面就将简单的讨论每个索引选项。 在这里讨论如下的索引类型: B 树索引(默认类型) 位图索引 HASH 索引 索引组织表索引 反转键(reverse key)索引 基于函数的索引 分区索引(本地和全局索引) 位图连接索引 1.2.2.1 B 树索引 (默认类型) B 树索引在 Oracle 中是一个通用索引。在创建索引时它就是默认的索引类型。B 树索 引可以是一个列的(简单)索引,也可以是组合/复合(多个列)的索引。B 树索引最多可以包括 32 列。 在下图的例子中,B 树索引位于雇员表的 last_name 列上。这个索引的二元高度为 3; 接下来,Oracle 会穿过两个树枝块(branch block),到达包含有 ROWID 的树叶块。在每个 树枝块中,树枝行包含链中下一个块的 ID 号。 树叶块包含了索引值、ROWID,以及指向前一个和后一个树叶块的指针。Oracle 可以 从两个方向遍历这个二叉树。B 树索引保存了在索引列上有值的每个数据行的 ROWID 值。 Oracle 不会对索引列上包含 NULL 值的行进行索引。如果索引是多个列的组合索引,而其 中列上包含 NULL 值,这一行就会处于包含 NULL 值的索引列中,且将被处理为空(视为 NULL)。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 技巧:索引列的值都存储在索引中。因此,可以建立一个组合(复合)索引,这些索引可以直 接满足查询,而不用访问表。这就不用从表中检索数据,从而减少了 I/O 量。 B-tree 特点: 适合与大量的增、删、改(OLTP) 不能用包含 OR 操作符的查询; 适合高基数的列(唯一值多) 典型的树状结构; 每个结点都是数据块; 大多都是物理上一层、两层或三层不定,逻辑上三层; 叶子块数据是排序的,从左向右递增; 在分支块和根块中放的是索引的范围; 1.2.2.2 位图索引 位图索引非常适合于决策支持系统(Decision Support System,DSS)和数据仓 库,它们不应该用于通过事务处理应用程序访问的表。它们可以使用较少到中等 基数(不同值的数量)的列访问非常大的表。尽管位图索引最多可达 30 个列,但 通常它们都只用于少量的列。 例如,您的表可能包含一个称为 Sex 的列,它有两个可能值:男和女。这个 基数只为 2,如果用户频繁地根据 Sex 列的值查询该表,这就是位图索引的基列。 当一个表内包含了多个位图索引时,您可以体会到位图索引的真正威力。如果有 多个可用的位图索引,Oracle 就可以合并从每个位图索引得到的结果集,快速删 除不必要的数据。 Bitmapt 特点: 适合与决策支持系统; 做 UPDATE 代价非常高; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 非常适合 OR 操作符的查询; 基数比较少的时候才能建位图索引; 技巧:对于有较低基数的列需要使用位图索引。性别列就是这样一个例子,它有 两个可能值:男或女(基数仅为 2)。位图对于低基数(少量的不同值)列来说非常 快,这是因为索引的尺寸相对于 B 树索引来说小了很多。因为这些索引是低基 数的 B 树索引,所以非常小,因此您可以经常检索表中超过半数的行,并且仍 使用位图索引。 当大多数条目不会向位图添加新的值时,位图索引在批处理(单用户)操作中 加载表(插入操作)方面通常要比 B 树做得好。当多个会话同时向表中插入行时不 应该使用位图索引,在大多数事务处理应用程序中都会发生这种情况。 示例 下面来看一个示例表 PARTICIPANT,该表包含了来自个人的调查数据。列 Age_Code、Income_Level、Education_Level 和 Marital_Status 都包括了各自 的位图索引。下图显示了每个直方图中的数据平衡情况,以及对访问每个位图索 引的查询的执行路径。图中的执行路径显示了有多少个位图索引被合并,可以看 出性能得到了显著的提高。 如上图图所示,优化器依次使用 4 个单独的位图索引,这些索引的列在 WHERE 子句中被引用。每个位图记录指针(例如 0 或 1),用于指示表中的哪些 行包含位图中的已知值。有了这些信息后,Oracle 就执行 BITMAP AND 操作以 查找将从所有 4 个位图中返回哪些行。该值然后被转换为 ROWID 值,并且查询 继续完成剩余的处理工作。注意,所有 4 个列都有非常低的基数,使用索引可以 非常快速地返回匹配的行。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 技巧:在一个查询中合并多个位图索引后,可以使性能显著提高。位图索引 使用固定长度的数据类型要比可变长度的数据类型好。较大尺寸的块也会提高对 位图索引的存储和读取性能。 下面的查询可显示索引类型。 SQL> select index_name, index_type from user_indexes; INDEX_NAME INDEX_TYPE ------------------------------ ---------------------- TT_INDEX NORMAL IX_CUSTADDR_TP NORMAL B 树索引作为 NORMAL 列出;而位图索引的类型值为 BITMAP。 技巧:如果要查询位图索引列表,可以在 USER _INDEXES 视图中查询 index_type 列。 建议不要在一些联机事务处理(OLTP)应用程序中使用位图索引。B 树索引的 索引值中包含 ROWID,这样 Oracle 就可以在行级别上锁定索引。位图索引存 储为压缩的索引值,其中包含了一定范围的 ROWID,因此 Oracle 必须针对一 个给定值锁定所有范围内的 ROWID。这种锁定类型可能在某些 DML 语句中造 成死锁。SELECT 语句不会受到这种锁定问题的影响。 位图索引的使用限制: 基于规则的优化器不会考虑位图索引。 当执行 ALTER TABLE 语句并修改包含有位图索引的列时,会使位图索引失 效。 位图索引不包含任何列数据,并且不能用于任何类型的完整性检查。 位图索引不能被声明为唯一索引。 位图索引的最大长度为 30。 技巧:不要在繁重的 OLTP 环境中使用位图索引 1.2.2.3 HASH 索引 使用 HASH 索引必须要使用 HASH 集群。建立一个集群或 HASH 集群的同 时,也就定义了一个集群键。这个键告诉 Oracle 如何在集群上存储表。在存储 数据时,所有与这个集群键相关的行都被存储在一个数据库块上。 如果数据都存储在同一个数据库块上,并且将 HASH 索引作为 WHERE 子 句中的确切匹配,Oracle 就可以通过执行一个 HASH 函数和 I/O 来访问数据—— 而通过使用一个二元高度为 4 的 B 树索引来访问数据,则需要在检索数据时使 用 4 个 I/O。 如下图所示,其中的查询是一个等价查询,用于匹配 HASH 列和确切的值。 Oracle 可以快速使用该值,基于 HASH 函数确定行的物理存储位置。 HASH 索引可能是访问数据库中数据的最快方法,但它也有自身的缺点。集Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 群键上不同值的数目必须在创建 HASH 集群之前就要知道。需要在创建 HASH 集群的时候指定这个值。低估了集群键的不同值的数字可能会造成集群的冲突 (两个集群的键值拥有相同的 HASH 值)。这种冲突是非常消耗资源的。冲突会造 成用来存储额外行的缓冲溢出,然后造成额外的 I/O。如果不同 HASH 值的数目 已经被低估,您就必须在重建这个集群之后改变这个值。 ALTER CLUSTER 命令不能改变 HASH 键的数目。HASH 集群还可能浪费 空间。如果无法确定需要多少空间来维护某个集群键上的所有行,就可能造成空 间的浪费。如果不能为集群的未来增长分配好附加的空间,HASH 集群可能就不 是最好的选择。如果应用程序经常在集群表上进行全表扫描,HASH 集群可能也 不是最好的选择。由于需要为未来的增长分配好集群的剩余空间量,全表扫描可 能非常消耗资源。 在实现 HASH 集群之前一定要小心。您需要全面地观察应用程序,保证在实 现这个选项之前已经了解关于表和数据的大量信息。通常,HASH 对于一些包含 有序值的静态数据非常有效。 技巧:HASH 索引在有限制条件(需要指定一个确定的值而不是一个值范围)的情 况下非常有用。 1.2.2.4 索引组织表 索引组织表会把表的存储结构改成 B 树结构,以表的主键进行排序。这种特 殊的表和其他类型的表一样,可以在表上执行所有的 DML 和 DDL 语句。由于 表的特殊结构,ROWID 并没有被关联到表的行上。 对于一些涉及精确匹配和范围搜索的语句,索引组织表提供了一种基于键的 快速数据访问机制。基于主键值的 UPDATE 和 DELETE 语句的性能也同样得以 提高,这是因为行在物理上有序。由于键列的值在表和索引中都没有重复,存储Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 所需要的空间也随之减少。 如果不会频繁地根据主键列查询数据,则需要在索引组织表中的其他列上创 建二级索引。不会频繁根据主键查询表的应用程序不会了解到使用索引组织表的 全部优点。对于总是通过对主键的精确匹配或范围扫描进行访问的表,就需要考 虑使用索引组织表。 技巧:可以在索引组织表上建立二级索引。 1.2.2.5 反转键索引 当载入一些有序数据时,索引肯定会碰到与 I/O 相关的一些瓶颈。在数据载 入期间,某部分索引和磁盘肯定会比其他部分使用频繁得多。为了解决这个问题, 可以把索引表空间存放在能够把文件物理分割在多个磁盘上的磁盘体系结构上。 为了解决这个问题,Oracle 还提供了一种反转键索引的方法。如果数据以反 转键索引存储,这些数据的值就会与原先存储的数值相反。这样,数据 1234、 1235 和 1236 就被存储成 4321、5321 和 6321。结果就是索引会为每次新插入 的行更新不同的索引块。 技巧:如果您的磁盘容量有限,同时还要执行大量的有序载入,就可以使用 反转键索引。 不可以将反转键索引与位图索引或索引组织表结合使用。因为不能对位图索 引和索引组织表进行反转键处理。 1.2.2.6 基于函数的索引 可以在表中创建基于函数的索引。如果没有基于函数的索引,任何在列上执 行了函数的查询都不能使用这个列的索引。例如,下面的查询就不能使用 JOB 列上的索引,除非它是基于函数的索引: select * from emp where UPPER(job) = 'MGR'; 下面的查询使用 JOB 列上的索引,但是它将不会返回 JOB 列具有 Mgr 或 mgr 值的行: select * from emp where job = 'MGR'; 可以创建这样的索引,允许索引访问支持基于函数的列或数据。可以对列表 达式 UPPER(job)创建索引,而不是直接在 JOB 列上建立索引,如: create index EMP$UPPER_JOB on emp(UPPER(job)); 尽管基于函数的索引非常有用,但在建立它们之前必须先考虑下面一些问题: 能限制在这个列上使用的函数吗?如果能,能限制所有在这个列上执行的所 有函数吗 是否有足够应付额外索引的存储空间? 在每列上增加的索引数量会对针对该表执行的 DML 语句的性能带来何种影 响? Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 基于函数的索引非常有用,但在实现时必须小心。在表上创建的索引越多, INSERT、UPDATE 和 DELETE 语句的执行就会花费越多的时间。 注意:对于优化器所使用的基于函数的索引来说,必须把初始参数 QUERY _REWRITE _ ENABLED 设定为 TRUE。 示例: select count(*) from sample where ratio(balance,limit) >.5; Elapsed time: 20.1 minutes create index ratio_idx1 on sample (ratio(balance, limit)); select count(*) from sample where ratio(balance,limit) >.5; Elapsed time: 7 seconds!!! 1.2.2.7 分区索引 分区索引就是简单地把一个索引分成多个片断。通过把一个索引分成多个片 断,可以访问更小的片断(也更快),并且可以把这些片断分别存放在不同的磁盘 驱动器上(避免 I/O 问题)。B 树和位图索引都可以被分区,而 HASH 索引不可以 被分区。可以有好几种分区方法:表被分区而索引未被分区;表未被分区而索引 被分区;表和索引都被分区。不管采用哪种方法,都必须使用基于成本的优化器。 分区能够提供更多可以提高性能和可维护性的可能性 有两种类型的分区索引:本地分区索引和全局分区索引。每个类型都有两个 子类型,有前缀索引和无前缀索引。表各列上的索引可以有各种类型索引的组合。 如果使用了位图索引,就必须是本地索引。把索引分区最主要的原因是可以减少 所需读取的索引的大小,另外把分区放在不同的表空间中可以提高分区的可用性 和可靠性。 在使用分区后的表和索引时,Oracle 还支持并行查询和并行 DML。这样就 可以同时执行多个进程,从而加快处理这条语句。 1.2.2.7.1.本地分区索引(通常使用的索引) 可以使用与表相同的分区键和范围界限来对本地索引分区。每个本地索引的 分区只包含了它所关联的表分区的键和 ROWID。本地索引可以是 B 树或位图索 引。如果是 B 树索引,它可以是唯一或不唯一的索引。 这种类型的索引支持分区独立性,这就意味着对于单独的分区,可以进行增 加、截取、删除、分割、脱机等处理,而不用同时删除或重建索引。Oracle 自 动维护这些本地索引。本地索引分区还可以被单独重建,而其他分区不会受到影 响。 (1) 有前缀的索引 有前缀的索引包含了来自分区键的键,并把它们作为索引的前导。例如,让 我们再次回顾 participant 表。在创建该表后,使用 survey_id 和 survey_date 这 两个列进行范围分区,然后在 survey_id 列上建立一个有前缀的本地索引,如下Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 图所示。这个索引的所有分区都被等价划分,就是说索引的分区都使用表的相同 范围界限来创建。 技巧:本地的有前缀索引可以让 Oracle 快速剔除一些不必要的分区。也就是说 没有包含 WHERE 条件子句中任何值的分区将不会被访问,这样也提高了语句 的性能。 (2) 无前缀的索引 无前缀的索引并没有把分区键的前导列作为索引的前导列。若使用有同样分 区键(survey_id 和 survey_date)的相同分区表,建立在 survey_date 列上的索引 就是一个本地的无前缀索引,如下图所示。可以在表的任一列上创建本地无前缀 索引,但索引的每个分区只包含表的相应分区的键值。 如果要把无前缀的索引设为唯一索引,这个索引就必须包含分区键的子集。 在这个例子中,我们必须把包含 survey 和(或)survey_id 的列进行组合(只要 survey_id 不是索引的第一列,它就是一个有前缀的索引)。 技巧:对于一个唯一的无前缀索引,它必须包含分区键的子集。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.2.2.7.2.全局分区索引 全局分区索引在一个索引分区中包含来自多个表分区的键。一个全局分区索 引的分区键是分区表中不同的或指定一个范围的值。在创建全局分区索引时,必 须定义分区键的范围和值。 全局索引只能是 B 树索引。Oracle 在默认情况下不会维护全局分区索引。 如果一个分区被截取、增加、分割、删除等,就必须重建全局分区索引,除非在 修改表时指定 ALTER TABLE 命令的 UPDATE GLOBAL INDEXES 子句。 (2)有前缀的索引 通常,全局有前缀索引在底层表中没有经过对等分区。没有什么因素能限制 索引的对等分区,但 Oracle 在生成查询计划或执行分区维护操作时,并不会充 分利用对等分区。如果索引被对等分区,就必须把它创建为一个本地索引,这样 Oracle 可以维护这个索引,并使用它来删除不必要的分区,如下图所示。在该 图的 3 个索引分区中,每个分区都包含指向多个表分区中行的索引条目。 分区的、全局有前缀索引 技巧:如果一个全局索引将被对等分区,就必须把它创建为一个本地索引, 这样 Oracle 可以维护这个索引,并使用它来删除不必要的分区。 (2)无前缀的索引 Oracle 不支持无前缀的全局索引。 1.2.2.8 位图连接索引 位图连接索引是基于两个表的连接的位图索引,在数据仓库环境中使用这种Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 索引改进连接维度表和事实表的查询的性能。创建位图连接索引时,标准方法是 连接索引中常用的维度表和事实表。当用户在一次查询中结合查询事实表和维度 表时,就不需要执行连接,因为在位图连接索引中已经有可用的连接结果。通过 压缩位图连接索引中的 ROWID 进一步改进性能,并且减少访问数据所需的 I/O 数量。 创建位图连接索引时,指定涉及的两个表。相应的语法应该遵循如下模式: create bitmap index FACT_DIM_COL_IDX on FACT(DIM.Descr_Col) from FACT, DIM where FACT.JoinCol = DIM.JoinCol; 位图连接的语法比较特别,其中包含 FROM 子句和 WHERE 子句,并且引 用两个单独的表。索引列通常是维度表中的描述列——就是说,如果维度是 CUSTOMER,并且它的主键是 CUSTOMER_ID,则通常索引 Customer_Name 这样的列。如果事实表名为 SALES,可以使用如下的命令创建索引: create bitmap index SALES_CUST_NAME_IDX on SALES(CUSTOMER.Customer_Name) from SALES, CUSTOMER where SALES.Customer_ID=CUSTOMER.Customer_ID; 如果用户接下来使用指定 Customer_Name 列值的 WHERE 子句查询 SALES 和 CUSTOMER 表,优化器就可以使用位图连接索引快速返回匹配连接 条件和 Customer_Name 条件的行。 位图连接索引的使用一般会受到限制: 1)只可以索引维度表中的列。 2)用于连接的列必须是维度表中的主键或唯一约束;如果是复合主键,则 必须使用连接中的每一列。 3)不可以对索引组织表创建位图连接索引,并且适用于常规位图索引的限 制也适用于位图连接索引。 1.3 分区表总结 1.3.1. 分区表理论知识 Oracle 提供了分区技术以支持 VLDB(Very Large DataBase)。分区表通过对分 区列的判断,把分区列不同的记录,放到不同的分区中。分区完全对应用透明。 Oracle 的分区表可以包括多个分区,每个分区都是一个独立的段 (SEGMENT),可以存放到不同的表空间中。查询时可以通过查询表来访问各 个分区中的数据,也可以通过在查询时直接指定分区的方法来进行查询。 When to Partition a Table 什么时候需要分区表,官网的 2 个建议如下: (1)Tables greater than 2GB should always be considered for partitioning. (2)Tables containing historical data, in which new data is added into the newest partition. A typical example is a historical table where only the current month's data is Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 updatable and the other 11 months are read only. 在 oracle 10g 中最多支持:1024k-1 个分区: Tables can be partitioned into up to 1024K-1 separate partitions 联机文档上有关分区表和索引的说明: Partitioned Tables and Indexes http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/partconc.htm #sthref2604 分区提供以下优点: (1)由于将数据分散到各个分区中,减少了数据损坏的可能性; (2)可以对单独的分区进行备份和恢复; (3)可以将分区映射到不同的物理磁盘上,来分散 IO; (4)提高可管理性、可用性和性能。 Oracle 10g 提供了以下几种分区类型: (1)范围分区(range); (2)哈希分区(hash); (3)列表分区(list); (4)范围-哈希复合分区(range-hash); (5)范围-列表复合分区(range-list)。 Range 分区: Range 分区是应用范围比较广的表分区方式,它是以列的值的范围来做为分 区的划分条件,将记录存放到列值所在的 range 分区中。 如按照时间划分,2010 年 1 月的数据放到 a 分区,2 月的数据放到 b 分区, 在创建的时候,需要指定基于的列,以及分区的范围值。 在按时间分区时,如果某些记录暂无法预测范围,可以创建 maxvalue 分区, 所有不在指定范围内的记录都会被存储到 maxvalue 所在分区中。 如: create table pdba (id number, time date) partition by range (time) ( partition p1 values less than (to_date('2010-10-1', 'yyyy-mm-dd')), partition p2 values less than (to_date('2010-11-1', 'yyyy-mm-dd')), partition p3 values less than (to_date('2010-12-1', 'yyyy-mm-dd')), partition p4 values less than (maxvalue) ) Hash 分区: 对于那些无法有效划分范围的表,可以使用 hash 分区,这样对于提高性能 还是会有一定的帮助。hash 分区会将表中的数据平均分配到你指定的几个分区 中,列所在分区是依据分区列的 hash 值自动分配,因此你并不能控制也不知道Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 哪条记录会被放到哪个分区中,hash 分区也可以支持多个依赖列。 如: create table test ( transaction_id number primary key, item_id number(8) not null ) partition by hash(transaction_id) ( partition part_01 tablespace tablespace01, partition part_02 tablespace tablespace02, partition part_03 tablespace tablespace03 ); 在这里,我们指定了每个分区的表空间。 List 分区: List 分区也需要指定列的值,其分区值必须明确指定,该分区列只能有一个, 不能像 range 或者 hash 分区那样同时指定多个列做为分区依赖列,但它的单个分 区对应值可以是多个。 在分区时必须确定分区列可能存在的值,一旦插入的列值不在分区范围内, 则插入/更新就会失败,因此通常建议使用 list 分区时,要创建一个 default 分区 存储那些不在指定范围内的记录,类似 range 分区中的 maxvalue 分区。 在根据某字段,如城市代码分区时,可以指定 default,把非分区规则的数据,全 部放到这个 default 分区。 如: create table custaddr ( id varchar2(15 byte) not null, areacode varchar2(4 byte) ) partition by list (areacode) ( partition t_list025 values ('025'), partition t_list372 values ('372') , partition t_list510 values ('510'), partition p_other values (default) ) 组合分区: 如果某表按照某列分区之后,仍然较大,或者是一些其它的需求,还可以通 过分区内再建子分区的方式将分区再分区,即组合分区的方式。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 组合分区呢在 10g 中有两种:range-hash,range-list。注意顺序,根分区只 能是 range 分区,子分区可以是 hash 分区或 list 分区。 如: create table test ( transaction_id number primary key, transaction_date date ) partition by range(transaction_date) subpartition by hash(transaction_id) subpartitions 3 store in (tablespace01,tablespace02,tablespace03) ( partition part_01 values less than(to_date(‘2009-01-01‘,‘yyyy-mm-dd‘)), partition part_02 values less than(to_date(‘2010-01-01‘,‘yyyy-mm-dd‘)), partition part_03 values less than(maxvalue) ); create table emp_sub_template (deptno number, empname varchar(32), grade number) partition by range(deptno) subpartition by hash(empname) subpartition template (subpartition a tablespace ts1, subpartition b tablespace ts2, subpartition c tablespace ts3, subpartition d tablespace ts4 ) (partition p1 values less than (1000), partition p2 values less than (2000), partition p3 values less than (maxvalue) ); create table quarterly_regional_sales (deptno number, item_no varchar2(20), txn_date date, txn_amount number, state varchar2(2)) tablespace ts4 partition by range (txn_date) subpartition by list (state) (partition q1_1999 values less than (to_date('1-apr-1999','dd-mon-yyyy')) (subpartition q1_1999_northwest values ('or', 'wa'), subpartition q1_1999_southwest values ('az', 'ut', 'nm'), subpartition q1_1999_northeast values ('ny', 'vm', 'nj'), subpartition q1_1999_southeast values ('fl', 'ga'), subpartition q1_1999_northcentral values ('sd', 'wi'), Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 subpartition q1_1999_southcentral values ('ok', 'tx') ), partition q2_1999 values less than ( to_date('1-jul-1999','dd-mon-yyyy')) (subpartition q2_1999_northwest values ('or', 'wa'), subpartition q2_1999_southwest values ('az', 'ut', 'nm'), subpartition q2_1999_northeast values ('ny', 'vm', 'nj'), subpartition q2_1999_southeast values ('fl', 'ga'), subpartition q2_1999_northcentral values ('sd', 'wi'), subpartition q2_1999_southcentral values ('ok', 'tx') ), partition q3_1999 values less than (to_date('1-oct-1999','dd-mon-yyyy')) (subpartition q3_1999_northwest values ('or', 'wa'), subpartition q3_1999_southwest values ('az', 'ut', 'nm'), subpartition q3_1999_northeast values ('ny', 'vm', 'nj'), subpartition q3_1999_southeast values ('fl', 'ga'), subpartition q3_1999_northcentral values ('sd', 'wi'), subpartition q3_1999_southcentral values ('ok', 'tx') ), partition q4_1999 values less than ( to_date('1-jan-2000','dd-mon-yyyy')) (subpartition q4_1999_northwest values ('or', 'wa'), subpartition q4_1999_southwest values ('az', 'ut', 'nm'), subpartition q4_1999_northeast values ('ny', 'vm', 'nj'), subpartition q4_1999_southeast values ('fl', 'ga'), subpartition q4_1999_northcentral values ('sd', 'wi'), subpartition q4_1999_southcentral values ('ok', 'tx') ) ); 在Oracle 11g中,组合分区功能这块有所增强,又增加了range-range,list-range, list-list,list-hash,并且 11g 里面还支持 Interval 分区和虚拟列分区。 1.3.2 普通表转分区表方法 将普通表转换成分区表有 4 种方法: 1. Export/import method 2. Insert with a subquery method 3. Partition exchange method 4. DBMS_REDEFINITION 具体参考: How to Partition a Non-partitioned Table [ID 1070693.6] http://blog.csdn.net/tianlesoftware/archive/2011/03/02/6218704.aspx Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 逻辑导出导入这里就不做说明,我们看看其他三种方法。 1.3.2.1 插入: Insert with a subquery method 这种方法就是使用 insert 来实现。 当然在创建分区表的时候可以一起插入 数据,也可以创建好后在 insert 进去。 这种方法采用 DDL 语句,不产生 UNDO, 只产生少量 REDO,建表完成后数据已经在分布到各个分区中。 SQL> select count(*) from dba; COUNT(*) ---------- 2713235 SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'; 会话已更改。 SQL> select time_fee from dba where rownum<5; TIME_FEE ------------------- 2011-02-17 19:29:09 2011-02-17 19:29:15 2011-02-17 19:29:18 2011-02-17 19:29:20 SQL> 1.3.2.1.1 Oracle 11g 的 Interval 在 11g 里的 Interval 创建,这种方法对没有写全的分区会自动创建。 比如我 这里只写了 1 月日期,如果插入的数据有其他月份的,会自动生成对应的分区。 create table intervaldave partition by range (time_fee) interval ( numtoyminterval (1, 'month') ) (partition part1 values less than (to_date ('01/12/2010', 'mm/dd/yyyy'))) as select id, time_fee from dave; SQL> select table_name,partition_name from user_tab_partitions where table_name='INTERVALDAVE'; TABLE_NAME PARTITION_NAME ------------------------------ ------------------------------ INTERVALDAVE PART1 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 INTERVALDAVE SYS_P24 INTERVALDAVE SYS_P25 INTERVALDAVE SYS_P26 INTERVALDAVE SYS_P33 INTERVALDAVE SYS_P27 INTERVALDAVE SYS_P28 1.3.2.1.2 Oracle 10g 版本 在 10g 里面,我需要写全所有的分区。 sql> create table pdba (id, time) partition by range (time) 2 (partition p1 values less than (to_date('2010-10-1', 'yyyy-mm-dd')), 3 partition p2 values less than (to_date('2010-11-1', 'yyyy-mm-dd')), 4 partition p3 values less than (to_date('2010-12-1', 'yyyy-mm-dd')), 5 partition p4 values less than (maxvalue)) 6 as select id, time_fee from dba; 表已创建。 SQL> select table_name,partition_name from user_tab_partitions where table_name='PDBA'; TABLE_NAME PARTITION_NAME ------------------------------ ------------------------------ PDBA P1 PDBA P2 PDBA P3 PDBA P4 sql> select count(*) from pdba partition (p1); count(*) ---------- 1718285 sql> select count(*) from pdba partition (p2); count(*) ---------- 183667 sql> select count(*) from pdba partition (p3); count(*) ---------- 188701 sql> select count(*) from pdba partition (p4); count(*) ---------- 622582 sql> Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 现在分区表已经建好了,但是表名不一样,需要用 rename 对表重命名一下: SQL> rename dba to dba_old; 表已重命名。 SQL> rename pdba to dba; 表已重命名。 SQL> select table_name,partition_name from user_tab_partitions where table_name='DBA'; TABLE_NAME PARTITION_NAME ------------------------------ ------------------------------ DBA P1 DBA P2 DBA P3 DBA P4 1.3.2.2 交换分区:Partition exchange method 这种方法只是对数据字典中分区和表的定义进行了修改,没有数据的修改或 复制,效率最高。适用于包含大数据量的表转到分区表中的一个分区的操作。尽 量在闲时进行操作。 交换分区的操作步骤如下: 1. 创建分区表,假设有 2 个分区,P1,P2. 2. 创建表 A 存放 P1 规则的数据。 3. 创建表 B 存放 P2 规则的数据。 4. 用表 A 和 P1 分区交换。 把表 A 的数据放到到 P1 分区 5. 用表 B 和 p2 分区交换。 把表 B 的数据存放到 P2 分区。 创建分区表: sql> create table p_dba 2 (id number,time date) 3 partition by range(time) 4 ( 5 partition p1 values less than (to_date('2010-09-1', 'yyyy-mm-dd')), 6 partition p2 values less than (to_date('2010-11-1', 'yyyy-mm-dd')) 7 ); 表已创建。 注意:我这里只创建了 2 个分区,没有创建存放其他数据的分区。 创建 2 个分别对应分区的基表: SQL> CREATE TABLE dba_p1 as SELECT id,time_fee FROM dba_old WHERE time_fee CREATE TABLE dba_p2 as SELECT id,time_fee FROM dba_old WHERE time_feeTO_DATE('2010-09-1', 'YYYY-MM-DD'); 表已创建。 SQL> select count(*) from dba_p1; COUNT(*) ---------- 1536020 SQL> select count(*) from dba_p2; COUNT(*) ---------- 365932 讲 2 个基表与 2 个分区进行交换: SQL> alter table p_dba exchange partition p1 with table dba_p1; 表已更改。 SQL> alter table p_dba exchange partition p2 with table dba_p2; 表已更改。 查询 2 个分区: SQL> select count(*) from p_dba partition(p1); COUNT(*) ---------- 1536020 SQL> select count(*) from p_dba partition(p2); COUNT(*) ---------- 365932 注意:数据和之前的基表一致。 查询原来的 2 个基表: SQL> select count(*) from dba_p2; COUNT(*) ---------- 0 SQL> select count(*) from dba_p1; COUNT(*) ---------- 0 注意: 2 个基表的数据变成成 0。 在这里我们看一个问题,一般情况下,我们在创建分区表的时候,都会有一Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 个其他分区,用来存放不匹配分区规则的数据。 在这个例子中,我只创建了 2 个分区,没有创建 maxvalue 分区。 现在我来插入一条不满足规则的数据,看结 果: SQL> insert into p_dba values(999999,to_date('2012-12-29','yyyy-mm-dd')); insert into p_dba values(999999,to_date('2012-12-29','yyyy-mm-dd')) * 第 1 行出现错误: ORA-14400: 插入的分区关键字未映射到任何分区 SQL> insert into p_dba values(999999,to_date('2009-12-29','yyyy-mm-dd')); 已创建 1 行。 SQL> select * from p_dba where id=999999; ID TIME ---------- -------------- 999999 29-12 月-09 SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'; 会话已更改。 SQL> select * from p_dba where id=999999; ID TIME ---------- ------------------- 999999 2009-12-29 00:00:00 通过这个测试可以清楚,如果插入的数据不满足分区规则,会报 ORA-14400 错误。 1.3.2.3 使用在线重定义:DBMS_REDEFINITION 在线重定义能保证数据的一致性,在大部分时间内,表都可以正常进行 DML 操作。只在切换的瞬间锁表,具有很高的可用性。这种方法具有很强的灵活性, 对各种不同的需要都能满足。而且,可以在切换前进行相应的授权并建立各种约 束,可以做到切换完成后不再需要任何额外的管理操作。 关于 DBMS_REDEFINITION 的介绍,参考官方连接: http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_re defi.htm#CBBFDJBC 关于用在线重定义创建分区表,参考: How To Partition Existing Table Using DBMS_Redefinition [ID 472449.1] http://blog.csdn.net/tianlesoftware/archive/2011/03/02/6218693.aspx 这个功能只在 9.2.0.4 以后的版本才有,在线重定义表具有以下功能: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 (1)修改表的存储参数; (2)将表转移到其他表空间; (3)增加并行查询选项; (4)增加或删除分区; (5)重建表以减少碎片; (6)将堆表改为索引组织表或相反的操作; (7)增加或删除一个列。 使用在线重定义的一些限制条件: (1) There must be enough space to hold two copies of the table. (2) Primary key columns cannot be modified. (3) Tables must have primary keys. (4) Redefinition must be done within the same schema. (5) New columns added cannot be made NOT NULL until after the redefinition operation. (6) Tables cannot contain LONGs, BFILEs or User Defined Types. (7) Clustered tables cannot be redefined. (8) Tables in the SYS or SYSTEM schema cannot be redefined. (9) Tables with materialized view logs or materialized views defined on them cannot be redefined. (10) Horizontal sub setting of data cannot be performed during the redefinition. 在 Oracle 10.2.0.4 和 11.1.0.7 版本下,在线重定义可能会遇到如下 bug: Bug 7007594 - ORA-600 [12261] http://blog.csdn.net/tianlesoftware/archive/2011/03/02/6218681.aspx 在线重定义的大致操作流程如下: (1)创建基础表 A,如果存在,就不需要操作。 (2)创建临时的分区表 B。 (3)开始重定义,将基表 A 的数据导入临时分区表 B。 (4)结束重定义,此时在 DB 的 Name Directory 里,已经将 2 个表进行了 交换。即此时基表 A 成了分区表,我们创建的临时分区表 B 成了普通表。 此 时我们可以删除我们创建的临时表 B。它已经是普通表。 下面看一个示例: 1. 创建基本表和索引 sql> conn icd/icd; 已连接。 sql> create table unpar_table ( 2 id number(10) primary key, 3 create_date date 4 ); Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 表已创建。 sql> insert into unpar_table select rownum, created from dba_objects; 已创建 72288 行。 sql> create index create_date_ind on unpar_table(create_date); 索引已创建。 sql> commit; 提交完成。 2. 收集表的统计信息 sql> exec dbms_stats.gather_table_stats('icd', 'unpar_table', cascade => true); pl/sql 过程已成功完成。 3. 创建临时分区表 sql> create table par_table (id number primary key, time date) partition by range (time) 2 (partition p1 values less than (to_date('2004-7-1', 'yyyy-mm-dd')), 3 partition p2 values less than (to_date('2005-1-1', 'yyyy-mm-dd')), 4 partition p3 values less than (to_date('2005-7-1', 'yyyy-mm-dd')), 5 partition p4 values less than (maxvalue)); 表已创建。 4. 进行重定义操作 4.1 检查重定义的合理性 sql> exec dbms_redefinition.can_redef_table('icd', 'unpar_table'); pl/sql 过程已成功完成。 4.2 如果 4.1 没有问题,开始重定义,这个过程可能要等一会。 这里要注意:如果分区表和原表列名相同,可以用如下方式进行: SQL> BEGIN DBMS_REDEFINITION.start_redef_table( uname => 'ICD', orig_table => 'unpar_table', int_table => 'par_table'); END; / 如果分区表的列名和原表不一致,那么在开始重定义的时候,需要重新指定 映射关系: SQL> EXEC DBMS_REDEFINITION.START_REDEF_TABLE( 'ICD', 'unpar_table', 'par_table', 'ID ID, create_date TIME', -- 在这里指定新的映射关系 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 DBMS_REDEFINITION.CONS_USE_PK); 这一步操作结束后,数据就已经同步到这个临时的分区表里来了。 4.3 同步新表,这是可选的操作 SQL> BEGIN 2 dbms_redefinition.sync_interim_table( 3 uname => 'ICD', 4 orig_table => 'unpar_table', 5 int_table => 'par_table'); 6 END; 7 / PL/SQL 过程已成功完成。 4.4 创建索引,在线重定义只重定义数据,索引还需要单独建立。 sql> create index create_date_ind2 on par_table(time); 索引已创建。 4.5 收集新表的统计信息 sql> exec dbms_stats.gather_table_stats('icd', 'par_table', cascade => true); pl/sql 过程已成功完成。 4.6 结束重定义 SQL> BEGIN 2 dbms_redefinition.finish_redef_table( 3 uname => 'ICD', 4 orig_table => 'unpar_table', 5 int_table => 'par_table'); 6 END; 7 / PL/SQL 过程已成功完成。 结束重定义的意义: 基表 unpar_table 和临时分区表 par_table 进行了交换。 此时临时分区表 par_table 成了普通表,我们的基表 unpar_table 成了分区表。 我们在重定义的时候,基表 unpar_table 是可以进行 DML 操作的。 只有在 2 个表进行切换的时候会有短暂的锁表。 5. 删除临时表 SQL> DROP TABLE par_table; 表已删除。 6. 索引重命名 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL> ALTER INDEX create_date_ind2 RENAME TO create_date_ind; 索引已更改。 7. 验证 sql> select partitioned from user_tables where table_name = 'UNPAR_TABLE'; par --- yes sql> select partition_name from user_tab_partitions where table_name = 'UNPAR_TABLE'; partition_name ------------------------------ p1 p2 p3 p4 sql> select count(*) from unpar_table; count(*) ---------- 72288 sql> select count(*) from unpar_table partition (p4); count(*) ---------- 72288 sql> 1.3.2.4 使用导出导入 这种方法的步骤是: (1)将普通表 dump 出来 (2)创建分区表 (3)将 dump 文件导入数据。 分区表的迁移和这个步骤差不多。有 2 点要注意: (1)分区表导出的 dump 文件比普通表导出的大。 (2)导入分区表的时间要比普通表的时间要长。 补充一些 exp/imp,expdp/impdp 与分区表有关的知识:使用 exp -help 查看: example: imp scott/tiger ignore=y tables=(emp,dept) full=n or tables=(t1:p1,t1:p2), if t1 is partitioned table example: exp scott/tiger grants=y tables=(emp,dept,mgr) or tables=(t1:p1,t1:p2), if t1 is partitioned table Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 example: expdp scott/tiger dumpfile=scott.dmp directory=dmpdir schemas=scott or tables=(t1:p1,t1:p2), if t1 is partitioned table example: impdp scott/tiger directory=dmpdir dumpfile=scott.dmp 一些优化参考 Blog: exp/imp 与 expdp/impdp 对比 及使用中的一些优化事项 http://blog.csdn.net/tianlesoftware/archive/2010/12/23/6093973.aspx 1.3.2.4.1 迁移分区表的步骤 (1)导出分区表,可以使用 exp 或者 expdp (2)建立新的分区表 (3)导入分区表。 A)如果是 imp,加 ignore=y 参数,该参数会忽略创建表时的错误并继续加 载数据。 B)如果是 impdp,加 table_exists_action=append 参数. table_exists_action: action to take if imported object already exists. valid keywords: (skip), append, replace and truncate. 1.3.2.4.2 示例 1:使用 exp/imp 分区表: create table pdba (id, time) partition by range (time) (partition p1 values less than (to_date('2010-10-1', 'yyyy-mm-dd')), partition p2 values less than (to_date('2010-11-1', 'yyyy-mm-dd')), partition p3 values less than (to_date('2010-12-1', 'yyyy-mm-dd')), partition p4 values less than (maxvalue)) as select id, time from sys.dba; SQL> select partition_name from user_tab_partitions where table_name='PDBA'; PARTITION_NAME ------------------------------ P1 P2 P3 P4 SQL> select count(*) from pdba partition(p1); COUNT(*) ---------- 1718285 SQL> select count(*) from pdba partition(p2); COUNT(*) ---------- Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 183667 SQL> select count(*) from pdba partition(p3); COUNT(*) ---------- 188701 SQL> select count(*) from pdba partition(p4); COUNT(*) ---------- 622582 SQL> 1. 导出表或者某个分区 (1)导出整个表: C:\Users\Administrator.DavidDai>exp 'sys/sys as sysdba' tables=pdba file='d:\partition.dmp' log='d:\partition.log' Export: Release 11.2.0.1.0 - Production on 星期四 3 月 3 15:29:42 2011 Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved. 连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options 已导出 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集 即将导出指定的表通过常规路径... . . 正在导出表 PDBA . . 正在导出分区 P1 导出了 1718285 行 . . 正在导出分区 P2 导出了 183667 行 . . 正在导出分区 P3 导出了 188701 行 . . 正在导出分区 P4 导出了 622582 行 成功终止导出, 没有出现警告。 (2)导出某个分区: C:\Users\Administrator.DavidDai>exp 'sys/sys as sysdba' tables=pdba:p4 file='d:\partition_p4.dmp' log='d:\partition_p4.log' Export: Release 11.2.0.1.0 - Production on 星期四 3 月 3 15:30:09 2011 Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved. 连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options 已导出 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集 即将导出指定的表通过常规路径... . . 正在导出表 PDBA . . 正在导出分区 P4 导出了 622582 行 成功终止导出, 没有出现警告。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 说明:开始用的分区表是 11g 的 Interval 分区表,结果用 exp 导,报: EXP-00006: internal inconsistency error EXP-00000: Export terminated unsuccessfully exp 不支持 11g 的新特性。参考: Exporting System or Composite Partitioned Table Using Classic Export Gives EXP-6 AND EXP-0 [ID 762774.1] http://blog.csdn.net/tianlesoftware/archive/2011/03/03/6220799.aspx 2. 创建分区表 2.1 可以使用一下语句获取表的 DDL 语句: SELECT DBMS_METADATA.GET_DDL('TABLE',u.table_name) FROM USER_TABLES u; 更多参考: ORACLE 使用 DBMS_METADATA.GET_DDL 获取 DDL 语句 http://blog.csdn.net/tianlesoftware/archive/2009/11/25/4868007.aspx 2.2 使用 imp 语句获取: C:\Users\Administrator.DavidDai>imp 'sys/sys as sysdba' tables=pdba indexfile='D:\table.sql' file='d:\partition.dmp' ignore=y Import: Release 11.2.0.1.0 - Production on 星期四 3 月 3 15:49:47 2011 Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved. 连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options 经由常规路径由 EXPORT:V11.02.00 创建的导出文件 已经完成 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集中的导入 . . 正在跳过分区 "PDBA":"P1" . . 正在跳过分区 "PDBA":"P2" . . 正在跳过分区 "PDBA":"P3" . . 正在跳过分区 "PDBA":"P4" 成功终止导入, 没有出现警告。 这里我们在 imp 上加了个参数:indexfile='D:\table.sql',这条 imp 语句只会在对 应的文件里生成分区表的 ddl 语句。 然后编辑创建好就可以了。 最简单的方法就是使用第三方的工具,如 Toad,直接就能查到表的定义语句了。 3. 导入分区数据 我们在第一步导出里做了 2 种,一个是导出全表,另一个是导出一个分区。 我们分别导入验证。 3.1 导入一个分区 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 C:\Users\Administrator.DavidDai>imp 'sys/sys as sysdba' tables=pdba:p4 file='d:\partition_p4.dmp' ignore=y Import: Release 11.2.0.1.0 - Production on 星期四 3 月 3 15:58:27 2011 Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved. 连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options 经由常规路径由 EXPORT:V11.02.00 创建的导出文件 已经完成 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集中的导入 . 正在将 SYS 的对象导入到 SYS . 正在将 SYS 的对象导入到 SYS . . 正在导入分区 "PDBA":"P4"导入了 622582 行 成功终止导入, 没有出现警告。 SQL> select count(*) from pdba partition(p4); COUNT(*) ---------- 622582 SQL> select count(*) from pdba partition(p1); COUNT(*) ---------- 0 3.2 导入整个表 导入之前先把 P4 分区的数据 truncate 掉: SQL> alter table pdba truncate partition p4; 表被截断。 SQL> select count(*) from pdba partition(p4); COUNT(*) ---------- 0 C:\Users\Administrator.DavidDai>imp 'sys/sys as sysdba' tables=pdba file='d:\partition.dmp' ignore=y Import: Release 11.2.0.1.0 - Production on 星期四 3 月 3 16:01:08 2011 Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved. 连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options 经由常规路径由 EXPORT:V11.02.00 创建的导出文件 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 已经完成 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集中的导入 . 正在将 SYS 的对象导入到 SYS . 正在将 SYS 的对象导入到 SYS . . 正在导入分区 "PDBA":"P1"导入了 1718285 行 . . 正在导入分区 "PDBA":"P2"导入了 183667 行 . . 正在导入分区 "PDBA":"P3"导入了 188701 行 . . 正在导入分区 "PDBA":"P4"导入了 622582 行 成功终止导入, 没有出现警告。 1.3.2.4.3 示例 2:使用 expdp/impdp 1. 导出 dump 文件 create directory dump as 'd:\backup'; grant read, write on directory dump to system; (1)整个表 C:\Users\Administrator.DavidDai>Expdp system/system DIRECTORY=dump DUMPFILE=partition.dmp TABLES=PDBA logfile=exp.log; Export: Release 11.2.0.1.0 - Production on 星期四 3 月 3 16:18:15 2011 Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved. 连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options 启动 "SYSTEM"."SYS_EXPORT_TABLE_01": system/******** DIRECTORY=dump DUMPFILE=partition.dmp TABLES=PDBA logfile=exp.log; 正在使用 BLOCKS 方法进行估计... 处理对象类型 TABLE_EXPORT/TABLE/TABLE_DATA 使用 BLOCKS 方法的总估计: 61 MB 处理对象类型 TABLE_EXPORT/TABLE/TABLE 处理对象类型 TABLE_EXPORT/TABLE/PRE_TABLE_ACTION . . 导出了 "SYSTEM"."PDBA":"P1" 31.12 MB 1718285 行 . . 导出了 "SYSTEM"."PDBA":"P4" 11.28 MB 622582 行 . . 导出了 "SYSTEM"."PDBA":"P3" 3.422 MB 188701 行 . . 导出了 "SYSTEM"."PDBA":"P2" 3.331 MB 183667 行 已成功加载/卸载了主表 "SYSTEM"."SYS_EXPORT_TABLE_01" ********************************************************************* ********* Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SYSTEM.SYS_EXPORT_TABLE_01 的转储文件集为: D:\BACKUP\PARTITION.DMP 作业 "SYSTEM"."SYS_EXPORT_TABLE_01" 已于 16:18:34 成功完成 (2)一个分区 C:\Users\Administrator.DavidDai>Expdp system/system DIRECTORY=dump DUMPFILE=partition_p4.dmp TABLES=PDBA:P4 logfile=exp_p4.log; Export: Release 11.2.0.1.0 - Production on 星期四 3 月 3 16:19:23 2011 Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved. 连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options 启动 "SYSTEM"."SYS_EXPORT_TABLE_01": system/******** DIRECTORY=dump DUMPFILE=partition_p4.dmp TABLES=PDBA:P4 logfile=exp_p4.log; 正在使用 BLOCKS 方法进行估计... 处理对象类型 TABLE_EXPORT/TABLE/TABLE_DATA 使用 BLOCKS 方法的总估计: 14 MB 处理对象类型 TABLE_EXPORT/TABLE/TABLE 处理对象类型 TABLE_EXPORT/TABLE/PRE_TABLE_ACTION . . 导出了 "SYSTEM"."PDBA":"P4" 11.28 MB 622582 行 已成功加载/卸载了主表 "SYSTEM"."SYS_EXPORT_TABLE_01" ********************************************************************* ********* SYSTEM.SYS_EXPORT_TABLE_01 的转储文件集为: D:\BACKUP\PARTITION_P4.DMP 作业 "SYSTEM"."SYS_EXPORT_TABLE_01" 已于 16:19:32 成功完成 2. 创建分区表 用 dbms_metadate.get_ddl() 直接获取就可以了,方法同示例 1. 3. 导入 dump 文件 (1)导入一个分区 C:\Users\Administrator.DavidDai>impdp system/system DIRECTORY=dump DUMPFILE=partition_p4.dmp TABLES=PDBA:P4 logfile=imp_p4.log table_exists_action=append -- 注意这个参数,后面不用加分号,直接回车就执行了。 Import: Release 11.2.0.1.0 - Production on 星期四 3 月 3 16:24:15 2011 Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved. 连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 With the Partitioning, OLAP, Data Mining and Real Application Testing options 已成功加载/卸载了主表 "SYSTEM"."SYS_IMPORT_TABLE_01" 启动 "SYSTEM"."SYS_IMPORT_TABLE_01": system/******** DIRECTORY=dump DUMPFILE=partition_p4.dmp TABLES=PDBA logfile=imp_p4.log table_exists_action=append 处理对象类型 TABLE_EXPORT/TABLE/TABLE ORA-39152: 表 "SYSTEM"."PDBA" 已存在。由于附加了 table_exists_action, 数据将附加到现有表, 但是将跳过所有相关元数据。 处理对象类型 TABLE_EXPORT/TABLE/TABLE_DATA . . 导入了 "SYSTEM"."PDBA":"P4" 11.28 MB 622582 行 作业 "SYSTEM"."SYS_IMPORT_TABLE_01" 已经完成, 但是有 1 个错误 (于 16:24:21 完成) (2)导入整个表 C:\Users\Administrator.DavidDai>impdp system/system DIRECTORY=dump DUMPFILE=partition.dmp TABLES=PDBA logfile=imp.log table_exists_action=append Import: Release 11.2.0.1.0 - Production on 星期四 3 月 3 16:26:51 2011 Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved. 连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options 已成功加载/卸载了主表 "SYSTEM"."SYS_IMPORT_TABLE_01" 启动 "SYSTEM"."SYS_IMPORT_TABLE_01": system/******** DIRECTORY=dump DUMPFILE=partition.dmp TABLES=PDBA logfile=imp.log table_exists_action=append 处理对象类型 TABLE_EXPORT/TABLE/TABLE ORA-39152: 表 "SYSTEM"."PDBA" 已存在。由于附加了 table_exists_action, 数据将附加到现有表, 但是将跳过所有相关元数据。 处理对象类型 TABLE_EXPORT/TABLE/TABLE_DATA . . 导入了 "SYSTEM"."PDBA":"P1" 31.12 MB 1718285 行 . . 导入了 "SYSTEM"."PDBA":"P4" 11.28 MB 622582 行 . . 导入了 "SYSTEM"."PDBA":"P3" 3.422 MB 188701 行 . . 导入了 "SYSTEM"."PDBA":"P2" 3.331 MB 183667 行 作业 "SYSTEM"."SYS_IMPORT_TABLE_01" 已经完成, 但是有 1 个错误 (于 16:27:02 完成) Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.3.3 分区表的其他操作 1.3.3.1 添加新的分区 添加新的分区有 2 中情况: (1)原分区里边界是 maxvalue 或者 default。 这种情况下,我们需要把边界分 区 drop 掉,加上新分区后,在添加上新的分区。 或者采用 split,对边界分区进 行拆分。 (2)没有边界分区的。 这种情况下,直接添加分区就可以了。 以边界分区添加新分区示例: (1)分区表和索引的信息如下: SQL> create table custaddr 2 ( 3 id varchar2(15 byte) not null, 4 areacode varchar2(4 byte) 5 ) 6 partition by list (areacode) 7 ( 8 partition t_list556 values ('556') tablespace icd_service, 9 partition p_other values (default)tablespace icd_service 10 ); 表已创建。 SQL> create index ix_custaddr_id on custaddr(id) 2 local ( 3 partition t_list556 tablespace icd_service, 4 partition p_other tablespace icd_service 5 ); 索引已创建。 (2)插入几条测试数据: SQL> insert into custaddr values('1','556'); 已创建 1 行。 SQL> insert into custaddr values('2','551'); 已创建 1 行。 SQL> insert into custaddr values('3','555'); 已创建 1 行。 SQL> commit; 提交完成。 SQL> select * from custaddr; ID AREA --------------- ---- 1 556 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 2 551 3 555 SQL> select * from custaddr partition(t_list556); ID AREA --------------- ---- 1 556 SQL> (3)删除 default 分区 sql> alter table custaddr drop partition p_other; 表已更改。 sql> select table_name,partition_name from user_tab_partitions where table_name='CUSTADDR'; table_name partition_name ------------------------------ ------------------------------ custaddr t_list556 (4)添加新分区 SQL> alter table custaddr add partition t_list551 values('551') tablespace icd_service; 表已更改。 SQL> select table_name,partition_name from user_tab_partitions where table_name='CUSTADDR'; TABLE_NAME PARTITION_NAME ------------------------------ ------------------------------ CUSTADDR T_LIST556 CUSTADDR T_LIST551 (5)添加 default 分区 SQL> alter table custaddr add partition p_other values (default) tablespace icd_service; 表已更改。 SQL> select table_name,partition_name from user_tab_partitions where table_name='CUSTADDR'; TABLE_NAME PARTITION_NAME ------------------------------ ------------------------------ CUSTADDR T_LIST556 CUSTADDR T_LIST551 CUSTADDR P_OTHER (6)对于局部索引,oracle 会自动增加一个局部分区索引。验证一下: sql> select owner,index_name,table_name,partitioning_type from dba_part_indexes where index_name='ix_custaddr_id'; owner index_name table_name Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 ---------------------- ------------------------------ ------------------ icd ix_custaddr_id custaddr sql> select index_owner,index_name,partition_name from dba_ind_partitions where index_name='ix_custaddr_id'; index_owner index_name partition_name ------------------------------ ------------------------------ ------------------ icd ix_custaddr_id p_other icd ix_custaddr_id t_list551 icd ix_custaddr_id t_list556 分区索引自动创建了。 1.3.3.2 split 分区拆分 在上节中,我们说明了可以使用 split 的方式来添加分区。 这里我们用 split 方法继续上面的实验。 sql> alter table custaddr split partition p_other values('552') into (partition t_list552 tablespace icd_service, partition p_other tablespace icd_service); 表已更改。 --注意这里红色的地方,如果是 Range 类型的,使用 at,List 使用 Values。 SQL> select table_name,partition_name from user_tab_partitions where table_name='CUSTADDR'; TABLE_NAME PARTITION_NAME ------------------------------ ------------------------------ CUSTADDR T_LIST556 CUSTADDR T_LIST551 CUSTADDR T_LIST552 CUSTADDR P_OTHER SQL> select index_owner,index_name,partition_name from dba_ind_partitions where index_name='IX_CUSTADDR_ID'; index_owner index_name partition_name ------------------------------ ------------------------------ ------------------ icd ix_custaddr_id p_other icd ix_custaddr_id t_list551 icd ix_custaddr_id t_list552 icd ix_custaddr_id t_list556 注意:分区表会自动维护局部分区索引。全局索引会失效,需要进行 rebuild。 1.3.3.3 合并分区 Merge 相邻的分区可以 merge 为一个分区,新分区的下边界为原来边界值较低的分Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 区,上边界为原来边界值较高的分区,原先的局部索引相应也会合并,全局索引 会失效,需要 rebuild。 SQL> alter table custaddr merge partitions t_list552,p_other into partition p_other; 表已更改。 SQL> select index_owner,index_name,partition_name from dba_ind_partitions where index_name='IX_CUSTADDR_ID'; index_owner index_name partition_name -------------------- ------------------------------ ------------------ icd ix_custaddr_id p_other icd ix_custaddr_id t_list551 icd ix_custaddr_id t_list556 SQL> select table_name,partition_name from user_tab_partitions where table_name='CUSTADDR'; table_name partition_name ------------------------------ ------------------------------ custaddr t_list556 custaddr t_list551 custaddr p_other 1.3.3.4 移动分区 SQL> alter table custaddr move partition P_OTHER tablespace system; 表已更改。 SQL> alter table custaddr move partition P_OTHER tablespace icd_service; 表已更改。 注意:分区移动会自动维护局部分区索引,oracle 不会自动维护全局索引,所 以需要我们重新 rebuild 分区索引,具体需要 rebuild 哪些索引,可以通过 dba_part_indexes,dba_ind_partitions 去判断。 SQL> Select index_name,status From user_indexes Where table_name='CUSTADDR'; INDEX_NAME STATUS ------------------------------ -------- IX_CUSTADDR_ID N/A 1.3.3.5 Truncate 分区 SQL> select * from custaddr partition(T_LIST556); ID AREA Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 --------------- ---- 1 556 SQL> alter table custaddr truncate partition(T_LIST556); 表被截断。 SQL> select * from custaddr partition(T_LIST556); 未选定行 说明: Truncate 相对 delete 操作很快,数据仓库中的大量数据的批量数据加载可能 会有用到;截断分区同样会自动维护局部分区索引,同时会使全局索引 unusable, 需要重建 1.3.3.6 Drop 分区 SQL> alter table custaddr drop partition T_LIST551; 表已更改。 SQL> select table_name,partition_name from user_tab_partitions where table_name='CUSTADDR'; TABLE_NAME PARTITION_NAME ------------------------------ ------------------------------ CUSTADDR T_LIST556 CUSTADDR P_OTHER 同样会自动维护局部分区索引,同时会使全局索引 unusable,需要重建 1.3.4 分区表的索引 分区索引分为本地(local index)索引和全局索引(global index)。局部索引比全 局索引容易管理, 而全局索引比较快。 与索引有关的表: dba_part_indexes 分区索引的概要统计信息,可以得知每个表上有哪些分区 索引,分区索引的类型(local/global) dba_ind_partitions 每个分区索引的分区级统计信息 dba_indexes/dba_part_indexes 可以得到每个表上有哪些非分区索引 Local 索引肯定是分区索引,Global 索引可以选择是否分区,如果分区,只 能是有前缀的分区索引。 分区索引分 2 类:有前缀(prefix)的分区索引和无前缀(nonprefix)的分区索引: (1)有前缀的分区索引指包含了分区键,并且将其作为引导列的索引。 如: create index i_id_global on PDBA(id) global --引导列 2 partition by range(id) --分区键 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 3 (partition p1 values less than (200), 4 partition p2 values less than (maxvalue) 5 ); 这里的 ID 就是分区键,并且分区键 id 也是索引的引导列。 (2)无前缀的分区索引的列不是以分区键开头,或者不包含分区键列。 如: create index ix_custaddr_local_id_p on custaddr(id) local ( partition t_list556 tablespace icd_service, partition p_other tablespace icd_service ) 这个分区是按照 areacode 来的。但是索引的引导列是 ID。 所以它就是非前 缀分区索引。 全局分区索引不支持非前缀的分区索引,如果创建,报错如下: sql> create index i_time_global on PDBA(id) global --索引引导列 2 partition by range(time) --分区建 3 (partition p1 values less than (TO_DATE('2010-12-1', 'YYYY-MM-DD')), 4 partition p2 values less than (maxvalue) 5 ); partition by range(time) * 第 2 行出现错误: ORA-14038: GLOBAL 分区索引必须加上前缀 1.3.4.4.1 Local 本地索引 对于 local 索引,当表的分区发生变化时,索引的维护由 Oracle 自动进行。 注意事项: (1) 局部索引一定是分区索引,分区键等同于表的分区键。 (2) 前缀和非前缀索引都可以支持索引分区消除,前提是查询的条件中包含索 引分区键。 (3) 局部索引只支持分区内的唯一性,无法支持表上的唯一性,因此如果要用 局部索引去给表做唯一性约束,则约束中必须要包括分区键列。 (4) 局部分区索引是对单个分区的,每个分区索引只指向一个表分区;全局索 引则不然,一个分区索引能指向 n 个表分区,同时,一个表分区,也可能指向 n 个索引分区,对分区表中的某个分区做 truncate 或者 move,shrink 等,可能会影 响到 n 个全局索引分区,正因为这点,局部分区索引具有更高的可用性。 (5) 位图索引必须是局部分区索引。 (6) 局部索引多应用于数据仓库环境中。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 (7) B 树索引和位图索引都可以分区,但是 HASH 索引不可以被分区。 示例: sql> create index ix_custaddr_local_id on custaddr(id) local; 索引已创建。 和下面 SQL 效果相同,因为 local 索引就是分区索引: create index ix_custaddr_local_id_p on custaddr(id) local ( partition t_list556 tablespace icd_service, partition p_other tablespace icd_service ) SQL> create index ix_custaddr_local_areacode on custaddr(areacode) local; 索引已创建。 验证 2 个索引的类型: SQL> select index_name,table_name,partitioning_type,locality,ALIGNMENT from user_part_indexes where table_name='CUSTADDR'; index_name table_name partition locali alignment ------------------------------ ---------- --------- ------ ------------ ix_custaddr_local_areacode custaddr list local prefixed ix_custaddr_local_id custaddr list local non_prefixed 因为我们的 custaddr 表是按 areacode 进 行 分 区 的 , 所 以 索 引 ix_custaddr_local_areacode 是有前缀的索引(prefixed)。而 ix_custaddr_local_id 是非前缀索引。 1.3.4.4.2 Global 索引 对于 global 索引,可以选择是否分区,而且索引的分区可以不与表分区相对 应。全局分区索引只能是 B 树索引,到目前为止(10gR2),oracle 只支持有前缀 的全局索引。 另外 oracle 不会自动的维护全局分区索引,当我们在对表的分区做修改之后, 如果对分区进行维护操作时不加上 update global indexes 的话,通常会导致全局 索引的 INVALDED,必须在执行完操作后 REBUILD。 注意事项: (1)全局索引可以分区,也可以是不分区索引,全局索引必须是前缀索引,即 全局索引的索引列必须是以索引分区键作为其前几列。 (2)全局索引可以依附于分区表;也可以依附于非分区表。 (3)全局分区索引的索引条目可能指向若干个分区,因此,对于全局分区索引,Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 即使只截断一个分区中的数据,都需要 rebulid 若干个分区甚至是整个索引。 (4)全局索引多应用于 oltp 系统中。 (5)全局分区索引只按范围或者散列分区,hash 分区是 10g 以后才支持。 (6) oracle9i 以后对分区表做 move 或者 truncate 的时可以用 update global indexes 语句来同步更新全局分区索引,用消耗一定资源来换取高度的可用性。 (7) 表用 a 列作分区,索引用 b 做局部分区索引,若 where 条件中用 b 来查询, 那么 oracle 会扫描所有的表和索引的分区,成本会比分区更高,此时可以考虑用 b 做全局分区索引。 注意:Oracle 只支持 2 中类型的全局分区索引: range partitioned 和 Hash Partitioned. 官网的说明如下: Global Partitioned Indexes Oracle offers two types of global partitioned index: range partitioned and hash partitioned. (1)Global Range Partitioned Indexes Global range partitioned indexes are flexible in that the degree of partitioning and the partitioning key are independent from the table's partitioning method. They are commonly used for OLTP environments and offer efficient access to any individual record. The highest partition of a global index must have a partition bound, all of whose values are MAXVALUE. This ensures that all rows in the underlying table can be represented in the index. Global prefixed indexes can be unique or nonunique. You cannot add a partition to a global index because the highest partition always has a partition bound of MAXVALUE. If you wish to add a new highest partition, use the ALTER INDEX SPLIT PARTITION statement. If a global index partition is empty, you can explicitly drop it by issuing the ALTER INDEX DROP PARTITION statement. If a global index partition contains data, dropping the partition causes the next highest partition to be marked unusable. You cannot drop the highest partition in a global index. (2)Global Hash Partitioned Indexes Global hash partitioned indexes improve performance by spreading out contention when the index is monotonically growing. In other words, most of the index insertions occur only on the right edge of an index. (3)Maintenance of Global Partitioned Indexes By default, the following operations on partitions on a heap-organized table mark all global indexes as unusable: ADD (HASH) COALESCE (HASH) DROP Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 EXCHANGE MERGE MOVE SPLIT TRUNCATE 示例 1 全局索引,全局索引对所有分区类型都支持: sql> create index ix_custaddr_ global_id on custaddr(id) global; 索引已创建。 示例 2:全局分区索引,只支持 Range 分区和 Hash 分区: (1)创建 2 个测试分区表: sql> create table pdba (id number, time date) partition by range (time) 2 ( 3 partition p1 values less than (to_date('2010-10-1', 'yyyy-mm-dd')), 4 partition p2 values less than (to_date('2010-11-1', 'yyyy-mm-dd')), 5 partition p3 values less than (to_date('2010-12-1', 'yyyy-mm-dd')), 6 partition p4 values less than (maxvalue) 7 ); 表已创建。 SQL> create table Thash 2 ( 3 id number primary key, 4 item_id number(8) not null 5 ) 6 partition by hash(id) 7 ( 8 partition part_01, 9 partition part_02, 10 partition part_03 11 ); 表已创建。 (2)创建分区索引 示例 2:全局分区索引 SQL> create index i_id_global on PDBA(id) global 2 partition by range(id) 3 (partition p1 values less than (200), 4 partition p2 values less than (maxvalue) 5 ); 索引已创建。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 --这个是有前缀的分区索引。 SQL> create index i_time_global on PDBA(id) global 2 partition by range(time) 3 (partition p1 values less than (TO_DATE('2010-12-1', 'YYYY-MM-DD')), 4 partition p2 values less than (maxvalue) 5 ); partition by range(time) * 第 2 行出现错误: ORA-14038: GLOBAL 分区索引必须加上前缀 SQL> create index i_time_global on PDBA(time) global 2 partition by range(time) 3 (partition p1 values less than (TO_DATE('2010-12-1', 'YYYY-MM-DD')), 4 partition p2 values less than (maxvalue) 5 ); 索引已创建。 --有前缀的分区索引 SQL> select index_name,table_name,partitioning_type,locality,ALIGNMENT from user_part_indexes where table_name='PDBA'; index_name table_name partition locali alignment ------------------------------ ---------- --------- ------ ------------ i_id_global pdba range global prefixed i_time_global pdba range global prefixed SQL> CREATE INDEX ix_hash ON PDBA (id,time) GLOBAL 2 PARTITION BY HASH (id) 3 (PARTITION p1, 4 PARTITION p2, 5 PARTITION p3, 6 PARTITION p4); 索引已创建。 只要索引的引导列包含分区键,就是有前缀的分区索引。 1.3.4.4.3 索引重建问题 (1)分区索引 对于分区索引,不能整体进行重建,只能对单个分区进行重建。语法如下: Alter index idx_name rebuild partition index_partition_name [online nologging] 说明: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 online:表示重建的时候不会锁表。 nologging:表示建立索引的时候不生成日志,加快速度。 如果要重建分区索引,只能 drop 表原索引,在重新创建: SQL>create index loc_xxxx_col on xxxx(col) local tablespace SYSTEM; 这个操作要求较大的临时表空间和排序区。 示例: SQL> select index_name,partition_name from user_ind_partitions where index_name='I_TIME_GLOBAL'; INDEX_NAME PARTITION_NAME ------------------------------ ------------------------------ I_TIME_GLOBAL P1 I_TIME_GLOBAL P2 SQL> alter index I_TIME_GLOBAL rebuild partition p1 online nologging; 索引已更改。 SQL> alter index I_TIME_GLOBAL rebuild partition p2 online nologging; 索引已更改。 (2)全局索引 Oracle 会自动维护分区索引,对于全局索引,如果在对分区表操作时,没有 指定 update index,则会导致全局索引失效,需要重建。 SQL> select owner,index_name,table_name,status from dba_indexes where INDEX_NAME='IX_PDBA_GLOBAL'; owner index_name table_name status ------------------------------ ------------------------------ ---------- ------- sys ix_pdba_global pdba valid 删除一个分区: SQL> alter table pdba drop partition p2; 表已更改。 SQL> select owner,index_name,table_name,status from dba_indexes where INDEX_NAME='IX_PDBA_GLOBAL'; owner index_name table_name status ------------------------------ ------------------------------ ---------- ------- sys ix_pdba_global pdba valid split 分区: SQL> alter table pdba split partition P4 at(TO_DATE('2010-12-21 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 00:00:00','YYYY-MM-DD HH24:MI:SS')) into (partition P4, partition P5); 表已更改。 SQL> select owner,index_name,table_name,status from dba_indexes where INDEX_NAME='IX_PDBA_GLOBAL'; owner index_name table_name status ------------------------------ ------------------------------ ---------- ------- sys ix_pdba_global pdba valid drop 分区时使用 update indexes SQL> alter table pdba drop partition P4 UPDATE INDEXES; 表已更改。 SQL> select owner,index_name,table_name,status from dba_indexes where INDEX_NAME='IX_PDBA_GLOBAL'; owner index_name table_name status ---------------------- ------------------------------ ---------- ------- sys ix_pdba_global pdba valid 做了几个 drop 分区操作,全局索引没有失效,有点奇怪。 不过如果在生产环境 中,还是小心点。 重建全局索引命令如下: Alter index idx_name rebuild [online nologging] 示例: SQL> Alter index ix_pdba_global rebuild online nologging; 索引已更改。 补充一点,分区表存储空间的问题: SQL> select table_name,partition_name,tablespace_name from user_tab_partitions where table_name='DBA'; TABLE_NAME PARTITION_NAME TABLESPACE_NAME ---------- ------------------------------ ------------------------------ DBA P1 SYSTEM DBA P2 SYSTEM DBA P3 SYSTEM DBA P4 SYSTEM 通过 user_tab_partitions 表可以查看到每个分区对应的 tablesapce_name. 但是, 如果通过 all_tables 表,却查不到分区表对应表空间的信息。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 分区表: SQL> select owner,table_name,tablespace_name,cluster_name from all_tables where table_name='DBA'; OWNER TABLE_NAME TABLESPACE_NAME CLUSTER_NAME ----- ---------- ------------------------------ ----------------------------------------------------- SYS DBA 普通表: SQL> select owner,table_name,tablespace_name,cluster_name from all_tables where table_name='DAVE'; OWNER TABLE_NAME TABLESPACE_NAME CLUSTER_NAME ----- ---------- ------------------------------ --------------------------------------------------- SYS DAVE SYSTEM 1.3.5 Oracle 11g 中的分区表 1.3.5.1 11g 中的分区表新特性 Partition(分区)一直是 Oracle 数据库引以为傲的一项技术,正是分区的存 在让 Oracle 高效的处理海量数据成为可能,在 Oracle 11g 中,分区技术在易用性 和可扩展性上再次得到了增强。 1.3.5.1.1 Interval Partitioning 在曾经的一个项目中,由于数据量的巨大,所以表设计为每一个小时一个分 区,数据库管理员日常要做的一件重复而无聊的工作就是每隔一天要生成新的 24 个分区,用以存储第二天的数据。而在 11g 中这项工作可以交由 Oracle 自动 完成了,基于 Range 和 List 的 Interval Partitioning 分区类型登场。 CREATE TABLE TB_INTERVAL PARTITION BY RANGE (time_col) INTERVAL(NUMTOYMINTERVAL(1, 'month')) (PARTITION P0 VALUES LESS THAN (TO_DATE('1-1-2010', 'dd-mm-yyyy'))); 指定需要 Oracle 自动创建分区的间隔时间,上面这个例子是 1 个月,然后 至少创建一个基本分区,上面这个例子是在 2010-1-1 之前的所有数据都在 P0 分 区中,以后每个月的数据都会存放在 Oracle 自动创建的一个新分区中。 1.3.5.1.2 System Partitioning 系统分区,在这个新的类型中,我们不需要指定任何分区键,数据会进入哪 个分区完全由应用程序决定,实际上也就是由 SQL 来决定,终于,我们在 Insert 语句中可以指定插入哪个分区了。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 假设我们创建了下面这张分区表,注意,没有指定任何分区键: CREATE TABLE systab (c1 integer, c2 integer) PARTITION BY SYSTEM ( PARTITION p1 TABLESPACE tbs_1, PARTITION p2 TABLESPACE tbs_2, PARTITION p3 TABLESPACE tbs_3, PARTITION p4 TABLESPACE tbs_4 ); 现在由 SQL 语句来指定插入哪个分区: -- 数据插入 p1 分区 INSERT INTO systab PARTITION (p1) VALUES (4,5); -- 数据插入第 2 个分区,也就是 p2 分区 INSERT INTO systab PARTITION (2) VALUES (7,8); -- 为了实现绑定变量,用 pno 变量来代替实际分区号,以避免过度解析 INSERT INTO systab PARTITION (:pno) VALUES (9,10); 由于 System Partitioning 的特殊性,所以很明显,这种类型的分区将不支持 Partition Split 操作,也不支持 create table as select 操作。 1.3.5.1.3 More Composite Partitioning 在 10g 中,我们知道复合分区只支持 Range-List 和 Range-Hash,而在在 11g 中复合分区的类型大大增加,现在 Range,List,Interval 都可以作为 Top level 分区,而 Second level 则可以是 Range,List,Hash,也就是在 11g 中可以有 3*3=9 种复合分区,满足更多的业务需求。 1.3.5.1.4 Virtual Column-Based Partitioning Virtual Column 是 11g 中的一个新功能,这种列中的数据并不实际存储于磁 盘上(我们可以看成是一个类似 Function 的列),只有当读取的时候才实时计算。 暂时不讨论性能问题,这个功能还是比较有意思的。 可以通过这样的语句来创建虚拟列。 CREATE TABLE tb_v (col_1 number(6) not null, col_2 number not null, „ col_v as (col_1 *( 1+col_2)); 虚拟列虽然没有实际的存储空间,但是却可以跟其他普通列一样,创建索引, 作为分区键,甚至可以收集统计信息。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.3.5.2 11g 虚拟列实现 按星期分区表 在 11g 之前 分区表的 partition key 必须是物理存在的。 11g 开始提供了虚拟 列,并且可以作为 partition key 。 1. 创建分区表: CREATE TABLE PT ( getdate date NOT NULL, wd NUMBER GENERATED ALWAYS AS (TO_NUMBER (TO_CHAR (getdate, 'D'))) VIRTUAL --虚拟列 ) PARTITION BY LIST (wd) (PARTITION Sun VALUES (1), PARTITION Mon VALUES (2), PARTITION Tue VALUES (3), PARTITION Wed VALUES (4), PARTITION Thu VALUES (5), PARTITION Fri VALUES (6), PARTITION Sat VALUES (7) ); 2. 插入测试数据 SQL> insert into pt(getdate) values(sysdate); 已创建 1 行。 SQL> insert into pt(getdate) values(sysdate-1); 已创建 1 行。 SQL> insert into pt(getdate) values(sysdate-2); 已创建 1 行。 SQL> insert into pt(getdate) values(sysdate-3); 已创建 1 行。 SQL> insert into pt(getdate) values(sysdate-4); 已创建 1 行。 SQL> insert into pt(getdate) values(sysdate-5); 已创建 1 行。 SQL> insert into pt(getdate) values(sysdate-6); 已创建 1 行。 SQL> insert into pt(getdate) values(sysdate-7); 已创建 1 行。 SQL> commit; 提交完成。 3. 查看数据: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL> select * from pt; GETDATE WD -------------- ---------- 06-6 月 -10 1 07-6 月 -10 2 08-6 月 -10 3 09-6 月 -10 4 10-6 月 -10 5 03-6 月 -10 5 04-6 月 -10 6 05-6 月 -10 7 已选择 8 行。 SQL> alter session set nls_date_format='YYYY-MM-DD'; 会话已更改。 SQL> select * from pt; GETDATE WD ---------- ---------- 2010-06-06 1 2010-06-07 2 2010-06-08 3 2010-06-09 4 2010-06-10 5 2010-06-03 5 2010-06-04 6 2010-06-05 7 已选择 8 行。 4. 查看每个分区里的内容: SQL> select * from pt partition(sun); GETDATE WD ---------- ---------- 2010-06-06 1 SQL> select * from pt partition(mon); GETDATE WD ---------- ---------- 2010-06-07 2 SQL> select * from pt partition(tue); GETDATE WD ---------- ---------- 2010-06-08 3 SQL> select * from pt partition(wed); GETDATE WD ---------- ---------- 2010-06-09 4 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL> select * from pt partition(fri); GETDATE WD ---------- ---------- 2010-06-04 6 SQL> select * from pt partition(sat); GETDATE WD ---------- ---------- 2010-06-05 7 SQL> 注:如果是 10g,就要添加一物理列。 1.3.5.3 Interval 分区 示例 在 Oracle Database 11g 中还可以创建新类型的 Interval 分区表,Interval 类型 分区表,可以根据加载数据,自动创建指定间隔的分区。 1.3.5.3.1 创建按月分区的分区表 1. 创建分区表 /* Formatted on 2010/6/10 20:21:12 (QP5 v5.115.810.9015) */ create table intervalpart (c1 number, c3 date) partition by range (c3) interval ( numtoyminterval (1, 'month') ) (partition part1 values less than (to_date ('01/12/2010', 'mm/dd/yyyy')), partition part2 values less than (to_date ('02/12/2010', 'mm/dd/yyyy')) ) 注意:如果在建 Interval 分区表是没有把所有的分区写完成,在插入相关数据后会 自动生成分区 2. 查看现在表的分区: SQL> select table_name,partition_name from user_tab_partitions where table_name='INTERVALPART'; TABLE_NAME PARTITION_NAME ------------------------------ ------------------------------ INTERVALPART PART1 INTERVALPART PART2 3. 插入测试数据: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL> begin 2 for i in 0 .. 11 loop 3 insert into intervalpart values(i,add_months(to_date('2010-1-1','yyyy-mm-dd'),i)); 4 end loop ; 5 commit; 6 end; 7 / PL/SQL 过程已成功完成。 补充:add_months() 函数获取前一个月或者下一个月的月份, 参数中 负数 代 表 往前, 正数 代表 往后。 --上一个月 select to_char(add_months(trunc(sysdate),-1),'yyyymm') from dual; --下一个月 select to_char(add_months(trunc(sysdate),1),'yyyymm') from dual; 4. 观察自动创建的分区: SQL> select table_name,partition_name from user_tab_partitions where table_name='INTERVALPART'; TABLE_NAME PARTITION_NAME ------------------------------ ------------------------------ INTERVALPART PART1 INTERVALPART PART2 INTERVALPART SYS_P22 INTERVALPART SYS_P23 INTERVALPART SYS_P24 INTERVALPART SYS_P25 INTERVALPART SYS_P26 INTERVALPART SYS_P27 INTERVALPART SYS_P28 INTERVALPART SYS_P29 INTERVALPART SYS_P30 INTERVALPART SYS_P31 已选择 12 行。 5. 查看分区内容: SQL> select * from INTERVALPART; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 C1 C3 ---------- ---------- 1 2010-01-01 0 2010-01-01 1 2010-02-01 2 2010-03-01 3 2010-04-01 4 2010-05-01 5 2010-06-01 6 2010-07-01 7 2010-08-01 8 2010-09-01 9 2010-10-01 10 2010-11-01 11 2010-12-01 已选择 13 行。 SQL> select * from INTERVALPART partition(part1); C1 C3 ---------- ---------- 1 2010-01-01 0 2010-01-01 SQL> select * from INTERVALPART partition(part2); C1 C3 ---------- ---------- 1 2010-02-01 1.3.5.3.2 创建一个以天为间隔的分区表 1. 创建分区表: SQL> create table dave 2 ( 3 id number, 4 dt date 5 ) 6 partition by range (dt) 7 INTERVAL (NUMTODSINTERVAL(1,'day')) 8 ( 9 partition p100101 values less than (to_date('2010-01-01','yyyy-mm-dd')) 10 ); Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 2. 查看表分区: SQL> select table_name,partition_name from user_tab_partitions where table_name='DAVE'; TABLE_NAME PARTITION_NAME ------------------------------ ------------------------------ DAVE P100101 3. 插入测试数据: SQL> begin 2 for i in 1 .. 12 loop 3 insert into dave values(i,trunc(to_date('2010-1-1','yyyy-mm-dd')+i)); 4 end loop; 5 commit; 6 end; 7 / PL/SQL 过程已成功完成。 4. 观察自动创建的分区: SQL> select table_name,partition_name from user_tab_partitions where table_name='DAVE'; TABLE_NAME PARTITION_NAME ------------------------------ ------------------------------ DAVE P100101 DAVE SYS_P32 DAVE SYS_P33 DAVE SYS_P34 DAVE SYS_P35 DAVE SYS_P36 DAVE SYS_P37 DAVE SYS_P38 DAVE SYS_P39 DAVE SYS_P40 DAVE SYS_P41 DAVE SYS_P42 DAVE SYS_P43 已选择 13 行。 5. 查看分区内容: SQL> select * from dave partition(SYS_P32); ID DT ---------- ---------- Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1 2010-01-02 SQL> select * from dave partition(SYS_P33); ID DT ---------- ---------- 2 2010-01-03 SQL> select * from dave partition(SYS_P34); ID DT ---------- ---------- 3 2010-01-04 SQL> select * from dave; ID DT ---------- ---------- 1 2010-01-02 2 2010-01-03 3 2010-01-04 4 2010-01-05 5 2010-01-06 6 2010-01-07 7 2010-01-08 8 2010-01-09 9 2010-01-10 10 2010-01-11 11 2010-01-12 12 2010-01-13 已选择 12 行。 1.4 Oracle 锁 1.4.1 锁(Lock) 1.4.1.1 锁的概念 数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数 据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可 能会读取和存储不正确的数据,破坏数据库的一致性。 加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对 象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了 一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。 在 Oracle 数据库中,它并不是对某个表加上锁或者某几行加上锁,锁是以 数据块的一个属性存在的。 也就是说,每个数据块本身就存储着自己数据块中 数据的信息,这个地方叫 ITL(Interested Transaction List), 凡是在这个数据块上Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 有活动的事务,它的信息就会记录在这里面供后续的操作查询,一保证事务的一 致性。 1.4.1.2 锁的分类 1.4.1.2.1. 按用户与系统划分,可以分为自动锁与显示锁 a) 自动锁(Automatic Locks): 当进行一项数据库操作时,缺省情况下,系 统自动为此数据库操作获得所有有必要的锁。自动锁分 DML 锁,DDL 锁,system locks。 b) 显示锁(Manual Data Locks): 某些情况下,需要用户显示的锁定数据库 操作要用到的数据,才能使数据库操作执行得更好,显示锁是用户为数据库对象 设定的。 Oracle Database performs locking automatically to ensure data concurrency, data integrity, and statement-level read consistency. However, you can manually override the Oracle Database default locking mechanisms. Overriding the default locking is useful in situations such as the following: Applications require transaction-level read consistency or repeatable reads. In this case, queries must produce consistent data for the duration of the transaction, not reflecting changes by other transactions. You can achieve transaction-level read consistency by using explicit locking, read-only transactions, serializable transactions, or by overriding default locking. Applications require that a transaction have exclusive access to a resource so that the transaction does not have to wait for other transactions to complete. You can override Oracle Database automatic locking at the session or transaction level. At the session level, a session can set the required transaction isolation level with the ALTER SESSION statement. At the transaction level, transactions that include the following SQL statements override Oracle Database default locking: (1)The SET TRANSACTION ISOLATION LEVEL statement (2)The LOCK TABLE statement (which locks either a table or, when used with views, the base tables) (3)The SELECT ... FOR UPDATE statement Locks acquired by the preceding statements are released after the transaction ends or a rollback to savepoint releases them. If Oracle Database default locking is overridden at any level, then the database administrator or application developer should ensure that the overriding locking procedures operate correctly. The locking procedures must satisfy the following criteria: data integrity is guaranteed, data concurrency is acceptable, and deadlocks are not possible or are appropriately handled. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.4.1.2.2. 按锁级别划分,可分为: 排它锁(Exclusive Locks,即 X 锁)和共享 锁(Share Locks,即 S 锁) a) 共享锁( S ): 共享锁使一个事务对特定数据库资源进行共享访问——另 一事务也可对此资源进行访问或获得相同共享锁。共享锁为事务提供高并发性, 但如拙劣的事务设计+共享锁容易造成死锁或数据更新丢失。 b) 排它锁( X): 事务设置排它锁后,该事务单独获得此资源,另一事务不 能在此事务提交之前获得相同对象的共享锁或排它锁。 1.4.1.2.3 按操作划分,可分为 DML 锁(data locks,数据锁)、DDL 锁(data dictionary lock)和 System Locks。 Lock Description DML Locks Protect data. For example, table locks lock entire tables, while row locks lock selected rows. See "DML Locks". DDL Locks Protect the structure of schema objects—for example, the dictionary definitions of tables and views. See "DDL Locks". System Locks Protect internal database structures such as data files. Latches, mutexes, and internal locks are entirely automatic. See "System Locks". 1.4.1.2.4 DML 锁 这部分内容,可以参考 Oracle 联机文档 Automatic Locks in DML Operations http://download.oracle.com/docs/cd/E11882_01/server.112/e10592/ap_locks001. htm#SQLRF55502 DML 锁用于控制并发事务中的数据操纵,保证数据的一致性和完整性。DML 锁主要用于保护并发情况下的数据完整性。 它又分为: (1)TM 锁(表级锁) (2)TX 锁(事务锁或行级锁) 当 Oracle 执行 DML 语句时,系统自动在所要操作的表上申请 TM 类型的锁。 当 TM 锁获得后,系统再自动申请 TX 类型的锁,并将实际锁定的数据行的锁标 志位进行置位。这样在事务加锁前检查TX锁相容性时就不用再逐行检查锁标志, 而只需检查 TM 锁模式的相容性即可,大大提高了系统的效率。 在数据行上只有 X 锁(排他锁)。在 Oracle 数据库中,当一个事务首次发起 一个 DML 语句时就获得一个 TX 锁,该锁保持到事务被提交或回滚。当两个或Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 多个会话在表的同一条记录上执行 DML 语句时,第一个会话在该条记录上加 锁,其他的会话处于等待状态。当第一个会话提交后,TX 锁被释放,其他会话 才可以加锁。 当 Oracle 数据库发生 TX 锁等待时,如果不及时处理常常会引起 Oracle 数据 库挂起,或导致死锁的发生,产生 ORA-600 的错误。这些现象都会对实际应用 产生极大的危害,如长时间未响应,大量事务失败等。 TM 锁(表锁) 当事务获得行锁后,此事务也将自动获得该行的表锁(共享锁),以防止其它事 务进行 DDL 语句影响记录行的更新。事务也可以在进行过程中获得共享锁或排 它锁,只有当事务显示使用 LOCK TABLE 语 句显示的定义一个排它锁时,事务 才会获得表上的排它锁,也可使用 LOCK TABLE 显示的定义一个表级的共享锁 (LOCK TABLE 具体用法请参考相关文档)。 TM 锁包括了 SS、SX、S、X 等多种模式,在数据库中用 0-6 来表示。不 同的 SQL 操作产生不同类型的 TM 锁。 TM 锁类型表 锁模式 锁描述 解释 SQL 操作 0 none 1 NULL 空 Select 2 SS(Row-S) 行级共享锁,其他对象只能 查询这些数据行 Select for update、Lock for update、Lock row share 3 SX(Row-X) 行级排它锁,在提交前不允 许做 DML 操作 Insert、Update、 Delete、 Lock row share 4 S(Share) 共享锁 Create index、Lock share 5 SSX(S/Row-X) 共享行级排它锁 Lock share row exclusive 6 X(Exclusive) 排它锁 Alter table、Drop able、 Drop index 、 Truncate table 、Lock exclusive TX 锁(行锁) 当事务执行数据库插入、更新、删除操作时,该事务自动获得操作 表中操 作行的排它锁。 对用户的数据操纵,Oracle 可以自动为操纵的数据进行加锁,但如果有操纵 授权,则为满足并发操纵的需要另外实施加锁。DML 锁可由一个用户进程以显 式的方式加锁,也可通过某些 SQL 语句隐含方式实现。 这部分属于 Manual Data Locks。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 DML 锁有如下三种加锁方式: (1)、共享锁方式(SHARE) (2)、独占锁方式(EXCLUSIVE) (3)、共享更新锁(SHARE UPDATE) 其中: SHARE,EXCLUSIVE 用于 TM 锁(表级锁) SHARE UPDATE 用于 TX 锁(行级锁)。 (1)共享方式的表级锁(Share) 共享方式的表级锁是对表中的所有数据进行加锁,该锁用于保护查询数据的 一致性,防止其它用户对已加锁的表进行更新。其它用户只能对该表再施加共享 方式的锁,而不能再对该表施加独占方式的锁,共享更新锁可以再施加,但不允 许持有共享更新封锁的进程做更新。共享该表的所有用户只能查询表中的数据, 但不能更新。 共享方式的表级锁只能由用户用 SQL 语句来设置,基语句格式如下: LOCK TABLE <表名>[,<表名>]... IN SHARE MODE [NOWAIT] 执行该语句,对一个或多个表施加共享方式的表封锁。当指定了选择项 NOWAIT,若该锁暂时不能施加成功,则返回并由用户决定是进行等待,还是先 去执行别的语句。 持有共享锁的事务,在出现如下之一的条件时,便释放其共享锁: A、执行 COMMIT 或 ROLLBACK 语句。 B、退出数据库(LOG OFF)。 C、程序停止运行。 共享方式表级锁常用于一致性查询过程,即在查询数据期间表中的数据不发生改 变。 (2)独占方式表级锁(Exclusive) 独占方式表级锁是用于加锁表中的所有数据,拥有该独占方式表封锁的用 户,即可以查询该表,又可以更新该表,其它的用户不能再对该表施加任何加锁 (包括共享、独占或共享更新封锁)。其它用户虽然不能更新该表,但可以查询 该表。 独占方式的表封锁可通过如下的 SQL 语句来显示地获得: LOCK TABLE <表名>[,<表名>].... IN EXCLUSIVE MODE [NOWAIT] 独占方式的表级锁也可以在用户执行 DML 语句 INSERT、UPDATE、DELETE 时隐含获得。 拥有独占方式表封锁的事务,在出现如下条件之一时,便释放该封锁: (1)、执行 COMMIT 或 ROLLBACK 语句。 (2)、退出数据库(LOG OFF) (3)、程序停止运行。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 独占方式封锁通常用于更新数据,当某个更新事务涉及多个表时,可减少发生死 锁。 (3)共享更新加锁方式(Share Update) 共享更新加锁是对一个表的一行或多行进行加锁,因而也称作行级加锁。表 级加锁虽然保证了数据的一致性,但却减弱了操作数据的并行性。行级加锁确保 在用户取得被更新的行到该行进行更新这段时间内不被其它用户所修改。因而行 级锁即可保证数据的一致性又能提高数据操作的迸发性。 可通过如下的两种方式来获得行级封锁: (1)、执行如下的 SQL 封锁语句,以显示的方式获得: LOCK TABLE < 表名>[,< 表名>].... IN SHARE UPDATE MODE [NOWAIT] (2)、用如下的 SELECT ...FOR UPDATE 语句获得: SELECT <列名>[,<列名>]...FROM < 表名> WHERE <条件> FOR UPDATE OF <列名>[,<列名>].....[NOWAIT] 一旦用户对某个行施加了行级加锁,则该用户可以查询也可以更新被加锁的 数据行,其它用户只能查询但不能更新被加锁的数据行.如果其它用户想更新该 表中的数据行,则也必须对该表施加行级锁.即使多个用户对一个表均使用了共 享更新,但也不允许两个事务同时对一个表进行更新,真正对表进行更新时,是 以独占方式锁表,一直到提交或复原该事务为止。行锁永远是独占方式锁。 当出现如下之一的条件,便释放共享更新锁: (1)、执行提交(COMMIT)语句; (2)、退出数据库(LOG OFF) (3)、程序停止运行。 执行 ROLLBACK 操作不能释放行锁。 1.4.1.2.5 DDL 锁(dictionary locks) DDL 锁用于保护数据库对象的结构,如表、索引等的结构定义。 DDL 锁又可以分为:排它 DDL 锁、共享 DDL 锁、分析锁 (1) 排它 DDL 锁: 创建、修改、删除一个数据库对象的 DDL 语句获得操作对象的 排它锁。如 使用 alter table 语句时,为了维护数据的完成性、一致性、合法性,该事务获得 一排它 DDL 锁。 (2) 共享 DDL 锁: 需在数据库对象之间建立相互依赖关系的 DDL 语句通常需共享获得 DDL 锁。如创建一个包,该包中的过程与函数引用了不同的数据库表,当编译此包时,Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 该事务就获得了引用表的共享 DDL 锁。 (3) 分析锁: ORACLE 使用共享池存储分析与优化过的 SQL 语句及 PL/SQL 程序,使运 行相同语句的应用速度更快。一个在共享池中缓存的对象获得它所引用数据库对 象的分析锁。分析锁是一种独特的 DDL 锁类型,ORACLE 使用它追踪共享池对 象及它所引用数据库对象之间的依赖关系。当一个事务修改或删除了共享池持有 分析锁的数据库对象时,ORACLE 使共享池中的对象作废,下次在引用这条 SQL/PLSQL 语 句时,ORACLE 重新分析编译此语句。 DDL 级加锁也是由 ORACLE RDBMS 来控制,它用于保护数据字典和数据 定义改变时的一致性和完整性。它是系统在对 SQL 定义语句作语法分析时自动 地加锁,无需用户干予。 字典/语法分析加锁共分三类: (1)字典操作锁: 用于对字典操作时,锁住数据字典,此封锁是独占的,从而保护任何一 个时刻仅能对一个字典操作。 (2)字典定义锁: 用于防止在进行字典操作时又进行语法分析,这样可以避免在查询字典 的同时改动某个表的结构。 (3)表定义锁: 用于一个 SQL 语句正当访问某个表时,防止字典中与该表有关的项目被 修改。 Automatic Locks in DDL Operations http://download.oracle.com/docs/cd/E11882_01/server.112/e10592/ap_locks002.htm# SQLRF55509 A data dictionary (DDL) lock protects the definition of a schema object while an ongoing DDL operation acts on or refers to the object. Only individual schema objects that are modified or referenced are locked during DDL operations. The database never locks the whole data dictionary. Oracle Database acquires a DDL lock automatically on behalf of any DDL transaction requiring it. Users cannot explicitly request DDL locks. For example, if a user creates a stored procedure, then Oracle Database automatically acquires DDL locks for all schema objects referenced in the procedure definition. The DDL locks prevent these objects from being altered or dropped before procedure compilation is complete. Exclusive DDL Locks An exclusive DDL lock prevents other sessions from obtaining a DDL or DML lock. Most DDL operations, except for those described in "Share DDL Locks", require exclusive DDL locks for a resource to prevent destructive interference with Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 other DDL operations that might modify or reference the same schema object. For example, DROP TABLE is not allowed to drop a table while ALTER TABLE is adding a column to it, and vice versa. Exclusive DDL locks last for the duration of DDL statement execution and automatic commit. During the acquisition of an exclusive DDL lock, if another DDL lock is already held on the schema object by another operation, then the acquisition waits until the older DDL lock is released and then proceeds. Share DDL Locks A share DDL lock for a resource prevents destructive interference with conflicting DDL operations, but allows data concurrency for similar DDL operations. For example, when a CREATE PROCEDURE statement is run, the containing transaction acquires share DDL locks for all referenced tables. Other transactions can concurrently create procedures that reference the same tables and acquire concurrent share DDL locks on the same tables, but no transaction can acquire an exclusive DDL lock on any referenced table. A share DDL lock lasts for the duration of DDL statement execution and automatic commit. Thus, a transaction holding a share DDL lock is guaranteed that the definition of the referenced schema object remains constant during the transaction. Breakable Parse Locks A parse lock is held by a SQL statement or PL/SQL program unit for each schema object that it references. Parse locks are acquired so that the associated shared SQL area can be invalidated if a referenced object is altered or dropped. A parse lock is called a breakable parse lock because it does not disallow any DDL operation and can be broken to allow conflicting DDL operations. A parse lock is acquired in the shared pool during the parse phase of SQL statement execution. The lock is held as long as the shared SQL area for that statement remains in the shared pool. 1.4.1.2.6 System Locks System Locks http://download.oracle.com/docs/cd/E11882_01/server.112/e10713/consist.htm#C IHJBIBB Oracle Database uses various types of system locks to protect internal database and memory structures. These mechanisms are inaccessible to users because users have no control over their occurrence or duration. 1. Latches Latches are simple, low-level serialization mechanisms that coordinate Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 multiuser access to shared data structures, objects, and files. Latches protect shared memory resources from corruption when accessed by multiple processes. Specifically, latches protect data structures from the following situations: (1)Concurrent modification by multiple sessions (2)Being read by one session while being modified by another session (3)Deallocation (aging out) of memory while being accessed Typically, a single latch protects multiple objects in the SGA. For example, background processes such as DBWn and LGWR allocate memory from the shared pool to create data structures. To allocate this memory, these processes use a shared pool latch that serializes access to prevent two processes from trying to inspect or modify the shared pool simultaneously. After the memory is allocated, other processes may need to access shared pool areas such as the library cache, which is required for parsing. In this case, processes latch only the library cache, not the entire shared pool. Unlike enqueue latches such as row locks, latches do not permit sessions to queue. When a latch becomes available, the first session to request the latch obtains exclusive access to it. Latch spinning occurs when a process repeatedly requests a latch in a loop, whereas latch sleeping occurs when a process releases the CPU before renewing the latch request. Typically, an Oracle process acquires a latch for an extremely short time while manipulating or looking at a data structure. For example, while processing a salary update of a single employee, the database may obtain and release thousands of latches. The implementation of latches is operating system-dependent, especially in respect to whether and how long a process waits for a latch. An increase in latching means a decrease in concurrency. For example, excessive hard parse operations create contention for the library cache latch. The V$LATCH view contains detailed latch usage statistics for each latch, including the number of times each latch was requested and waited for. 2. Mutexes A mutual exclusion object (mutex) is a low-level mechanism that prevents an object in memory from aging out or from being corrupted when accessed by concurrent processes. A mutex is similar to a latch, but whereas a latch typically protects a group of objects, a mutex protects a single object. Mutexes provide several benefits: (1)A mutex can reduce the possibility of contention. Because a latch protects multiple objects, it can become a bottleneck when processes attempt to access any of these objects concurrently. By serializing access to an individual object rather than a group, a mutex increases availability. (2)A mutex consumes less memory than a latch. (3)When in shared mode, a mutex permits concurrent reference by multiple Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 sessions. 3. Internal Locks Internal locks are higher-level, more complex mechanisms than latches and mutexes and serve various purposes. The database uses the following types of internal locks: (1)Dictionary cache locks These locks are of very short duration and are held on entries in dictionary caches while the entries are being modified or used. They guarantee that statements being parsed do not see inconsistent object definitions. Dictionary cache locks can be shared or exclusive. Shared locks are released when the parse is complete, whereas exclusive locks are released when the DDL operation is complete. (2)File and log management locks These locks protect various files. For example, an internal lock protects the control file so that only one process at a time can change it. Another lock coordinates the use and archiving of the online redo log files. Data files are locked to ensure that multiple instances mount a database in shared mode or that one instance mounts it in exclusive mode. Because file and log locks indicate the status of files, these locks are necessarily held for a long time. (3)Tablespace and undo segment locks These locks protect tablespaces and undo segments. For example, all instances accessing a database must agree on whether a tablespace is online or offline. Undo segments are locked so that only one database instance can write to a segment. 1.4.2 死锁 A situation in which two or more users are waiting for data locked by each other. Such deadlocks are rare in Oracle Database. 定义: 当两个用户希望持有对方的资源时就会发生死锁. 即两个用户互相等待对方释放资源时,oracle 认定为产生了死锁,在这种情 况下,将以牺牲一个用户作为代价,另一个用户继续执行,牺牲的用户的事务将 回滚. 例子: 1:用户 1 对 A 表进行 Update,没有提交。 2:用户 2 对 B 表进行 Update,没有提交。 此时双反不存在资源共享的问题。 3:如果用户 2 此时对 A 表作 update,则会发生阻塞,需要等到用户一的事物结束。 4:如果此时用户 1 又对 B 表作 update,则产生死锁。此时 Oracle 会选择其中一 个用户进行会滚,使另一个用户继续执行操作。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 起因: Oracle 的死锁问题实际上很少见,如果发生,基本上都是不正确的程序设计 造成的,经过调整后,基本上都会避免死锁的发生。 在 Oracle 系统中能自动发现死锁,并选择代价最小的,即完成工作量最少的 事务予以撤消,释放该事务所拥有的全部锁,记其它的事务继续工作下去。 从系统性能上考虑,应该尽可能减少资源竞争,增大吞吐量,因此用户在给 并发操作加锁时,应注意以下几点: 1、对于 UPDATE 和 DELETE 操作,应只锁要做改动的行,在完成修改后 立即提交。 2、当多个事务正利用共享更新的方式进行更新,则不要使用共享封锁,而 应采用共享更新锁,这样其它用户就能使用行级锁,以增加并行性。 3、尽可能将对一个表的操作的并发事务施加共享更新锁,从而可提高并行 性。 4、在应用负荷较高的期间,不宜对基础数据结构(表、索引、簇和视图) 进行修改 如果死锁不能自动释放,就需要我们手工的 kill session。 步骤如下: 1. 查看有无死锁对象,如有 kill session /* Formatted on 2010/8/18 9:51:59 (QP5 v5.115.810.9015) */ SELECT 'alter system kill session ''' || sid || ',' || serial# || ''';' "Deadlock" FROM v$session WHERE sid IN (SELECT sid FROM v$lock WHERE block = 1); 如果有,会返回类似与如下的信息: alter system kill session '132,731'; alter system kill session '275,15205'; alter system kill session '308,206'; alter system kill session '407,3510'; kill session: 执行 alter system kill session '391,48398'(sid 为 391); 注意: 应当注意对于 sid 在 100 以下的应当谨慎,可能该进程对应某个 application,如对应某个事务,可以 kill. 2. 查看导致死锁的 SQL Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 /* Formatted on 2010/8/18 0:06:11 (QP5 v5.115.810.9015) */ SELECT s.sid, q.sql_text FROM v$sqltext q, v$session s WHERE q.address = s.sql_address AND s.sid = &sid -- 这个&sid 是第一 步查询出来的 ORDER BY piece; 返回: SID SQL_TEXT ---------- ---------------------------------------------------------------- 77 UPDATE PROFILE_USER SET ID=1,COMPANY_ID=2,CUSTOMER_ID=3,NAMED 77 _INSURED_ID=4,LOGIN=5,ROLE_ID=6,PASSWORD=7,EMAIL=8,TIME_ZON 77 E=9 WHERE PROFILE_USER.ID=:34 3 rows selected. 3. 查看谁锁了谁 /* Formatted on 2010/8/18 0:07:49 (QP5 v5.115.810.9015) */ SELECT s1.username || '@' || s1.machine || ' ( SID=' || s1.sid || ' ) is blocking ' || s2.username || '@' || s2.machine || ' ( SID=' || s2.sid || ' ) ' AS blocking_status FROM v$lock l1, v$session s1, v$lock l2, v$session s2 WHERE s1.sid = l1.sid AND s2.sid = l2.sid AND l1.BLOCK = 1 AND l2.request > 0 AND l1.id1 = l2.id1 AND l2.id2 = l2.id2; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 或者 /* Formatted on 2010/8/18 0:03:46 (QP5 v5.115.810.9015) */ SELECT /*+ rule */ LPAD (' ', DECODE (l.xidusn, 0, 3, 0)) || l.oracle_username User_name, o.owner, o.object_name, o.object_type, s.sid, s.serial# FROM v$locked_object l, dba_objects o, v$session s WHERE l.object_id = o.object_id AND l.session_id = s.sid ORDER BY o.object_id, xidusn DESC 1.4.3 锁 和 阻塞 1.4.3.1 相关概念 通常来讲,系统如果平时运行正常,突然会停止不动,多半是被阻塞(Blocked) 住了。 我们可以通过 v$lock 这张视图,看查看阻塞的信息。 SQL> desc v$lock; 名称 是否为空? 类型 ----------------------------------------- -------- ----------------- ADDR RAW(4) KADDR RAW(4) SID NUMBER TYPE VARCHAR2(2) ID1 NUMBER ID2 NUMBER LMODE NUMBER REQUEST NUMBER CTIME NUMBER BLOCK NUMBER Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 我们关注的比较多的是 request 和 block 字段。 如果某个 request 列是一个非 0 值,那么它就是在等待一个锁。 如果 block 列是 1,这个 SID 就持有了一个锁,并且阻塞别人获得这个锁。 这个锁的类型由 TYPE 字段定义。锁的模式有 LMODE 字段定义,ID1 和 ID2 字段定义了这个锁的相 关信息。ID1 相同,就代表指向同一个资源。 这样就有可能有加锁者和等待者。 LMODE 的 6 中模式参考上面的 TM 锁类型表。 可以结合 v$lock 和 v$session 视图来查询相关的信息: /* Formatted on 2010/8/18 10:03:08 (QP5 v5.115.810.9015) */ SELECT sn.username, m.SID, sn.SERIAL#, m.TYPE, DECODE (m.lmode, 0, 'None', 1, 'Null', Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 2, 'Row Share', 3, 'Row Excl.', 4, 'Share', 5, 'S/Row Excl.', 6, 'Exclusive', lmode, LTRIM (TO_CHAR (lmode, '990'))) lmode, DECODE (m.request, 0, 'None', 1, 'Null', 2, 'Row Share', 3, 'Row Excl.', 4, 'Share', 5, 'S/Row Excl.', 6, 'Exclusive', request, LTRIM (TO_CHAR (m.request, '990'))) request, m.id1, m.id2 FROM v$session sn, v$lock m WHERE (sn.SID = m.SID AND m.request != 0) --存在锁请求,即被阻塞 OR (sn.SID = m.SID --不存在锁请求,但是锁定的对象被其他会话请求锁定 AND m.request = 0 AND lmode != 4 AND (id1, id2) IN (SELECT s.id1, s.id2 FROM v$lock s WHERE request != 0 AND s.id1 = m.id1 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 AND s.id2 = m.id2)) ORDER BY id1, id2, m.request; 或者 /* Formatted on 2010/8/18 0:03:02 (QP5 v5.115.810.9015) */ SELECT /*+ rule */ s .username, DECODE (l.TYPE, 'TM', 'TABLE LOCK', 'TX', 'ROW LOCK', NULL) lock_level, o.owner, o.object_name, o.object_type, s.sid, s.serial#, s.terminal, s.machine, s.program, s.osuser FROM v$session s, v$lock l, dba_objects o WHERE l.sid = s.sid AND l.id1 = o.object_id(+) AND s.username IS NOT NULL 1.4.3.2 引起阻塞的几种常见情况 (1)DML 语句引起阻塞 (2)外键没有创建索引 1.4.3.2.1 DML 语句 当一个会话保持另一个会话正在请求的资源上的锁定时,就会发生阻塞。被 阻塞的会话将一直挂起,直到持有锁的会话放弃锁定的资源为止。 4 个常见的 dml 语句会产生阻塞: (1)INSERT (2)UPDATE (3)DELETE (4)SELECT…FOR UPDATE INSERT Insert 发生阻塞的唯一情况就是用户拥有一个建有主键约束的表。当 2 个的 会话同时试图向表中插入相同的数据时,其中的一个会话将被阻塞,直到另外一 个会话提交或会滚。一个会话提交时,另一个会话将收到主键重复的错误。回滚 时,被阻塞的会话将继续执行。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Update 和 Delete UPDATE 和 DELETE 当执行 Update 和 delete 操作的数据行已经被另外的会 话锁定时,将会发生阻塞,直到另一个会话提交或会滚。 Select …for update 当一个用户发出 select..for update 的错作准备对返回的结果集进行修改时,如 果结果集已经被另一个会话锁定,此时 Oracle 已经对返回的结果集上加了排它 的行级锁,所有其他对这些数据进行的修改或删除操作都必须等待这个锁的释放 (操作 commit 或 rollback.),产生的外在现象就是其他的操作将发生阻塞. 同样这个查询的事务将会对该表加表级锁,不允许对该表的任何 ddl 操作, 否则将会报出 Ora-00054:resource busy and acquire with nowait specified. 可以通过发出 select„ for update nowait 的语句来避免发生阻塞,如果资源 已经被另一个会话锁定,则会返回以下错误:Ora-00054:resource busy and acquire with nowait specified. 1.4.3.2.2 外键没有创建索引 如果系统中有主,外键引用关系,并且满足一下三个条件中的任意一个,那 么就应该考虑给外键字段创建索引,否则系统的性能可能会下降甚至阻塞。 (1) 主表上有频繁的删除操作 (2) 主键上有频繁的修改操作。 (3) 业务上经常会出现主表和从表做关联查询的情况。 第一和第二个条件操作的时候,主表会在从表上创建一个锁定,以保证主表 主键的修改不会导致从表的数据在引用上出现问题,这是一个数据引用完整性的 要求。 如果主表上经常出现这样的删除或者是对主键列进行修改的操作,或者 每次操作的记录数很多,都将会造成从表长时间被锁定,而影响其他用户的正常 操作。 比如主表每次删除 1000 行数据,它就需要扫描从表 1000 次,以确定每 一行记录的改变都不会造成从表数据在引用上的不完整。 特别是在 OLAP 系统中,从表经常会是非常巨大的表,在这种情况下,如果 从表没有索引,那么查询几乎是不可想象的。 Oracle OLAP 与 OLTP 介绍 http://blog.csdn.net/tianlesoftware/archive/2010/08/08/5794844.aspx 1.4.4 Latch 说明 1.4.4.1 Latch Latch 属于 System Lock, 用于保护 SGA区中共享数据结构的一种串行化锁定 机制。Latch 的实现是与操作系统相关的,尤其和一个进程是否需要等待一个 latch、需要等待多长时间有关。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Latch 是 Oracle 提供的轻量级锁资源,是一种能够极快地被获取和释放的锁, 能快速,短时间的锁定资源,防止多个并发进程同时修改访问某个共享资源,它 只工作在 SGA 中,通常用于保护描述 buffer cache 中 block 的数据结构。 比如 SGA 中,各种数据被反复从磁盘读取到内存,又被重新写回到磁盘上, 如果有并发的用户做相同的事情,Oracle 必须使用一种机制,来保证数据在读取 的时候,只能由一个会话来完成,这种保护机制就是 Latch。 并发(concurrency): 是说有超过两个以上的用户对同样的数据做修改(可 能包括插入,删除和修改)。 并行(parallel): 是说将一件事情分成很多小部分,让每一部分同时执行, 最后将执行结果汇总成最终结果。 与每个 latch 相联系的还有一个清除过程,当持有 latch 的进程成为死进程时, 该清除过程就会被调用。Latch 还具有相关级别,用于防止死锁,一旦一个进程 在某个级别上得到一个 latch,它就不可能再获得等同或低于该级别的 latch。 Latch 不会造成阻塞,只会导致等待。 阻塞是一种系统设计上的问题,等待 是一种系统资源争用的问题。 1.4.4.2 有关 SPin 的说明 比如数据缓存中的某个块要被读取,我们会获得这个块的 latch,这个过程 叫做 spin,另外一个进程恰好要修改这个块,他也要 spin 这个块,此时他必须等 待,当前一个进程释放 latch 后才能 spin 住,然后修改,如果多个进程同时请求 的话,他们之间将出现竞争,没有一个入队机制,一旦前面进程释放所定,后面 的进程就蜂拥而上,没有先来后到的概念,并且这一切都发生的非常快,因为 Latch 的特点是快而短暂。 SPIN 与休眠(sleep): 休眠意味着暂时的放弃 CPU,进行上下文切换(context switch),这样 CPU 要 保存当前进程运行时的一些状态信息,比如堆栈,信号量等数据结构,然后引入 后续进程的状态信息,处理完后再切换回原来的进程状态,这个过程如果频繁的 发生在一个高事务,高并发进程的处理系统里面,将是个很昂贵的资源消耗,所 以 Oracle 选择了 spin,让进程继续占有 CPU,运行一些空指令,之后继续请求, 继续 spin,直到达到_spin_count 值,这时会放弃 CPU,进行短暂的休眠,再继 续刚才的动作。 1.4.4.3 进程获取 Latch 的过程 任何时候,只有一个进程可以访问内存中的某一个数据块,如果进程因为别 的进程正占用块而无法获得 Latch 时,他会对 CPU 进行一次 spin(旋转),时间非 常的短暂,spin 过后继续获取,不成功仍然 spin,直到 spin 次数到达阀值限制(这 个由隐含参数_spin_count 指定),此时进程会停止 spin,进行短期的休眠,休眠过 后会继续刚才的动作,直到获取块上的 Latch 为止。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 进程休眠的时间也是存在算法的,他会随着 spin 次数而递增,以厘秒为单位, 如 1,1,2,2,4,4,8,8,。。。休眠的阀值限制由隐含参数_max_exponential_sleep 控制,默认是 2 秒,如果当前进程已经占用了别的 Latch,则他的休眠时间不会 太长(过长会引起别的进程的 Latch 等待),此时的休眠最大时间有隐含参数 _max_sleep_holding_latch 决定,默认是 4 厘秒。这种时间限制的休眠又称为短期 等待。 另外一种情况是长期等待锁存器(Latch Wait Posting),此时等待进程请求 Latch 不成功,进入休眠,他会向锁存器等待链表(Latch Wait List)压入一条信号, 表示获取 Latch 的请求,当占用进程释放 Latch 时会检查 Latch Wait List,向请求 的进程传递一个信号,激活休眠的进程。Latch Wait List 是在 SGA 区维护的一个 进程列表,他也需要 Latch 来保证其正常运行,默认情况下 share pool latch 和 library cache latch 是采用这个机制。 如果将隐含参数_latch_wait_posting 设置为 2,则所有 Latch 都采用这种等待 方式,使用这种方式能够比较精确的唤醒某个等待的进程,但维护 Latch Wait List 需要系统资源,并且对 Latch Wait List 上 Latch 的竞争也可能出现瓶颈。 如果一个进程请求,旋转,休眠 Latch 用了很长时间,他会通知 PMON 进 程,查看 Latch 的占用进程是否已经意外终止或死亡,如果是则 PMON 会清除 释放占用的 Latch 资源。 总之, Latch 获取的流程:请求-SPIN-休眠-请求-SPIN-休眠 ... ... 占用。 1.4.4.4 Latch 和 Lock 从某种意义上说,Latch 是内存中的资源锁,数据库对象(表,索引等)的锁叫 Lock。 Latch 和 Lock 的区别: (1). Latch 是对内存数据结构提供互斥访问的一种机制,而 Lock 是以不同 的模式来套取共享资源对象,各个模式间存在着兼容或排斥,从这点看出,Latch 的访问,包括查询也是互斥的,任何时候,只能有一个进程能 pin 住内存的某一 块,幸好这个过程是相当的短暂,否则系统性能将没的保障,从 9I 开始,允许 多个进程同时查询相同的内存块。 (2). Latch 只作用于内存中,他只能被当前实例访问,而 Lock 作用于数据 库对象,在 RAC 体系中实例间允许 Lock 检测与访问 (3). Latch 是瞬间的占用,释放,Lock 的释放需要等到事务正确的结束, 他占用的时间长短由事务大小决定 (4). Latch 是非入队的,而 Lock 是入队的 (5). Latch 不存在死锁,而 Lock 中存在。 1.4.4.5 Latch 争用 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 如果发现系统中经常由于 Lock 导致用户等待,这时需要考虑系统在逻辑设 计上是否有问题,比如多用户对主键的删除或者修改,是否有用户使用 select „ for update 这样的语法,外键是否创建索引的因素。 这些因素是需要结合系统的 业务逻辑性来进行数据库对象设计的。 如果发现系统慢是因为很多的 Latch 争用,就要考虑系统及数据库自身设计 上是否存在问题,比如是否使用绑定变量,是否存在热快,数据存储参数设计是 否合理等因素。 导致 Latch 争用而等待的原因非常多,内存中很多资源都可能存在争用。 最 常见的两类 latch 争用如下: (1)共享池中的 Latch 争用。 (2)数据缓冲池中的 latch 争用。 1.4.4.5.1 共享池中的 Latch 争用 共享池中如果存在大量的 SQL 被反复分析,就会造成很大的 Latch 争用和长 时间的等待,最常见的现象就是没有绑定变量。 最常见的集中共享池里的 Latch 是 library cache。 可以通过一下 SQL 来查 询: SQL> select * from v$latchname where name like 'library cache%'; LATCH# NAME HASH ---------- -------------------------------------------------- ---------- 217 library cache 3055961779 218 library cache lock 916468430 219 library cache pin 2802704141 220 library cache pin allocation 4107073322 221 library cache lock allocation 3971284477 222 library cache load lock 2952162927 223 library cache hash chains 1130479025 在分析系统性能时,如果看到有 library cache 这样的 Latch 争用,就可以断 定是共享池中出现了问题,这种问题基本是由 SQL 语句导致的,比如没有绑定 变量或者一些存储过程被反复分析。 资源的争用可以通过如下 SQL 来查看: SQL> select event,count(*) from v$session_wait group by event; EVENT COUNT(*) ---------------------------------------------------------------- ---------- Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL*Ne tmessage from client 4 Streams AQ: waiting for messages in the queue 1 ASM background timer 1 gcs remote message 1 ges remote message 1 jobq slave wait 1 rdbms ipc message 14 smon timer 1 pmon timer 1 Streams AQ: qmn slave idle wait 1 class slave wait 1 SQL*Net message to client 1 Streams AQ: waiting for time management or cleanup tasks 1 Streams AQ: qmn coordinator idle wait 1 DIAG idle wait 1 15 rows selected. 1.4.4.5.2 数据缓冲池 Latch 争用 访问频率非常高的数据块被称为热快(Hot Block),当很多用户一起去访问 某几个数据块时,就会导致一些 Latch 争用,最常见的 latch 争用有: (1) buffer busy waits (2) cache buffer chain 这两个 Latch 的争用分别发生在访问数据块的不同时刻。 Cache buffer chian 产生原因: 当一个会话需要去访问一个内存块时,它首先要去一个像链表一样的结构中 去搜索这个数据块是否在内存中,当会话访问这个链表的时候需要获得一个 Latch,如果获取失败,将会产生 Latch cache buffer chain 等待,导致这个等待的 原因是访问相同的数据块的会话太多或者这个列表太长(如果读到内存中的数据 太多,需要管理数据块的 hash 列表就会很长,这样会话扫描列表的时间就会增 加,持有 chache buffer chain latch 的时间就会变长,其他会话获得这个 Latch 的 机会就会降低,等待就会增加)。 Buffer busy waits 产生原因: 当一个会话需要访问一个数据块,而这个数据块正在被另一个用户从磁盘读 取到内存中或者这个数据块正在被另一个会话修改时,当前的会话就需要等待, 就会产生一个 buffer busy waits 等待。 产生这些 Latch 争用的直接原因是太多的会话去访问相同的数据块导致热快 问题,造成热快的原因可能是数据库设置导致或者重复执行的 SQL 频繁访问一 些相同的数据块导致。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Latch 是简单的、低层次的序列化技术,用以保护 SGA 中的共享数据结构, 比如并发用户列表和 buffer cache 里的 blocks 信息。一个服务器进程或后台进程 在开始操作或寻找一个共享数据结构之前必须获得对应的 latch,在完成以后释 放 latch。不必对 latch 本身进行优化,如果 latch 存在竞争,表明 SGA 的一部分 正在经历不正常的资源使用。 1.4.4.6 热块产生的原因 热快产生的原因不尽相同,按照数据块的类型,可以分成一下几种类型,不 同热快类型处理的方式都是不同的。 (1) 表数据块 (2) 索引数据块 (3) 索引根数据块 (4) 文件头数据块 1.4.4.6.1 表数据块 比如在 OLTP 系统中,对于一些小表,会给出某些数据块被频繁查询或者修 改的操作,这时候,这些被频繁访问的数据块就会变成热块,导致内存中 Latch 争用。 如果出现这样热块的情况,并且表不太大,一个方法是可以考虑将表数据分 布在更多的数据块上,减少数据块被多数会话同时访问的频率。 可以通过一下命令将每个数据块存放记录的数量减少到最少: Alter table minimize records_per_block; 我们把数据分布到更多的数据块上,大大降低了一个数据块被重复读取的概 率。 但是这种方法的缺点很明显,就是降低了数据的性能,在这种情况下,访 问相同的数据意味着需要读取更多的数据块,性能会有所降低。 1.4.4.6.2 索引数据块 这样的情况通常发生在一个 RAC 架构里,某个表的索引键值出现典型的“右 倾”现象,比如一个表的主键使用一个序列来生成键值,那么在这个主键在索引 数据块上的键值就是以一种顺序递增的方式排列的,比如:1,2,3,4,5…., 由于这些键值分布得非常接近,当许多用户在 RAC 的不同实例来向表中插入主 键时,就会出现相同的索引数据块在不同实例的内存中被调用,形成一种数据块 的争用,对于这种情况,使用反向索引可以缓解这种争用。 反向索引是将从前 的索引键值按照反向的方式排列,在正常的主键 B-Tree 索引中,键值会按照大 小的顺序排列,比如:1234,反向索引,键值就变成 4321. 这样,本来是放在相同的索引数据块上的键值,现在分布熬不同的数据块上, 这样用户在 RAC 不同的实例上插入的主键值因为分布在不同的数据块上,所以 不会导致热块的产生,这基本是反向索引被使用的唯一情况。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 反向索引使用场合之所以如此受限制,是因为它丢弃了 B-Tree 索引的一个 最重要的功能: Index range scan 索引访问方式中,这个方式最常见,但是反向索引却不能使用这个功能,因 为反向索引已经把键值的排列顺序打乱,当按照键值顺序查找一个范围时,在反 向索引中,由于键值被反向存储,这些值已经不是连续存放的了。 所以 Index range scan 的方式在反向索引中没有任何意义。在反向索引中只能通过全表扫描 或者全索引扫描的方式来实现。 这就是反向索引的一个非常严重的缺陷。 1.4.4.6.3 索引根数据块 热块也可能发生在索引的根数据块上。 在 B-Tree 索引里,当 Oracle 访问一 个索引键值时,首先访问索引的根,然后是索引的分支,最后才是索引的叶块。 索引的键值就是存储在叶块上面。 如图: 当索引的根,枝数据都集中在几个数据块上时,比如 D,G 所在的枝数据块, 当用户访问的范围从 A-F,都会访问这个数据块,如果很多用户频繁的访问这个 范围的索引键值,有可能导致这个枝数据块变成热快。 当出现这种现象时,可以考虑对索引做分区,以便于使用这些根,枝数据块 分布到不同的数据段(分区)上,减少数据块的并行访问的密度,从而避免由于 索引根,枝数据块太集中导致热块产生。 1.4.4.6.4 段头数据块 在 Oracle 9i 之前,数据块的空间使用情况需要手工来管理,在每个数据段 的段头有一个或者几个 Free list 列表,用于存放段中哪些数据块可以使用。 当数据块的数据达到数据块总容量的一个比例时(PCT_FREE 参数决定), 数据块就会从 Free list 中删除,这个数据块就不能在插入数据。 当数据块的空间减少到一个比例时(PCT_USED 参数决定),数据块就会被 放到 Free list 列表中,这些数据库可以被用来插入数据。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 在 OLTP 系统中,一些数据段的 Free List 可能会是一个访问很频繁的数据块, 比如这个数据库上有些表有很多删除,插入的动作,很多会话需要不断访问这些 数据块的 Free List 列表,以便获得需要的数据块信息。 此时这个数据块(称作 段头数据块)就会变成一个热块,此时内存中就会出现如 cacha buffer chain 这样 的 Latch 等待事件。 当出现这个问题时,一个常见的解决方法是增加 Free List 的数量,以便于分 散会话访问数据块的密度。 从 Oracle 9i 开始,引入了一个自动段管理的技术 ASSM(Automatic Segment Space Management: ASSM),它让 Oracle 自动管理“Free List”。 实际上在 ASSM 里,已经没有 Free List 这样的结构,Oracle 使用位图方式来标记数据块是否可 用,这种数据块的空间管理方式比用一个列表来管理效率更高。 对于 OLTP 系统,表的 DML 操作非常密集,对于这些表,使用 ASSM 方式 来管理会比人工管理更加方便和准确,能有效的避免段头变成热块。 对于 OLAP 系统,这个参数并没有太大的实际意义,因为在这样的数据库中, 很少有表发生频繁的修改,OLAP 系统主要的工作是报表和海量数据的批量加 载。 1.4.4.7 检查 Latch 的相关 SQL 1.4.4.7.1 查看造成 LATCH BUFFER CACHE CHAINS 等待事件的热快 SELECT DISTINCT a.owner, a.segment_name FROM dba_extents a, (SELECT dbarfil, dbablk FROM x$bh WHERE hladdr IN (SELECT addr FROM ( SELECT addr FROM v$latch_children ORDER BY sleeps DESC) WHERE ROWNUM < 20)) b WHERE a.RELATIVE_FNO = b.dbarfil AND a.BLOCK_ID <= b.dbablk AND a.block_id + a.blocks > b.dbablk; 1.4.4.7.2 查询当前数据库最繁忙的 Buffer,TCH(Touch)表示访问次数越高,热 点快竞争问题就存在 SELECT * FROM ( SELECT addr, Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 ts#, file#, dbarfil, dbablk, tch FROM x$bh ORDER BY tch DESC) WHERE ROWNUM < 11; 1.4.4.7.3 查询当前数据库最繁忙的 Buffer,结合 dba_extents 查询得到这些热点 Buffer 来自哪些对象 SELECT e.owner, e.segment_name, e.segment_type FROM dba_extents e, (SELECT * FROM (SELECT addr, ts#, file#, dbarfil, dbablk, tch FROM x$bh ORDER BY tch DESC) WHERE ROWNUM < 11) b WHERE e.relative_fno = b.dbarfil AND e.block_id <= b.dbablk AND e.block_id + e.blocks > b.dbablk; 1.4.4.7.4 如果在 Top 5 中发现 latch free 热点块事件时,可以从 V$latch_children 中查询具体的子 Latch 信息 SELECT * FROM (SELECT addr, child#, gets, misses, sleeps, immediate_gets igets, immediate_misses imiss, spin_gets sgets FROM v$latch_children WHERE NAME = 'cache buffers chains' ORDER BY sleeps DESC) WHERE ROWNUM < 11; 1.4.4.7.5 获取当前持有最热点数据块的 Latch 和 buffer 信息 SELECT b.addr, a.ts#, a.dbarfil, a.dbablk, a.tch, b.gets, b.misses, b.sleeps FROM (SELECT * FROM (SELECT addr, ts#, file#, dbarfil, dbablk, tch, hladdr FROM x$bh ORDER BY tch DESC) Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 WHERE ROWNUM < 11) a, (SELECT addr, gets, misses, sleeps FROM v$latch_children WHERE NAME = 'cache buffers chains') b WHERE a.hladdr = b.addr; 1.4.4.7.6 利用前面的 SQL 可以找到这些热点 Buffer 的对象信息 SELECT distinct e.owner, e.segment_name, e.segment_type FROM dba_extents e, (SELECT * FROM (SELECT addr, ts#, file#, dbarfil, dbablk, tch FROM x$bh ORDER BY tch DESC) WHERE ROWNUM < 11) b WHERE e.relative_fno = b.dbarfil AND e.block_id <= b.dbablk AND e.block_id + e.blocks > b.dbablk; 1.4.4.7.7 结合 SQL 视图可以找到操作这些对象的相关 SQL,然后通过优化 SQL 减少数据的访问,或者优化某些容易引起争用的操作(如 connect by 等操作) 来减少热点块竞争 break on hash_value skip 1 SELECT /*+ rule */ hash_value,sql_text FROM v$sqltext WHERE (hash_value, address) IN ( SELECT a.hash_value, a.address FROM v$sqltext a, (SELECT DISTINCT a.owner, a.segment_name, a.segment_type FROM dba_extents a, (SELECT dbarfil, dbablk FROM (SELECT dbarfil, dbablk FROM x$bh ORDER BY tch DESC) WHERE ROWNUM < 11) b WHERE a.relative_fno = b.dbarfil AND a.block_id <= b.dbablk AND a.block_id + a.blocks > b.dbablk) b WHERE a.sql_text LIKE '%' || b.segment_name || '%' AND b.segment_type = 'TABLE') ORDER BY hash_value, address, piece; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.5 等待事件 1.5.1 等待事件的相关知识 1.5.1.1 等待事件分类 等待事件主要可以分为两类,即空闲(IDLE)等待事件和非空闲(NON-IDLE) 等待事件。 1). 空闲等待事件指ORACLE正等待某种工作,在诊断和优化数据库的时候, 不用过多注意这部分事件。 2). 非空闲等待事件专门针对 ORACLE 的活动,指数据库任务或应用运行过 程中发生的等待,这些等待事件是在调整数据库的时候需要关注与研究的。 在 Oracle 10g 中的等待事件有 872 个,11g 中等待事件 1116 个。 我们可以 通过 v$event_name 视图来查看等待事件的相关信息。 1.5.1.2 查看 v$event_name 视图的字段结构 SQL> desc v$event_name; 名称 是否为空? 类型 ----------------------------------------- -------- --------------- EVENT# NUMBER EVENT_ID NUMBER NAME VARCHAR2(64) PARAMETER1 VARCHAR2(64) PARAMETER2 VARCHAR2(64) PARAMETER3 VARCHAR2(64) WAIT_CLASS_ID NUMBER WAIT_CLASS# NUMBER WAIT_CLASS VARCHAR2(64) 1.5.1.3 查看等待事件总数 SQL> select count(*) from v$event_name; COUNT(*) ---------- 1116 1.5.1.4 查看等待事件分类情况 /* Formatted on 2010/8/11 16:08:55 (QP5 v5.115.810.9015) */ SELECT wait_class#, wait_class_id, wait_class, COUNT ( * ) AS "count" Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 FROM v$event_name GROUP BY wait_class#, wait_class_id, wait_class ORDER BY wait_class#; WAIT_CLASS# WAIT_CLASS_ID WAIT_CLASS count ----------- ------------- -------------------- ---------- 0 1893977003 Other 717 1 4217450380 Application 17 2 3290255840 Configuration 24 3 4166625743 Administrative 54 4 3875070507 Concurrency 32 5 3386400367 Commit 2 6 2723168908 Idle 94 7 2000153315 Network 35 8 1740759767 User I/O 45 9 4108307767 System I/O 30 10 2396326234 Scheduler 7 11 3871361733 Cluster 50 12 644977587 Queueing 9 1.5.1.5 相关的几个视图 V$SESSION: 代表数据库活动的开始,视为源起。 V$SESSION_WAIT: 视图用以实时记录活动 SESSION 的等待情况,是当前信 息。 V$SESSION_WAIT_HISTORY: 是对 V$SESSION_WAIT 的简单增强,记录活 动 SESSION 的最近 10 次等待。 V$SQLTEXT: 当数据库出现瓶颈时,通常可以从 V$SESSION_WAIT 找到那 些正在等待资源的 SESSION,通过 SESSION 的 SID,联合 V$SESSION 和 V$SQLTEXT 视图就可以捕获这些 SESSION 正在执行的 SQL 语句。 V$ACTIVE_SESSION_HISTORY: 是 ASH 的核心,用以记录活动 SESSION 的历 史等待信息,每秒采样一次,这部分内容记录在内存中,期望值是记录一个小时 的内容。 WRH#_ACTIVE_SESSION_HISTORY : 是 V$ACTIVE_SESSION_HISTORY 在 AWR 的存储地。 V$ACTIVE_SESSION_HISTORY: 中的信息会被定期(每小时一次)的刷新到负载 库中,并缺省保留一个星期用于分析。 DBA_HIST_ACTIVE_SESS_HISTORY: 视图是 WRH#_ACTIVE_SESSION_HISTORY 视图和其他几个视图的联合展现,通常通 过这个视图进行历史数据的访问。 V$SYSTEM_EVENT 由于 V$SESSION 记录的是动态信息,和 SESSION 的生命 周期相关,而并不记录历史信息,所以 ORACLE 提供视图 V$SYSTEM_EVENT 来记录数据库自启动以来所有等待事件的汇总信息。通过这个视图,用户可以迅 速获得数据库运行的总体概况。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.5.2 33 个常见的等待事件 1.5.2.1 Buffer busy waits 从本质上讲,这个等待事件的产生仅说明了一个会话在等待一个 Buffer(数 据块),但是导致这个现象的原因却有很多种。常见的两种是: 当一个会话视图修改一个数据块,但这个数据块正在被另一个会话修改时。 当一个会话需要读取一个数据块,但这个数据块正在被另一个会话读取到内 存中时。 Oracle 操作的最小单位是块(Block),即使你要修改一条记录,也需要对这 条记录所在的这个数据块做操作。 当你对这个数据块做修改时,其他的会话将 被阻止对这个数据块上的数据做修改(即使其他用户修改的不是当前用户修改的 数据),但是可以以一致性的方式读取这个数据块(from undo)。当前的用户修 改完这个数据块后,将会立即释放掉加在这个数据块上的排他锁,这样另一个会 话就可以继续修改它。 修改操作是一个非常短暂的时间,这种加锁的机制我们 叫 Latch。 当一个会话修改一个数据块时,是按照以下步骤来完成的: (1)以排他的方式获得这个数据块(Latch) (2)修改这个数据块。 (3)释放 Latch。 Buffer busy waits 等待事件常见于数据库中存在的热快的时候,当多个用户频 繁地读取或者修改同样的数据块时,这个等待事件就会产生。 如果等待的时间 很长,我们在 AWR 或者 statspack 报告中就可以看到。 这个等待事件有三个参数。 查看有几个参数我们可以用以下 SQL: SQL> select name, parameter1, parameter2, parameter3 from v$event_name where name='buffer busy waits'; NAME PARAMETER1 PARAMETER2 PARAMETER3 -------------------- ---------- ---------- ---------- buffer busy waits file# block# class# 在下面的示例中,查询的方法和这个一样,所以其他事件对参数的查询将不 做过多的说明。 File#: 等待访问数据块所在的文件 id 号。 Blocks: 等待访问的数据块号。 ID: 在 10g 之前,这个值表示一个等待时间的原因,10g 之后则表示等待事件 的类别。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.5.2.2 Buffer latch 内存中数据块的存放位置是记录在一个 hash 列表(cache buffer chains)当中 的。 当一个会话需要访问某个数据块时,它首先要搜索这个 hash 列表,从列表 中获得数据块的地址,然后通过这个地址去访问需要的数据块,这个列表 Oracle 会使用一个 latch 来保护它的完整性。 当一个会话需要访问这个列表时,需要获 取一个 Latch,只有这样,才能保证这个列表在这个会话的浏览当中不会发生变 化。 产生 buffer latch 的等待事件的主要原因是: (1)Buffer chains 太长,导致会话搜索这个列表花费的时间太长,使其他的 会话处于等待状态。 (2)同样的数据块被频繁访问,就是我们通常说的热快问题。 产生 buffer chains 太长,我们可以使用多个 buffer pool 的方式来创建更多的 buffer chains,或者使用参数 DB_BLOCK_LRU_LATCHES 来增加 latch 的数量, 以便于更多的会话可以获得 latch,这两种方法可以同时使用。 这个等待事件有两个参数: Latch addr: 会话申请的 latch 在 SGA 中的虚拟地址,通过以下的 SQL 语句可 以根据这个地址找到它对应的 Latch 名称: select * from v$latch a,v$latchname b where addr=latch addr -- 这里的 latch addr 是你从等待事件中看到的值 and a.latch#=b.latch#; chain#: buffer chains hash 列表中的索引值,当这个参数的值等于 s 0xfffffff 时,说明当前的会话正在等待一个 LRU latch。 1.5.2.3 Control file parallel write 当数据库中有多个控制文件的拷贝时,Oracle 需要保证信息同步地写到各个 控制文件当中,这是一个并行的物理操作过程,因为称为控制文件并行写,当发 生这样的操作时,就会产生 control file parallel write 等待事件。 控制文件频繁写入的原因很多,比如: (1)日志切换太过频繁,导致控制文件信息相应地需要频繁更新。 (2)系统 I/O 出现瓶颈,导致所有 I/O 出现等待。 当系统出现日志切换过于频繁的情形时,可以考虑适当地增大日志文件的大 小来降低日志切换频率。 当系统出现大量的 control file parallel write 等待事件时,可以通过比如降低 控制文件的拷贝数量,将控制文件的拷贝存放在不同的物理磁盘上的方式来缓解 I/O 争用。 这个等待事件包含三个参数: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Files: Oracle 要写入的控制文件个数。 Blocks: 写入控制文件的数据块数目。 Requests:写入控制请求的 I/O 次数。 1.5.2.4 Control file sequential read 当数据库需要读取控制文件上的信息时,会出现这个等待事件,因为控制文 件的信息是顺序写的,所以读取的时候也是顺序的,因此称为控制文件顺序读, 它经常发生在以下情况: (1)备份控制文件 (2)RAC 环境下不同实例之间控制文件的信息共享 (3)读取控制文件的文件头信息 (4)读取控制文件其他信息 这个等待事件有三个参数: File#:要读取信息的控制文件的文件号。 Block#: 读取控制文件信息的起始数据块号。 Blocks:需要读取的控制文件数据块数目。 1.5.2.5 Db file parallel read 这是一个很容易引起误导的等待事件,实际上这个等待事件和并行操作(比 如并行查询,并行 DML)没有关系。 这个事件发生在数据库恢复的时候,当有 一些数据块需要恢复的时候,Oracle 会以并行的方式把他们从数据文件中读入到 内存中进行恢复操作。 这个等待事件包含三个参数: Files: 操作需要读取的文件个数。 Blocks: 操作需要读取的数据块个数。 Requests:操作需要执行的 I/O 次数。 1.5.2.6 Db file parallel write 这是一个后台等待事件,它同样和用户的并行操作没有关系,它是由后台进 程 DBWR 产生的,当后台进程 DBWR 想磁盘上写入脏数据时,会发生这个等待。 DBWR 会批量地将脏数据并行地写入到磁盘上相应的数据文件中,在这个批 次作业完成之前,DBWR 将出现这个等待事件。 如果仅仅是这一个等待事件, 对用户的操作并没有太大的影响,当伴随着出现 free buffer waits 等待事件时,说 明此时内存中可用的空间不足,这时候会影响到用户的操作,比如影响到用户将 脏数据块读入到内存中。 当出现 db file parallel write 等待事件时,可以通过启用操作系统的异步 I/O 的方式来缓解这个等待。 当使用异步 I/O 时,DBWR 不在需要一直等到所有数Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 据块全部写入到磁盘上,它只需要等到这个数据写入到一个百分比之后,就可以 继续进行后续的操作。 这个等待事件有两个参数: Requests: 操作需要执行的 I/O 次数。 Timeouts:等待的超时时间。 1.5.2.7 Db file scattered read 这个等待事件在实际生产库中经常可以看到,这是一个用户操作引起的等待 事件,当用户发出每次 I/O 需要读取多个数据块这样的 SQL 操作时,会产生这 个等待事件,最常见的两种情况是全表扫描(FTS: Full Table Scan)和索引快 速扫描(IFFS: index fast full scan)。 这个名称中的 scattered( 发散),可能会导致很多人认为它是以 scattered 的方 式来读取数据块的,其实恰恰相反,当发生这种等待事件时,SQL 的操作都是 顺序地读取数据块的,比如 FTS 或者 IFFS 方式(如果忽略需要读取的数据块已 经存在内存中的情况)。 这里的 scattered 指的是读取的数据块在内存中的存放方式,他们被读取到内 存中后,是以分散的方式存在在内存中,而不是连续的。 这个等待事件有三个参数: File#: 要读取的数据块所在数据文件的文件号。 Block#: 要读取的起始数据块号。 Blocks:需要读取的数据块数目。 1.5.2.8 Db file sequential read 这个等待事件在实际生产库也很常见,当 Oracle 需要每次 I/O 只读取单个数 据块这样的操作时,会产生这个等待事件。 最常见的情况有索引的访问(除 IFFS 外的方式),回滚操作,以 ROWID 的方式访问表中的数据,重建控制文件,对 文件头做 DUMP 等。 这里的 sequential 也并非指的是 Oracle 按顺序的方式来访问数据,和 db file scattered read 一样,它指的是读取的数据块在内存中是以连续的方式存放的。 这个等待事件有三个参数: File#: 要读取的数据块锁在数据文件的文件号。 Block#: 要读取的起始数据块号。 Blocks:要读取的数据块数目(这里应该等于 1)。 1.5.2.9 Db file single write 这个等待事件通常只发生在一种情况下,就是 Oracle 更新数据文件头信息Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 时(比如发生 Checkpoint)。 当这个等待事件很明显时,需要考虑是不是数据库中的数据文件数量太大, 导致 Oracle 需要花较长的时间来做所有文件头的更新操作(checkpoint)。 这个等待事件有三个参数: File#: 需要更新的数据块所在的数据文件的文件号。 Block#:需要更新的数据块号。 Blocks:需要更新的数据块数目(通常来说应该等于 1)。 1.5.2.10 Direct path read 这个等待事件发生在会话将数据块直接读取到 PGA 当中而不是 SGA 中的情 况,这些被读取的数据通常是这个会话私有的数据,所以不需要放到 SGA 作为 共享数据,因为这样做没有意义。 这些数据通常是来自与临时段上的数据,比 如一个会话中 SQL 的排序数据,并行执行过程中间产生的数据,以及 Hash Join, merge join 产生的排序数据,因为这些数据只对当前的会话的 SQL 操作有意义, 所以不需要放到 SGA 当中。 当发生 direct path read 等待事件时,意味着磁盘上有大量的临时数据产生, 比如排序,并行执行等操作。 或者意味着 PGA 中空闲空间不足。 这个等待事件有三个参数: Descriptor address: 一个指针,指向当前会话正在等待的一个 direct read I/O。 First dba: descriptor address 中最旧的一个 I/O 数据块地址。 Block cnt: descriptor address 上下文中涉及的有效的 buffer 数量。 1.5.2.11 Direct path write 这个等待事件和 direct path read 正好相反,是会话将一些数据从 PGA 中直 接写入到磁盘文件上,而不经过 SGA。 这种情况通常发生在: (1)使用临时表空间排序(内存不足) (2)数据的直接加载(使用 append 方式加载数据) (3)并行 DML 操作。 这个等待事件有三个参数: Descriptor address: 一个指针,指向当前会话正在等待的一个 direct I/O. First dba: descriptor address 中最旧的一个 I/O 数据块地址。 Block cnt: descriptor address 上下文中涉及的有效地 buffer 数量。 1.5.2.12 Enqueue Enqueue 这个词其实是 lock 的另一种描述语。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 当我们在 AWR 报告中发现长时间的 enqueue 等待事件时,说明数据库中出 现了阻塞和等待,可以关联 AWR 报告中的 enqueue activity 部分来确定是哪一种 锁定出现了长时间等待。 这个等待事件有 2 个参数: Name: enqueue 的名称和类型。 Mode: enqueue 的模式。 可以使用如下 SQL 查看当前会话等待的 enqueue 名称和类型: /* Formatted on 2010/8/12 11:00:56 (QP5 v5.115.810.9015) */ SELECT CHR (TO_CHAR (BITAND (p1, -16777216)) / 16777215) || CHR (TO_CHAR (BITAND (p1, 16711680)) / 65535) "Lock", TO_CHAR (BITAND (p1, 65535)) "Mode" FROM v$session_wait WHERE event = 'enqueue' Oracle 的 enqueue 包含以下模式: 模式代码 解释 1 Null mode 2 Sub-Share 3 Sub-Exclusive 4 Share 5 Share/Sub-Exclusive 6 Exclusive Oracle 的 enqueue 有如下类型: Enqueue 缩写 缩写解释 BL Buffer Cache management BR Backup/Restore CF Controlfile transaction CI Cross-instance Call Invocation CU Bind Enqueue DF Datafile DL Direct Loader Index Creation DM Database Mount DR Distributed Recovery Process DX Dirstributed Transaction FP File Object Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 FS File Set HW High-water Lock IN Instance Number IR Instance Recovery IS Instance State IV Library Cache Invalidation JI Enqueue used during AJV snapshot refresh JQ Job Queue KK Redo Log ―Kick‖ KO Multiple Object Checkpoint L[A-p] Library Cache Lock LS Log start or switch MM Mount Definition MR Media recovery N[A-Z] Library Cache bin PE Alter system set parameter =value PF Password file PI Parallel slaves PR Process startup PS Parallel slave synchronization Q[A-Z] Row Cache RO Object Reuse RT Redo Thread RW Row Wait SC System Commit Number SM SMON SN Sequence Number SQ Sequence Number Enqueue SR Synchronized replication SS Sort segment ST Space management transaction SV Sequence number Value TA Transaction recovery TC Thread Checkpoint Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 TE Extend Table TM DML enqueue TO Temporary Table Object Enqueue TS Temporary Segement(also TableSpace) TT Temporary Table TX Transaction UL User-defined Locks UN User name US Undo segment, Serialization WL Being Written Redo Log XA Instance Attribute Log XI Instance Registration Lock 关于 enqueue 可以参考如下的连接: Wait Events - Enqueue Waits http://www.toadworld.com/KNOWLEDGE/KnowledgeXpertforOracle /tabid/648/TopicID/WE1/Default.aspx 1.5.2.13 Free buffer waits 当一个会话将数据块从磁盘读到内存中时,它需要到内存中找到空闲的内存 空间来存放这些数据块,当内存中没有空闲的空间时,就会产生这个等待;除此 之外,还有一种情况就是会话在做一致性读时,需要构造数据块在某个时刻的前 映像(image),此时需要申请内存来存放这些新构造的数据块,如果内存中无法 找到这样的内存块,也会发生这个等待事件。 当数据库中出现比较严重的 free buffer waits 等待事件时,可能的原因是: (1) data buffer 太小,导致空闲空间不够 (2) 内存中的脏数据太多,DBWR 无法及时将这些脏数据写到磁盘中以释 放空间 这个等待事件包含 2 个参数: File#: 需要读取的数据块所在的数据文件的文件号。 Block#: 需要读取的数据块块号。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.5.2.14 Latch free 在 10g 之前的版本里,latch free 等待事件代表了所有的 latch 等待,在 10g 以后,一些常用的 latch 事件已经被独立了出来: SQL> select name from v$event_name where name like 'latch%' order by 1; NAME ---------------------------------------------------------------- latch activity latch free latch: Change Notification Hash table latch latch: In memory undo latch latch: MQL Tracking Latch latch: PX hash array latch latch: Undo Hint Latch latch: WCR: processes HT latch: WCR: sync latch: cache buffer handles latch: cache buffers chains latch: cache buffers lru chain latch: call allocation latch: change notification client cache latch latch: checkpoint queue latch latch: enqueue hash chains latch: gc element latch: gcs resource hash latch: ges resource hash list latch: lob segment dispenser latch latch: lob segment hash table latch latch: lob segment query latch latch: messages latch: object queue header operation latch: parallel query alloc buffer latch: redo allocation latch: redo copy latch: redo writing latch: row cache objects latch: session allocation latch: shared pool latch: undo global data latch: virtual circuit queues 已选择 33 行。 所以 latch free 等待事件在 10g 以后的版本中并不常见,而是以具体的 Latch 等待事件出现。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 这个等待事件有三个参数: Address: 会话等待的 latch 地址。 Number: latch 号,通过这个号,可以从 v$latchname 视图中找到这个 latch 的相关的信息。 SQL> select * from v$latchname where latch#=number; Tries: 会话尝试获取 Latch 的次数。 1.5.2.15 Library cache lock 这个等待时间发生在不同用户在共享中由于并发操作同一个数据库对象导致 的资源争用的时候,比如当一个用户正在对一个表做 DDL 操作时,其他的用户 如果要访问这张表,就会发生 library cache lock 等待事件,它要一直等到 DDL 操作完成后,才能继续操作。 这个事件包含四个参数: Handle address: 被加载的对象的地址。 Lock address: 锁的地址。 Mode: 被加载对象的数据片段。 Namespace: 被加载对象在 v$db_object_cache 视图中 namespace 名称。 1.5.2.16 Library cache pin 这个等待事件和 library cache lock 一样是发生在共享池中并发操作引起的事 件。通常来讲,如果 Oracle 要对一些 PL/SQL 或者视图这样的对象做重新编译, 需要将这些对象 pin 到共享池中。 如果此时这个对象被其他的用户特有,就会 产生一个 library cache pin 的等待。 这个等待事件也包含四个参数: Handle address: 被加载的对象的地址。 Lock address: 锁的地址。 Mode: 被加载对象的数据片段。 Namespace: 被加载对象在 v$db_object_cache 视图中 namespace 名称。 1.5.2.17 Log file parallel write 后台进程 LGWR 负责将 log buffer 当中的数据写到 REDO 文件中,以重用 log buffer 的数据。 如果每个 REDO LOG 组里面有 2 个以上的成员,那么 LGWR 进程会并行地将 REDO 信息写入这些文件中。 如果数据库中出现这个等待事件的瓶颈,主要的原因可能是磁盘 I/O 性能不 够或者 REDO 文件的分布导致了 I/O 争用,比如同一个组的 REDO 成员文件放 在相同的磁盘上。 这个等待事件有三个参数: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Files: 操作需要写入的文件个数。 Blocks: 操作需要写入的数据块个数。 Requests:操作需要执行的 I/O 次数。 1.5.2.18 Log buffer space 当 log buffer 中没有可用空间来存放新产生的 redo log 数据时,就会发生 log buffer space 等待事件。 如果数据库中新产生的 redo log 的数量大于 LGWR 写 入到磁盘中的 redo log 数量,必须等待 LGWR 完成写入磁盘的操作,LGWR 必 须确保 redo log 写到磁盘成功之后,才能在 redo buffer 当中重用这部分信息。 如果数据库中出现大量的 log buffer space 等待事件,可以考虑如下方法: (1) 增加 redo buffer 的大小。 (2) 提升磁盘的 I/O 性能 1.5.2.19 Log file sequential read 这个等待事件通常发生在对 redo log 信息进行读取时,比如在线 redo 的归档 操作,ARCH 进程需要读取 redo log 的信息,由于 redo log 的信息是顺序写入的, 所以在读取时也是按照顺序的方式来读取的。 这个等待事件包含三个参数: Log#: 发生等待时读取的 redo log 的 sequence 号。 Block#: 读取的数据块号。 Blocks: 读取的数据块个数。 1.5.2.20 Log file single write 这个等待事件发生在更新 redo log 文件的文件头时,当为日志组增加新的日 志成员时或者 redo log 的 sequence 号改变时,LGWR 都会更新 redo log 文件头 信息。 这个等待事件包含三个参数: Log#: 写入的 redo log 组的编号。 Block#:写入的数据块号。 Blocks:写入的数据块个数。 1.5.2.21 Log file switch(archiving needed) 在归档模式下,这个等待事件发生在在线日志切换(log file switch)时,需 要切换的在线日志还没有被归档进程(ARCH)归档完毕的时候。 当在线日志 文件切换到下一个日志时,需要确保下一个日志文件已经被归档进程归档完毕, 否则不允许覆盖那个在线日志信息(否则会导致归档日志信息不完整)。 出现这样的等待事件通常是由于某种原因导致 ARCH 进程死掉,比如 ARCHTianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 进程尝试向目的地写入一个归档文件,但是没有成功(介质失效或者其他原因), 这时 ARCH 进程就会死掉。 如果发生这种情况,在数据库的 alert log 文件中可 以找到相关的错误信息。 这个等待事件没有参数。 1.5.2.22 Log file switch(checkpoint incomplete) 当一个在线日志切换到下一个在线日志时,必须保证要切换到的在线日志上 的记录的信息(比如一些脏数据块产生的 redo log)被写到磁盘上(checkpoint), 这样做的原因是,如果一个在线日志文件的信息被覆盖,而依赖这些 redo 信息 做恢复的数据块尚未被写到磁盘上(checkpoint),此时系统 down 掉的话,Oracle 将没有办法进行实例恢复。 在 v$log 视图里记录了在线日志的状态。 通常来说,在线日志有三种状态。 Active: 这个日志上面保护的信息还没有完成 checkpoint。 Inactive: 这个日志上面保护的信息已完成 checkpoint。 Current: 当前的日志。 Oracle 在做实例恢复时,会使用状态为 current 和 Active 的日志进行实例恢复。 如果系统中出现大量的 log file switch(checkpoint incomplete)等待事件,原 因可能是日志文件太小或者日志组太少,所以解决的方法是,增加日志文件的大 小或者增加日志组的数量。 这个等待事件没有参数。 1.5.2.23 Log file sync 这是一个用户会话行为导致的等待事件,当一个会话发出一个 commit 命令 时,LGWR 进程会将这个事务产生的 redo log 从 log buffer 里面写到磁盘上,以 确保用户提交的信息被安全地记录到数据库中。 会话发出的 commit 指令后,需要等待 LGWR 将这个事务产生的 redo 成功写 入到磁盘之后,才可以继续进行后续的操作,这个等待事件就叫作 log file sync。 当系统中出现大量的 log file sync 等待事件时,应该检查数据库中是否有用 户在做频繁的提交操作。 这种等待事件通常发生在 OLTP 系统上。 OLTP 系统中存在很多小的事务, 如果这些事务频繁被提交,可能引起大量的 log file sync 的等待事件。 这个等待事件包含一个参数: Buffer#: redo buffer 中需要被写入到磁盘中的 buffer。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.5.2.24 SQL*Net break/reset to client 当出现这个等待事件时,说明服务器端在给客户端发送一个断开连接或者重 置连接的请求,正在等待客户的响应,通常的原因是服务器到客户端的网络不稳 定导致的。 这个等待事件包含两个参数: Driver id: 服务器和客户端连接使用的协议信息。 Break?:零表示服务端向客户端发送一个重置(reset)信息,非零表示 服务器端向客户端发送一个断开(break)消息。 1.5.2.25 SQL*Net break/reset to dblink 这个等待事件和 SQL*Net break/reset to client 相同。 不过它表示的是数据库 通过 dblink 访问另一台数据库时,他们之间建立起一个会话,这个等待事件发生 在这个会话之间的通信过程中,同样如果出现这个等待事件,需要检查两台数据 库之间的通信问题。 这个等待事件有两个参数: Driver id: 服务器和客户端连接使用的协议信息。 Break?:零表示服务端向客户端发送一个重置(reset)信息,非零表示 服务器端向客户端发送一个断开(break)消息。 1.5.2.26 SQL*Net message from client 这个等待事件基本上是最常见的一个等待事件。 当一个会话建立成功后,客 户端会向服务器端发送请求,服务器端处理完客户端请求后,将结果返回给客户 端,并继续等待客户端的请求,这时候会产生 SQL*Net message from client 等待 事件。 很显然,这是一个空闲等待,如果客户端不再向服务器端发送请求,服务器 端将一直处于这个等待事件状态。 这个等待事件包含两个参数: Driver id: 服务器端和客户端连接使用的协议信息。 #bytes: 服务器端接收到的来自客户端消息的字节数。 1.5.2.27 SQL*Net message from dblink 这个等待事件和 SQL*Net message from client 相同,不过它表示的是数据库 通过 dblink 访问另一个数据库时,他们之间会建立一个会话,这个等待事件发 生在这个会话之间的通信过程中。 这个等待事件也是一个空闲等待事件。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 这个事件包含两个参数: Driver id: 服务器端和客户端连接使用的协议信息。 #bytes: 服务器端通过 dblink 收到的来自另一个服务器端消息的字节数。 1.5.2.28 SQL*Net message to client 这个等待事件发生在服务器端向客户端发送消息的时候。 当服务器端向客户 端发送消息产生等待时,可能的原因是用户端太繁忙,无法及时接收服务器端送 来的消息,也可能是网络问题导致消息无法从服务器端发送到客户端。 这个等待事件有两个参数: Driver id: 服务器端和客户端连接使用的协议信息。 #bytes: 服务器端向客户端发送消息的字节数。 1.5.2.29 SQL*Net message to dblink 这个等待事件和 SQL*Net message to client 相同,不过是发生在数据库服务 器和服务器之间的等待事件,产生这个等待的原因可能是远程服务器繁忙,而无 法及时接收发送过来的消息,也可能是服务器之间网络问题导致消息无法发送过 来。 这个等待时间包含两个参数: Driver id: 服务器端和客户端连接使用的协议信息。 #bytes: 服务器端通过 dblink 发送给另一个服务器消息的字节数。 1.5.2.30 SQL*Net more data from client 服务器端等待用户发出更多的数据以便完成操作,比如一个大的 SQL 文本, 导致一个 SQL*Net 数据包无法完成传输,这样服务器端会等待客户端把整个 SQL 文本发过来在做处理,这时候就会产生一个 SQL*Net more data from client 等待事件。 这个等待时间包含两个参数: Driver id: 服务器端和客户端连接使用的协议信息。 #bytes: 服务器端从客户端接收到消息的字节数。 1.5.2.31 SQL*Net more data from dblink 在一个分布式事务中,SQL 分布在不同的数据库中执行,远程数据库执行完 毕后将结果通过 dblink 返给发出 SQL 的数据库,在等待数据从其他数据库中通 过 dblink 传回的过程中,如果数据在远程数据库上处理时间很久,或者有大量的 结果集需要返回,或者网络性能问题都会产生 SQL*Net more data from dblink 等 待事件,它的意思是本地数据库需要等到所有的数据从远程处理完毕通过 dblink 传回后,才可以在本机继续执行操作。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 这个等待时间包含两个参数: Driver id: 服务器端和客户端连接使用的协议信息。 #bytes: 服务器端通过 dblink 发送给另一个服务器消息的字节数。 1.5.2.32 SQL*Net more data to client 当服务器端有太多的数据需要发给客户端时,可能会产生 SQL*Net more data to client 等待事件,也可能由于网络问题导致服务器无法及时地将信息或者处理 结果发送给客户端,同样会产生这个等待。 这个等待时间包含两个参数: Driver id: 服务器端和客户端连接使用的协议信息。 #bytes: 服务器端向客户端发送消息的字节数。 1.5.2.33 SQL*Net more data to dblink 这个等待事件和 SQL*Net more data to client 等待时间基本相同,只不过等待 发生在分布式事务中,即本地数据库需要将更多的数据通过 dblink 发送给远 程数据库。由于发送的数据太多或者网络性能问题,就会出现 SQL*Net more data to dblink 等待事件。 这个等待时间包含两个参数: Driver id: 服务器端和客户端连接使用的协议信息。 #bytes: 服务器端通过 dblink 发送给另一个服务器消息的字节数。 1.6 存储过程 1.6.1 Procedure 定义 1.6.1.1 定义 存储过程(Stored Procedure )是一组为了完成特定功能的 SQL 语句集,经 编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(如果该存储 过程带有参数)来执行它。存储过程是数据库中的一个重要对象,任何一个设计 良好的数据库应用程序都应该用到存储过程。 存储过程是由流控制和 SQL 语句 书写的过程,这个过程经编译和优化后存储在数据库服务器中,应用程序使用时 只要调用即可。在 ORACLE 中,若干个有联系的过程可以组合在一起构成程序 包。 1.6.1.2 优 点 1. 存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编 译,而一般 SQL 语句每执行一次就编译一次,所以使用存储过程可提高数据库执 行速度。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 2. 当对数据库进行复杂操作时(如对多个表进行 Update、Insert、Query、Delete 时),可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使 用。 3.存储过程可以重复使用,可减少数据库开发人员的工作量。 4.安全性高,可设定只有某用户才具有对指定存储过程的使用权。 1.6.1.3 存储过程与函数的对比 1.6.2 存储过程使用示例 1.6.2.1. 存储过程格式 /* Formatted on 2011/1/17 13:20:44 (QP5 v5.115.810.9015) */ CREATE OR REPLACE procedure proc_trade( v_tradeid in number, --交易id v_third_ip in varchar2, --第三方ip v_third_time in date , --第三方完成时间 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 v_thire_state in number , --第三方状态 o_result out number, --返回值 o_detail out varchar2 --详细描述 ) as -- 定义变量 v_error varchar2(500); begin --对变量赋值 o_result:=0; o_detail:='验证失败'; --业务逻辑处理 if v_tradeid >100 then insert into table_name(...) values(...); commit; elsif v_tradeid < 100 and v_tradeid>50 then insert into table_name(...) values(...); commit; else goto log; end if; --跳转标志符,名称自己指定 <> o_result:=1; --捕获异常 exception when no_data_found then result := 2; when dup_val_on_index then result := 3; when others then result := -1; end proc_trade; 在上面这个存储过程中使用了输入参数,并返回输出参数,这里的参数类型 是我们自己指定的。 这种写法可行,但是最好使用%type 来获取参数的类型 (table_name.column_name%TYPE)。 这样就不会出现参数类型的错误。 如: CREATE OR REPLACE PROCEDURE spdispsms ( Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 aempid IN otherinfo.empid%TYPE, amsg IN otherinfo.msg%TYPE, abillno IN otherinfo.billno%TYPE, ainfotype IN otherinfo.infotype%TYPE, aopid IN otherinfo.OPERATOR%TYPE, ainfoid OUT otherinfo.infoid%TYPE, RESULT OUT INTEGER ) 1.6.2.2. 存储过程中的循环 存储过程写的是业务逻辑,循环是常用的处理方法之一。 1.6.2.2.1 for ... in ... loop 循环 1:循环遍历游标 示例1: CREATE OR REPLACE PROCEDURE proc_test AS CURSOR c1 IS SELECT * FROM dat_trade; BEGIN FOR x IN c1 LOOP DBMS_OUTPUT.put_line (x.id); END LOOP; END proc_test; 示例 2: CREATE OR REPLACE PROCEDURE proc_test AS BEGIN FOR x IN (SELECT power_id FROM sys_power) LOOP DBMS_OUTPUT.put_line (x.power_id); END LOOP; END proc_test; 2:根据数值进行循环 示例 1: CREATE OR REPLACE PROCEDURE proc_test (v_num IN NUMBER) AS BEGIN for x in 1..100 loop Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 dbms_output.put_line(x); end loop; END proc_test; 示例 2:在过程里指定输入参数 v_num. 在调用过程时指定循环次数。 CREATE OR REPLACE PROCEDURE proc_test (v_num IN NUMBER) AS BEGIN FOR x IN 1 .. v_num LOOP DBMS_OUTPUT.put_line (x); END LOOP; END proc_test; 1.6.2.2.2 loop 循环 LOOP DELETE FROM orders WHERE senddate < TO_CHAR (ADD_MONTHS (SYSDATE, -3), 'yyyy-mm-dd') AND ROWNUM < 1000; EXIT WHEN SQL%ROWCOUNT < 1; COMMIT; END LOOP; 这里的 SQL%ROWCOUNT 是 隐 士 游 标 。 除 了 这 个 , 还 有 其 他 几 个:%found,%notfound, %isopen。 1.6.2.2.3 while 循环 CREATE OR REPLACE PROCEDURE proc_test (v_num IN NUMBER) AS i NUMBER := 1; BEGIN WHILE i < v_num LOOP BEGIN i := i + 1; DBMS_OUTPUT.put_line (i); END; END LOOP; END proc_test; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.6.2.3. 存储过程中的判断 判断也是存储过程中最常用的方法之一。 1.6.2.3.1 if ... elsif ... else ... 判断 CREATE OR REPLACE PROCEDURE proc_test (v_num IN NUMBER) AS BEGIN IF v_num < 10 THEN DBMS_OUTPUT.put_line (v_num); ELSIF v_num > 10 AND v_num < 50 THEN DBMS_OUTPUT.put_line (v_num - 10); ELSE DBMS_OUTPUT.put_line (v_num - 50); END IF; END proc_test; 1.6.2.3.2 case ... when ... end case 判断 CREATE OR REPLACE PROCEDURE proc_test (v_num IN NUMBER) AS BEGIN case v_num when 1 then DBMS_OUTPUT.put_line (v_num); when 2 then DBMS_OUTPUT.put_line (v_num); when 3 then DBMS_OUTPUT.put_line (v_num); else null; end case; END proc_test; 1.6.2.4. 游标 存储过程中使用游标也是很常见的。 这里的游标分两种: 1.6.2.4.1 Cursor 型游标(不能用于参数传递) 这种方法具体参考 1.6.2.2.1:循环遍历游标 中的示例。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.6.2.4.2 SYS_REFCURSOR 型游标 该游标是 Oracle 以预先定义的游标,可作出参数进行传递。 注意一点:SYS_REFCURSOR 只能通过 OPEN 方法来打开和赋值 我们可以使用这种类似的游标来返回一个结果集: CREATE OR REPLACE procedure proc_test( checknum in number, --每次返回的数据量 ref_cursor out sys_refcursor --返回的结果集,游标 ) as begin open ref_cursor for select * from (select * from dat_trade where state=41 order by id) where rownumshow errors 来查看错误。不过在开发中估计也很少有人直接使用 sqlplus 来写存储过程。 效率低,调试又麻烦。 还是使用工具方便点。我一直使用的是 Toad 的。 如果想在某处退出存储过程,直接使用 Return;就可以了。 与存储过程编写 相关的数组和游标, 这两块说起来还是有很多东西。 在上面的示例中, 也简 单的举了几个有关游标与存储过程编写的例子。 1.7 Oracle 内存管理 Oracle 的内存配置与 oracle 性能息息相关。关于内存的配置,是最影响 Oracle 性能的配置。内存还直接影响到其他两个重要资源的消耗:CPU 和 IO. 先看 Oracle 内存存储的主要内容是什么: 程序代码(PLSQL、Java); 关于已经连接的会话的信息,包括当前所有活动和非活动会话; 程序运行时必须的相关信息,例如查询计划; Oracle 进程之间共享的信息和相互交流的信息,例如锁; 那些被永久存储在外围存储介质上,被 cache 在内存中的数据(如 redo log 条目,数据块)。 每个 Oracle 数据库都是由 Oracle Instance(实例)与数据库(数据文件,控 制文件、重做日志文件)组成,其中所谓实例就是用户同数据库交互的媒介,用 户通过于一个实例相连来操作数据库。而实例又是由统一的内存结构(SGA, PGA,UGA)和一批内存驻留进程组成。实例在操作系统中用 ORACLE_SID 来 标识,在 Oracle 中用参数 INSTANCE_NAME 来标识, 它们两个的值是相同的。 数据库启动时,系统首先在服务器内存中分配系统全局区(SGA), 构成了 Oracle 的内存结构,然后启动若干个常驻内存的操作系统进程,即组成了 Oracle 的 进 程结构,内存区域和后台进程合称为一个 Oracle 实例。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.7.1 SGA SGA 是一组为系统分配的共享的内存结构,可以包含一个数据库实例的数据 或控制信息。如果多个用户连接到同一个数据库实例,在实例的 SGA 中,数据 可以被多个用户共享。 当数据库实例启动时,SGA 的内存被自动分配;当数 据库实例关闭时,SGA 内存被回收。 SGA 是占用内存最大的一个区域,同时 也是影响数据库性能的重要因素。 SGA 区是可读写的。所有登录到实例的用户都能读取 SGA 中的信息,而在 oracle 做执行操作时,服务进程会将修改的信息写入 SGA 区。 SGA 主要包括了以下的数据结构: 数据缓冲(Buffer Cache) 重做日志缓冲(Redo Log Buffer) 共享池(Shared Pool) Java 池(Java Pool) 大池(Large Pool) 流池(Streams Pool --- 10g 以后才有) 数据字典缓存(Data Dictionary Cache) 其他信息(如数据库和实例的状态信息) SQL> show sga Total System Global Area 612368384 bytes Fixed Size 1250428 bytes Variable Size 192940932 bytes Database Buffers 411041792 bytes Redo Buffers 7135232 bytes SGA 中的数据字典缓存 和其他信息 会被实例的后台进程所访问,它们在 实例启动后就固定在 SGA 中了,而且不会改变,所以这部分又称为固定 SGA (Fixed SGA)。这部分区域的大小一般小于 100K。 Shared Pool、Java Pool、Large Pool 和 Streams Pool 这几块内存区的大小是相 应系统参数设置而改变的,所以有通称为可变 SGA(Variable SGA)。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 截图出自 Oracle 11g 的架构图。 下载地址:http://download.csdn.net/source/2346700 通过下面的语句查询 SQL> show parameter sga NAME TYPE VALUE ------------------------------------ ----------- ------- lock_sga boolean FALSE pre_page_sga boolean FALSE sga_max_size big integer 584M sga_target big integer 584M 先对这几个参数做一下说明: SQL> select name,value ,ISSYS_MODIFIABLE from v$parameter where name like 'sga%'; NAME VALUE ISSYS_MOD --------------- --------------- --------- sga_max_size 612368384 FALSE sga_target 612368384 IMMEDIATE 如果 ISSYS_MODIFIABLE 返回的是 false,说明该参数无法用 alter system 语句动态修改,需要重启数据库。 所以 sga_max_size 是不可以动态调整的。但是我们可以对 sga_target 进行动 态的调整。 1.7.1.1 相关参数说明 1.7.1.1.1 SGA_MAX_SIZE SGA 区包括了各种缓冲区和内存池,而大部分都可以通过特定的参数来指定 他们的大小。但是,作为一个昂贵的资源,一个系统的物理内存大小是有限。尽 管对于 CPU 的内存寻址来说,是无需关系实际的物理内存大小的,但是过多的Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 使用虚拟内存导致 page in/out,会大大影响系统的性能,甚至可能会导致系统 crash。所以需要有一个参数来控制 SGA 使用虚拟内存的最大大小,这个参数就 是 SGA_MAX_SIZE。 当实例启动后,各个内存区只分配实例所需要的最小大小,在随后的运行过 程中,再根据需要扩展他们的大小,而他们的总和大小受到了 SGA_MAX_SIZE 的限制。 当试图增加一个内存的大小,并且如果这个值导致所有内存区大小总和大于 SGA_MAX_SIZE 时,oracle 会提示错误,不允许修改。 当然,如果在设置参数时,指定区域为 spfile 时(包括修改 SGA_MAX_SIZE 本身),是不会受到这个限制的。这样就可能出现这样的情况,在 spfile 中,SGA 各个内存区设置大小总和大于 SGA_MAX_SIZE。这时,oracle 会如下处理:当 实例再次启动时,如果发现 SGA 各个内存总和大于 SGA_MAX_SIZE,它会将 SGA_MAX_SIZE 的值修改为 SGA 各个内存区总和的值。 SGA 所分配的是虚拟内存,但是,在我们配置 SGA 时,一定要使整个 SGA 区都在物 理内存中,否则,会导致 SGA 频繁的页入/页出,会极大影响系统性能。 对于 OLTP 系统,一般的建议是将 SGA_MAX_SIZE 设为物理内存的 60%, PGA 设为 20%。 但是现在服务器内存是相当大的。 几百 G 的内存随处可见。 60%也就是几百 G 内存。 显然这样也是不合适的。 所以要根据自己系统来设定 设定这个值。这个也就所说的 DBA 的经验。 这是是需要经验的积累。 下表的几个数值供参考。 系统内存 SGA_MAX_SIZE 值 1G 400-500M 2G 1G 4G 2500M 8G 5G SGA 的实际大小可以通过以下公式估算: SGA 实际大小 = DB_CACHE_SIZE + DB_KEEP_CACHE_SIZE + DB_RECYCLE_CACHE_SIZE + DB_nk_CACHE_SIZE + SHARED_POOL_SIZE + LARGE_POOL_SIZE + JAVA_POOL_SIZE + STREAMS_POOL_SIZE(10g 中的 新内存池) + LOG_BUFFERS+11K(Redo Log Buffer 的保护页) + 1MB + 16M(SGA 内部内存消耗,适合于 9i 及之前版本) 1.7.1.1.2 PRE_PAGE_SGA oracle 实例启动时,会只载入各个内存区最小的大小。而其他 SGA 内存只作 为虚拟内存分配,只有当进程 touch 到相应的页时,才会置换到物理内存中。我 们可以通过设置 PRE_PAGE_SGA 参数,让实例一启动后,所有 SGA 都分配到物理 内存。 这个参数的默认值为 FALSE,即不将全部 SGA 置入物理内存中。当设置为 TRUETianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 时,实例启动会将全部 SGA 置入物理内存中。它可以使实例启动达到它的最大性 能状态,但是,启动时间也会更长(因为为了使所有 SGA 都置入物理内存中, oracle 进程需要 touch 所有的 SGA 页)。 SQL> alter system set pre_page_sga=true scope=spfile; 1.7.1.1.3 LOCK_SGA 为了保证 SGA 都被锁定在物理内存中,而不必页入/页出,可以通过参数 LOCK_SGA 来控制。这个参数默认值为 FALSE,当指定为 TRUE 时,可以将全 部 SGA 都锁定在物理内存中。当然,有些系统不支持内存锁定,这个参数也就 无效了。 1.7.1.1.4 SGA_TARGET Oracle10g 中引入的一个非常重要的参数。在 10g 之前,SGA 的各个内存区 的大小都需要通过各自的参数指定,并且都无法超过参数指定大小的值,尽管他 们之和可能并没有达到 SGA 的最大限制。此外,一旦分配后,各个区的内存只 能给本区使用,相互之间是不能共享的。拿 SGA 中两个最重要的内存区 Buffer Cache 和 Shared Pool 来说,它们两个对实例的性能影响最大,但是就有这样的 矛盾存在:在内存资源有限的情况下,某些时候数据被 cache 的需求非常大,为 了提高 buffer hit,就需要增加 Buffer Cache,但由于 SGA 有限,只能从其他区―抢‖ 过来——如缩小 Shared Pool,增加 Buffer Cache;而有时又有大块的 PLSQL 代 码被解析驻入内存中,导致 Shared Pool 不足,甚至出现 4031 错误,又需要扩大 Shared Pool,这时可能又需要人为干预,从 Buffer Cache 中将内存夺回来。 10g 以后有了新特性:自动共享内存管理(Automatic Shared Memory Management ASMM)。而控制这一特性的,也就仅仅是这一个参数 SGA_TARGE。设 置这个参数后,就不需要为每个内存区来指定大小了。SGA_TARGET 指定了 SGA 可以使用的最大内存大小,而 SGA 中各个内存的大小由 Oracle 自行控制,不需 要人为指定。Oracle 可以随时调节各个区域的大小,使之达到系统性能最佳状 态的个最合理大小,并且控制他们之和在 SGA_TARGET 指定的值之内。一旦给 SGA_TARGET 指定值后(默认为 0,即没有启动 ASMM),就自动启动了 ASMM 特性。 如果不设置 SGA_TARGET,则自动共享内存管理功能被禁止。 设置了 SGA_TARGET 后,以下的 SGA 内存区就可以由 ASMM 来自动调整: 共享池(Shared Pool) Java 池(Java Pool) 大池(Large Pool) 数据缓存区(Buffer Cache) 流池(Streams Pool) 对于 SGA_TARGET 的限制,它的大小是不能超过 SGA_MAX_SIZE 的大小 的。 要注意的是:当指定 SGA_TARGET 小于 SGA_MAX_SIZE,实例重启后,SGA_MAX_SIZE 就自动变为和 SGA_TARGET 一样的值了。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SGA_TARGET,它的值可以动态修改(在 SGA_MAX_SIZE 范围内)。在 10g 之前,如果需要修改 SGA 的大小(即修改 SGA_MAX_SIZE 的值)需要重启实 例才能生效。当然,在 10g 中,修改 SGA_MAX_SIZE 的值还是需要重启的。但 是有了 SGA_TARGET 后,可以将 SGA_MAX_SIZE 设置偏大,再根据实际需要 调整 SGA_TARGET 的值(我个人不推荐频繁修改 SGA 的大小,SGA_TARGET 在实例启动时设置好,以后不要再修改)。 SGA_TARGET 带来一个重要的好处就是,能使 SGA 的利用率达到最佳,从 而节省内存成本。因为 ASMM 启动后,Oracle 会自动根据需要调整各个区域的 大小,大大减少了某些区域内存紧张,而某些区域又有内存空闲的矛盾情况出现。 这也同时大大降低了出现 4031 错误的几率。 1.7.1.2 Database Buffer Cache Buffer Cache 是 SGA 区中专门用于存放从数据文件中读取的的数据块拷贝的 区域。Oracle 进程如果发现需要访问的数据块已经在 buffer cache 中,就直接读 写内存中的相应区域,而无需读取数据文件,从而大大提高性能(内存的读取效 率是磁盘读取效率的 14000 倍)。Buffer cache 对于所有 oracle 进程都是共享的, 即能被所有 oracle 进程访问。 和 Shared Pool 一样,buffer cache 被分为多个集合,这样能够大大降低多 CPU 系统中的争用问题。 1.7.1.2.1 Buffer cache 的管理 Oracle 对于 buffer cache 的管理,是通过两个重要的链表实现的:写链表和 最近最少使用链表(the Least Recently Used LRU)。写链表所指向的是所有脏数 据块缓存(即被进程修改过,但还没有被回写到数据文件中去的数据块,此时缓 冲中的数据和数据文件中的数据不一致)。而 LRU 链表指向的是所有空闲的缓 存、pin 住的缓存以及还没有来的及移入写链表的脏缓存。空闲缓存中没有任何 有用的数据,随时可以使用。而 pin 住的缓存是当前正在被访问的缓存。LRU 链 表的两端就分别叫做最近使用端(the Most Recently Used MRU)和最近最少使 用端(LRU)。 1)Buffer cache 的数据块访问 当一个 Oracle 进程访问一个缓存时,这个进程会将这块缓存移到 LRU 链表 中的 MRU。而当越来越多的缓冲块被移到 MRU 端,那些已经过时的脏缓冲(即 数据改动已经被写入数据文件中,此时缓冲中的数据和数据文件中的数据已经一 致)则被移到 LRU 链表中 LRU 端。 当一个 Oracle 用户进程第一次访问一个数据块时,它会先查找 buffer cache 中是否存在这个数据块的拷贝。如果发现这个数据块已经存在于 buffer cache(即 命中 cache hit),它就直接读从内存中取该数据块。如果在 buffer cache 中没有发 现该数据块(即未命中 cache miss),它就需要先从数据文件中读取该数据块到 buffer cache 中,然后才访问该数据块。命中次数与进程读取次数之比就是我们 一个衡量数据库性能的重要指标:buffer hit ratio(buffer 命中率),可以通过以下 语句获得自实例启动至今的 buffer 命中率: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL>select (1-(sum(decode(name, 'physical reads',value,0))/(sum(decode(name, 'db block gets',value,0)) +sum(decode(name,'consistent gets',value,0))))) * 100 "Hit Ratio" from v$sysstat; Hit Ratio ---------- 98.3471481 一个良好性能的系统,命中率一般保持在 95%左右。 关于命中率,可以参考我的 blog:Oracle 检查命中率的 SQL http://blog.csdn.net/tianlesoftware/archive/2009/10/16/4674153.aspx 上面提到,如果未命中(missed),则需要先将数据块读取到缓存中去。这时, oracle 进程需要从空闲列表种找到一个适合大小的空闲缓存。如果空闲列表中没 有适合大小的空闲 buffer,它就会从 LRU 端开始查找 LRU 链表,直到找到一个 可重用的缓存块或者达到最大查找块数限制。在查找过程中,如果进程找到一个 脏缓存块,它将这个缓存块移到写链表中去,然后继续查找。当它找到一个空闲 块后,就从磁盘中读取数据块到缓存块中,并将这个缓存块移到 LRU 链表的 MRU 端。 当有新的对象需要请求分配 buffer 时,会通过内存管理模块请求分配空闲的 或者可重用的 buffer。―free buffer requested‖就是产生这种请求的次数; 当请求分配 buffer 时,已经没有适合大小的空闲 buffer 时,需要从 LRU 链表 上获取到可重用的 buffer。但是,LRU 链表上的 buffer 并非都是立即可重用的, 还会存在一些块正在被读写或者已经被别的用户所等待。根据 LRU 算法,查找 可重用的 buffer 是从链表的 LRU 端开始查找的,如果这一段的前面存在这种不 能理解被重用的 buffer,则需要跳过去,查找链表中的下一个 buffer。―free buffer inspected‖就是被跳过去的 buffer 的数目。 如果 Oracle 用户进程达到查找块数限制后还没有找到空闲缓存,它就停止查 找 LRU 链表,并且通过信号通知 DBW0 进程将脏缓存写入磁盘去。 2) 全表扫描 当发生全表扫描(Full Table Scan)时,用户进程读取表的数据块,并将他们 放在 LRU 链表的 LRU 端(和上面不同,不是放在 MRU 端)。这样做的目的是 为了使全表扫描的数据尽快被移出。因为全表扫描一般发生的频率较低,并且全 表扫描的数据块大部分在以后都不会被经常使用到。 而如果你希望全表扫描的数据能被 cache 住,使之在扫描时放在 MRU 端, 可以通过在创建或修改表(或簇)时,指定 CACHE 参数。 3) Flush Buffer 回顾一下前面一个用户进程访问一个数据块的过程,如果访问的数据块不在 buffer cache 中,就需要扫描 LRU 链表,当达到扫描块数限制后还没有找到空闲 buffer,就需要通知 DBW0 将脏缓存回写到磁盘。如果一个系统中存在大量的脏 缓冲,那么就可能导致用户进程访问数据性能下降。 我们可以通过人工干预将所有脏缓冲回写到磁盘去,这就是 flush buffer。 在 9i,可以用以下语句: alter system set events = 'immediate trace name flush_cache'; --9i Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 在 10g,可以用以下方式(9i 的方式在 10g 仍然有效): alter system flush buffer_cache; -- 10g 另外,9i 的设置事件的方式可以是针对系统全部的,也可以是对会话的(即 将该会话造成的脏缓冲回写)。 1.7.1.2.2 Buffer Cache 的重要参数配置 1) Buffer Cache 的大小配置 由于 Buffer Cache 中存放的是从数据文件中来的数据块的拷贝,因此,它的 大小的计算也是以块的尺寸为基数的。而数据块的大小是由参数 db_block_size 指定的。9i 以后,块的大小默认是 8K,它的值一般设置为和操作系统的块尺寸 相同或者它的倍数。 而参数db_block_buffers则指定了Buffer Cache中缓存块数。因此,buffer cache 的大小就等于 db_block_buffers * db_block_size。 在 9i 以后,Oracle 引入了一个新参数:db_cache_size。这个参数可以直接指 定 Buffer Cache 的大小,而不需要通过上面的方式计算出。它的默认值 48M,这 个数对于一个系统来说一般是不够用的。 10G 中提供了自动内存管理,通过使用 sga_target 在在多个组件间自动分配内 存以保证最有效的内存使用.如 shared pool javapool largepool buffer cache 都无需 显式设置这些组件的大小,默认都是 0,当某个组件需要内存时,可以通过内部自动 调整机制请求内存转移. 注意:db_cache_size 和 db_block_buffers 是不能同时设置的,否则实例启动 时会报错。 示例: SQL> alter system set db_block_buffers=16384 scope=spfile; system altered. SQL> alter system set db_cache_size=20M scope=memory; system altered. SQL> startup force ORA-00381: cannot use both new and old parameters for buffer cache size specification 9i 中,推荐使用 db_cache_size 来指定 buffer cache 的大小。 在 OLTP 系统中,对于 DB_CACHE_SIZE 的设置,推荐配置是: DB_CACHE_SIZE = SGA_MAX_SIZE/2~ SGA_MAX_SIZE*2/3 最后,DB_CACHE_SIZE 是可以联机修改的,即实例无需重启,除非增大 Buffer Cache 导致 SGA 实际大小大于 SGA_MAX_SIZE。 2) 多种块尺寸系统中的 Buffer Cache 的配置 从 9i 开始,Oracle 支持创建不同块尺寸的表空间,并且可以为不同块尺寸的Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 数据块指定不同大小的 buffer cache。 9i 以后,除了 SYSTEM 表空间和 TEMPORARY 表空间必须使用标准块尺寸 外,所有其他表空间都可以最多指定四种不同的块尺寸。而标准块尺寸还是由上 面的所说的参数 db_block_size 来指定。而 db_cache_size 则是标致块尺寸的 buffer cache 的大小。 非标准块尺寸的块大小可以在创建表空间(CREATE TABLESPACE)是通过 BLOCKSIZE 参数指定。而不同块尺寸的 buffer cache 的大小就由相应参数 DB_nK_CACHE_SZIE 来指定,其中 n 可以是 2,4,8,16 或者 32。例如,你 创建了一个块大小为 16K 的非标准块尺寸的表空间,你就可以通过设置 DB_16K_CACHE_SIZE 为来指定缓存这个表空间数据块的 buffer cache 的大小。 任何一个尺寸的 Buffer Cache 都是不可以缓存其他尺寸的数据块的。因此, 如果你打算使用多种块尺寸用于你的数据库的存储,你必须最少设置 DB_CACHE_SIZE 和 DB_nK_CACHE_SIZE 中的一个参数(10g 后,指定了 SGA_TARGET 就可以不需要指定 Buffer Cache 的大小)。并且,你需要给你要用 到的非标准块尺寸的数据块指定相应的 Buffer Cache 大小。这些参数使你可以为 系统指定多达 4 种不同块尺寸的 Buffer Cache。 另外,注意一点,DB_nK_CACHE_SIZE 参数不能设定标准块尺寸的缓冲区 大 小 。 举 例 来 说 , 如 果 DB_BLOCK_SIZE 设 定 为 4K , 就 不 能 再 设 定 DB_4K_CACHE_SIZE 参数。 3)多缓冲池 可以配置不同的 buffer cache,可以达到不同的 cache 数据的目的。比如,可 以设置一部分 buffer cache 缓存过的数据在使用后后马上释放,使后来的数据可 以立即使用缓冲池;还可以设置数据进入缓冲池后就被 keep 住不再释放。部分 数据库对象(表、簇、索引以及分区)可以控制他们的数据缓存的行为,而这些 不同的缓存行为就使用不同缓冲池。 保持缓冲池(Keep Buffer Pool)用于缓存那些永久驻入内存的数据块。它的 大小由参数 DB_KEEP_CACHE_SZIE 控制; 回收缓冲池(Recycle Buffer Pool)会立即清除那些不在使用的数据缓存块。 它的大小由参数 DB_RECYLE_CACHE_SIZE 指定; 默认的标准缓存池,也就是上面所说的 DB_CACHE_SIZE 指定。 这三个参数相互之间是独立的。并且他们都只适用于标准块尺寸的数据块。 与 8i 兼容参数 DB_BLOCK_BUFFERS 相应的,DB_KEEP_CACHE_SIZE 对应有 BUFFER_POOL_KEEP 、 DB_RECYLE_CACHE_SIZE 对应有 BUFFER_POOL_RECYCLE 。同样,这些参数之间是互斥的,即 DB_KEEP_CACHE_SIZE 和 BUFFER_POOL_KEEP 之间只能设置一个。 4) 缓冲池建议器 从 9i 开始,Oracle 提供了一些自动优化工具,用于调整系统配置,提高系统 性能。建议器就是其中一种。建议器的作用就是在系统运行过程中,通过监视相 关统计数据,给相关配置在不同情况下的性能效果,提供给 DBA 做决策,以选 取最佳的配置。 9i 中,Buffer Cache 就有了相应的建议器。参数 db_cache_advice 用于该建议Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 器的开关,默认值为 FALSE(即关)。当设置它为 TRUE 后,在系统运行一段时 间后,就可以查询视图 v$db_cache_advice 来决定如何使之 DB_CACHE_SIZE 了。 关于这个建议器和视图,我们会在下面的内容中介绍。 5) 其他相关参数 DB_BLOCK_LRU_LATCHES LRU 链表作为一个内存对象,对它的访问是需要进行锁(latch)控制的,以防 止多个用户进程同时使用一个空闲缓存块。DB_BLOCK_LRU_LATCHES 设置了 LUR latch 的数量范围。Oracle 通过一系列的内部检测来决定是否使用这个参数 值。如果这个参数没有设置,Oracle 会自动为它计算出一个值。一般来说,oracle 计算出来的值是比较合理,无需再去修改。 9i 以后这个参数是隐含参数。对于隐含参数,我建议在没有得到 Oracle 支持 的情况下不要做修改,否则,如果修改了,Oracle 是可以拒绝为你做支持的。 DB_WRITER_PROCESSES 在前面分析 Oracle 读取 Buffer Cache 时,提到一个 Oracle 重要的后台进程 DBW0,这个(或这些)进程负责将脏缓存块写回到数据文件种去,称为数据库 书写器进程(Database Writer Process)。DB_WRITER_PROCESSES 参数配置写 进程的个数,各个进程以 DBWn 区分,其中 n>=0,是进程序号。一般情况下, DB_WRITER_PROCESSES = MAX(1, TRUNC(CPU 数/8))。也就是说,CPU 数小 于 8 时,DB_WRITER_PROCESSES 为 1,即只有一个写进程 DBW0。这对于一 般的系统来说也是足够用。当你的系统的修改数据的任务很重,并且已经影响到 性能时,可以调整这个参数。这个参数不要超过 CPU 数,否则多出的进程也不 会起作用,另外,它的最大值不能超过 20。 DBWn 进程除了上面提到的在用户进程读取 buffer cache 时会被触发,还能 被 Checkpoint 触发(Checkpoint 是实例从 redo log 中做恢复的起始点)。 1.7.1.3 Share Pool SGA 中的共享池由库缓存(Library Cache)、字典缓存(Dictionary Cache)、 用于并行执行消息的缓冲以及控制结构组成。 Shared Pool 的大小由参数 SHARED_POOL_SIZE 决定。9i 中,在 32 位系统 下,这个参数的默认值是 8M,而 64 位系统下的默认值位 64M。最大为 4G。 10g 以后可以通过 SGA_TARGET 参数来自动调整。 对于 Shared Pool 的内存管理,是通过修正过的 LRU 算法表来实现的。 1.7.1.3.1 库缓存(Library Cache) Library Cache 中包括共享 SQL 区(Shared SQL Areas)、PL/SQL 存储过程以 及控制结构(如锁、库缓存句柄)。 任何用户都可以访问共享 SQL 区(可以通过 v$sqlarea 访问)。因此库缓存存 在于 SGA 的共享池中。 1) 共享 SQL 区和私有 SQL 区 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Oracle 会为每一条 SQL 语句运行(每运行一条语句 Oracle 都会打开一个游 标)提供一个共享 SQL 区( Shared SQL Areas)和私有 SQL 区( Private SQL Areas 属于 PGA)。当发现两个(或多个)用户都在运行同一 SQL 语句时,Oracle 会重 新组织 SQL 区,使这些用户能重用共享 SQL 区。但他们还会在私有 SQL 区中 保存一份这条 SQL 语句的拷贝。 一个共享 SQL 区中保存了一条语句的解析树和查询计划。在多用户系统中, Oracle 通过为 SQL 语句使用同一共享 SQL 区多次运行来节省内存。 当一条新的 SQL 语句被解析时,Oracle 从共享池中分配一块内存来存储共享 SQL 区。这块内存的大小与这条语句的复杂性相关。如果 Shared Pool 不够空间 分配给共享 SQL 区,Oracle 将释放从 LRU 链表中查找到最近最少使用的内存块, 直到有足够空间给新的语句的共享 SQL 区。如果 Oracle 释放的是一个共享 SQL 区的内存,那么相应的语句在下次执行时需要再次解析并重新分配共享 SQL 区。 而从解析语句到分配共享 SQL 区是一个比较消耗 CPU 的工程。这就是为什么我 们提倡使用绑定变量的原因了。在没有使用绑定变量时,语句中的变量的数值不 同,oracle 就视为一条新的语句(9i 后可以通过 cursor_sharing 来控制),重复上 面的解析、内存分配的动作,将大大消耗系统资源,降低系统性能。 2) PL/SQL 程序单元 Oracle 对于 PL/SQL 程序单元(存储过程、函数、包、匿名 PL/SQL 块和触 发器)的处理过程和对单个的 SQL 语句的处理过程相似。它会分配一个共享区 来存储被解析、编译过的程序单元。同时分配一个私有区域来存放运行程序单元 的会话所指定的程序单元的参数值(包括本地变量、全局变量和包变量——这也 叫做包的实例化)和用于执行程序所需的内存。如果多个用户运行同一个程序单 元,则他们共享同一个共享区域,并且各自保持一份私有区域,用于用户会话中 指定的变量值。 而一个 PL/SQL程序单元中的每条单个 SQL语句的处理过程则和上面描述的 SQL 语句的处理过程相同。要注意一点,尽管这些语句是从 PL/SQL 程序单元中 来的,但是 Oracle 还是会为这些语句分配一块共享 SQL 区,同时为每个用户分 配一个相应的私有 SQL 区。 1.7.1.3.2 字典缓存(Dictionary Cache) 数据字典是有关于数据库的参考信息、数据库的结构信息和数据库中的用户 信息的一组表和视图的集合,如我们常用到的 V$视图、DBA_视图都属于数据字 典。在 SQL 语句解析的过程中,Oracle 可以非常迅速的访问(如果需要的话) 这些数据字典,在 SQL Trace 中,这种对数据字典的访问就被统计为回调 (recursive calls)。 因为 Oracle 对数据字典访问如此频繁,因此内存中有两处地方被专门用于存 放数据字典。一个地方就是数据字典缓存(Data Dictionary Cache)。 数据字典缓 存也被称为行缓存(Row Cache),因为它是以记录行为单元存储数据的,而不 像 Buffer Cache 是以数据块为单元存储数据。内存中另外一个存储数据字典的地 方是库缓存。所有 Oracle 的用户都可以访问这两个地方以获取数据字典信息。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.7.1.3.3 共享池的内存管理 通常来说,共享池是根据修正过的 LRU 算法来是否其中的对象(共享 SQL 区和数据自动记录行)的,否则这些对象就一直保持在共享池中。如果共享池需 要为一个新对象分配内存,并且共享池中没有足够内存时,内存中那些不经常使 用的对象就被释放掉。一个被许多会话使用过的共享池对象,即使最初创建它的 进程已经结束,只要它是有用的,都会被修正过的 LRU 算法一直保持在共享池 中。这样就使一个多用户的 Oracle 系统对 SQL 语句的处理和内存消耗最小。 注意,即使一个共享 SQL 区与一个打开的游标相关,但如果它长时间没有 被使用,它还是可能会被从共享池中释放出来。而此时如果打开的游标还需要运 行它的相关语句,Oracle 就会重新解析语句,并分配新的共享 SQL 区。 当一条 SQL 语句被提交给 Oracle 执行,Oracle 会自动执行以下的内存分配步骤: 1. Oracle 检查共享池,看是否已经存在关于这条语句的共享 SQL 区。如果 存在,这个共享 SQL 区就被用于执行这条语句。而如果不存在,Oracle 就从共 享池中分配一块新的共享 SQL 区给这条语句。同时,无论共享 SQL 区存在与否, Oracle 都会为用户分配一块私有 SQL 区以保存这条语句相关信息(如变量值)。 2. Oracle 为会话分配一个私有 SQL 区。私有 SQL 区的所在与会话的连接 方式相关。 在以下情况下,Oracle 也会将共享 SQL 区从共享池中释放出来: 1)当使用 ANALYZE 语句更新或删除表、簇或索引的统计信息时,所有与 被分析对象相关的共享 SQL 区都被从共享池中释放掉。当下一次被释放掉的语 句被执行时,又重新在一个新的共享 SQL 区中根据被更新过的统计信息重新解 析。 2) 当对象结构被修改过后,与该对象相关的所有共 SQL 区都被标识为无 效(invalid)。在下一次运行语句时再重新解析语句。 3)如果数据库的全局数据库名(Global Database Name)被修改了,共享池 中的所有信息都会被清空掉。 4 )DBA 通过手工方式清空共享池: ALTER SYSTEM FLUSH SHARED_POOL; Shared Pool 能被分成几个区域,分别被不同的 latch(latch 数最大为 7,可以通 过隐含参数_kghdsidx_count 设置)保护。 表 x$kghlu 可以查看 shared pool 中的 LRU 列表。当满足以下条件之一时, shared pool 会分为多个区,分别有不同的 LRU 链表管理: 1)在 10g 之前版本,如果 shared pool 大于 128M、CPU 数量大于 4; 2)Oracle 数据库版本为 10g 这时,在 x$kghlu 中就会对应不同记录。 1.7.1.3.4 保留共享池 前面提到,如果 Oracle 解析一个 PL/SQL 程序单元,也需要从共享池中分配 内存给这些程序单元对象。由于这些对象本一般比较大(如包),所以分配的内Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 存空间也相对较大。系统经过长时间运行后,共享池可能存在大量内存碎片,导 致无法满足对于大块内存段的分配。 为了使有足够空间缓存大程序块,Oracle 专门从共享池内置出一块区域来来 分配内存保持这些大块。这个保留共享池的默认大小是共享池的 5%。它的大小 也可以通过参数 SHARED_POOL_RESERVED_SIZE 来调整。保留区是从共享池 中分配,不是直接从 SGA 中分配的,它是共享池的保留部分,用于存储大块段。 Shared Pool 中内存大于 5000 字节的大段就会被存放在共享池的保留部分。 而这个大小限制是通过隐含参数_SHARED_POOL_RESERVED_MIN_ALLOC来 设定的(如前面所说,隐含参数不要去修改它)。除了在实例启动过程中,所有 小于这个数的内存段永远都不会放到保留部分中,而大于这个值的大内存段也永 远不会存放到非保留区中,即使共享池的空间不够用的情况下也是如此。 保留区的空闲内存也不会被包含在普通共享池的空闲列表中。它会维护一个 单独的空闲列表。保留池也不会在它的 LRU 列表中存放可重建(Recreatable 关 于内存段的各种状态我们在后面的内容中再介绍)段。当释放普通共享池空闲列 表上的内存时是不会清除这些大段的,同样,在释放保留池的空闲列表上的大内 存段时也不会清除普通共享池中内存。 通过视图 V$SHARED_POOL_RESERVED 可以查到保留池的统计信息。其 中字段 REQUEST_MISSES 记录了没有立即从空闲列表中得到可用的大内存段 请求次数。这个值要为 0。因为保留区必须要有足够个空闲内存来适应那些短期 的内存请求,而无需将那些需要长期 cache 住的没被 pin 住的可重建的段清除。 否则就需要考虑增大 SHARED_POOL_RESERVED_SIZE 了。 可以通过观察视图 V$SHARED_POOL_RESERVED 的 MAX_USED_SPACE 字段来判断保留池的大小是否合适。大多数情况下,你会观察到保留池是很少被 使用的,也就是说 5%的保留池空间可能有些浪费。但这需要经过长期观察来决 定是否需要调整保留池大小。 保留区使用 shared pool 的 LRU 链表来管理内存块,但是在做扫描时,相互 是不受影响的。例如,内存管理器扫描 shared pool 的 LRU 链表,清出空间以分 配给一个小于 5000 字节的内存请求,是不会清出保留区的内存块的,相反亦然。 1.7.1.3.5 将重要、常用对象保持(Keep)在共享池中 根据 LRU 算法,一些一段时间没有使用到的内存块会被情况释放。这就可 能导致一些重要的对象(如一个含有大量通用算法函数的包、被 cache 的序列) 被从内存中清除掉。这些对象可能只是间歇被使用,但是因为他们的处理过程复 杂(不仅包本身重新分配内存、解析,还要检查里面的所有语句),要在内存中 重建他们的代价非常大。 我们可以通过调用存储过程 DBMS_SHARED_POOL.KEEP 将这些对象保持 在共享池中来降低这种风险。这个存储过程立即将对象及其从事对象载入 library cache 中,并将他们都标记为保持(Keeping)状态。对于这种对象,我们建议在 实例启动时就 Keep 住,以减少内存碎片的几率。 有一种观点认为那些大对象(如包)是没有必要被 Keep 住的,因为他们会 被保持在共享池的保留区(如前所述,这个区通常使用率很低),所以一般不可 能被清出。这个观点是错误滴!因为大多数大对象实际上是被分为多个小的内存 段被载入共享池的,因此根本不会因为对象的大小而受到特别的保护。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 另外,也不要通过频繁调用某些对象以防止他们被从共享池中清出。如果共 享池大小设置合理,在系统运行的高峰时期,LRU 链表会相对较短,那些没有 被 pin 住的对象会很快被清出,除非他们被 keep 住了。 1.7.1.3.6 关于 Shared Pool 的重要参数 1) SHARED_POOL_SIZE 它指定了 Shared Pool 的大小。9i 下,在 32 位系统中,这个参数的默认值是 8M,而 64 位系统中的默认值位 64M。 但是,在 SGA 中还存在一块叫内部 SGA 消耗(Internal SGA Overhead)的 内存被放置在共享池中。在 9i 及之前版本,共享池的统计大小(通过 v$sgastat 视图统计)为 SHARED_POOL_SIZE +内部 SGA 消耗大小。而 10g 以后, SHARED_POOL_SIZE 就已经包含了这部分内存大小。因此在 10g 中,共享池的 实际使用大小就是 SHARED_POOL_SIZE -内部 SGA 消耗大小,这在配置共享池 大小时需要考虑进去,否则,扶过 SHARED_POOL_SIZE 设置过小,在实例启 动时就会报 ORA-00371 错误。 2) SHARED_POOL_RESERVED_SIZE 这个参数前面已经提到,指定了共享池中缓存大内存对象的保留区的大小。 这里不再赘述。 3) _SHARED_POOL_RESERVED_MIN_ALLOC 这个参数前面也已经介绍,设置了进入保留区的对象大小的阀值。 1.7.1.4 重做日志缓存(Redo Log Buffer) Redo Log Buffer 是 SGA 中一段保存数据库修改信息的缓存。这些信息被存 储在重做条目(Redo Entry)中.重做条目中包含了由于 INSERT、UPDATE、 DELETE、CREATE、ALTER 或 DROP 所做的修改操作而需要对数据库重新组织 或重做的必须信息。在必要时,重做条目还可以用于数据库恢复。 重做条目是 Oracle 数据库进程从用户内存中拷贝到 Redo Log Buffer 中去的。 重做条目在内存中是连续相连的。后台进程 LGWR 负责将 Redo Log Buffer 中的 信息写入到磁盘上活动的重做日志文件(Redo Log File)或文件组中去的。 参数 LOG_BUFFER 决定了 Redo Log Buffer 的大小。它的默认值是 512K(一 般这个大小都是足够的),最大可以到 4G。10g 中可通过参数自动设置。当系统 中存在很多的大事务或者事务数量非常多时,可能会导致日志文件 IO 增加,降 低性能。这时就可以考虑增加 LOG_BUFFER。 但是,Redo Log Buffer 的实际大小并不是 LOB_BUFFER 的设定大小。为了 保护 Redo Log Buffer,oracle 为它增加了保护页(一般为 11K): SQL> select * from v$sgastat where name = 'log_buffer'; POOL NAME BYTES ------------ -------------------------- ---------- log_buffer 7135232 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL> show parameter log_buffer NAME TYPE VALUE ------------------------------------ ----------- ---------------- log_buffer integer 7024640 SQL> 1.7.1.5 大池(large pool) 大池是 SGA 中的一块可选内存池,根据需要时配置。在以下情况下需要配 置大池: 1) 用于共享服务(Shared Server MTS 方式中)的会话内存和 Oracle 分 布式事务处理的 Oracle XA 接口 2) 使用并行查询(Parallel Query Option PQO)时 3) IO 服务进程 4) Oracle 备份和恢复操作(启用了 RMAN 时) 通过从大池中分配会话内存给共享服务、Oracle XA 或并行查询,oracle 可以 使用共享池主要来缓存共享 SQL,以防止由于共享 SQL 缓存收缩导致的性能消 耗。此外,为 Oracle 备份和恢复操作、IO 服务进程和并行查询分配的内存一般 都是几百 K,这么大的内存段从大池比从共享池更容易分配得到。 参数 LARGE_POOL_SIZE 设置大池的大小。大池是属于 SGA 的可变区 (Variable Area)的 ,它不属于共享池。对于大池的访问,是受到 large memory latch 保护的。大池中只有两种内存段:空闲(free)和可空闲(freeable)内存段。它 没有可重建(recreatable)内存段,因此也不用 LRU 链表来管理(这和其他内存 区的管理不同)。大池最大大小为 4G。 为了防止大池中产生碎片,隐含参数_LARGE_POOL_MIN_ALLOC 设置了 大池中内存段的最小大小,默认值是 16K(同样,不建议修改隐含参数)。 此外,large pool 是没有 LRU 链表的。 1.7.1.6 Java 池(Java Pool) Java 池也是 SGA 中的一块可选内存区,它也属于 SGA 中的可变区。 Java 池的内存是用于存储所有会话中特定 Java 代码和 JVM 中数据。Java 池 的使用方式依赖与 Oracle 服务的运行模式。 Java 池的大小由参数 JAVA_POOL_SIZE 设置。Java Pool 最大可到 1G。 在 Oracle 10g 以后,提供了一个新的建议器——Java 池建议器——来辅助 DBA 调整 Java 池大小。建议器的统计数据可以通过视图 V$JAVA_POOL_ADVICE 来查询。如何借助建议器调整 Java 池的方法和使用 Buffer Cache 建议器类似,可以参考 Buffer Cache 中关于建议器部分。 1.7.1.7 流池(Streams Pool) 流池是 Oracle 10g 中新增加的。是为了增加对流的支持。 流池也是可选内存区,属于 SGA 中的可变区。它的大小可以通过参数 STREAMS_POOL_SIZE 来指定。如果没有被指定,oracle 会在第一次使用流时Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 自动创建。如果设置了 SGA_TARGET 参数,Oracle 会从 SGA 中分配内存给流 池;如果没有指定 SGA_TARGET,则从 buffer cache 中转换一部分内存过来给流 池。转换的大小是共享池大小的 10%。 Oracle 同样为流池提供了一个建议器——流池建议器。建议器的统计数据可 以通过视图 V$STREAMS_POOL_ADVICE 查询。使用方法参看 Buffer Cache 中 关于优化器部分。 1.7.2 PGA PGA(Program Global Area 程序全局区)是一块包含一个服务进程的数据和 控制信息的内存区域。它是 Oracle 在一个服务进程启动是创建的,是非共享的。 一个 Oracle 进程拥有一个 PGA 内存区。一个 PGA 也只能被拥有它的那个服 务进程所访问,只有这个进程中的 Oracle 代码才能读写它。因此,PGA 中的结 构是不需要 Latch 保护的。 我们可以设置所有服务进程的 PGA 内存总数受到实例分配的总体 PGA (Aggregated PGA)限制。 在专有服务器(Dedicated Server)模式下,Oracle 会为每个会话启动一个 Oracle 进程;而在多线程服务(Multi-Thread Server MTS)模式下,由多个会话 共享通一个 Oracle 服务进程。 PGA 中包含了关于进程使用到的操作系统资源的信息,以及一些关于进程状 态的信息。而关于进程使用的 Oracle 共享资源的信息则是在 SGA 中。这样做可 以使在进程以外中止时,能够及时释放和清除这些资源。 •Stack Space 是用来存储用户会话变量和数组的存储区域; •User Session Data 是为用户会话使用的附加存储区。 |--Session Information |--Sort Area |--Cursor Information 注意 Session information(用户会话信息)在独占服务器中与在共享服务器中所 处的内存区域是不同的。 1.7.2.1 PGA 的组成 PGA 由两组区域组成:固定 PGA 和可变 PGA(或者叫 PGA 堆,PGA Heap 【堆——Heap 就是一个受管理的内存区】)。固定 PGA 和固定 SGA 类似,它的Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 大小时固定的,包含了大量原子变量、小的数据结构和指向可变 PGA 的指针。 可变 PGA 是一个内存堆。它的内存段可以通过视图 X$KSMPP(另外一个视图 X$KSMSP 可以查到可变 SGA 的内存段信息,他们的结构相同)查到。PGA 堆 包含用于存放 X$ 表的的内存(依赖与参数设置,包括 DB_FILES 、 CONTROL_FILES)。 总的来说,PGA 的可变区中主要分为以下三部分内容: 1)私有 SQL 区; 2)游标和 SQL 区 3)会话内存 1.7.2.1.1 私有 SQL 区(Private SQL Area) 私有 SQL 区包含了绑定变量值和运行时期内存结构信息等数据。每一个运 行 SQL 语句的会话都有一个块私有 SQL 区。所有提交了相同 SQL 语句的用户 都有各自的私有 SQL 区,并且他们共享一个共享 SQL 区。因此,一个共享 SQL 区可能和多个私有共享区相关联。 一个游标的私有 SQL 区又分为两个生命周期不同的区: 永久区:包含绑定变量信息。当游标关闭时被释放。 运行区:当执行结束时释放。 创建运行区是一次执行请求的第一步。对于 INSERT、UPDATE 和 DELETE 语句,Oracle 在语句运行结束时释放运行区。对于查询操作,Oracle 只有在所有 记录被 fetch 到或者查询被取消时释放运行区。 1.7.2.1.2 游标和 SQL 区(Cursors and SQL Areas) 一个 Oracle 预编译程序或 OCI 程序的应用开发人员能够很明确的打开一个 游标,或者控制一块特定的私有 SQL 区,将他们作为程序运行的命名资源。另 外,oracle 隐含的为一些 SQL 语句产生的递归调用(前面有介绍,读取数据字典 信息)也使用共享 SQL 区。 私有 SQL 区是由用户进程管理的。如何分配和释放私有 SQL 区极大的依赖 与你所使用的应用工具。而用户进程可以分配的私有 SQL 区的数量是由参数 OPEN_CURSORS 控制的,它的默认值是 50。 在游标关闭前或者语句句柄被释放前,私有 SQL 区将一直存在(但其中的 运行区是在语句执行结束时被释放,只有永久区一直存在)下去。应用开发人员 可以通过将所有打开的不再使用的游标都关闭来释放永久区,以减少用户程序所 占用的内存。 1.7.2.1.3 会话内存(Session Memory) 会话内存是一段用于保存会话变量(如登录信息)和其他预会话相关信息的 内存。对于共享服务器模式下,会话内存是共享的,而不是私有的。 对于复杂的查询(如决策支持系统中的查询),运行区的很大一部分被那些Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 内存需求很大的操作分配给 SQL 工作区(SQL Work Area)。这些操作包括: 基于排序的操作(ORDER BY、GROUP BY、ROLLUP、窗口函数); Hash Join Bitmap merge Bitmap create 例如,一个排序操作使用工作区(这时也可叫排序区 Sort Area)来将一部分 数据行在内存排序;而一个 Hash Join 操作则使用工作区(这时也可以叫做 Hash 区 Hash Area)来建立 Hash 表。如果这两种操作所处理的数据量比工作区大, 那就会将输入的数据分成一些更小的数据片,使一些数据片能够在内存中处理, 而其他的就在临时表空间的磁盘上稍后处理。尽管工作区太小时,Bitmap 操作 不会将数据放到磁盘上处理,但是他们的复杂性是和工作区大小成反比的。因此, 总的来说,工作区越大,这些操作就运行越快。 工作区的大小是可以调整的。一般来说,大的工作区能让一些特定的操作性 能更佳,但也会消耗更多的内存。工作区的大小足够适应输入的数据和相关的 SQL 操作所需的辅助的内存就是最优的。如果不满足,因为需要将一部分数据 放到临时表空间磁盘上处理,操作的响应时间会增长。 1.7.2.2 PGA 内存自动管理 SQL 工作区可以是自动的、全局的管理 。DBA 只 要 设 置 参 数 PGA_AGGREGATE_TARGET 给一个实例的 PGA 内存指定总的大小。设置这个 参数后,Oracle 将它作为一个总的全局限制值,尽量使所有 Oracle 服务进程的 PGA 内存总数不超过这个值。 在 这 个 参 数 出 现 之 前 , DBA 要调整参数 SORT_AREA_SIZE 、 HASH_AREA_SIZE, 、 BITMAP_MERGE_AREA_SIZE 和 CREATE_BITMAP_AREA_SIZE(关于这些参数,我们会在后面介绍),使性能 和 PGA 内存消耗最佳。对这些参数的调整是非常麻烦的,因为即要考虑所有相 关的操作,使工作区适合它们输入数据大小,又要使 PGA 内存不消耗过大导致 系统整体性能下降。 9i 以后,通过设置了参数 PGA_AGGREGATE_TARGET,使所有会话的工作 区的大小都是自动分配。同时,所有*_AREA_SIZE 参数都会失效。在任何时候, 实例中可用于工作区的 PGA 内存总数都是基于参数 PGA_AGGREGATE_TARGET 的。工作区内存总数等于参数 PGA_AGGREGATE_TARGET 的值减去系统其他组件(如分配给会话的 PGA 内 存)的内存消耗。分配给 Oracle 进程的 PGA 内存大小是根据它们对内存的需求 情况来的。 参数 WORKAREA_SIZE_POLICY 决定是否使用 PGA_AGGREGATE_TARGET 来管理 PGA 内存。它 有两个 值:AUTO 和 MANUAL。默认是 AUTO,即使用 PGA_AGGREGATE_TARGET 来管理 PGA 内存。其实,从参数 WORKAREA_SIZE_POLICY 的名字上可以看出,Oracle 的 PGA 内存自动管理只会调整工作区部分,而非工作区部分(固定 PGA 区)则不 会受影响。 还有注意一点就是:10g 之前,PGA_AGGREGATE_TARGET 只在专用服务Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 模式下生效。而 10g 以后,PGA 内存自动管理在专有服务模式(Dedicated Server) 和 MTS 下都有效。另外,9i 在 OpenVMS 系统上还不支持 PGA 内存自动管理, 但 10g 支持。 设置了 PGA_AGGREGATE_TARGET 以后,每个进程 PGA 内存的大小也是 受限制的: 串 行 操 作 时 , 每 个 进 程 可 用 的 PGA 内存为 MIN(PGA_AGGREGATE_TARGET * 5%, _pga_max_size/2) , 其 中 隐 含 参 数 _pga_max_size 的默认值是 200M,同样不建议修改它。 并行操作时,并行语句可用的 PGA 内存为 PGA_AGGREGATE_TARGET * 30% / DOP(Degree Of Parallelism 并行度)。 1.7.2.3 专有服务(Dedicated Server)和共享服务(Shared Server) 对 PGA 内存的管理和分配,很大程度上依赖与服务模式。下面这张表显示 了在不同模式下,PGA 内存不同部分的分配的异同: 内存区 专有服务 共享服务 会话内存 私有的 共享的 永久区所在区域 PGA SGA SELECT 语句的运行区所在区域 PGA PGA DML/DDL 语句的运行区所在区 域 PGA PGA 1.7.3 UGA (The User Global Area) PGA 是一段包含一个 Oracle 服务或后台进程的数据和控制信息的内存。 PGA 的大小依赖与系统的配置。 在专用服务(Dedicated Server)模式下,一个服务进程与一个用户进程相关, PGA 就包括了堆空间和 UGA。而 UGA(User Global Area 用户全局区)由用户 会话数据、游标状态和索引区组成。 在共享服务(MTS)模式下,一个共享服务进程被多个用户进程共享,此时 UGA 是 Shared Pool 或 Large Pool 的一部分(依赖与配置)。 许多 DBA 都不理解 PGA 和 UGA 之间的区别。其实这种区别可以简单的理 解为进程和会话直接的区别。在专用服务模式下,进程和会话是一对一的;而在 MTS 模式下,进程和会话是一对多的关系。PGA 是服务于进程的,它包含的是 进程的信息;而 UGA 是服务于会话的,它包含的是会话的信息。因此,MTS 模 式下,PGA 和 UGA 之间的关系也是一对多的。 UGA 中包含了一个会话的信息,包括: 1)打开游标的永久区和运行区; 2)包的状态信息,特别是包的变量; 3)Java 会话的信息; 4)激活的角色; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 5)激活的跟踪事件(ALTER SESSION SET EVENT …); 6)起作用的 NLS 参数(SELECT * FROM NLS_SESSION_PARAMETERS;); 7)所有打开的 db link; 8)会话对于信任的 Oracle 的托管访问标记(mandatory access control (MAC) 和 PGA 一样,UGA 也由两组区组成,固定 UGA 和可变 UGA(或者说 UGA 堆)。固定 UGA 包含了大概 70 个原子变量、小的数据结构以及指向 UGA 堆的 指针。 UGA heap 中的段可以通过表 X$KSMUP 查到(它的结构和 X$KSMSP 相同)。 UGA 堆包含了存储一些固定表(X$表)的永久内存(依赖与特定参数的设置, 如 OPEN_CURSORS,OPEN_LINKS 和 MAX_ENABLED_ROLES)。除此以外, 大部分的 UGA 用于私有 SQL 区。UGA 内存的所在依赖于会话的设置。 在专用服务模式下,会话和进程是一对一的关系,UGA 位于 PGA 中。固定 UGA 是 PGA 中的一段内存段,而 UGA 堆是 PGA 的子堆。 在 MTS 模式下,固定 UGA 是 shared pool 中的一段内存段,而 UGA 堆是 Large Pool 的子堆,如果从 large pool 分配失败,则从 shared pool 中分配。 MTS 模式下,可以通过 Profile 中的 PRIVATE_SGA 项(通过 dba_profiles 查 看)来控制每个 UGA 占用的 SGA 的总的大小,但是不建议这样做。 Oracle 9.2 以后,有一个新的隐含参数:_use_realfree_heap。当设置这个参数 为 true 时,Oracle 会为 CGA、UGA 单独分配堆,而不从 PGA 中分配。它的默 认值为 false,而当设置了 pga_aggregate_target 后,它的值自动被改为 true。 1.7.4 CGA (The Call Global Area) 与其他的全局区不同,CGA(Call Global Area 调用全局区)的存在是瞬间的。 它只存在于一个调用过程中。对于实例的一些低层次的调用需要 CGA,包括: 1)解析一条 SQL 语句; 2)执行一条 SQL 语句; 3)取一条 SELECT 语句的输出值。 如果语句产生了递归调用,则需要为每个递归调用分配一个 CGA。如上所 述,递归调用是在语句解析、优化器产生语句查询计划、DML 操作时需要查询 或修改数据字典信息的调用。 无论 UGA 存在于 PGA 还是 SGA,CGA 都是 PGA 的 subheap。因为无论那 种模式,会话在做调用时总需要一个进行进行处理。这一点很重要,特别是在 MTS 模式下时,如果发现一次调用很久没有响应,则可能需要增加 PGA 的大小。 当然,调用并不是只通过 CGA 中的数据结构来工作。实际上,调用所需要 的大部分的重要数据结构都来自于 UGA。例如私有 SQL 取和排序区都存放在 UGA 中,因为调用结束后,它们是被保留的。CGA 中只包含了那些调用结束后 可以被释放的数据。例如,CGA 中包含了直接 IO 缓存、关于递归调用的信息、 用于表达式评估(产生查询计划时)的的堆空间和其他一些临时数据。 Java 调用内存也分配在 CGA 中。它被分为三部分空间:堆空间、新空间和Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 老空间。在调用期间(调用长短依赖于使用期长短和大小),在新空间和老空间 中的内存段不再使用的内存段将被垃圾收集器回收。 1.7.5 软件代码区(Software Code Area) 软件代码区是一部分用于存放那些正在运行和可以被运行的代码(Oracle 自 身的代码)的内存区。Oracle 代码一般存储在一个不同于用户程序存储区的软件 代码区,而用户程序存储区是排他的、受保护的区域。 软件区的大小一般是固定的,只有 Oracle 软件升级或重装后才会改变。在不 同操作系统下,这部分区域所要求的大小也不同。 软件区是只读的,可以被安装成共享的或非共享的。可能的情况下,Oracle 代码是共享的,这样所有 Oracle 用户都可以直接访问这些代码,而不需要各自 保存一份拷贝在自己的内存中。这样可以节省大量内存并提高整体性能。 而用户程序也可以是共享的或非共享的。一些 Oracle 工具(如 SQL Plus)能 被安装成共享的,但有些不能。如果一台机器运行多个实例,这些实例可以使用 同一个 Oracle 代码区。 另外要注意的是:并不是所有操作系统都能将软件区安装成共享的,如 Windows。 1.8 ASSM (auto segment space management) 1.8.1 官网说明 Logical Storage Structures http://download.oracle.com/docs/cd/E11882_01/server.112/e16508/logica l.htm#CNCPT7668 其中有关 ASSM 的内容如下: Logical Space Management Oracle Database must use logical space management to track and allocate the extents in a tablespace. When a database object requires an extent, the database must have a method of finding and providing it. Similarly, when an object no longer requires an extent, the database must have a method of making the free extent available. Oracle Database manages space within a tablespace based on the type that you create. You can create either of the following types of tablespaces:  Locally managed tablespaces (default) Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 The database uses bitmaps in the tablespaces themselves to manage extents. Thus, locally managed tablespaces have a part of the tablespace set aside for a bitmap. Within a tablespace, the database can manage segments with automatic segment space management (ASSM) or manual segment space management (MSSM).  Dictionary-managed tablespaces The database uses the data dictionary to manage extents (see "Overview of the Data Dictionary"). Figure 12-3 shows the alternatives for logical space management in a tablespace. Figure 12-3 Logical Space Management Description of "Figure 12-3 Logical Space Management" 1.8.1.1 Locally Managed Tablespaces A locally managed tablespace maintains a bitmap in the data file header to track free and used space in the data file body. Each bit corresponds to a group of blocks. When space is allocated or freed, Oracle Database changes the bitmap values to reflect the new status of the blocks. The following graphic is a conceptual representation of bitmap-managed storage. A 1 in the header refers to used space, whereas a 0 refers to free space. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 A locally managed tablespace has the following advantages:  Avoids using the data dictionary to manage extents Recursive operations can occur in dictionary-managed tablespaces if consuming or releasing space in an extent results in another operation that consumes or releases space in a data dictionary table or undo segment.  Tracks adjacent free space automatically In this way, the database eliminates the need to coalesce free extents.  Determines the size of locally managed extents automatically Alternatively, all extents can have the same size in a locally managed tablespace and override object storage options. Note: Oracle strongly recommends the use of locally managed tablespaces with Automatic Segment Space Management. Segment space management is an attribute inherited from the tablespace that contains the segment. Within a locally managed tablespace, the database can manage segments automatically or manually. For example, segments in Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 tablespace users can be managed automatically while segments in tablespace tools are managed manually. 1.8.1.1.1 Automatic Segment Space Management The ASSM method uses bitmaps to manage space. Bitmaps provide the following advantages:  Simplified administration ASSM avoids the need to manually determine correct settings for many storage parameters. Only one crucial SQL parameter controls space allocation: PCTFREE. This parameter specifies the percentage of space to be reserved in a block for future updates (see "Percentage of Free Space in Data Blocks"). ASSM 管理,只需要一个参数:PCTFREE  Increased concurrency Multiple transactions can search separate lists of free data blocks, thereby reducing contention and waits. For many standard workloads, application performance with ASSM is better than the performance of a well-tuned application that uses MSSM.  Dynamic affinity of space to instances in an Oracle Real Application Clusters (Oracle RAC) environment ASSM is more efficient and is the default for permanent, locally managed tablespaces. Note: This chapter assumes the use of ASSM in all of its discussions of logical storage space. 1.8.1.1.2 Manual Segment Space Management The legacy MSSM method uses a linked list called a free list to manage free space in the segment. For a database object that has free space, a free list keeps track of blocks under the high water mark (HWM), which is the dividing Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 line between segment space that is used and not yet used. As blocks are used, the database puts blocks on or removes blocks from the free list as needed. In addition to PCTFREE, MSSM requires you to control space allocation with SQL parameters such as PCTUSED, FREELISTS, and FREELIST GROUPS. PCTUSED sets the percentage of free space that must exist in a currently used block for the database to put it on the free list. For example, if you set PCTUSED to 40 in a CREATE TABLE statement, then you cannot insert rows into a block in the segment until less than 40% of the block space is used. As an illustration, suppose you insert a row into a table. The database checks a free list of the table for the first available block. If the row cannot fit in the block, and if the used space in the block is greater than or equal to PCTUSED, then the database takes the block off the list and searches for another block. If you delete rows from the block, then the database checks whether used space in the block is now less than PCTUSED. If so, then the database places the block at the beginning of the free list. An object may have multiple free lists. In this way, multiple sessions performing DML on a table can use different lists, which can reduce contention. Each database session uses only one free list for the duration of its session. As shown in Figure 12-4, you can also create an object with one or more free list groups, which are collections of free lists. Each group has a master free list that manages the individual process free lists in the group. Space overhead for free lists, especially for free list groups, can be significant. Figure 12-4 Free List Groups Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Description of "Figure 12-4 Free List Groups" Managing segment space manually can be complex. You must adjust PCTFREE and PCTUSED to reduce row migration (see "Chained and Migrated Rows") and avoid wasting space. For example, if every used block in a segment is half full, and if PCTUSED is 40, then the database does not permit inserts into any of these blocks. Because of the difficulty of fine-tuning space allocation parameters, Oracle strongly recommends ASSM. In ASSM, PCTFREE determines whether a new row can be inserted into a block, but it does not use free lists and ignores PCTUSED. -- ASSM 会忽略 PCTUSED 参数 1.8.1.2 Dictionary-Managed Tablespaces A dictionary-managed tablespace uses the data dictionary to manage its extents. Oracle Database updates tables in the data dictionary whenever an extent is allocated or freed for reuse. For example, when a table needs an extent, the database queries the data dictionary tables, and searches for free extents. If the database finds space, then it modifies one data dictionary table and inserts a row into another. In this way, the database manages space by modifying and moving data. The SQL that the database executes in the background to obtain space for database objects is recursive SQL. Frequent use of recursive SQL can have a negative impact on performance because updates to the data dictionary must Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 be serialized. Locally managed tablespaces, which are the default, avoid this performance problem. 1.8.2 ASSM 说明 在 Orale 9i 以前,表的剩余空间的管理与分配都是由链接列表 freelist 来完 成的,因为 freelist 存在串行的问题因此容易引起往往容易引起段头的争用与空 间的浪费(其实这一点并不明显),最主要的还是因为需要 DBA 花费大量的精 力去管理这些争用并监控表的空间利用。 自动段空间管理(ASSM),它首次出现在 Oracle 9.2 里。有了 ASSM,链 接列表 freelist 被位图所取代,它是一个二进制的数组,能够迅速有效地管理存 储扩展和剩余区块(free block),因此能够改善分段存储本质,ASSM 表空间上 创建的段还有另外一个称呼叫 Bitmap Managed Segments(BMB 段)。 让我们看看位图 freelist 是如何实现的。从使用区段空间管理自动参数创建 tablespace 开始: create tablespace demo datafile '/ora01/oem/demo01.dbf ' size 5m EXTENT MANAGEMENT LOCAL -- Turn on LMT SEGMENT SPACE MANAGEMENT AUTO -- Turn on ASSM; 一旦定义好了 tablespace,那么表和索引就能够使用各种方法很容易地被移 动到新的 tablespace 里,带有 ASSM 的本地管理 tablespace 会略掉任何为 PCTUSED、NEXT 和 FREELISTS 所指定的值。 当表格或者索引被分配到这个 tablespace 以后,用于独立对象的 PCTUSED 的值会被忽略,而 Oracle9i 会使用位图数组来自动地管理 tablespace 里表格和 索引的 freelist。对于在 LMT 的 tablespace 内部创建的表格和索引而言,这个 NEXT 扩展子句是过时的,因为由本地管理的 tablespace 会管理它们。但是, INITIAL 参数仍然是需要的,因为 Oracle 不可能提前知道初始表格加载的大小。 对于 ASSM 而言,INITIAL 最小的值是三个块。 新的管理机制用位图来跟踪或管理每个分配到对象的块,每个块有多少剩余 空间根据位图的状态来确定,如>75%,50%-75%,25%-50%和<25%,也就是说 位图其实采用了四个状态位来代替以前的 pctused,什么时候该利用该数据块则 由设定的 pctfree 来确定。 使用 ASSM 的一个巨大优势是,位图 freelist 肯定能够减轻缓冲区忙等待 (buffer busy wait)的负担,这个问题在 Oracle9i 以前的版本里曾是一个严重 的问题 。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 在没有多个 freelist 的时候,每个 Oracle 表格和索引在表格的头部都曾有一 个数据块,用来管理对象所使用的剩余区块,并为任何 SQL 插入声明所创建的 新数据行提供数据块。当数据缓冲内的数据块由于被另一个 DML 事务处理锁定 而无法使用的时候,缓冲区忙等待就会发生。当你需要将多个任务插入到同一个 表格里的时候,这些任务就被强制等待,而同时 Oracle 会在同时分派剩余的区 块,一次一个。 有了 ASSM 之后,Oracle 宣称显著地提高了 DML 并发操作的性能,因为(同 一个)位图的不同部分可以被同时使用,这样就消除了寻找剩余空间的串行化。 根据 Oracle 的测试结果,使用位图 freelist 会消除所有分段头部(对资源)的争 夺,还能获得超快的并发插入操作 尽管 ASSM 显示出了令人激动的特性并能够简化 Oracle DBA 的工作,但是 Oracle9i 的位图分段管理还是有一些局限性的: 1. 一旦 DBA 被分配之后,它就无法控制 tablespace 内部的独立表格和索引 的存储行为。 2. 大型对象不能够使用 ASSM,而且必须为包含有 LOB 数据类型的表格创 建分离的 tablespace。 3. 你不能够使用 ASSM 创建临时的 tablespace。这是由排序时临时分段的 短暂特性所决定的。 4. 只有本地管理的 tablespace 才能够使用位图分段管理。 5· 使用超高容量的 DML(例如 INSERT、UPDATE 和 DELETE 等)的时候 可能会出现性能上的问题。 1.8.3 相关测试 1、我们先创建一个本地管理的表空间,采用段自动管理方式 /* Formatted on 2009-12-7 19:17:33 (QP5 v5.115.810.9015) */ CREATE TABLESPACE demo DATAFILE 'D:\demo01.dbf' SIZE 50M EXTENT MANAGEMENT LOCAL --一定是本地管理 SEGMENT SPACE MANAGEMENT AUTO; --ASSM管理的标志 2、创建同样一个表 /* Formatted on 2009-12-7 19:18:00 (QP5 v5.115.810.9015) */ CREATE TABLE demotab (x NUMBER) TABLESPACE demo STORAGE (INITIAL 1000 K); 我们指定初试区间大小是1000K Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 /* Formatted on 2009-12-7 19:18:37 (QP5 v5.115.810.9015) */ SELECT t.table_name, t.initial_extent, t.next_extent, t.pct_free, t.pct_used FROM user_tables t WHERE t.table_name = 'DEMOTAB'; TABLE_NAME INITIAL_EXTENT NEXT_EXTENT PCT_FREE PCT_USED ----------------------- -------------- --------------- ---------------- ------------------- DEMOTAB 1024000 10 可以看到,NEXT_EXTENT 与 PCT_USED 都为空。 3、执行该过程,检查表的初始状态 exec show_space('demotab','auto','T','Y'); --show_space() 代码见 6.5 节。 Total Blocks............................128 Total Bytes.............................1048576 Unused Blocks...........................125 Unused Bytes............................1024000 Last Used Ext FileId....................7 Last Used Ext BlockId...................9 Last Used Block.........................3 ************************************************* The segment is analyzed 0% -- 25% free space blocks.............0 0% -- 25% free space bytes..............0 25% -- 50% free space blocks............0 25% -- 50% free space bytes.............0 50% -- 75% free space blocks............0 50% -- 75% free space bytes.............0 75% -- 100% free space blocks...........0 75% -- 100% free space bytes............0 Unused Blocks...........................0 Unused Bytes............................0 Total Blocks............................0 Total bytes.............................0 从这里我们能看到一些该表的特性,其中最引人注意的就是表头了,占用了Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 三个块的大小(128-125) 另外一个注意的地方就是该表从第9个块开始,文件头占用了64K的空间等于 8个块。 我们从dba_extent中也能看到这样的信息,是从第9个块开始的。 /* Formatted on 2009-12-7 19:24:23 (QP5 v5.115.810.9015) */ SELECT t.segment_name, t.extent_id, t.block_id FROM dba_extents t WHERE t.segment_name = 'DEMOTAB'; SEGMENT_NAME EXTENT_ID BLOCK_ID --------------- ---------- ---------- DEMOTAB 0 9 DEMOTAB 1 17 DEMOTAB 2 25 DEMOTAB 3 33 DEMOTAB 4 41 DEMOTAB 5 49 DEMOTAB 6 57 DEMOTAB 7 65 DEMOTAB 8 73 DEMOTAB 9 81 DEMOTAB 10 89 DEMOTAB 11 97 DEMOTAB 12 105 DEMOTAB 13 113 DEMOTAB 14 121 DEMOTAB 15 129 从这里可以看到,第一个区间的开始块是 9 4、我直接开始分析第 9,10,11 个块(段头) SQL> alter system dump datafile 7 block 9; System altered SQL> alter system dump datafile 7 block 10; System altered SQL> alter system dump datafile 7 block 11; System altered 进入 Udump 查看刚才生成的 trace 文件 *** 2009-12-07 19:30:16.406 *** SERVICE NAME:(DBA.ANQINGREN.ORG) 2009-12-07 19:30:16.390 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 *** SESSION ID:(123.758) 2009-12-07 19:30:16.390 Start dump data blocks tsn: 8 file#: 7 minblk 9 maxblk 9 buffer tsn: 8 rdba: 0x01c00009 (7/9) scn: 0x0000.001a0da0 seq: 0x01 flg: 0x04 tail: 0x0da02001 frmt: 0x02 chkval: 0x44e6 type: 0x20=FIRST LEVEL BITMAP BLOCK Hex dump of block: st=0, typ_found=1 Dump of memory from 0x085C8400 to 0x085CA400 85C8400 0000A220 01C00009 001A0DA0 04010000 [ ...............] 85C8410 000044E6 00000000 00000000 00000000 [.D..............] 85C8420 00000000 00000000 00000000 00000000 [................] Repeat 1 times 85C8440 00000000 00000000 00000000 00000004 [................] 85C8450 FFFFFFFF 0000000D 00000003 00000010 [................] 85C8460 00010002 00000000 00000000 00000000 [................] 85C8470 00000000 00000003 00000000 00000000 [................] 85C8480 00000000 00000000 00000000 00000000 [................] 85C8490 01C0000A 00000000 00000000 00000003 [................] 85C84A0 00000008 01C0000C 00000000 00000000 [................] 85C84B0 00000000 00000000 00000000 00000001 [................] 85C84C0 0000D302 00000000 00000000 01C00009 [................] 85C84D0 00000008 00000000 01C00011 00000008 [................] 85C84E0 00000008 00000000 00000000 00000000 [................] 85C84F0 00000000 00000000 00000000 00000000 [................] Repeat 8 times 85C8580 00000000 00000000 00000000 00001011 [................] 85C8590 00000000 00000000 00000000 00000000 [................] Repeat 485 times 85CA3F0 00000000 00000000 00000000 0DA02001 [............. ..] Dump of First Level Bitmap Block -------------------------------- nbits : 4 nranges: 2 parent dba: 0x01c0000a poffset: 0 unformatted: 13 total: 16 first useful block: 3 owning instance : 1 instance ownership changed at Last successful Search Freeness Status: nf1 0 nf2 0 nf3 0 nf4 0 Extent Map Block Offset: 4294967295 First free datablock : 3 Bitmap block lock opcode 0 Locker xid: : 0x0000.000.00000000 Inc #: 0 Objd: 54018 HWM Flag: HWM Set Highwater:: 0x01c0000c ext#: 0 blk#: 3 ext size: 8 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 #blocks in seg. hdr's freelists: 0 #blocks below: 0 mapblk 0x00000000 offset: 0 -------------------------------------------------------- DBA Ranges : -------------------------------------------------------- 0x01c00009 Length: 8 Offset: 0 0x01c00011 Length: 8 Offset: 8 0:Metadata 1:Metadata 2:Metadata 3:unformatted 4:unformatted 5:unformatted 6:unformatted 7:unformatted 8:unformatted 9:unformatted 10:unformatted 11:unformatted 12:unformatted 13:unformatted 14:unformatted 15:unformatted -------------------------------------------------------- End dump data blocks tsn: 8 file#: 7 minblk 9 maxblk 9 *** 2009-12-07 19:35:44.296 Start dump data blocks tsn: 8 file#: 7 minblk 10 maxblk 10 buffer tsn: 8 rdba: 0x01c0000a (7/10) scn: 0x0000.001a0dc1 seq: 0x01 flg: 0x04 tail: 0x0dc12101 frmt: 0x02 chkval: 0x5439 type: 0x21=SECOND LEVEL BITMAP BLOCK Hex dump of block: st=0, typ_found=1 Dump of memory from 0x085C8400 to 0x085CA400 85C8400 0000A221 01C0000A 001A0DC1 04010000 [!...............] 85C8410 00005439 00000000 00000000 00000000 [9T..............] 85C8420 00000000 00000000 00000000 00000000 [................] Repeat 1 times 85C8440 00000000 00000000 00000000 01C0000B [................] 85C8450 00000008 00000008 00000000 00000000 [................] 85C8460 00000000 00000000 0000D302 00000001 [................] 85C8470 00000000 01C00009 00010005 01C00019 [................] 85C8480 00010005 01C00029 00010005 01C00039 [....).......9...] 85C8490 00010005 01C00049 00010005 01C00059 [....I.......Y...] 85C84A0 00010005 01C00069 00010005 01C00079 [....i.......y...] 85C84B0 00010005 00000000 00000000 00000000 [................] 85C84C0 00000000 00000000 00000000 00000000 [................] Repeat 498 times 85CA3F0 00000000 00000000 00000000 0DC12101 [.............!..] Dump of Second Level Bitmap Block number: 8 nfree: 8 ffree: 0 pdba: 0x01c0000b Inc #: 0 Objd: 54018 opcode:0 xid: L1 Ranges : -------------------------------------------------------- Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 0x01c00009 Free: 5 Inst: 1 0x01c00019 Free: 5 Inst: 1 0x01c00029 Free: 5 Inst: 1 0x01c00039 Free: 5 Inst: 1 0x01c00049 Free: 5 Inst: 1 0x01c00059 Free: 5 Inst: 1 0x01c00069 Free: 5 Inst: 1 0x01c00079 Free: 5 Inst: 1 -------------------------------------------------------- End dump data blocks tsn: 8 file#: 7 minblk 10 maxblk 10 Start dump data blocks tsn: 8 file#: 7 minblk 11 maxblk 11 buffer tsn: 8 rdba: 0x01c0000b (7/11) scn: 0x0000.001a0dc6 seq: 0x01 flg: 0x04 tail: 0x0dc62301 frmt: 0x02 chkval: 0x79ad type: 0x23=PAGETABLE SEGMENT HEADER Hex dump of block: st=0, typ_found=1 Dump of memory from 0x085C8400 to 0x085CA400 85C8400 0000A223 01C0000B 001A0DC6 04010000 [#...............] 85C8410 000079AD 00000000 00000000 00000000 [.y..............] 85C8420 00000000 00000010 00000080 00000A9C [................] 85C8430 00000000 00000003 00000008 01C0000C [................] 85C8440 00000000 00000000 00000000 00000000 [................] Repeat 1 times 85C8460 00000003 00000008 01C0000C 00000000 [................] 85C8470 00000000 00000000 00000000 01C00009 [................] 85C8480 01C00009 00000000 00000000 00000000 [................] 85C8490 00000000 00000000 00000000 00000000 [................] Repeat 3 times 85C84D0 00000001 00002000 00000000 00001434 [..... ......4...] 85C84E0 00000000 01C0000A 00000001 01C00079 [............y...] 85C84F0 01C0000A 00000000 00000000 00000000 [................] 85C8500 00000000 00000000 00000010 00000000 [................] 85C8510 0000D302 10000000 01C00009 00000008 [................] 85C8520 01C00011 00000008 01C00019 00000008 [................] 85C8530 01C00021 00000008 01C00029 00000008 [!.......).......] 85C8540 01C00031 00000008 01C00039 00000008 [1.......9.......] 85C8550 01C00041 00000008 01C00049 00000008 [A.......I.......] 85C8560 01C00051 00000008 01C00059 00000008 [Q.......Y.......] 85C8570 01C00061 00000008 01C00069 00000008 [a.......i.......] 85C8580 01C00071 00000008 01C00079 00000008 [q.......y.......] 85C8590 01C00081 00000008 00000000 00000000 [................] 85C85A0 00000000 00000000 00000000 00000000 [................] Repeat 144 times 85C8EB0 01C00009 01C0000C 01C00009 01C00011 [................] Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 85C8EC0 01C00019 01C0001A 01C00019 01C00021 [............!...] 85C8ED0 01C00029 01C0002A 01C00029 01C00031 [)...*...)...1...] 85C8EE0 01C00039 01C0003A 01C00039 01C00041 [9...:...9...A...] 85C8EF0 01C00049 01C0004A 01C00049 01C00051 [I...J...I...Q...] 85C8F00 01C00059 01C0005A 01C00059 01C00061 [Y...Z...Y...a...] 85C8F10 01C00069 01C0006A 01C00069 01C00071 [i...j...i...q...] 85C8F20 01C00079 01C0007A 01C00079 01C00081 [y...z...y.......] 85C8F30 00000000 00000000 00000000 00000000 [................] Repeat 144 times 85C9840 00000000 00000000 01C0000A 00000000 [................] 85C9850 00000000 00000000 00000000 00000000 [................] Repeat 185 times 85CA3F0 00000000 00000000 00000000 0DC62301 [.............#..] Extent Control Header ----------------------------------------------------------------- Extent Header:: spare1: 0 spare2: 0 #extents: 16 #blocks: 128 last map 0x00000000 #maps: 0 offset: 2716 Highwater:: 0x01c0000c ext#: 0 blk#: 3 ext size: 8 #blocks in seg. hdr's freelists: 0 #blocks below: 0 mapblk 0x00000000 offset: 0 Unlocked -------------------------------------------------------- Low HighWater Mark : Highwater:: 0x01c0000c ext#: 0 blk#: 3 ext size: 8 #blocks in seg. hdr's freelists: 0 #blocks below: 0 mapblk 0x00000000 offset: 0 Level 1 BMB for High HWM block: 0x01c00009 Level 1 BMB for Low HWM block: 0x01c00009 -------------------------------------------------------- Segment Type: 1 nl2: 1 blksz: 8192 fbsz: 0 L2 Array start offset: 0x00001434 First Level 3 BMB: 0x00000000 L2 Hint for inserts: 0x01c0000a Last Level 1 BMB: 0x01c00079 Last Level II BMB: 0x01c0000a Last Level III BMB: 0x00000000 Map Header:: next 0x00000000 #extents: 16 obj#: 54018 flag: 0x10000000 Inc # 0 Extent Map ----------------------------------------------------------------- 0x01c00009 length: 8 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 0x01c00011 length: 8 0x01c00019 length: 8 0x01c00021 length: 8 0x01c00029 length: 8 0x01c00031 length: 8 0x01c00039 length: 8 0x01c00041 length: 8 0x01c00049 length: 8 0x01c00051 length: 8 0x01c00059 length: 8 0x01c00061 length: 8 0x01c00069 length: 8 0x01c00071 length: 8 0x01c00079 length: 8 0x01c00081 length: 8 Auxillary Map -------------------------------------------------------- Extent 0 : L1 dba: 0x01c00009 Data dba: 0x01c0000c Extent 1 : L1 dba: 0x01c00009 Data dba: 0x01c00011 Extent 2 : L1 dba: 0x01c00019 Data dba: 0x01c0001a Extent 3 : L1 dba: 0x01c00019 Data dba: 0x01c00021 Extent 4 : L1 dba: 0x01c00029 Data dba: 0x01c0002a Extent 5 : L1 dba: 0x01c00029 Data dba: 0x01c00031 Extent 6 : L1 dba: 0x01c00039 Data dba: 0x01c0003a Extent 7 : L1 dba: 0x01c00039 Data dba: 0x01c00041 Extent 8 : L1 dba: 0x01c00049 Data dba: 0x01c0004a Extent 9 : L1 dba: 0x01c00049 Data dba: 0x01c00051 Extent 10 : L1 dba: 0x01c00059 Data dba: 0x01c0005a Extent 11 : L1 dba: 0x01c00059 Data dba: 0x01c00061 Extent 12 : L1 dba: 0x01c00069 Data dba: 0x01c0006a Extent 13 : L1 dba: 0x01c00069 Data dba: 0x01c00071 Extent 14 : L1 dba: 0x01c00079 Data dba: 0x01c0007a Extent 15 : L1 dba: 0x01c00079 Data dba: 0x01c00081 -------------------------------------------------------- Second Level Bitmap block DBAs -------------------------------------------------------- DBA 1: 0x01c0000a End dump data blocks tsn: 8 file#: 7 minblk 11 maxblk 11 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.9 ADDM Blog: http://blog.csdn.net/tianlesoftware/archive/2010/05/28/5630942.aspx 1.9.1 ADDM 概述 ADDM(Automatic Database Diagnostic Monitor) 是植入 Oracle 数据库的一 个自诊断引擎.ADDM 通过检查和分析 AWR 获取的数据来判断 Oracle 数据库中 可能的问题. 在 Oracle9i 及之前,DBA 们已经拥有了很多很好用的性能分析工具,比如, tkprof、sql_trace、statspack、set event 10046&10053 等等。这些工具能够帮助 DBA 很快的定位性能问题。但这些工具都只给出一些统计数据,然后再由 DBA 们根 据自己的经验进行优化。 Oracle10g 中推出了新的优化诊断工具: 数据库自动诊断监视工具 (Automatic Database Diagnostic Monitor :ADDM)和 SQL 优化建议工具(SQL Tuning Advisor: STA)。这两个工具的结合使用,能使 DBA 节省大量优化时间, 也大大减少了系统宕机的危险。简单点说,ADDM 就是收集相关的统计数据到 自动工作量知识库(Automatic Workload Repository :AWR)中,而 STA 则根据这些 数据,给出优化建议。 例如,一个系统资源紧张,出现了明显的性能问题,由以往的办法,做个一 个 statspack 快照,等 30 分钟,再做一次。查看报告,发现‘ db file scattered read‘ 事件在 top 5 events 里面。根据经验,这个事件一般可能是因为缺少索引、统计 分析信息不够新、热表都放在一个数据文件上导致 IO 争用等原因引起的。根据 这些经验,我们需要逐个来定位排除,比如查看语句的查询计划、查看 user_tables 的 last_analysed 子段,检查热块等等步骤来最后定位出原因,并给出优化建议。 但是,有了 STA 以后,它就可以根据 ADDM 采集到的数据直接给出优化建议, 甚至给出优化后的语句。 ADDM 能发现定位的问题包括: •操作系统内存页入页出问题 •由于 Oracle 负载和非 Oracle 负载导致的 CPU 瓶颈问题 •导致不同资源负载的 Top SQL 语句和对象——CPU 消耗、IO 带宽占用、潜在 IO 问题、RAC 内部通讯繁忙 •按照 PLSQL 和 JAVA 执行时间排的 Top SQL 语句. •过多地连接 (login/logoff). •过多硬解析问题——由于 shared pool 过小、书写问题、绑定大小不适应、解析 失败原因引起的。 •过多软解析问题 •索引查询过多导致资源争用. •由于用户锁导致的过多的等待时间 (通过包 dbms_lock 加的锁) •由于 DML 锁导致的过多等待时间(例如锁住表了) •由于管道输出导致的过多等待时间(如通过包 dbms_pipe.put 进行管道输出) Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 •由于并发更新同一个记录导致的过多等待时间(行级锁等待) •由于 ITL 不够导致的过多等待时间(大量的事务操作同一个数据块) •系统中过多的 commit 和 rollback(logfile sync 事件). •由于磁盘带宽太小和其他潜在问题(如由于 logfile 太小导致过多的 checkpoint, MTTR 设置问题,过多的 undo 操作等等)导致的 IO 性能问题 I •对于 DBWR 进程写数据块,磁盘 IO 吞吐量不足 •由于归档进程无法跟上 redo 日至产生的速度,导致系统变慢 •redo 数据文件太小导致的问题 •由于扩展磁盘分配导致的争用 •由于移动一个对象的高水位导致的争用问题 •内存太小问题——SGA Target, PGA, Buffer Cache, Shared Pool •在一个实例或者一个机群环境中存在频繁读写争用的热块 •在一个实例或者一个机群环境中存在频繁读写争用的热对象 •RAC 环境中内部通讯问题 •LMS 进程无法跟上导致锁请求阻塞 •在 RAC 环境中由于阻塞和争用导致的实例倾斜 •RMAN 导致的 IO 和 CPU 问题 •Streams 和 AQ 问题 •资源管理等待事件 ADDM 提供了一个整体的优化方案.基于一段时间内的 AWR snapshots(默认 一小时一次)可以执行 ADDM 分析,它可以帮我们诊断在这段期间内数据库可能 存在的瓶颈. ADDM 分析的目标是减小吞吐量的度量值, 在这里我们将它称为"DB TIME". DB TIME是一个累积值(数据库服务器处理用户请求所花费的时间). 它包括了等 待时间和 CPU 处理的时间(针对所有活跃的用户进程而言),可以通过查询下面两 个视图来获得它的值: V$SESS_TIME_MODEL, V$SYS_TIME_MODEL. AWR 收集的数据时放到内存中(share pool),通过一个新的后台进程 MMON 定期写到磁盘中。所以 10g 的 share pool 要求比以前版本更大,一般推荐比以前 大 15-20%。 注意: ADDM 不会将处理用户响应时间作为调优的目标, 你应该使用"TRACE" 技术来监控它. 通过减小"DB TIME", 使用同样多的系统资源,数据库服务器可以处理更多 的用户请求,也就是提高了吞吐量. 通过 ADDM 报告的问题是按照 DB time 排序 的. 1.9.2 ADDM 分析的结果 ADDM 分析的结果以一些"Finding"的样式来表达. 每个"Finding"都属于以 下三种类型之一: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1. 问题: 描述了导致数据库性能问题的根源; 2. 征兆: 包含了可能导致其他问题的信息 3. 信息: 报告其他没有问题的模块 1.9.3 设置 ADDM 缺省情况下,ADDM 已 经 被 自 动 启 用 , 通过初始化参数文件中的 STATISTICS_LEVEL 来控制. 这个参数应该被设置成TYPICAL或者ALL(缺省值是TYPICAL).如果你将这 个参数设置成 basic,很多 Oracle 的特性将被屏蔽. ALTER SESSION SET STATISTICS_LEVEL= TYPICAL; ADDM 对于 I/O 性能的评估分析在部分程度上依赖于这个 DBIO_EXPECTED. 这个参数的含义是读取一个数据块所花费的平均时间(以微 秒为单位). Oracle 使用的是缺省值(10 毫秒), 对于现在流行的硬盘来说, 这是一 个比较合适的值.如果你的硬盘比较陈旧,或者你有一个非常好的 RAM DISK,请 修改这个值. 为了决定 DBIO_EXPECTED 这个参数该怎样去正确地配置,需要完成下面的步 骤: 1. 基于你的机器的硬件,估量一下读取单个数据库块所花费的平均时间. 注意:这个度量应该针对随机的 I/O(包括寻道的时间).传统的值应该属于 5000-20000 微秒这个区间. 2. 为接下来的 ADDM 执行设置一个时间参数. 例如:如果估计的值是 8000 微秒, 你应该以 SYS 的身份执行下面的过程: EXECUTE DBMS_ADVISOR.SET_DEFAULT_PARAMETER ('ADDM','DBIO_EXPECTED',8000); 1.9.4 通过 Oracle Enterprise Manager 来访问 ADDM 1.9.5 诊断与 ADDM 相关的问题 为了诊断数据库性能问题, ADDM 分析可以跨越任意两个 snapshots,只要它 们满足下面两个条件: 1. 两个快照在创建过程中没有错误并且没有被删除; 2. 两个快照期间数据库不能发生关闭和启动的事件 (同 statspack). 最简单的运行 ADDM 分析的方法就是运行 Enterprise Manager. 另外, 也可以手 工 地 执 行 $ORACLE_HOME/rdbms/admin/addmrpt.sql 以及Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 dbms_advisor 包. 这些脚本和包可以被任何用户执行,只要它们被赋予了 ADVISOR 的角色. 5.1 使用 addmrpt.sql 来运行 和 statspack 包中的 spreport.sql 非常相似 5.2 使用 dbms_advisor 包: 关于该包的详细用法参考官方文档: DBMS_ADVISOR http://download.oracle.com/docs/cd/E11882_01/appdev.112/e16760/d_advis.htm #ARPLS350 在后面的示例中也有简单的使用。 1.9.6 与 ADDM 相关的视图 DBA_ADVISOR_TASKS DBA_ADVISOR_LOG DBA_ADVISOR_RECOMMENDATIONS DBA_ADVISOR_FINDINGS 1.9.7 工作采集、诊断过程 Oracle10g 提供了一个图形化的界面(通过 OEM),使这个工具使用起来非 常简单。下面这里介绍一下如何通过 sqlplus 使用这个工具。 第一步:创建测试用的表 SQL> CREATE TABLE bigtab AS SELECT rownum as "id", a.* FROM dba_objects a; Table created. SQL> create table smalltab as select rownum as "id", a.* FROM dba_tables a; Table created. SQL> ALTER TABLE bigtab MODIFY (empno NUMBER); Table altered. SQL> DECLARE 2 n NUMBER; 3 BEGIN 4 FOR n IN 1..100 5 LOOP 6 INSERT INTO bigtab SELECT rownum as "id", a.* FROM dba_objects a; 7 COMMIT; 8 END LOOP; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 9 END; / PL/SQL procedure successfully completed. 第二步:采集一次工作量快照 SQL> begin 2 dbms_workload_repository.create_snapshot('TYPICAL'); 3 end; 4 / PL/SQL procedure successfully completed. 第三步:进行一些高负荷操作 DECLARE v_var number; BEGIN FOR n IN 1..6 LOOP select count(*) into v_var from bigtab b, smalltab a; END LOOP; END; / PL/SQL procedure successfully completed. 第四步:再次采集一次工作量快照 要注意的是:两次快照之间的间隔时间必须足够(一般推荐 30 分钟左右),否则 得到的 ADDM 报告中就会提示:THERE WAS NOT ENOUGH DATABASE TIME FOR ADDM ANALYSIS. SQL> begin 2 dbms_workload_repository.create_snapshot('TYPICAL'); 3 end; 4 / PL/SQL procedure successfully completed. 第五步:创建一个优化诊断任务并执行 先获取到两次快照的 ID: SQL> select snap_id from 2 (SELECT * FROM dba_hist_snapshot 3 ORDER BY snap_id desc) 4 where rownum <=2; SNAP_ID -------- 66 65 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 然后创建优化任务,并执行。 DECLARE task_name VARCHAR2(30) := 'DEMO_ADDM01'; task_desc VARCHAR2(30) := 'ADDM Feature Test'; task_id NUMBER; BEGIN dbms_advisor.create_task('ADDM', task_id, task_name, task_desc, null); dbms_advisor.set_task_parameter(task_name, 'START_SNAPSHOT', 65); dbms_advisor.set_task_parameter(task_name, 'END_SNAPSHOT', 66); dbms_advisor.set_task_parameter(task_name, 'INSTANCE', 1); dbms_advisor.set_task_parameter(task_name, 'DB_ID', 1712582900); dbms_advisor.execute_task(task_name); END; / PL/SQL procedure successfully completed. DBID 查看 sql SQL> select dbid from v$database; DBID ---------- 1712582900 其中,set_task_parameter 是用来设置任务参数的。START_SNAPSHOT 是起始快 照 ID,END_SNAPSHOT 是结束快照 ID,INSTANCE 是实例号,对于单实例, 一般是 1,在 RAC 环境下,可以通过查询视图 v$instance 得到,DB_ID 是数据 库的唯一识别号,可以通过查询 v$database 查到。 第六步:查看优化建议结果 通知函数 dbms_advisor.get_task_report 可以得到优化建议结果。 SQL> SET LONG 1000000 PAGESIZE 0 LONGCHUNKSIZE 1000 SQL> COLUMN get_clob FORMAT a80 SQL> SELECT dbms_advisor.get_task_report('DEMO_ADDM01', 'TEXT', 'ALL') FROM DUAL; DBMS_ADVISOR.GET_TASK_REPORT(' -------------------------------------------------------------------------------- DETAILED ADDM REPORT FOR TASK 'DEMO_ADDM01' WITH ID 243 ------------------------------------------------------- Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Analysis Period: 23-NOV-2005 from 15:02:27 to 16:06:42 Database ID/Instance: 1712582900/1 Database/Instance Names: EDGAR/edgar Host Name: HUANGED Database Version: 10.2.0.1.0 Snapshot Range: from 65 to 66 Database Time: 1463 seconds Average Database Load: .4 active sessions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ FINDING 1: 100% impact (1463 seconds) ------------------------------------- Significant virtual memory paging was detected on the host operating system. RECOMMENDATION 1: Host Configuration, 100% benefit (1463 seconds) ACTION: Host operating system was experiencing significant paging but no particular root cause could be detected. Investigate processes that do not belong to this instance running on the host that are consuming significant amount of virtual memory. Also consider adding more physical memory to the host. FINDING 2: 100% impact (1463 seconds) ------------------------------------- SQL statements consuming significant database time were found. RECOMMENDATION 1: SQL Tuning, 68% benefit (998 seconds) ACTION: Tune the PL/SQL block with SQL_ID "064wqx7c5b81z". Refer to the "Tuning PL/SQL Applications" chapter of Oracle's "PL/SQL User's Guide and Reference" RELEVANT OBJECT: SQL statement with SQL_ID 064wqx7c5b81z DECLARE v_var number; BEGIN FOR n IN 1..10000 LOOP select count(*) into v_var from bigtab b, smalltab a; END LOOP; END; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 RECOMMENDATION 2: SQL Tuning, 67% benefit (986 seconds) ACTION: Run SQL Tuning Advisor on the SQL statement with SQL_ID "fvqfghq71cqns". RELEVANT OBJECT: SQL statement with SQL_ID fvqfghq71cqns and PLAN_HASH 3281046854 SELECT COUNT(*) FROM BIGTAB B, SMALLTAB A RATIONALE: SQL statement with SQL_ID "fvqfghq71cqns" was executed 6 times and had an average elapsed time of 166 seconds. FINDING 3: 69% impact (1002 seconds) ------------------------------------ Time spent on the CPU by the instance was responsible for a substantial part of database time. RECOMMENDATION 1: SQL Tuning, 67% benefit (986 seconds) ACTION: Run SQL Tuning Advisor on the SQL statement with SQL_ID "fvqfghq71cqns". RELEVANT OBJECT: SQL statement with SQL_ID fvqfghq71cqns and PLAN_HASH 3281046854 SELECT COUNT(*) FROM BIGTAB B, SMALLTAB A RATIONALE: SQL statement with SQL_ID "fvqfghq71cqns" was executed 6 times and had an average elapsed time of 166 seconds. RATIONALE: Average CPU used per execution was 162 seconds. RECOMMENDATION 2: SQL Tuning, 2.1% benefit (30 seconds) ACTION: Tune the PL/SQL block with SQL_ID "2b064ybzkwf1y". Refer to the "Tuning PL/SQL Applications" chapter of Oracle's "PL/SQL User's Guide and Reference" RELEVANT OBJECT: SQL statement with SQL_ID 2b064ybzkwf1y BEGIN EMD_NOTIFICATION.QUEUE_READY(:1, :2, :3); END; RATIONALE: SQL statement with SQL_ID "2b064ybzkwf1y" was executed 125 times and had an average elapsed time of 0.26 seconds. RATIONALE: Average CPU used per execution was 0.24 seconds. FINDING 4: 2.2% impact (33 seconds) ----------------------------------- PL/SQL execution consumed significant database time. RECOMMENDATION 1: SQL Tuning, 2.2% benefit (33 seconds) ACTION: Tune the PL/SQL block with SQL_ID "2b064ybzkwf1y". Refer to the "Tuning PL/SQL Applications" chapter of Oracle's "PL/SQL User's Guide Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 and Reference" RELEVANT OBJECT: SQL statement with SQL_ID 2b064ybzkwf1y BEGIN EMD_NOTIFICATION.QUEUE_READY(:1, :2, :3); END; RATIONALE: SQL statement with SQL_ID "2b064ybzkwf1y" was executed 125 times and had an average elapsed time of 0.26 seconds. RATIONALE: Average time spent in PL/SQL execution was 0.26 seconds. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ ADDITIONAL INFORMATION ---------------------- Wait class "Application" was not consuming significant database time. Wait class "Commit" was not consuming significant database time. Wait class "Concurrency" was not consuming significant database time. Wait class "Configuration" was not consuming significant database time. Wait class "Network" was not consuming significant database time. Wait class "User I/O" was not consuming significant database time. Session connect and disconnect calls were not consuming significant database time. Hard parsing of SQL statements was not consuming significant database time. The analysis of I/O performance is based on the default assumption that the average read time for one database block is 10000 micro-seconds. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ TERMINOLOGY ----------- DATABASE TIME: This is the ADDM's measurement of throughput. From the user's point of view: this is the total amount of time spent by users waiting for a response from the database after issuing a call (not including networking). From the database instance point of view: this is the total time spent by forground processes waiting for a database resource (e.g., read I/O), running on the CPU and waiting for a free CPU (run-queue). The target of ADDM analysis is to reduce this metric as much as possible, thereby reducing the instance's response time. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 AVERAGE DATABASE LOAD: At any given time we can count how many users (also called 'Active Sessions') are waiting for an answer from the instance. This is the ADDM's measurement for instance load. The 'Average Database Load' is the average of the the load measurement taken over the entire analysis period. We get this number by dividing the 'Database Time' by the analysis period. For example, if the analysis period is 30 minutes and the 'Database Time' is 90 minutes, we have an average of 3 users waiting for a response. IMPACT: Each finding has an 'Impact' associated with it. The impact is the portion of the 'Database Time' the finding deals with. If we assume that the problem described by the finding is completely solved, then the 'Database Time' will be reduced by the amount of the 'Impact'. BENEFIT: Each recommendation has a 'benefit' associated with it. The ADDM analysis estimates that the 'Database Time' can be reduced by the 'benefit' amount if all the actions of the recommendation are performed. 说明:其中第五步到第六步可以直接执行 $ORACLE_HOME/rdbms/admin/addmrpt.sql 来得到,这个脚本的执行过程和 statspack 脚本执行过程类似: SQL> @addmrpt Current Instance ~~~~~~~~~~~~~~~~ DB Id DB Name Inst Num Instance ----------- ------------ -------- ------------ 1712582900 EDGAR 1 edgar Instances in this Workload Repository schema ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DB Id Inst Num DB Name Instance Host ------------ -------- ------------ ------------ ------------ * 1712582900 1 EDGAR edgar HUANGED Using 1712582900 for database Id Using 1 for instance number Specify the number of days of snapshots to choose from Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Entering the number of days (n) will result in the most recent (n) days of snapshots being listed. Pressing without specifying a number lists all completed snapshots. Listing the last 3 days of Completed Snapshots Snap Instance DB Name Snap Id Snap Started Level ------------ ------------ --------- ------------------ ----- edgar EDGAR 7 22 Nov 2005 00:00 1 ... ... 64 23 Nov 2005 15:02 1 65 23 Nov 2005 16:00 1 66 23 Nov 2005 16:06 1 Specify the Begin and End Snapshot Ids ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Enter value for begin_snap: 65 Begin Snapshot Id specified: 66 Enter value for end_snap: 66 End Snapshot Id specified: 66 Specify the Report Name ~~~~~~~~~~~~~~~~~~~~~~~ The default report file name is addmrpt_1_65_66.txt. To use this name, press to continue, otherwise enter an alternative. Enter value for report_name: Using the report name addmrpt_1_65_66.txt Running the ADDM analysis on the specified pair of snapshots ... Generating the ADDM report for this analysis ... ... ... Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 此外,如 果 是 RAC 环 境 下 , 可 以 执 行 $ORACLE_HOME/rdbms/admin/addmrpti.sql,这脚本的执行,会多出要求输入 DB ID 和 instance ID 的要求。 1.9.8 诊断结果分析 我们从上面的建议结果看到了,ADDM Report 的结果与 Statspack Report 的结果大不相同。Statspack Report 的结果给出的都是统计数据、各种事件,然后 由 DBA 根据这些数据给出优化建议,而 ADDM Report 的结果包含就已经是给 出的优化建议了 第一部分: Analysis Period: 23-NOV-2005 from 15:02:27 to 16:06:42 Database ID/Instance: 1712582900/1 Database/Instance Names: EDGAR/edgar Host Name: HUANGED Database Version: 10.2.0.1.0 Snapshot Range: from 65 to 66 Database Time: 1463 seconds Average Database Load: .4 active sessions 这一部分包括一些基础信息,分析时间段、DB 和 instance ID&名字、主机名 字、Oracle 版本、快照范围、数据库消耗时间、多少个活动会话。 第二部分: 下面就是 ADDM 发现的问题,并给出的相应建议。在我们这个例子中总共 发现 4 个问题,下面一一解释一下。 第一个问题: FINDING 1: 100% impact (1463 seconds) ------------------------------------- Significant virtual memory paging was detected on the host operating system. RECOMMENDATION 1: Host Configuration, 100% benefit (1463 seconds) ACTION: Host operating system was experiencing significant paging but no particular root cause could be detected. Investigate processes that do not belong to this instance running on the host that are consuming significant amount of virtual memory. Also consider adding more physical memory to the host. 先看第一行:100% impact (1463 seconds),这是这个问题所持续的实践及其 对系统的影响,它的时间是 1463 秒,和分析期间的数据库消耗时间(在第一部 分中)是一样(1463 秒),所以对系统的影响是 1463/1463*100=100%的。 再看第二行:Significant virtual memory paging was detected on the host operating system.,这是 ADDM 发现的这个问题的具体描述:在操作系统中发现Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 有显著的虚拟内存页入页出的问题。 然后看 ADDM 给出的建议及其作用:Host Configuration, 100% benefit (1463 seconds)——更改主机配置,100%有效。 最后是具体该如何操作:略——在主机的操作系统上发现了明显的页入页 出,但是没有发现明显导致内存频繁换如换出的根本原因。需要仔细检查那些消 耗大量虚拟内存的进程(除 Oracle 实例外)。此外,还可以考虑增大主机的物理 内存。说明一下:我的这个实例是跑在我自己的 PC 机上,Oracle 运行的同时有 大量的其他消耗内存的程序(word 等)在运行,所以肯定有大量的内存交换存 在。 再看第二个问题: FINDING 2: 100% impact (1463 seconds) ------------------------------------- SQL statements consuming significant database time were found. RECOMMENDATION 1: SQL Tuning, 68% benefit (998 seconds) ACTION: Tune the PL/SQL block with SQL_ID "064wqx7c5b81z". Refer to the "Tuning PL/SQL Applications" chapter of Oracle's "PL/SQL User's Guide and Reference" RELEVANT OBJECT: SQL statement with SQL_ID 064wqx7c5b81z DECLARE v_var number; BEGIN FOR n IN 1..10000 LOOP select count(*) into v_var from bigtab b, smalltab a; END LOOP; END; ADDM 发现有 SQL 语句在消耗大量数据库时间,它的影响是 100%的。给 出的建议是优化 SQL,能取得 68%的效果。 具体操作是优化ADDM找到的PL/SQL块,它的SQL_ID 是"064wqx7c5b81z" (可以通过 select sql_text from v$sql where sql_id=‘064wqx7c5b81z‘;查到)。至于 如何优化 SQL 语句,可以参考 Oracle 文档 PL/SQL User's Guide and Reference 中 的 Tuning PL/SQL Applications 章节。下面的内容便是我们用来插入数据的测试 语句。 下面是 ADDM 发现的其他问题语句: FINDING 3: 69% impact (1002 seconds) ------------------------------------ Time spent on the CPU by the instance was responsible for a substantial part of database time. RECOMMENDATION 1: SQL Tuning, 67% benefit (986 seconds) Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 ACTION: Run SQL Tuning Advisor on the SQL statement with SQL_ID "fvqfghq71cqns". RELEVANT OBJECT: SQL statement with SQL_ID fvqfghq71cqns and PLAN_HASH 3281046854 SELECT COUNT(*) FROM BIGTAB B, SMALLTAB A RATIONALE: SQL statement with SQL_ID "fvqfghq71cqns" was executed 6 times and had an average elapsed time of 166 seconds. RATIONALE: Average CPU used per execution was 162 seconds. RECOMMENDATION 2: SQL Tuning, 2.1% benefit (30 seconds) ACTION: Tune the PL/SQL block with SQL_ID "2b064ybzkwf1y". Refer to the "Tuning PL/SQL Applications" chapter of Oracle's "PL/SQL User's Guide and Reference" RELEVANT OBJECT: SQL statement with SQL_ID 2b064ybzkwf1y BEGIN EMD_NOTIFICATION.QUEUE_READY(:1, :2, :3); END; RATIONALE: SQL statement with SQL_ID "2b064ybzkwf1y" was executed 125 times and had an average elapsed time of 0.26 seconds. RATIONALE: Average CPU used per execution was 0.24 seconds. 这个问题的描述是,实例消耗的 CPU 事件占据了大量的数据库运行时间。 由于发现了两条问题语句,所以这里有两个建议。 第一个建议就是优化我们的测试语句。并且说明了这个问题的根本原因:这 条语句总共执行过 6 次,平均每次消耗了 166 秒。平均这个问题消耗的 CPU 时 间是 162 秒。 第二个建议实际上是针对一个系统过程,这个过程是用来读取队列信息的, 消耗的资源比较小,我们这里就不需要关心了。 再看最后一个问题: FINDING 4: 2.2% impact (33 seconds) ----------------------------------- PL/SQL execution consumed significant database time. RECOMMENDATION 1: SQL Tuning, 2.2% benefit (33 seconds) ACTION: Tune the PL/SQL block with SQL_ID "2b064ybzkwf1y". Refer to the "Tuning PL/SQL Applications" chapter of Oracle's "PL/SQL User's Guide and Reference" RELEVANT OBJECT: SQL statement with SQL_ID 2b064ybzkwf1y BEGIN EMD_NOTIFICATION.QUEUE_READY(:1, :2, :3); END; RATIONALE: SQL statement with SQL_ID "2b064ybzkwf1y" was executed 125 times and had an average elapsed time of 0.26 seconds. RATIONALE: Average time spent in PL/SQL execution was 0.26 seconds. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 从内容上看,这个问题就是上一个问题中的第二个建议。但是,它导致的 结果是不一样的。看这个问题的描述:PL/SQL 的执行次数消耗了大量的数据库 时间。它的根本原因是因为执行次数太多(125 次)。可见 ADDM 的问题检查相 当全面。 第三部分: 这一部分的内容是关于此次优化建议的一些附加信息: ADDITIONAL INFORMATION ---------------------- Wait class "Application" was not consuming significant database time. Wait class "Commit" was not consuming significant database time. Wait class "Concurrency" was not consuming significant database time. Wait class "Configuration" was not consuming significant database time. Wait class "Network" was not consuming significant database time. Wait class "User I/O" was not consuming significant database time. Session connect and disconnect calls were not consuming significant database time. Hard parsing of SQL statements was not consuming significant database time. The analysis of I/O performance is based on the default assumption that the average read time for one database block is 10000 micro-seconds. 这是关于这次优化诊断对各类事件(在 Oracle10g,新增了很多新的事件, 主要是将原先一些较含糊的事件细化了,同时将所有事件进行了归类。可以查看 视图 V$SYSTEM_WAIT_CLASS)的一些总结:Application、Commit、Concurrency、 Configuration、Network、User I/O 类等待事件没有显著消耗数据库时间;会话连 接、断连请求没有消耗大量数据库时间;对 SQL 语句的硬解析没有消耗大量数 据库时间;对 IO 性能的分析是基于默认假设每次读一个数据块的时间是 10000 微秒的。 第四部分: 这部分是对诊断报告中用到的术语的解释: TERMINOLOGY ----------- DATABASE TIME: This is the ADDM's measurement of throughput. From the user's point of view: this is the total amount of time spent by users waiting for a response from the database after issuing a call (not including networking). From the database instance point of view: this is the total time spent by forground processes waiting for a database resource (e.g., read I/O), running on the CPU and waiting for a free CPU (run-queue). The target of ADDM analysis is to reduce this metric as much as possible, Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 thereby reducing the instance's response time. AVERAGE DATABASE LOAD: At any given time we can count how many users (also called 'Active Sessions') are waiting for an answer from the instance. This is the ADDM's measurement for instance load. The 'Average Database Load' is the average of the the load measurement taken over the entire analysis period. We get this number by dividing the 'Database Time' by the analysis period. For example, if the analysis period is 30 minutes and the 'Database Time' is 90 minutes, we have an average of 3 users waiting for a response. IMPACT: Each finding has an 'Impact' associated with it. The impact is the portion of the 'Database Time' the finding deals with. If we assume that the problem described by the finding is completely solved, then the 'Database Time' will be reduced by the amount of the 'Impact'. BENEFIT: Each recommendation has a 'benefit' associated with it. The ADDM analysis estimates that the 'Database Time' can be reduced by the 'benefit' amount if all the actions of the recommendation are performed. DATABASE TIME:是 ADDM 的度量数据。从用户角度看:这是从向数据 库请求开始,消耗在用户等待响应上的全部时间(不包括网络响应时间);从数 据库实例角度看:前台进程消耗在等待一种数据库资源(例如,IO 读)、CPU 运 行和等待 CPU 释放(队列等待)的总共时间。ADDM 分析的目标就尽量降低这 个数字,也就是减少实例响应时间 AVERAGE DATABASE LOAD:所有能统计到的有多少用户(也称为―活动 会话‖)等待实例响应。这是实例负荷的度量指标。平均数据库负荷是由整个分 析计算出来的平均负荷。通过―Database Time‖除以分析周期时间得到。例如,分 析周期时 30 分钟,而数据库运行消耗时间是 90 分钟,那就说明平均有 3 个用户 在等待响应。 IMPACT:每一个找到的问题都有―影响‖这一项。―影响‖是数据库消耗时间 用于处理这个问题的时间不分。假定我们所找到的这个问题完全解决,那么数据 库消耗时间就会相应减少―影响‖时间。 BENEFIT:每一个找到的问题都―受益‖这一项。如果所有建议操作得到实施, ADDM 分析估计数据库消耗时间能减少―受益‖的全部时间。 找到了有问题的 SQL 后我们就可以用 Oracle SQL Tuning Advisor 工具来优化该 SQL. 1.10 SQL Tuning Advisor (STA) 使用 说明 Blog: http://blog.csdn.net/tianlesoftware/archive/2010/05/28/5630888.aspx Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 在 Oracle10g 之前,优化 SQL 是个比较费力的技术活,不停的分析执行计划, 加 hint,分析统计信息等等。在 10g 中,Oracle 推出了自己的 SQL 优化辅助工 具: SQL 优化器(SQL Tuning Advisor :STA),它是新的 DBMS_SQLTUNE 包。 使用 STA 一定要保证优化器是 CBO 模式下。 执行 DBMS_SQLTUNE 包进行 sql 优化需要有 advisor 的权限: SQL> create user dave identified by dave; 用户已创建。 SQL> grant connect,resource to dave; 授权成功。 SQL> grant advisor to dave; 授权成功。 下面演示一个示例。 1.10.1 准备工作 SQL>create table bigtab as select rownum as "id",a.* from sys.all_objects a; SQL>create table smalltab as select rownum as "id", a.* FROM sys.all_tables a; 然后多运行几次下面的脚本,增加表里的数据: SQL>insert into bigtab select rownum as "id",a.* from sys.all_objects a; SQL>insert into smalltab select rownum as "id", a.* FROM sys.all_tables a; 这里创建一张大表和一张小表,并且都没有索引,下面执行一个查询: SQL> set timing on SQL> set autot on SQL> select count(*) from bigtab a, smalltab b where a.object_name=b.table_name; COUNT(*) ---------- 2141537 已用时间: 00: 00: 20.05 执行计划 ---------------------------------------------------------- Plan hash value: 3089226980 -------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 -------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 45 | 3146 (1)| 00:00:38 | | 1 | SORT AGGREGATE | | 1 | 45 | | | |* 2 | HASH JOIN | | 447K| 19M| 3146 (1)| 00:00:38 | | 3 | TABLE ACCESS FULL| SMALLTAB | 27327 | 533K| 264 (1)| 00:00:04 | | 4 | TABLE ACCESS FULL| BIGTAB | 712K| 16M| 2878 (1)| 00:00:35 | -------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("A"."OBJECT_NAME"="B"."TABLE_NAME") 统计信息 ---------------------------------------------------------- 0 recursive calls 0 db block gets 31149 consistent gets 21058 physical reads 0 redo size 426 bytes sent via SQL*Net to client 416 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed 1.10.2 创建优化任务 通过调用函数 CREATE_TUNING_TASK 来创建优化任务,调用存储过程 EXECUTE_TUNING_TASK 执行该任务: SQL> set autot off SQL> set timing off SQL> DECLARE 2 my_task_name VARCHAR2(30); 3 my_sqltext CLOB; 4 BEGIN 5 my_sqltext := 'select count(*) from bigtab a, smalltab b where a.object_name=b.table_name'; 6 my_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK( 7 sql_text => my_sqltext, Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 8 user_name => 'DAVE', -- 注意是大写,不然会报错,用户 无效 9 scope => 'COMPREHENSIVE', 10 time_limit => 60, 11 task_name => 'tuning_sql_test', 12 description => 'Task to tune a query on a specified table'); 13 14 DBMS_SQLTUNE.EXECUTE_TUNING_TASK( task_name => 'tuning_sql_test'); 15 END; 16 / PL/SQL procedure successfully completed. 在函数 CREATE_TUNING_TASK,sql_text 是需要优化的语句,user_name 是该 语句通过哪个用户执行,scope 是优化范围(limited 或 comprehensive), time_limit 优化过程的时间限制,task_name 优化任务名称,description 优化任务描述。 1.10.3 执行优化任务 通过调用 dbms_sqltune.execute_tuning_task 过程来执行前面创建好的优化任 务。 SQL> exec dbms_sqltune.execute_tuning_task('tuning_sql_test'); PL/SQL 过程已成功完成。 1.10.4 检查优化任务的状态 通过查看 user_advisor_tasks/dba_advisor_tasks 视图可以查看优化任务的当前状 态。 SQL> SELECT task_name,status FROM USER_ADVISOR_TASKS WHERE task_name ='tuning_sql_test'; TASK_NAME STATUS ------------------------------ ----------- tuning_sql_test COMPLETED 1.10.5 查看优化结果 通过 dbms_sqltune.report_tning_task 函数可以获得优化任务的结果。 SQL> SET LONG 999999 SQL> set serveroutput on size 999999 SQL> SET LINESIZE 100 SQL> SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK( 'tuning_sql_test') Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 from DUAL; DBMS_SQLTUNE.REPORT_TUNING_TASK('TUNING_SQL_TEST') ---------------------------------------------------------------------------------------------------- GENERAL INFORMATION SECTION ------------------------------------------------------------------------------- Tuning Task Name : tuning_sql_test Tuning Task Owner : DEMO Scope : COMPREHENSIVE Time Limit(seconds) : 60 Completion Status : COMPLETED Started at : 5/28/2010 13:16:43 Completed at : 5/28/2010 13:16:44 Number of Index Findings : 1 Schema Name: DEMO SQL ID : 6p64dnnsqf9pm SQL Text : select count(*) from bigtab a, smalltab b where a.object_name=b.table_name ------------------------------------------------------------------------------- FINDINGS SECTION (1 finding) ------------------------------------------------------------------------------- 1- Index Finding (see explain plans section below) The execution plan of this statement can be improved by creating one or more indices. Recommendation (estimated benefit: 100%) ---------------------------------------- - Consider running the Access Advisor to improve the physical schema design or creating the recommended index. create index DEMO.IDX$$_06C50001 on SYS.SMALLTAB('TABLE_NAME'); - Consider running the Access Advisor to improve the physical schema design or creating the recommended index. create index DEMO.IDX$$_06C50002 on SYS.BIGTAB('OBJECT_NAME'); Rationale --------- Creating the recommended indices significantly improves the execution plan of this statement. However, it might be preferable to run "Access Advisor" using a representative SQL workload as opposed to a single statement. This Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 will allow to get comprehensive index recommendations which takes into account index maintenance overhead and additional space consumption. EXPLAIN PLANS SECTION ------------------------------------------------------------------------------- 1- Original ----------- Plan hash value: 3089226980 -------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 36 | 3550 (2)| 00:00:43 | | 1 | SORT AGGREGATE | | 1 | 36 | | | |* 2 | HASH JOIN | | 155K| 5462K| 3550 (2)| 00:00:43 | | 3 | TABLE ACCESS FULL| SMALLTAB | 1223 | 22014 | 11 (0)| 00:00:01 | | 4 | TABLE ACCESS FULL| BIGTAB | 1205K| 20M| 3526 (1)| 00:00:43 | -------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("A"."OBJECT_NAME"="B"."TABLE_NAME") 2- Using New Indices -------------------- Plan hash value: 494801882 ----------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ----------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 36 | 1108 (3)| 00:00:14 | | 1 | SORT AGGREGATE | | 1 | 36 | | | |* 2 | HASH JOIN | | 155K| 5462K| 1108 (3)| 00:00:14 | | 3 | INDEX FAST FULL SCAN| IDX$$_06C50001 | 1223 | 22014 | 3 (0)| 00:00:01 | | 4 | INDEX FAST FULL SCAN| IDX$$_06C50002 | 1205K| 20M| Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1093 (2)| 00:00:14 | ----------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("A"."OBJECT_NAME"="B"."TABLE_NAME") ------------------------------------------------------------------------------ 看一下这个优化建议报告: 第一部分是关于这次优化任务的基本信息:如任务名称、执行时间、范围、 涉及到的语句等等。 第二部分是关于这次优化任务的所找到的问题以及给出的优化建议。前面先 给出了问题描述:可以通过建立更多的所引来提高性能;然后是建议的具体内容: 在表 smalltab 的字段 table_name 上创建索引,在表 bigtab 的字段 object_name 上 创建索引;最后是相关注意事项:此次优化虽然给出了创建索引的建议,但是最 好通过 SQL 访问建议器(SQL Access Advisor SAA)结合整个数据库的工作量来深 入分析,那样就能给出考虑了索引维护和空间消耗等因素的更加合理的建议。 最后,报告还给出了原有的查询计划,以及采用优化建议以后的查询计划的 对比。可以看出 COST 值大大下降。 1.10.6 删除优化任务 通过调用 dbms_sqltuen.drop_tuning_task 可以删除已经存在的优化任务 SQL>exec dbms_sqltune.drop_tuning_task('tuning_sql_test'); PL/SQL procedure successfully completed. 1.11 ASH(Active Session History) Blog: http://blog.csdn.net/tianlesoftware/archive/2011/05/26/6448765.aspx 1.11.1 官网说明 Performance tuning and problem diagnosis are the two most challenging and important management tasks that any database administrator performs. In line with the primary drive of the server manageability effort, the Autometic Database Diagnostic Monitor (ADDM) attempts to make, performing these two tasks, a lot simpler and easier. ADDM employs an iterative top-down approach and drives a rule-based expert system, to identify bottlenecks in a system and suggest relevant recommendations to tackle them. ASH acquires the information it requires to sample the active session‘s activity from the database kernel‘s session state objects. The quantity of information sampled by ASH could be quite voluminous, and therefore, ASH maintains a fixed sized circular buffer in the database System Global Area (SGA). The fixed sized circular buffer will be allocated during database start-up time. Since the information collected Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 by the ASH infrastructure compliments the information present in SWRF snapshots, and can be used for drilldown purposes during problem diagnosis or performance tuning, the ASH data is also periodically flushed to disk. -- ASH 的数据也会定期的写入磁盘 The flushing and purging policies of ASH, including the way ASH respects SWRF baselines, are completely tied with SWRF policies. Still, flushing the entire content of ASH on to disk could be too populous to be feasible, and therefore, only one out of every ten active session samples will be flushed to disk. -- 将整个 ASH 内容频繁的写入磁盘不容易,所以只有 1/10 的 active session 数据写入磁盘 In addition to ADDM using the ASH to achieve its objectives, the ASH contents will also be displayed in the Oracle Enterprise Manager (EM) / Mozart [OEM-SWRF] performance screen. The graph that summarizes the ASH contents in the EM performance screen will be a stacked graph showing the distribution of the elapsed database time onto various wait times and CPU time, during every minute. The ASH infrastructure will provide a single V$ view (V$ACTIVE_SESSION_HISTORY), to view the in-memory contents of ASH. --可以通过 V$ACTIVE_SESSION_HISTORY 视图查看内存中 ASH 的信息 The ASH infrastructure will also provide a way to dump the in-memory contents of its circular buffer onto an external file in a human readable format. The ASH dump file can be transported to another system, imported onto a user table, and analyzed using the ADDM in that system. -- 也可以将内存中的 ASM 数据 dump 到外部文件,并转移到其他系统进行 分析。 ASH Memory Size ============== Size of ASH Circular Buffer = Max [Min [ #CPUs * 2 MB, 5% of Shared Pool Size, 30MB ], 1MB ] --最小 1M,最大 30M Catagoreising the Active Session ============================ i. Present inside a user call ii. Not a recursive session iii. Not waiting for the ‗IDLE‘ wait-event iv. If it is a background process, not waiting for its usual timer-event v. If it is a parallel slave, not waiting for the PX_IDLE wait event. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 So will not see any info if a process is waitting for "SQL*Net message from client". online 和 offline 分析示例 Let start with ONLINE analysis ======================== I have open two session. first one (SID 16) is running the DML like SQL> delete test where rowid='AAAKB9AAEAAAAAiAAA'; From second session (SID 15) run the same DML, and it is obvious that second session will wait for first session to commit. Lets check the info in V$ACTIVE_SESSION_HISTORY. ------------------------------------------------ Run the following script. SQL> select SESSION_ID,NAME,P1,P2,P3,WAIT_TIME,CURRENT_OBJ#,CURRENT_FILE#, CURRENT_BLOCK# from v$active_session_history ash, v$event_name enm where ash.event#=enm.event# and SESSION_ID=&SID and SAMPLE_TIME>=(sysdate-&minute/(24*60)); Input is Enter value for sid: 15 Enter value for minute: 1 /* How many minutes activity you want to see */ output is 59 lines as it is wiatting more than 1 minute more than 1 minute SESSION_ID NAME P1 P2 P3 WAIT_TIME CURRENT_OBJ# CURRENT_FILE# CURRENT_BLOCK# ---------- ------------------------------ ---------- ---------- ---------- ---------- ------------ ------------- -------------- 15 enq: TX - row lock contention 1415053318 589825 143 0 41085 4 34 15 enq: TX - row lock contention 1415053318 589825 143 0 41085 4 34 15 enq: TX - row lock contention 1415053318 589825 143 0 41085 4 34 continue ............. 15 enq: TX - row lock contention 1415053318 589825 143 0 41085 4 34 15 enq: TX - row lock contention 1415053318 589825 143 0 41085 4 34 15 enq: TX - row lock contention 1415053318 589825 143 0 41085 4 34 So you have object details with problem info. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Lets do the OFFLINE analysis of ASH ============================== So if your are not able to find the problem online, you can dump the ASH to a trace. Command would be like below: where level means minute. lets dump for 10 minutes history 1. SQL> alter session set events 'immediate trace name ashdump level 10'; or 2. SQL> alter system set events 'immediate trace name ashdump level 10'; or 3. SQL> oradebug setmypid SQL> oradebug dump ashdump 10; So you will get the trace file in udump. Output of trace would be like <<>> 2594829169,1,161390,"07-18-2003 16:05:21.098717000",13,1,0,"",65535,0,0,2,0,0,0,4294967295,0,0,2,35,100,0,0,10 05855,0,"oracle@usunrat21 (MMNL)","","","" Oracle has provide an utility under $ORACLE_HOME/rdbms/demo (Location may change), by which you can upload the ASH trace dump to a database table and do the analysis. Please see the following Note Note 555303.1 ashdump* scripts and post-load processing of MMNL traces for the scripts. Script Details ============ 1. "ashdump_loader" -> Main script to run with one argument. Argument is the the name of tracefile. (available in 10g only) 2. "ashdump_table.sql" -> It would be called by the main script to create the table called SYSTEM.ACTIVE_SESSION_HISTORY_DUMP. 3. "ashdump_sqlldr.ctl" -> It is the third script called by main script to load the trace into table called SYSTEM.ACTIVE_SESSION_HISTORY_DUMP. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 注意:You must use the same oracle version to compare the OFFLINE trace with the other view. 1.11.2 ASH 说明 ASH 以 V$SESSION 为基础,每秒采样一次,记录活动会话等待的事件。不 活动的会话不会采样,采样工作由新引入的后台进程 MMNL 来完成。 ASH buffers 的最小值为 1MB,最大值不超过 30MB。内存中记录数据。期望 值是记录一小时的内容。 ASH 报告生成脚本:@?/rdbms/admin/ashrpt.sql ASH 内存记录数据始终是有限的,为了保存历史数据,引入了自动负载信息 库(Automatic Workload Repository ,AWR) 由后台进程 MMON 完成。ASH 信息同 样被采集写出到 AWR 负载库中。由于内存不是足够的,所以 MMNL 进程在 ASH 写满后会将信息写出到 AWR 负载库中。ASH 全部写出是不可接受的,所以一般 只写入收集的 10%的数据量,而且使用 direct-path insert 完成,尽量减少日志的 生成,从而最小化数据库性能影响。 内存中的 ASH 信息可以通过 V$ACTIVE_SESSION_HISTORY 查询,而 写 出到 AWR 负载库的 ASH 信息,可以通过 AWR 的基础表 wrh$active_session_hist 查询,wrh$active_session_hist 是一个分区表,Oracle 会自动进行数据清理。 一般来说,我们在监控数据库时,如果是当前正在发生的问题,我们可以通 过 v$session+v$sqlarea 来找出性能最差的 SQL 语句。如果在一个小时以内发生 的我们可以通过生成 ASH 报告来找出 SQL。如果是 1 小时以上或几天我们可以 通过 AWR 报告来找出几小时,几天以来最影响系统的 SQL 语句。ADDM 报告 基于 AWR 库,默认可以保存 30 天的 ADDM 报告。 相关查询试图: v$session (当前正在发生) v$session_wait (当前正在发生) v$session_wait_history (会话最近的 10 次等待事件) v$active_session_history (内存中的 ASH 采集信息,理论为 1 小时) wrh$_active_session_history (写入 AWR 库中的 ASH 信息,理论为 1 小时以上) dba_hist_active_sess_history (根据 wrh$_active_session_history 生成的视图) 1.11.3 ASH 报告生成示例 ASH 组件以 v$active_session_history 视图为基础,生成 ASH 报表,ASH 报 表与 statspack 类似,可以提供以下信息: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Top User Events Top Background Events Top Event P1/P2/P3 Values Top Service/Module Top Client IDs Top SQL Command Types Top SQL using literals Top Blocking Sessions Top DB Objects Top DB Files Top Latches Activity Over Time 报表间隔时间可以精确到分钟,因而 ASH 可以提供比 STATSPACK 或 AWR 更详细的关于历史会话的信息,可以作为 statspack 或 awr 的补充。ASH 报告通 过@$ORACLE_HOME/rdbms/admin/ashrpt.sql 脚本生成,包括 hmtl 和 text 两种 格式。 SYS@anqing1(rac1)> @?/rdbms/admin/ashrpt.sql; -- 调用脚本 Current Instance ~~~~~~~~~~~~~~~~ DB Id DB Name Inst Num Instance ----------- ------------ -------- ------------ 715014091 ANQING 1 anqing1 Specify the Report Type ~~~~~~~~~~~~~~~~~~~~~~~ Enter 'html' for an HTML report, or 'text' for plain text Defaults to 'html' Enter value for report_type: text -- 选择生成的 ASH 报告类型,是 text 还是 html Type Specified: text Instances in this Workload Repository schema ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DB Id Inst Num DB Name Instance Host ------------ -------- ------------ ------------ ------------ Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 715014091 1 ANQING anqing singledb * 715014091 1 ANQING anqing1 rac1 715014091 2 ANQING anqing2 rac2 Defaults to current database Using database id: 715014091 Defaults to current instance Using instance number: 1 ASH Samples in this Workload Repository schema ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Oldest ASH sample available: 19-May-11 14:49:59 [ 10585 mins in the past] Latest ASH sample available: 26-May-11 23:14:34 [ 1 mins in the past] Specify the timeframe to generate the ASH report ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Enter begin time for report: -- Valid input formats: -- To specify absolute begin time: -- [MM/DD[/YY]] HH24:MI[:SS] -- Examples: 02/23/03 14:30:15 -- 02/23 14:30:15 -- 14:30:15 -- 14:30 -- To specify relative begin time: (start with '-' sign) -- -[HH24:]MI -- Examples: -1:15 (SYSDATE - 1 Hr 15 Mins) -- -25 (SYSDATE - 25 Mins) Defaults to -15 mins Enter value for begin_time: 8:00 -- 输入 ASH 开始的时间,时间格式上面的示例有说明 Report begin time specified: 8:00 Enter duration in minutes starting from begin time: Defaults to SYSDATE - begin_time Press Enter to analyze till current time Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Enter value for duration: -- 输入 ASH 结束时间,默认是 SYSDATE - begin_time Report duration specified: Using 26-May-11 08:00:00 as report begin time Using 26-May-11 23:15:12 as report end time Specify Slot Width (using ashrpti.sql) for 'Activity Over Time' section ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~ -- Explanation: -- In the 'Activity Over Time' section of the ASH report, -- the analysis period is divided into smaller slots -- and top wait events are reported in each of those slots. -- Default: -- The analysis period will be automatically split upto 10 slots -- complying to a minimum slot width of -- 1 minute, if the source is V$ACTIVE_SESSION_HISTORY or -- 5 minutes, if the source is DBA_HIST_ACTIVE_SESS_HISTORY. Specify Slot Width in seconds to use in the 'Activity Over Time' section: Defaults to a value as explained above: Slot Width specified: Specify Report Targets (using ashrpti.sql) to generate the ASH report ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~ -- Explanation: -- ASH Report can accept "Report Targets", -- like a particular SQL statement, or a particular SESSION, -- to generate the report on. If one or more report targets are -- specified, then the data used to generate the report will only be -- the ASH samples that pertain to ALL the specified report targets. -- Default: -- If none of the report targets are specified, -- then the target defaults to all activity in the database instance. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Specify SESSION_ID (eg: from V$SESSION.SID) report target: Defaults to NULL: SESSION report target specified: Specify SQL_ID (eg: from V$SQL.SQL_ID) report target: Defaults to NULL: (% and _ wildcards allowed) SQL report target specified: Specify WATI_CLASS name (eg: from V$EVENT_NAME.WAIT_CLASS) report target: [Enter 'CPU' to investigate CPU usage] Defaults to NULL: (% and _ wildcards allowed) WAIT_CLASS report target specified: Specify SERVICE_HASH (eg: from V$ACTIVE_SERVICES.NAME_HASH) report target: Defaults to NULL: SERVICE report target specified: Specify MODULE name (eg: from V$SESSION.MODULE) report target: Defaults to NULL: (% and _ wildcards allowed) MODULE report target specified: Specify ACTION name (eg: from V$SESSION.ACTION) report target: Defaults to NULL: (% and _ wildcards allowed) ACTION report target specified: Specify CLIENT_ID (eg: from V$SESSION.CLIENT_IDENTIFIER) report target: Defaults to NULL: (% and _ wildcards allowed) CLIENT_ID report target specified: Specify PLSQL_ENTRY name (eg: "SYS.DBMS_LOB.*") report target: Defaults to NULL: (% and _ wildcards allowed) PLSQL_ENTRY report target specified: Specify the Report Name Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 ~~~~~~~~~~~~~~~~~~~~~~~ The default report file name is ashrpt_1_0526_2315.txt. To use this name, press to continue, otherwise enter an alternative. Enter value for report_name: /u01/daveash.txt -- 输入 ASH 报告的名称,可以指定生成的目录,默认情况是当前登陆 sqlplus 的目录。 这里的扩展最好加上,如果不加扩展名,扩展名会变成 lst. 但不影响 数据。 Using the report name /u01/daveash.txt Summary of All User Input ------------------------- Format : TEXT DB Id : 715014091 Inst num : 1 Begin time : 26-May-11 08:00:00 End time : 26-May-11 23:15:12 Slot width : Default Report targets : 0 Report name : /u01/daveash ASH Report For ANQING/anqing1 DB Name DB Id Instance Inst Num Release RAC Host ------------ ----------- ------------ -------- ----------- --- ------------ ANQING 715014091 anqing1 1 10.2.0.4.0 YES rac1 CPUs SGA Size Buffer Cache Shared Pool ASH Buffer Size ---- ------------------ ------------------ ------------------ ------------------ 1 272M (100%) 144M (52.9%) 96M (35.3%) 2.0M (0.7%) Analysis Begin Time: 26-May-11 08:00:00 Analysis End Time: 26-May-11 23:15:12 Elapsed Time: 915.2 (mins) Sample Count: 795 Average Active Sessions: 0.01 Avg. Active Session per CPU: 0.01 Report Target: None specified Top User Events DB/Inst: ANQING/anqing1 (May 26 08:00 to Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 23:15) Avg Active Event Event Class % Activity Sessions ----------------------------------- --------------- ---------- ---------- latch free Other 8.55 0.00 CPU + Wait for CPU CPU 7.17 0.00 log file sync Commit 2.26 0.00 ------------------------------------------------------------- Top Background Events DB/Inst: ANQING/anqing1 (May 26 08:00 to 23:15) Avg Active Event Event Class % Activity Sessions ----------------------------------- --------------- ---------- ---------- control file sequential read System I/O 36.73 0.01 control file parallel write System I/O 28.30 0.00 log file parallel write System I/O 4.91 0.00 CPU + Wait for CPU CPU 3.40 0.00 db file parallel write System I/O 3.40 0.00 ------------------------------------------------------------- Top Event P1/P2/P3 Values DB/Inst: ANQING/anqing1 (May 26 08:00 to 23:15) Event % Event P1 Value, P2 Value, P3 Value % Activity ------------------------------ ------- ----------------------------- ---------- Parameter 1 Parameter 2 Parameter 3 -------------------------- -------------------------- -------------------------- control file sequential read 36.73 "0","11","1" 21.01 file# block# blocks "0","3","1" 11.45 "0","4","1" 1.64 control file parallel write 28.30 "2","3","2" 28.30 files block# requests latch free 8.68 "817412680","389","0" Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 8.55 address number tries log file parallel write 4.91 "2","2","2" 1.13 files blocks requests db file parallel write 3.40 "1","0","2147483647" 3.40 requests interrupt timeout ------------------------------------------------------------- Top Service/Module DB/Inst: ANQING/anqing1 (May 26 08:00 to 23:15) Service Module % Activity Action % Action -------------- ------------------------ ---------- ------------------ ---------- SYS$BACKGROUND UNNAMED 80.25 UNNAMED 80.25 SYS$USERS UNNAMED 9.43 UNNAMED 9.43 DBMS_SCHEDULER 5.16 MYJOB 4.91 1.89 1.89 racgimon@rac1 (TNS V1-V3 1.01 UNNAMED 1.01 ------------------------------------------------------------- Top Client IDs DB/Inst: ANQING/anqing1 (May 26 08:00 to 23:15) No data exists for this section of the report. ------------------------------------------------------------- Top SQL Command Types DB/Inst: ANQING/anqing1 (May 26 08:00 to 23:15) -> 'Distinct SQLIDs' is the count of the distinct number of SQLIDs with the given SQL Command Type found over all the ASH samples in the analysis period Distinct Avg Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Active SQL Command Type SQLIDs % Activity Sessions ---------------------------------------- ---------- ---------- ---------- SELECT 7 1.38 0.00 ------------------------------------------------------------- Top SQL Statements DB/Inst: ANQING/anqing1 (May 26 08:00 to 23:15) SQL ID Planhash % Activity Event % Event ------------- ----------- ---------- ------------------------------ ---------- 4gd6b1r53yt88 N/A 1.38 PX Deq: reap credit 0.75 ** SQL Text Not Available ** 531sc6y5xdd41 N/A 1.01 SQL*Net break/reset to client 0.63 ** SQL Text Not Available ** ------------------------------------------------------------- Top SQL using literals DB/Inst: ANQING/anqing1 (May 26 08:00 to 23:15) No data exists for this section of the report. ------------------------------------------------------------- Top PL/SQL Procedures DB/Inst: ANQING/anqing1 (May 26 08:00 to 23:15) No data exists for this section of the report. ------------------------------------------------------------- Top Sessions DB/Inst: ANQING/anqing1 (May 26 08:00 to 23:15) -> '# Samples Active' shows the number of ASH samples in which the session was found waiting for that particular event. The percentage shown in this column is calculated with respect to wall clock time and not total database activity. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 -> 'XIDs' shows the number of distinct transaction IDs sampled in ASH when the session was waiting for that particular event -> For sessions running Parallel Queries, this section will NOT aggregate the PQ slave activity into the session issuing the PQ. Refer to the 'Top Sessions running PQs' section for such statistics. Sid, Serial# % Activity Event % Event --------------- ---------- ------------------------------ ---------- User Program # Samples Active XIDs -------------------- ------------------------------ ------------------ -------- 160, 1 39.87 control file parallel write 28.30 SYS oracle@rac1 (CKPT) 225/55K [ 0%] 0 control file sequential read 11.45 91/55K [ 0%] 0 167, 1 24.91 control file sequential read 22.64 SYS oracle@rac1 (LMON) 180/55K [ 0%] 0 CPU + Wait for CPU 1.51 12/55K [ 0%] 0 148,23561 8.55 latch free 8.55 SYS oracle@rac1 (J002) 68/55K [ 0%] 0 161, 1 4.91 log file parallel write 4.91 SYS oracle@rac1 (LGWR) 39/55K [ 0%] 0 162, 1 3.40 db file parallel write 3.40 SYS oracle@rac1 (DBW0) 27/55K [ 0%] 0 ------------------------------------------------------------- Top Blocking Sessions DB/Inst: ANQING/anqing1 (May 26 08:00 to 23:15) -> Blocking session activity percentages are calculated with respect to Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 waits on enqueues, latches and "buffer busy" only -> '% Activity' represents the load on the database caused by a particular blocking session -> '# Samples Active' shows the number of ASH samples in which the blocking session was found active. -> 'XIDs' shows the number of distinct transaction IDs sampled in ASH when the blocking session was found active. Blocking Sid % Activity Event Caused % Event --------------- ---------- ------------------------------ ---------- User Program # Samples Active XIDs -------------------- ------------------------------ ------------------ -------- 161, 1 2.26 log file sync 2.26 SYS oracle@rac1 (LGWR) 130/55K [ 0%] 0 ------------------------------------------------------------- Top Sessions running PQs DB/Inst: ANQING/anqing1 (May 26 08:00 to 23:15) No data exists for this section of the report. ------------------------------------------------------------- Top DB Objects DB/Inst: ANQING/anqing1 (May 26 08:00 to 23:15) No data exists for this section of the report. ------------------------------------------------------------- Top DB Files DB/Inst: ANQING/anqing1 (May 26 08:00 to 23:15) No data exists for this section of the report. ------------------------------------------------------------- Top Latches DB/Inst: ANQING/anqing1 (May 26 08:00 to 23:15) Max Sample Latch % Latch Blocking Sid % Activity Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Wait secs ------------------------------ ---------- --------------- ---------- ---------- # Waits # Sampled Wts # Sampled Wts # Sampled Wts # Sampled Wts Sampled < 10ms 10ms - 100ms 100ms - 1s > 1s -------------- -------------- -------------- -------------- -------------- latch: JS slv state obj latch 8.55 Held Shared 8.55 0.000000 0 0 0 0 0 ------------------------------------------------------------- Activity Over Time DB/Inst: ANQING/anqing1 (May 26 08:00 to 23:15) -> Analysis period is divided into smaller time slots -> Top 3 events are reported in each of those slots -> 'Slot Count' shows the number of ASH samples in that slot -> 'Event Count' shows the number of ASH samples waiting for that event in that slot -> '% Event' is 'Event Count' over all ASH samples in the analysis period Slot Event Slot Time (Duration) Count Event Count % Event -------------------- -------- ------------------------------ -------- ------- 08:00:00 (84.0 min) 67 control file sequential read 27 3.40 control file parallel write 20 2.52 CPU + Wait for CPU 8 1.01 09:24:00 (92.0 min) 71 control file sequential read 23 2.89 control file parallel write 22 2.77 CPU + Wait for CPU 10 1.26 10:56:00 (92.0 min) 64 control file sequential read 28 3.52 control file parallel write 22 2.77 CPU + Wait for CPU 4 0.50 12:28:00 (92.0 min) 66 control file sequential read 29 3.65 control file parallel write 21 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 2.64 CPU + Wait for CPU 11 1.38 14:00:00 (92.0 min) 56 control file sequential read 30 3.77 control file parallel write 22 2.77 SQL*Net break/reset to client 1 0.13 15:32:00 (92.0 min) 77 control file sequential read 29 3.65 control file parallel write 22 2.77 CPU + Wait for CPU 15 1.89 17:04:00 (92.0 min) 76 control file sequential read 35 4.40 control file parallel write 25 3.14 CPU + Wait for CPU 4 0.50 18:36:00 (92.0 min) 159 latch free 68 8.55 control file sequential read 33 4.15 control file parallel write 22 2.77 20:08:00 (92.0 min) 80 control file sequential read 33 4.15 control file parallel write 24 3.02 CPU + Wait for CPU 5 0.63 21:40:00 (92.0 min) 73 control file sequential read 25 3.14 control file parallel write 24 3.02 CPU + Wait for CPU 10 1.26 23:12:00 (3.2 min) 6 CPU + Wait for CPU 4 0.50 control file parallel write 1 0.13 log file parallel write 1 0.13 ------------------------------------------------------------- End of Report Report written to /u01/daveash.txt Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SYS@anqing1(rac1)> 这个就是用 ashrpt.sql 脚本来生成报告,当然也可以使用 Toad 来生成,这个 也是比较方便的一个工具。 1.12 AWR Blog:http://blog.csdn.net/tianlesoftware/archive/2009/10/16/4682300.aspx 1.12.1 AWR 说明 Oracle 10g 之前对数据库做性能检测使用 statspack 工具。 关于 statspack 的 说明,参考我的 Blog: statspack 安装使用 和 report 分析 http://blog.csdn.net/tianlesoftware/archive/2009/10/16/4682329.aspx Oracle Database 10g 提 供 了 一 个 新 的 工 具 : (AWR:Automatic Workload Repository)。Oracle 建议用户用这个取代 Statspack。AWR 实质上是一个 Oracle 的内置工具,它采集与性能相关的统计数据,并从那些统计数据中导出性能量度, 以跟踪潜在的问题。 与 Statspack 不同,快照由一个称为 MMON 的新的后台进程及其从进程自 动地每小时采集一次。为了节省空间,采集的数据在 7 天后自动清除。快照频 率和保留时间都可以由用户修改。它产生两种类型的输出:文本格式(类似于 Statspack 报表的文本格式但来自于 AWR 信息库)和默认的 HTML 格式(拥 有到部分和子部分的所有超链接),从而提供了非常用户友好的报表。 AWR 使用几个表来存储采集的统计数据,所有的表都存储在新的名称为 SYSAUX 的特定表空间中的 SYS 模式下,并且以 WRM$_* 和 WRH$_* 的 格式命名。前一种类型存储元数据信息(如检查的数据库和采集的快照),后一 种类型保存实际采集的统计数据。H 代表“历史数据 (historical)”而 M 代表“元 数据 (metadata)”。 在这些表上构建了几种带前缀 DBA_HIST_ 的视图,这些视图可以用来编写 您自己的性能诊断工具。视图的名称直接与表相关;例如,视图 DBA_HIST_SYSMETRIC_SUMMARY 是在 WRH$_SYSMETRIC_SUMMARY 表上构建的。 注意一点: statistics_level 默认是 typical,在 10g 中表监控是激活的,强烈建议在 10g 中此参数的值是 typical。如果 STATISTICS_LEVEL 设置为 basic,不仅不能监控 表,而且将禁掉如下一些 10g 的新功能: ASH(Active Session History) ASSM(Automatic Shared Memory Management) Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 AWR(Automatic Workload Repository) ADDM(Automatic Database Diagnostic Monitor) 1.12.2 AWR 使用 SQL>@?/rdbms/admin/awrrpt.sql Specify the Report Type ~~~~~~~~~~~~~~~~~~~~~~~ Would you like an HTML report, or a plain text report? Enter 'html' for an HTML report, or 'text' for plain text Defaults to 'html' 输入 report_type 的值: Type Specified: html Specify the number of days of snapshots to choose from ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Entering the number of days (n) will result in the most recent (n) days of snapshots being listed. Pressing without specifying a number lists all completed snapshots. 输入 num_days 的值: 1 Listing the last day's Completed Snapshots Snap Instance DB Name Snap Id Snap Started Level ------------ ------------ --------- ------------------ ----- orcl10g ORCL10G 142 03 7 月 2009 08:11 1 143 03 7 月 2009 09:00 1 144 03 7 月 2009 10:00 1 145 03 7 月 2009 11:00 1 146 03 7 月 2009 12:01 1 Specify the Begin and End Snapshot Ids ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 输入 begin_snap 的值: 142 Begin Snapshot Id specified: 142 输入 end_snap 的值: 146 End Snapshot Id specified: 146 Specify the Report Name ~~~~~~~~~~~~~~~~~~~~~~~ The default report file name is awrrpt_1_142_146.html. To use this name, Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 press to continue, otherwise enter an alternative. 输入 report_name 的值: D:\awrrpt_1_142_146.html Report written to D:\awrrpt_1_142_146.html 1.12.3 AWR 操作 3.1. 查看当前的 AWR 保存策略 SQL> col SNAP_INTERVAL format a20 SQL> col RETENTION format a20 SQL> select * from dba_hist_wr_control; DBID SNAP_INTERVAL RETENTION TOPNSQL ---------- -------------------- -------------------- ---------- 262089084 +00000 01:00:00.0 +00007 00:00:00.0 DEFAULT 以上结果表示,每小时产生一个 SNAPSHOT,保留 7 天。 3.2. 调整 AWR 配置 AWR 配置都是通过 dbms_workload_repository 包进行配置。 3.2.1 调整 AWR 产生 snapshot 的频率和保留策略,如将收集间隔时间改为 30 分 钟一次。并且保留 5 天时间(单位都是分钟): SQL> exec dbms_workload_repository.modify_snapshot_settings(interval=>30, retention=>5*24*60); 3.2.2 关闭 AWR,把 interval 设为 0 则关闭自动捕捉快照 SQL> exec dbms_workload_repository.modify_snapshot_settings(interval=>0); 3.2.3 手工创建一个快照 SQL> exec DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT(); 3.2.4 查看快照 SQL> select * from sys.wrh$_active_session_history 3.2.5 手工删除指定范围的快照 SQL> exec DBMS_WORKLOAD_REPOSITORY.DROP_SNAPSHOT_RANGE(low_snap_id => 973, high_snap_id => 999, dbid => 262089084); 3.2.6 创建 baseline,保存这些数据用于将来分析和比较 SQL> exec dbms_workload_repository.create_baseline(start_snap_id => 1003, Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 end_snap_id => 1013, 'apply_interest_1'); 3.2.7 删除 baseline SQL> exec DBMS_WORKLOAD_REPOSITORY.DROP_BASELINE(baseline_name => 'apply_interest_1', cascade => FALSE); 3.2.8 将 AWR 数据导出并迁移到其它数据库以便于以后分析 SQL> exec DBMS_SWRF_INTERNAL.AWR_EXTRACT(dmpfile => 'awr_data.dmp', mpdir => 'DIR_BDUMP', bid => 1003, eid => 1013); 3.2.9 迁移 AWR 数据文件到其他数据库 SQL> exec DBMS_SWRF_INTERNAL.AWR_LOAD(SCHNAME => 'AWR_TEST', dmpfile => 'awr_data.dmp', dmpdir => 'DIR_BDUMP'); 把 AWR 数据转移到 SYS 模式中: SQL> exec DBMS_SWRF_INTERNAL.MOVE_TO_AWR (SCHNAME => 'TEST'); 1.12.4 AWR 报告分析 这部分内容,可以参考 statspack,这 2 个内容都差不多。 statspack 安装使用 和 report 分析 http://blog.csdn.net/tianlesoftware/archive/2009/10/16/4682329.aspx 4.1 SQL ordered by Elapsed Time 记录了执行总和时间的 TOP SQL(请注意是监控范围内该 SQL 的执行时间总 和,而不是单次 SQL 执行时间 Elapsed Time = CPU Time + Wait Time)。 Elapsed Time(S): SQL 语句执行用总时长,此排序就是按照这个字段进行的。 注意该时间不是单个 SQL 跑的时间,而是监控范围内 SQL 执行次数的总和时间。 单位时间为秒。Elapsed Time = CPU Time + Wait Time CPU Time(s): 为 SQL 语句执行时 CPU 占用时间总时长,此时间会小于等于 Elapsed Time 时间。单位时间为秒。 Executions: SQL 语句在监控范围内的执行次数总计。 Elap per Exec(s): 执行一次 SQL 的平均时间。单位时间为秒。 % Total DB Time: 为 SQL 的 Elapsed Time 时间占数据库总时间的百分比。 SQL ID: SQL 语句的 ID 编号,点击之后就能导航到下边的 SQL 详细列表中, 点击 IE 的返回可以回到当前 SQL ID 的地方。 SQL Module: 显示该 SQL 是用什么方式连接到数据库执行的,如果是用 SQL*Plus 或者 PL/SQL 链接上来的那基本上都是有人在调试程序。一般用前台 应用链接过来执行的 sql 该位置为空。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL Text: 简单的 sql 提示,详细的需要点击 SQL ID。 4.2 SQL ordered by CPU Time: 记录了执行占 CPU 时间总和时间最长的 TOP SQL(请注意是监控范围内该 SQL 的执行占 CPU 时间总和,而不是单次 SQL 执行时间)。 4.3 SQL ordered by Gets: 记录了执行占总 buffer gets(逻辑 IO)的 TOP SQL(请注意是监控范围内该 SQL 的执行占 Gets 总和,而不是单次 SQL 执行所占的 Gets)。 4.4 SQL ordered by Reads: 记录了执行占总磁盘物理读(物理 IO)的 TOP SQL(请注意是监控范围内该 SQL 的执行占磁盘物理读总和,而不是单次 SQL 执行所占的磁盘物理读)。 4.5 SQL ordered by Executions: 记录了按照 SQL 的执行次数排序的 TOP SQL。该排序可以看出监控范围内 的 SQL 执行次数。 4.6 SQL ordered by Parse Calls: 记录了 SQL 的软解析次数的 TOP SQL。说到软解析(soft prase)和硬解析(hard prase),就不能不说一下 Oracle 对 sql 的处理过程。 4.7 SQL ordered by Sharable Memory: 记录了 SQL 占用 library cache 的大小的 TOP SQL。Sharable Mem (b):占用 library cache 的大小,单位是 byte。 4.8 SQL ordered by Version Count: 记录了 SQL 的打开子游标的 TOP SQL。 4.9 SQL ordered by Cluster Wait Time: 记录了集群的等待时间的 TOP SQL 1.12.5 AWR 查看 DB 负载 AWR 报告是 DBA 常用的一个性能报告。 关于 AWR 报告的生成,参考我 的 Blog: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Oracle AWR 介绍 http://blog.csdn.net/tianlesoftware/archive/2009/10/16/4682300.aspx 在 AWR 报告的前第二部分就是有关快照的一个统计信息说明。 Snap Id Snap Time Sessions Cursors/Session Begin Snap: 3954 30-May-11 08:00:28 100 25.1 End Snap: 3962 30-May-11 16:00:44 146 21.0 Elapsed: 480.26 (mins) DB Time: 1,768.80 (mins) 这个是我的一个测试数据,其中有 Elapsed 和 DB Time. 通过这 2 个数据, 就可以计算出 DB 的负载情况。 DB Time 指 cpu time+ wait time(不包含空闲等待)。 即 db time 记录的是服 务器花在数据库运算(非后台进程)和等待(非空闲等待)上的时间。 Elapsed: 指的是整个时间,如果有多个 CPU,总时间就是 Elapsed*CPU 个 数。 查看 CPU 个数可以使用如下命令: [root@db1 proc]# cat /proc/cpuinfo | grep 'processor' | wc -l 16 Linux CPU 信息查看 http://blog.csdn.net/tianlesoftware/archive/2010/10/27/5970500.aspx 现在计算一下这个测试数据 DB 的负载: 1,768.80/(480.26*16) =23% 即在整个 DB 运行期间,有 23%的时间是在处理事务信息。 注意这个数据不包含 DB 后台进程的时间。 1.13 Statspack Blog:http://blog.csdn.net/tianlesoftware/archive/2009/10/16/4682329.aspx 1.13.1. Statspack 安装 statspack 是 Oracle 9i 之前使用的一个数据库收集工具。 通过该工具的分析 可以清楚的看到数据库的信息。 statspack 的安装过程如下: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1. 安装 statspack. 在 oracle_home\rdmbs\admin\目录下运行: SQL>@spcreate.sql 若创建失败则在同一目录下运行: @spdrop.sql 2. 测试: SQL>execute statspack.snap PL/SQL procedure successfully completed. SQL>execute statspack.snap PL/SQL procedure successfully completed. SQL>@spreport.sql exec statspack.snap; -- 进行信息收集统计,每次运行都将产生一个快照号, 获得快照号,必须要有两个以上的快照,才能生成报表 查选快照信息: SQL>select SNAP_ID, SNAP_TIME from STATS$SNAPSHOT; 获取 statspack 报告: @spreport.sql -- 输入需要查看的开始快照号与结束快照号 其他相关脚本: spauto.sql: 利用 dbms_job 提交一个作业,自动的进行 STATPACK 的信息收 集统计 sppurge.sql :清除一段范围内的统计信息,需要提供开始快照与结束快照号 sptrunc.sql : 清除(truncate)所有统计信息 1.13.2 查看 Statspack 生成源代码 在 oracle 9i 里面,我们可以通过查看 statspack 生成脚本来帮助我们理解 report,但是 10g 的 AWR 是通过 dbms_workload_repository 包来实现 AWR 的。 包把代码都封装了起来,我们无法查看。 statspack 的生成脚本位置:$ORACLE_HOME/rdbms/admin/sprepins.sql 代码很长,不过看懂了,能帮助我们理解 statspack 中各个数据的意义。 1.13.3 statspack report 分析 3.1 调整的先后次序 1. Tune the design. -- Application designers Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 2. Tune the application. -- Application developers 3. Tune memory. 4. Tune I/O. 5. Tune contention. 6. Tune the operating system. 3.2 Statspack 分析报告详解 statspack 输出结果中必须查看的十项内容 1、负载间档(Load profile) 2、实例效率点击率(Instance efficiency hit ratios) 3、首要的 5 个等待事件(Top 5 wait events) 4、等待事件(Wait events) 5、闩锁等待 6、首要的 SQL(Top sql) 7、实例活动(Instance activity) 8、文件 I/O(File I/O) 9、内存分配(Memory allocation) 10、缓冲区等待(Buffer waits 3.2.1.报表头信息 数据库实例相关信息,包括数据库名称、ID、版本号及主机等信息。 STATSPACK report for DB Name DB Id Instance Inst Num Release Cluster Host BLISSDB 4196236801 blissdb 1 9.2.0.4.0 NO BLISS Snap Id Snap Time Sessions Curs/Sess Comment Begin Snap: 4 23-6 月 -05 17:43:32 10 3.3 End Snap: 5 23-6 月 -05 18:01:32 12 6.1 Elapsed: 18.00 (mins) Cache Sizes (end) Buffer Cache: 24M Std Block Size: 8K Shared Pool Size: 48M Log Buffer: 512K 3.2.2.负载间档 该部分提供每秒和每个事物的统计信息,是监控系统吞吐量和负载变化的重 要部分。 Load Profile ~~~~~~~~~~~~ Per Second Per Transaction Redo size: 431,200.16 18,627,847.04z Logical reads: 4,150.76 179,312.72 Block changes: 2,252.52 97,309.00 Physical reads: 23.93 1,033.56 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Physical writes: 68.08 2,941.04 User calls: 0.96 41.36 Parses: 1.12 48.44 Hard parses: 0.04 1.92 Sorts: 0.77 33.28 Logons: 0.00 0.20 Executes: 2.36 102.12 Transactions: 0.02 其中参数说明: Redo size:每秒产生的重做日志大小(单位字节),可标志数据变更频率, 数据 库任务的繁重与否。本例中平均每秒产生了 430K 左右的重做,每个事务品均产 生了 18M 的重做。 Logical reads:平次每秒产生的逻辑读,单位是 block。 block changes:每秒 block 变化数量,数据库事物带来改变的块数量。 Physical reads:平均每秒数据库从磁盘读取的 block 数。 Logical reads 和 Physical reads 比较:大约有 0.55%的逻辑读导致了物理 I/O, 平均每个事务执行了大约 18 万个逻辑读,在这个例子中,有一些大的事务被执 行,因此很高的读取数目是可以接受的。 Physical writes:平均每秒数据库写磁盘的 block 数。 User calls:每秒用户 call 次数。 Parses 和 Hard parses:每秒大约 1.12 个解析,其中有 4%为硬解析,系统每 25 秒分析一些 SQL,都还不错。对于优化好的系统,运行了好几天后,这一列 应该达到 0,所有的 sql 在一段时间后都应该在共享池中。 Sorts:每秒产生的排序次数。 Executes:每秒执行次数。 Transactions:每秒产生的事务数,反映数据库任务繁重与否。 % Blocks changed per Read: 54.27 Recursive Call %: 86.94 Rollback per transaction %: 12.00 Rows per Sort: 32.59 参数说明: % Blocks changed per Read:说明 46%的逻辑读是用于那些只读的而不是可修 改的块,该系统只更新 54%的块。 Rollback per transaction %:事务回滚的百分比。计算公式为:Round(User rollbacks / (user commits + user rollbacks) ,4)* 100%。本例中每 8.33 个事务导致一 个回滚。如果回滚率过高,可能说明数据库经历了太多的无效操作。过多的回滚 可能还会带来 Undo Block 的竞争。 3.2.3.实例命中率 该部分可以提前找出 ORACLE 潜在将要发生的性能问题,很重要。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Instance Efficiency Percentages (Target 100%) ~~~~~~~~~~~~~~~~~~~~ Buffer Nowait %: 100.00 Redo NoWait %: 100.00 Buffer Hit %: 99.42 In-memory Sort %: 100.00 Library Hit %: 98.11 Soft Parse %: 96.04 Execute to Parse %: 52.57 Latch Hit %: 100.00 Parse CPU to Parse Elapsd %: 11.40 % Non-Parse CPU: 99.55 参数说明: Buffer Nowait %:在缓冲区中获取 Buffer 的未等待比率,Buffer Nowait<99% 说明,有可能是有热块(查找 x$bh 的 tch 和 v$latch_children 的 cache buffers chains)。 Redo NoWait %:在 Redo 缓冲区获取 Buffer 的未等待比率。 Buffer Hit %:数据块在数据缓冲区中的命中率,通常应在 90%以上,否则, 小于 95%,需要调整重要的参数,小于 90%可能是要加 db_cache_size,但是大 量的非选择的索引也会造成该值很高(大量的 db file sequential read)。如果一个 经常访问的列上的索引被删除,可能会造成 buffer hit 显著下降。如果增加了索 引,但是它影响了 ORACLE 正确的选择表连接时的驱动顺序,那么可能会导致 buffer hit 显著增高。如果命中率变化幅度很大,说明需要改变 SQL 模式。 In-memory Sort %:在内存中的排序率。 Library Hit %:主要代表 sql 在共享区的命中率,通常在 95%以上,否则需 要要考虑加大共享池,绑定变量,修改 cursor_sharing 等参数。 Soft Parse %:近似看作 sql 在共享区的命中率,小于<95%,需要考虑到绑定, 如果低于 80%,那么就可能 sql 基本没有被重用。 Execute to Parse %:一个语句执行和分析了多少次的度量。在一个分析,然 后执行语句,且再也不在同一个会话中执行它的系统中,这个比值为 0。 计算公式为:Execute to Parse =100 * (1 - Parses/Executions)。所以如果系统 Parses > Executions,就可能出现该比率小于 0 的情况。本例中,对于每个分析来 说大约执行了 2.1 次。该值<0 通常说明 shared pool 设置或效率存在问题,造成 反复解析,reparse 可能较严重,或者可是同 snapshot 有关,如果该值为负值或者 极低,通常说明数据库性能存在问题。 Latch Hit %:要确保>99%,否则存在严重的性能问题,比如绑定等会影响该 参数。 Parse CPU to Parse Elapsd %:计算公式为:Parse CPU to Parse Elapsd %= 100*(parse time cpu / parse time elapsed)。即:解析实际运行时间/(解析实际运行 时间+解析中等待资源时间)。此处为 11.4%,非常低,用于解析花费的每个 CPU 秒花费了大约 8.77 秒的 wall clock 时间,这说明花了很多时间等待一个资源。如 果该比率为 100%,意味着 CPU 时间等于经过的时间,没有任何等待。 % Non-Parse CPU : 计 算 公 式 为 : % Non-Parse CPU =round(100*1-PARSE_CPU/TOT_CPU),2)。太低表示解析消耗时间过多。与 PARSE_CPU 相比,如果 TOT_CPU 很高,这个比值将接近 100%,这是很好的, 说明计算机执行的大部分工作是执行查询的工作,而不是分析查询的工作。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 3.2.4.Shared Pool 相关统计数据 Shared Pool Statistics Begin End ------ ------ Memory Usage %: 60.45 62.42 % SQL with executions>1: 81.38 78.64 % Memory for SQL w/exec>1: 70.36 68.02 参数说明: Memory Usage %:正在使用的共享池的百分率。这个数字应该长时间稳定在 75%~90%。如果这个百分率太低,就浪费内存。如果这个百分率太高,会使共 享池外部的组件老化,如果 SQL 语句被再次执行,这将使得 SQL 语句被硬解析。 在一个大小合适的系统中,共享池的使用率将处于 75%到略低于 90%的范围内。 % SQL with executions>1:这是在共享池中有多少个执行次数大于一次的 SQL 语句的度量。在一个趋向于循环运行的系统中,必须认真考虑这个数字。 在这个循环系统中,在一天中相对于另一部分时间的部分时间里执行了一组不同 的 SQL 语句。在共享池中,在观察期间将有一组未被执行过的 SQL 语句,这仅 仅是因为要执行它们的语句在观察期间没有运行。只有系统连续运行相同的 SQL 语句组,这个数字才会接近 100%。这里显示,在这个共享池中几乎有 80%的 SQL 语句在 18 分钟的观察窗口中运行次数多于一次。剩下的 20%的语句可能已经在 那里了--系统只是没有理由去执行它。 % Memory for SQL w/exec>1:这是与不频繁使用的 SQL 语句相比,频繁使 用的 SQL 语句消耗内存多少的一个度量。这个数字将在总体上与% SQL with executions>1 非常接近,除非有某些查询任务消耗的内存没有规律。 在稳定状态下,总体上会看见随着时间的推移大约有 75%~85%的共享池被 使用。如果 Statspack 报表的时间窗口足够大到覆盖所有的周期,执行次数大于 一次的 SQL 语句的百分率应该接近于 100%。这是一个受观察之间持续时间影响 的统计数字。可以期望它随观察之间的时间长度增大而增大。 3.2.5.首要等待事件 常见等待事件说明: oracle 等待事件是衡量 oracle 运行状况的重要依据及指示,主要有空闲等待 事件和非空闲等待事件。 TIMED_STATISTICS:=TRUE,等待事件按等待的时间排序,= FALSE,等 待事件按等待的数量排序。 运行 statspack 期间必须 session 上设置 TIMED_STATISTICS = TRUE。 空闲等待事件是 oracle 正等待某种工作,在诊断和优化数据库时候,不用过 多注意这部分事件,非空闲等待事件专门针对 oracle 的活动,指数据库任务或应 用程序运行过程中发生的等待,这些等待事件是我们在调整数据库应该关注的。 Top 5 Timed Events Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 ~~~~~~~~~~~~~~~~~~ % Total Event Waits Time (s) Ela Time -------------------------------------------- ------------ ----------- -------- db file sequential read 22,154 259 62.14 CPU time 49 11.67 log file parallel write 2,439 26 6.30 db file parallel write 400 22 5.32 SQL*Net message from dblink 4,575 15 3.71 ------------------------------------------------------------- 这里是比其他任何事件都能使速度减慢的事件。比较影响性能的常见等待事 件: db file scattered read:该事件通常与全表扫描有关。因为全表扫描是被放入内 存中进行的进行的,通常情况下它不可能被放入连续的缓冲区中,所以就散布在 缓冲区的缓存中。该指数的数量过大说明缺少索引或者限制了索引的使用(也可 以调整 optimizer_index_cost_adj)。这种情况也可能是正常的,因为执行全表扫描 可能比索引扫描效率更高。当系统存在这些等待时,需要通过检查来确定全表扫 描是否必需的来调整。如果经常必须进行全表扫描,而且表比较小,把该表存人 keep 池。如果是大表经常进行全表扫描,那么应该是 OLAP 系统,而不是 OLTP 的。 db file sequential read:该事件说明在单个数据块上大量等待,该值过高通常 是由于表间连接顺序很糟糕,或者使用了非选择性索引。通过将这种等待与 statspack 报表中已知其它问题联系起来(如效率不高的 sql),通过检查确保索引扫 描是必须的,并确保多表连接的连接顺序来调整, DB_CACHE_SIZE 可以决定该 事件出现的频率。 db file sequential read:该事件说明在单个数据块上大量等待,该值过高通常 是由于表间连接顺序很糟糕,或者使用了非选择性索引。通过将这种等待与 statspack 报表中已知其它问题联系起来(如效率不高的 sql),通过检查确保索引 扫描是必须的,并确保多表连接的连接顺序来调整,DB_CACHE_SIZE 可以决 定该事件出现的频率。 buffer busy wait:当缓冲区以一种非共享方式或者如正在被读入到缓冲时, 就会出现该等待。该值不应该大于 1%,确认是不是由于热点块造成(如果是可 以用反转索引,或者用更小块大小)。 latch free:常跟应用没有很好的应用绑定有关。闩锁是底层的队列机制(更 加准确的名称应该是互斥机制),用于保护系统全局区(SGA)共享内存结构闩 锁用于防止对内存结构的并行访问。如果闩锁不可用,就会记录一次闩锁丢失。 绝大多数得闩锁问题都与使用绑定变量失败(库缓存闩锁)、生成重作问题(重 执行分配闩锁)、缓存的争用问题(缓存 LRU 链) 以及缓存的热数据宽块(缓存链) 有关。当闩锁丢失率高于 0.5%时,需要调整这个问题。 log buffer space:日志缓冲区写的速度快于 LGWR 写 REDOFILE 的速度,可 以增大日志文件大小,增加日志缓冲区的大小,或者使用更快的磁盘来写数据。 logfile switch:通常是因为归档速度不够快,需要增大重做日志。 log file sync:当一个用户提交或回滚数据时,LGWR 将会话得重做操作从日 志缓冲区填充到日志文件中,用户的进程必须等待这个填充工作完成。在每次提Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 交时都出现,如果这个等待事件影响到数据库性能,那么就需要修改应用程序的 提交频率, 为减少这个等待事件,须一次提交更多记录,或者将重做日志 REDO LOG 文件访在不同的物理磁盘上。 Wait time: 等待时间包括日志缓冲的写入和发送操作。 更多内容参考: Oracle 常见的 33 个等待事件 http://blog.csdn.net/tianlesoftware/archive/2010/08/12/5807800.aspx 3.2.6.数据库用户程序发生的所有等待事件 Wait Events for DB: BLISSDB Instance: blissdb Snaps: 4 -5 -> s - second -> cs - centisecond - 100th of a second -> ms - millisecond - 1000th of a second -> us - microsecond - 1000000th of a second -> ordered by wait time desc, waits desc (idle events last) Avg Total Wait wait Waits Event Waits Timeouts Time (s) (ms) /txn ---------------------------- ------------ ---------- ---------- ------ -------- db file sequential read 22,154 0 259 12 886.2 log file parallel write 2,439 2,012 26 11 97.6 db file parallel write 400 0 22 55 16.0 SQL*Net message from dblink 4,575 0 15 3 183.0 SQL*Net more data from dblin 64,490 0 13 0 2,579.6 control file parallel write 416 0 5 13 16.6 db file scattered read 456 0 5 11 18.2 write complete waits 9 0 5 568 0.4 control file sequential read 370 0 5 13 14.8 log buffer space 126 0 4 34 5.0 free buffer waits 11 1 3 313 0.4 log file switch completion 13 0 2 188 0.5 log file sync 90 0 1 8 3.6 log file sequential read 10 0 0 16 0.4 latch free 17 6 0 8 0.7 direct path read 56 0 0 1 2.2 direct path write 56 0 0 1 2.2 SQL*Net more data to client 173 0 0 0 6.9 SQL*Net message to dblink 4,575 0 0 0 183.0 LGWR wait for redo copy 8 0 0 1 0.3 log file single write 10 0 0 1 0.4 db file single write 5 0 0 0 0.2 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL*Net break/reset to clien 5 0 0 0 0.2 async disk IO 15 0 0 0 0.6 SQL*Net message from client 789 0 3,290 4170 31.6 virtual circuit status 36 36 1,082 30069 1.4 wakeup time manager 34 34 1,034 30403 1.4 SQL*Net message to client 791 0 0 0 31.6 SQL*Net more data from clien 30 0 0 0 1.2 ------------------------------------------------------------- 3.2.7.数据库后台进程发生的等待事件 Background Wait Events for DB: BLISSDB Instance: blissdb Snaps: 4 -5 -> ordered by wait time desc, waits desc (idle events last) Avg Total Wait wait Waits Event Waits Timeouts Time (s) (ms) /txn ---------------------------- ------------ ---------- ---------- ------ -------- log file parallel write 2,439 2,012 26 11 97.6 db file parallel write 400 0 22 55 16.0 control file parallel write 406 0 5 13 16.2 control file sequential read 258 0 4 16 10.3 db file sequential read 19 0 1 51 0.8 log buffer space 24 0 0 9 1.0 log file sequential read 10 0 0 16 0.4 latch free 14 6 0 9 0.6 db file scattered read 6 0 0 14 0.2 direct path read 56 0 0 1 2.2 direct path write 56 0 0 1 2.2 LGWR wait for redo copy 8 0 0 1 0.3 log file single write 10 0 0 1 0.4 rdbms ipc message 7,339 3,337 3,172 432 293.6 pmon timer 373 373 1,083 2903 14.9 smon timer 3 3 924 ###### 0.1 ------------------------------------------------------------- 3.2.8.TOP SQL 调整首要的 25 个缓冲区读操作和首要的 25 个磁盘读操作做的查询,将可对 系统性能产生 5%到 5000%的增益。 SQL ordered by Gets for DB: BLISSDB Instance: blissdb Snaps: 4 -5 -> End Buffer Gets Threshold: 10000 -> Note that resources reported for PL/SQL includes the resources used by all SQL statements called within the PL/SQL code. As individual SQL statements are also reported, it is possible and valid for the summed Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 total % to exceed 100 CPU Elapsd Buffer Gets Executions Gets per Exec %Total Time (s) Time (s) Hash Value --------------- ------------ -------------- ------ -------- --------- ---------- 1,230,745 1 1,230,745.0 27.5 16.39 60.69 1574310682 Module: PL/SQL Developer insert into city_day_cal select * from rptuser.city_day_cal@db15 1 143,702 1 143,702.0 3.2 1.75 18.66 3978122706 Module: PL/SQL Developer insert into city_day_cal select * from rptuser.city_day_cal@db15 1 where curtime between to_date('200501','yyyymm') and to_date(' 200502','yyyymm')-1 在报表的这一部分,通过 Buffer Gets 对 SQL 语句进行排序,即通过它执行 了多少个逻辑 I/O 来排序。顶端的注释表明一个 PL/SQL 单元的缓存获得(Buffer Gets)包括被这个代码块执行的所有 SQL 语句的 Buffer Gets。因此将经常在这个 列表的顶端看到 PL/SQL 过程,因为存储过程执行的单独的语句的数目被总计出 来。 SQL ordered by Reads for DB: BLISSDB Instance: blissdb Snaps: 4 -5 -> End Disk Reads Threshold: 1000 CPU Elapsd Physical Reads Executions Reads per Exec %Total Time (s) Time (s) Hash Value --------------- ------------ -------------- ------ -------- --------- ---------- 3,587 1 3,587.0 13.9 0.17 5.13 3342983569 Module: PL/SQL Developer select min(curtime),max(curtime) from city_day_cal 1,575 1 1,575.0 6.1 1.75 18.66 3978122706 Module: PL/SQL Developer insert into city_day_cal select * from rptuser.city_day_cal@db15 1 where curtime between to_date('200501','yyyymm') and to_date(' 200502','yyyymm')-1 这部分通过物理读对 SQL 语句进行排序。这显示引起大部分对这个系统进 行读取活动的 SQL,即物理 I/O。 SQL ordered by Executions for DB: BLISSDB Instance: blissdb Snaps: 4 -5 -> End Executions Threshold: 100 CPU per Elap per Executions Rows Processed Rows per Exec Exec (s) Exec (s) Hash Value ------------ --------------- ---------------- ----------- ---------- ---------- 748 748 1.0 0.00 0.00 3371479671 select t.name, (select owner_instance from sys.aq$_queue_table_ affinities where table_objno = t.objno) from system.aq$_queue _tables t where t.name = :1 and t.schema = :2 for update skip lo Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 cked 442 1,142 2.6 0.00 0.00 1749333492 select position#,sequence#,level#,argument,type#,charsetid,chars etform,properties,nvl(length, 0), nvl(precision#, 0),nvl(scale, 0),nvl(radix, 0), type_owner,type_name,type_subname,type_linknam e,pls_type from argument$ where obj#=:1 and procedure#=:2 order by sequence# desc 这部分告诉我们在这段时间中执行最多的 SQL 语句。为了隔离某些频繁执 行的查询,以观察是否有某些更改逻辑的方法以避免必须如此频繁的执行这些查 询,这可能是很有用的。或许一个查询正在一个循环的内部执行,而且它可能在 循环的外部执行一次,可以设计简单的算法更改以减少必须执行这个查询的次 数。即使它运行的飞快,任何被执行几百万次的操作都将开始耗尽大量的时间。 3.2.9.实例活动 Instance Activity Stats for DB: BLISSDB Instance: blissdb Snaps: 4 -5 Statistic Total per Second per Trans CPU used by this session 4,870 4.5 194.8 CPU used when call started 4,870 4.5 194.8 CR blocks created 45 0.0 1.8 DBWR buffers scanned 24,589 22.8 983.6 DBWR checkpoint buffers written 14,013 13.0 560.5 DBWR checkpoints 5 0.0 0.2 „„ dirty buffers inspected 38,834 36.0 1,553.4 --脏缓冲的个数 free buffer inspected 40,463 37.5 1,618.5 --如果数量很大,说明缓冲区过小 „„ 3.2.10.I/O 下面两个报表是面向 I/O 的。通常,在这里期望在各设备上的读取和写入操 作是均匀分布的。要找出什么文件可能非常“热”。一旦 DBA 了解了如何读取 和写入这些数据,他们也许能够通过磁盘间更均匀的分配 I/O 而得到某些性能提 升。 Tablespace IO Stats for DB: BLISSDB Instance: blissdb Snaps: 4 -5 ->ordered by IOs (Reads + Writes) desc Tablespace Av Av Av Av Buffer Av Buf Reads Reads/s Rd(ms) Blks/Rd Writes Writes/s Waits Wt(ms) BLISS_DATA 17,649 16 12.3 1.2 44,134 41 0 0.0 UNDOTBS1 4,484 4 9.6 1.0 29,228 27 0 0.0 SYSTEM 340 0 31.0 1.1 36 0 0 0.0 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 File IO Stats for DB: BLISSDB Instance: blissdb Snaps: 4 -5 ->ordered by Tablespace, File Tablespace Filename ------------------------ ---------------------------------------------------- Av Av Av Av Buffer Av Buf Reads Reads/s Rd(ms) Blks/Rd Writes Writes/s Waits Wt(ms) -------------- ------- ------ ------- ------------ -------- ---------- ------ BLISS_DATA D:ORACLEORADATABLISSDBBLISS01.DBF 5,779 5 12.0 1.2 14,454 13 0 D:ORACLEORADATABLISSDBBLISS02.DBF 5,889 5 12.1 1.2 14,772 14 0 D:ORACLEORADATABLISSDBBLISS03.DBF 5,981 6 12.6 1.2 14,908 14 0 3.2.11.缓冲池 Buffer Pool Statistics for DB: BLISSDB Instance: blissdb Snaps: 4 -5 -> Standard block size Pools D: default, K: keep, R: recycle -> Default Pools for other block sizes: 2k, 4k, 8k, 16k, 32k Free Write Buffer Number of Cache Buffer Physical Physical Buffer Complete Busy P Buffers Hit % Gets Reads Writes Waits Waits Waits --- ---------- ----- ----------- ----------- ---------- ------- -------- ------ D 3,000 99.4 4,482,816 25,756 73,470 11 9 0 ------------------------------------------------------------- 如果我们使用多缓冲池的功能,上面的报表会告诉我们缓冲池引起的使用故 障。实际上这只是我们在报表的开头看到的信息的重复。 3.2.12.回滚段活动 Instance Recovery Stats for DB: BLISSDB Instance: blissdb Snaps: 4 -5 -> B: Begin snapshot, E: End snapshot Targt Estd Log File Log Ckpt Log Ckpt MTTR MTTR Recovery Actual Target Size Timeout Interval (s) (s) Estd IOs Redo Blks Redo Blks Redo Blks Redo Blks Redo Blks B 37 17 169 4012 3453 184320 3453 E 37 32 1385 57132 184320 184320 436361 一般期望活动在各回滚段间(除了 SYSTEM 回滚段外)均匀分布。在检查报表 的这一部分时,报表标题也具有需要记住的最有用信息。尤其是,如果完全使用 最佳设置时关于 Optmal 比 Avg Active 更大的建议。因为这是与 DBA 最有关的 活动(I/O 和回滚段信息)。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.14 SYSAUX 表空间 说明 1.14.1 SYSAUX 说明 在 Oracle 10g 版本中,引入了 SYSTEM 表空间的一个辅助表空间: SYSAUX 表空间。 SYSAUX 表空间存放一些其他的 metadata 组件,如 OEM,Streams 等会默认 存放在 SYSAUX 表空间里。这样也能降低 SYSTEM 表空间的负载。 因此 SYSAUX 表空间也是在在 DB 创建或者升级时自动创建的。 如果在手工使用 SQL 创建 DB 时没有指定 SYSAUX tablespace,那么创建语句会报错。 无法执 行。 在正常操作下, 不能 drop 和 rename SYSAUX 表空间。 如果 SYSAUX 表 空间不可用时, 数据库的核心功能还是可以继续运行的。只是一些存放在 SYSAUX 表空间里的功能收到限制,就如我们之前说的 OEM。 在 DB 创建时指定 SYSAUX 表空间,必须指定如下 4 个属性: (1). PERMANENT (2). READ WRITE (3). EXTENT MANAGMENT LOCAL (4). SEGMENT SPACE MANAGMENT AUTO 我们不能使用 alter tablespace 来修改这 4 个属性,同样也不能 drop 和 rename SYSAUX 表空间。 我们可以使用 v$sysaux_occupants 视图来查看 SYSAUX 表空间里的组件信 息,如: SQL> select occupant_name,schema_name,move_procedure from v$sysaux_occupants; occupant_name schema_name move_procedure ------------------------- -------------------- ---------------------------------------- logmnr system sys.dbms_logmnr_d.set_tablespace logstdby system sys.dbms_logstdby.set_tablespace streams sys xdb xdb xdb.dbms_xdb.movexdb_tablespace ao sys dbms_aw.move_awmeta xsoqhist sys dbms_xsoq.olapimoveproc xsamd olapsys dbms_amd.move_olap_catalog sm/awr sys sm/advisor sys sm/optstat sys sm/other sys statspack perfstat Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 odm dmsys move_odm sdo mdsys mdsys.move_sdo wm wmsys dbms_wm.move_proc ordim ordsys ordim/plugins ordplugins ordim/sqlmm si_informtn_schema em sysman emd_maintenance.move_em_tblspc text ctxsys dri_move_ctxsys ultrasearch wksys move_wk ultrasearch_demo_user wk_test move_wk expression_filter exfsys em_monitoring_user dbsnmp tsm tsmsys job_scheduler sys 26 rows selected. 这些组件占据这 SYSAUX 表空间,所以这些组件的大小也就决定 SYSAUX 表空间的大小。 根据这些组件创建时的初始化大小,SYSAUX 至少需要 400M 的空间。 还有一点要注意,就是这里的 schema_name 对应的是用户名。 SQL> desc dba_users; Name Null? Type ----------------------------------------- -------- ---------------------------- USERNAME NOT NULL VARCHAR2(30) USER_ID NOT NULL NUMBER PASSWORD VARCHAR2(30) ACCOUNT_STATUS NOT NULL VARCHAR2(32) LOCK_DATE DATE EXPIRY_DATE DATE DEFAULT_TABLESPACE NOT NULL VARCHAR2(30) TEMPORARY_TABLESPACE NOT NULL VARCHAR2(30) CREATED NOT NULL DATE PROFILE NOT NULL VARCHAR2(30) INITIAL_RSRC_CONSUMER_GROUP VARCHAR2(30) EXTERNAL_NAME VARCHAR2(4000) Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL> select username,account_status,default_tablespace from dba_users; USERNAME ACCOUNT_STATUS DEFAULT_TABLESPA ------------------------------ -------------------------------- ---------------- MDDATA EXPIRED & LOCKED USERS MDSYS EXPIRED & LOCKED SYSAUX ORDSYS EXPIRED & LOCKED SYSAUX CTXSYS EXPIRED & LOCKED SYSAUX ANONYMOUS EXPIRED & LOCKED SYSAUX EXFSYS EXPIRED & LOCKED SYSAUX OUTLN EXPIRED & LOCKED SYSTEM DIP EXPIRED & LOCKED USERS DMSYS EXPIRED & LOCKED SYSAUX DBSNMP OPEN SYSAUX SCOTT EXPIRED & LOCKED USERS WMSYS EXPIRED & LOCKED SYSAUX SYSMAN OPEN SYSAUX XDB EXPIRED & LOCKED SYSAUX TSMSYS EXPIRED & LOCKED USERS ORDPLUGINS EXPIRED & LOCKED SYSAUX MGMT_VIEW OPEN SYSTEM SI_INFORMTN_SCHEMA EXPIRED & LOCKED SYSAUX OLAPSYS EXPIRED & LOCKED SYSAUX SYS OPEN SYSTEM SYSTEM OPEN SYSTEM 21 rows selected. 这里没有显示这些组件的描述信息,因为显示不全。 感兴趣的,可以自己 查看一下。 SQL> desc v$sysaux_occupants Name Null? Type ----------------------------------------- -------- ---------------------------- OCCUPANT_NAME VARCHAR2(64) OCCUPANT_DESC VARCHAR2(64) SCHEMA_NAME VARCHAR2(64) MOVE_PROCEDURE VARCHAR2(64) MOVE_PROCEDURE_DESC VARCHAR2(64) Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SPACE_USAGE_KBYTES NUMBER 在 v$sysaux_occupants 视图里有个 move_procudure 的过程。 这个过程就是 用迁移组件信息的。就是对于已经安装好的组件,如果我们想把这些组件放到其 他的空间,就可以使用这个存储过程。如果没有对应的过程,就不可移动。 这样做可以控制 SYSAUX 表空间的大小。 比如我们的 AWR。 AWR 是 SYSAUX 中占用空间最多的组件。 对于一个有 10 个并发 session 的系统,就 需要 200M 的空间。当然,也可以修改 AWR 的保存策略来控制 AWR 所占用空 间的大小。 1.14.2 示例 1.14.2.1. 将 Logminer 从 SYSAUX 表空间,迁移到 users 表空间,在还原回来 (1)查看之前的信息: SQL> select OCCUPANT_NAME,OCCUPANT_DESC,SCHEMA_NAME,MOVE_PROCEDUR E,SPACE_USAGE_KBYTES from v$sysaux_occupants where occupant_name='LOGMNR'; OCCUPANT_NAME OCCUPANT_DESC SCHEMA_NAME MOVE_PROCEDURE SPACE_USAGE_KBYTES --------------- --------------- -------------------- ---------------------------------------- ------------------ LOGMNR LogMiner SYSTEM SYS.DBMS_LOGMNR_D.SET_TABLESPACE 6080 (2)移动 SQL> exec SYS.DBMS_LOGMNR_D.SET_TABLESPACE('USERS'); PL/SQL procedure successfully completed. (3)验证 SQL> select OCCUPANT_NAME,OCCUPANT_DESC,SCHEMA_NAME,MOVE_PROCEDUR E,SPACE_USAGE_KBYTES from v$sysaux_occupants where occupant_name='LOGMNR'; OCCUPANT_NAME OCCUPANT_DESC SCHEMA_NAME MOVE_PROCEDURE SPACE_USAGE_KBYTES --------------- --------------- -------------------- ---------------------------------------- ------------------ Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 LOGMNR LogMiner SYSTEM SYS.DBMS_LOGMNR_D.SET_TABLESPACE 0 --注意,这里占空的空间变成了 0. 数据迁移到了 USERS 表空间 (4)还原到 SYSAUX 表空间 SQL> exec SYS.DBMS_LOGMNR_D.SET_TABLESPACE('SYSAUX'); PL/SQL procedure successfully completed. (5)验证 SQL> select OCCUPANT_NAME,OCCUPANT_DESC,SCHEMA_NAME,MOVE_PROCEDUR E,SPACE_USAGE_KBYTES from v$sysaux_occupants where occupant_name='LOGMNR'; OCCUPANT_NAME OCCUPANT_DESC SCHEMA_NAME MOVE_PROCEDURE SPACE_USAGE_KBYTES --------------- --------------- -------------------- ---------------------------------------- ------------------ LOGMNR LogMiner SYSTEM SYS.DBMS_LOGMNR_D.SET_TABLESPACE 6080 --大小又变回来了。 1.14.2.2 SYSAUX 不能 drop SQL> drop tablespace SYSAUX including contents and datafiles; drop tablespace SYSAUX including contents and datafiles * ERROR at line 1: ORA-13501: Cannot drop SYSAUX tablespace 1.14.2.3 SYSAUX 不能重命名 SQL> alter tablespace SYSAUX rename to DAVE; alter tablespace SYSAUX rename to DAVE * ERROR at line 1: ORA-13502: Cannot rename SYSAUX tablespace 1.14.2.3 不能将 SYSAUX 改成只读 SQL> alter tablesapce SYSAUX read only; alter tablesapce SYSAUX read only * ERROR at line 1: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 ORA-00940: invalid ALTER command 1.15 Oracle undo 表空间管理 1.15.1 undo 说明 undo 表空间对 Oracle 来说,它保存的数据的前镜像,即修改之前的内容。 它是非常重要的的一个表空间。 官网对 undo 的定义如下: Oracle Database creates and manages information that is used to roll back, or undo, changes to the database. Such information consists of records of the actions of transactions, primarily before they are committed. These records are collectively referred to as undo. Undo records are used to: 1. Roll back transactions when a ROLLBACK statement is issued 2. Recover the database 3. Provide read consistency 4. Analyze data as of an earlier point in time by using Oracle Flashback Query 5. Recover from logical corruptions using Oracle Flashback features When a ROLLBACK statement is issued, undo records are used to undo changes that were made to the database by the uncommitted transaction. During database recovery, undo records are used to undo any uncommitted changes applied from the redo log to the datafiles. Undo records provide read consistency by maintaining the before image of the data for users who are accessing the data at the same time that another user is changing it. 在上面列举了 Undo 的几个作用。比如 rollback,recover,一致性读,Flashback 等。 1.15.2 Undo 表空间的两种管理方式 Oracle 的 Undo 有两种方式: 一是使用 undo 表空间,二是使用回滚段. 我们通过 undo_management 参数来控制使用哪种方式,如果设为 auto,就 使用 UNDO 表空间,这时必须要指定一个 UNDO 表空间。 如果设为 manual, 系统启动后使用 rollback segment 方式存储 undo 信息。 SQL> show parameter undo NAME TYPE VALUE Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 ------------------------------------ ----------- ------------------ undo_management string AUTO undo_retention integer 900 undo_tablespace string UNDOTBS1 如果系统没有指定 undo_management,那么系统默认以 manual 方式启动,即 使设置了 auto 方式的参数,这些参数将被忽略。 当实例启动的时候,系统自动选择第一个有效的 undo 表空间或者是 rollback segment,如果没有有效的可用的 undo 表空间或者是回滚段,系统使用 system rollback segment。这种情况是不被推荐的,当系统运行在没有 undo 的情况下, 系统会在 alert.log 中记录一条警告信息。 1.15.2.1 当使用 rollback segment 时 当 undo_management 被设置成 MENUAL 时使用系统回滚段, 即将 undo records 记录到 SYSTEM 表空间下的 SYSTEM 段。 SQL> col segment_name format a10 SQL> select segment_name,tablespace_name,bytes,next_extent from dba_segments where segment_type='ROLLBACK'; SEGMENT_NA TABLESPACE_NAME BYTES NEXT_EXTENT ---------- ------------------------------ ---------- ----------- SYSTEM SYSTEM 393216 1048576 通过上面的这条语句,我们查到了这个用于 rollback 的 system segment 存在 与 system 表空间。 默认情况下,只有一个 segment,并且它还比较小,所以, 如果使用 system 段来存储 undo records。肯定会影响数据库的性能。 所以 Oracle 是建议使用 Undo tablespace 来管理 undo records。 1.15.2.2 使用 Undo 表空间 当 undo_management 设置成 AUTO 时使用 UNDO tablespace 来管理回滚段。 这个时候,我们将有多个 undo segment,并且这些 segment 是存放在 UNDO 表 空间里的。 这样对 DB 的性能就会提高。 SQL> select segment_name,tablespace_name,bytes,next_extent from dba_segments where segment_type='TYPE2 UNDO'; SEGMENT_NAME TABLESPACE_NAME BYTES NEXT_EXTENT -------------------- -------------------- ---------- ----------- _SYSSMU1$ UNDOTBS1 1179648 65536 _SYSSMU2$ UNDOTBS1 1179648 65536 _SYSSMU3$ UNDOTBS1 2228224 65536 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 _SYSSMU4$ UNDOTBS1 1179648 65536 _SYSSMU5$ UNDOTBS1 262144 65536 _SYSSMU6$ UNDOTBS1 1179648 65536 _SYSSMU7$ UNDOTBS1 1179648 65536 _SYSSMU8$ UNDOTBS1 1179648 65536 _SYSSMU9$ UNDOTBS1 1179648 65536 _SYSSMU10$ UNDOTBS1 1179648 65536 通过以上 SQL 的查询结果,我们可以看出,有 10 个 undo segment 来存放 undo records。 以上我们是通过 dba_segment 表查看的结果。 也可以通过 v$rollstat 和 v$rollname 两个视图来查看信息。 这 2 个视图会显示所有 rollback 段的信息。 包括 system 段和 undo 段。 SQL> col name format a15 SQL> select s.usn,n.name,s.extents,s.hwmsize,s.status from v$rollstat s, v$rollname n where s.usn=n.usn; USN NAME EXTENTS HWMSIZE STATUS ---------- --------------- ---------- ---------- --------------- 0 SYSTEM 6 385024 ONLINE 1 _SYSSMU1$ 3 7659520 ONLINE 2 _SYSSMU2$ 3 9691136 ONLINE 3 _SYSSMU3$ 4 7462912 ONLINE 4 _SYSSMU4$ 3 76668928 ONLINE 5 _SYSSMU5$ 4 8511488 ONLINE 6 _SYSSMU6$ 3 7462912 ONLINE 7 _SYSSMU7$ 3 33480704 ONLINE 8 _SYSSMU8$ 3 8577024 ONLINE 9 _SYSSMU9$ 3 7462912 ONLINE 10 _SYSSMU10$ 3 13754368 ONLINE 11 rows selected. 1.15.3 undo_retention 和 retention guarantee 参数 我们可以使用 6.1 节的脚本来查看表空间的使用情况。 还可以使用如下 SQL 来查看 undo 表空间里空闲和非空闲比例: /* Formatted on 2010/6/23 9:49:53 (QP5 v5.115.810.9015) */ SELECT tablespace_name, status, SUM (bytes) / 1024 / 1024 "Bytes(M)" Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 FROM dba_undo_extents GROUP BY tablespace_name, status; TABLESPACE_NAME STATUS Bytes(M) -------------------- --------- ---------- UNDOTBS1 UNEXPIRED 9.1875 UNDOTBS1 EXPIRED 13.6875 我们看一下查询的结果,UNEXPIRED 和 EXPIRED 是已使用的 undo 表 空间,其中 expired 说明是已经过期的数据,也就是 15 分钟(默认情况)以外 的数据,以被覆盖,可以认为是空闲的。 在这里就关系到一个参数: UNDO_RETENTION,该参数用来指定 undo 记 录保存的最长时间,以秒为单位,是个动态参数,完全可以在实例运行时随时修 改,通常默认是 900 秒,也就是 15 分钟。 undo_retention 只是指定 undo 数据的过期时间,并不是说,undo 中的数据 一定会在 undo 表空间中保存 15 分钟,比如说刚一个新事务开始的时候,如果 undo 表空间已经被写满,则新事务的数据会自动覆盖已提交事务的数据,而不 管这些数据是否已过期,因此呢,这就又关联回了第一点,当你创建一个自动管 理的 undo 表空间时,还要注意其空间大小,要尽可能保证 undo 表空间有足够 的存储空间。 undo_retention 中指定的时间一过,已经提交事务中的数据就立刻无法访问, 它只是失效,只要不被别的事务覆盖,它会仍然存在,并可随时被 flashback 特 性引用。如果你的 undo 表空间足够大,而数据库又不是那么繁忙,那么其实 undo_retention 参数的值并不会影响到你,哪怕你设置成 1,只要没有事务去覆 盖 undo 数据,它就会持续有效。总之,要注意 undo 表空间的大小,保证其有 足够的存储空间。 只有在一种情况下,undo 表空间能够确保 undo 中的数据在 undo_retention 指定时间过期前一定有效,就是为 undo 表空间指定 Retention Guarantee,指定 之后,oracle 对于 undo 表空间中未过期的 undo 数据不会覆盖,例如: SQL> Alter tablespace undotbs1 retention guarantee; 禁止 undo 表空间 retention guarantee,例如: SQL> Alter tablespace undotbs1 retention noguarantee; UNDO 表空间是会被重用的,只有当事务没结束,或开了 retention guarantee, 或在 undo_retention 时间内不能被重用。 在 undo_retention 规定的时间内,数据都是有效的,过期后都会设为无效, 状态被改为 Expired,这些回滚段将会被看作 Free Space。但是只要数据没有被覆 盖就可以使用。如果空间已满,新事务的数据会自动覆盖掉已经提交的事务数据,Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 即使在 undo_retention 的时间内。除非指定 Retention Guarantee 模式,才能保证 在 undo_retention 内不被覆盖。 1.15.4 undo 表空间满时的处理方法 默认情况下的 Undo_retention 只有 15 分钟,这个默认值,一般都无法满足 系统的需求。 一般建议是改成 3 个小时, 这样给万一的情况,多争取一些时间。 SQL> alter system set undo_retention=10800; -- 3 个小时 系统已更改。 当然,undo_retention 设置的越大,所需要的 undo tablespace 也就越大。 这 个需要结合自己的系统来设置这个参数。 1.15.4.1 先模拟 UNDO 表空间满的情况 SQL> create undo tablespace undo datafile 'F:\backup\undo.dbf' size 1m ; 表空间已创建。 SQL> alter tablespace undo retention guarantee; 表空间已更改。 SQL> alter system set undo_tablespace=undo; 系统已更改。 SQL> create table DBA(id number); 表已创建。 SQL> begin 2 for i in 1 .. 100000 loop 3 insert into dba values(i); 4 commit; 5 end loop; 6 end; 7 / begin * 第 1 行出现错误: ORA-30036: 无法按 8 扩展段 (在还原表空间 'UNDO' 中) ORA-06512: 在 line 3 1.15.4.2 处理方法 处理方法有两种,一是添加 undo 表空间的数据文件,二是切换 UNDO tablespace. 这种情况下多用在 undo 表空间已经非常大的情况。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.15.4.2.1 增加数据文件 SQL> ALTER TABLESPACE undo ADD DATAFILE 'F:\backup\undo02.dbf' size 100M reuse; 表空间已更改。 SQL> begin 2 for i in 1..100000 loop 3 insert into dba values(1); 4 commit; 5 end loop; 6 end; 7 / PL/SQL 过程已成功完成。 1.15.4.2.2 切换 UNDO 表空间 1、建立新的表空间 UNDOTBS2 SQL> CREATE UNDO TABLESPACE UNDOTBS2 DATAFILE 'F:\backup\undo03.dbf' size 100M reuse; 表空间已创建。 2、切换到新建的 UNOD 表空间上来,操作如下 SQL> alter system set undo_tablespace=UNDOTBS2 scope=both; 系统已更改。 3、将原来的 UNDO 表空间,置为脱机: SQL> alter tablespace UNDO offline; 表空间已更改。 4、删除原来的 UNDO 表空间: SQL> drop tablespace UNDO including contents AND DATAFILES CASCADE CONSTRAINTS ; 表空间已删除。 如果只是 drop tablespace UNDO ,则只会在删除控制文件里的记录,并不会 物理删除文件。 Drop undo 表空间的时候必须是在未使用的情况下才能进行。如果 undo 表空 间正在使用(例如事务失败,但是还没有恢复成功),那么 drop 表空间命令将失 败。在 drop 表空间的时候可以使用 including contents。 1.15.5 undo 表空间损坏的处理方法 出现 undo 损坏的情况,大多数是因为异常宕机,在启动的时候报的错误。 DB 不能启动。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 比如:ORA-00600: internal error code, arguments: [4194], 当 alert log 里出现 ORA-600 + [4194] 时,基本就可以断定,是 undo 表空间 爱你出现了损坏。对于 Undo 损坏的情况,能用备份恢复最好,如果不能,就只 能通过一些特殊的方法来恢复。 1.15.5.1 方法一:使用 system segment 当我们使用 undo 表空间出现损坏时,可以先用 system segment 启动 DB, 启动之后,在重新创建 UNDO 表空间,在用 undo 来启动。 步骤如下: (1)用 spfile 创建 pfile,然后修改参数: #*.undo_tablespace='UNDOTBS1' #*.undo_management='AUTO' #*.undo_tablespace #*.undo_retention undo_management='MANUAL' rollback_segments='SYSTEM' (2)用修改之后的 pfile,重启 DB SQL> STARTUP MOUNT pfile='F:\initorcl.ora' ; (3)删除原来的表空间,创建新的 UNDO 表空间 SQL> drop tablespace undotbs; SQL> create undo tablespace undotbs1 datafile '/u01/oradata/undotbs1.dbf' size 10M; (4)关闭数据库,修改 pfile 参数,然后用新的 pfile 创建 spfile,在正常启动数 据库。 *.undo_tablespace='UNDOTBS1' *.undo_management='AUTO' #undo_management='MANUAL' #rollback_segments='SYSTEM' 1.15.5.2 方法二:跳过损坏的 segment 在方法一里面,我们使用了 system segment。 通过前面的说明,我们了解到, undo segment 有多个,我们可以通过 alert log 来查看正在使用的是哪些 segment, 这些段有可能损坏了。 我们只需要把这些损坏的 segment 跳过,先正常启动 DB, 在创建新的 UNDO 表空间,在切换一下。 (1)修改 pfile,添加参数: *._corrupted_rollback_segments='_SYSSMU11$','_SYSSMU12$','_SYSSMU13$' Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 这些字段的值,我们通过 alert log 查看。 也可以通过如下命令查看: #strings system01.dbf | grep _SYSSMU | cut -d $ -f 1 | sort -u (2)用修改之后的 pfile 启动 DB 因为跳过了哪些损坏的 segment,所以 DB 可以正常启动。 (3)创建新的 UNDO 表空间,并切换过来 SQL> create undo tablespace undotbs1 datafile '/u01/oradata/undotbs1.dbf' size 10M; SQL> alter system set undo_tablespace=undotbs1; SQL> drop tablespace undotbs; (4)修改 pfile,创建 spfile,并正常启动 删除: *._corrupted_rollback_segments='_SYSSMU11$','_SYSSMU12$','_SYSSMU13$' 1.16 Oracle 表空间 创建参数 说明 官网的几个链接: Logical Storage Structures http://download.oracle.com/docs/cd/E11882_01/server.112/e16508/logical.htm#CNC PT402 CREATE TABLESPACE http://download.oracle.com/docs/cd/E11882_01/server.112/e17118/statements_7003.h tm#SQLRF01403 先看一个表空间的创建 SQL: CREATE TABLESPACE SYSAUX DATAFILE '/u01/app/oracle/oradata/orcl/sysaux01.dbf' SIZE 250M AUTOEXTEND ON NEXT 10M MAXSIZE UNLIMITED LOGGING ONLINE PERMANENT EXTENT MANAGEMENT LOCAL AUTOALLOCATE BLOCKSIZE 8K SEGMENT SPACE MANAGEMENT AUTO FLASHBACK ON; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 结合这个例子,对几个参数做下说明: 1.16.1 logging_clause Specify the default logging attributes of all tables, indexes, materialized views, materialized view logs, and partitions within the tablespace. LOGGING is the default. This clause is not valid for a temporary or undo tablespace. The tablespace-level logging attribute can be overridden by logging specifications at the table, index, materialized view, materialized view log, and partition levels. --指定 表,视图,索引等的 loging 属性。 该属性不行应用与 undo 和 temporary 表空间。 在表空间级别设置的 logging 属性可以被表等对象自身的属 性覆盖。 1.16.2 permanent_tablespace_clause Use the following clauses to create a permanent tablespace. (Some of these clauses are also used to create a temporary or undo tablespace.) tablespace Specify the name of the tablespace to be created. Note on the SYSAUX Tablespace SYSAUX is a required auxiliary system tablespace. You must use the CREATE TABLESPACE statement to create the SYSAUX tablespace if you are upgrading from a release prior to Oracle Database 11g. You must have the SYSDBA system privilege to specify this clause, and you must have opened the database in MIGRATE mode. You must specify EXTENT MANAGEMENT LOCAL and SEGMENT SPACE MANAGEMENT AUTO for the SYSAUX tablespace. The DATAFILE clause is optional only if you have enabled Oracle Managed Files. See "DATAFILE | TEMPFILE Clause" for the behavior of the DATAFILE clause. Take care to allocate sufficient space for the SYSAUX tablespace. For guidelines on creating this tablespace, refer to Oracle Database Upgrade Guide. Restrictions on the SYSAUX Tablespace You cannot specify OFFLINE or TEMPORARY for the SYSAUX tablespace. --该选项主要用于指定指定表空间的类型,permanent 表示永久的,如果是 其他类型,则写 temporary 或者 undo。 如果是创建 SYSAUX 表空间,则必须 指定 extent managent 类型和 segment space management 类型。 1.16.3 extent_management_clause The extent_management_clause lets you specify how the extents of the tablespace will be managed. Note: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 After you have specified extent management with this clause, you can change extent management only by migrating the tablespace. (1). AUTOALLOCATE specifies that the tablespace is system managed. Users cannot specify an extent size. You cannot specify AUTOALLOCATE for a temporary tablespace. (2). UNIFORM specifies that the tablespace is managed with uniform extents of SIZE bytes.The default SIZE is 1 megabyte. All extents of temporary tablespaces are of uniform size, so this keyword is optional for a temporary tablespace. However, you must specify UNIFORM in order to specify SIZE. You cannot specify UNIFORM for an undo tablespace. If you do not specify AUTOALLOCATE or UNIFORM, then the default is UNIFORM for temporary tablespaces and AUTOALLOCATE for all other types of tablespaces. If you do not specify the extent_management_clause, then Oracle Database interprets the MINIMUM EXTENT clause and the DEFAULT storage_clause to determine extent management. Note: The DICTIONARY keyword is deprecated. It is still supported for backward compatibility. However, Oracle recommends that you create locally managed tablespaces. Locally managed tablespaces are much more efficiently managed than dictionary-managed tablespaces. The creation of new dictionary-managed tablespaces is scheduled for desupport. 根据表空间中区的管理方式不周,表空间可以分为数据字典管理(Dictionary managed)与本地化管理(Local Managed)类型。 在数据字典管理表空间中,区大小由参数: initial, next, minextents, maxextents, pctincrease 决定。 在本地化管理中,区大小设置方式分为 uniform 及 autoallocate 两种类型。 Uniform:区的大小相同。如果设置了 uniform 则 pctincrease 自动为 0。 Autoallocate:区大小 oracle 自动分配。 Oracle9i 之前的,通常是数据字典管理。Oracle9i 及以后,通常使用本地化 管理表空间。 1.16.4 BLOCKSIZE Clause Use the BLOCKSIZE clause to specify a nonstandard block size for the tablespace. In order to specify this clause, the DB_CACHE_SIZE and at least one DB_nK_CACHE_SIZE parameter must be set, and the integer you specify in this Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 clause must correspond with the setting of one DB_nK_CACHE_SIZE parameter setting. Restriction on BLOCKSIZE You cannot specify nonstandard block sizes for a temporary tablespace or if you intend to assign this tablespace as the temporary tablespace for any users. 1.16.5 segment_management_clause The segment_management_clause is relevant only for permanent, locally managed tablespaces. It lets you specify whether Oracle Database should track the used and free space in the segments in the tablespace using free lists or bitmaps. This clause is not valid for a temporary tablespace. (1)AUTO Specify AUTO if you want the database to manage the free space of segments in the tablespace using a bitmap. If you specify AUTO, then the database ignores any specification for PCTUSED, FREELIST, and FREELIST GROUPS in subsequent storage specifications for objects in this tablespace. This setting is called automatic segment-space management and is the default. (2)MANUAL Specify MANUAL if you want the database to manage the free space of segments in the tablespace using free lists. Oracle strongly recommends that you do not use this setting and that you create tablespaces with automatic segment-space management. To determine the segment management of an existing tablespace, query the SEGMENT_SPACE_MANAGEMENT column of the DBA_TABLESPACES or USER_TABLESPACES data dictionary view. Notes: If you specify AUTO segment management, then: (1). If you set extent management to LOCAL UNIFORM, then you must ensure that each extent contains at least 5 database blocks. (2). If you set extent management to LOCAL AUTOALLOCATE, and if the database block size is 16K or greater, then Oracle manages segment space by creating extents with a minimum size of 5 blocks rounded up to 64K. Restrictions on Automatic Segment-Space Management This clause is subject to the following restrictions: (1). You can specify this clause only for a permanent, locally managed tablespace. (2). You cannot specify this clause for the SYSTEM tablespace. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.16.6 flashback_mode_clause Use this clause in conjunction with the ALTER DATABASE FLASHBACK clause to specify whether the tablespace can participate in FLASHBACK DATABASE operations. This clause is useful if you have the database in FLASHBACK mode but you do not want Oracle Database to maintain Flashback log data for this tablespace. This clause is not valid for temporary or undo tablespaces. (1)FLASHBACK ON Specify FLASHBACK ON to put the tablespace in FLASHBACK mode. Oracle Database will save Flashback log data for this tablespace and the tablespace can participate in a FLASHBACK DATABASE operation. If you omit the flashback_mode_clause, then FLASHBACK ON is the default. (2)FLASHBACK OFF Specify FLASHBACK OFF to take the tablespace out of FLASHBACK mode. Oracle Database will not save any Flashback log data for this tablespace. You must take the data files in this tablespace offline or drop them prior to any subsequent FLASHBACK DATABASE operation. Alternatively, you can take the entire tablespace offline. In either case, the database does not drop existing Flashback logs. Note: The FLASHBACK mode of a tablespace is independent of the FLASHBACK mode of an individual table. 1.17 Oracle Table 创建参数 说明 先看一个 oracle 10g 下 table 创建 SQL,完全是默认是值: CREATE TABLE SYS.QS ( USERNAME VARCHAR2(30 BYTE) NOT NULL, USER_ID NUMBER NOT NULL, CREATED DATE NOT NULL ) TABLESPACE SYSTEM PCTUSED 40 PCTFREE 10 INITRANS 1 MAXTRANS 255 STORAGE ( INITIAL 64K MINEXTENTS 1 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 MAXEXTENTS UNLIMITED PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT ) LOGGING NOCOMPRESS NOCACHE NOPARALLEL MONITORING; 对于 数据字典管理(Dictionary managed)和 本地化管理(Local Managed) 的表空间,他们的参数是不同的, 在 Local Managed 模式下,的 autoallocate 和 uniform 类型不同,参数也会不同。 这里使用的是 local managed autoallocate 类 型的表空间。 官网链接: storage_clause http://download.oracle.com/docs/cd/E11882_01/server.112/e17118/clauses009.htm#S QLRF30013 CREATE TABLE http://download.oracle.com/docs/cd/E11882_01/server.112/e17118/statements_7002.h tm#SQLRF01402 1.17.1 Storage 参数说明 1.17.1.1. INITIAL Specify the size of the first extent of the object. Oracle allocates space for this extent when you create the schema object. Refer to size_clause for information on that clause. In locally managed tablespaces, Oracle uses the value of INITIAL, in conjunction with the type of local management—AUTOALLOCATE or UNIFORM—and the values of MINEXTENTS, NEXT and PCTINCREASE, to determine the initial size of the segment. (1). With AUTOALLOCATE extent management, Oracle uses the INITIAL setting to optimize the number of extents allocated. Extents of 64K, 1M, 8M, and 64M can be allocated. During segment creation, the system chooses the greatest of these four sizes that is equal to or smaller than INITIAL, and allocates as many extents of that size as are needed to reach or exceed the INITIAL setting. For Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 example, if you set INITIAL to 4M, then the database creates four 1M extents. But if you set INITIAL to 14M, then the database creates two 8M extents, which exceeds the INITIAL setting, rather than creating the less optimal one 8M extent plus six 1M extents. (2). For UNIFORM extent management, the number of extents is determined from initial segment size and the uniform extent size specified at tablespace creation time. For example, in a uniform locally managed tablespace with 1M extents, if you specify an INITIAL value of 5M, then Oracle creates five 1M extents. Consider this comparison: With AUTOALLOCATE, if you set INITAL to 72K, then the initial segment size will be 128K (greater than INITIAL). The database cannot allocate an extent smaller than 64K, so it must allocate two 64K extents. If you set INITIAL to 72K with a UNIFORM extent size of 24K, then the database will allocate three 24K extents to equal 72K. In dictionary managed tablespaces, the default initial extent size is 5 blocks, and all subsequent extents are rounded to 5 blocks. If MINIMUM EXTENT was specified at tablespace creation time, then the extent sizes are rounded to the value of MINIMUM EXTENT. -- 自 Oracle 9i 以后,推荐使用本地管理的表空间,不建议使用字典管理的 表空间。 Restriction on INITIAL You cannot specify INITIAL in an ALTER statement. 1.17.1.2. MINEXTENTS (1)In locally managed tablespaces, Oracle Database uses the value of MINEXTENTS in conjunction with PCTINCREASE, INITIAL and NEXT to determine the initial segment size. (2)In dictionary-managed tablespaces, specify the total number of extents to allocate when the object is created. The default and minimum value is 1, meaning that Oracle allocates only the initial extent, except for rollback segments, for which the default and minimum value is 2. The maximum value depends on your operating system. (1). In a locally managed tablespace, MINEXTENTS is used to compute the initial amount of space allocated, which is equal to INITIAL * MINEXTENTS. Thereafter this value is set to 1, which is reflected in the DBA_SEGMENTS view. (2). In a dictionary-managed tablespace, MINEXTENTS is simply the minimum number of extents that must be allocated to the segment. If the MINEXTENTS value is greater than 1, then Oracle calculates the size of subsequent extents based on the values of the INITIAL, NEXT, and PCTINCREASE Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 storage parameters. When changing the value of MINEXTENTS by specifying it in an ALTER statement, you can reduce the value from its current value, but you cannot increase it. Resetting MINEXTENTS to a smaller value might be useful, for example, before a TRUNCATE ... DROP STORAGE statement, if you want to ensure that the segment will maintain a minimum number of extents after the TRUNCATE operation. Restrictions on MINEXTENTS The MINEXTENTS storage parameter is subject to the following restrictions: (1). MINEXTENTS is not applicable at the tablespace level. (2). You cannot change the value of MINEXTENTS in an ALTER statement or for an object that resides in a locally managed tablespace. 1.17.1.3. MAXEXTENTS This storage parameter is valid only for objects in dictionary-managed tablespaces. Specify the total number of extents, including the first, that Oracle can allocate for the object. The minimum value is 1 except for rollback segments, which always have a minimum of 2. The default value depends on your data block size. Restriction on MAXEXTENTS MAXEXTENTS is ignored for objects residing in a locally managed tablespace, unless the value of ALLOCATION_TYPE is USER for the tablespace in the DBA_TABLESPACES data dictionary view. --该参数在 local managed tablespace 是忽略的。 UNLIMITED Specify UNLIMITED if you want extents to be allocated automatically as needed. Oracle recommends this setting as a way to minimize fragmentation. Do not use this clause for rollback segments. Doing so allows the possibility that long-running rogue DML transactions will continue to create new extents until a disk is full. Caution: A rollback segment that you create without specifying the storage_clause has the same storage parameters as the tablespace in which the rollback segment is created. Thus, if you create a tablespace with MAXEXTENTS UNLIMITED, then the rollback segment will have this same default. 1.17.1.4. PCTINCREASE (1)In locally managed tablespaces, Oracle Database uses the value of Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 PCTINCREASE during segment creation to determine the initial segment size and ignores this parameter during subsequent space allocation. (2)In dictionary-managed tablespaces, specify the percent by which the third and subsequent extents grow over the preceding extent. The default value is 50, meaning that each subsequent extent is 50% larger than the preceding extent. The minimum value is 0, meaning all extents after the first are the same size. The maximum value depends on your operating system. Oracle rounds the calculated size of each new extent to the nearest multiple of the data block size. If you change the value of the PCTINCREASE parameter by specifying it in an ALTER statement, then Oracle calculates the size of the next extent using this new value and the size of the most recently allocated extent. Restriction on PCTINCREASE You cannot specify PCTINCREASE for rollback segments. Rollback segments always have a PCTINCREASE value of 0. 1.17.1.5. FREELISTS (1)In tablespaces with manual segment-space management, Oracle Database uses the FREELISTS storage parameter to improve performance of space management in OLTP systems by increasing the number of insert points in the segment. (2)In tablespaces with automatic segment-space management, this parameter is ignored, because the database adapts to varying workload. In tablespaces with manual segment-space management, for objects other than tablespaces and rollback segments, specify the number of free lists for each of the free list groups for the table, partition, cluster, or index. The default and minimum value for this parameter is 1, meaning that each free list group contains one free list. The maximum value of this parameter depends on the data block size. If you specify a FREELISTS value that is too large, then Oracle returns an error indicating the maximum value. This clause is not valid or useful if you have specified the SECUREFILE parameter of LOB_parameters. If you specify both the SECUREFILE parameter and FREELISTS, then the database silently ignores the FREELISTS specification. Restriction on FREELISTS You can specify FREELISTS in the storage_clause of any statement except when creating or altering a tablespace or rollback segment. 1.17.1.6. FREELIST GROUPS (1)In tablespaces with manual segment-space management, Oracle Database uses the value of this storage parameter to statically partition the segment free space Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 in an Oracle Real Application Clusters environment. This partitioning improves the performance of space allocation and deallocation by avoiding inter instance transfer of segment metadata. In tablespaces with automatic segment-space management, this parameter is ignored, because Oracle dynamically adapts to inter instance workload. (2)In tablespaces with manual segment-space management, specify the number of groups of free lists for the database object you are creating. The default and minimum value for this parameter is 1. Oracle uses the instance number of Oracle Real Application Clusters (Oracle RAC) instances to map each instance to one free list group. Each free list group uses one database block. Therefore: (1). If you do not specify a large enough value for INITIAL to cover the minimum value plus one data block for each free list group, then Oracle increases the value of INITIAL the necessary amount. (2). If you are creating an object in a uniform locally managed tablespace, and the extent size is not large enough to accommodate the number of freelist groups, then the create operation will fail. This clause is not valid or useful if you have specified the SECUREFILE parameter of LOB_parameters. If you specify both the SECUREFILE parameter and FREELIST GROUPS, then the database silently ignores the FREELIST GROUPS specification. Restriction on FREELIST GROUPS You can specify the FREELIST GROUPS parameter only in CREATE TABLE, CREATE CLUSTER, CREATE MATERIALIZED VIEW, CREATE MATERIALIZED VIEW LOG, and CREATE INDEX statements. 1.17.1.7. BUFFER_POOL The BUFFER_POOL clause lets you specify a default buffer pool or cache for a schema object. All blocks for the object are stored in the specified cache. (1). If you define a buffer pool for a partitioned table or index, then the partitions inherit the buffer pool from the table or index definition unless overridden by a partition-level definition. (2). For an index-organized table, you can specify a buffer pool separately for the index segment and the overflow segment. Restrictions on the BUFFER_POOL Parameter BUFFER_POOL is subject to the following restrictions: (1). You cannot specify this clause for a cluster table. However, you can specify it for a cluster. (2). You cannot specify this clause for a tablespace or a rollback segment. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.17.1.7.1 KEEP Specify KEEP to put blocks from the segment into the KEEP buffer pool. Maintaining an appropriately sized KEEP buffer pool lets Oracle retain the schema object in memory to avoid I/O operations. KEEP takes precedence over any NOCACHE clause you specify for a table, cluster, materialized view, or materialized view log. 1.17.1.7.2 RECYCLE Specify RECYCLE to put blocks from the segment into the RECYCLE pool. An appropriately sized RECYCLE pool reduces the number of objects whose default pool is the RECYCLE pool from taking up unnecessary cache space. 1.17.1.7.3 DEFAULT Specify DEFAULT to indicate the default buffer pool. This is the default for objects not assigned to KEEP or RECYCLE. 1.17.2 其他参数说明 1. Pctfree: 默认值是 10,如果数据块的使用率高于 pctfree 的值,则该数据块 从 freelist 中移出。 2. Pctused :默认值是 40,如果数据块的使用率小于 pctused 的值,则该数据块 重新加入到 fresslist 中。Pctfree, Pctused 是互相消涨的, 其和不能超过 100 3. Initrans : 默认值 1,该参数表示在单一块中最初活动的交易事务数。 4. Maxtrans :默认值是 255,表示在单一块中最大交易事务数。 5. logging_clause Specify whether the creation of the table and of any indexes required because of constraints, partition, or LOB storage characteristics will be logged in the redo log file (LOGGING) or not (NOLOGGING).The logging attribute of the table is independent of that of its indexes. This attribute also specifies whether subsequent direct loader (SQL*Loader) and direct-path INSERT operations against the table, partition, or LOB storage are logged (LOGGING) or not logged (NOLOGGING). 6. table_compression The table_compression clause is valid only for heap-organized tables. Use this clause to instruct the database whether to compress data segments to reduce disk use. The COMPRESS keyword enables table compression. The NOCOMPRESS keyword disables table compression. NOCOMPRESS is the default. (1)When you enable table compression by specifying either COMPRESS or Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 COMPRESS BASIC, you enable basic table compression. Oracle Database attempts to compress data during direct-path INSERT operations when it is productive to do so. The original import utility (imp) does not support direct-path INSERT, and therefore cannot import data in a compressed format. Tables with COMPRESS or COMPRESS BASIC use a PCTFREE value of 0 to maximize compression, unless you explicitly set a value for PCTFREE in the physical_attributes_clause. In earlier releases, this type of compression was called DSS table compression and was enabled using COMPRESS FOR DIRECT_LOAD OPERATIONS. This syntax has been deprecated. (2)When you enable table compression by specifying COMPRESS FOR OLTP, you enable OLTP table compression. Oracle Database compresses data during all DML operations on the table. This form of compression is recommended for OLTP environments. Tables with COMPRESS FOR OLTP or NOCOMPRESS use the PCTFREE default value of 10, to maximize compress while still allowing for some future DML changes to the data, unless you override this default explicitly. In earlier releases, OLTP table compression was enabled using COMPRESS FOR ALL OPERATIONS. This syntax has been deprecated. (3)When you specify COMPRESS FOR QUERY or COMPRESS FOR ARCHIVE, you enable hybrid columnar compression. With hybrid columnar compression, data can be compressed during bulk load operations. During the load process, data is transformed into a column-oriented format and then compressed. Oracle Database uses a compression algorithm appropriate for the level you specify. In general, the higher the level, the greater the compression ratio. Hybrid columnar compression can result in higher compression ratios, at a greater CPU cost. Therefore, this form of compression is recommended for data that is not frequently updated. COMPRESS FOR QUERY is useful in data warehousing environments. Valid values are LOW and HIGH, with HIGH providing a higher compression ratio. The default is HIGH. COMPRESS FOR ARCHIVE uses higher compression ratios than COMPRESS FOR QUERY, and is useful for compressing data that will be stored for long periods of time. Valid values are LOW and HIGH, with HIGH providing the highest possible compression ratio. The default is LOW. Tables with COMPRESS FOR QUERY or COMPRESS FOR ARCHIVE use a PCTFREE value of 0 to maximize compression, unless you explicitly set a value for PCTFREE in the physical_attributes_clause. For these tables, PCTFREE has no effect for blocks loaded using direct-path INSERT. PCTFREE is honored for blocks loaded using conventional INSERT, and for blocks created as a result of DML operations on blocks originally loaded using direct-path INSERT. 7. CACHE | NOCACHE | CACHE READS Use the CACHE clauses to indicate how Oracle Database should store blocks in the buffer cache. If you specify neither CACHE nor NOCACHE, then: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 (1). In a CREATE TABLE statement, NOCACHE is the default. (2). In an ALTER TABLE statement, the existing value is not changed. CACHE For data that is accessed frequently, this clause indicates that the blocks retrieved for this table are placed at the most recently used end of the least recently used (LRU) list in the buffer cache when a full table scan is performed. This attribute is useful for small lookup tables. As a parameter in the LOB_storage_clause, CACHE specifies that the database places LOB data values in the buffer cache for faster access. The database evaluates this parameter in conjunction with the logging_clause. If you omit this clause, then the default value for both BasicFile and SecureFile LOBs is NOCACHE LOGGING. Restriction on CACHE You cannot specify CACHE for an index-organized table. However, index-organized tables implicitly provide CACHE behavior. NOCACHE For data that is not accessed frequently, this clause indicates that the blocks retrieved for this table are placed at the least recently used end of the LRU list in the buffer cache when a full table scan is performed. NOCACHE is the default for LOB storage. As a parameter in the LOB_storage_clause, NOCACHE specifies that the LOB values are not brought into the buffer cache. NOCACHE is the default for LOB storage. Restriction on NOCACHE You cannot specify NOCACHE for an index-organized table. CACHE READS CACHE READS applies only to LOB storage. It specifies that LOB values are brought into the buffer cache only during read operations but not during write operations. 8. parallel_clause The parallel_clause lets you parallelize creation of the table and set the default degree of parallelism for queries and the DML INSERT, UPDATE, DELETE, and MERGE after table creation. Note: The syntax of the parallel_clause supersedes syntax appearing in earlier releases of Oracle. Superseded syntax is still supported for backward compatibility but may Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 result in slightly different behavior from that documented. NOPARALLEL Specify NOPARALLEL for serial execution. This is the default. PARALLEL Specify PARALLEL if you want Oracle to select a degree of parallelism equal to the number of CPUs available on all participating instances times the value of the PARALLEL_THREADS_PER_CPU initialization parameter. PARALLEL integer Specification of integer indicates the degree of parallelism, which is the number of parallel threads used in the parallel operation. Each parallel thread may use one or two parallel execution servers. Normally Oracle calculates the optimum degree of parallelism, so it is not necessary for you to specify integer. 可通过数据字典表 DBA_TABLES、ALL_TABLES、USER_TABLES 查看参 数设置情况,如: Select table_name,initial_extent,next_extent,min_extents,max_extents,pct_increase from user_tables; 1.18 数据块 Block 说明 在官网看到了这段信息,讲的很细。 贴过来。 Logical Storage Structures http://download.oracle.com/docs/cd/E11882_01/server.112/e16508/logica l.htm#CNCPT7668 Oracle Database manages the logical storage space in the data files of a database in units called data blocks, also called Oracle blocks or pages. A data block is the minimum unit of database I/O. 1.18.1 Data Blocks and Operating System Blocks At the physical level, database data is stored in disk files made up of operating system blocks. An operating system block is the minimum unit of data that the operating system can read or write. In contrast, an Oracle block is a logical storage structure whose size and structure are not known to the operating system. Figure shows that operating system blocks may differ in size from data blocks. The database requests data in multiples of data blocks, not operating system blocks. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 When the database requests a data block, the operating system translates this operation into a requests for data in permanent storage. The logical separation of data blocks from operating system blocks has the following implications: (1)Applications do not need to determine the physical addresses of data on disk. (2)Database data can be striped or mirrored on multiple physical disks. 1.18.2 Database Block Size Every database has a database block size. The DB_BLOCK_SIZE initialization parameter sets the data block size for a database when it is created. The size is set for the SYSTEM and SYSAUX tablespaces and is the default for all other tablespaces. The database block size cannot be changed except by re-creating the database. If DB_BLOCK_SIZE is not set, then the default data block size is operating system-specific. The standard data block size for a database is 4 KB or 8 KB. If the size differs for data blocks and operating system blocks, then the data block size must be a multiple of the operating system block size. 1.18.3 Tablespace Block Size You can create individual tablespaces whose block size differs from the DB_BLOCK_SIZE setting. A nonstandard block size can be useful when moving a transportable tablespace to a different platform. 1.18.4 Data Block Format Every data block has a format or internal structure that enables the database to track the data and free space in the block. This format is similar whether the data block contains table, index, or table cluster data. Figure shows the format of an uncompressed data block. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.18.5 Data Block Overhead Oracle Database uses the block overhead to manage the block itself. The block overhead is not available to store user data. The block overhead includes the following parts: 1.18.5.1 Block header This part contains general information about the block, including disk address and segment type. For blocks that are transaction-managed, the block header contains active and historical transaction information. A transaction entry is required for every transaction that updates the block. Oracle Database initially reserves space in the block header for transaction entries. In data blocks allocated to segments that support transactional changes, free space can also hold transaction entries when the header space is depleted. The space required for transaction entries is operating system dependent. However, transaction entries in most operating systems require approximately 23 bytes. 1.18.5.2 Table directory For a heap-organized table, this directory contains metadata about tables whose rows are stored in this block. Multiple tables can store rows in the same block. -- metadata,元数据,指表的定义语句。 heap-organized table: A table in which the data rows are stored in no particular order on disk. By default, CREATE TABLE creates a heap-organized table. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.18.5.3 Row directory For a heap-organized table, this directory describes the location of rows in the data portion of the block. After space has been allocated in the row directory, the database does not reclaim this space after row deletion. Thus, a block that is currently empty but formerly had up to 50 rows continues to have 100 bytes allocated for the row directory. The database reuses this space only when new rows are inserted in the block. Some parts of the block overhead are fixed in size, but the total size is variable. On average, the block overhead totals 84 to 107 bytes. 1.18.6 Row Format The row data part of the block contains the actual data, such as table rows or index key entries. Just as every data block has an internal format, every row has a row format that enables the database to track the data in the row. Oracle Database stores rows as variable-length records. A row is contained in one or more row pieces. Each row piece has a row header and column data. Figure shows the format of a row. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.18.6.1 Row Header Oracle Database uses the row header to manage the row piece stored in the block. The row header contains information such as the following: (1)Columns in the row piece (2)Pieces of the row located in other data blocks If an entire row can be inserted into a single data block, then Oracle Database stores the row as one row piece. However, if all of the row data cannot be inserted into a single block or an update causes an existing row to outgrow its block, then the database stores the row in multiple row pieces (see "Chained and Migrated Rows"). A data block usually contains only one row piece per row. (3)Cluster keys for table clusters (see "Overview of Table Clusters") A row fully contained in one block has at least 3 bytes of row header. 1.18.6.2 Column Data After the row header, the column data section stores the actual data in the row. The row piece usually stores columns in the order listed in the CREATE TABLE statement, but this order is not guaranteed. For example, columns of type LONG are created last. For each column in a row piece, Oracle Database stores the column length and data separately. The space required depends on the data type. If the data type of a column is variable length, then the space required to hold a value can grow and shrink with updates to the data. Each row has a slot in the row directory of the data block header. The slot points to the beginning of the row. See Also: "Table Storage" and "Index Storage" 1.18.7 Rowid Format Oracle Database uses a rowid to uniquely identify a row. Internally, the rowid is a structure that holds information that the database needs to access a row. A rowid is not physically stored in the database, but is inferred from the file and block on which the data is stored. An extended rowid includes a data object number. This rowid type uses a base 64 encoding of the physical address for each row. The encoding characters are A-Z, a-z, 0-9, +, and /. Example 12-1 queries the ROWID pseudocolumn to show the extended rowid of the row in the employees table for employee 100. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Example 12-1 ROWID Pseudocolumn SQL> SELECT ROWID FROM employees WHERE employee_id = 100; ROWID ------------------ AAAPecAAFAAAABSAAA the following Figure illustrates the format of an extended rowid. An extended rowid is displayed in a four-piece format, OOOOOOFFFBBBBBBRRR, with the format divided into the following components: 1.18.7.1 OOOOOO The data object number identifies the segment (data object AAAPec in Example 12-1). A data object number is assigned to every database segment. Schema objects in the same segment, such as a table cluster, have the same data object number. -- 数据对象编号:每个数据对象(如表或索引)在创建时都分配有此编号, 并且此编号在数据库中是唯一的. 1.18.7.2 FFF The tablespace-relative data file number identifies the data file that contains the row (file AAF in Example 12-1). 相关文件编号:此编号对于表空间中的每个文件是唯一的 1.18.7.3 BBBBBB The data block number identifies the block that contains the row (block AAAABS in Example 12-1). Block numbers are relative to their data file, not their tablespace. Thus, two rows with identical block numbers could reside in different data files of the same tablespace. 块编号:表示包含此行的块在文件中的位置 1.18.7.4 RRR The row number identifies the row in the block (row AAA in Example 12-1). 行编号:标识块头中行目录位置的位置 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 After a rowid is assigned to a row piece, the rowid can change in special circumstances. For example, if row movement is enabled, then the rowid can change because of partition key updates, Flashback Table operations, shrink table operations, and so on. If row movement is disabled, then a rowid can change if the row is exported and imported using Oracle Database utilities. Note: Internally, the database performs row movement as if the row were physically deleted and reinserted. However, row movement is considered an update, which has implications for triggers. 1.18.8 Data Block Compression The database can use table compression to eliminate duplicate values in a data block (see "Table Compression"). This section describes the format of data blocks that use compression. The format of a data block that uses basic and OLTP table compression is essentially the same as an uncompressed block. The difference is that a symbol table at the beginning of the block stores duplicate values for the rows and columns. The database replaces occurrences of these values with a short reference to the symbol table. Assume that the rows in Example 12-2 are stored in a data block for the seven-column sales table. Example 12-2 Rows in sales Table 2190,13770,25-NOV-00,S,9999,23,161 2225,15720,28-NOV-00,S,9999,25,1450 34005,120760,29-NOV-00,P,9999,44,2376 9425,4750,29-NOV-00,I,9999,11,979 1675,46750,29-NOV-00,S,9999,19,1121 When basic or OLTP table compression is applied to this table, the database replaces duplicate values with a symbol reference. Example 12-3 is a conceptual representation of the compression in which the symbol * replaces 29-NOV-00 and % replaces 9999. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Example 12-3 OLTP Compressed Rows in sales Table 2190,13770,25-NOV-00,S,%,23,161 2225,15720,28-NOV-00,S,%,25,1450 34005,120760,*,P,%,44,2376 9425,4750,*,I,%,11,979 1675,46750,*,S,%,19,1121 Table 12-1 conceptually represents the symbol table that maps symbols to values. Table 12-1 Symbol Table Symbol Value Column Rows * 29-NOV-00 3 958-960 % 9999 5 956-960 1.18.9 Space Management in Data Blocks As the database fills a data block from the bottom up, the amount of free space between the row data and the block header decreases. This free space can also shrink during updates, as when changing a trailing null to a nonnull value. The database manages free space in the data block to optimize performance and avoid wasted space. Note: This section assumes the use of automatic segment space management. 1.18.9.1 Percentage of Free Space in Data Blocks The PCTFREE storage parameter is essential to how the database manages free space. This SQL parameter sets the minimum percentage of a data reserved as free space for updates to existing rows. Thus, PCTFREE is important for preventing row migration and avoiding wasted space. For example, assume that you create a table that will require only occasional updates, most of which will not increase the size of the existing data. You specify the PCTFREE parameter within a CREATE TABLE statement as follows: CREATE TABLE test_table (n NUMBER) PCTFREE 20; Figure 12-9 shows how a PCTFREE setting of 20 affects space management. The database adds rows to the block over time, causing the row data to grow upwards toward the block header, which is itself expanding downward toward the row data. The PCTFREE setting ensures that at least 20% of the data block is free. For example, the database prevents an INSERT statement from filling the block so that the Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 row data and header occupy a combined 90% of the total block space, leaving only 10% free. Figure 12-9 PCTFREE Note: This discussion does not apply to LOB data types, which do not use the PCTFREE storage parameter or free lists. See "Overview of LOBs". 1.18.9.2 Optimization of Free Space in Data Blocks While the percentage of free space cannot be less than PCTFREE, the amount of free space can be greater. For example, a PCTFREE setting of 20% prevents the total amount of free space from dropping to 5% of the block, but permits 50% of the block to be free space. The following SQL statements can increase free space: (1)DELETE statements (2)UPDATE statements that either update existing values to smaller values or increase existing values and force a row to migrate (3)INSERT statements on a table that uses OLTP compression If inserts fill a block with data, then the database invokes block compression, which may result in the block having more free space. The space released is available for INSERT statements under the following conditions: (1)If the INSERT statement is in the same transaction and after the statement Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 that frees space, then the statement can use the space. (2)If the INSERT statement is in a separate transaction from the statement that frees space (perhaps run by another user), then the statement can use the space made available only after the other transaction commits and only if the space is needed. 1.18.9.3 Coalescing Fragmented Space Released space may or may not be contiguous with the main area of free space in a data block, as shown in Figure 12-10. Noncontiguous free space is called fragmented space. Figure 12-10 Data Block with Fragmented Space Oracle Database automatically and transparently coalesces the free space of a data block only when the following conditions are true: (1)An INSERT or UPDATE statement attempts to use a block that contains sufficient free space to contain a new row piece. (2)The free space is fragmented so that the row piece cannot be inserted in a contiguous section of the block. After coalescing, the amount of free space is identical to the amount before the operation, but the space is now contiguous. Figure 12-11 shows a data block after space has been coalesced. Figure 12-11 Data Block After Coalescing Free Space Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Oracle Database performs coalescing only in the preceding situations because otherwise performance would decrease because of the continuous coalescing of the free space in data blocks. 1.18.9.4 Reuse of Index Space The database can reuse space within an index block. For example, if you insert a value into a column and delete it, and if an index exists on this column, then the database can reuse the index slot when a row requires it. The database can reuse an index block itself. Unlike a table block, an index block only becomes free when it is empty. The database places the empty block on the free list of the index structure and makes it eligible for reuse. However, Oracle Database does not automatically compact the index: an ALTER INDEX REBUILD or COALESCE statement is required. Figure 12-12 represents an index of the employees.department_id column before the index is coalesced. The first three leaf blocks are only partially full, as indicated by the gray fill lines. Figure 12-12 Index Before Coalescing Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Figure 12-13 shows the index in Figure 12-12 after the index has been coalesced. The first two leaf blocks are now full, as indicated by the gray fill lines, and the third leaf block has been freed. Figure 12-13 Index After Coalescing Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.18.9.5 Chained and Migrated Rows Oracle Database must manage rows that are too large to fit into a single block. The following situations are possible: (1)The row is too large to fit into one data block when it is first inserted. In row chaining, Oracle Database stores the data for the row in a chain of one or more data blocks reserved for the segment. Row chaining most often occurs with large rows. Examples include rows that contain a column of data type LONG or LONG RAW, a VARCHAR2(4000) column in a 2 KB block, or a row with a huge number of columns. Row chaining in these cases is unavoidable. (2)A row that originally fit into one data block is updated so that the overall row length increases, but insufficient free space exists to hold the updated row. In row migration, Oracle Database moves the entire row to a new data block, assuming the row can fit in a new block. The original row piece of a migrated row contains a pointer or "forwarding address" to the new block containing the migrated row. The rowid of a migrated row does not change. (3)A row has more than 255 columns. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Oracle Database can only store 255 columns in a row piece. Thus, if you insert a row into a table that has 1000 columns, then the database creates 4 row pieces, typically chained over multiple blocks. Figure 12-14 depicts shows the insertion of a large row in a data block. The row is too large for the left block, so the database chains the row by placing the first row piece in the left block and the second row piece in the right block. Figure 12-14 Row Chaining Figure 12-15, the left block contains a row that is updated so that the row is now too large for the block. The database moves the entire row to the right block and leaves a pointer to the migrated row in the left block. Figure 12-15 Row Migration Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 When a row is chained or migrated, the I/O needed to retrieve the data increases. This situation results because Oracle Database must scan multiple blocks to retrieve the information for the row. For example, if the database performs one I/O to read an index and one I/O to read a nonmigrated table row, then an additional I/O is required to obtain the data for a migrated row. The Segment Advisor, which can be run both manually and automatically, is an Oracle Database component that identifies segments that have space available for reclamation. The advisor can offer advice about objects that have significant free space or too many chained rows. 1.19 Oracle 字符集 1.19.1 什么是 Oracle 字符集 Oracle 字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容 关系。ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理, 检索数据。它使数据库工具,错误消息,排序次序,日期,时间,货币,数字, 和日历自动适应本地化语言和平台。 影响 Oracle 数据库字符集最重要的参数是 NLS_LANG 参数。 它的格式如下: NLS_LANG = language_territory.charset 它有三个组成部分(语言、地域和字符集),每个成分控制了 NLS 子集的特性。 其中: Language: 指定服务器消息的语言, 影响提示信息是中文还是英文 Territory: 指定服务器的日期和数字格式, Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Charset: 指定字符集。 如:AMERICAN _ AMERICA. ZHS16GBK 从 NLS_LANG 的组成我们可以看出,真正影响数据库字符集的其实是第三部分。 所以两个数据库之间的字符集只要第三部分一样就可以相互导入导出数据,前面 影响的只是提示信息是中文还是英文。 1.19.2 字符集的相关知识 1.19.2.1 字符集 实质就是按照一定的字符编码方案,对一组特定的符号,分别赋予不同数值 编码的集合。Oracle 数据库最早支持的编码方案是 US7ASCII。 Oracle 的字符集命名遵循以下命名规则: 即: <语言><比特位数><编码> 比如: ZHS16GBK 表示采用 GBK 编码格式、16 位(两个字节)简体中文字符 集 1.19.2.2 字符编码方案 1.19.2.2.1 单字节编码 (1)单字节 7 位字符集,可以定义 128 个字符,最常用的字符集为 US7ASCII (2)单字节 8 位字符集,可以定义 256 个字符,适合于欧洲大部分国家 例如:WE8ISO8859P1(西欧、8 位、ISO 标准 8859P1 编码) 1.19.2.2.2 多字节编码 (1)变长多字节编码 某些字符用一个字节表示,其它字符用两个或多个字符表示,变长多字节编 码常用于对亚洲语言的支持, 例如日语、汉语、印地语等 例如:AL32UTF8(其中 AL 代表 ALL,指适用于所有语言)、zhs16cgb231280 (2)定长多字节编码 每一个字符都使用固定长度字节的编码方案,目前 oracle 唯一支持的定长多 字节编码是 AF16UTF16,也是仅用于国家字符集 1.19.2.2.3 unicode 编码 Unicode 是一个涵盖了目前全世界使用的所有已知字符的单一编码方案,也就 是说 Unicode 为每一个字符提供唯一的编码。UTF-16 是 unicode 的 16 位编码方 式,是一种定长多字节编码,用 2 个字节表示一个 unicode 字符,AF16UTF16 是 UTF-16 编码字符集。 UTF-8 是 unicode 的 8 位编码方式,是一种变长多字节编码,这种编码可以用 1、2、3 个字节表示一个 unicode 字符,AL32UTF8,UTF8、UTFE 是 UTF-8 编 码字符集 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.19.2.3 字符集超级 当一种字符集(字符集 A)的编码数值包含所有另一种字符集(字符集 B) 的编码数值,并且两种字符集相同编码数值代表相同的字符时,则字符集 A 是 字符集 B 的超级,或称字符集 B 是字符集 A 的子集。 Oracle 官方文档资料中有子集-超级对照表(subset-superset pairs),例如: WE8ISO8859P1 是 WE8MSWIN1252 的子集。由于 US7ASCII 是最早的 Oracle 数据库编码格式,因此有许多字符集是 US7ASCII 的超集,例如 WE8ISO8859P1、 ZHS16CGB231280、ZHS16GBK 都是 US7ASCII 的超集。 1.19.2.4 数据库字符集(oracle 服务器端字符集) 数据库字符集在创建数据库时指定,在创建后通常不能更改。在创建数据库 时,可以指定字符集(CHARACTER SET) 和国家字符集(NATIONAL CHARACTER SET)。 1.19.2.4.1 字符集 (1)用来存储 CHAR, VARCHAR2, CLOB, LONG 等类型数据 (2)用来标示诸如表名、列名以及 PL/SQL 变量等 (3)用来存储 SQL 和 PL/SQL 程序单元等 1.19.2.4.2 国家字符集 (1)用以存储 NCHAR, NVARCHAR2, NCLOB 等类型数据 (2)国家字符集实质上是为 oracle 选择的附加字符集,主要作用是为了增强 oracle 的字符处理能力,因为 NCHAR 数据类型可以提供对亚洲使用定长多字节 编码的支持,而数据库字符集则不能。国家字符集在 oracle9i 中进行了重新定义, 只能在 unicode 编码中的 AF16UTF16 和 UTF8 中选择,默认值是 AF16UTF16 1.19.2.4.3 查询字符集参数 可以查询以下数据字典或视图查看字符集设置情况 nls_database_parameters、props$、v$nls_parameters 查 询 结 果 中 NLS_CHARACTERSET 表 示 字 符 集 , NLS_NCHAR_CHARACTERSET 表示国家字符集 1.19.2.4.4 修改数据库字符集 按照上文所说,数据库字符集在创建后原则上不能更改。不过有 2 种方法可 行。 (1) 如果需要修改字符集,通常需要导出数据库数据,重建数据库,再导入数 据库数据的方式来转换。 (2) 通过 ALTER DATABASE CHARACTER SET 语句修改字符集,但创建数 据库后修改字符集是有限制的,只有新的字符集是当前字符集的超集时才能修改Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 数据库字符集,例如 UTF8 是 US7ASCII 的超集,修改数据库字符集可使用 ALTER DATABASE CHARACTER SET UTF8。 1.19.2.5 客户端字符集(NLS_LANG 参数) 1.19.2.5.1 客户端字符集含义 客户端字符集定义了客户端字符数据的编码方式,任何发自或发往客户端的 字符数据均使用客户端定义的字符集编码,客户端可以看作是能与数据库直接连 接的各种应用,例如 sqlplus,exp/imp 等。客户端字符集是通过设置 NLS_LANG 参数来设定的。 1.19.2.5.2 NLS_LANG 参数格式 NLS_LANG=_. Language: 显示 oracle 消息,校验,日期命名 Territory:指定默认日期、数字、货币等格式 Client character set:指定客户端将使用的字符集 例如:NLS_LANG=AMERICAN_AMERICA.US7ASCII AMERICAN 是语言,AMERICA 是地区,US7ASCII 是客户端字符集 1.19.2.5.3 客户端字符集设置方法 1)UNIX 环境 $NLS_LANG=―simplified chinese‖_china.zhs16gbk $export NLS_LANG 编辑 oracle 用户的 profile 文件 2)Windows 环境 编辑注册表 Regedit.exe --- 》 HKEY_LOCAL_MACHINE --- 》 SOFTWARE --- 》 ORACLE-HOME 1.19.2.5.4 NLS 参数查询 Oracle 提供若干 NLS 参数定制数据库和用户机以适应本地格式,例如有 NLS_LANGUAGE,NLS_DATE_FORMAT,NLS_CALENDER 等,可以通过查询 以下数据字典或 v$视图查看。 NLS_DATABASE_PARAMETERS:显示数据库当前 NLS 参数取值,包括数 据库字符集取值 NLS_SESSION_PARAMETERS: 显示由 NLS_LANG 设置的参数,或经 过 alter session 改变后的参数值(不包括由 NLS_LANG 设置的客户端字符集) NLS_INSTANCE_PARAMETE: 显示由参数文件 init.ora 定义的参数 V$NLS_PARAMETERS:显示数据库当前 NLS 参数取值 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.19.2.5.5 修改 NLS 参数 使用下列方法可以修改 NLS 参数 (1)修改实例启动时使用的初始化参数文件 (2)修改环境变量 NLS_LANG (3)使用 ALTER SESSION 语句,在 oracle 会话中修改 (4)使用某些 SQL 函数 NLS 作用优先级别:Sql function > alter session > 环境变量或注册表 > 参数 文件 > 数据库默认参数 1.19.3 EXP/IMP 与 字符集 1.19.3.1 EXP/IMP Export 和 Import 是一对读写 Oracle 数据的工具。Export 将 Oracle 数据库 中的数据输出到操作系统文件中, Import 把这些文件中的数据读到 Oracle 数据 库中,由于使用 exp/imp 进行数据迁移时,数据从源数据库到目标数据库的过程 中有四个环节涉及到字符集,如果这四个环节的字符集不一致,将会发生字符集 转换。 EXP ____________ _________________ _____________ |imp 导入文件|<-|环境变量 NLS_LANG|<-|数据库字符集| ------------ ----------------- ------------- IMP ____________ _________________ _____________ |imp 导入文件|->|环境变量 NLS_LANG|->|数据库字符集| ------------ ----------------- ------------- 四个字符集是 (1)源数据库字符集 (2)Export 过程中用户会话字符集(通过 NLS_LANG 设定) (3)Import 过程中用户会话字符集(通过 NLS_LANG 设定) (4)目标数据库字符集 1.19.3.2 导出的转换过程 在 Export 过程中,如果源数据库字符集与 Export 用户会话字符集不一致, 会发生字符集转换,并在导出文件的头部几个字节中存储 Export 用户会话字符 集的 ID 号。在这个转换过程中可能发生数据的丢失。 例: 如 果 源 数 据 库 使 用 ZHS16GBK ,而 Export 用 户 会 话 字 符 集 使 用 US7ASCII,由于 ZHS16GBK 是 16 位字符集,而 US7ASCII 是 7 位字符集,这个 转换过程中,中文字符在 US7ASCII 中不能够找到对等的字符,所以所有中文字 符都会丢失而变成―?? ‖形式,这样转换后生成的 Dmp 文件已经发生了数据丢失。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 因此如果想正确导出源数据库数据,则 Export 过程中用户会话字符集应等于源 数据库字符集或是源数据库字符集的超集 1.19.3.3 导入的转换过程 (1)确定导出数据库字符集环境 通过读取导出文件头,可以获得导出文件的字符集设置 (2)确定导入 session 的字符集,即导入 Session 使用的 NLS_LANG 环境变 量 (3)IMP 读取导出文件 读取导出文件字符集 ID,和导入进程的 NLS_LANG 进行比较 (4)如果导出文件字符集和导入 Session 字符集相同,那么在这一步骤内就 不需要转换,如果不同,就需要把数据转换为导入 Session 使用的字符集。可以 看出,导入数据到数据库过程中发生两次字符集转换 第一次:导入文件字符集与导入 Session 使用的字符集之间的转换,如果这个转 换过程不能正确完成,Import 向目标数据库的导入过程也就不能完成。 第二次:导入 Session 字符集与数据库字符集之间的转换。 1.19.4 查看数据库字符集 涉及三方面的字符集, 1. oracelserver 端的字符集; 2. oracle client 端的字符集; 3. dmp 文件的字符集。 在做数据导入的时候,需要这三个字符集都一致才能正确导入。 1.19.4.1 查询 oracle server 端的字符集 有很多种方法可以查出 oracle server 端的字符集,比较直观的查询方法是以 下这种: SQL> select userenv('language') from dual; USERENV('LANGUAGE') ---------------------------------------------------- SIMPLIFIED CHINESE_CHINA.ZHS16GBK SQL>select userenv(‗language‘) from dual; AMERICAN _ AMERICA. ZHS16GBK 1.19.4.2 如何查询 dmp 文件的字符集 用 oracle 的 exp 工具导出的 dmp 文件也包含了字符集信息,dmp 文件的第 2 和第 3 个字节记录了 dmp 文件的字符集。如果 dmp 文件不大,比如只有几 M 或 几十 M,可以用 UltraEdit 打开(16 进制方式),看第 2 第 3 个字节的内容,如 0354,Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 然后用以下 SQL 查出它对应的字符集: SQL> select nls_charset_name(to_number('0354','xxxx')) from dual; ZHS16GBK 如果 dmp 文件很大,比如有 2G 以上(这也是最常见的情况),用文本编辑器 打开很慢或者完全打不开,可以用以下命令(在 unix 主机上): cat exp.dmp |od -x|head -1|awk '{print $2 $3}'|cut -c 3-6 然后用上述 SQL 也可以得到它对应的字符集。 1.19.4.3 查询 oracle client 端的字符集 在 windows 平台下,就是注册表里面相应 OracleHome 的 NLS_LANG。还可 以在 dos 窗口里面自己设置, 比如: set nls_lang=AMERICAN_AMERICA.ZHS16GBK 这样就只影响这个窗口里面的环境变量。 在 unix 平台下,就是环境变量 NLS_LANG。 $echo $NLS_LANG AMERICAN_AMERICA.ZHS16GBK 如果检查的结果发现 server 端与 client 端字符集不一致,请统一修改为同 server 端相同的字符集。 补充: (1).数据库服务器字符集 select * from nls_database_parameters 来源于 props$,是表示数据库的字符集。 (2).客户端字符集环境 select * from nls_instance_parameters 其来源于 v$parameter,表示客户端的字符集的设置,可能是参数文件,环境变 量或者是注册表 (3).会话字符集环境 select * from nls_session_parameters 来源于 v$nls_parameters,表示会话自己的设置,可能是会话的环境变量或者是 alter session 完成,如果会话没有特殊的设置,将与 nls_instance_parameters 一致。 (4).客户端的字符集要求与服务器一致,才能正确显示数据库的非 Ascii 字符。 如果多个设置存在的时候,NLS 作用优先级别:Sql function > alter session > 环境变量或注册表 > 参数文件 > 数据库默认参数 字符集要求一致,但是语言设置却可以不同,语言设置建议用英文。如字符 集是 zhs16gbk,则 nls_lang 可以是 American_America.zhs16gbk。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.19.5 修改 oracle 的字符集 按照上文所说,数据库字符集在创建后原则上不能更改。因此,在设计和安 装之初考虑使用哪一种字符集十分重要。对数据库 server 而言,错误的修改字符 集将会导致很多不可测的后果,可能会严重影响数据库的正常运行,所以在修改 之前一定要确认两种字符集是否存在子集和超集的关系。一般来说,除非万不得 已,我们不建议修改 oracle 数据库 server 端的字符集。特别说明,我们最常用的 两种字符集 ZHS16GBK 和 ZHS16CGB231280 之间不存在子集和超集关系,因此 理论上讲这两种字符集之间的相互转换不受支持。 不过修改字符集有 2 种方法可行。 1. 通常需要导出数据库数据,重建数据库,再导入数据库数据的方式来转换。 2. 通过 ALTER DATABASE CHARACTER SET 语句修改字符集,但创建数据库 后修改字符集是有限制的,只有新的字符集是当前字符集的超集时才能修改数据 库字符集,例如 UTF8 是 US7ASCII 的超集,修改数据库字符集可使用 ALTER DATABASE CHARACTER SET UTF8。 1.19.5.1 修改 server 端字符集(不建议使用) 1. 关闭数据库 SQL>SHUTDOWN IMMEDIATE 2. 启动到 Mount SQL>STARTUP MOUNT; SQL>ALTER SYSTEM ENABLE RESTRICTED SESSION; SQL>ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0; SQL>ALTER SYSTEM SET AQ_TM_PROCESSES=0; SQL>ALTER DATABASE OPEN; --这里可以从父集到子集 SQL>ALTER DATABASE CHARACTER SET ZHS16GBK; SQL>ALTER DATABASE NATIONAL CHARACTER SET ZHS16GBK; --如果是从子集到父集,需要使用 INTERNAL_USE 参数,跳过超子集检测 SQL>ALTER DATABASE CHARACTER SET INTERNAL_USE AL32UTF8; SQL>ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE AL32UTF8; SQL>SHUTDOWN IMMEDIATE; SQL>STARTUP 注意:如果没有大对象,在使用过程中进行语言转换没有什么影响,(切记 设定的字符集必须是 ORACLE 支持,不然不能 start) 按上面的做法就可以。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 若出现‗ORA-12717: Cannot ALTER DATABASE NATIONAL CHARACTER SET when NCLOB data exists‘ 这样的提示信息, 要解决这个问题有两种方法 1. 利用 INTERNAL_USE 关键字修改区域设置, 2. 利用 re-create,但是 re-create 有点复杂,所以请用 internal_use SQL>SHUTDOWN IMMEDIATE; SQL>STARTUP MOUNT EXCLUSIVE; SQL>ALTER SYSTEM ENABLE RESTRICTED SESSION; SQL>ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0; SQL>ALTER SYSTEM SET AQ_TM_PROCESSES=0; SQL>ALTER DATABASE OPEN; SQL>ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE UTF8; SQL>SHUTDOWN immediate; SQL>startup; 如果按上面的做法做,National charset 的区域设置就没有问题 1.19.5.2 修改 dmp 文件字符集 上文说过,dmp 文件的第 2 第 3 字节记录了字符集信息,因此直接修改 dmp 文件的第 2 第 3 字节的内容就可以‗骗‘过 oracle 的检查。这样做理论上也仅是从 子集到超集可以修改,但很多情况下在没有子集和超集关系的情况下也可以修 改,我们常用的一些字符集,如 US7ASCII,WE8ISO8859P1,ZHS16CGB231280, ZHS16GBK 基本都可以改。因为改的只是 dmp 文件,所以影响不大。 具体的修改方法比较多,最简单的就是直接用 UltraEdit 修改 dmp 文件的第 2 和第 3 个字节。 比如想将 dmp 文件的字符集改为 ZHS16GBK,可以用以下 SQL 查出该种字 符集对应的 16 进制代码: SQL> select to_char(nls_charset_id('ZHS16GBK'), 'xxxx') from dual; 0354 然后将 dmp 文件的 2、3 字节修改为 0354 即可。 如果 dmp 文件很大,用 ue 无法打开,就需要用程序的方法了。 1.19.5.3 客户端字符集设置方法 1)UNIX 环境 $NLS_LANG=―simplified chinese‖_china.zhs16gbk $export NLS_LANG 编辑 oracle 用户的 profile 文件 2)Windows 环境 编辑注册表 Regedit.exe --- 》 HKEY_LOCAL_MACHINE --- 》 SOFTWARE --- 》 ORACLE-HOME Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 或者在窗口设置: set nls_lang=AMERICAN_AMERICA.ZHS16GBK 1.20 SCN,RedoLog 和 Checkpoint 1.20.1 Redo log 作用 数据库异常关机(比如突然断电,shutdown abort: 它会立即关闭数据库,等 同于断电)之后,这时已经 commit 的事务已经记录到 online redo log 中,下次启 动数据库时,Oracle 进行恢复操作,将 online redo log 中的事务操作调入内存中, 进行相应操作后将数据记入到数据文件中,数据操作完成。 对于没有 commit 而已经写入数据文件或回退段的数据,也要进行回滚操作, 将数据恢复到 rollback 的状态,使数据文件和控制文件恢复到崩溃前的一致性状 态。总之,数据库下次打开时会占用比正常关闭更长的时间。 注意: 并不是所有异常关机后,下次启动时都可以恢复到正常状态,异常关机容易 导致坏块的产生,这种情况下数据库是不能正常启动的,如果处理不当,将会导 致大量数据的丢失。 Rolling Forward(前滚) Oracle 启动实例并加载数据库,然后通过 Online Redologs 中的重做日志,重 现实例崩溃前对数据库的修改操作。在恢复过程中对于已经提交的事务,但尚未 写入数据文件的那部分数据全部写入数据文件. Rolling Back(回滚) Rolling Forward 之后,虽然已经提交的修改操作更改的数据都已经被写入数 据文件,但在实例崩溃时,部分未提交的事务操作的数据也被写入到数据文件, 这些事务必须被撤销. 有关前滚和回滚,更多信息,参考 2.6 小节。 触发 LGWR 进程的条件有: 1. 用户提交 2. 有 1/3 重做日志缓冲区未被写入磁盘 3. 有大于 1M 的重做日志缓冲区未被写入磁盘 4. 3 秒超时 5. DBWR 需要写入的数据的 SCN 大于 LGWR 记录的 SCN,DBWR 触发 LGWR 写入。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.20.2 SCN(system change number) SCN 是当 Oracle 数据更新后,由 DBMS 自动维护去累积递增的一个数字。 当 一个事务 commit 时,LGWR 会将 log buffer 写入 redo log file,同时也会将该事 务的 SCN 同步写入到 redo log file 内(wait-until-completed)。因此当你 commit transaction 时, 在成功的讯息返回之前,LGWR 必须先完整的完成上述行为之 后,否则你是看不到提交成功的响应讯息。 可以理解的,返回的 SCN,也是目前 redo log file 最新的 SCN 纪录。 因为 commit 后的交易才会有 SCN,而一旦 commit 就会立刻写入 redo log file 中。 系统时间标记与 scn 之间存在一张表,即 SYS 下的 SMON_SCN_TIME。 SQL> desc sys.smon_scn_time 名称 是否为空? 类型 ----------------------------------------- -------- --------------------------- THREAD NUMBER TIME_MP NUMBER TIME_DP DATE SCN_WRP NUMBER SCN_BAS NUMBER NUM_MAPPINGS NUMBER TIM_SCN_MAP RAW(1200) SCN NUMBER ORIG_THREAD NUMBER 每隔 5 分钟,系统产生一次系统时间标记与 scn 的 匹 配 并 存 入 SYS.SMON_SCN_TIME 表(由 SMON 进程来进行 Update 操作),该表中记录了 最近 1440 个系统时间标记与 scn 的匹配记录,由于该表只维护了最近的 1440 条 记录,即最近 5 天内的记录。 对 系统时间标记与 scn 的每 5 分钟匹配一次 做个说明,比如: SCN:339988 对应 2011-01-25 17:00:00 SCN:339989 对应 2011-01-25 17:05:00, 当查询2011-01-25 17:00:00 到2011-01-25 17:04:59 这段时间点内的SCN时, oracle 都会将其匹配为 SCN:339988。 查看 SCN 和 timestamp 之间的对应关系: select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss') from sys.smon_scn_time order by 2; 查询目前系统最新的 SCN: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL>select dbms_flashback.get_system_change_number from dual; 或者: SQL> select current_scn from v$database; CURRENT_SCN ----------- 1428603737 timestamp 与 SCN 互换的 2 个方法: select timestamp_to_scn(to_date('2011-01-25 12:10:00','yyyy-mm-dd hh24:mi:ss')) from dual; select scn_to_timestamp(351277605) from dual; 在 Metalink 搜到一篇 Timestamp 与 SCN 之间映射关系的文章,原文参考: How to map SCN with Timestamp before 10g [ID 365536.1] http://blog.csdn.net/tianlesoftware/archive/2011/01/25/6163757.aspx However, in earlier releases, while there is a system object - SYS.SMON_SCN_TIME that will provide the SCN to TIME mapping information. There is no conversion facility provided. SYS.SMON_SCN_TIME will have a maximum of 1440 rows and each record will be for a 5 minute period. Oracle maintains this information for maximum of 5 days after which the records will be recycled. This means that data is stored 12 times per hour * 24 hours * 5 days=1440 rows. SCN value is stored internally as : i. SCN_wrap ii. SCN_base Whenever the SCN is incremented, the BASE component is incremented first unil it reaches it maximum. Once the BASE reaches the maximum value allowed, it is initialized to zero again after incrementing the WRAP by 1. --开始时 WRAP 为 0,即 SCN_WRP=0. 当 BASE 增长到最大值后,SCN_BAS 变为 0. 同时 SCN_WRP 增长到 1 Using this logic, we can calculate the timestamp of the SCN as follows: (SCN_WRP * 4294967296) + SCN_BAS should give us the SCN in the number format --SCN 的计算公式,这里我们看出 SCN 是根据 SCN_BAS 计算出来的。和系统 时间是没有关系的。 只是方便我们来进行操作,如闪回恢复,而将 SCN 和 系 统时间每隔 5 分钟进行一次映射。 映射完后,由 SMON 进程将映射关系写入Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SMON_SCN_TIME 表。 可以把 SCN 看成是 Oracle 内部的时间。 To get the time/date for an SCN value in 9i, use the following example: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- (a) Get the current SCN base. SQL>select max(scn_bas) SCN_BASE from smon_scn_time; 1603342197 --(b) Get the complete SCN and the timestamp. SQL> alter session set NLS_DATE_FORMAT='DD-MON-YY HH:MI:SS'; SQL> select time_dp TIMESTAMP, scn_wrp*4294967296+SCN_bas SCN from smon_scn_time where scn_bas='1603342197'; TIMESTAMP SCN ------------------ ---------- 28-JUL-06 05:31:08 8252235517813 这篇文章讲的是 10g 之前的。 在 metalink 上搜了半天,只找到一条区别, 就是 11g 下 smon_scn_time 存储的记录可以超过 1440 条。 1.20.3 Checkpoint (检查点) 1.20.3.1 检查点定义 大多数关系型数据库都采用"在提交时并不强迫针对数据块的修改完成"而是 "提交时保证修改记录(以重做日志的形式)写入日志文件"的机制,来获得性能 的优势。即:当用户提交事务,写数据文件是"异步"的,写日志文件是"同步"的。 这就可能导致数据库实例崩溃时,内存中的 DB_Buffer 中的修改过的数据, 可能没有写入到数据块中。数据库在重新打开时,需要进行恢复,来恢复 DB Buffer 中的数据状态,并确保已经提交的数据被写入到数据块中。 检查点是这个过程中的重要机制,通过它来确定,恢复时哪些重做日志应该 被扫描并应用于恢复。 先看一下 checkpoint queue 概念,检查点发生后,触发 DBWn,CKPT 获取 发生检查点时对应的 SCN,通知 DBWn 要写到这个 SCN 为止, DBWR 写 dirty buffer 是根据 buffer 在被首次 modify 的时候的时间的顺序写出,也就是 buffer 被 modify 的时候会进入一个 queue (checkpoint queue),DBWr 就根据 queue 从其中批量地写到数据文件。 由于这里有一个顺序的关系,所以 dbwr 的写的 进度就是可衡量的,写到哪个 buffer 的时候该 buffer 的首次变化时候的 scn 就是Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 当前所有数据文件 block 的最新 scn,但是由于无法适时的将 dbwr 的进度记录下 来,所以 oracle 选择了一些策略。 其中就包括 ckpt 进程的检查点和心跳。 检查点发生以后,CKPT 进程检查 checkpoint queue(也就是脏块链表)是否过 长,如果是,则触发 DBWn,将一部分脏块写入数据文件,从而缩短 checkpoint queue。 Checkpoint 发生时,一方面通知 dbwr 进行下一批写操作,(dbwr 写入的时 候,一次写的块数是有一个批量写的隐藏参数控制的); 另一方面,oracle 采用了 一个心跳的概念,以 3 秒的频率将 dbwr 写的进度反应到控制文件中,也就是把 dbwr 当前刚写完的 dirty buffer 对应的 scn 写入数据文件头和控制文件,这就是 检查点 scn。 这个 3 秒和增量检查点不是一个概念,3 秒只是在控制文件中,ckpt 进程去 更新当前 dbwr 写到哪里了,这个对于 ckpt 进程来说叫 heartbeat ,heartbeat 是 3 秒一次,3 秒可以看作不停的检查并记录检查点执行情况(DBWR 的写进度)。 检查点发生之后数据库的数据文件、控制文件处于一致状态的含义是不需要 进行介质恢复,只表示数据文件头一致,但是并不表示数据文件内容一致,因为 数据文件内容可能在没有发生检查点的其它情况下的 dbwr 写数据文件,这样数 据文件内容就不一致,若掉电需要进行崩溃恢复。 oracle8 以后推出了 incremental checkpoint(增量检查点)的机制,在以前的版 本里每 checkpoint 时都会做一个 full thread checkpoint(完全检查点),这样的话所有 脏数据会被写到磁盘,巨大的 i/o 对系统性能带来很大影响。 为了解决这个问题,oracle 引入了 checkpoint queue 机制,每一个脏块会被移 到检查点队列里面去,按照 low rdb(第一次对此块修改对应的 redo block address) 来排列,靠近检查点队列尾端的数据块的 low rba 值是最小的,而且如果这些赃 块被再次修改后它在检查点队列里的顺序也不会改变,这样就保证了越早修改的 块越早写入磁盘。每隔 3 秒钟 ckpt 会去更新控制文件和数据文件,记录 checkpoint 执行的情况。 触发 DBWR 进程的条件有: 1. DBWR 超时,大约 3 秒 2. 系统中没有多余的空缓冲区来存放数据 3. CKPT 进程触发 DBWR checkpoint 有两个目的: 1、确保数据一致性。 2、使数据库能快速地恢复。 Checkpoint 期间会有下面进程发生: 1. DBWR 写所有脏数据到数据文件; 2. LGWR 更新控制文件和数据文件的 SCN。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.20.3.2 Checkpoints 相关优化参数 Checkpoints 是一个数据库优化的难点。频繁的 Checkpoints 可以实现快速的 恢复,但也会使性能下降。怎样处理这个问题呢? 依赖于数据库数据文件的数量,一个 Checkpoint 可能是高速的运行。因为所 有的数据文件在 Checkpoint 期间都会被冻结。更频繁的 Checkpoints 可以快速恢 复数据库。这也客户对不按规定系统宕机的容忍的原因。然而,在一些特殊情况 下,频繁的 Checkpoints 也不能保证可以快速恢复。我们假设数据库在 95%的时 间内是正常运行,5%由于实例失败导致不可用,要求恢复。对大多数客户而言, 他们更希望调整 95%的性能而不是 5%的宕机时间。这个假设表明,性能是摆在 第一位的,所以我门的目标就是在优化期间减少 Checkpoints 的频繁度。 优化 Checkpoints 包括 4 个关键的初始化参数: - FAST_START_MTTR_TARGET - LOG_CHECKPOINT_INTERVAL - LOG_CHECKPOINT_TIMEOUT - LOG_CHECKPOINTS_TO_ALERT 1.20.3.2.1 FAST_START_MTTR_TARGET Oracle9i 以来 FAST_START_MTTR_TARGET 参数是调整 checkpoint 的首选 的方法。FAST_START_MTTR_TARGET 可以指定单实例恢复需要的秒数。基于 内部的统计,增长的 checkpoint 会 自 动 调 整 的 checkpint 的 目 标 以 满 足 FAST_START_MTTR_TARGET 的需求。 v$instance_recovery.estimated_mttr 显示当前估计需要恢复的秒数。这个值会 被显示即使 FAST_START_MTTR_TARGET 没有被指定。 v$instance_recovery.target_mttr 表明在短时间内 MTTR 的目标。 v$mttr_target_advice 显示这个当前 MTTR 设置的工作量产生的 I/O 数量和其 他 I/O。这个视图帮助用户评定这个在优化和恢复之前的平衡。 1.20.3.2.2 LOG_CHECKPOINT_INTERVAL LOG_CHECKPOINT_INTERVAL 参数指定这个最大的重做块的间隔数目。 如果 FAST_START_MTTR_TARGET 被指定,LOG_CHECKPOINT_INTERVAL 不能被设置为 0。 在 大 多 数 Unix 系统的 OS 块 大 小 是 512 字 节 。 设 置 LOG_CHECKPOINT_INTERVAL=10000 意味着这个增长的 checkpoint 不能追加 到当前日志,因为多于 5M。如果你的重做日志是 20M,你将发出 4 个 checkpoint 对每个重做日志。 LOG_CHECKPOINT_INTERVAL 会发生影响当一个 checkpoint 发生时,小 心设置这个参数,保持它随着重做日志文件大小变化而变化。checkpoint 频繁是Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 这个影响数据库恢复的原因之一。短的 checkpoint 间隔意味数据库将快速恢复, 也增加了资源的利用。这个参数也影响数据库向前回滚的时间。实际的恢复时间 是基于这个时间,当然还有失败的类型和需要归档日志的数量。 1.20.3.2.3 LOG_CHECKPOINT_TIMEOUT 这个参数指定 checkpoint 发出的时间间隔。换句话说,它指定一次脏数据多 少时间写出一次。checkpoint 频率会影响这个数据库恢复的时间。长时间的间隔 会要求数据库恢复要求更久。 Oracle 建议用 LOG_CHECKPOINT_interval 去控制 checkpoint 而不用 LOG_CHECKPOINT_TIMEOUT,LOG_CHECKPOINT_TIMEOUT 每 n 秒发一次 checkpoint,不顾事务提交的频率。这可能会导致一些没有必要的 checkpoint 在 事务已经变化的情况下。不必要的 checkpoint 必须被避免。 还有一个容易误解的地方:LOG_CHECKPOINT_TIMEOUT 会间隔性地发 出 log switch。而 Log switch 会触发一个 checkpoint,但 checkpoint 不会导致一个 log switch。唯一手工方式 alter system switch logfile 或者重新设置 redo logs 大小 可以导致频繁 switch。 SQL> alter system set log_checkpoint_timeout=300;[单位是秒] 1.20.3.2.4 log_checkpoint_to_alert 设置为真,可以在告警日志中观察到增量检查点的触发。 SQL> alter system set log_checkpoints_to_alert=true; 对于优化和恢复, 在线重做日志的大小是关键的。 1.20.3.3 Checkpoint 触发条件 1.20.3.3.1 触发完全检查点 条件 发完全检查点,促使 DBWR 将检查点时刻前所有的脏数据写入数据文件。 另外,一般正常运行期间的数据库不会产生完全检查点。 1. 通过正常事务处理或者立即选项关闭例程时 (shutdown immediate 或者 Shutdown normal). 2. 当通过设置初始化参数: LOG_CHECKPOINT_INTERVAL, LOG_CHECKPOINT_TIMEOUT , FAST_START_IO_TARGET 强制时; 3. 当数据库管理员手动请求时: ALter system checkpoint; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 alter tablespace ... offline; 4. 每次日志切换时; alter system switch logfile 注意: 1. alter system switch logfile 也将触发完全检查点的发生。 2. alter database datafile ... offline 不会触发检查点进程。 如果是单纯的 offline datafile,那么将不会触发文件检查点,只有针对 offline tablespace 的时候才会触发文件检查点,这也是为什么 online datafile 需要 media recovery 而 online tablespace 不需要。 对于表空间的 offline 后再 online 这种情况,最好做个强制的 checkpoint 比较好。 关于 offline datafile 和 tablespace 的区别也可以参考 1.25 节。 1.20.3.3.2 触发增量检查点 1. 在联机热备份数据文件前,要求该数据文件中被修改的块从DB_Buffer 写 入数据文件中。所以,发出这样的命令: ALTER TABLESPACE tablespace_name BIGEN BACKUP / end backup; 也将触发和该表空间的数据文件有关的局部检查点; 2. 另外, ALTER TABLESPACE tablespace_name READ ONLY; ALTER TABLESPACE tablespace_name OFFLINE NORMAL; 等命令都会触发增量检查点。 1.20.3.4 检查点的一些讨论 1.20.3.4.1. Commit 成功后,数据还会丢失吗? 对于 Oracle 来说,用户所做的 DML 操作一旦被提交,则先是在 database buffer cache 中进行修改,同时在修改之前会将数据的前镜像保存在回滚段中,然后将 修改之前和修改之后的数据都写入到 redo log buffer 中,当接收到 commit 命令之 后,则 redo log buffer 开始写 redo log file ,并且记录此时的 scn,当 redo log file 写完了之后,表示这次事务提交操作已经确认被数据库记录了,只有当 redo log file 写成功了,才会给用户 Commit completed 的成功字样。 而对于 Database buffer cache 中的 dirty buffer 则会等待触发 DBWn 才写入, 但是如果此时断电,则数据已经被记录到了 redo log file 中,系统在重新启动的 时候,会自动进行嵌滚和回滚来保证数据的一致。所以,只要是 commit 成功的Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 了,数据不会丢失! 1.20.3.4.2. 数据库发生一次 DBWn,是否将所有 buffer cache 中的 dirty buffer 都写入,还是先将脏队列中的数据写入? 这话看起来有道理,但实际上,dbwr 在写的时候又不断地在产生 dirty buffer , 所以说检查点发生的时候是期望把该时间点之前的所有脏缓冲区写入数据文件。 所有的 buffer,不在 LRU list 上就在 dirty list 上, dbwr 写入的时候,一次写的块 数是有一个批量写的隐藏参数控制的。 所以说要是 dbwr 将 dirty list 也好, lru list 上的也好,要实现全部写入,都 是一个现实系统中很难存在的现象。dirty 总是在不断的产生,dbwr 总是在不断 地写,增量检查点发生的时候也并不意味着一定要更新数据文件头,检查点开始 的时候只表示该次检查点结束的时候要更新数据文件头的话数据文件头具有该 时间点的一致性。 1.20.3.4.3. 关于检查点等待事件: 有些事件的产生必须等待检查点的完成,才能开始数据库的其它操作:日志 文件切换就是其中一个事件,日志切换必须等待检查点完成。 log file switch (checkpoint incomplete) 这个等待事件本身也说明,日志切换时 产生的检查点是需要等待的,这个日志文件所对应脏块全部写完后,检查点进程 更新控制文件和数据头,然后这个检查点才能算完成。 也就是说日志切换必须等待检查点完成,而检查点在等待 DBWn 完成。 这种等待 DBWn 完成的检查点,最后一步写入控制文件和数据文件头的 SCN,肯定是 DBWn 完成的最后一块的 SCN。 1.20.3.4.4. 检查点为什么要等待 dbwr 完成后才进行切换(log switch)? log switch 时,是不能立即 switch 到 active 状态的,log group 必须等待。 active 表示该 log group 还没有完成归档(归档模式下)或者该 log group 有进行 instance recovery 的需要用到的日志。所以当 checkpoint 发生时,如果 dbwr 还没 有写完它该写完的 dirty buffers(该 checkpoint 时间点以前产生的 dirty buffers, 靠 scn 判断),则该 log group 处于 active 状态,不会进行日志切换,当然也不会发 生日志文件被覆盖的问题了。 1.20.3.4.5. 如果没有设置 archive log ,在检查点发生后,发生 log switch 一个轮 回,log file 是否会被覆盖掉? 当检查点发生后,会触发 lgwr,lgwr 会把此时 SCN 以前在 redo buffer 中的 所有操作写到 redo log file,同时 lgwr 也会触发 dbwr 进程,dbwr 也开始把此刻 以前 database buffer 中的 dirty buffer 队列中的操作写入 data file。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 其实检查点发生后,就是 lgwr 和 dbwr 写 buffer 到磁盘文件的过程,但是两 者的读写速度时不同的,dbwr 写 buffer 到数据文件的过程相对较慢,因为 dbwr 写过程是一个随机读取存储的过程。Lgwr 写 buffer 到 redo 文件的过程比 dbwr 要快很多,因为 lgwr 是顺序读取写入的。 由于以上 lgwr 和 dbwr 写操作的速度不同,就产生了一个等待问题。即当 lgwr 轮循一圈后,要进行日志切换,覆盖 redo log file,但是此时 dbwr 还没有写完, 那么 lgwr 就会出现等待,oracle 也会 hang 在那里,同时 alter 文件中会提示一个 相应的提示 checkpoint not complete。等检查点完成后数据库自动恢复正常。 如: Thread 1 advanced to log sequence 14215 (LGWR switch) Current log# 1 seq# 14215 mem# 0: /u03/oradata/newccs/redo01.log Mon Nov 30 17:35:54 2009 Thread 1 cannot allocate new log, sequence 14216 Checkpoint not complete Current log# 1 seq# 14215 mem# 0: /u03/oradata/newccs/redo01.log Mon Nov 30 17:35:55 2009 Thread 1 advanced to log sequence 14216 (LGWR switch) Current log# 2 seq# 14216 mem# 0: /u03/oradata/newccs/redo02.log log switch 时,会触发检查点,标记检查点时,DBWR 要把 log file 中 covered by the log being checkpointed 的数据写入到数据文件上,如果 Dbwr 没有写完,那 么前一个 logfile 是不能被覆盖的。因此必须等检查点完毕,也可以说是将要被 覆盖的日志相关的数据块全部写入数据文件后,该日志文件才能被覆盖! 果这种情况出现,alert 文件中会记录 checkpoint not complete 事件,这通常表 明你的 dbwr 写入过慢或者 logfile 组数过少或 log file 太小。 1.20.3.4.6. 检查点发生时,出现日志切换,但是 dbwr 还没有写完,是否会覆盖 redo log file,如果此时掉电,dbwr 挂起,会出现丢失数据吗? 会覆盖 redo 文件,要等待 dbwr 写完才覆盖。或者说要等待检查点完成才覆 盖。 如果 DBWn 正在写的脏块是指对应到即将被覆盖的那个日志文件的,那么, 因为在这些操作完成之前,不可能有覆盖这件事发生,假设你预料的掉电发生了, 不会有什么问题,实例恢复时的前滚从刚才准备覆盖的那个日志文件开始。 如果正在写的脏块是指对应到刚刚被写满的那个日志文件的,肯定一时半会 也写不完,日志切换也不会等它,如果切换成功后 dbwr 挂了,后面的写脏块操 作估计也还没完成,但是,刚写满的那个文件并没有被覆盖,也不会有任何问题。 因此不会出现数据丢失! 当一个很大的 dml 发生时,用户在 commit 后,需要将 redo log buffer 中的脏Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 数据写入 redo log file 中。如果在写的过程中,发现一个 redo log file 写不下的话, 需要写另外一个 redo log file,这时应该触发 checkpoint,接着触发 DBWn,将脏 数据写入 datafile,这时发生掉电,导致 DBWR 失败。这时其实就可以说 commit 失败了。以上所述其实就是 commit 没有提交成功。 1.20.3.4.7. alter systen switch logfile 会触发完全检查点; 但是为什么,日志切换 以后检查点只能记录到上一次归档日志产生的时间呢?而不是现在归档日志产 生的时间呢? 因为这时的 checkpoint enqueue 队列中,也就是脏块队列中脏块还不够多, 还不足以触发 DBWn 写脏块。所以,内存里需要写入的脏块所对应的 redo 还存 在于上一个 redo log 里,这时你去看该 redo log 的 status 为 active。 我们可以通过一下语句查看相关信息: SQL> select * from x$kccrt; 1.20.4 checkpoint 和 scn 的关系 checkpoint 发生的目的就是要把储存在 buffer 内的已提交的事务写回 disk, 否则一旦发生 crash,需要进行 recovery 时,你就必须花很多的时间从 redo log file 内最后的 SCN 交易开始进行 recovery,这样在商业应用上是很浪费时间和没有 效率的。 重点在于当 commit 一个事务时,只会立刻将 redo buffer 写入 redo log file 内, 但是并不会马上将该 update 后的 block(dirty block)同步写回 disk datafile 中,这是 为了减少过多 disk IO 的考虑,所以采取 batch 的方式写入。 When a checkpoint occurs, Oracle must update the headers of all datafiles to record the details of the checkpoint. This is done by the CKPT process. The CKPT process does not write blocks to disk; DBWn always performs that work. 在 shutdown normal or shutdown immediate 下,也就是所谓的 clean shutdown, checkpoint 也会自动触发,并且把 SCN 纪录写回。 当发生 checkpoint 时,会把 SCN 写到四个地方去。三个地方于 control file 内, 一个在 datafile header。 Control file 三个地方为 (1)System checkpoint SCN SQL> select checkpoint_change# from v$database; CHECKPOINT_CHANGE# -------------------- Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 292767 (2)Datafile checkpoint SCN SQL> select name,checkpoint_change# from v$datafile where name like '%users01%'; NAME CHECKPOINT_CHANGE# ----------------------------------- -------------------- /u02/oradata/OMFD1/users01.dbf 292767 (3)Stop SCN SQL> select name,last_change# from v$datafile where name like '%users01%'; NAME LAST_CHANGE# ----------------------------------- ------------ /u02/oradata/OMFD1/users01.dbf 正常 datafile 在 read-write mode 下 last_change#一定是 NULL Datafile header 中的一个 SCN:Start SCN 在 datafile header SQL> select name,checkpoint_change# from v$datafile_header where name like '%users01%'; NAME CHECKPOINT_CHANGE# ----------------------------------- -------------------- /u02/oradata/OMFD1/users01.dbf 292767 1.20.5 相关问题 1.20.5.1 为什么储存在 CONTROL FILE 中要分为两个地方(SYSTEM CHECKPOINT SCN,DATAFILE CHECKPOINT SCN) ? 当你把一个 tbs 设为 read-only 时,他的 SCN 会冻结停止,此时 DATAFILE CHECKPOINT SCN 是不会再递增改变的, 但是整体的 SYSTEM CHECKPOINT SCN 却仍然会不断递增前进。所以,这就是为什么需要分别在两个地方储存 SCN。 1.20.5.2 正常 shutdown database 后,SCN 会发生什么变化? 我们可以把数据库开在 mount mode SQL>select checkpoint_change# from v$database; CHECKPOINT_CHANGE# -------------------- 293184 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL>select name,checkpoint_change#,last_change# from v$datafile where name like '%user%'; NAME CHECKPOINT_CHANGE# LAST_CHANGE# ----------------------------------- -------------------- -------------- /u02/oradata/OMFD1/users01.dbf 293184 293184 可以看到储存在 control file 中的三个 SCN 位置都是相同,注意此时的 stop scn 不会是 NULL,而是等于 start scn 我们来查询 datafile header SCN: SQL>select name,checkpoint_change# from v$datafile_header where name like '%users01%'; NAME CHECKPOINT_CHANGE# ----------------------------------- -------------------- /u02/oradata/OMFD1/users01.dbf 293184 当 clean shutdown 时,checkpoint 会进行,并且此时 datafile 的 stop scn 和 start scn 会相同。 等到我门开启数据库时,Oracle 检查 datafile header 中的 start scn 和存于 control file 中的 datafile 的 scn 是否相同, 如果相同,接着检查 start scn 和 stop scn 是否相同,如果仍然相同,数据库就会正常开启,否则就需要 recovery... 等到数据库开启后,储存在 control file 中的 stop scn 就会恢复为 NULL 值,此时 表示 datafile 是 open 在正常模式下了。 如果不正常 SHUTDOWN (shutdown abort),则 mount 数据库后,你会发现 stop scn 并不是等于其它位置的 scn, 而是等于 NULL,这表示 Oracle 在 shutdown 时没有进行 checkpoint,下次开机必须进行 crash recovery。 crash recovery 必须先进行 roll forward(从 redo log file 中从目前的 start SCN 开始,重做后面 的已提交之交易)。再从 roll back segment 做 rollback 未完成(dead transaction)交 易。检验 controlfile 中的 SCN 会等于 datafile header 的 SCN。 这个就是我们在 2.6 节里前滚和后滚的顺序问题。 SQL>select 'controlfile' "SCN location",name,checkpoint_change# from v$datafile where name like '%users01%' union select 'file header',name,checkpoint_change# from v$datafile_header where name like '%users01%'; SCN location NAME CHECKPOINT_CHANGE# -------------- ----------------------------------- -------------------- Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 controlfile /u02/oradata/OMFD1/users01.dbf 293188 file header /u02/oradata/OMFD1/users01.dbf 293188 1.20.5.3 crash recovery 和 media recovery 的比较 启动数据库时,如果发现 STOP SCN = NULL,表示需要进行 crash recovery; 启动数据库时,如果发现有 datafile header 的 START SCN 不等于储存于 CONTROLFILE 的 DATAFILE SCN,表示需要进行 Media recovery 1.20.5.4 RECOVERY DATABASE 两种常见问题 (1) recover database until cancel ==> open database resetlog 这种情况下 DATAFILE HEADER 中的 SCN 一定会小于 CONTROLFILE 中 的 DATAFILE SCN。 如果你有进行RESTORE DATAFILE,则该RESTORE的DATAFILE HEADER SCN 一定会小于目前 CONTROLFILE 的 DATAFILE SCN,此时会无法开启数据 库,必须进行 media recovery。 重做 archive log 直到该 datafile header 的 SCN=current scn restore datafile 后,可以 mount database 然后去检查 controlfile and datafile header 的 SCN: SQL>select 'controlfile' "SCN location",name,checkpoint_change# from v$datafile where name like '%users01%' union select 'file header',name,checkpoint_change# from v$datafile_header where name like '%users01%'; SCN location NAME CHECKPOINT_CHANGE# -------------- ----------------------------------- -------------------- controlfile /u02/oradata/OMFD1/users01.dbf 313551 file header /u02/oradata/OMFD1/users01.dbf 313401 (2)recover database until cancel using backup controlfile; ===> open database resetlog 这种情况下,DATAFILE HEADER 中的 SCN 一定会大于 CONTROLFILE 的 DATAFILE SCN。 因为控制文件是旧的控制文件。所以它保存的信息也是以前 的信息。 如果只是某 TABLE 被 DROP 掉,没有破坏数据库整体数据结构,还可以用 NCOMPLETE RECOVERY 解决; 如果是某个 TABLESPACE OR DATAFILE 被 DROP 掉,因为档案结构已经 破坏,目前的 CONTROL FILE 内已经没有 该 DATAFILE 的信息,就算你只 RESTORE DATAFILE 然后进行 INCOMPLETE RECOVERY 也无法救回被 DROPTianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 的 DATA FILE。 只好 RESOTRE 之前备份的 CONTROL FILE(里头被 DROP DATAFILE Metadata 此时还存在),不过 RESTOREC CONTROL FILE 后 此时 Oracle 会发现 CONTROL FILE 内的 SYSTEM SCN 会小于目前的 DATAFILE HEADER SCN, 也不等于目前储存于 LOG FILE 内的 SCN, 此时就必须使用 RECOVER DATABASE UNTIL CANCEL USING BACKUP CONTROLFILE 到 DROP DATAFILE OR DROP TABLESPACE 之前的 SCN。 1.21 用户 对 表空间配额(quota )说明 1.21.1 官网的说明 Oracle 官网对 quota 的定义如下: A limit on a resource, such as a limit on the amount of database storage used by a database user. A database administrator can set tablespace quotas for each Oracle Database username. 有关 Oracle Quota 这块,只在 Oracle 的安全管理这块搜到了一些内容。 Managing Security for Oracle Database Users http://download.oracle.com/docs/cd/E11882_01/network.112/e16543/users.htm# DBSEG10220 1.21.1.1 Assigning a Tablespace Quota for the User You can assign each user a tablespace quota for any tablespace (except a temporary tablespace). Assigning a quota accomplishes the following: (1)Users with privileges to create certain types of objects can create those objects in the specified tablespace. (2)Oracle Database limits the amount of space that can be allocated for storage of a user's objects within the specified tablespace to the amount of the quota. By default, a user has no quota on any tablespace in the database. If the user has the privilege to create a schema object, then you must assign a quota to allow the user to create objects. At a minimum, assign users a quota for the default tablespace, and additional quotas for other tablespaces in which they can create objects. The following CREATE USER statement assigns the following quotas for the test_ts and data_ts tablespaces: CREATE USER jward Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 IDENTIFIED BY password DEFAULT TABLESPACE data_ts QUOTA 100M ON test_ts QUOTA 500K ON data_ts TEMPORARY TABLESPACE temp_ts PROFILE clerk; -- 在创建用户的时候,就指定用户在特定表空间上的配额 You can assign a user either individual quotas for a specific amount of disk space in each tablespace or an unlimited amount of disk space in all tablespaces. Specific quotas prevent a user's objects from using too much space in the database. -- 配额的指定可以禁止用户的对象使用过多的表空间 You can assign quotas to a user tablespace when you create the user, or add or change quotas later. (You can find existing user quotas by querying the USER_TS_QUOTAS view.) 。 If a new quota is less than the old one, then the following conditions remain true: (1)If a user has already exceeded a new tablespace quota, then the objects of a user in the tablespace cannot be allocated more space until the combined space of these objects is less than the new quota. (2)If a user has not exceeded a new tablespace quota, or if the space used by the objects of the user in the tablespace falls under a new tablespace quota, then the user's objects can be allocated space up to the new quota. 1.21.1.2 Restricting the Quota Limits for User Objects in a Tablespace You can restrict the quota limits for user objects in a tablespace by using the ALTER USER SQL statement to change the current quota of the user to zero. After a quota of zero is assigned, the objects of the user in the tablespace remain, and the user can still create new objects, but the existing objects will not be allocated any new space. For example, you could not insert data into one of this user's exiting tables. The operation will fail with an ORA-1536 space quota exceeded for tables error. 1.21.1.3 Granting Users the UNLIMITED TABLESPACE System Privilege To permit a user to use an unlimited amount of any tablespace in the database, grant the user the UNLIMITED TABLESPACE system privilege. This overrides all explicit tablespace quotas for the user. If you later revoke the privilege, then you must explicitly grant quotas to individual tablespaces. You can grant this privilege only to users, not to roles. Before granting the UNLIMITED TABLESPACE system privilege, you must consider the consequences of doing so. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Advantage: You can grant a user unlimited access to all tablespaces of a database with one statement. Disadvantages: (1)The privilege overrides all explicit tablespace quotas for the user. (2)You cannot selectively revoke tablespace access from a user with the UNLIMITED TABLESPACE privilege. You can grant selective or restricted access only after revoking the privilege. 1.21.1.4 Listing All Tablespace Quotas Use the DBA_TS_QUOTAS view to list all tablespace quotas specifically assigned to each user. For example: SELECT * FROM DBA_TS_QUOTAS; TABLESPACE USERNAME BYTES MAX_BYTES BLOCKS MAX_BLOCKS ---------- --------- -------- ---------- ------- ---------- USERS JFEE 0 512000 0 250 USERS DCRANNEY 0 -1 0 -1 When specific quotas are assigned, the exact number is indicated in the MAX_BYTES column. This number is always a multiple of the database block size, so if you specify a tablespace quota that is not a multiple of the database block size, then it is rounded up accordingly. Unlimited quotas are indicated by -1. 1.21.2 Quota 说明 配额大小指的是用户指定使用表空间的的大小。在 1.1 节里提到,默认情况 下,用户对所有表空间都是没有配额的,即不受空间的限制。 查看几个用户的 创建脚本来验证一下: CREATE USER SYSTEM IDENTIFIED BY DEFAULT TABLESPACE SYSTEM Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 TEMPORARY TABLESPACE TEMP PROFILE DEFAULT ACCOUNT UNLOCK; -- 2 Roles for SYSTEM GRANT AQ_ADMINISTRATOR_ROLE TO SYSTEM WITH ADMIN OPTION; GRANT DBA TO SYSTEM WITH ADMIN OPTION; ALTER USER SYSTEM DEFAULT ROLE ALL; -- 5 System Privileges for SYSTEM GRANT GLOBAL QUERY REWRITE TO SYSTEM; GRANT CREATE MATERIALIZED VIEW TO SYSTEM; GRANT CREATE TABLE TO SYSTEM; GRANT UNLIMITED TABLESPACE TO SYSTEM WITH ADMIN OPTION; GRANT SELECT ANY TABLE TO SYSTEM; CREATE USER DAVE IDENTIFIED BY DEFAULT TABLESPACE USERS TEMPORARY TABLESPACE TEMP PROFILE DEFAULT ACCOUNT UNLOCK; -- 2 Roles for DAVE GRANT CONNECT TO DAVE; GRANT RESOURCE TO DAVE; ALTER USER DAVE DEFAULT ROLE ALL; -- 1 System Privilege for DAVE GRANT UNLIMITED TABLESPACE TO DAVE; 从这 2 个脚本来看,默认情况下,都会对用户赋 unlimited tablespace 的权限。 这是是在创建的时候指定的,当我们的用户创建好之后,我们也可以修改用户的 配额。 1.21.2.1. 创建用户时,指定限额 SQL> conn / as sysdba; Connected. SQL> create user anqing identified by anqing default tablespace users temporary tablespace temp quota 10M on users; User created. 查询用户配额的信息: SQL> select tablespace_name,username,max_bytes from DBA_TS_QUOTAS where username='ANQING'; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 TABLESPACE_NAME USERNAME MAX_BYTES ------------------------------ ---------- ---------- USERS ANQING 10485760 1.21.2.2.更改用户的表空间限额: 不对用户做表空间限额控制: SQL> grant unlimited tablespace to anqing; Grant succeeded. 这种方式是全局性的. 即修改用户多所有表空间的配额。 如果我们想改某个具体的,即针对用户的某个特定的表空间,可以使用如下 SQL: SQL> alter user anqing quota unlimited on users; User altered. 查看配额: SQL> select tablespace_name,username,max_bytes from DBA_TS_QUOTAS where username='ANQING'; TABLESPACE_NAME USERNAME MAX_BYTES ------------------------------ ---------- ---------- USERS ANQING -1 这时候 max_bytes 为-1,即不受限制。 1.21.2.3. 回收用户对表空间的配额: 同样两种方式, 全局: SQL> revoke unlimited tablespace from anqing; Revoke succeeded. 在查看配额,已经没有了相关信息: SQL> select tablespace_name,username,max_bytes from DBA_TS_QUOTAS where username='ANQING'; no rows selected 针对某个特定的表空间: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL> alter user anqing quota 0 on users; User altered. 1.22 Oracle DB 服务器 系统时间修改问题 与 SCN 关系的研究 论坛里一个朋友说将 DB 服务器系统时间往往后修改了 3 个月(从 11 年改 成 10 年),启动 DB 报 600 的错误。 1.22.1 先做个测试 1.22.1.1 关闭 DB SQL> shutdown immediate Database closed. Database dismounted. ORACLE instance shut down. 1.22.1.2 修改系统时间 1.22.1.2.1 现在时间 [root@singledb ~]# date Tue Jan 25 11:05:32 EST 2011 1.22.1.2.2 修改时间 将时间往前调整一下: [root@singledb ~]# date -s 1/1/2011 Sat Jan 1 00:00:00 EST 2011 [root@singledb ~]# date Sat Jan 1 00:00:22 EST 2011 1.22.1.3 启动 DB SQL> startup ORACLE instance started. Total System Global Area 360710144 bytes Fixed Size 1219424 bytes Variable Size 117441696 bytes Database Buffers 239075328 bytes Redo Buffers 2973696 bytes Database mounted. Database opened. 启动并没有问题,也没有遇到网友的 600 错误。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.22.2 修改系统时间与 SCN 关系 有关 SCN 的信息,参考 1.20 小节。 通过前面的分析,可以看出修改系统时间和 SCN 没有直接的关系。在第一 节中也做了测试。 对于 DB 服务器如何修改时间: (1)停止应用 (2)停止数据库 (3)修改时间 不过,如果不是特殊情况,不建议修改。稳定第一。尤其是 RAC 环境,对 时间要求更严格。 在这里说了,修改系统时间和 SCN 没有直接影响,但我在测试中,发现他 们是有联系的。 SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss'; Session altered. SQL> select sysdate from dual; SYSDATE ------------------- 2010-01-01 01:21:58 SQL> select * from ( select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss') time from sys.smon_scn_time order by 2 desc) where rownum<10; SCN TIME ---------- ------------------- 943223 2012-01-01 02:43:33 943058 2012-01-01 02:38:14 942811 2012-01-01 02:33:02 922652 2012-01-01 00:01:52 922182 2012-01-01 00:00:45 920862 2011-01-25 11:46:21 920717 2011-01-25 11:41:17 920571 2011-01-25 11:36:38 919996 2011-01-25 11:31:21 9 rows selected. SQL> select dbms_flashback.get_system_change_number from dual; GET_SYSTEM_CHANGE_NUMBER ------------------------ 945394 从上面的几个查询结果我们发现二个问题: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 (1)smon_scn_time 表中的 SCN(943223) 小于系统当前的 SCN 值(945394)。 (2)smon_scn_time 表中最后更新时间(2012-01-01 02:43:33)大于系统当前时 间(2010-01-01 01:21:58)。 由此我们推出一个结论:当 smon_scn_time 最后更新时间大于系统时间时, SMON 不会将 SCN 与 TIMESTAMP 的映射结果写入到 sys.smon_scn_time 表中。 如果 SCN 与 TIMESTAMP 的映射不能写入到 smon_scn_time 表中,我们就 不能进行 SCN 与 TIMESTAMP 转换,就不能利用 timestamp 进行相关的操作, 如恢复。参考: Oracle 不同故障的恢复方案 http://blog.csdn.net/tianlesoftware/archive/2010/12/30/6106178.aspx 为了验证上面的结论,我们把系统改成大于 smon_scn_time 最后更新时间。 SQL> select sysdate from dual; SYSDATE ------------------- 2012-02-01 00:00:16 SQL> select dbms_flashback.get_system_change_number from dual; GET_SYSTEM_CHANGE_NUMBER ------------------------ 946462 SQL> select * from ( select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss') time from sys.smon_scn_time order by 2 desc) where rownum<10; SCN TIME ---------- ------------------- 945872 2012-02-01 00:00:51 943223 2012-01-01 02:43:33 943058 2012-01-01 02:38:14 942811 2012-01-01 02:33:02 922652 2012-01-01 00:01:52 922182 2012-01-01 00:00:45 920862 2011-01-25 11:46:21 920717 2011-01-25 11:41:17 920571 2011-01-25 11:36:38 这次成功写入 smon_scn_time 表。由此可见: (1)系统时间往后改(如从 2011 年改到 2012 年),对 DB 没有影响,可能某 些应用可能会受影响。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 (2)系统时间往前改(如从 2011 年改到 2010 年),那么 SMON 不会将 SCN 与 timestamp 写入 smon_scn_time 表。 所以对于生产系统,在系统上线之前就应该校队好系统时间,本着稳定第一 的原则,上线之后就不建议在修改 DB 服务器的时间了。 1.23 Oracle 10g Scheduler 特性 Blog: http://blog.csdn.net/tianlesoftware/archive/2009/10/22/4715218.aspx Scheduler 可以简单简单的帮助我们调度成百上千的 tasks。Oracle Scheduler 通过在 DBMS_SCHEDULER PL/SQL 包中存储和过程来执行。 1.23.1 使用 Jobs JOBS,其实就是 Scheduler 管理的一个(或多个)任务的执行调度。 1.23.1.1 创建 Jobs 通过 DBMS_SCHEDULER 包来创建 Jobs,是使用其 CREATE_JOB 过程。在 创建 Job 时,用户可以指定要执行的任务,调度信息(什么时候执行,执行周期, 终止日期等)以及其它一些任务相关的属性。例如: create table TEST (id number); CREATE OR REPLACE PROCEDURE IT AS BEGIN insert into TEST VALUES(1); END; SQL> BEGIN DBMS_SCHEDULER.CREATE_JOB ( job_name => 'JobTest', job_type => 'STORED_PROCEDURE', job_action => 'SYSTEM.IT', start_date => sysdate, repeat_interval => 'FREQ=MINUTELY;INTERVAL=10'); END; / 事实上,有权限的话,用户也可以创建其它 SCHEMA 下的 JOB,只需要在 指定JOB_NAME 时,按照schema.job_name 的格式即可。这种情况下创建的JOB, 其 CREATED 与 OWNER 有可能并不相同。当使用 CREATE_JOB 过程创建 JOB 时,可指定的参数值很多,只不过多数情况下用户仅指定部分参数即可满足Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 需求。 其中,上例中指定的参数,分别代表的含义如下: JOB_NAME:指定任务的名称,必选值,注意要确保指定的名称唯一。 JOB_TYPE:任务执行的操作类型,必选值,有下列几个可选值: (1) PLSQL_BLOCK:表示任务执行的是一个 PL/SQL 匿名块。 ( 2 )STORED_PROCEDURE : 表 示 任 务 执 行 的 是 ORACLE 过程( 含 L/SQL PROCEDURE 和 JAVA PROCEDURE),本例中正是指定这一参数值。 (3)EXECUTABLE:表示任务执行的是一个外部程序,比如说操作系统命令。 (4)CHAIN:表示任务执行的是一个 CHAIN。 JOB_ACTION:任务执行的操作,必选值,应与 JOB_TYPE 类型中指定的参数 相匹配。比如说对于 PL/SQL 匿名块,此处就可以放置 PL/SQL 块的具体代表, 类似 DECLARE .. BEGIN ..END 这类;如果是 ORACLE 过程,那么此处应该指 定具体的过程名,注意由于任务执行,即使过程中有 OUT 之类参数,实际执行 时也不会有输出的。 START_DATE:指定任务初次执行的时间,本参数可为空,当为空时,表示任务 立刻执行,效果等同于指定该参数值为 SYSDATE。 REPEAT_INTERVAL:指定任务执行的频率,比如多长时间会被触发再次执行。 本参数也可以为空,如果为空的话,就表示当前设定的任务只执行一次。 REPEAT_INTERVAL 参数与标准 JOB 中的 INTERVAL 参数有很大区别,相比之 下,REPEAT_INTERVAL 参数的语法结构要复杂的多。其中最重要的是 FREQ 和 INTERVAL 两个关键字。 ( 1 ) FREQ 关键字用来指定间隔的时间周期,可选参数有: YEARLY, MONTHLY, WEEKLY, DAILY,HOURLY, MINUTELY, and SECONDLY, 分别表示年、月、周、日、时、分、秒等单位。 (2)INTERVAL 关键字用来指定间隔的频繁,可指定的值的范围从 1-99。 例如:REPEAT_INTERVAL=>'FREQ=DAILY;INTERVAL=1';表示每天执行一次, 如果将 INTERVAL 改为 7 就表示每 7 天执行一次,效果等同于 FREQ=WEEKLY;INTERVAL=1。 一般来说,使用 DBMS_SCHEDULER.CREATE_JOB 创建一个 JOB,至少需 要指定上述参数中的前 3 项。除此之外,还可以在 CREATE_JOB 时,指定下列 参数: (1)NUMBER_OF_ARGUMENTS:指定该 JOB 执行时需要附带的参数的数量, 默认值为 0,注意当 JOB_TYPE 列值为 PLSQL_BLOCK 或 CHAIN 时,本参数 必须设置为 0,因为上述两种情况下不支持附带参数。 (2)END_DATE:指定任务的过期时间,默认值为 NULL。任务过期后,任务 的 STATE 将自动被修改为 COMPLETED,ENABLED 被置为 FALSE。如果该参 数设置为空的话,表示该任务永不过期,将一直按照 REPEAT_INTERVAL 参数 设置的周期重复执行,直到达到设置的 MAX_RUNS 或 MAX_FAILURES 值。 (3)JOB_CLASS:指定任务关联的 CLASS,默认值为 DEFAULT_JOB_CLASS。 (4)ENABLED:指定任务是否启用,默认值为 FALSE。FALSE 状态表示该任 务并不会被执行,除非被用户手动调用,或者用户将该任务的状态修改为 TRUE。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 (5)AUTO_DROP:当该标志被置为 TRUE 时,ORACLE 会在满足条件时自动 删除创建的任务 1)任务已过期; 2)任务最大运行次数已达 MAX_RUNS 的设置值; 3)任务未指定 REPEAT_INTERVAL 参数,仅运行一次; 该参数的默认值即为 TRUE。用户在执行 CREATE_JOB 过程时可以手动将 该标志指定为 FALSE,当参数值设置为 FALSE 时,即使满足上述提到的条件任 务也不会被自动删除,这种情况下,唯一能够导致任务被删除的情况,就是用户 主动调用 DROP_JOB 过程。 (6)COMMENTS:设置任务的注释信息,默认值为 NULL。 上面的例子创建了一个新的 JOB,不过这个 JOB 与普通 JOB 不同,此时查 询 USER_JOBS 视图是查不到刚刚创建的 JOB 的信息,因为这个 JOB 是 SCHEDULER 管理的 JOB。要查询 SCHEDULER 管理的 JOBS,应该通过 user_scheduler_jobs(all_scheduler_jobs,dba_scheduler_jobs 也可以 ), 例如: SQL> select job_name,job_type,job_action,to_char(start_date,'yyyy-mm-dd hh24:mi:ss') TM,repeat_interval,enabled,state from user_scheduler_jobs; JOB_NAME JOB_TYPE JOB_ACTION TM REPEAT_INTERVAL ENABL STATE ---------- ---------------- ---------- ---------- ------------------------- ------ ------ JOBTEST STORED_PROCEDURE SYSTEM.IT 2009-09-25 FREQ=MINUTELY ;INTERVAL=10 FALSE DISABLED 注意:JOB 虽然成功创建了,但却并未执行.因为 ENABLED 参数当不显式 指定时,该参数的默认值为 false。 1.23.1.2 管理 Jobs 1.23.1.2.1 启用 Jobs 前面创建 JOB 时,由于未显式的指定 ENABLED 参数,因此即使指定了 START_DATE , 不 过 默 认 情 况 下 JOB 不会自动执行。对于这种情况, DBMS_SCHEDULER 包中提供了一个过程 ENABLE,可以用来修改 JOB 的启 用状态,调用方式非常简单,例如: SQL> exec dbms_scheduler.enable('JOBTEST'); PL/SQL procedure successfully completed. 1.23.1.2.2 禁用 Jobs DBMS_SCHEDULER.ENABLE 仅用来将 JOB(其实不仅仅对 JOB 有效,对于 CHAIN、PROGRAM 等也有效)的启用状态置为 TRUE。如果想将其启用状态置 为 FALSE,还有一个与该功能对应的过程:DBMS_SCHEDULER.DISABLE,如: SQL> exec dbms_scheduler.disable('JOBTEST'); Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 PL/SQL procedure successfully completed. 这两个过程仅用来重置对象的状态,因此均可以无限次执行,即使执行时对 象已经被置为要指定的状态。 1.23.1.2.3 修改 Jobs 由于 JOB 的属性众多,难免可能会遇到需要修改的情况,比如说前面创建 JOB 时不小心,指定要执行的过程名输入错误(CREATE_JOB 在创建时不会自动 检查指定的过程是否有效),这种情况下就必然涉及到对 JOB 的修改(或者说重定 义),DBMS_SCHEDULER 包中专门提供了一个过程 SET_ATTRIBUTE,可以用 来修改任务的属性值。 例如,修改刚刚创建的 JOB:INSERT_TEST_TBL 执行的过程,执行语句如下: SQL> exec dbms_scheduler.set_attribute('JobTest','JOB_ACTION','SYSTEM.IT'); PL/SQL procedure successfully completed SET_ATTRIBUTE 过程虽然仅有三个参数,不过能够修改的属性值可是不 少,以下列举几个较常用到的: ( 1 ) LOGGING_LEVEL: 指定对 jobs 执行情况记录的日志信息级别。 SCHEDULER 管理的 JOB 对任务的执行情况专门进行了记录,同时用户还可以 选择日志中记录信息的级别,有下列三种选择: 1)DBMS_SCHEDULER.LOGGING_OFF:关闭日志记录功能; 2) DBMS_SCHEDULER.LOGGING_RUNS:对任务的运行信息进行记录; 3) DBMS_SCHEDULER.LOGGING_FULL:记录任务所有相关信息,不仅 有任务的运行情况,甚至连任务的创建、修改等也均将记入日志。 提示: 查看 scheduler 管理的 job , 可以通过 user_scheduler_job_log 和 user_scheduler_job_run_details 两个视图中查询。 (2) RESTARTABLE:指定 jobs 运行出错后,是否能够适时重启创建任务时如 未明确指定,本参数默认情况下设置为 FALSE,如果设置为 TRUE,就表示当任 务运行时出错,下次运行时间点到达时仍会启动,并且如果运行仍然出错,会继 续重新运行,不过如果连接出错达到 6 次,该 job 就会停止。 (3) MAX_FAILURES:指定 jobs 最大连续出错次数该参数值可指定的范围从 1-1000000,默认情况下该参数设置为 NULL,表示无限制。达到指定出错次数 后,该 job 会被自动 disable。 (4) MAX_RUNS:指定 jobs 最大运行次数,该参数值可指定的范围从 1-1000000,默认情况下该参数设置为 NULL,表示无限制(只是运行次数无限制, 实际 job 是否继续运行,仍受制于 end_date 以及 max_failures 等参数的设置)。达 到指定运行次数后,该 job 也将被自动 disable,并且状态会被置为 COMPLETED。 ( 5 ) JOB_TYPE : 指定 job 执 行 的 任 务 的 类 型 , 有 四 个 可 选 值 : 'PLSQL_BLOCK', 'STORED_PROCEDURE', 'EXECUTABLE', and 'CHAIN'。 (6) JOB_ACTION :指定 job 执 行 的 任 务.这一参数所指定的值依赖于 JOB_TYPE 参数中的值, 比如说 JOB_TYPE 设置为'STORED_PROCEDURE', 那么本参数值中指定的一定是 ORACLE 中的过程名。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 (7) START_DATE:指定 job 初次启动的时间 (8)END_DATE:指定 job 停止运行的时间 本参数又与 AUTO_DROP 相关联,如果 AUTO_DROP 设置为 TRUE 的话, 那么一旦 job 到达停止运行的时间,该 job 就会被自动删除,否则的话 job 任何 存在,不过状态被修改为 COMPLETED。 除此之外, 其它还包括 max_run_duration , job_weight , instance_stickiness , stop_on_window_close , job_priority , schedule_limit , program_name , number_of_arguments , schedule_name , repeat_interval , job_class , comments , auto_drop,event_spec,raise_events 等等。 另外需要注意一点,除了用户手动创建的 jobs 之外,数据库在运行过程中也 有可能自动创建 jobs。对于这类 jobs 除非必要,否则不建议进行修改。至于如何 区分 jobs 是用户创建,还是数据库自动创建,可以通过*_SCHEDULER_JOBS 视 图的 SYSTEM 列来确定,如果该列显示为 TRUE,则表示由系统创建。 1.23.1.2.4 执行 Jobs 虽然说 jobs 大多都应该是自动执行,不过经过前面的示例看出,并不是说创 建了 jobs 它就会自动执行,是否能够真正自动执行由 jobs 自身的多个相关属性 决定。 可以使用 DBMS_SCHEDULER 包手动调用 jobs 并执行。如: SQL> exec dbms_scheduler.run_job('JOBTEST'); PL/SQL procedure successfully completed jobs 每执行一次,无论成功或失败,均会在*_scheduler_job_log 中生成一条 对 应 的 记 录 ( 前提是 logging_level 属 性 值 未 设 置 为 dbms_scheduler.logging_off) , 同 时 , 用 户 也 可 以 通 过 *_scheduler_job_run_details 视图查询 job 执行的详细信息。 1.23.1.2.5 停止 Jobs 停止 job 可以使用 DMBS_SCHEDULER.STOP_JOB 过程,例如: SQL> exec dbms_scheduler.stop_job('JOBTEST'); PL/SQL procedure successfully completed 注意,STOP_JOB 过程不仅仅是更新 job 的状态,而是停止当前正在执行的 任务,如果你处理的任务当前未在运行的话,那么执行 STOP_JOB 过程,会触 发 ORA-27366 错误。 停止 Jobs 也会触发一条任务的日志信息,对于执行停止操作的 job,其 *_SCHEDULER_JOB_LOG 视图的 OPERATION 会记录为'STOPPED' , ADDITIONAL_INFO 列 中 记 录 的 信 息 类 似 'REASON="Stop job called by user:username"'。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.23.1.2.6 删除 Jobs 删除创建的 job 就比较简单了,直接执行 dbms_scheduler.drop_job 过程即可, 例如: SQL> exec dbms_scheduler.drop_job('JOBTEST'); PL/SQL procedure successfully completed 删除 jobs 并不是修改该 job 中某个字段的标记值,而是直接删除其在数据字 典中的字义,因此被删除的 job 如果未来发现仍然需要,只能重建,而无法通过 其它方式快速恢复。不过,删除 jobs 的操作,并不会级联删除这些 job 曾经执行 过的日志信息。 1.23.2 使用 Programs 进入 10g 版本之后,可以在 ORACLE 中执行操作系统命令,或是 ORACLE 数 据库外的应用,因为有了 DBMS_SCHEDULER,因为有了 PROGRAM。 1.23.2.1 创建 Programs Scheduler 中的 Program 对象并不是常规意义上的"程序"或"应用",而就是一 个"对象",由 DBA 定义的,具有执行某项功能的特殊对象。Program 中实际执行 的操作可以分为下列三种类型: (1) PL/SQL BLOCK:标准的 pl/sql 代码块; (2) STORED PROCEDURE:编译好的 PL/SQL 存储过程,或者 Java 存储过程, 以及外部的子程序; (3) EXECUTEABLE:ORACLE 数据库之外的应用,比如操作系统命令等等。 创建 Programs 使用 DBMS_SCHEDULER.CREATE_PROGRAM 过程,该过 程支持的参数如下: SQL> desc dbms_scheduler.create_program; Parameter Type Mode Default ------------------- -------------- ---- -------- PROGRAM_NAME VARCHAR2 IN PROGRAM_TYPE VARCHAR2 IN PROGRAM_ACTION VARCHAR2 IN NUMBER_OF_ARGUMENTS BINARY_INTEGER IN Y ENABLED BOOLEAN IN Y COMMENTS VARCHAR2 IN Y 如上所示,前三项为必选参数,各参数实际代表的意义如下: (1) PROGRAM_NAME:指定一个 program 名称; (2) PROGRAM_TYPE:Program 的类型,如前文中所述,Program 支持三种类 型; (3) PROGRAM_ACTION:实际执行的操作,应与前面 PROGRAM_TYPE 参 数关联使用。比如说前面指定了 PROGRAM_TYPE 为"PLSQL_BLOCK",那么Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 此处要执行的 action 就 应 当 是 一 段 标 准 的 pl/sql 代 码 。 如 果 前 面 指 定 PROGRAM_TYPE 为"STORED_PROCEDURE",那么此处要执行的 action 就应 当是 ORACLE 中 定 义 好 的 存 储 过 程 (含 Java 存储过程), 如 果 前 面 指 定 PROGRAM_TYPE 为"EXECUTABLE",那么此处就应该指定外部命令的命令行 信息(含路径信息); (4)NUMBER_OF_ARGUMENTS:指定支持的参数个数,默认值为 0 即没有 参数。每个 program 最多能够 支持 255 个参数,注意如果 PROGRAM_TYPE 设置为 PLSQL_BLOCK,那么本 参数自动忽略; (5) ENABLED:指定是否将创建的 program 置为有效状态,默认情况下为 false。 (6) COMMENTS:这个不用再说了吧,注释信息。 下面实际操作一下看看,PL/SQL 或 PROCEDURE 没有挑战(ORACLE 中直 接即可调用),咱们创建一下 program,直接调用操作系统中的 ipconfig 命令,操 作如下: SQL> BEGIN DBMS_SCHEDULER.CREATE_PROGRAM ( program_name => 'IPCONFIG', program_action => 'C:\WINDOWS\system32\ipconfig.exe', program_type => 'EXECUTABLE', enabled => TRUE); END; / PL/SQL procedure successfully completed. 1.23.2.2 管理 Programs CREATE_PROGRAM 过程的参数时提到,每个 program 最多支持 255 个参 数,要为 program 添加参数,可以通过 DEFINE_PROGRAM_ARGUMENT 过程。 不过在为其添加参数前,要注意 program 的 NUMBER_OF_ARGUMENTS 指定 的数量,如果该值为 0,那么为其添加参数时就会报错。 查询创建的 program 的信息,可以通过 USER_SCHEDULER_PROGRAMS 视 图,例如: SQL> select program_name,program_type,program_action,number_of_arguments,en abled from user_scheduler_programs; 由于前面创建 program 时並未指定 NUMBER_OF_ARGUMENTS 的值,因此 我们这里需要首先修改该值为一个非 0 值,操作如下: SQL> exec dbms_scheduler.set_attribute('IPCONFIG','NUMBER_OF_ARGUMENT S',1); PL/SQL procedure successfully completed. 另外需要注意, program 的 NUMBER_OF_ARGUMENTS 参数不是说想改就Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 能改的,正常情况下该处理必须是在 program 处于 enabled 之前确认完毕,否则 会触发 ORA-27465 错误,因此要修改 program 的参数之前,必须首先确保要修 改 program 的 enabled 状态为 false。 那么对于已经处于 enabled 状态的 program,在修改之前要修改其状态。如: SQL> exec dbms_scheduler.disable('IPCONFIG'); PL/SQL procedure successfully completed. 如果想启用,执行 dbms_scheduler.enable 过程即可。 接下来,就可以为刚刚创建的 IPCONFIG 添加路径参数,操作如下: SQL> BEGIN DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT ( program_name => 'IPCONFIG', argument_position => 1, argument_name => 'dirpath', argument_type => 'VARCHAR2', default_value => 'C:\'); END; / PL/SQL procedure successfully completed. exec DBMS_SCHEDULER.ENABLE('IPCONFIG'); 查询为 program 定义的参数,可以通过 user_scheduler_program_args 视图, 例如: SQL> select program_name,argument_name,argument_position,argument_type default_value from user_scheduler_program_args; 删除 program 的 argument ,使用 drop_program_argument 过程即可,例如: SQL> exec dbms_scheduler.drop_program_argument('IPCONFIG','dirpath'); PL/SQL procedure successfully completed. 该过程第一个参数指定 program 名称,第二个参数指定定义的 argument 名 称,当然此处也可以指定 argument 的位置,即前例视图返回结果中的 ARGUMENT_POSITION 列值。 要删除 program 的话就更简单了,使用 DROP_PROGRAM 过程即可,例如: SQL> exec dbms_scheduler.drop_program('IPCONFIG'); PL/SQL procedure successfully completed. 在删除 program 的同时,也会删除该 program 对应的所有 arguments。 scheduler 中创建 job 时,也可以指定执行外部的程序。scheduler 中的 job 更像是 之前版本继承过来的 jobs,只不过 10g 中 scheduler 管理的 jobs 功能更加强大。Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 programs 与 jobs 不同的是,jobs 是定义好的,定时执行的任务,而 programs 则 是定义好的,等待被执行的对象。 1.23.3 使用 Schedules 10g 中的 SCHEDULER 中新增的概念太多。比如说 jobs,仍然可以理解成之 前版本中的 jobs,不过功能更加强大。 1.23.3.1 创建和管理 Schedules Schedule , 用 来 描 述 job 的 执 行 周 期 。 创 建 schedule 可 以 通 过 dbms_scheduler.create_schedule 过程,该过程支持的参数如下: SQL>desc dbms_scheduler SQL>desc dbms_scheduler.create_schedule; Parameter Type Mode Default? --------------- ------------------------ ---- -------- SCHEDULE_NAME VARCHAR2 IN START_DATE TIMESTAMP WITH TIME ZONE IN Y REPEAT_INTERVAL VARCHAR2 IN END_DATE TIMESTAMP WITH TIME ZONE IN Y COMMENTS VARCHAR2 IN Y 各参数分别代表含意如下: (1)SCHEDULE_NAME:指定 schedule 名称,注意名称不能重复。 (2) START_DATE:指定该调度的开始时间,可为空,当为空时表示该调度暂 不起用。 (3) REPEAT_INTERVAL:指定调度的执行频率或周期。 (4) END_DATE:指定调度的结束时间,可为空,为空时就表示该调度将一直 进行。 (5) COMMENTS:注释信息。 Schedules 中的 REPEAT_INTERVAL 参数和 Jobs 中的 REPEAT_INTERVAL 参数功能完全相同,甚至参数格式也一模一样。其中最重要的是 FREQ 和 INTERVAL 两个关键字。 ( 1 ) FREQ 关键字用来指定间隔的时间周期,可选参数有: YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, and SECONDLY,分别表示年、月、周、日、时、分、秒 等单位。 (2) INTERVAL 关键字用来指定间隔的频繁,可指定的值的范围从 1-99。 比如说, 当指定 REPEAT_INTERVAL=>'FREQ=DAILY;INTERVAL=1';就表示每 天执行一次, 如果将 INTERVAL 改为 7 就表示每 7 天执行一次,效果等同于 FREQ=WEEKLY;INTERVAL=1。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 下面,创建一个 schedule,指定调度为每周一次的频率,执行脚本如下: SQL> BEGIN DBMS_SCHEDULER.CREATE_SCHEDULE ( schedule_name => 'MySchedule', start_date => SYSDATE, repeat_interval => 'FREQ=WEEKLY; INTERVAL=1', comments => 'Every 1 weeks'); END; / 查询当前已经创建的 schedules,可以通过*_SCHEDULER_SCHEDULES 视 图(含 DBA_,ALL_,USER_),例如,查看当前用户拥有的 schedules,执行语句如 下: SQL> select schedule_name,repeat_interval from user_scheduler_schedules; 如果要修改 schedule 属性的话,也是使用 dbms_scheduler.set_attribute 过程, 该过程的调用方式前面已经多次演示过,对于 schedule 来说,能够修改的属性包 括:repeat_interval、comments、end_date、start_date 以及 event_spec。 删除 schedule,执行 DBMS_SCHEDULER.DROP_SCHEDULE 过程即可,如: sql> exec dbms_scheduler.drop_schedule('my_first_schedule'); pl/sql procedure successfully completed. 1.23.3.2 Schedules 调度 Programs 执行的 Jobs 通过 schedule 调度 program 的执行的 job。下面我们通过实例来演示,如何 创建通过 schedule 调度 program 的执行的 job 。 1. 我们用前面创建的 Program: IPCONFIG,执行操作系统命令 ipconfig。 2. 用我们刚创建的 schedule:MySchedule 3. 创建 job,按照指定的 schedule,执行 program,操作如下: SQL> BEGIN DBMS_SCHEDULER.CREATE_JOB ( job_name => 'ExecCmd', program_name => 'IPCONFIG', schedule_name => 'MySchedule', enabled => true); END; / 创建 job 时,start_date,repeat_interval,job_action 等均无须指定,因为这些参 数将由 program 和 schedule 来控制。这样,操作完成后,ORACLE 就会自动定 时(当前设置为每周执行一次)program 中定义的操作。 要查看当前的执行情况,通过*_scheduler_job_run_details 即可查询Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 (*_scheduler_job_log 也可以,不过该视图中信息不如 detail 中全面)。例如,查看 刚刚创建的"ExecCmd"任务的执行情况,执行命令如下: SQL> select log_id,log_date,status,additional_info from user_scheduler_job_run_deta ils where job_name = 'ExecCmd'; 1.23.3.3 设置 Repeat Interval Job 和 Schedule 中 REPEAT_INTERVAL 参数都是用来控制执行的频率或周 期,虽然说周期是一个时间性概念,不过 REPEAT_INTERVAL 指定的时候并不 是一个时间值,而是由一组关键字描述的时间。 除了前面介绍 Job 和 Schedule 的 REPEAT_INTERVAL 参数时,提到该参数 拥有 FREQ 以及 INTERVAL 两个关键字,其实除此之外,还有如 BYMONTH、 BYWEEKNO、BYYEARDAY、BYDATE 等等参数,可以用来进行更精确的定义, 比如通过 BYMONTH 关键字指定调度运行的月份,BYDAY 指定调度在哪天运 行等等。 REPEAT_INTERVAL 参数的详细语法如下: repeat_interval = regular_schedule | combined_schedule ============================== regular_schedule = frequency_clause [";" interval_clause] [";" bymonth_clause] [";" byweekno_clause] [";" byyearday_clause] [";" bydate_clause] [";" bymonthday_clause] [";" byday_clause] [";" byhour_clause] [";" byminute_clause] [";" bysecond_clause] [";" bysetpos_clause] [";" include_clause] [";" exclude_clause] [";" intersect_clause][";" periods_clause] [";" byperiod_clause] ============================== combined_schedule = schedule_list [";" include_clause] [";" exclude_clause] [";" intersect_clause] frequency_clause = "FREQ" "=" ( predefined_frequency | user_defined_frequency ) predefined_frequency = "YEARLY" | "MONTHLY" | "WEEKLY" | "DAILY" | "HOURLY" | "MINUTELY" | "SECONDLY" user_defined_frequency = named_schedule ============================== interval_clause = "INTERVAL" "=" intervalnum intervalnum = 1 through 99 bymonth_clause = "BYMONTH" "=" monthlist monthlist = monthday ( "," monthday)* month = numeric_month | char_month numeric_month = 1 | 2 | 3 ... 12 char_month = "JAN" | "FEB" | "MAR" | "APR" | "MAY" | "JUN" | "JUL" | "AUG" | "SEP" | "OCT" | "NOV" | "DEC" byweekno_clause = "BYWEEKNO" "=" weeknumber_list weeknumber_list = weeknumber ( "," weeknumber)* Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 weeknumber = [minus] weekno weekno = 1 through 53 byyearday_clause = "BYYEARDAY" "=" yearday_list yearday_list = yearday ( "," yearday)* yearday = [minus] yeardaynum yeardaynum = 1 through 366 bydate_clause = "BYDATE" "=" date_list date_list = date ( "," date)* date = [YYYY]MMDD [ offset | span ] bymonthday_clause = "BYMONTHDAY" "=" monthday_list monthday_list = monthday ( "," monthday)* monthday = [minus] monthdaynum monthdaynum = 1 through 31 byday_clause = "BYDAY" "=" byday_list byday_list = byday ( "," byday)* byday = [weekdaynum] day weekdaynum = [minus] daynum daynum = 1 through 53 /* if frequency is yearly */ daynum = 1 through 5 /* if frequency is monthly */ day = "MON" | "TUE" | "WED" | "THU" | "FRI" | "SAT" | "SUN" byhour_clause = "BYHOUR" "=" hour_list hour_list = hour ( "," hour)* hour = 0 through 23 byminute_clause = "BYMINUTE" "=" minute_list minute_list = minute ( "," minute)* minute = 0 through 59 bysecond_clause = "BYSECOND" "=" second_list second_list = second ( "," second)* second = 0 through 59 bysetpos_clause = "BYSETPOS" "=" setpos_list setpos_list = setpos ("," setpos)* setpos = [minus] setpos_num setpos_num = 1 through 9999 ============================== include_clause = "INCLUDE" "=" schedule_list exclude_clause = "EXCLUDE" "=" schedule_list intersect_clause = "INTERSECT" "=" schedule_list schedule_list = schedule_clause ("," schedule_clause)* schedule_clause = named_schedule [ offset ] named_schedule = [schema "."] schedule periods_clause = "PERIODS" "=" periodnum byperiod_clause = "BYPERIOD" "=" period_list period_list = periodnum ("," periodnum)* periodnum = 1 through 100 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 ============================== offset = ("+" | "-") ["OFFSET:"] duration_val span = ("+" | "-" | "^") "SPAN:" duration_val duration_val = dur-weeks | dur_days dur_weeks = numofweeks "W" dur_days = numofdays "D" numofweeks = 1 through 53 numofdays = 1 through 376 minus = "-" 例如:设置任务仅在周 5 的时候运行: REPEAT_INTERVAL => 'FREQ=DAILY; BYDAY=FRI'; REPEAT_INTERVAL => 'FREQ=WEEKLY; BYDAY=FRI'; REPEAT_INTERVAL => 'FREQ=YEARLY; BYDAY=FRI'; 设置任务隔一周运行一次,并且仅在周 5 运行: REPEAT_INTERVAL => 'FREQ=WEEKLY; INTERVAL=2; BYDAY=FRI'; 设置任务在当月最后一天运行: REPEAT_INTERVAL => 'FREQ=MONTHLY; BYMONTHDAY=-1'; 设置任务在 3 月 10 日运行: REPEAT_INTERVAL => 'FREQ=YEARLY; BYMONTH=MAR; BYMONTHDAY= 10'; REPEAT_INTERVAL => 'FREQ=YEARLY; BYDATE=0310'; 上述两条语句功能相同。 设置任务每 10 隔天运行: REPEAT_INTERVAL => 'FREQ=DAILY; INTERVAL=10'; 设置任务在每天的下午 4、5、6 点时运行: REPEAT_INTERVAL => 'FREQ=DAILY; BYHOUR=16,17,18'; 设置任务在每月 29 日运行: REPEAT_INTERVAL => 'FREQ=MONTHLY; BYMONTHDAY=29'; 设置任务在每年的最后一个周 5 运行: REPEAT_INTERVAL => 'FREQ=YEARLY; BYDAY=-1FRI'; 设置任务每隔 50 个小时运行: REPEAT_INTERVAL => 'FREQ=HOURLY; INTERVAL=50'; 注意:SCHEDULER 中的 REPEAT_INTERVAL 也完全可以按照以前 Job 方 式设置, REPEAT_INTERVAL 实际上是指定周期,直接指定一个时间值,当然Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 也是周期。 比如说,设置任务每天执行一次,也可以设置 REPEAT_INTERVAL 参数值 如下: REPEAT_INTERVAL => 'trunc(sysdate)+1' 又比如设置任务每周执行一次: REPEAT_INTERVAL => 'trunc(sysdate)+7' 不过需要注意,这种方式仅用于创建 SCHEDULER 中 jobs 时使用,不能用 于 schedule。 1.23.4 使用 Events SCHEDULER 中有两种触发 EVENT 的情况: (1) Scheduler 触发的 Events Scheduler 中触发的 Events,一般是说当前 schduler 中 job 的状态发生修改, 类似 job 启动,或者运行结束,或者达到运行时间等诸如此类的动作,都能够抛 出一个 EVENT,接收到 EVENT 的 applicate 就可以根据这些信息进行适当的处 理。 比如说,由于系统太过于繁忙,超出 job 启动时间后 30 分钟,job 仍然没能 顺利启动,那么这个时候,Scheduler 就可以抛出一条 EVENT 给外部的应用,以 便外部应用能够及时通知 DBA,进行处理。 (2) application 触发的 Events 外部的应用也可以触发 Events,并且由 Scheduler 来接收并处理这一类型的 Events。所谓 Scheduler 处理 EVENT 就是指 Scheduler 启动相应的 job 来执行相 关操作,这类 job 在创建时专门声明了 event 的处理,这样当接收到 EVENT 时, 这类 job 就会启动。 Scheduler 使用 Oracle 高级队列来抛出以及销毁 Events。当抛出 Schduler 触 发的 Events 时,Scheduler 将消息入队到默认的 event 队列,application 则通过检 查该队列来处理 Events。当抛出 application 触发的 Events 时,application 将消息 入队到处理 job 对应的队列中。 1.23.4.1 Scheduler 抛出的 Events Scheduler 抛出的 Events 一般是指 job 状态改变时触发的,默认情况下,job 是 不触发 Events 的。 Scheduler 中的 job 有一个属性叫 raise_events,专门用来设置 job 触发 Events 的条件,该属性在 CREATE_JOB 时不能执行,因此默认情况下该属性不 会赋值,自然也就不会触发 EVENT。要设置 raise_events 属性,只能是在 job 创 建完成后,通过 SET_ATTRIBUTE 过程修改 job 的 raise_events 属性。 例如,修改前面创建的 jobtest,启用 raise_events 属性,执行语句如下: sql> begin Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 dbms_scheduler.set_attribute('jobtest', 'raise_events',dbms_scheduler.job_all_events); end; / 上述示例中指定的 raise_events 属性的属性值 dbms_scheduler.job_all_events, 就是抛出 events 的触发条件。 触发 Events 的有下列的类型,分别代表不同的操作: (1)job_started:JOB 启动; (2) job_succeeded:JOB 成功结束; (3) job_failed:JOB 执行失败; (4) job_broken:JOB 被置为 BROKEN 状态; (5) job_completed:JOB 达到最大运行次数,或者运行的结束日期; (6) job_stopped:JOB 被 STOP_JOB 过程置为停止执行的状态; (7) job_sch_lim_reached:Job 的 schedule 达到限定值; (8) job_disabled:JOB 被置于 DISABLE 状态; (9) job_chain_stalled:运行于 chain 的 JOB 被置于 CHAIN_STALLED 状态; (10) job_all_events:含上述提到的所有类型; (11)job_run_completed:由于 Job 运行出错、成功结束或被手动停止。 起用 raise_events 后,Scheduler 就会按照设定的触发条件,当达到触发条件 时,即会抛出事件信息到 SYS.SCHEDULER$_EVENT_QUEUE 队列。 例如,手动执行一次 JOBTEST,看看是否向队列中记录信息,操作如下: SQL> exec dbms_scheduler.run_job('JOBTEST'); PL/SQL procedure successfully completed. 执行下列脚本,出队数据: SQL> set serveroutput on SQL> DECLARE l_dequeue_options DBMS_AQ.dequeue_options_t; l_message_properties DBMS_AQ.message_properties_t; l_message_handle RAW(16); l_queue_msg sys.scheduler$_event_info; BEGIN l_dequeue_options.consumer_name := 'TEST'; DBMS_AQ.dequeue(queue_name => 'SYS.SCHEDULER$_EVENT_QUEUE', dequeue_options => l_dequeue_options, message_properties => l_message_properties, payload => l_queue_msg, msgid => l_message_handle); COMMIT; DBMS_OUTPUT.put_line('event_type : ' || l_queue_msg.event_type); DBMS_OUTPUT.put_line('object_owner : ' || l_queue_msg.object_owner); Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 DBMS_OUTPUT.put_line('object_name : ' || l_queue_msg.object_name); DBMS_OUTPUT.put_line('event_timestamp: ' || l_queue_msg.event_timestamp); DBMS_OUTPUT.put_line('error_code : ' || l_queue_msg.error_code); DBMS_OUTPUT.put_line('event_status : ' || l_queue_msg.event_status); DBMS_OUTPUT.put_line('log_id : ' || l_queue_msg.log_id); DBMS_OUTPUT.put_line('run_count : ' || l_queue_msg.run_count); DBMS_OUTPUT.put_line('failure_count : ' || l_queue_msg.failure_count); DBMS_OUTPUT.put_line('retry_count : ' || l_queue_msg.retry_count); END; / event_type : JOB_STARTED object_owner : TEST object_name : INSERT_TEST_TBL event_timestamp: 25-AUG-09 12.49.29.558758 PM +08:00 error_code : 0 event_status : 1 log_id : run_count : 1 failure_count : 0 retry_count : 0 PL/SQL procedure successfully completed. 从返回的信息可以看到,event 的类型为 JOB_STARTED,表示 JOB 启动。 实际上 job:JOBTEST 执行一次至少会向队列中插入两条 event 信息,一条为 JOB_STARTED,一条则为 JOB_SUCCEEDED(也可能是 JOB_FAILED),这里不 详细演示,感兴趣的朋友不妨自行测试。 提示:sys.scheduler$_event_queue 队列基于 sys.scheduler$_event_qtab 队列表, 因此查询 sys.scheduler$_event_qtab 也可以获取上述的信息。 sys.scheduler$_event_queue 是一个固定队列,实际应用的过程中,dba 应该根 据实际情况,将该表访问权限授予相关用户,以便顺利出队该队列中的 events 信 息。 默认情况下 Scheduler 仅保留最近 24 小时的 Events 信息,如果希望修改该设 置的话,可以通过 SET_SCHEDULER_ATTRIBUTE 过程,修改 scheduler 的 event_expiry_time 属性,该项属性的属性值以秒为单位。 1.23.4.2 Application 抛出的 Events Scheduler 能够抛出 Events 让外部应用处理,外部的应用也可以抛出 Events 让 Scheduler 启动 job 处理,不过并不是任何 job 都能够对外部应用抛出的 Events 做出响应,必须在创建 jobs 时明确指定响应的事件。可以通过如下参数 指定: (1)queue_spec:指定外部应用抛出的 events 消息入队的队列名; (2)event_condition:指定触发 job 启动的条件,这一参数的参数值在设置时应Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 当基于事件消息的自身属性,因为事件消息在入队时,消息的属性都是由 application 定义的,因此在设置触发条件时,也应该根据这些属性值就行设置。 下面,我们就演示创建一个由 event 触发启动的 job,具体的操作步骤如下: SQL> create or replace type Test_type1 as object 2 ( 3 event_type VARCHAR2(10), 4 object_owner VARCHAR2(30), 5 object_name VARCHAR2(30) 6 ); 7 / Type created. SQL> begin 2 dbms_aqadm.create_queue_table( 3 queue_table => 'my_queue_tbl1', 4 queue_payload_type => 'Test_type1', 5 multiple_consumers => true); 6 end; 7 / PL/SQL procedure successfully completed. SQL> begin 2 dbms_aqadm.create_queue( 3 queue_name => 'event_t1', 4 queue_table => 'my_queue_tbl1'); 5 end; 6 / PL/SQL procedure successfully completed. 准备工作完成,下面就来创建一个 event 触发启动的 job,创建脚本如下: SQL> BEGIN 2 DBMS_SCHEDULER.CREATE_JOB ( 3 job_name => 'EVENT_JOB_T1', 4 job_type => 'STORED_PROCEDURE', 5 job_action => 'SYSTEM.IT', 6 event_condition => 'tab.user_data.event_type = ''OP_INSERT''', 7 queue_spec => 'EVENT_T1', 8 enabled => TRUE); 9 END; 10 / PL/SQL procedure successfully completed. 上述脚本仅做演示,因此创建的 job 仍然执行 IT 过程。 通过 pl/sql 直接向 event_t1 队列中添加消息的方式,触发 job 的启动,具体Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 操作如下。 (1)首先要执行 DBMS_AQADM.START_QUEUE 过程,将 event_t1 置于允 许入队和出队状态(默认情况下创建的队列是不允许出队和入队操作的),脚本如 下: SQL> exec dbms_aqadm.start_queue(queue_name => 'event_t1',enqueue => true,deq ueue => true); PL/SQL procedure successfully completed. (2)执行入队操作: SQL> declare v_Message Test_type1; v_EnqueueOptions dbms_aq.enqueue_options_t; v_MessageProperties dbms_aq.message_properties_t; v_msg_handle raw(16); begin v_message := jss_type1('OP_SELECT', user, 'tmpObj'); dbms_aq.enqueue(queue_name => 'event_t1', enqueue_options => v_enqueueOptions, message_properties => v_messageproperties, payload => v_message, msgid => v_msg_handle); commit; end; / PL/SQL procedure successfully completed. (3)查询队列表中的数据: SQL> select user_data from my_queue_tbl1; USER_DATA(EVENT_TYPE, OBJECT_OWNER, OBJECT_NAME) --------------------------------------------------------- JSS_TYPE1('OP_SELECT', 'TEST', 'tmpObj') (4)然后查询 job SQL> select to_char(created,'yyyy-mm-dd hh24:mi:ss') from jss_1; TO_CHAR(CREATED,'YY ------------------- 2009-08-25 12:49:29 看起来 jss_1 表中并未有新增加记录, job 没有执行。因为创建 job 时指定 的 event_condition 条件吗: event_condition => 'tab.user_data.event_type = ''OP_INSERT''', 只有当 event_type 为'OP_INSERT'时才会触发 job 的执行,前面入队时指定的 是 OP_SELECT,当然没有触发 job 中指定的 procedure ,下面再次执行入队操作: SQL> declare v_Message jss_type1; v_EnqueueOptions dbms_aq.enqueue_options_t; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 v_MessageProperties dbms_aq.message_properties_t; v_msg_handle raw(16); begin v_message := jss_type1('OP_INSERT', user, 'tmpObj'); dbms_aq.enqueue(queue_name => 'event_t1', enqueue_options => v_enqueueOptions, message_properties => v_messageproperties, payload => v_message, msgid => v_msg_handle); commit; end; / 再次查看 jss_1 表看看: SQL> select to_char(created,'yyyy-mm-dd hh24:mi:ss') from jss_1; TO_CHAR(CREATED,'YY ------------------- 2009-08-25 12:49:29 2009-08-25 13:21:21 多了一条记录,说明 job 已经被自动触发。 最后再补充一句,基于 event 的 job 不能通过 dbms_scheduler.run_job 过程执 行,否则会触发 ora-00942: table or view does not exist 错误。 1.23.5 使用 Chains CHAIN 可 以 被 视 做 一 组 Programs 的复合,举个简单的例子:运行 PROGRAM:A 以及 PROGRAM:B,如果成功的话继续运行 PROGRAM:C,否则 的话运行 PROGRAM:D。Programs:A、B、C、D 以及执行的逻辑关系就构成了 一个最简单的 CHAIN。 关于 CHAIN 的管理操作比较多,比如创建/删除/修改 Chains,添加/修改/删 除 Chain Steps 等等。 1.23.5.1 创建 Chains 1.23.5.1.1 创建 CHAIN 对象 创建 CHAIN 使用 DBMS_SCHEDULER.CREATE_CHAIN 过程,这个过程调 用非常简单,因为需要指定的参数极少,该过程的定义如下: SQL> desc dbms_scheduler.create_chain; Parameter Type Mode Default? ------------------- ---------------------- ---- -------- CHAIN_NAME VARCHAR2 IN RULE_SET_NAME VARCHAR2 IN Y EVALUATION_INTERVAL INTERVAL DAY TO SECOND IN Y Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 COMMENTS VARCHAR2 IN Y 在创建时,甚至可以简单到只指定一个 CHAIN 的名称,其它均为空即可,例如: SQL> exec dbms_scheduler.create_chain('my_chain1'); PL/SQL procedure successfully completed. 定义好的 Chains,可以通过*_SCHEDULER_CHAINS 视图查看,例如: SQL> select chain_name from user_scheduler_chains; CHAIN_NAME ------------------------------ MY_CHAIN1 1.23.5.1.2 创建 Chain Step Chain Steps 就 是 用 来 指 定 CHAIN 执行的操作及执行步骤, 创建 CHAIN STEP 是通过 DBMS_SCHEDULER.DEFINE_CHAIN_STEP 过程进行,例 如,为刚刚创建的 my_chain1 添加一个 step,执行操作如下: SQL> begin DBMS_SCHEDULER.DEFINE_CHAIN_STEP ( chain_name => 'my_chain1', step_name => 'my_step1', program_name => 'p_p1'); end; / PL/SQL procedure successfully completed. Chain Steps 即可以调用 PROGRAM,也可以调用 EVENT,甚至调用其它 CHAIN(这就叫嵌套 CHAIN)。 下面接着为 my_chain1 添加两个 step,操作如下: SQL> begin DBMS_SCHEDULER.DEFINE_CHAIN_STEP ( chain_name => 'my_chain1', step_name => 'my_step2', program_name => 'p_p2'); DBMS_SCHEDULER.DEFINE_CHAIN_STEP ( chain_name => 'my_chain1', step_name => 'my_step3', program_name => 'p_p3'); end; / PL/SQL procedure successfully completed. 要查询定义的 Chain Steps,则是通过*_SCHEDULER_CHAIN_STEPS 视图,例Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 如: SQL> select chain_name,step_name,program_name from user_scheduler_chain_steps ; CHAIN_NAME STEP_NAME PROGRAM_NAME -------------------- -------------------- -------------------- MY_CHAIN1 MY_STEP1 P_P1 MY_CHAIN1 MY_STEP2 P_P2 MY_CHAIN1 MY_STEP3 P_P3 1.23.5.1.3 创建 Chain Rule 接下来,要为 CHAIN 的运行定义规则。定 义 规 则 是 使 用 DBMS_SCHEDULER.DEFINE_CHAIN_RULE 过 程 , Chain Rules 依赖于 Chain Steps,每个 CHAIN RULE 都拥有 condition 和 action 属 性 , 当 满 足 condition 时则执行 action 中指定的 step。 DBMS_SCHEDULER.DEFINE_CHAIN_RULE 过程的语法如下: SQL> desc dbms_scheduler.define_chain_rule; Parameter Type Mode Default? ---------- -------- ---- -------- CHAIN_NAME VARCHAR2 IN CONDITION VARCHAR2 IN ACTION VARCHAR2 IN RULE_NAME VARCHAR2 IN Y COMMENTS VARCHAR2 IN Y 需要注意的是 CONDITION 和 ACTION 两个参数。在为 condition 参数指定 值时,其语法看起来稍稍复杂一些,或者说是灵活,condition 参数值支持下列的 语法形式: TRUE FALSE stepname [NOT] SUCCEEDED stepname [NOT] FAILED stepname [NOT] STOPPED stepname [NOT] COMPLETED stepname ERROR_CODE IN (integer, integer, integer ...) stepname ERROR_CODE NOT IN (integer, integer, integer ...) stepname ERROR_CODE = integer stepname ERROR_CODE != integer stepname ERROR_CODE <> integer stepname ERROR_CODE > integer stepname ERROR_CODE >= integer stepname ERROR_CODE < integer stepname ERROR_CODE <= integer Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 甚至于,还可以制定成下列逻辑语法: expression AND expression expression OR expression NOT (expression) 比如说,我们希望条件为 step1 成功运行,那么可以指定 condition 参数值如下: 'step1 completed' Action 参数相对简单一些,这个参数用来指定当满足 condition 参数时,CHAIN 执 行的操作。 例如,创建 CHAIN RULE,首先执行 my_step1,如果 my_step1 成功执行的 话,就继续执行 my_step2,如果 my_step2 也成功执行的话,则结束该 CHAIN, 创建脚本如下: SQL> BEGIN DBMS_SCHEDULER.DEFINE_CHAIN_RULE ( chain_name => 'my_chain1', condition => 'TRUE', action => 'START my_step1', rule_name => 'my_rule1'); DBMS_SCHEDULER.DEFINE_CHAIN_RULE ( chain_name => 'my_chain1', condition => 'my_step1 completed', action => 'START my_step2', rule_name => 'my_rule2'); DBMS_SCHEDULER.DEFINE_CHAIN_RULE ( chain_name => 'my_chain1', condition => 'my_step2 completed', action => 'end 0', rule_name => 'my_rule3'); END; / PL/SQL procedure successfully completed. 1.23.5.1.4 运行 Chains 最后,来运行一下创建的 my_chain1 吧 , 手 动 运 行 CHAIN 是通过 DBMS_SCHEDULER.RUN_CHAIN 过程,例如: SQL> BEGIN DBMS_SCHEDULER.RUN_CHAIN ( chain_name => 'my_chain1', start_steps => 'my_step1'); END; / Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 PL/SQL procedure successfully completed. 语句执行成功,下面需要查看一下执行的结果。我们之前定义的 p_p1 等 program 对象,实际上是调用 procedure,向一个指定表 jss_t2 中插入记录,这里 直接查询一下该表,就知道执行情况了(在此之前,jss_t2 表为空): SQL> select * from jss_t2; TP DT ------------------------------ ------------ p_p1 inserted 03-SEP-09 p_p2 inserted 03-SEP-09 jss_t2 表中有了两条记录,对应前面设置的 CHAIN RULE,说明 my_step1 和 my_step2 均已正确执行。 提示:Chains 在执行前,必须被置于 enabled 状态,默认情况下刚刚创建的 CHAIN 都是 disabled 状态,要修改 Chains 的状态,还是通过 DBMS_SCHEDULER.ENABLE 和 DBMS_SCHEDULER.DISABLE 两过程,这里 就不演示了。手动执行的 CHAIN 的话没有系统级的日志记录,因此如果希望看 到详细执行情况的话,建议创建 job 来执行 CHAIN,例如: SQL> BEGIN DBMS_SCHEDULER.CREATE_JOB ( job_name => 'chain_job_1', job_type => 'CHAIN', job_action => 'my_chain1', repeat_interval => 'freq=daily;interval=1', enabled => TRUE); END; / PL/SQL procedure successfully completed. 然后,dba 就可以通过定期观察*_scheduler_job_run_details 视图来确认 chain 的 执行情况了。 1.23.5.2 管理 Chains 1.23.5.2.1 修改 Chains 属性 对于 CHAIN 对象来说,能够修改的属性只有两个:evaluation_interval 和 comments,这两个参数一般情况下甚至都不会进行设置。如果你碰到了确实需 要修改的情况,可以使用 DBMS_SCHEDULER.SET_ATTRIBUTE 过程。例如: SQL> select chain_name,comments from user_scheduler_chains; CHAIN_NAME COMMENTS -------------------- -------------------------- MY_CHAIN1 SQL> exec dbms_scheduler.set_attribute('my_chain1','comments','change it for a test!' ); PL/SQL procedure successfully completed. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL> select chain_name,comments from user_scheduler_chains; CHAIN_NAME COMMENTS -------------------- -------------------------- MY_CHAIN1 change it for a test ! 1.23.5.2.2 设置 Chain Step 运行属性 修改 chain step 的运行属性就不能使用 dbms_scheduler.set_attribute 了,而是 有专门的过程 dbms_scheduler.alter_chain 处理,该过程的定义如下: SQL> desc dbms_scheduler.alter_chain; Parameter Type Mode Default? ---------- -------- ---- -------- CHAIN_NAME VARCHAR2 IN STEP_NAME VARCHAR2 IN ATTRIBUTE VARCHAR2 IN VALUE BOOLEAN IN 前两个参数就不说了,ATTRIBUTE 参数用来指定 STEP 的属性值,可设定 的属性值有 3 个,每个属性值都有 TRUE 和 FALSE 两个选项,由 VALUE 参数 指定: (1)PAUSE:设置该参数值为 TRUE 时,当 step 运行时,其运行状态就会变更 为 PAUSED; (2) SKIP:设置该参数值为 TRUE 时,当 step 满足运行条件时,并不是执行 step 中的 program,而是直接跳过,注意当 SKIP 参数值设置为 TRUE,并且 PAUSE 参数值也被设置为 TRUE,那么将会以 PAUSE 的状态优先; (3) RESTART_ON_RECOVERY:设置该参数值为 TRUE 时,如果由于数据库 shutdown 导致 step 被停止,那么当下次数据库启动时,step 会自动重新运行。 DBMS_SCHEDULER.ALTER_CHAIN 过程修改 Chain Step 属性后,只有当 下次运行时才会生效,如果要修改当前运行中 Chain Step 的属性,也有一个专门 的过程 DBMS_SCHEDULER.ALTER_RUNNING_CHAIN 进行处理,该过程语法 与 DBMS_SCHEDULER.ALTER_CHAIN 一模一样。 1.23.5.2.3 删除 Chain Rules Chain Rules 没有对应的修改方法,如果要修改某个 Chain 的 rule,只能首先 删除不适当的 rule,然后重新添加新 rule(所谓添加,其实就是再重新定义一个 rule)。 删除 Chain Rule 有专门的过程 DBMS_SCHEDULER.DROP_CHAIN_RULE, 该过程语法如下: SQL> desc dbms_scheduler.drop_chain_rule; Parameter Type Mode Default? ---------- -------- ---- -------- CHAIN_NAME VARCHAR2 IN RULE_NAME VARCHAR2 IN Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 FORCE BOOLEAN IN Y 举个简单的示例,比如删除前面定义的 my_rule3,执行过程如下: SQL> exec dbms_scheduler.drop_chain_rule('my_chain1','my_rule3',true); PL/SQL procedure successfully completed. 1.23.5.2.4 删除 Chain Steps 删除 Chain Step 也有专门的过程 dbms_scheduler.drop_chain_step 进行处理, 该过程语法如下: SQL> desc dbms_scheduler.drop_chain_step; Parameter Type Mode Default? ---------- -------- ---- -------- CHAIN_NAME VARCHAR2 IN STEP_NAME VARCHAR2 IN FORCE BOOLEAN IN Y 例如,删除之前定义的 my_step3,执行过程如下: SQL> exec dbms_scheduler.drop_chain_step('my_chain1','my_step3',true); PL/SQL procedure successfully completed. 1.23.5.2.5 删除 Chains 如果要删除 Chain 那就更简单了,执行 dbms_scheduler.drop_chain 过程即可, 例如: SQL> exec dbms_scheduler.drop_chain('my_chain1',true); PL/SQL procedure successfully completed. 注意,执行 drop_chain 时,如果不指定 force 参数为 TRUE,那么默认情况 下 ORACLE 会首先检查要删除的 CHAIN 是否还有被依赖的对象,如果存在的 话,会报 ORA-27479 错误,提示仍然有依赖的对象(所谓依赖的对象就是指,该 chain 仍然存在 chain_step 或 chain_rule 之类),因此无法直接删除。 这种情况下解决方案有两种: (1)手动删除所有相关的 chain_step 和 chain_rule,然后再执行 chain 的删除, (2)附加 force 参数并指定参数值为 true,这样 ORACLE 就会自动替你清除所 有依赖的对象了。 1.23.6 使用 Job Classes Job Classes 相当于创建了一个 job 组,DBA 可以将那些具有相同特性的 job, 统统放到相同的 Job Classes 中,然后通过对 Job Class 应用 ORACLE 中的"资源 使用计划"特性,就可以对这些 job 执行过程中所需要的资源分配情况进行管理。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.23.6.1 创建 Job Classes 使用 DBMS_SCHEDULER 包的 CREATE_JOB_CLASS 过 程 创 建 Job Classes,该过程支持的参数如下: SQL> desc dbms_scheduler.create_job_class; Parameter Type Mode Default? ----------------------- -------------- ---- -------- JOB_CLASS_NAME VARCHAR2 IN RESOURCE_CONSUMER_GROUP VARCHAR2 IN Y SERVICE VARCHAR2 IN Y LOGGING_LEVEL BINARY_INTEGER IN Y LOG_HISTORY BINARY_INTEGER IN Y COMMENTS VARCHAR2 IN Y 其中: JOB_CLASS_NAME:要创建的 Job Class 的名称,注意指定的长度不要超过 30 个 字符,也不要与现有 Job Class 同名; RESOURCE_CONSUMER_GROUP:指定创建的 Job Class 所在的 RCG; Resource Consumer Group 可以将其理解成一个资源分配的方式,处于相同 RCG 组中的用户、会话、或者对象共用一组资源,这组资源中可供分配的资源 按照 DBA 指定的方式分配给 RCG。如果设计合理,通过这种方式,可以更有效 的利用服务器的资源。 SERVICE:指定创建的 Job Class 所在 Service,本选项常见于 RAC 环境,我们 都知道 RAC 环境由多实例+数据库组成,此处所指定的 Service 实际就是指 Job Class 会在哪个实例上运行。 注意:本参数与 RESOURCE_CONSUMER_GROUP 参数相互冲突,同一个 Job Class 只同设置两个参数中的一个值。 LOGGING_LEVEL:指定日志记录的级别,有下列三种级别: (1)DBMS_SCHEDULER.LOGGING_OFF:关闭日志记录功能; (2) DBMS_SCHEDULER.LOGGING_RUNS:对该 Job Class 下所有任务的运 行信息进行记录; (3) DBMS_SCHEDULER.LOGGING_FULL:记录该 Job Class 下任务的所有相 关信息,不仅有任务的运行情况,甚至连任务的创建、修改等也均将记入日志。 LOG_HISTORY:指定日志记录的时间,以天为单位,比如指定 LOG_HISTORY 参 数值为 90,就表示日志信息保留最近 90 天的内容。 COMMENTS:指定注释信息。 上述各个参数,除了 LOG_CLASS_NAME 参数为必选参外,其它均为可选参数, 例如: SQL> EXEC DBMS_SCHEDULER.CREATE_JOB_CLASS('my_first_jc'); PL/SQL procedure successfully completed 查询系统中已经存在的 job classes .可以通过 dba_scheduler_job_classes 视图 ( 或 all_scheduler_job_class 视图) Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 当创建 Jobs 时,可以通过 JOB_CLASS 参数来指定 job 所在的 Job Class,如 果不指定的话,创建的 job 默认属于 DEFAULT_JOB_CLASS 。可以使用 *_SCHEDULER_JOBS 视图中的 JOB_CLASS 列查看对应的信息。 1.23.6.2 管理 Job Classes DBMS_SCHEDULER.SET_ATTRIBUTE 过程的 SET_ATTRIBUTE 也可以用 来修改 Job Class 的属性,操作方法与修改 job 属性完全相同,只不过作用函概的 范围更广,修改 Job Class 后,该 Job Class 下属的所有 job 属性都会被级联修改(当 前正运行的不会立刻生效,将等到下次运行时生效)。 例如:修改刚刚创建的 MY_FIRST_JC 的日志保存时间: SQL> EXEC DBMS_SCHEDULER.SET_ATTRIBUTE('SYS.MY_FIRST_JC','LOG _HISTORY','30'); PL/SQL procedure successfully completed. 提示:Job Class 可被修改的属性,即创建时可选择指定的那 5 个属性。 1.23.6.3 删除 Job Classes DBMS_SCHEDULER 包提供了 DROP_JOB_CLASS 过 程 , 用 来 删 除 Job Classes。该过程调用非常简单,例如,删除刚刚创建的 MY_FIRST_JC,执 行命令如下: SQL> EXEC DBMS_SCHEDULER.DROP_JOB_CLASS('MY_FIRST_JC'); PL/SQL procedure successfully completed. 如果有多个 Job Classes 需要删除,并不需要多次执行 DROP_JOB_CLASS, 只需要在为该过程指定值时,参数值间以逗号分隔即可。 1.23.7 使用 Windows 此 处 所 说 的 Windows ,是指 SCHEDULER 特 性 中 的 一 个 子 项 。 在 SCHEDULER 中,WINDOW 对应的是一个时间窗口的概念。我们知道普通的 jobs 是没有运行时间管理地概念的,就是说一个 job 启动之后,用户只能被动地 等待其执行,一直到其执行地任务完成(或 DBA 手动 kill 对应进程),在此期间, 执行的 job 将与其它活动的进程共同竞争当前系统中的资源。 对于大型数据库系统,系统资源那可是相当宝贵的,在 9i 之前,谁想用就用, 谁也管不了,其中表示最甚的就是 job。你是否想起了 Job Classes,没错定义 Job Classes 确实可以控制 job 能够使用的资源,不过单单使用 Job Classes 并不能 灵活的控制 job 在合适的时间使用适当的资源。 进入 10g 之后,SCHEDULER 中提供了 WINDOW,事情终于有了缓解。 WINDOW 可以指定一个时间窗口,在此期间,通过与 Job Classes 的搭配组合, 能够有效控制 job 执行时支配(使用)的资源。比如说 job 通常是在凌晨服务器负 载较低时执行,那么就可以通过 WINDOW 设置在此期间,允许 jobs 使用更多的 系统资源,而到了工作时间后,如果 job 仍未执行完成,为其分配另一个有限的Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 资源,以尽可能降低 job 执行占用的资源对其它业务的影响。 1.23.7.1 创建 Window 创建 window 有一个专门的过程:dbms_scheduler.create_window 进行处理, 该过程有两种调用方式,如下: --基于 SCHEDULE DBMS_SCHEDULER.CREATE_WINDOW ( window_name IN VARCHAR2, resource_plan IN VARCHAR2, schedule_name IN VARCHAR2, duration IN INTERVAL DAY TO SECOND, window_priority IN VARCHAR2 DEFAULT 'LOW', comments IN VARCHAR2 DEFAULT NULL); --基于定义的调度 DBMS_SCHEDULER.CREATE_WINDOW ( window_name IN VARCHAR2, resource_plan IN VARCHAR2, start_date IN TIMESTAMP WITH TIME ZONE DEFAULT NULL, repeat_interval IN VARCHAR2, end_date IN TIMESTAMP WITH TIME ZONE DEFAULT NULL, duration IN INTERVAL DAY TO SECOND, window_priority IN VARCHAR2 DEFAULT 'LOW', comments IN VARCHAR2 DEFAULT NULL); 下列几个参数可能需要关注: (1)Resource_plan:这一参数用来指定要使用的资源使用计划,当打开 WINDOW 时,就会自动按照指定的资源使用计划中的设置分配资源,当 WINDOW 关闭时,系统会自动切换回适当资源计划。这个参数在执行过程时甚 至可以指定为 NULL 或空值'',当设置为 NULL 时,就表示使用默认的资源计划, 当设置为空值''时,表示禁用资源使用计划。 (2) Duration:指定 WINDOW 的有效期,比如说指定为 interval '5' hour 就表示 5 个小时,该参数在执行过程时必须指定参数值,否则创建会报错。 (3) Window_priority:该参数用来指定 WINDOW 的优先级。因为在相同时间 只有一个 WINDOW 有效,因此如果在创建 WINDOW 时发现重叠的情况, ORACLE 就需要根据这一参数指定的规则,来确定优先级,说白了就是先把资 源给谁用,这一参数有两个可选值:HIGH 或 LOW,默认值为 LOW。 正如前面 CREATE_WINDOW 过程语法结构显示的那样,调用该过程有两种 方式,差异就在于是指定现有定义好的调度 SCHEDULE,还是在执行过程时指 定调度,目标和实现的功能都是相同的,这里仅做示例,咱就挑个最复杂的方式 吧,执行过程时指定调度,执行脚本如下: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL> begin dbms_scheduler.create_window( window_name => 'my_first_wd1', resource_plan => null, start_date => sysdate, repeat_interval => 'FREQ=DAILY; INTERVAL=5', duration => interval '1' hour); end; / PL/SQL procedure successfully completed. 查询当前拥有的 WINDOW,可以通过*_SCHEDULER_WINDOWS 视图(注意只 有 DBA 和 ALL,没有 USER,因为所有定义的 WINDOW 都属于 SYS 用户)。除 了*_SCHEDULER_WINDOWS 视图显示当前所有 WINDOW 外,还有: (1)*_SCHEDULER_WINDOW_DETAILS 视图:显示 WINDOW 的详细信息; (2)*_SCHEDULER_WINDOW_LOG 视图:显示 WINDOW 的日志,比如打开 和关闭; 1.23.7.2 管理 Window 修改对象属性,使用 SET_ATTRIBUTE 过程; SQL> exec dbms_scheduler.set_attribute('sys.my_first_wd1','start_date',sysdate+1); PL/SQL procedure successfully completed. ENABLE 对象,使用 ENABLE 过程; SQL> exec dbms_scheduler.enable('sys.my_first_wd1'); PL/SQL procedure successfully completed. DISABLE 对象,使用 DISABLE 过程; SQL> exec dbms_scheduler.disable('sys.my_first_wd1'); PL/SQL procedure successfully completed. 删除对象,使用 DROP_WINDOW 过程; SQL> exec dbms_scheduler.drop_window('sys.my_first_wd1'); PL/SQL procedure successfully completed. 除此之外呢,对于 WINDOW 对象来说,由于其特殊作用,又有:手动打开 WINDOW,使用 OPEN_WINDOW 过程; 注意 WINDOW 是依赖于其调度的,因此在手动打开 WINDOW 时,必须为 其指定 duration 属性: SQL> exec dbms_scheduler.open_window('sys.my_first_wd1',interval '1' hour);; PL/SQL procedure successfully completed. 手动关闭 WINDOW,使用 CLOSE_WINDOW 过程; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL> exec dbms_scheduler.close_window('sys.my_first_wd1'); PL/SQL procedure successfully completed. 关闭和打开 WINDOW ,都会记录日志,大家可以通过 *_SCHEDULER_WINDOW_LOG 视图中获取这部分信息。 1.23.7.3 关于 WINDOWGROUP 除了 WINDOW 外,还有一个与 WINDOW 有关系的叫 WINDOW GROUP, 一个 WINDOW GROUP 可能包含多个 WINDOW。 使用 WINDOW GROUP 的本意是这样的,假如说某个 job 执行的时间比较 长,甚至全天 24 小时都在执行,对于这类 job,单个 WINDOW 很难有效调整其 资源占用,这时间呢,就 可 以 通 过 设 置 一 个 WINDOW GROUP ,该 WINDOW GROUP 中包含了多个 WINDOW,每个 WINDOW 分别负责不同时间 点时的资源使用计划。 然后在创建 JOB 时,指定 schedule_name 参数为 WINDOW GROUP 的名称 (SCHEDULE_NAME 可以指定为 WINDOW GROUP , WINDOW GROUP,还 可以直接指定成 WINDOW ),这样,就可以通过很简单的方式,将 job 与 window 联系在一起了。 WINDOW GROUP 的创建和管理与前面介绍的方式极其相似: (1)创建,使用 CREATE_WINDOW_GROUP 过程; (2) 删除,使用 DROP_WINDOW_GROUP 过程; (3) 添加 WINDOW 成员,使用 ADD_WINDOW_GROUP_MEMBER 过程; (4) 删除 WINDOW 成员,使用 REMOVE_WINDOW_GROUP_MEMBER 过程; (5) 启用,使用 ENABLE 过程; (6) 禁用,使用 DISABLE 过程; 1.24 坏块小结 1.25 ALTER DATABASE 与 ALTER TABLESPACE OFFLINE 的区别 1.25.1 DataFile 脱机或联机的两种方法: ① ALTER DATABASE 语句修改单独的 DataFile ② ALTER TABLESPACE 语句修改所有的 DataFile 1.25.1.1 ARCHIVRLOG 模式下的更改 DataFile 状态 ALTER DATABASE DATAFILE '/u02/oracle/rbdb1/stuff01.dbf' ONLINE; ALTER DATABASE DATAFILE '/u02/oracle/rbdb1/stuff01.dbf' OFFLINE; 或者用文件号来表示 : SQL>select file#,name,checkpoint_change# from v$datafile; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 FILE# NAME CHECKPOINT_CHANGE# 1 D:\ORACLE\ORADATA\DBA\SYSTEM01.DBF 1194854 2 D:\ORACLE\ORADATA\DBA\UNDOTBS01.DBF 1194854 3 D:\ORACLE\ORADATA\DBA\SYSAUX01.DBF 1194854 4 D:\ORACLE\ORADATA\DBA\USERS01.DBF 1194854 5 D:\ORACLE\ORADATA\DBA\TEST01.DBF 1203262 ALTER DATABASE DATAFILE 5 ONLINE; ALTER DATABASE DATAFILE 5 OFFLINE; 注:只有在 ARCHIVELOG 模式下才可使用 ALTER DATABASE 来更改 DataFile 1.25.1.2 在 NOARCHIVELOG 模式下使 DataFile 脱机 由于在 NOARCHIVELOG 模式下,数据文件脱机后会造成数据的遗失,所 以只能使用 ALTER DATABASE 语句下带有 DATAFILE 和 OFFLINE DROP 子句 的选项将该 DataFile 直接取消,例如该 DataFile 只包含临时段数据,并没有备份 时 alter database datafile '/u02/oracle/rbdb1/users3.dbf' offline drop; 1.25.1.3 修改 TableSpace 中所有 DataFile 或 TempFile 的可用性 ALTER TABLESPACE ... DATAFILE {ONLINE|OFFLINE} ALTER TABLESPACE ... TEMPFILE {ONLINE|OFFLINE} 注:修改某 TableSpace 中的所有数据文件,但是 TableSpace 本身的状态不改变。 我们不能使用'alter database datafile ... offline' 在归档模式下,但是 'alter tablespace ... offline' 可以。 我们不是使用'alter tablespace ... offline'在数据库的 read-only 模式下,但是'alter database datafile ... offline' 可以。 总结: ① ALTER TABLESPACE 可以在数据库装载状态时发布,无需打开 ② 涉及到系统表空间、撤销表空间、默认临时表空间时,必须是未打开的 数据库 ③ ALTER DATABASE DATAFILE 语句中必须填入文件全名 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.25.2 表空间 与 数据文件 脱机的区别 1.25.2.1 ALTER TABLESPACE ... OFFLINE Does a checkpoint on the datafiles Takes the datafiles offline 表空间 Offline 时,数据文件的 SCN 会被冻结,而且表空间的数据文件 offline/online 时又会发生文件检查点,使单个数据文件 SCN 和数据库其他问题 不一致。 表空间 online 时,Oracle 会取得当前 SCN,解冻 offline 文件 SCN,和当前 SCN 同步。 tablespace offline 有几种选项可供选择: normal, temporary,immediate, for recovery, 而在 datafile 中则没有这些选项。 SQL>select dbms_flashback.get_system_change_number from dual; GET_SYSTEM_CHANGE_NUMBER ------------------------ 1203246 SQL>alter tablespace test offline; Tablespace altered. SQL>select file#,name,checkpoint_change# from v$datafile; FILE# NAME CHECKPOINT_CHANGE# 1 D:\ORACLE\ORADATA\DBA\SYSTEM01.DBF 1194854 2 D:\ORACLE\ORADATA\DBA\UNDOTBS01.DBF 1194854 3 D:\ORACLE\ORADATA\DBA\SYSAUX01.DBF 1194854 4 D:\ORACLE\ORADATA\DBA\USERS01.DBF 1194854 5 D:\ORACLE\ORADATA\DBA\TEST01.DBF 1203262 SQL>select dbms_flashback.get_system_change_number from dual; GET_SYSTEM_CHANGE_NUMBER ------------------------ 1203328 SQL>alter tablespace test online; Tablespace altered. SQL>select file#,name,checkpoint_change# from v$datafile; FILE# NAME CHECKPOINT_CHANGE# 1 D:\ORACLE\ORADATA\DBA\SYSTEM01.DBF 1,194,854 2 D:\ORACLE\ORADATA\DBA\UNDOTBS01.DBF 1,194,854 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 3 D:\ORACLE\ORADATA\DBA\SYSAUX01.DBF 1,194,854 4 D:\ORACLE\ORADATA\DBA\USERS01.DBF 1,194,854 5 D:\ORACLE\ORADATA\DBA\TEST01.DBF 1,203,343 SQL>select dbms_flashback.get_system_change_number from dual; GET_SYSTEM_CHANGE_NUMBER ------------------------ 1203440 1.25.2.2 ALTER DATABASE DATAFILE ... OFFLINE 单纯的 offline datafile,将不会触发文件检查点,只有针对 offline tablespace 的时候才会触发文件检查点,这也是为什么 online datafile 需要 media recovery 而 online tablespace 不需要。 注:只有在 ARCHIVELOG 模式下才可使用 ALTER DATABASE 来更改 DataFile SQL>select file#,name,checkpoint_change# from v$datafile; FILE# NAME CHECKPOINT_CHANGE# 1 D:\ORACLE\ORADATA\DBA\SYSTEM01.DBF 1,194,854 2 D:\ORACLE\ORADATA\DBA\UNDOTBS01.DBF 1,194,854 3 D:\ORACLE\ORADATA\DBA\SYSAUX01.DBF 1,194,854 4 D:\ORACLE\ORADATA\DBA\USERS01.DBF 1,194,854 5 D:\ORACLE\ORADATA\DBA\TEST01.DBF 1,203,343 SQL>select dbms_flashback.get_system_change_number from dual; GET_SYSTEM_CHANGE_NUMBER ------------------------ 1219831 SQL>alter database datafile 5 offline; Database altered. SQL>select file#,name,checkpoint_change# from v$datafile; FILE# NAME CHECKPOINT_CHANGE# 1 D:\ORACLE\ORADATA\DBA\SYSTEM01.DBF 1,194,854 2 D:\ORACLE\ORADATA\DBA\UNDOTBS01.DBF 1,194,854 3 D:\ORACLE\ORADATA\DBA\SYSAUX01.DBF 1,194,854 4 D:\ORACLE\ORADATA\DBA\USERS01.DBF 1,194,854 5 D:\ORACLE\ORADATA\DBA\TEST01.DBF 1,203,343 SQL>select dbms_flashback.get_system_change_number from dual; GET_SYSTEM_CHANGE_NUMBER ------------------------ Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1219882 SQL>alter database datafile 5 online; Error at line 1 ORA-01113: 文件 5 需要介质恢复 ORA-01110: 数据文件 5: 'D:\ORACLE\ORADATA\DBA\TEST01.DBF' SQL>recover datafile 5; 完成介质恢复 SQL>alter database datafile 5 online; Database altered. SQL>select file#,name,checkpoint_change# from v$datafile; FILE# NAME CHECKPOINT_CHANGE# 1 D:\ORACLE\ORADATA\DBA\SYSTEM01.DBF 1,194,854 2 D:\ORACLE\ORADATA\DBA\UNDOTBS01.DBF 1,194,854 3 D:\ORACLE\ORADATA\DBA\SYSAUX01.DBF 1,194,854 4 D:\ORACLE\ORADATA\DBA\USERS01.DBF 1,194,854 5 D:\ORACLE\ORADATA\DBA\TEST01.DBF 1,219,929 SQL>select dbms_flashback.get_system_change_number from dual; GET_SYSTEM_CHANGE_NUMBER ------------------------ 1220043 1.26 Oracle 临时表 Blog:http://blog.csdn.net/tianlesoftware/archive/2009/10/20/4705283.aspx 1.26.1 临时表说明 Oracle Database temporary tables hold data that exists only for the duration of a transaction or session. Data in a temporary table is private to the session, which means that each session can only see and modify its own data. Temporary tables are useful in applications where a result set must be buffered. For example, a scheduling application enables college students to create optional semester course schedules. Each schedule is represented by a row in a temporary table. During the session, the schedule data is private. When the student decides on a schedule, the application moves the row for the chosen schedule to a permanent table. At the end of the session, the schedule data in the temporary data is automatically dropped. Temporary Table Creation The CREATE GLOBAL TEMPORARY TABLE statement creates a temporary table. The ON COMMIT clause specifies whether the table data is transaction-specific Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 (default) or session-specific. Unlike temporary tables in some other relational databases, when you create a temporary table in an Oracle database, you create a static table definition. The temporary table is a persistent object described in the data dictionary, but appears empty until your session inserts data into the table. You create a temporary table for the database itself, not for every PL/SQL stored procedure. Because temporary tables are statically defined, you can create indexes for them with the CREATE INDEX statement. Indexes created on temporary tables are also temporary. The data in the index has the same session or transaction scope as the data in the temporary table. You can also create a view or trigger on a temporary table. -- 临时表可以创建临时的索引,视图,触发器。 Segment Allocation in Temporary Tables Like permanent tables, temporary tables are defined in the data dictionary. Temporary segments are allocated when data is first inserted. Until data is loaded in a session the table appears empty. Temporary segments are deallocated at the end of the transaction for transaction-specific temporary tables and at the end of the session for session-specific temporary tables. 临时表只在Oracle 8i 以及以上产品中支持。ORACLE数据库除了可以保存永 久表外,还可以建立临时表temporary tables。这些临时表用来保存一个会话 SESSION的数据,或者保存在一个事务中需要的数据。当会话退出或者用户提交 commit和回滚rollback事务的时候,临时表的数据自动清空,但是临时表的结构 以及元数据还存储在用户的数据字典中。 Oracle的临时表创建之后基本不占用表空间,临时表并非存放在用户的表空 间中,而是存放在 Schema 所指定的临时表空间中。如果你没有指定临时表(包 括临时表的索引)存放的表空的时候,你插入到临时表的数据是存放在ORACLE 系统的临时表空间中(TEMP)。 可以对临时表创建索引,视图,触发器,可以用export和import工具导入导 出表的定义,但是不能导出数据。表的定义对所有的会话可见。建立在临时表上 的索引也是临时的,也是只对当前会话或者事务有效. 尽管对临时表的DML操作速度比较快,但同样也是要产生 Redo Log ,只是 同样的DML语句,比对 PERMANENT 的DML 产生的Redo Log 少。 临时表的不足之处: 1.不支持lob对象,这也许是设计者基于运行效率的考虑,但实际应用中确Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 实需要此功能时就无法使用临时表了。 2.不支持主外键关系 特性和性能(与普通表和视图的比较) 1.临时表只在当前连接内有效 2.临时表不建立索引,所以如果数据量比较大或进行多次查询时,不推荐使用 3.数据处理比较复杂的时候时表快,反之视图快点 4.在仅仅查询数据的时候建议用游标: open cursor for 'sql clause'; 临时表的应用: 对于一个电子商务类网站,不同消费者在网站上购物,就是一个独立的 SESSION,选购商品放进购物车中,最后将购物车中的商品进行结算。也就是说, 必须在整个SESSION期间保存购物车中的信息。同时,还存在有些消费者,往往 最终结账时放弃购买商品。如果,直接将消费者选购信息存放在最终表 (PERMANENT)中,必然对最终表造成非常大的压力。因此,对于这种案例,就 可以采用创建临时表(ON COMMIT PRESERVE ROWS)的方法来解决。数据只在 SESSION 期间有效,对于结算成功的有效数据,转移到最终表中后,ORACLE自动 TRUNCATE 临时数据;对于放弃结算的数据,ORACLE 同样自动进行 TRUNCATE , 而无须编码控制,并且最终表只处理有效订单,减轻了频繁的DML的压力。 Temp Table 的另一个应用,就是存放数据分析的中间数据。 1.26.2 创建临时表 1.26.2.1 Creating a Temporary Table Temporary tables are useful in applications where a result set is to be buffered (temporarily persisted), perhaps because it is constructed by running multiple DML operations. For example, consider the following: A Web-based airlines reservations application allows a customer to create several optional itineraries. Each itinerary is represented by a row in a temporary table. The application updates the rows to reflect changes in the itineraries. When the customer decides which itinerary she wants to use, the application moves the row for that itinerary to a persistent table. During the session, the itinerary data is private. At the end of the session, the optional itineraries are dropped. The definition of a temporary table is visible to all sessions, but the data in a temporary table is visible only to the session that inserts the data into the table. Use the CREATE GLOBAL TEMPORARY TABLE statement to create a temporary table. The ON COMMIT clause indicates if the data in the table is transaction-specific (the default) or session-specific, the implications of Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 which are as follows: ON COMMIT Setting Implications DELETE ROWS This creates a temporary table that is transaction specific. A session becomes bound to the temporary table with a transactions first insert into the table. The binding goes away at the end of the transaction. The database truncates the table (delete all rows) after each commit. PRESERVE ROWS This creates a temporary table that is session specific. A session gets bound to the temporary table with the first insert into the table in the session. This binding goes away at the end of the session or by issuing a TRUNCATE of the table in the session. The database truncates the table when you terminate the session. This statement creates a temporary table that is transaction specific: CREATE GLOBAL TEMPORARY TABLE admin_work_area (startdate DATE, enddate DATE, class CHAR(20)) ON COMMIT DELETE ROWS; Indexes can be created on temporary tables. They are also temporary and the data in the index has the same session or transaction scope as the data in the underlying table. By default, rows in a temporary table are stored in the default temporary tablespace of the user who creates it. However, you can assign a temporary table to another tablespace upon creation of the temporary table by using the TABLESPACE clause of CREATE GLOBAL TEMPORARY TABLE. You can use this feature to conserve space used by temporary tables. For example, if you must perform many small temporary table operations and the default temporary tablespace is configured for sort operations and thus uses a large extent size, these small operations will consume lots of unnecessary disk space. In this case it is better to allocate a second temporary tablespace with a smaller extent size. The following two statements create a temporary tablespace with a 64 KB extent size, and then a new temporary table in that tablespace. CREATE TEMPORARY TABLESPACE tbs_t1 TEMPFILE 'tbs_t1.f' SIZE 50m REUSE AUTOEXTEND ON MAXSIZE UNLIMITED EXTENT MANAGEMENT LOCAL UNIFORM SIZE 64K; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 CREATE GLOBAL TEMPORARY TABLE admin_work_area (startdate DATE, enddate DATE, class CHAR(20)) ON COMMIT DELETE ROWS TABLESPACE tbs_t1; 1.26.2.2 创建临时表 Oracle临时表,有两种类型: 会话级的临时表 事务级的临时表。 1.26.2.2.1. 会话级的临时表 因为这这个临时表中的数据和你的当前会话有关系,当你当前SESSION不退 出的情况下,临时表中的数据就还存在,而当你退出当前SESSION的时候,临时 表中的数据就全部没有了,当然这个时候你如果以另外一个SESSION登陆的时候 是看不到另外一个SESSION中插入到临时表中的数据的。即两个不同的SESSION 所插入的数据是互不相干的。 当某一个SESSION退出之后临时表中的数据就被截断(truncate table,即数 据清空)了。 注:这里要说明的是,ORACLE Truncate 掉的数据仅仅是分配给不同 Session 或 Transaction的 Temp Segment 上的数据,而不是将整张表数据 TRUNCATE 掉。当Commit的时候则数据还在,当Rollback的时候则数据也是一样被回滚. 会话级的临时表创建方法: SQL>CREATE GLOBAL TEMPORARY TABLE TABLE_NAME () ON COMMIT PRESERVE ROWS; 或者 SQL>CREATE GLOBAL TEMPORARY TABLE TABLE_NAME ON COMMIT PRESERVE ROWS AS SELECT * FROM TABLE_NAME; 示例: SQL> CREATE GLOBAL TEMPORARY TABLE TT(ID NUMBER(2)) ON COMMIT PRESERVE ROWS ; 表已创建。 SQL> SELECT * FROM TT; 未选定行 SQL> INSERT INTO TT VALUES(1); Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 已创建 1 行。 SQL> COMMIT; 提交完成。 SQL> SELECT * FROM TT; ID ---------- 1 SQL> INSERT INTO TT VALUES(2); 已创建 1 行。 SQL> SELECT * FROM TT; ID ---------- 1 2 SQL> ROLLBACK; 回退已完成。 SQL> SELECT * FROM TT; ID ---------- 1 1.26.2.2.2 事务特有的临时表(默认类型) 该临时表与事务相关,当进行事务提交或者事务回滚的时候,临时表中的数 据将自行被截断,其他的内容和会话级的临时表的一致(包括退出 SESSION 的 时候,事务级的临时表也会被自动截断)。一旦 COMMIT 后,数据就被自动 TRUNCATE 掉了. 事务级临时表的创建方法: SQL>CREATE GLOBAL TEMPORARY TABLE TABLE_NAME () ON COMMIT DELETE ROWS; 或者 SQL>CREATE GLOBAL TEMPORARY TABLE TABLE_NAME ON COMMIT DELETE ROWS AS SELECT * FROM TABLE_NAME; CREATE GLOBAL TEMPORARY TABLE TABLE_NAME; 在不指明类型的情况下,默认 为事务临时表。 SQL> CREATE GLOBAL TEMPORARY TABLE TT2(ID NUMBER(2)) ON COMMIT DELETE ROWS ; 表已创建。 SQL> SELECT * FROM TT2; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 未选定行 SQL> INSERT INTO TT2 VALUES(1); 已创建 1 行。 SQL> SELECT * FROM TT2; ID ---------- 1 SQL> COMMIT; 提交完成。 SQL> SELECT * FROM TT2; 未选定行 SQL> 1.27 Oracle Temp 临时表空间 1.27.1 Temporary Tablespacs 说明 A temporary tablespace contains transient data that persists only for the duration of a session. No permanent schema objects can reside in a temporary tablespace. The database stores temporary tablespace data in temp files. Temporary tablespaces can improve the concurrency of multiple sort operations that do not fit in memory. These tablespaces also improve the efficiency of space management operations during sorts. When the SYSTEM tablespace is locally managed, a default temporary tablespace is included in the database by default during database creation. A locally managed SYSTEM tablespace cannot serve as default temporary storage. -- 本地管理的 system 表空间,不能作为默认的临时表空间。 You cannot make a default temporary tablespace permanent. You can specify a user-named default temporary tablespace when you create a database by using the DEFAULT TEMPORARY TABLESPACE extension to the CREATE DATABASE statement. If SYSTEM is dictionary managed, and if a default temporary tablespace is not defined at database creation, then SYSTEM is the default temporary storage. However, the database writes a warning in the alert log saying that a default temporary tablespace is recommended. -- 当 SYSTEM 表空间是数据字典管理时,并且没有定义默认的临时表空间, 那么 SYSTEM 表空间会作为默认的 temporary storage。 关于表空间的两种类型: locally managed 和 dictionary managed 的区别,参 考我的 Blog: Oracle 自动段空间管理(ASSM:auto segment space management) http://blog.csdn.net/tianlesoftware/archive/2009/12/07/4958989.aspx Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 A temporary tablespace contains schema objects only for the duration of a session. Locally managed temporary tablespaces have temporary files (temp files), which are special files designed to store data in hash, sort, and other operations. Temp files also store result set data when insufficient space exists in memory. Temp files are similar to permanent data files, with the following exceptions: (1)Permanent database objects such as tables are never stored in temp files. (2)Temp files are always set to NOLOGGING mode, which means that they never have redo generated for them. Media recovery does not recognize temp files. (3)You cannot make a temp file read-only. (4)You cannot create a temp file with the ALTER DATABASE statement. (5)When you create or resize temp files, they are not always guaranteed allocation of disk space for the file size specified. On file systems such as Linux and UNIX, temp files are created as sparse files. In this case, disk blocks are allocated not at file creation or resizing, but as the blocks are accessed for the first time. Caution: Sparse files enable fast temp file creation and resizing; however, the disk could run out of space later when the temp files are accessed. (6)Temp file information is shown in the data dictionary view DBA_TEMP_FILES and the dynamic performance view V$TEMPFILE, but not in DBA_DATA_FILES or the V$DATAFILE view. 临时表空间主要用途是在数据库进行排序运算、管理索引、访问视图等操作 时提供临时的运算空间,当运算完成之后系统会自动清理。当 oracle 里需要用到 sort 的时候,PGA 中 sort_area_size 大小不够时,将会把数据放入临时表空间里 进行排序,同时如果有异常情况的话,也会被放入临时表空间,正常来说,在完 成 Select 语句、create index 等一些使用 TEMP 表空间的排序操作后,Oracle 是 会自动释放掉临时段的。注意这里的释放,仅仅是将这些空间标记为空闲,并可 重用,真正占用的磁盘空间并没有释放。所以 Temp 表空间可能会越来越大。 排序是很耗资源的,Temp 表空间满了,关键是优化你的语句,尽量使排序减 少才是上策. 1.27.2 Temp 表空间的操作 You cannot use the ALTER TABLESPACE statement, with the TEMPORARY keyword, to change a locally managed permanent tablespace into a locally managed temporary tablespace. You must use the CREATE TEMPORARY TABLESPACE statement to create a locally managed temporary tablespace. You can use ALTER TABLESPACE to add a tempfile, take a tempfile offline, or Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 bring a tempfile online, as illustrated in the following examples: ALTER TABLESPACE lmtemp ADD TEMPFILE '/u02/oracle/data/lmtemp02.dbf' SIZE 18M REUSE; SQL>ALTER TABLESPACE lmtemp TEMPFILE OFFLINE; SQL>ALTER TABLESPACE lmtemp TEMPFILE ONLINE; Note: You cannot take a temporary tablespace offline. Instead, you take its tempfile offline. The view V$TEMPFILE displays online status for a tempfile. -- 不可以将 Temp 表空间 offline,但是可以将 tempfile offline。V$TEMPFILE 显示了 tempfile 的状态。 The ALTER DATABASE statement can be used to alter tempfiles. The following statements take offline and bring online tempfiles. They behave identically to the last two ALTER TABLESPACE statements in the previous example. SQL>ALTER DATABASE TEMPFILE '/u02/oracle/data/lmtemp02.dbf' OFFLINE; SQL>ALTER DATABASE TEMPFILE '/u02/oracle/data/lmtemp02.dbf' ONLINE; The following statement resizes a tempfile: -- resize 表空间 SQL>ALTER DATABASE TEMPFILE '/u02/oracle/data/lmtemp02.dbf' RESIZE 18M; The following statement drops a tempfile and deletes its operating system file: SQL>ALTER DATABASE TEMPFILE '/u02/oracle/data/lmtemp02.dbf' DROP INCLUDING DATAFILES; -- drop tempfile 和它的物理文件。 The tablespace to which this tempfile belonged remains. A message is written to the alert log for the tempfile that was deleted. If an operating system error prevents the deletion of the file, the statement still succeeds, but a message describing the error is written to the alert log. -- 当我们把 temp 表空间的数据文件文件删除之后,表空间的信息还会存在, 但是在 alert log 里会有错误信息。 It is also possible to use the ALTER DATABASE statement to enable or disable the automatic extension of an existing tempfile, and to rename a tempfile. See Oracle Database SQL Language Reference for the required syntax. Note: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 To rename a tempfile, you take the tempfile offline, use operating system commands to rename or relocate the tempfile, and then use the ALTER DATABASE RENAME FILE command to update the database controlfiles. tempfile 数据文件重命名的步骤: (1)将 tempfile offline (2)在操作系统上重命名 tempfile (3)使用 alter database rename file 更新控制文件。 1.27.3 临时表空间满时的处理方法 1.27.3.1 添加数据文件 如果 Temporary tablespace 还不大,那么我们可以增加一些数据文件。SQL 语 句如下: SQL>ALTER TABLESPACE TEMP ADD TEMPFILE 'D:\ORADATA\NEWCCS\TEMP02.DBF' SIZE 100M AUTOEXTEND OFF; 一般来说,Temp tablespace 和 Undo Tablespace 是不建议设置为自增长,设 置自增长可能会把磁盘给撑满。 1.27.3.2 修改数据文件大小 可以将原来的数据文件改大一点,如: SQL>ALTER DATABASE TEMPFILE 'D:\ ORADATA\NEWCCS\TEMP02.DBF' RESIZE 100M; 1.27.4 Temp 表空间过大的处理方法 Temp 表空间过大,会占用很多的磁盘空间,这时候,我们可以用一下 2 中 方法来缩小 temp 表空间的大小。 1.27.4.1 替换 Temp 表空间 1.27.4.1.1 查看目前 Temp 表空间的信息 SQL> select name from v$tempfile; NAME ——————————————————————— D:\ORACLE\ORADATA\TEST\TEMP01.DBF Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL> select username,temporary_tablespace from dba_users; USERNAME TEMPORARY_TABLESPACE ------------------------------ ------------------------------ MGMT_VIEW TEMP SYS TEMP SYSTEM TEMP DBSNMP TEMP SYSMAN TEMP 关于用户这块是要特别注意的,如果我们将默认的 Temp 表空间指向其他的 名称,那么这些用户的信息就会失效,所以,我们特换时,要么创建一个临时的 Temp 表空间中转一下,这样切换之后,我们的 temp 表空间名称不变,要么改 变名称,同时更新相关用户的 default temp 表空间。 这里用中转的方法来测试。 1.27.4.1.2 创建中转临时表空间 UNIFORM specifies that the tablespace is managed with uniform extents of SIZE bytes.The default SIZE is 1 megabyte. All extents of temporary tablespaces are of uniform size, so this keyword is optional for a temporary tablespace. However, you must specify UNIFORM in order to specify SIZE. You cannot specify UNIFORM for an undo tablespace. -- Temp 表空间必须是 uniform 的,undo 必须是 autoallocate 的。默认情况 下 uniform 是 1M。 If you do not specify AUTOALLOCATE or UNIFORM, then the default is UNIFORM for temporary tablespaces and AUTOALLOCATE for all other types of tablespaces. 更多内容参考: Oracle 表空间 创建参数 说明 http://blog.csdn.net/tianlesoftware/archive/2011/01/27/6166928.aspx 创建 SQL 如下: SQL>CREATE TEMPORARY TABLESPACE TEMP2 TEMPFILE 'D:\APP\ADMINISTRATOR\ORADATA\NEWCCS\TEMP03.DBF' SIZE 10M AUTOEXTEND OFF; EXTENT MANAGEMENT LOCAL UNIFORM SIZE 1M; 上面是默认情况,等于一下 SQL: SQL>CREATE TEMPORARY TABLESPACE TEMP2 TEMPFILE 'D:\APP\ADMINISTRATOR\ORADATA\NEWCCS\TEMP03.DBF' SIZE 10M AUTOEXTEND OFF EXTENT MANAGEMENT LOCAL UNIFORM SIZE 1M; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.27.4.1.3 修改 Temp2 为默认临时表空间 SQL>alter database default temporary tablespace temp2; 1.27.4.1.4. 删除原来临时表空间 SQL>drop tablespace temp including contents and datafiles; 1.27.4.1.5. 重新创建临时表空间 SQL>CREATE TEMPORARY TABLESPACE TEMP TEMPFILE 'D:\APP\ADMINISTRATOR\ORADATA\NEWCCS\TEMP03.DBF' SIZE 10M AUTOEXTEND OFF; EXTENT MANAGEMENT LOCAL UNIFORM SIZE 1M; 1.27.4.1.6. 重置缺省临时表空间为新建的 temp 表空间 SQL>alter database default temporary tablespace temp; 1.27.4.1.7. 删除中转用临时表空间 SQL>drop tablespace temp2 including contents and datafiles; 1.27.4.1.8 如果有必要,重新指定用户表空间为重建的临时表空间 SQL>alter user dave temporary tablespace temp; 1.27.4.2 Shrinking a Locally Managed Temporary Tablespace Large sort operations performed by the database may result in a temporary tablespace growing and occupying a considerable amount of disk space. After the sort operation completes, the extra space is not released; it is just marked as free and available for reuse. -- 当排序操作完成, 占用的空间并没有释放,仅仅是将它标记为空闲,并 可重用。 Therefore, a single large sort operation might result in a large amount of allocated temporary space that remains unused after the sort operation is complete. For this reason, the database enables you to shrink locally managed temporary tablespaces and release unused space. --可以使用 shrink 来释放没有使用的空间。 (1)You use the SHRINK SPACE clause of the ALTER TABLESPACE statement to shrink a temporary tablespace, or (2)the SHRINK TEMPFILE clause of the ALTER TABLESPACE statement to shrink a specific tempfile of a temporary tablespace. Shrinking frees as much space as possible while maintaining the other attributes of the tablespace or tempfile. The optional KEEP clause defines a minimum size for the tablespace or tempfile. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Shrinking is an online operation, which means that user sessions can continue to allocate sort extents if needed, and already-running queries are not affected. -- shrink 是一个 online 的操作,不影响其他的查询。 示例一: The following example shrinks the locally managed temporary tablespace lmtmp1 to a size of 20M. SQL>ALTER TABLESPACE lmtemp1 SHRINK SPACE KEEP 20M; 示例二: The following example shrinks the tempfile lmtemp02.dbf of the locally managed temporary tablespace lmtmp2. Because the KEEP clause is omitted, the database attempts to shrink the tempfile to the minimum possible size. SQL>ALTER TABLESPACE lmtemp2 SHRINK TEMPFILE '/u02/oracle/data/lmtemp02.dbf'; 1.28 控制文件 Blog: http://blog.csdn.net/tianlesoftware/archive/2009/12/09/4974440.aspx 1.28.1 Oracle 控制文件主要包含如下条目 Database entry Checkpoint progress records Redo thread records Log file records Data file records Temp file records Tablespace records Log file history records Offline range records Archived log records Backup set records Backup piece records Backup datafile records Backup log records Datafile copy records Backup datafile corruption records Datafile copy corruption records Deletion records Proxy copy records Incarnation records Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.28.2 可以通过 dump 看到 控制文件内 1.28.2.1 直接 dump controlfile alter system set events 'immediate trace name controlf level 10' 1.28.2.2. 使用 alter database backup controlfile to filename 以上两种方法生成的 dump 文件是不可读的即乱码。 只有生成 trace 后,才 是可读的。 1.28.2.3. 使用 alter database backup controlfile to trace 生成的 trace 文件在 udump 目录下,可以通过日期来判断。 SQL>show parameter user_dump_dest 也可以使用如下 SQL 查询对应的 trace 文件: SELECT a.VALUE || b.symbol || c.instance_name || '_ora_' || d.spid || '.trc' trace_file FROM (SELECT VALUE FROM v$parameter WHERE name = 'user_dump_dest') a, (SELECT SUBSTR (VALUE, -6, 1) symbol FROM v$parameter WHERE name = 'user_dump_dest') b, (SELECT instance_name FROM v$instance) c, (SELECT spid FROM v$session s, v$process p, v$mystat m WHERE s.paddr = p.addr AND s.sid = m.sid AND m.statistic# = 0) d TRACE_FILE -------------------------------------------------------------------------------- /u01/app/oracle/admin/dave/udump/dave_ora_7215.trc 整个 Trace 的内容如下: [oracle@qs-dmm-rh2 udump]$ cat dave_ora_7215.trc /u01/app/oracle/admin/dave/udump/dave_ora_7215.trc Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options ORACLE_HOME = /u01/app/oracle/product/10.2.0/db_1 System name: Linux Node name: qs-dmm-rh2 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Release: 2.6.18-194.el5 Version: #1 SMP Tue Mar 16 21:52:43 EDT 2010 Machine: i686 Instance name: dave Redo thread mounted by this instance: 0 Oracle process number: 15 Unix process pid: 7215, image: oracle@qs-dmm-rh2 (TNS V1-V3) *** ACTION NAME:() 2011-03-17 22:05:46.401 *** MODULE NAME:(sqlplus@qs-dmm-rh2 (TNS V1-V3)) 2011-03-17 22:05:46.401 *** SERVICE NAME:() 2011-03-17 22:05:46.401 *** SESSION ID:(159.1) 2011-03-17 22:05:46.401 ORA-01160: file is not a data file ORA-01110: data file : '/u01/app/oracle/oradata/dave/temp01.dbf' *** 2011-03-17 22:08:25.791 Control file created with size 370 blocks *** 2011-03-17 22:10:21.444 tkcrrsarc: (WARN) Failed to find ARCH for message (message:0x1) tkcrrpa: (WARN) Failed initial attempt to send ARCH message (message:0x1) kwqmnich: current time:: 14: 10: 24 kwqmnich: instance no 0 check_only flag 1 kwqmnich: initialized job cache structure krvscm(+): Validating controlfile with logical metadata krvscm(+): Initial controlfile state krvscm(+): kccdiflg [400001] kccdifl2 [1000] krvscm(+): kccdi2ldscn [0x0000.00000000] krvscm(+): kccdi2lrscn [0x0000.00000000] krvscm(+): Inspecting logical metadata krvscm(+): Metadata state krvscm(+): hasPrepSwitchSta [0] krvscm(+): hasPrepSwitchPri [0] krvscm(+): hasReceivedDict [0] krvscm(+): hasDumpedDict [0] krvscm(+): hasCommittedBor [0] krvscm(+): hasSwitchedFromPri [0] krvscm(+): hasStartedTa [0] krvscm(+): hasValidSess [0] krvscm(+): hasTxnConsistency [0] krvscm(+): hasCleanlyShutdown [0] krvscm(+): Generating new controlfile state from metadata krvscm(+): Updating controlfile with new state krvscm(+): New controlfile state krvscm(+): kccdiflg [400001] kccdifl2 [1000] Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 krvscm(+): kccdi2ldscn [0x0000.00000000] krvscm(+): kccdi2lrscn [0x0000.00000000] krvscm(+): Updating SGA associated with controlfile state krvscm(+): Validation complete *** 2011-03-17 22:13:21.115 -- The following are current System-scope REDO Log Archival related -- parameters and can be included in the database initialization file. -- -- LOG_ARCHIVE_DEST='' -- LOG_ARCHIVE_DUPLEX_DEST='' -- -- LOG_ARCHIVE_FORMAT=%t_%s_%r.dbf -- -- DB_UNIQUE_NAME="dave_st" -- -- LOG_ARCHIVE_CONFIG='SEND, RECEIVE' -- LOG_ARCHIVE_CONFIG='DG_CONFIG=("dave_pd")' -- LOG_ARCHIVE_MAX_PROCESSES=2 -- STANDBY_FILE_MANAGEMENT=AUTO -- STANDBY_ARCHIVE_DEST=/u01/archivelog -- FAL_CLIENT=dave_st -- FAL_SERVER=dave_pd -- -- LOG_ARCHIVE_DEST_2='SERVICE=dave_pd' -- LOG_ARCHIVE_DEST_2='OPTIONAL REOPEN=120 NODELAY' -- LOG_ARCHIVE_DEST_2='LGWR NOAFFIRM NOEXPEDITE NOVERIFY ASYNC=61440' -- LOG_ARCHIVE_DEST_2='REGISTER NOALTERNATE NODEPENDENCY' -- LOG_ARCHIVE_DEST_2='NOMAX_FAILURE NOQUOTA_SIZE NOQUOTA_USED' -- LOG_ARCHIVE_DEST_2='DB_UNIQUE_NAME=dave_pd' -- LOG_ARCHIVE_DEST_2='VALID_FOR=(STANDBY_LOGFILE,STANDBY_RO LE)' -- LOG_ARCHIVE_DEST_STATE_2=ENABLE -- -- LOG_ARCHIVE_DEST_1='LOCATION=/u01/archivelog' -- LOG_ARCHIVE_DEST_1='OPTIONAL REOPEN=300 NODELAY' -- LOG_ARCHIVE_DEST_1='ARCH NOAFFIRM NOEXPEDITE NOVERIFY SYNC' -- LOG_ARCHIVE_DEST_1='REGISTER NOALTERNATE NODEPENDENCY' -- LOG_ARCHIVE_DEST_1='NOMAX_FAILURE NOQUOTA_SIZE NOQUOTA_USED' -- LOG_ARCHIVE_DEST_1='DB_UNIQUE_NAME=dave_st' Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 -- LOG_ARCHIVE_DEST_1='VALID_FOR=(PRIMARY_ROLE,ONLINE_LOGFILE S)' -- LOG_ARCHIVE_DEST_STATE_1=ENABLE -- -- Below are two sets of SQL statements, each of which creates a new -- control file and uses it to open the database. The first set opens -- the database with the NORESETLOGS option and should be used only if -- the current versions of all online logs are available. The second -- set opens the database with the RESETLOGS option and should be used -- if online logs are unavailable. -- The appropriate set of statements can be copied from the trace into -- a script file, edited as necessary, and executed when there is a -- need to re-create the control file. -- -- Set #1. NORESETLOGS case --对使用 noresetlogs 的说明 -- -- The following commands will create a new control file and use it -- to open the database. -- Data used by Recovery Manager will be lost. -- Additional logs may be required for media recovery of offline -- Use this only if the current versions of all online logs are -- available. -- After mounting the created controlfile, the following SQL -- statement will place the database in the appropriate -- protection mode: -- ALTER DATABASE SET STANDBY DATABASE TO MAXIMIZE PERFORMANCE STARTUP NOMOUNT CREATE CONTROLFILE REUSE DATABASE "DAVE" NORESETLOGS ARCHIVELOG MAXLOGFILES 16 MAXLOGMEMBERS 2 MAXDATAFILES 30 MAXINSTANCES 1 MAXLOGHISTORY 292 LOGFILE GROUP 1 '/u01/app/oracle/oradata/dave/redo01.log' SIZE 50M, GROUP 2 '/u01/app/oracle/oradata/dave/redo02.log' SIZE 50M, GROUP 3 '/u01/app/oracle/oradata/dave/redo03.log' SIZE 50M -- STANDBY LOGFILE DATAFILE '/u01/app/oracle/oradata/dave/system01.dbf', Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 '/u01/app/oracle/oradata/dave/undotbs01.dbf', '/u01/app/oracle/oradata/dave/sysaux01.dbf', '/u01/app/oracle/oradata/dave/users01.dbf' CHARACTER SET ZHS16GBK ; --以上是创建控制文件的语法 -- Commands to re-create incarnation table -- Below log names MUST be changed to existing filenames on -- disk. Any one log file from each branch can be used to -- re-create incarnation records. -- ALTER DATABASE REGISTER LOGFILE '/u01/archivelog/1_1_746031707.dbf'; -- Recovery is required if any of the datafiles are restored backups, -- or if the last shutdown was not normal or immediate. RECOVER DATABASE -- All logs need archiving and a log switch is needed. ALTER SYSTEM ARCHIVE LOG ALL; -- Database can now be opened normally. ALTER DATABASE OPEN; -- Commands to add tempfiles to temporary tablespaces. -- Online tempfiles have complete space information. -- Other tempfiles may require adjustment. ALTER TABLESPACE TEMP ADD TEMPFILE '/u01/app/oracle/oradata/dave/temp01.dbf' SIZE 32505856 REUSE AUTOEXTEND OFF; --这里是要注意的地方,重建控制文件的时候,不能写上临时表空间,等控制文 件创建完毕之后,在手工的执行 SQL 加上临时表空间。 -- End of tempfile additions. -- -- Set #2. RESETLOGS case --第二种情况,使用 resetlogs 的说明 -- -- The following commands will create a new control file and use it -- to open the database. -- Data used by Recovery Manager will be lost. -- The contents of online logs will be lost and all backups will -- be invalidated. Use this only if online logs are damaged. -- After mounting the created controlfile, the following SQL -- statement will place the database in the appropriate -- protection mode: -- ALTER DATABASE SET STANDBY DATABASE TO MAXIMIZE PERFORMANCE STARTUP NOMOUNT CREATE CONTROLFILE REUSE DATABASE "DAVE" RESETLOGS ARCHIVELOG Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 MAXLOGFILES 16 MAXLOGMEMBERS 2 MAXDATAFILES 30 MAXINSTANCES 1 MAXLOGHISTORY 292 LOGFILE GROUP 1 '/u01/app/oracle/oradata/dave/redo01.log' SIZE 50M, GROUP 2 '/u01/app/oracle/oradata/dave/redo02.log' SIZE 50M, GROUP 3 '/u01/app/oracle/oradata/dave/redo03.log' SIZE 50M -- STANDBY LOGFILE DATAFILE '/u01/app/oracle/oradata/dave/system01.dbf', '/u01/app/oracle/oradata/dave/undotbs01.dbf', '/u01/app/oracle/oradata/dave/sysaux01.dbf', '/u01/app/oracle/oradata/dave/users01.dbf' CHARACTER SET ZHS16GBK ; -- Commands to re-create incarnation table -- Below log names MUST be changed to existing filenames on -- disk. Any one log file from each branch can be used to -- re-create incarnation records. -- ALTER DATABASE REGISTER LOGFILE '/u01/archivelog/1_1_746031707.dbf'; -- Recovery is required if any of the datafiles are restored backups, -- or if the last shutdown was not normal or immediate. RECOVER DATABASE USING BACKUP CONTROLFILE -- Database can now be opened zeroing the online logs. ALTER DATABASE OPEN RESETLOGS; -- Commands to add tempfiles to temporary tablespaces. -- Online tempfiles have complete space information. -- Other tempfiles may require adjustment. ALTER TABLESPACE TEMP ADD TEMPFILE '/u01/app/oracle/oradata/dave/temp01.dbf' SIZE 32505856 REUSE AUTOEXTEND OFF; -- End of tempfile additions. -- 1.28.3 控制文件的重建 不到最后时刻,如三个控制文件都已损坏,又没有控制文件的备份。还是不 要重建控制文件,处理不好就会有数据丢失。 (1)db 启动到 mount 状态 SQL> startup nomount Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 (2)创建控制文件 create controlfile reuse database dave noresetlogs archivelog LOGFILE GROUP 1 '/u01/app/oracle/oradata/dave/redo01.log', GROUP 2 '/u01/app/oracle/oradata/dave/redo02.log', GROUP 3 '/u01/app/oracle/oradata/dave/redo03.log' DATAFILE '/u01/app/oracle/oradata/dave/sysaux01.dbf', '/u01/app/oracle/oradata/dave/system01.dbf', '/u01/app/oracle/oradata/dave/undotbs01.dbf', '/u01/app/oracle/oradata/dave/users01.dbf' CHARACTER SET ZHS16GBK; 我这里使用的是 noresetlogs,所以直接 open 数据库就可以了: SQL>alter database open; 如果是 resetlogs 创建的控制文件,那么我们就需要使用: SQL>alter database open resetlogs; 来打开 DB. (3)添加 TEMP 表空间 SQL> ALTER TABLESPACE TEMP ADD TEMPFILE '/u01/app/oracle/oradata/dave/temp01.dbf' size 100M; Tablespace altered. 注意: 如果使用 resetlogs 打开的数据库,就需要对 DB 做一次备份。 resetlogs 命令表示一个数据库逻辑生存期的结束和另一个数据库逻辑生存期 的开始,每次使用 resetlogs 命令的时候,SCN 不会被重置,不过 oracle 会重置 日志序列号,而且会重置联机重做日志内容. 这样做是为了防止不完全恢复后日志序列会发生冲突(因为现有日志和数据 文件间有了时间差)。 1.29 物化视图 1.30 视图 1.31 Oracle 参数分类 和 参数的查看方法 Blog:http://blog.csdn.net/tianlesoftware/archive/2010/05/13/5583655.aspx Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Oracle 数据库系统根据初始化参数文件 init.ora 中设置的参数来配置自身的 启动,每个实例在启动之前,首先读取这些参数文件中设置的不同参数。 Oracle 系统中的参数,根据系统使用情况可以简单分为两大类: 普通参数:也就是 Oracle 系统正常使用的一些参数, 非凡参数:包括三种,过时参数、强调参数和隐藏参数。 随着 Oracle 数据库新版本的发布,相应每次都会增加或者删除一些参数。下 面具体介绍如何查询当前系统版本中的各种参数情况。 1.31.1 过时参数 和 强调参数 Oracle 数据库中,系统提供了几个视图可以查看系统参数的情况。视图 V$OBSOLETE_PARAMETER 中 含 有 所 有 的 过 时 (obsolete) 和强调 (underscored) 参数。 这里首先说明一下什么是 Oracle 的过时 (obsolote) 和强调 (underscored) 参数,过时参数,顾名思义就是在 Oracle 以前的版本中存在,但在新版本中已 经淘汰了的参数,已经不再使用;而强调参数,是指那些在新版本中保留了下来, 但是除非非凡需要不希望用户使用的那些参数。在视图 V$OBSOLETE_PARAMETER 中,包含这些参数的名称和一个标志字 ISSPECIFIED ,该标志字用来指出这个参数是否在 init.ora 文件中已实际设置。 下面的 SQL 脚本列出了当前系统中所有的过时参数名称以及它们是否在当前 系统中设定。 /* Formatted on 2010-5-12 17:46:27 (QP5 v5.115.810.9015) */ SELECT name, isspecified FROM v$obsolete_parameter; 上面谈到, Oracle 系统并没有将 V$OBSOLETE_PARAMETER 视图中的 所有参数均丢弃,而是将其中的一部分转换为强调参数,下面就来讨论如何查看 这些参数是已被丢弃还是被转换。这可以通过系统视图 X$KSPPO 来查看,该 视图中包含一个名为 KSPPOFLAG 的字段,用来指明该参数在当前版本中是被 丢弃还是被强调,假如该值为 1 ,则表示该参数已被丢弃,该值为 2 ,则表明 该参数现为强调参数。 /* Formatted on 2010-5-12 17:46:06 (QP5 v5.115.810.9015) */ SELECT kspponm, DECODE (ksppoflg, 1, 'Obsolete', 2, 'Underscored') FROM x$ksppo ORDER BY kspponm; 注:该视图只在 sys 用户下可以看到。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.31.2 隐藏参数 Oracle 系统中还有一类参数称之为隐藏参数 (hidden parameters) ,是系统中 使用,但 Oracle 官方没有公布的参数,这些参数可能是那些还没有成熟或者是 系统开发中使用的参数。这些参数在所有 Oracle 官方提供的文档中都没有介 绍,他们的命名有一个共同特征就是都以 '_' 作为参数的首字符. 下面的查询可以得到当前系统中的所有隐藏参数,需要以 sys 用户登陆,查看 两个视图:x$ksppi, x$ksppcv. /* Formatted on 2010-5-12 17:45:46 (QP5 v5.115.810.9015) */ SELECT ksppinm, ksppstvl, ksppdesc FROM x$ksppi x, x$ksppcv y WHERE x.indx = y.indx AND TRANSLATE (ksppinm, '_', '#') LIKE '#%'; 或者用: /* Formatted on 2010-5-12 17:07:26 (QP5 v5.115.810.9015) */ SELECT i.ksppinm name, i.ksppdesc description, CV.ksppstvl VALUE, CV.ksppstdf isdefault, DECODE (BITAND (CV.ksppstvf, 7), 1, 'MODIFIED', 4, 'SYSTEM_MOD', 'FALSE') ismodified, DECODE (BITAND (CV.ksppstvf, 2), 2, 'TRUE', 'FALSE') isadjusted FROM sys.x$ksppi i, sys.x$ksppcv CV WHERE i.inst_id = USERENV ('Instance') AND CV.inst_id = USERENV ('Instance') AND i.indx = CV.indx AND i.ksppinm LIKE '/_%' ESCAPE '/' ORDER BY REPLACE (i.ksppinm, '_', ''); 1.31.3 系统当前参数 下面的脚本以英文字母顺序列出了系统当前使用的所有参数。在列出的参数 中,假如参数名称前面有 # 这个符号,则表示该参数没有明确指定,采用了系 统中的默认参数。 /* Formatted on 2010-5-12 17:44:11 (QP5 v5.115.810.9015) */ SELECT DECODE (isdefault, 'TRUE', '# '), DECODE (isdefault, 'TRUE', RPAD (name, 43), RPAD Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 (name, 45)), VALUE FROM v$parameter ORDER BY name; 注意:上面的 SQL 脚本没有列出系统中的隐藏参数。 1.32 Oracle 数据字典说明 Blog:http://blog.csdn.net/tianlesoftware/archive/2010/09/04/5862508.aspx 1.32.1 官网上有关数据字典的信息 关于 Oracle 的数据字典,官网的文档上有详细的说明,地址: Data Dictionary and Dynamic Performance Views http://download.oracle.com/docs/cd/E11882_01/server.112/e10713/datad ict.htm#CNCPT2140 Overview of the Data Dictionary An important part of an Oracle database is its data dictionary, which is a read-only set of tables that provides administrative metadata about the database. A data dictionary contains information such as the following:  The definitions of every schema object in the database, including default values for columns and integrity constraint information  The amount of space allocated for and currently used by the schema objects  The names of Oracle Database users, privileges and roles granted to users, and auditing information related to users (see "User Accounts") The data dictionary is a central part of data management for every Oracle database. For example, the database performs the following actions:  Accesses the data dictionary to find information about users, schema objects, and storage structures  Modifies the data dictionary every time that a DDL statement is issued (see "Data Definition Language (DDL) Statements") Because Oracle Database stores data dictionary data in tables, just like other data, users can query the data with SQL. For example, users can run SELECT Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 statements to determine their privileges, which tables exist in their schema, which columns are in these tables, whether indexes are built on these columns, and so on. Contents of the Data Dictionary The data dictionary consists of the following types of objects:  Base tables These underlying tables store information about the database. Only Oracle Database should write to and read these tables. Users rarely access the base tables directly because they are normalized and most data is stored in a cryptic format.  Views These views decode the base table data into useful information, such as user or table names, using joins and WHERE clauses to simplify the information. These views contain the names and description of all objects in the data dictionary. Some views are accessible to all database users, whereas others are intended for administrators only. Typically, data dictionary views are grouped in sets. In many cases, a set consists of three views containing similar information and distinguished from each other by their prefixes, as shown in Table 6-1. By querying the appropriate views, you can access only the information relevant for you. Data Dictionary View Sets Prefix User Access Contents Notes DBA_ Database administrators All objects Some DBA_ views have additional columns containing information useful to the administrator. ALL_ All users Objects to which user has privileges Includes objects owned by user. These views obey the current set of enabled roles. USER_ All users Objects owned by user Views with the prefix USER_ usually Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Prefix User Access Contents Notes exclude the column OWNER. This column is implied in the USER_ views to be the user issuing the query. Not all views sets have three members. For example, the data dictionary contains a DBA_LOCK view but no ALL_LOCK view. The system-supplied DICTIONARY view contains the names and abbreviated descriptions of all data dictionary views. The following query of this view includes partial sample output: SQL> SELECT * FROM DICTIONARY ORDER BY TABLE_NAME; TABLE_NAME COMMENTS ------------------------------ ---------------------------------------- ALL_ALL_TABLES Description of all object and relational tables accessible to the user ALL_APPLY Details about each apply process that dequeues from the queue visible to the current user Views with the Prefix DBA_ Views with the prefix DBA_ show all relevant information in the entire database. DBA_ views are intended only for administrators. For example, the following query shows information about all objects in the database: SELECT OWNER, OBJECT_NAME, OBJECT_TYPE FROM DBA_OBJECTS ORDER BY OWNER, OBJECT_NAME; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Views with the Prefix ALL_ Views with the prefix ALL_ refer to the user's overall perspective of the database. These views return information about schema objects to which the user has access through public or explicit grants of privileges and roles, in addition to schema objects that the user owns. For example, the following query returns information about all the objects to which you have access: SELECT OWNER, OBJECT_NAME, OBJECT_TYPE FROM ALL_OBJECTS ORDER BY OWNER, OBJECT_NAME; Because the ALL_ views obey the current set of enabled roles, query results depend on which roles are enabled, as shown in the following example: SQL> SET ROLE ALL; Role set. SQL> SELECT COUNT(*) FROM ALL_OBJECTS; COUNT(*) ---------- 68295 SQL> SET ROLE NONE; Role set. SQL> SELECT COUNT(*) FROM ALL_OBJECTS; COUNT(*) ---------- 53771 Application developers should be cognizant of the effect of roles when using ALL_ views in a stored procedure, where roles are not enabled by default. Views with the Prefix USER_ The views most likely to be of interest to typical database users are those with the prefix USER_. These views: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907  Refer to the user's private environment in the database, including metadata about schema objects created by the user, grants made by the user, and so on  Display only rows pertinent to the user, returning a subset of the information in the ALL_ views  Has columns identical to the other views, except that the column OWNER is implied  Can have abbreviated PUBLIC synonyms for convenience For example, the following query returns all the objects contained in your schema: SELECT OBJECT_NAME, OBJECT_TYPE FROM USER_OBJECTS ORDER BY OBJECT_NAME; The DUAL Table DUAL is a small table in the data dictionary that Oracle Database and user-written programs can reference to guarantee a known result. The dual table is useful when a value must be returned only once, for example, the current date and time. All database users have access to DUAL. The DUAL table has one column called DUMMY and one row containing the value X. The following example queries DUAL to perform an arithmetical operation: SQL> SELECT ((3*4)+5)/3 FROM DUAL; ((3*4)+5)/3 ----------- 5.66666667 Oracle Dual 表详解 http://blog.csdn.net/tianlesoftware/archive/2009/11/04/4764326.aspx 1.32.2 数据字典 Oracle 数据字典是有表和视图组成,存储有关数据库结构信息的一些数据库 对象。数据库字典描述了实际数据是如何组织的。比如一个表的创建者信息,创Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 建时间信息,所属表空间信息,用户访问权限信息等。对它们可以象处理其他数 据库表或视图一样进行查询,但不能进行任何修改。它们存放在 SYSTEM 表空 间中,当用户在对数据库中的数据进行操作时遇到困难就可以访问数据字典来查 看详细的信息。用户可以用 SQL 语句访问数据库数据字典。 Oracle 数据库字典通常是在创建和安装数据库时被创建的,Oracle 数据字典 是 Oracle 数据库系统工作的基础,没有数据字典的支持,Oracle 数据库系统就不 能进行任何工作。数据字典中的表是不能直接被访问的,但是可以访问数据字典 中的视图。 1.32.2.1 数据字典内容包括 1,数据库中所有模式对象的信息,如表、视图、簇、及索引等。 2,分配多少空间,当前使用了多少空间等。 3,列的缺省值。 4,约束信息的完整性。 5,Oracle 用户的名字。 6,用户及角色被授予的权限。 7,用户访问或使用的审计信息。 8,其它产生的数据库信息。 1.32.2.2 数据字典分为 数据字典表 和 数据字典视图 1.32.2.2.1 数据字典表 数据字典表里的数据是 Oracle 系统存放的系统数据,而普通表存放的是用户 的数据。为了方便的区别这些表,这些表的名字都是用"$"结尾,这些表属于 SYS 用户。 数据字典表由$ORACLE_HOME/rdbms/admin/sql.bsq 脚本创建, 这个脚本 里又调用了其他的脚本来创建这些数据字典表。 在那些创建脚本里有基表的创 建 SQL。 感兴趣的自己打开看看。 Oracle 对数据字典表的说明: These underlying tables store information about the database. Only Oracle Database should write to and read these tables. Users rarely access the base tables directly because they are normalized and most data is stored in a cryptic format. 这些数据字典表,只有 Oracle 能够进行读写。 SYS 用户下的这些数据字典表,存放在 system 表空间下面,表名都用"$"结 尾,为了便于用户对数据字典表的查询, Oracle 对这些数据字典都分别建立了 用户视图,这样即容易记住,还隐藏了数据字典表表之间的关系,Oracle 针对这 些对象的范围,分别把视图命名为 DBA_XXXX, ALL_XXXX 和 USER_XXXX。 关于这 3 类视图,下面有介绍。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Oracle 为了便于汇总数据字典表的信息,把所有的数据字典都汇集到 dictionary 表里了,通过对这个表的查询,我们可以很方便的找到数据库提供的 数据字典。 1.32.2.2.2 数据字典视图 动态性能视图由脚本:$ORACLE_HOME/rdbms/admin/catalog.sql 创建, 该 脚本也只是一个总的调用,在该脚本里由调用了其他的脚本。 感兴趣的可以自 己打开看一下,在那些脚本里,可以看到视图的创建 SQL. 这是因为这个脚本会创建动态视图,所以在做 DB 升级的时候,也需要执行 这个脚本,重新创建视图。 数据字典视图分 2 类:静态数据字典(静态性能视图) 和 动态数据字典(动 态性能视图) (1) 静态数据字典(静态性能视图) 静态数据字典中的视图分为三类,它们分别由三个前缀够成:user_*、 all_*、 dba_*。 user_*:该视图存储了关于当前用户所拥有的对象的信息。(即所有在该用户 模式下的对象) all_*:该试图存储了当前用户能够访问的对象的信息, 而不是当前用户拥有 的对象。(与 user_*相比,all_* 并不需要拥有该对象,只需要具有访问该对象的 权限即可) dba_*:该视图存储了数据库中所有对象的信息。(前提是当前用户具有访问 这些数据库的权限,一般来说必须具有管理员权限) 这些视图由 SYS 用户创建的,所以使用需要加上 SYS,为了方便, Oracle 为 每个数据字典表的视图头建立了同名字的公共同义词(public synonyms). 这样简 单的处理就省去了写 sys.的麻烦。 示例: (1)user_tables:主要描述当前用户拥有的所有表的信息,主要包括表名、 表空间名、簇名等。通过此视图可以清楚了解当前用户可以操作的表有哪些。 SQL>select * from user_tables; (2)user_indexes: 查询该用户拥有哪些索引。 SQL>select index_name from user_indexes; (3)user_views: 查询该用户拥有哪些视图 SQL>select view_name from user_views; (4)user_objects:查询该用户拥有哪些数据库对象,对象包括表、视图、存 储过程、触发器、包、索引、序列、JAVA 文件等。 SQL>select object_name from user_objects; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 (5)user_users:主要描述当前用户的信息,主要包括当前用户名、帐户 id、 帐户状态、表空间名、创建时间等。 SQL>select * from user_users; (6)all_objects:查询某一用户下的所有表、过程、函数等信息。 SQL>select owner , object_name ,object_type from all_objects (2) 动态数据字典(动态性能视图) 除了静态数据字典中三类视图,其他的字典视图中主要的是 V$视图,之所 以这样叫是因为他们都是以 V$或 GV$开头的。这些视图会不断的进行更新,从 而提供了关于内存和磁盘的运行情况,所以我们只能对其进行只读访问而不能修 改它们。 Throughout its operation, Oracle Database maintains a set of virtual tables that record current database activity. These views are called dynamic performance views because they are continuously updated while a database is open and in use. The views, also sometimes called V$ views。 V$视图是基于 X$虚拟视图的。V$视图是 SYS 用户所拥有的,在缺省状况下, 只有 SYS 用户和拥有 DBA 系统权限的用户可以看到所有的视图,没有 DBA 权 限的用户可以看到 USER_和 ALL_视图,但不能看到 DBA_视图。与 DBA_,ALL, 和 USER_视图中面向数据库信息相反,这些视图可视的给出了面向实例的信息。 动态性能表用于记录当前数据库的活动,只存于数据库运行期间,实际的信 息都取自内存和控制文件。 DBA 可以使用动态视图来监视和调节数据。 关于动态性能视图,参考: Oracle 动态性能视图 http://blog.csdn.net/tianlesoftware/archive/2010/09/04/5863191.aspx 1.32.2.3 视图家族 在 Oracle 的绝大多数数据字典视图中都有象 DBA_TABLES,ALL_TABLES 和 USER_TABLES 这样的视图家族。Oracle 中有超过 100 个视图家族,下表列 出了最重要和最常用的视图家族,需要注意的是每个视图家族都有一个 DBA_, 一个 ALL_ 和一个 USER_视图。 视图家族 描述 COL_PRIVS 包含了表的列权限,包括授予者、被授予者和权限 EXTENTS 数据范围信息,比如数据文件,数据段名(segment_name)和大小 INDEXES 索引信息,比如类型、唯一性和被涉及的表 IND_COLUMNS 索引列信息,比如索引上的列的排序方式 OBJECTS 对象信息,比如状态和 DDL time Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 ROLE_PRIVS 角色权限,比如 GRANT 和 ADMIN 选项 SEGMENTS 表和索引的数据段信息,比如 tablespace 和 storage SEQUECNCES 序列信息,比如序列的 cache、cycle 和 ast_number SOURCE 除触发器之外的所有内置过程、函数、包的源代码 SYNONYMS 别名信息,比如引用的对象和数据库链接 db_link SYS_PRIVS 系统权限,比如 grantee、privilege、admin 选项 TAB_COLUMNS 表和视图的列信息,包括列的数据类型 TAB_PRIVS 表权限,比如授予者、被授予者和权限 TABLES 表信息,比如表空间(tablespace),存储参数(storage parms)和数据行 的数量 TRIGGERS 触发器信息,比如类型、事件、触发体(trigger body) USERS 用户信息,比如临时的和缺省的表空间 VIEWS 视图信息,包括视图定义 在 Oracle 中还有一些不常用的数据字典表,但这些表不是真正的字典家族, 他们都是一些重要的单一的视图。这些视图见下表: 视图名称 描述 USER_COL_PRIVS_MADE 用户授予他人的列权限 USER_COL_PRIVS_RECD 用户获得的列权限 USER_TAB_PRIVS_MADE 用户授予他人的表权限 USER_TAB_PRIVS_RECD 用户获得的表权限 1.32.2.4 查看数据字典 我们通过 dictionary 字典来查看所有的视图和其描述。 该表只有 2 个字段: 表名和描述 SQL> desc dictionary 名称 是否为空? 类型 ----------------------------------------- -------- ------------------------- TABLE_NAME VARCHAR2(30) COMMENTS VARCHAR2(4000) 我们可以用以下 SQL 来查看所有数据字典对象: SQL>select * from dictionary; Oracle 11g 中有 2592 个对象。 SQL> select count(*) from dictionary; COUNT(*) ---------- 2592 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 部分数据如下表: 视图名 描述 ALL_CATALOG All tables, views, synonyms, sequences accessible to the user ALL_COL_COMMENTS Comments on columns of accessible tables and views ALL_COL_GRANTS_MADE Grants on columns for which the user is owner or grantor ALL_COL_GRANTS_RECD Grants on columns for which the user or PUBLIC is the grantee ALL_COL_PRIVS Grants on columns for which the user is the grantor, grantee, owner, or an enabled role or PUBLIC is the grantee ALL_COL_PRIVS_MADE Grants on columns for which the user is owner or grantor ALL_COL_PRIVS_RECD Grants on columns for which the user, PUBLIC or enabled role is the grantee ALL_CONSTRAINTS Constraint definitions on accessible tables ALL_CONS_COLUMNS Information about accessible columns in constraint definitions ALL_DB_LINKS Database links accessible to the user ALL_DEF_AUDIT_OPTS Auditing options for newly created objects ALL_DEPENDENCIES Dependencies to and from objects accessible to the user ALL_ERRORS Current errors on stored objects that user is allowed to create ALL_INDEXES Descriptions of indexes on tables accessible to the user ALL_IND_COLUMNS COLUMNs comprising INDEXes on accessible TABLES ALL_OBJECTS Objects accessible to the user ALL_REFRESH All the refresh groups that the user can touch ALL_REFRESH_CHILDREN All the objects in refresh groups, where the user can touch the group ALL_SEQUENCES Description of SEQUENCEs accessible to the user ALL_SNAPSHOTS Snapshots the user can look at ALL_SOURCE Current source on stored objects that user is allowed to create ALL_SYNONYMS All synonyms accessible to the user Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 ALL_TABLES Description of tables accessible to the user ALL_TAB_COLUMNS Columns of all tables, views and clusters ALL_TAB_COMMENTS Comments on tables and views accessible to the user ALL_TAB_GRANTS_MADE User's grants and grants on user's objects ALL_TAB_GRANTS_RECD Grants on objects for which the user or PUBLIC is the grantee ALL_TAB_PRIVS Grants on objects for which the user is the grantor, grantee, owner, or an enabled role or PUBLIC is the grantee ALL_TAB_PRIVS_MADE User's grants and grants on user's objects ALL_TAB_PRIVS_RECD Grants on objects for which the user, PUBLIC or enabled role is the grantee ALL_TRIGGERS Triggers accessible to the current user ALL_TRIGGER_COLS Column usage in user's triggers or in triggers on user's tables ALL_USERS Information about all users of the database ALL_VIEWS Text of views accessible to the user USER_AUDIT_CONNECT Audit trail entries for user logons/logoffs USER_AUDIT_OBJECT Audit trail records for statements concerning objects, specifically: table, cluster, view, index, sequence, [public] database link, [public] synonym, procedure, trigger, rollback segment, tablespace, role, user USER_AUDIT_SESSION USER_AUDIT_STATEMENT Audit trail records concerning grant, revoke, audit, noaudit and alter system USER_AUDIT_TRAIL Audit trail entries relevant to the user USER_CATALOG Tables, Views, Synonyms and Sequences owned by the user USER_CLUSTERS Descriptions of user's own clusters USER_CLU_COLUMNS Mapping of table columns to cluster columns USER_COL_COMMENTS Comments on columns of user's tables and views USER_COL_GRANTS Grants on columns for which the user is the owner, grantor or grantee USER_COL_GRANTS_MADE All grants on columns of objects owned by the user USER_COL_GRANTS_RECD Grants on columns for which the user is the grantee USER_COL_PRIVS Grants on columns for which the user is the owner, grantor or grantee Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 USER_COL_PRIVS_MADE All grants on columns of objects owned by the user USER_COL_PRIVS_RECD Grants on columns for which the user is the grantee USER_CONSTRAINTS Constraint definitions on user's own tables USER_CONS_COLUMNS Information about accessible columns in constraint definitions USER_CROSS_REFS Cross references for user's views and synonyms USER_DB_LINKS Database links owned by the user USER_DEPENDENCIES Dependencies to and from a users objects USER_ERRORS Current errors on stored objects owned by the user USER_EXTENTS Extents comprising segments owned by the user USER_FREE_SPACE Free extents in tablespaces accessible to the user USER_INDEXES Description of the user's own indexes USER_IND_COLUMNS COLUMNs comprising user's INDEXes or on user's TABLES USER_JOBS All jobs owned by this user USER_OBJECTS Objects owned by the user USER_OBJECT_SIZE Sizes, in bytes, of various pl/sql objects USER_OBJ_AUDIT_OPTS Auditing options for user's own tables and views USER_REFRESH All the refresh groups USER_REFRESH_CHILDREN All the objects in refresh groups, where the user owns the refresh group USER_RESOURCE_LIMITS Display resource limit of the user USER_ROLE_PRIVS Roles granted to current user USER_SEGMENTS Storage allocated for all database segments USER_SEQUENCES Description of the user's own SEQUENCEs USER_SNAPSHOTS Snapshots the user can look at USER_SNAPSHOT_LOGS All snapshot logs owned by the user USER_SOURCE Source of stored objects accessible to the user USER_SYNONYMS The user's private synonyms USER_SYS_PRIVS System privileges granted to current user USER_TABLES Description of the user's own tables USER_TABLESPACES Description of accessible tablespaces USER_TAB_AUDIT_OPTS Auditing options for user's own tables and views USER_TAB_COLUMNS Columns of user's tables, views and clusters USER_TAB_COMMENTS Comments on the tables and views owned by the user USER_TAB_GRANTS Grants on objects for which the user is the Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 owner, grantor or grantee USER_TAB_GRANTS_MADE All grants on objects owned by the user USER_TAB_GRANTS_RECD Grants on objects for which the user is the grantee USER_TAB_PRIVS Grants on objects for which the user is the owner, grantor or grantee USER_TAB_PRIVS_MADE All grants on objects owned by the user USER_TAB_PRIVS_RECD Grants on objects for which the user is the grantee USER_TRIGGERS Triggers owned by the user USER_TRIGGER_COLS Column usage in user's triggers USER_TS_QUOTAS Tablespace quotas for the user USER_USERS Information about the current user USER_VIEWS Text of views owned by the user AUDIT_ACTIONS Description table for audit trail action type codes. Maps action type numbers to action type names COLUMN_PRIVILEGES Grants on columns for which the user is the grantor, grantee, owner, or an enabled role or PUBLIC is the grantee DICTIONARY Description of data dictionary tables and views DICT_COLUMNS Description of columns in data dictionary tables and views DUAL GLOBAL_NAME global database name INDEX_HISTOGRAM statistics on keys with repeat count INDEX_STATS statistics on the b-tree RESOURCE_COST Cost for each resource ROLE_ROLE_PRIVS Roles which are granted to roles ROLE_SYS_PRIVS System privileges granted to roles ROLE_TAB_PRIVS Table privileges granted to roles SESSION_PRIVS Privileges which the user currently has set SESSION_ROLES Roles which the user currently has enabled. TABLE_PRIVILEGES Grants on objects for which the user is the grantor, grantee, owner, or an enabled role or PUBLIC is the grantee ACCESSIBLE_COLUMNS Synonym for ALL_TAB_COLUMNS ALL_COL_GRANTS Synonym for COLUMN_PRIVILEGES ALL_JOBS Synonym for USER_JOBS ALL_TAB_GRANTS Synonym for TABLE_PRIVILEGES CAT Synonym for USER_CATALOG Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 CLU Synonym for USER_CLUSTERS COLS Synonym for USER_TAB_COLUMNS DBA_AUDIT_CONNECT Synonym for USER_AUDIT_CONNECT DBA_AUDIT_RESOURCE Synonym for USER_AUDIT_RESOURCE DBA_REFRESH_CHILDREN Synonym for USER_REFRESH_CHILDREN DICT Synonym for DICTIONARY IND Synonym for USER_INDEXES OBJ Synonym for USER_OBJECTS SEQ Synonym for USER_SEQUENCES SM$VERSION Synonym for SM_$VERSION SYN Synonym for USER_SYNONYMS TABS Synonym for USER_TABLES V$ACCESS Synonym for V_$ACCESS V$ARCHIVE Synonym for V_$ARCHIVE V$BACKUP Synonym for V_$BACKUP V$BGPROCESS Synonym for V_$BGPROCESS V$CIRCUIT Synonym for V_$CIRCUIT V$COMPATIBILITY Synonym for V_$COMPATIBILITY V$COMPATSEG Synonym for V_$COMPATSEG V$CONTROLFILE Synonym for V_$CONTROLFILE V$DATABASE Synonym for V_$DATABASE V$DATAFILE Synonym for V_$DATAFILE V$DBFILE Synonym for V_$DBFILE V$DBLINK Synonym for V_$DBLINK V$DB_OBJECT_CACHE Synonym for V_$DB_OBJECT_CACHE V$DISPATCHER Synonym for V_$DISPATCHER V$ENABLEDPRIVS Synonym for V_$ENABLEDPRIVS V$FILESTAT Synonym for V_$FILESTAT V$FIXED_TABLE Synonym for V_$FIXED_TABLE V$LATCH Synonym for V_$LATCH V$LATCHHOLDER Synonym for V_$LATCHHOLDER V$LATCHNAME Synonym for V_$LATCHNAME V$LIBRARYCACHE Synonym for V_$LIBRARYCACHE V$LICENSE Synonym for V_$LICENSE V$LOADCSTAT Synonym for V_$LOADCSTAT V$LOADTSTAT Synonym for V_$LOADTSTAT V$LOCK Synonym for V_$LOCK V$LOG Synonym for V_$LOG V$LOGFILE Synonym for V_$LOGFILE V$LOGHIST Synonym for V_$LOGHIST Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 V$LOG_HISTORY Synonym for V_$LOG_HISTORY V$MLS_PARAMETERS Synonym for V_$MLS_PARAMETERS V$MTS Synonym for V_$MTS V$NLS_PARAMETERS Synonym for V_$NLS_PARAMETERS V$NLS_VALID_VALUES Synonym for V_$NLS_VALID_VALUES V$OPEN_CURSOR Synonym for V_$OPEN_CURSOR V$OPTION Synonym for V_$OPTION V$PARAMETER Synonym for V_$PARAMETER V$PQ_SESSTAT Synonym for V_$PQ_SESSTAT V$PQ_SLAVE Synonym for V_$PQ_SLAVE V$PQ_SYSSTAT Synonym for V_$PQ_SYSSTAT V$PROCESS Synonym for V_$PROCESS V$QUEUE Synonym for V_$QUEUE V$RECOVERY_LOG Synonym for V_$RECOVERY_LOG V$RECOVER_FILE Synonym for V_$RECOVER_FILE V$REQDIST Synonym for V_$REQDIST V$RESOURCE Synonym for V_$RESOURCE V$ROLLNAME Synonym for V_$ROLLNAME V$ROLLSTAT Synonym for V_$ROLLSTAT V$ROWCACHE Synonym for V_$ROWCACHE V$SESSION Synonym for V_$SESSION V$SESSION_CURSOR_CACHE Synonym for V_$SESSION_CURSOR_CACHE V$SESSION_EVENT Synonym for V_$SESSION_EVENT V$SESSION_WAIT Synonym for V_$SESSION_WAIT V$SESSTAT Synonym for V_$SESSTAT V$SESS_IO Synonym for V_$SESS_IO V$SGA Synonym for V_$SGA V$SGASTAT Synonym for V_$SGASTAT V$SHARED_SERVER Synonym for V_$SHARED_SERVER V$SQLAREA Synonym for V_$SQLAREA V$STATNAME Synonym for V_$STATNAME V$SYSSTAT Synonym for V_$SYSSTAT V$SYSTEM_CURSOR_CACHE Synonym for V_$SYSTEM_CURSOR_CACHE V$SYSTEM_EVENT Synonym for V_$SYSTEM_EVENT V$THREAD Synonym for V_$THREAD V$TIMER Synonym for V_$TIMER V$TRANSACTION Synonym for V_$TRANSACTION V$TYPE_SIZE Synonym for V_$TYPE_SIZE V$VERSION Synonym for V_$VERSION V$WAITSTAT Synonym for V_$WAITSTAT Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 V$_LOCK Synonym for V_$_LOCK 1.33 Oracle 数据字典表 -- SYS.COL$ Blog:http://blog.csdn.net/tianlesoftware/archive/2011/01/28/6168314.aspx 1.33.1 数据字典表 SYS.COL$ 说明 Oracle 的数据字典分两类,一个数据字典表,另一个是数据字典视图。 数据字典表里的数据是 Oracle 系统存放的系统数据,而普通表存放的是用户 的数据。为了方便的区别这些表,这些表的名字都是用"$"结尾,这些表属于 SYS 用户。 数据字典表由$ORACLE_HOME/rdbms/admin/sql.bsq 脚本创建。 这些数据字典表名称不好记,所以 Oracle 又根据这些表创建了一些视图。 即 方便使用,又影藏了那些数据字典表。 关于数据字典的更多内容,参考 1.32 小节的内容。 这里讲的 SYS.COL$表保存的就是表列的定义信息,但是我们查询表列的信 息时,却不是直接查询 SYS.COL$,而是查询 USER_TAB_COLUMNS 视图。 SQL> select owner,object_name,object_type from all_objects where object_name='COL$'; OWNER OBJECT_NAME OBJECT_TYPE ----------------- ------------------------------ ------------------ SYS COL$ TABLE SQL> set long 9999 SQL> select text from dba_views where view_name ='USER_TAB_COLUMNS'; TEXT -------------------------------------------------------------------------------- select TABLE_NAME, COLUMN_NAME, DATA_TYPE, DATA_TYPE_MOD, DATA_TYPE_OWNER, DATA_LENGTH, DATA_PRECISION, DATA_SCALE, NULLABLE, COLUMN_ID, DEFAULT_LENGTH, DATA_DEFAULT, NUM_DISTINCT, LOW_VALUE, HIGH_VALUE, DENSITY, NUM_NULLS, NUM_BUCKETS, LAST_ANALYZED, SAMPLE_SIZE, CHARACTER_SET_NAME, CHAR_COL_DECL_LENGTH, GLOBAL_STATS, USER_STATS, AVG_COL_LEN, CHAR_LENGTH, CHAR_USED, V80_FMT_IMAGE, DATA_UPGRADED, HISTOGRAM Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 from USER_TAB_COLS where HIDDEN_COLUMN = 'NO' 这里查看的是 USER_TAB_COLS 视图,我们在挖一层: SQL>select * from dba_views where view_name ='USER_TAB_COLS' select o.name, c.name, decode(c.type#, 1, decode(c.charsetform, 2, 'NVARCHAR2', 'VARCHAR2'), 2, decode(c.scale, null, decode(c.precision#, null, 'NUMBER', 'FLOAT'), 'NUMBER'), 8, 'LONG', 9, decode(c.charsetform, 2, 'NCHAR VARYING', 'VARCHAR'), 12, 'DATE', 23, 'RAW', 24, 'LONG RAW', 58, nvl2(ac.synobj#, (select o.name from obj$ o where o.obj#=ac.synobj#), ot.name), 69, 'ROWID', 96, decode(c.charsetform, 2, 'NCHAR', 'CHAR'), 100, 'BINARY_FLOAT', 101, 'BINARY_DOUBLE', 105, 'MLSLABEL', 106, 'MLSLABEL', 111, nvl2(ac.synobj#, (select o.name from obj$ o where o.obj#=ac.synobj#), ot.name), 112, decode(c.charsetform, 2, 'NCLOB', 'CLOB'), 113, 'BLOB', 114, 'BFILE', 115, 'CFILE', 121, nvl2(ac.synobj#, (select o.name from obj$ o where o.obj#=ac.synobj#), ot.name), 122, nvl2(ac.synobj#, (select o.name from obj$ o where o.obj#=ac.synobj#), ot.name), 123, nvl2(ac.synobj#, (select o.name from obj$ o where o.obj#=ac.synobj#), ot.name), 178, 'TIME(' ||c.scale|| ')', 179, 'TIME(' ||c.scale|| ')' || ' WITH TIME ZONE', 180, 'TIMESTAMP(' ||c.scale|| ')', 181, 'TIMESTAMP(' ||c.scale|| ')' || ' WITH TIME ZONE', 231, 'TIMESTAMP(' ||c.scale|| ')' || ' WITH LOCAL TIME ZONE', 182, 'INTERVAL YEAR(' ||c.precision#||') TO MONTH', 183, 'INTERVAL DAY(' ||c.precision#||') TO SECOND(' || c.scale || ')', 208, 'UROWID', 'UNDEFINED'), decode(c.type#, 111, 'REF'), Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 nvl2(ac.synobj#, (select u.name from "_BASE_USER" u, obj$ o where o.owner#=u.user# and o.obj#=ac.synobj#), ut.name), c.length, c.precision#, c.scale, decode(sign(c.null$),-1,'D', 0, 'Y', 'N'), decode(c.col#, 0, to_number(null), c.col#), c.deflength, c.default$, h.distcnt, h.lowval, h.hival, h.density, h.null_cnt, case when nvl(h.distcnt,0) = 0 then h.distcnt when h.row_cnt = 0 then 1 when (h.bucket_cnt > 255 or (h.bucket_cnt > h.distcnt and h.row_cnt = h.distcnt and h.density*h.bucket_cnt < 1)) then h.row_cnt else h.bucket_cnt end, h.timestamp#, h.sample_size, decode(c.charsetform, 1, 'CHAR_CS', 2, 'NCHAR_CS', 3, NLS_CHARSET_NAME(c.charsetid), 4, 'ARG:'||c.charsetid), decode(c.charsetid, 0, to_number(NULL), nls_charset_decl_len(c.length, c.charsetid)), decode(bitand(h.spare2, 2), 2, 'YES', 'NO'), decode(bitand(h.spare2, 1), 1, 'YES', 'NO'), h.avgcln, c.spare3, decode(c.type#, 1, decode(bitand(c.property, 8388608), 0, 'B', 'C'), 96, decode(bitand(c.property, 8388608), 0, 'B', 'C'), null), decode(bitand(ac.flags, 128), 128, 'YES', 'NO'), decode(o.status, 1, decode(bitand(ac.flags, 256), 256, 'NO', 'YES'), decode(bitand(ac.flags, 2), 2, 'NO', decode(bitand(ac.flags, 4), 4, 'NO', decode(bitand(ac.flags, 8), 8, 'NO', 'N/A')))), decode(c.property, 0, 'NO', decode(bitand(c.property, 32), 32, 'YES', 'NO')), decode(c.property, 0, 'NO', decode(bitand(c.property, 8), 8, 'YES', 'NO')), decode(c.segcol#, 0, to_number(null), c.segcol#), c.intcol#, case when nvl(h.row_cnt,0) = 0 then 'NONE' when (h.bucket_cnt > 255 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 or (h.bucket_cnt > h.distcnt and h.row_cnt = h.distcnt and h.density*h.bucket_cnt < 1)) then 'FREQUENCY' else 'HEIGHT BALANCED' end, decode(bitand(c.property, 1024), 1024, (select decode(bitand(cl.property, 1), 1, rc.name, cl.name) from sys.col$ cl, attrcol$ rc where cl.intcol# = c.intcol#-1 and cl.obj# = c.obj# and c.obj# = rc.obj#(+) and cl.intcol# = rc.intcol#(+)), decode(bitand(c.property, 1), 0, c.name, (select tc.name from sys.attrcol$ tc where c.obj# = tc.obj# and c.intcol# = tc.intcol#))) from sys.col$ c, sys."_CURRENT_EDITION_OBJ" o, sys.hist_head$ h, sys.coltype$ ac, sys.obj$ ot, sys."_BASE_USER" ut where o.obj# = c.obj# and bitand(o.flags, 128) = 0 and o.owner# = userenv('SCHEMAID') and c.obj# = h.obj#(+) and c.intcol# = h.intcol#(+) and c.obj# = ac.obj#(+) and c.intcol# = ac.intcol#(+) and ac.toid = ot.oid$(+) and ot.type#(+) = 13 and ot.owner# = ut.user#(+) and (o.type# in (3, 4) /* cluster, view */ or (o.type# = 2 /* tables, excluding iot - overflow and nested tables */ and not exists (select null from sys.tab$ t where t.obj# = o.obj# and (bitand(t.property, 512) = 512 or bitand(t.property, 8192) = 8192)))) 在这里,我们看到了本质:sys.col$ 。 Oracle 数据库没有提供直接修改表中列名称的功能,但在实际使用时常需要 修改表的列名和列顺序。 我们可以通过间接的方法来实现,就是重新创建一个新的具有正确列名和顺 序的数据库表,再将旧表的数据转储进来,最后删除旧表并将新表重命名为旧表 的方法来完成此功能。 这种方法的最大问题是要求有双倍的存储空间、较大的回滚段和较长的时 间,如果表中数据量较大,这项工作开销会很大。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 而 SYS.COL$保存的就是表列的信息,所以我们可以直接修改这个表列的信 息,从而改变表中列的顺序。 当然 Oracle 是不建议这么操作的。 这里也只做 个知识点了解一下。 1.33.2 SYS.COL$ 示例 1.33.2.1 创建测试表 SQL> conn dave/dave; 已连接。 SQL> create table myuser as select username,user_id from all_users; 表已创建。 SQL> select * from myuser where rownum=1; USERNAME USER_ID ------------------------------ ---------- DAVE 90 下面的操作就是将 2 个列换一下顺序,并将列名改为 ID 和 NAME. 1.33.2.2 从 ALL_OBJECTS 中查找对象 DAVE.MYUSER 表的 ID 在第一节里我们将了,对象的表列信息是存放在 SYS.COL$表里的,要修改对 象的列,就需要知道对象的 ID. SQL> SELECT OBJECT_NAME,OBJECT_ID FROM ALL_OBJECTS WHERE OWNER ='DAVE' AND OBJECT_NAME='MYUSER'; OBJECT_NAME OBJECT_ID ------------------------------ ---------- MYUSER 74344 1.33.2.3 根据 MYUSER 的 ID,从 SYS.COL$检索出表中列的定义信息 SQL> conn / as sysdba; 已连接。 SQL> SELECT OBJ#,COL#,NAME FROM SYS.COL$ WHERE OBJ# =74344; OBJ# COL# NAME ---------- ---------- ------------------------------ 74344 1 USERNAME 74344 2 USER_ID 注意:SYS.COL$ 只能 sys 用户才有权限查询。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.33.2.4 使用 Update 语句来进行修改 SQL> UPDATE SYS.COL$ SET COL# = 1,NAME='ID' WHERE OBJ# = 74344 AND NAME='USER_ID'; 已更新 1 行。 SQL> UPDATE SYS.COL$ SET COL# = 2,NAME='NAME' WHERE OBJ# = 74344 AND NAME ='USERNAME'; 已更新 1 行。 SQL> COMMIT; 提交完成。 1.33.2.5 重启数据库服务 由于数据字典是在数据库启动时加载到 SQL 中的,所以修改了它之后,还 需要重启数据库服务。 SQL> shutdown immediate; 数据库已经关闭。 已经卸载数据库。 ORACLE 例程已经关闭。 SQL> startup ORACLE 例程已经启动。 Total System Global Area 1071333376 bytes Fixed Size 1375792 bytes Variable Size 436208080 bytes Database Buffers 629145600 bytes Redo Buffers 4603904 bytes 数据库装载完毕。 数据库已经打开。 SQL> 1.33.2.6 再查看 SQL> conn dave/dave; 已连接。 SQL> select * from myuser where rownum=1; ID NAME ---------- ------------------------------ 90 DAVE Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 修改已经成功。 直接修改数据字典表是个危险的操作。 所以以上测试仅做了解。 1.34 Oracle 动态性能视图 Blog:http://blog.csdn.net/tianlesoftware/archive/2010/09/04/5863191.aspx 1.34.1 Oracle 联机文档上有关动态性能视图的内容: Data Dictionary and Dynamic Performance Views http://download.oracle.com/docs/cd/E11882_01/server.112/e10713/datadict.htm#i 4370 Throughout its operation, Oracle Database maintains a set of virtual tables that record current database activity. These views are called dynamic performance views because they are continuously updated while a database is open and in use. The views, also sometimes called V$ views, contain information such as the following:  System and session parameters  Memory usage and allocation  File states (including RMAN backup files)  Progress of jobs and tasks  SQL execution  Statistics and metrics The dynamic performance views have the following primary uses:  Oracle Enterprise Manager uses the views to obtain information about the database (see "Oracle Enterprise Manager").  Administrators can use the views for performance monitoring and debugging. See Also: Oracle Database Reference for a complete list of the dynamic performance views Contents of the Dynamic Performance Views Dynamic performance views are sometimes called fixed views because they cannot be altered or removed by a database administrator. However, database Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 administrators can query and create views on the tables and grant access to these views to other users. SYS owns the dynamic performance tables, whose names begin with V_$. Views are created on these tables, and then public synonyms prefixed with V$. For example, the V$DATAFILE view contains information about data files. The V$FIXED_TABLE view contains information about all of the dynamic performance tables and views. For almost every V$ view, a corresponding GV$ view exists. In Oracle Real Application Clusters (Oracle RAC), querying a GV$ view retrieves the V$ view information from all qualified database instances (see "Database Server Grid"). When you use the Database Configuration Assistant (DBCA) to create a database, Oracle automatically creates the data dictionary. Oracle Database automatically runs the catalog.sql script, which contains definitions of the views and public synonyms for the dynamic performance views. You must run catalog.sql to create these views and synonyms. Storage of the Dynamic Performance Views Dynamic performance views are based on virtual tables built from database memory structures. Thus, they are not conventional tables stored in the database. Read consistency is not guaranteed for the views because the data is updated dynamically. Because the dynamic performance views are not true tables, the data is dependent on the state of the database and instance. For example, you can query V$INSTANCE and V$BGPROCESS when the database is started but not mounted. However, you cannot query V$DATAFILE until the database has been mounted. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.34.2 动态性能视图 动态性能视图属于数据字典,系统管理员用户 SYS 可以访问它们。 关于数 据字典,从那靠 1.32 小节。 动态性能视图在数据库打开和使用时不断进行更新,而且它们的内容主要与 性能有关。虽然这些视图很像普通的数据库表,但它们不允许用户直接进行修改。 这些视图提供内部磁盘结构和内存结构方面的数据。用户可以对这些视图进行查 询,以便对系统进行管理与优化。 CATALOG.SQL 文件包含这些视图的定义以及公用同义词,必须运行 CATALOG.SQL 创建这些视图及同义词。升级系统也后要执行这个脚本. 当数据库管理员启动某个例程时,数据库会自动建立动态性能视图; 当停止某个例程时,数据库又会自动删除这些动态性能视图。 数据字典的信息是从数据文件中取得; 而动态性能视图的信息则是从 SGA 内存以及控制文件中取得。所以,两者所反映的信息还是有很大差异的。数据库 管理员利用这些动态性能视图,可以了解数据库运行的一些基本信息,为我们进 行数据库维护以及数据库性能优化提供一些数据上的支持。 一般情况下,我们可以通过动态性能数据掌握两类重要的数据库运行信息。 (1)了解数据库运行相关的性能数据,如内存的使用量、磁盘排序发 生的机率等等。 (2)取得与磁盘和内存结构相关的其他信息。 在通常情况下,数据库不同的状态其动态性能视图还是有比较大的差异: (1)数据库处于―NOMOUNT‖状态。数据库启动例程时,Oracle 数据库会 打开参数文件,分配 SGA 内存并启动后台进程。此时,其实数据库还没有挂栽。 此时,动态性呢视图收集的信息来源只有是 SGA,而不会从控制文件中收集相 关的信息。所以,动态性能视图的数量要少得多。 (2)当数据库处于 MOUNT 状态时,数据库会根据初始化参数打开所有的 控制文件。所以,当例程处于 Mount 状态时,动态性能视图其收集到的信息就 要第一个状态多的多。因为此时,动态性能视图还会去收集控制文件的相关信息。 不过,此时动态性能视图所收集到的资料还不是最全的。 (3)当用户打开数据库时,Oracle 系统会根据控制文件所记载的信息去打 开所有的数据库文件以及重做日志。此时,数据库管理员除了可以从 SGA 和控 制文件中获取信息的动态性能视图外,还可能访问与 Oracle 数据库性能相关的 动态性能视图,如会话等待时间等视图。另外需要注意一点,就是只有在这个状 态时,我们才能够访问数据库的数据字典视图。 SYS owns the dynamic performance tables, whose names begin with V_$. Views are created on these tables, and then public synonyms prefixed with V$. For Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 example, the V$DATAFILE view contains information about data files. The V$FIXED_TABLE view contains information about all of the dynamic performance tables and views. 从这段描述里,我们可以理解,通过 V$FIXED_TBLE 视图可以查看几乎所 有的动态性能表和视图。 V$是 V_$的同义词。 1.34.3 V$, V_$, GV$, X$ 视图说明 1.34.3.1 X$ 表 X$表包含了特定实例的各方面的信息,是 Oracle 数据库的运行基础,如当 前的配置信息,连接到实例的会话,以及丰富而有价值的性能信息。 X$表并不 是驻留在数据库文件的永久表或临时表。X$表仅仅驻留在内存中,当实例启动 时,由 Oracle 应用程序动态创建,在内存中进行实时的维护。 它们中的大多数 至少需要装载或已经打开的数据库。X$表为 SYS 用户所拥有,并且是只读的。 不 能进行 DML(更新,插入,删除)。X$表对数据库来说至关重要,所以 Oracle 不 允许 SYSDBA 之外的用户直接访问,显示授权不被允许。 可以从 v$fixed_table 中查到 X$: SQL> select count(*) from v$fixed_table where name like 'X$%'; COUNT(*) ---------- 945 在 Oracle 11g 共有 945 个 X$表。 关于 X$表,其创建信息我们也可以通过 bootstrap$表查看,该表中记录了数据库 启动的基本及驱动信息。 bootstrap$ 实际上存储的是数据字典的基表的定义,如 OBJ$,C_OBJ$,TAB$等等。 Oracle 通过读取这些定义创建数据字典的基表,进而创建数据字典。 SQL> select * from bootstrap$; bootstrap$ 部分比较深,有空在研究。 1.34.3.2 GV$ 和 V$ 同义词 1.34.3.2.1 V$ 视图 动态性能视图由前缀 V_$标识。这些视图的公用同义词具有前缀 V$。数据 库管理员或用户应该只访问 V$对象,而不是访问 V_$对象。动态性能视图由企 业管理器和 Oracle Trace 使用,Oracle Trace 是访问系统性能信息的主要界面。 一旦实例启动,从内存读取数据的 V$视图就可以访问了。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 注意: 每个 V$视图都包含类似语句: where inst_id = USERENV('Instance') 用于限制返回当前实例信息。 这一点我们可以通过 V$FIXED_VIEW_DEFINITION 视图 来验证。如: SQL> select view_definition from v_$fixed_view_definition where view_name='V$FIXED_TABLE'; VIEW_DEFINITION ----------------------------------------------------------------------------------------------------- select NAME , OBJECT_ID , TYPE , TABLE_NUM from GV$FIXED_TABLE where inst_id = USERENV('Instance') 通过 v$fixed_table 查询 V$视图信息: SQL> select count(*) from v$fixed_table where name like 'V$%'; COUNT(*) ---------- 525 1.34.3.2.2 GV$ 视图 从 Oracle8 开始,GV$视图开始被引入, GV$(Global V$,全局 V$)。除了 一些特例以外( 如:V$CACHE_LOCK 、 V$LOCK_ACTIVITY 、 V$LOCKS_WITH_COLLISIONS 和 V$ROLLNAME),每个 V$视图都有一个对 应的 GV$视图存在。在并行服务器环境下,可查询 GV$视图从所有限定实例中 检索 V$视图的信息。V$视图和 GV$视图是相同的,V$比 GV$只是少了 INST_ID 字段。INST_ID 列显示从其获得相关的 V$视图信息的实例号。INST_ID 列可用 作一个从可得到的实例集检索 V$信息的过滤器。 如: SQL>SELECT * FROM GV$LOCK WHERE INST_ID = 2; 表示从实例 2 上的 V$ 视图中检索信息。 通过 v$fixed_table 查询 GV$视图信息: SQL> select count(*) from v$fixed_table where name like 'GV$%'; COUNT(*) ---------- 496 从查询结果看,GV$是 496 个,V$是 525 个,从这个结果可以证明:不是每个 V$同义词都有对应的 GV$同义词。 1.34.3.3 V$FIXED_VIEW_DEFINITION 视图 通过 V$FIXED_VIEW_DEFINITION 视图可以获取组成 V$视图的底层 X$表的所有信息。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 示例 1.查看 V$FIXED_TABLE 视图定义 SQL> select view_definition from v$fixed_view_definition where view_name='V$FIXED_TABLE'; VIEW_DEFINITION ------------------------------------------------------------------------------------------------------- - select NAME , OBJECT_ID , TYPE , TABLE_NUM from GV$FIXED_TABLE where inst_id = USERENV('Instance') 从这里,我们看到 V$FIXED_TABLE 基于 GV$FIXED_TABLE 创建。 示例 2.查看 GV$FIXED_TABLE 定义 SQL> select view_definition from v$fixed_view_definition where view_name='GV$FIXED_TABLE'; VIEW_DEFINITION ------------------------------------------------------------------------------------------------------- select inst_id,kqftanam, kqftaobj, 'TABLE', indx from x$kqfta union all select inst_id,kqfvinam, kqfviobj, 'VIEW', 65537 from x$kqfvi union all select inst_id,kqfdtnam, kqfdtobj, 'TABLE', 65537 from x$kqfdt 从这里,我们找到了 GV$FIXED_TABLE 视图的创建语句,该视图基于 X$表创 建。 示例 3. 研究下 V$PARAMETER 视图 SQL> select view_definition from v$fixed_view_definition a where a.VIEW_NAME='V$PARAMETER'; VIEW_DEFINITION ------------------------------------------------------------------------------------------------------- ---------------- /* Formatted on 2010/9/4 13:37:37 (QP5 v5.115.810.9015) */ SELECT NUM, NAME, TYPE, VALUE, DISPLAY_VALUE, ISDEFAULT, ISSES_MODIFIABLE, ISSYS_MODIFIABLE, ISINSTANCE_MODIFIABLE, Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 ISMODIFIED, ISADJUSTED, ISDEPRECATED, ISBASIC, DESCRIPTION, UPDATE_COMMENT, HASH FROM GV$PARAMETER WHERE inst_id = USERENV ('Instance') 从这里,我们看到 V$PARAMETER 是基于 GV$PARAMETER 构造的。 SQL> select view_definition from v$fixed_view_definition a where a.VIEW_NAME='GV$PARAMETER'; VIEW_DEFINITION ------------------------------------------------------------------------------------------------------- ------------------------------------------- /* Formatted on 2010/9/4 13:38:10 (QP5 v5.115.810.9015) */ SELECT x.inst_id, x.indx + 1, ksppinm, ksppity, ksppstvl, ksppstdvl, ksppstdf, DECODE (BITAND (ksppiflg / 256, 1), 1, 'TRUE', 'FALSE'), DECODE (BITAND (ksppiflg / 65536, 3), 1, 'IMMEDIATE', 2, 'DEFERRED', 3, 'IMMEDIATE', 'FALSE'), DECODE (BITAND (ksppiflg, 4), 4, 'FALSE', DECODE (BITAND (ksppiflg / 65536, 3), 0, 'FALSE', 'TRUE')), DECODE (BITAND (ksppstvf, 7), 1, 'MODIFIED', 4, 'SYSTEM_MOD', 'FALSE'), DECODE (BITAND (ksppstvf, 2), 2, 'TRUE', 'FALSE'), DECODE (BITAND (ksppilrmflg / 64, 1), 1, 'TRUE', 'FALSE'), DECODE (BITAND (ksppilrmflg / 268435456, 1), 1, 'TRUE', 'FALSE'), ksppdesc, ksppstcmnt, ksppihash Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 FROM x$ksppi x, x$ksppcv y WHERE (x.indx = y.indx) AND BITAND (ksppiflg, 268435456) = 0 AND ( (TRANSLATE (ksppinm, '_', '#') NOT LIKE '##%') AND ( (TRANSLATE (ksppinm, '_', '#') NOT LIKE '#%') OR (ksppstdf = 'FALSE') OR (BITAND (ksppstvf, 5) > 0))) 在这里我们看到 GV$PARAMETER 来源于 x$ksppi, x$ksppcv 两个 X$表, x$ksppi, x$ksppcv 基本上包含所有数据库可调整参数. v$parameter 展现的是不包含"_"开头的参数。以"_"开头的参数我们通常称为 隐含参数,一般不建议修改,但很多因为功能强大经常使用而广为人知。 关于参数的更多内容参考 1.31 小节。 Oracle 参数分类 和 参数的查看方法 http://blog.csdn.net/tianlesoftware/archive/2010/05/13/5583655.as px 感兴趣的,可以自己研究下 V$FIXED_VIEW_DEFINITION 视图,它是我们研 究数据字典的一个入口。 1.34.3.4 GV_$, V_$视图 动态性能的视图是通过 catalog.sql 创建。当 catalog.sql 运行时: create or replace view v_$fixed_table as select * from v$fixed_table; create or replace public synonym v$fixed_table for v_$fixed_table; create or replace view gv_$fixed_table as select * from gv$fixed_table; create or replace public synonym gv$fixed_table for gv_$fixed_table; 我们注意到, 先创建 V_$和 GV_$ 视图,然后基于 V_$视图和 GV_$视图 来创建 V$和 GV$同义词。 所以,实际上通常我们访问的 V$视图,其实是指向 V_$视图的同义词。而 V_$视图是基于 X$表建立的。关于这一点可以通过:v$fixed_view_definition 视 图 来验证。 在上面 1.2.2 节有相关的示例。 访问 V$FIXED_VIEW_DEFINITION 视图可以获取组成 V$视图的底层 X$表的 所有信息 SQL> select count(*) from v$fixed_table where name like 'GV_%'; COUNT(*) ---------- 496 SQL> select count(*) from v$fixed_table where name like 'V_%'; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 COUNT(*) ---------- 525 动态性能对象那么多,如何来判断某个对象到底是同义词还是视图呢? 可以通 过如下 SQL 来实现: SQL> select object_type from all_objects where object_name=upper('v$datafile'); OBJECT_TYPE ------------------- SYNONYM 1.34.4 20 个常用的动态性能视图 (1)v$sysstat (2)v$sesstat (3)v$sql & v$sql_plan (4)v$sqltext & v$sqlarea (5)v$session (6)v$session_wait & v$session_event (7)v$process (8)v$lock & v$locked_object (9)v$filestat (10)v$session_longops (11)v$latch$ v$latch_children (12)v$db_object_cache (13)v$open_cursor (14)v$parameter & v$system_parameter (15)v$rollstat (16)v$rowcache (17)v$segstat & v$segment_statistics (18)v$system_event (19)v$undostat (20)v$waitstat 总结一下: 在实例启动时,会先创建 X$表,然后基于 X$表创建 GV_$ 和 V_$ 视图, 在基于 GV_$ 和 V_$视图创建 GV$和 V$同义词。 我们一般查询的都是同义词。 关于这些视图的定义,可以通过 V$FIXED_VIEW_DEFINITION 视图 来查看。 在数据库运行期间,动态性能视图保存在内存中,时刻监控着数据库的状态,我 们在需要的时候可以查看这些视图。 当实例关闭时,数据库又会从内存中自动 删除这些动态性能视图。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.35 Oracle 性能相关的几个 视图 和 参数 Blog:http://blog.csdn.net/tianlesoftware/archive/2010/09/06/5867276.aspx 1.35.1 性能视图 性能视图是 Oracle 中一些记录数据库性能方面的视图,通过查看这些视图, 获得数据库当前或历史上某个时间的性能数据。 它比 SQL_TRACE,AWR 报告 获取数据更及时,便捷。 在 1.34 节有相关说明。 1.35.1.1 V$SQL V$SQL 视 图 是 一 个 DBA 使用频率非常高的动态视图,它通常和 V$SESSION 一起使用来获得当前会话的一些 SQL 执行情况。可以通过该视图 查看正在执行的 SQL 语句及这条 SQL 运行了多长时间或者它正在等待什么样的 事件。 1.35.1.1.1 用 V$SQL 查看 SQL 内容 为了获取用户连接到数据库中的信息,需要先从 V$SESSION 视图确定用户 的 SID 号,然后用 v$session 和 v$sql 查看相关信息。 SQL>select * from v$session; 从这里确定根据 machine 列和 program 列确定 SID。 根据 SID 确定 SQL: /* Formatted on 2010/9/6 11:08:21 (QP5 v5.115.810.9015) */ SELECT a.sql_text, b.status, b.last_call_et, b.event FROM v$sql a, v$session b WHERE a.sql_id = b.sql_id AND b.sid = 23 也可以根据进程号来查看。具体参考 Blog: oracle 实时查询最耗 CPU 资源的 SQL 语句 http://blog.csdn.net/tianlesoftware/archive/2009/11/30/4898607.a spx 1.35.1.1.2 用 V$SQL 查看 SQL 执行和等待时间 对于已经执行完毕的会话,可以在 V$SQL 视图中找到它的执行时间和消耗 的 CPU 时间,这些信息对我们分析一些性能上存在问题的 SQL 有用处。比如对Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 比 SQL 消耗的 CPU 和执行时间,就可以大致知道 SQL 语句执行中是否有长时 间的等待事件: /* Formatted on 2010/9/6 13:05:05 (QP5 v5.115.810.9015) */ SELECT sql_text, cpu_time / (1000 * 1000) t_cpu, TRUNC (elapsed_time / (1000 * 1000)) t_elap, (cpu_time / elapsed_time / (1000 * 1000)) * 100 pct FROM v$sql WHERE sql_text LIKE 'insert into sf select%' SQL_TEXT T_CPU T_ELAP PCT ------------------------------ ---------- ---------- ---------- insert into sf select * from u .312002 0 .000056249 insert into sf select * from u .296402 0 .000062524 返回如上结果,如果说 T_ELAP 时间比较多,而 CPU 时间比较少,说明这 条语句在执行过程中基本处于等待状态。 关于各个等待事件,参考 Blog: Oracle 常见的 33 个等待事件 http://blog.csdn.net/tianlesoftware/archive/2010/08/12/5807800.a spx 1.35.1.1.3 共享池中的 SQL 并不是所有的 SQL 语句都可以从 V$SQL 中找到,因为 ORACLE 会动态地 更新共享池的信息,将一些过旧的 SQL 从共享池中删除,以便于新的 SQL 语句 提供共享池的空间。 我们可以手动的清空共享池中的信息,SQL 语句如下: SQL>alter system flush shared_pool; 我们知道,SQL 的解析的过程中,会把硬解析之后的 SQL 放在放在共享池 中,如果我们清空了共享池,那么就需要重新做硬分析。 Oracle SQL 的硬解析和软解析 http://blog.csdn.net/tianlesoftware/archive/2010/04/08/5458896.a spx 关于这点的验证,可以参考如下方法: (1) 开启 SQL_TRACE (2) 做一条事务 (3) 清空缓冲区 (4) 在做同样的事务 (5) 关闭 SQL_TRACE (6) 用 tkprof 查看 trace 文件,生成文件时加上 aggregate=no 参数,这样Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 如果是一条 SQL 执行多次,在 tkprof 的 trace 文件中会分别列出来。 这 个参数默认是 YES。 Oracle SQL Trace 和 10046 事件 http://blog.csdn.net/tianlesoftware/archive/2010/09/02/5857023.a spx 1.35.1.2 V$SQL_SHARED_CURSOR 官网链接: http://download.oracle.com/docs/cd/E11882_01/server.112/e10820/dynviews_3058.ht m#REFRN30254 这个视图存放了 SQL 在执行过程中游标共享的信息,它能帮助我们分析看 起来一样的 SQL,为什么没有共享的原因。 SQL> show parameter cursor_sharing; NAME TYPE VALUE ------------------------------------ ----------- ------ cursor_sharing string EXACT 查看 SQL: SQL> select parsing_user_id puid,parsing_schema_id psid,sql_text,sql_id,child_address from v$sql where sql_text like 'insert into t%'; PUID PSID SQL_TEXT SQL_ID CHILD_AD ---------- ---------- ------------------------------ ------------- -------- 0 0 insert into tabpart$ (obj#, da 9hp6m1g7j275b A21042D8 0 0 insert into tab$(obj#,ts#,file asnhcg241fr2y A877959C --- 如果这里有多条 SQL_TEXT,SQL_ID 相同的,就说明 SQL 没有重用。 我 们可以用如下 SQL 来确定是哪里不一致造成: 查看不能重用原因: SQL> select * from v$sql_shared_cursor where sql_id='asnhcg241fr2y'; SQL_ID ADDRESS CHILD_AD CHILD_NUMBER U S O O S L F E B P I S T A B D L T B I I R L I O E M U T N F A I T D L D B P C S C P T M B M R O P M F L P L A F L R L H P B ------------- -------- -------- ------------ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - asnhcg241fr2y A8779678 A877959C 0 N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 如果这里有 Y,就是导致不能重用的原因, 这 些 字 母 和 V$SQL_SHARED_CURSOR 每个字段对应。 1.35.1.3 V$SESSION 官网链接: http://download.oracle.com/docs/cd/E11882_01/server.112/e10820/dynviews_3016.ht m#REFRN30223 我们可以从该视图查看用户会话的信息。可以使用 machine 或者 module 找 到我们的用户。Macine 是客户端机器的名称,userName 是会话连接时提供的用 户名,Program 是客户端执行程序的名称,module 是 Oracle 的存储过程 DBMS_ALLPLCATION_INFO.SET_MODULE 给出的执行程序的名称。 这种直接查询 v$session 视图的方法只适合哪种两层结构的 C-S 架构,这种 是客户端直接连接到数据库。 但是现在基本都是三层架构。 通过中间件如 weblogic 来连接数据库。 这种情况下就需要在中间件服务上进行跟踪,比如获 得用户道和中间件的连接信息,然后根据中间件的信息或者日志来确定用户的最 终信息。 V$SESSION 常用来查看用户当前的状态,当前执行的 SQL 语句,SQL 语句 执行时间,以及等待事件等。 V$SESSION 里面有个字段 last_call_et(单位:秒),表示执行时间,这里有两 种状态: 1. Session 处于 active 状态,该字段表示 session 变成 active 到现在的时间; 2. Session 处于 inactive 状态, 此时表示 session 变成 inactive 到现在的时间。 示例 1:查询 active 的 session: SQL> select status,last_call_et,event from v$session where sid=23; STATUS LAST_CALL_ET EVENT -------- ------------ -------------------------------------------- INACTIVE 9976 SQL*Net message from client 这里的 9976 表示的从 session 变成 inactive 到现在的秒数。 示例 2:查询 inactive 的 session: /* Formatted on 2010/9/6 16:52:32 (QP5 v5.115.810.9015) */ SELECT a.sql_text, b.status, b.last_call_et, b.event FROM v$sql a, v$session b Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 WHERE a.sql_id = b.sql_id AND b.sid = '279'; 注意: 在 RAC 状态下,会话需要来自不同的实例,所以在 RAC 环境下需要使用 GV$SESSION 视图, 因为这个视图含有 INST_ID 字段,通过这个字段可以区 别实例。 1.35.1.4 V$SESSTAT 官网链接: http://download.oracle.com/docs/cd/E11882_01/server.112/e10820/dynviews_3027.ht m#REFRN30232 这个视图记录了某个 session 从运行以来各种资源统计数据,通过关联表 v$statname 可以查询出某个 session 的资源消耗情况,如: /* Formatted on 2010/9/6 17:06:56 (QP5 v5.115.810.9015) */ SELECT a.sid, b.name, a.VALUE FROM v$sesstat a, v$statname b WHERE a.sid = 23 AND a.statistic# = b.statistic# AND b.name IN ('consistent gets', 'physical reads', 'parse count (total)', 'parse count (hard)'); SID NAME VALUE ---------- -------------------- ---------- 23 consistent gets 29750 23 physical reads 386 23 parse count (total) 387 23 parse count (hard) 82 这里显示了 SID=23 的 session 的信息。 1.35.1.5 V$SESSION_WAIT 官网链接地址: http://download.oracle.com/docs/cd/E11882_01/server.112/e10820/dynviews_3023.ht m#REFRN30229 V$SESSION_WAIT 记录了会话的一些等待信息,这些等待信息在 v$session 视图里可以可以查到。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 示例: /* Formatted on 2010/9/6 17:19:40 (QP5 v5.115.810.9015) */ SELECT event, p1, p1text, p2, p2text, p3, p3text, wait_time, seconds_in_wait, state FROM v$session_wait WHERE sid = 23; 关于等待事件参考 Blog: Oracle 常见的 33 个等待事件 http://blog.csdn.net/tianlesoftware/archive/2010/08/12/5807800.a spx 1.35.2 性能参数 性能参数指它的设置会影响数据库性能问题的初始化参数。 这些参数比较 多,具体参考 ORACLE 官网文档。 1.35.2.1 CURSOR_SHARING 该参数决定在什么情况下可以使用共享游标,即 SQL 重用。它有三个值: EXACT, SIMILAR 和 FORCE. 默认情况下,oracle 将该参数值是 EXACT. 意思是 SQL 必须绝对一样才能 共享游标,否则将作为新的 SQL 语句处理。 这种设置的意义在于,从 Oracle 层面来看,通过精确地匹配每个 SQL 语句, 就可以保证只有语句完全相同的 SQL,才可以在共享池中被重用,否则将作为 新的 SQL 语句对待。 而把构造完全一样的 SQL 语句的任务留给用应用来完成, 即由应用来通过变量绑定的方式达到 SQL 重用,而不是依赖 ORACLE 来实现, 这样的好处是可以大大减少 ORACLE 花费在 SQL 分 析 上 的 资 源 消 耗 (cursor_sharing=similar),及避免 Oracle 不加判断地绑定变量导致执行计划选择 的错误(cursor_sharing=force). 1.35.2.1.1 cursor_sharing=exact(默认值) 这种情况下,只有 SQL 完全一样的,才会在共享池中重用 SQL,我们可以Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 使用绑定变量来实现 SQL 一样。但是在 OLTP 系统中,如果绑定变量的效果不 太好,将 CURSOR_SHARING 设置为 exact 就会增加 Oracle 对 SQL 的硬分析 量,消耗更多的系统资源。 如果出现这种情况,cursor_sharing 就需要设置为其 他的两个值。 1.35.2.1.2 cursor_sharing=similar SQL> alter session set cursor_sharing=similar; 会话已更改。 SQL> select * from all_objects set_similar where object_id=10; SQL> select * from all_objects set_similar where object_id=20; SQL> select sql_text from v$sql where sql_text like '%set_similar%'; SQL_TEXT ------------------------------------------------------------------------------ select * from all_objects set_similar where object_id=:"SYS_B_0" select * from all_objects set_similar where object_id=:"SYS_B_0" 如果你测试的结果不一样,把共享池清空一下就可以了: SQL> alter system flush shared_pool; 从这个结果看,当设置 cursor_sharing=similar 时,Oracle 会将 SQL 语句中的 谓词条件用同一个名称的一个变量替代:SYS_B_0, 如果谓词中还有其他变量, 将一次使用 SYS_B_1,SYS_B_2. 这两条语句看起来一样,但是,Oracle 依然 会把它们作为 2 条 SQL 语句来处理。 1.35.2.1.3 cursor_sharing=force SQL> alter session set cursor_sharing=force; SQL> select * from all_objects set_similar where object_id =2; SQL> select * from all_objects set_similar where object_id =1; SQL> select sql_text from v$sql where sql_text like '%set_similar%'; SQL_TEXT -------------------------------------------------------------------------- select * from all_objects set_similar where object_id =:"SYS_B_0" 如果你测试的结果不一样,把共享池清空一下就可以了: SQL> alter system flush shared_pool; 从上面的结果看,当设置 cursor_sharing=force 时,Oracle 会把这两条 SQL 语句的谓词用变量 SYS_B_0 代替,并且将它们看做同一条 SQL 语句来处理。 在 OLTP 系统才能使用绑定变量带来性能上的提升,因为在这样的系统中,Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL 执行计划基本上是相同的,不会因为谓词的条件而改变。 而在 OLAP 系统中,因为 OLAP 系统中数据的变化非常大,列上的数据分布 也可能很不均匀,这时候使用绑定变量,可能会出现问题。 按照 Oracle 官方的说法,将参数值设置为 EXACT 是最优的。但是它的前提 是需要通过应用程序绑定变量来达到最优的 SQL 重用。 只有高效的变量绑定, EXACT 值才是最优的。而 Similar 和 Force 是在系统没有使用绑定变量时,为了 降低系统大量的 SQL 解析而使用的补救方法,但是它有很多问题,如不加区别 或者略加区别的对谓词强制绑定变量,导致 SQL 的执行计划错误。 1.35.2.1.4 SIMILAR 和 Force 的区别 Similar:如果 CBO 发现被绑定变量的谓词还有其他执行计划可以选择,如 果谓词条件的值有变化,就将会产生一个新的子游标,而不是重用之前的 SQL 语句;如果谓词没有其他的执行计划可选择,则忽略谓词的值,重用之前的 SQL 语句。 Force: CBO 和 SQL 语句的所有谓词用变量替换,只做一次硬解析,之后 所有的 SQL 都重用第一个 SQL 语句。 1.35.2.2 DB_FILE_MULTIBLOCK_READ_COUNT Oracle 在做一次连续的数据库扫描时,一次 I/O 允许读取的最大数据块数, 但有一个限制,就是每次 I/O 的大小不能超过 Oracle 运行的操作系统的最大 I/O 值(通常是 1M)。 假设一张表有 10240KB 大小,数据块的大小为 8kb ,设置 DB_FILE_MULTIBLOCK_READ_COUNT=32,那么我们对这张表做全表扫描的 次数为: 10240/(32*8)=40 次,即 Oracle 对这张表做扫描需要花费 40 次 I/O。 但是实际上,Oracle 花费的 I/O 次数可能大于这个值,可可能小于这个值。 因为 Oracle 在读多个数据库时,当内存中已经有了某个数据块时,Oracle 就不 再从磁盘中读取它。 对于 OLTP 数据库来说,每次用户读取的记录数非常少,这个值可以考虑设 置的小一点;对于 OLAP 系统,因为查询的量非常大,所以可以考虑设置大一 些。 注意: 多数据块读取操作只发生在一下两种情况: (1) FTS(FULL TABLE SCAN) (2) INDEX_FFS(INDEX FAST FULL SCAN) 关于这两种连接方式,参考 Blog: Oracle 索引扫描的四种类型 http://blog.csdn.net/tianlesoftware/archive/2010/08/31/5852106.aspx 这个参数才 10g R2 版本后,Oracle 不建议修改它的默认值。 当设置这个值 为默认值时,Oracle 会通过收集 SQL 的 I/O 情况,来动态设置这个参数的值, 如果手工修改了它的默认值,Oracle 将确定使用这个新值。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 这个参数影响到 CBO 对成本的评估,通常来说,这个值设置的越大,FFS 或者 INDEX_FFS 得成本就会越低,执行计划就越向这面倾斜。 1.36 Oracle Dual 表详解 Blog:http://blog.csdn.net/tianlesoftware/archive/2009/11/03/4764326.aspx 1.36.1 官网说明 DUAL is a table automatically created by Oracle Database along with the data dictionary. DUAL is in the schema of the user SYS but is accessible by the name DUAL to all users. It has one column, DUMMY, defined to be VARCHAR2(1), and contains one row with a value X. Selecting from the DUAL table is useful for computing a constant expression with the SELECT statement. Because DUAL has only one row, the constant is returned only once. Alternatively, you can select a constant, pseudocolumn, or expression from any table, but the value will be returned as many times as there are rows in the table. Refer to "About SQL Functions" for many examples of selecting a constant value from DUAL. Note: Beginning with Oracle Database 10g Release 1, logical I/O is not performed on the DUAL table when computing an expression that does not include the DUMMY column. This optimization is listed as FAST DUAL in the execution plan. If you SELECT the DUMMY column from DUAL, then this optimization does not take place and logical I/O occurs. --查询虚拟列不会产生逻辑 IO。 1.36.2 DUAL 表的用途 Dual 是 Oracle 中的一个实际存在的表,任何用户均可读取,常用在没有目 标表的 Select 语句块中 --查看当前连接用户 SQL> select user from dual; USER ------------------------------ SYSTEM --查看当前日期、时间 SQL> select sysdate from dual; SYSDATE ----------- 2007-1-24 1 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL> select to_char(sysdate,''yyyy-mm-dd hh24:mi:ss'') from dual; TO_CHAR(SYSDATE,''YYYY-MM-DDHH2 ------------------------------ 2007-01-24 15:02:47 --当作计算器用 SQL> select 1+2 from dual; 1+2 ---------- 3 --查看序列值 SQL> create sequence aaa increment by 1 start with 1; SQL> select aaa.nextval from dual; NEXTVAL ---------- 1 SQL> select aaa.currval from dual; CURRVAL ---------- 1 1.36.3 关于 DUAL 表的测试与分析 DUAL 就是个一行一列的表,如果你往里执行 insert、delete、truncate 操作, 就会导致很多程序出问题。结果也因 sql*plus、pl/sql dev 等工具而异。 1.36.3.1 查看 DUAL 是什么 OBJECT DUAL 是属于 SYS schema 的一个表, 然后以 PUBLIC SYNONYM 的方式供 其他数据库 USER 使用. SQL> select owner, object_name , object_type from dba_objects where object_name like ''%DUAL%''; OWNER OBJECT_NAME OBJECT_TYPE ---------- ----------------- ------------------ SYS DUAL TABLE PUBLIC DUAL SYNONYM --查看表结构,只有一个字段 DUMMY,为 VARCHAR2(1)型 SQL> desc dual Name Type Nullable Default Comments ----- ----------- -------- ------- -------- DUMMY VARCHAR2(1) Y Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 --DUAL 表的结构: create table SYS.DUAL ( DUMMY VARCHAR2(1) ) tablespace SYSTEM pctfree 10 pctused 40 initrans 1 maxtrans 255 storage ( initial 16K next 16K minextents 1 maxextents 505 pctincrease 50 ); DUAL 表是建立在 SYSTEM 表空间的,第一是因为 DUAL 表是 SYS 这个用 户建的,本来默认的表空间就是 SYSTEM;第二,把这个可能经常被查询的表 和用户表分开来存放,对于系统性能的是有好处的。 有了创建了表、创建了同义词还是不够的。DUAL 在 SYS 这个 Schema 下面, 因此用别的用户登录是无法查询这个表的,因此还需要授权: grant select on SYS.DUAL to PUBLIC with grant option; 将 Select 权限授予公众。 接下来看看 DUAL 表中的数据,事实上,DUAL 表中的数据和 ORACLE 数 据库环境有着十分重要的关系(ORACLE 不会为此瘫痪,但是不少存储过程以 及一些查询将无法被正确执行)。 1.36.3.2 DUAL 表行数 问题 在创建数据库之后,DUAL 表中便已经被插入了一条记录。个人认为: DUMMY 字段的值并没有什么关系,重要的是 DUAL 表中的记录数 SQL> select count(*) from dual; COUNT(*) ---------- 1 SQL> select * from dual; DUMMY Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 ----- X --插入数据,再查询记录,只返回一行记录 SQL> insert into dual values (''Y''); 1 row created. SQL> commit; Commit complete. SQL> insert into dual values (''X''); 1 row created. SQL> insert into dual values (''Z''); 1 row created. SQL> commit; Commit complete. SQL> select count(*) from dual; COUNT(*) ---------- 4 SQL> select * from dual; DUMMY ----- X 假我们插入一条数据,DUAL 表不是返回一行,而是多行记录,那会是什么结果 呢? SQL> insert into dual values(''Y''); 1 行 已插入 SQL> commit; 提交完成 SQL> select * from dual; DUMMY ----- X Y SQL> select sysdate from dual; SYSDATE ----------- 2004-12-15 2004-12-15 这个时候返回的是两条记录,这样同样会引起问题。在通过使用 SQL>select sysdate into v_sysdate from dual; Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 来获取时间或者其他信息的存储过程来说, ORACLE 会抛出 TOO_MANY_ROWS(ORA-01422)异常。 因此,需要保证在 DUAL 表内有且仅有一条记录。当然,也不能把 DUAL 表的 UPDATE,INSERT,DELETE 权限随意释放出去,这样对于系统是很危险 的 --把表截掉 SQL> truncate table dual; Table truncated. SQL> select count(*) from dual; COUNT(*) ---------- 0 SQL> select * from dual; no rows selected SQL> select sysdate from dual; no rows selected --试着把 DUAL 表中的数据删除,看看会出现什么结果: SQL> delete from dual; 1 行 已删除 SQL> select * from dual; DUMMY ----- SQL> select sysdate from dual; SYSDATE ----------- 我们便取不到系统日期了。因为,sysdate 是个函数,作用于每一个数据行。 现在没有数据了,自然就不可能取出系统日期。 这个对于很多用: SQL>select sysdate into v_sysdate from dual; 这种方式取系统时间以及其他信息的存储过程来说是致命的,因为, ORACLE 会马上抛出一个 NO_DATA_FOUND(ORA-01403)的异常,即使异常 被捕获,存储过程也将无法正确完成要求的动作。 --对于 DELETE 操作来说,ORACLE 对 DUAL 表的操作做了一些内部处理,尽量 保证 DUAL 表中只返回一条记录.当然这写内部操作是不可见的 --不管表内有多少记录(没有记录除外),ORACLE 对于每次 DELETE 操作都只 删除了一条数据。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SQL> select count(*) from dual; COUNT(*) ---------- 2 SQL> delete from dual; 1 行 已删除 SQL> commit; 提交完成 SQL> select count(*) from dual; COUNT(*) ---------- 1 ORACLE 关于 DUAL 表不同寻常特性的解释 There is internalized code that makes this happen. Code checks that ensure that a table scan of SYS.DUAL only returns one row. Svrmgrl behaviour is incorrect but this is now an obsolete product. The base issue you should always remember and keep is: DUAL table should always have 1 ROW. Dual is a normal table with one dummy column of varchar2(1). This is basically used from several applications as a pseudo table for getting results from a select statement that use functions like sysdate or other prebuilt or application functions. If DUAL has no rows at all some applications (that use DUAL) may fail with NO_DATA_FOUND exception. If DUAL has more than 1 row then applications (that use DUAL) may fail with TOO_MANY_ROWS exception. So DUAL should ALWAYS have 1 and only 1 row 1.36.3.3 Drop Dual table. DUAL 表可以执行插入、更新、删除操作,还可以执行 drop 操作。但是不 要去执行 drop 表的操作,否则会使系统不能用,数据库起不了,会报 Database startup crashes with ORA-1092 错误。 如果 DUAL 表被―不幸‖删除后的恢复,处理的步骤如下: (1)用 sys 用户登陆。 (2)创建 DUAL 表。 (3)授予公众 SELECT 权限(SQL 如上述,但不要给 UPDATE,INSERT, DELETE 权限)。 (4)向 DUAL 表插入一条记录(仅此一条): insert into dual values(''X''); (5)提交修改。 具体操作: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 --用 sys 用户登陆。 SQL> create pfile=‘d:\pfile.bak‘ from spfile SQL> shutdown immediate --在 d:\pfile.bak 文件中最后加入一条:replication_dependency_tracking = FALSE --重新启动数据库: -- 这一步是关键 SQL> startup pfile=‘d:\pfile.bak‘ SQL> create table ―sys‖.‖DUAL‖ ( ―DUMMY‖ varchar2(1) ) pctfree 10 pctused 4; SQL> insert into dual values(‗X‘); SQL> commit; SQL> Grant select on dual to Public; 授权成功。 SQL> select * from dual; D - X SQL> shutdown immediate 数据库已经关闭。 已经卸载数据库。 ORACLE 例程已经关闭。 SQL> startup ORACLE 例程已经启动。 Total System Global Area 135338868 bytes Fixed Size 453492 bytes Variable Size 109051904 bytes Database Buffers 25165824 bytes Redo Buffers 667648 bytes 数据库装载完毕。 数据库已经打开。 SQL> --OK, 下面就可以正常使用了。 1.37 Linux 内核参数 和 Oracle 相关参数调整 Blog:http://blog.csdn.net/tianlesoftware/archive/2009/10/15/4668741.aspx Linux 内核参数的大小和 Oracle 有很大的关闭,比如 ORA-27102 的错误, 就是因为内核参数的大小不当造成。具体参考 Blog: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Upon startup of Linux database get ORA-27102: out of memory Linux-X86_64 Error: 28: No space left on device http://blog.csdn.net/tianlesoftware/archive/2011/05/16/6424945.aspx Oracle 11gR2 里也有一个类似的问题: Oracle 11gR2 RAC ORA-00845 MEMORY_TARGET not supported on this system 解决方法 http://blog.csdn.net/tianlesoftware/archive/2010/11/17/6013777.aspx 安装 Oracle 的时候,可以参考 Oracle 的安装文档,来设置相关的值,但是 有些参数的值还是需要根据我们自己的情况来进行调整。 1.37.1. Linux 系统下的核心参数 # vi /etc/sysctl.conf kernel.shmall = 2097152 kernel.shmmax = 2147483648 kernel.shmmni = 4096 kernel.sem = 250 32000 100 128 fs.file-max = 65536 net.ipv4.ip_local_port_range = 9000 65000 net.core.rmem_default = 4194304 net.core.rmem_max = 4194304 net.core.wmem_default = 262144 net.core.wmem_max = 262144 该参数保存在/etc/sysctl.conf 下,修改该文件不需要重启 OS,只需要使用如下命 令: # /sbin/sysctl -p 就可以让修改的参数生效。 1.37.2. kernel.shmmax 参数 1.37.2.1 说明 SHMMAX Available physical memory Defines the maximum allowable size of one shared memory segment. The SHMMAX setting should be large enough to hold the entire SGA in one shared memory segment. A low setting can cause creation of multiple shared memory segments which may lead to performance degradation. Shmmax 是核心参数中最重要的参数之一,用于定义单个共享内存段的最大 值,shmmax 设置应该足够大,能在一个共享内存段下容纳下整个的 SGA ,设置 的过低可能会导致需要创建多个共享内存段,这样可能导致系统性能的下降 。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SHMMAX 仅仅是在共享内存段被创建的时候用来比较的一个数字,当共享 内存段被一个进程(Process)创建,操作系统检查是否被要求的共享内存段的值大 于 shmmax 的值 ,如果是,那么将会抛出一个错误。这个时候系统会创建另外 的一个或多个共享内存段满足进程的需求 。一般来说,共享内存段个数和系统 性能没有太直接的关系,也不会对性能产生太大的影响。 在实例启动以及 Server Process 创建的时候,多个小的共享内存段可能会导 致当时轻微的系统性能的降低(在启动的时候 需要去创建多个虚拟地址段,在进 程创建的时候要让进程对多个段进行“识别”,会有一些影响),但是其他时候都 不会有影响。这意味着如果你的程序不是经常 Create Processes(以及 Destroy Them),性能方面就不是考虑的问题。 Oralce 建议 SHMMAX > SGA(SGA_MAX_SIZE),这样在任何时候都不会 有甚至轻微的性能下降的隐患。 1.37.2.2 示例 在上节说了,如果 shmmax 小与 SGA,Oracle 会创建多个共享内存段,我 们可以使用 Ipcs -sa 查看看到共享内存段个数。 (1)查看 [root@rac01 ~]# cat /etc/sysctl.conf | grep kernel.shmmax kernel.shmmax = 20971520 [root@rac01 ~]# ipcs -sa ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0x00000000 65537 oracle 640 4194304 27 0x00000000 98306 oracle 640 20971520 27 0x00000000 131075 oracle 640 20971520 27 0x00000000 163844 oracle 640 20971520 27 0x00000000 196613 oracle 640 20971520 27 0x00000000 229382 oracle 640 20971520 27 0x00000000 262151 oracle 640 20971520 27 0x00000000 294920 oracle 640 20971520 27 0xd2776b04 327689 oracle 640 20971520 27 ------ Semaphore Arrays -------- key semid owner perms nsems 0xfafd7074 360449 oracle 640 104 ------ Message Queues -------- key msqid owner perms used-bytes messages Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 因为 kernel.shmmax 设置过小,导致分配了多个共享内存段。 下边改大一些: [root@rac01 ~]# cat /etc/sysctl.conf | grep kernel.shmmax kernel.shmmax = 2147483648 [root@rac01 ~]# sysctl -p [root@rac01 ~]# su - oracle [oracle@rac01 ~]$ sqlplus '/as sysdba' SQL*Plus: Release 10.2.0.1.0 - Production on Mon Nov 16 05:50:00 2009 Copyright (c) 1982, 2005, Oracle. All rights reserved. Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production With the Partitioning, Real Application Clusters, Oracle Label Security, OLAP and Data Mining Scoring Engine options SQL> startup force ORACLE instance started. Total System Global Area 167772160 bytes Fixed Size 1218316 bytes Variable Size 104859892 bytes Database Buffers 58720256 bytes Redo Buffers 2973696 bytes Database mounted. Database opened. SQL> quit Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production With the Partitioning, Real Application Clusters, Oracle Label Security, OLAP and Data Mining Scoring Engine options 再看一下: [root@rac01 ~]# ipcs -sa ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0xd2776b04 360449 oracle 640 171966464 27 ------ Semaphore Arrays -------- key semid owner perms nsems Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 0xfafd7074 491521 oracle 640 104 ------ Message Queues -------- key msqid owner perms used-bytes messages 只有一个内存段分配了 1.37.3. kernel.shmall kernel.shmall 参数是控制共享内存页数。该参数大小为物理内存除以 pagesize; 查看 os 系统页的大小 #getconf PAGESIZE 4096 这里显示的 pagesize 是 4k,假设一个共享内存段的最大大小是 16G,那么 需要共享内存页数是 16GB/4KB=16777216KB/4KB=4194304 (页),也就是 64Bit 系统下 16GB 物理内存,设置 kernel.shmall = 4194304 才符合要求,几乎是原 来设置 2097152 的两倍。 1.37.4. kernel.shmmni 参数 shmmni 内核参数是共享内存段的最大数量(注意这个参数不是 shmmin,是 shmmni, shmmin 表示内存段最小大小 )。 shmmni 缺省值 4096 ,一般肯定是 够用了。 1.37.5. fs.file-max 参数 fs.file-max 为 512 乘以 processes。 如 128 个 process,则 file-max=512*128=65536。 1.37.6. Oracle 下需要做调整的参数 在 Oracle 10g 中引入了一个非常重要的参数:SGA_TARGET,这也是 Oracle 10g 的一个新特性。自动共享内存管理(Automatic Shared Memory Management ASMM),控制这一特性的,就仅仅是这个参数 SGA_TARGE。设置这个参数后, 你就不需要为每个内存区来指定大小了。SGA_TARGET 指定了 SGA 可以使用 的最大内存大小,而 SGA 中各个内存的大小由 Oracle 自行控制,不需要人为 指定。 Oracle 可以随时调节各个区域的大小,使之达到系统性能最佳状态的个最合 理大小,并且控制他们之和在 SGA_TARGET 指 定 的 值 之 内 。 一 旦 给 SGA_TARGET 指定值后(默认为 0,即没有启动 ASMM),就自动启动了 ASMM Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 特性。 10g 下设置 SGA_TARGET 之后启动 ASSM 特性之后, 只有以下的这些区 的内存大小动态共享起来: * Buffer cache (DB_CACHE_SIZE) * Shared pool (SHARED_POOL_SIZE) * Large pool (LARGE_POOL_SIZE) * Java pool (JAVA_POOL_SIZE) * Streams pool (STREAMS_POOL_SIZE) 而 SGA 中的其他区域的内存大小仍然是固定不共享的。它的含义和 SGA_MAX_SIZE 的一样,也表示 SGA 最大的大小,于是它也就有了一个限制, 那就是它的大小不能大于 SGA_MAX_SIZE 的大小。 Oracle10g 下, SGA_MAX_SIZE 仍然表示 SGA 的大小的上限值,而 SGA_TARGET 是 SGA 的所有组件的大小的最大值之和,即当 SGA_TARGET< SGA_MAX_SIZE 的时候,oracle 就 会 忽 略 SGA_MAX_SIZE 的值, SGA_TARGET 也就成了 SGA 的在此实例中的上限制,它能动态改变大小,但 是不能够大于 SGA_MAX_SIZE 的值。 当SGA_TARGET< SGA_MAX_SIZE 时,实例重启以后 SGA_MAX_SIZE 就 变成 SGA_TARGET 的大小了。 在 11g 中,这个 SGA_TARGET 只能设置是等于 SGA_MAX_SIZE 的大小 了,设置比它小,oracle 会自动帮你调整,设置比它大,那还是出错。现在可以 自己想想,oracle 对 SGA_TARGET 的大小处理在往正确的简单的方向前进中。 SGA_TARGET 带来一个重要的好处就是,能使 SGA 的利用率达到最佳, 从而节省内存成本。因为 ASMM 启动后,Oracle 会自动根据需要调整各个区域 的大小,大大减少了某些区域内存紧张,而某些区域又有内存空闲的矛盾情况出 现。 1.38 Oracle 补丁体系 及 opatch 工具 介绍 Blog: http://blog.csdn.net/tianlesoftware/archive/2010/08/13/5809526.aspx 1.38.1 CPU(Critical Patch Update) 一个 CPU 内包含了对多个安全漏洞的修复,并且也包括相应必需的非安全 漏洞的补丁。CPU 是累积型的,只要安装最新发布的 CPU 即可,其中包括之前 发布的所有 CPU 的内容。事实上,在 CPU 之前的安全漏洞修改除去个别例外也 被包括在 CPU 中。Oracle 公司只对处于标准技术支持和延长支持期间的产品提 供 CPU 更新,对处于维持支持范围的产品不提供新的 CPU.(对于 9.2 以前的版 本,只对处于 ECS 和 EMS 期间的版本提供 CPU 更新。) Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 一般对当前补丁发行版及前一个版本提供 CPU,但也有只限于当前补丁发行版 的例外情形。也就是说,一般需要先安装最新 PSR 后才可能安装 CPU.由于是累 积型的定期发布,所以对于某一平台的某一版本,如果两次 CPU 发布期间没有 发现新的安全漏洞,则新发布的 CPU 与前一版本完全相同。 可以在以下网址中可以找到 CPU 发布的信息,只要在 Oracle 免费注册一个用户, 就可以收到这些补丁的信息。但是,只有技术支持签约用户才可以从 metalink 下载补丁文件。 http://www.oracle.com/technology/deploy/security/alerts.htm Oracle 公司制定的 CPU 的发布日期大约在一月、四月、七月和十月的最接近 15 的星期二。 Critical Patch Updates Critical Patch Updates are the primary means of releasing security fixes for Oracle products to customers with valid support contracts. They are released on the Tuesday closest to the 15th day of January, April, July and October. Starting 2011, the scheduled dates for the release of Critical Patch Updates will be on the Tuesday closest to the 17th day of January, April, July and October. The next four dates are: 12 October 2010 18 January 2011 19 April 2011 19 July 2011 对于每一个 CPU,附有相应的说明文档(Critical Patch Update Note),其中 介绍安装过程和注意事项,在安装之前应认真阅读此文档。同样也存在文档 ―Oracle Critical Patch Update MM YYYY Known Issues for Oracle Database‖,其中 列出了说明文档中没有给出的新信息。 1.38.2 PSR(Patch Set Release) 和 PSU(Patch Set Update) 8i,9i,10g,11g 这是其主要版本号,每一版本会陆续有两至三个发行版,如 10.1, 10.2,和 11.1,11.2 分别是 10g 和 11g 的两个发行版。对于每一个发行版软件中 发现的 BUG,给出相应的修复补丁。每隔一定时期,会将所有补丁集成到软件 中,经过集成测试后,进行发布,也称为 PSR(Patch Set Release)。以 10.2 为 例,10.2.0.1.0 是基础发行版,至今已有三个 PSR 发布,每个 PSR 修改 5 位版本 号的第 4 位,最新 10.2 的 PSR 为 10.2.0.4.0。(11.1.0.6.0 是 11.1 的基础发行版, 11.1.0.7.0 是第一次 PSR) 。 在某个 PSR 之后编写的补丁,在还没有加入到下一个 PSR 之前,以个别补 丁(Interim Patch)的形式提供给客户。某个个别补丁是针对 Oracle 公司发现的 或客户报告的某一个 BUG 编写的补丁,多个个别补丁之间一同安装时可能会有Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 冲突,即同一个目标模块分别进行了不同的修改。另外,即便在安装时没有发现 冲突,由于没有进行严格的集成测试,运行过程中由于相互作用是否会发生意外 也不能完全排除。 除去修改功能和性能 BUG 的补丁,还有应对安全漏洞的安全补丁。Oracle 公司定期(一年四期)发布安全补丁集,称之为 CPU(Critical Patch Updates)。 由于数据库在信息系统的核心地位,对其性能和安全性的要求非常高。理应 及时安装所有重要补丁。另外一个方面,基于同样的理由,要求数据库系统必须 非常稳定,安装补丁而导致的系统故障和性能下降同样不可接受。DBA 经常面 临一个非常困难的选择:对于多个修复重要 BUG 的个别补丁是否安装。不安装, 失去预防故障发生的机会,以后故障发生时,自己是无作为;安装,如果这些补 丁中存在着倒退 BUG,或者相互影响,以后发生由于安装补丁而造成的故障时, 自己则是无事生非!而等待下一个 PSR,一般又需要一年时间。因此,出现了 PSU(Patch Set Update)。 PSU 解决以下几个问题: 1. 减轻 PSR 周期长而带来的不能及时更新的影响; 2. 解决多个个别补丁冲突和相互影响的问题; 3. 减轻 DBA 安装补丁的负担:补丁安装次数,不定期检查补丁发布。 PSU 具有如下特点: 第一、PSU 是 PSR 的补充,在两次 PSR 发布之间发布多个 PSU,加快更新 速度。每个 PSU 修改 5 位版本号的第 5 位。例如,安装此次发布的 PSU 后,11.1 版本―升级‖为 11.1.0.7.1;10.2 版本为 10.2.0.4.2。 第二、每个 PSU 中包含 25 至 100 个重要补丁,作为一个整体进行严格测试, 解决冲突问题,保证系统的稳定性。PSU 不仅包括对功能、性能修复的一般补丁, 也包括安全补丁。 第三、PSU 定期发布,计划一年分布四次,发布日期与 CPU 发布日期相同。 由于 PSU 包括同期发布的 CPU,只要安装 PSU 即可。(对部分平台,仍提供单 独的 CPU,供客户选择) 第四、如同 PSR 和 CPU 一样,PSU 是累积型的,即只要安装最新的 PSU 就 自动包括以前所有 PSU 的内容。 第五、使用 DBA 已经熟悉的 Opatch 工具安装/删除 PSU,命令仍是 apply 和 rollback。一个 PSU 可视作一个个别补丁,安装和删除操作都很简便。 第六、现有的个别补丁与 PSU 的关系分为三类:完全独立;是 PSU 的一部 分;与 PSU 冲突。第一类的个别补丁与 PSU 相互没有影响,可以独立的安装或 删除。对于第二类,在安装 PSU 之后,自然没有必要安装。若在 PSU 之前已安 装,则在安装 PSU 时会被自动删除。对于第三类个别补丁,如在 PSU 之前已安 装,必须在安装 PSU 时删除。客户可以向 Oracle 公司技术支持部门提出申请, 由 Oracle 负责提供与 PSU 不冲突的,在 PSU 之上安装的相应的新的版本。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 PSU 的限制:必须是在正常技术支持范围之内的版本(11.2、11.1 和 10.2), 并 且 PSU 只能在最新 PSR 之上安装。 1.38.3 OPatch 命令 先看一个官网的 Oracle OPatch 的说明: Oracle Software Patching Using Opatch http://download.oracle.com/docs/cd/B19306_01/em.102/b16227/oui8_op atch.htm 从 9.2 版开始,Oracle 公司实现了个别补丁安装工具 opatch. opatch 使用一个 称为 inventory 的系统数据结构(严格说是与 oui 共享 inventory),集中管理所有 已安装的个别补丁;个别补丁的安装和卸载都使用 opatch 命令完成,冲突检测 也由 opatch 在安装时自动完成;提供列表命令可以很方便得到已安装个别补丁 的信息。 10g(10.1 和 10.2)版本中,opatch 作为一个标准工具,在安装时自动安装。 (安装在$ORACLE_HOME/OPatch 下。)而对于 9.2 版,需要从 metalink 下载 opatch.无论是哪一个版本,系统中是否已经安装 opatch,在使用之前,应从 metalink 下载最新版本的 opatch.很遗憾,由于系统实现的问题,10.2 使用的 opatch 与之前版本(10.1 和 9.2)使用的 opatch 不兼容,不能混用,这一点必须注意。 opatch 是使用 perl 编写的脚本程序(其中也使用 JAVA API)。使用的 perl 版 本是 5.6 版,虽然在 5.6 之前的版本中也可运行,但应尽可能安装 5.6 或以上的 版本的 perl. 对于 DBA 来说一个好消息是,如果安装 9.2 版软件时保留了 HTTP 服务器,则在$ORACLE_HOME/Apache 下会自动安装 perl.(10g 会自动安装配 置 perl 和 opatch.) 1.38.3.1 opatch 命令存放位置 该命令的存放位置在$ORACLE_HOME 下的 OPatch 目录下。 -bash-3.2$ pwd /u01/oracle/oracle/product/10.2.0/db_1/OPatch -bash-3.2$ ls docs emdpatch.pl jlib opatch opatch.ini opatch.pl -bash-3.2$ ls -lrt total 44 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 -rw-r--r-- 1 oracle oinstall 18107 Apr 18 2005 emdpatch.pl -rw-r--r-- 1 oracle oinstall 2193 Jun 1 2005 opatch.pl -rwxr-xr-x 1 oracle oinstall 5672 Jun 1 2005 opatch drwxr-x--- 2 oracle oinstall 4096 Apr 21 13:24 jlib drwxr-x--- 2 oracle oinstall 4096 Apr 21 13:24 docs -rw-r--r-- 1 oracle oinstall 49 Apr 21 13:24 opatch.ini 1.38.3.2 使用“-help”参数可以获得 opatch 命令的帮助信息 -bash-3.2$ ./opatch --help Invoking OPatch 10.2.0.1.0 Oracle interim Patch Installer version 10.2.0.1.0 Copyright (c) 2005, Oracle Corporation. All rights reserved.. Oracle Home : /u01/oracle/oracle/product/10.2.0/db_1 Central Inventory : /u01/oracle/oraInventory from : /u01/oracle/oracle/product/10.2.0/db_1/oraInst.loc OPatch version : 10.2.0.1.0 OUI version : 10.2.0.1.0 OUI location : /u01/oracle/oracle/product/10.2.0/db_1//oui Log file location : /u01/oracle/oracle/product/10.2.0/db_1/cfgtoollogs/opatch/opatch-2010 _Aug_09_03-05-40-CST_Mon.log Usage: opatch [ -help ] [ -r[eport] ] [ command ] command := apply lsinventory query rollback version := -help Displays the help message for the command. -report Print the actions without executing (deprecated). example: 'opatch -help' 'opatch apply -help' 'opatch lsinventory -help' 'opatch rollback -help' OPatch succeeded. 这个是 10.2.0.1 版本的 opatch. 在 10.2.0.4 版本的 opatch 命令与之前Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 的又不同,它有添加了几个命令。 -bash-3.2$ ./opatch --help Invoking OPatch 11.1.0.6.6 Oracle Interim Patch Installer version 11.1.0.6.6 Copyright (c) 2009, Oracle Corporation. All rights reserved. Usage: opatch [ -help ] [ -r[eport] ] [ command ] command := apply lsinventory napply nrollback rollback query version prereq util := -help Displays the help message for the command. -report Print the actions without executing. example: 'opatch -help' 'opatch apply -help' 'opatch lsinventory -help' 'opatch napply -help' 'opatch nrollback -help' 'opatch rollback -help' 'opatch prereq -help' 'opatch util -help' OPatch succeeded. 官网上对命令的一些解释: apply Installs an interim patch. Refer to "apply Command" for more information. napply Installs n number of patches (hence napply). Refer to "napply Command" for more information. auto Applies Oracle Clusterware patches. Refer to "auto Command" for more information. lsinventory Lists what is currently installed on the system. Refer to "lsinventory Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Command" for more information. query Queries a given patch for specific details. Refer to "query Command" for more information. rollback Removes an interim patch. Refer to "rollback Command" for more information. nrollback Removes n number of patches (hence nrollback). Refer to "nrollback Command" for more information. version Prints the current version of the patch tool. Refer to "version Command" for more information. 在$ORACLE_HOME/OPatch/docs 目录下,用指南文件(Users_Guide.txt), 其中有详细的命令格式和使用示例,可以参考。 Opatch 执行操作时,除在屏幕输出结果外,还生成日志文件。日志文件的路 径和文件名格式如下: $ORACLE_HOME/.patch_storage/< patch_id >/< action >-< patch_id >_< mm-dd-yyyy_hh-mi-ss>.log 其中―patch_id‖是 Oracle 技术支持部门为个别补丁分配的编号。 1.38.3.3 opatch 安装个别补丁示例: 以 Patch 5689937 为例。 3.3.1 patch 下载 从 metalink 下载补丁的压缩文件 p5689937_10201_LINUX.zip.将此文件解 压缩至某一目录中。解压缩后,这一补丁的所有文件都在子目录 5689937 下,目 录名就是个别补丁的补丁号,opatch 依据目录名获得信息,所以一定不要重命名 子目录。 3.3.2 安装 patch 进入 patch 文件 5689937 目录,在 patch 的目录下面有一个 readme 的安装文 档,里面有安装步骤和一些问题的处理方法。 3.3.2.1 关闭数据库和监听 Shut down all instances and listeners associated with the Oracle home that you are updating. 3.3.2.2. 进入 patch 目录,运行 opatch apply 命令 -bash-3.2$ cd p5689937_10201_LINUX/ -bash-3.2$ ls Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 5689937 patchmd.xml README.html -bash-3.2$ cd 5689937/ -bash-3.2$ ls custom etc files README.txt -bash-3.2$ pwd /mnt/p5689937_10201_LINUX/5689937 -bash-3.2$ export PATH=$PATH:/usr/ccs/bin -bash-3.2$ $ORACLE_HOME/OPatch/opatch apply 3.3.2.3 启动实例,运行相关脚本 -bash-3.2$ cd $ORACLE_HOME/cpu/CPUJan2007/ -- 要进入这个目录 才能找到脚本 -bash-3.2$ sqlplus /nolog SQL*Plus: Release 10.2.0.1.0 - Production on Mon Aug 9 04:48:19 2010 Copyright (c) 1982, 2005, Oracle. All rights reserved. SQL> conn / as sysdba Connected to an idle instance. SQL> startup ORACLE instance started. Total System Global Area 281018368 bytes Fixed Size 1218968 bytes Variable Size 83887720 bytes Database Buffers 192937984 bytes Redo Buffers 2973696 bytes Database mounted. Database opened. SQL> @catcpu.sql 如果 catcpu.sql 脚本报任何无效对象,执行如下脚本: SQL> @?/rdbms/admin/utlrp.sql 可以用如下 SQL 检查无效对象: SQL> SELECT OBJECT_NAME FROM DBA_OBJECTS WHERE STATUS= 'INVALID'; 3.3.3 用 inventory 命令查看已经安装的 patch -bash-3.2$ $ORACLE_HOME/OPatch/opatch lsinventory Invoking OPatch 10.2.0.1.0 Oracle interim Patch Installer version 10.2.0.1.0 Copyright (c) 2005, Oracle Corporation. All rights reserved.. Oracle Home : /u01/oracle/oracle/product/10.2.0/db_1 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Central Inventory : /u01/oracle/oraInventory from : /u01/oracle/oracle/product/10.2.0/db_1/oraInst.loc OPatch version : 10.2.0.1.0 OUI version : 10.2.0.1.0 OUI location : /u01/oracle/oracle/product/10.2.0/db_1//oui Log file location : /u01/oracle/oracle/product/10.2.0/db_1/cfgtoollogs/opatch/opatch-2010_Aug_09_04- 55-55-CST_Mon.log Lsinventory Output file location : /u01/oracle/oracle/product/10.2.0/db_1/cfgtoollogs/opatch/lsinv/lsinventory-2010_Au g_09_04-55-55-CST_Mon.txt -------------------------------------------------------------------------------- Installed Top-level Products (1): Oracle Database 10g 10.2.0.1.0 There are 1 products installed in this Oracle Home. Interim patches (1) : Patch 5689937 : applied on Mon Aug 09 04:43:27 CST 2010 Created on 8 Jan 2007, 11:48:31 hrs US/Eastern Bugs fixed: 4671216, 4925103, 4604970, 4616376, 5689937, 4288876, 5225798, 5694720 4754888, 4750469, 4369235, 4751931, 4966716, 5049080, 5242648, 4348230 5490846, 4630549, 5490936, 5049088 -------------------------------------------------------------------------------- OPatch succeeded. 或者用$ORACLE_HOME/OPatch/opatch lsinventory –detail 命令查看详细。 1.38.3.4 卸载 opatch 3.4.1 关闭实例和监听 SQL> shutdown immediate 3.4.2 执行 opatch 命令 -bash-3.2$ cd $ORACLE_HOME/OPatch/ -bash-3.2$ ./opatch rollback -id 5689937 3.4.3 启动实例,执行 catcpu_rollback.sql 脚本 -bash-3.2$ cd $ORACLE_HOME/cpu/CPUJan2007/ Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 -bash-3.2$ sqlplus /nolog SQL*Plus: Release 10.2.0.1.0 - Production on Mon Aug 9 05:04:19 2010 Copyright (c) 1982, 2005, Oracle. All rights reserved. SQL> conn / as sysdba Connected to an idle instance. SQL> startup ORACLE instance started. Total System Global Area 281018368 bytes Fixed Size 1218968 bytes Variable Size 109053544 bytes Database Buffers 167772160 bytes Redo Buffers 2973696 bytes Database mounted. Database opened. SQL> @catcpu_rollback.sql -- 这个脚本在 patch 的安装目录里也有 如果在运行中出现无效对象,运行如下脚本: SQL> @?/rdbms/admin/utlrp.sql 检查无效对象: SQL> SELECT OBJECT_NAME FROM DBA_OBJECTS WHERE STATUS = 'INVALID'; 关于 Patch 的说明就到此。 在后说明一点。 有时我们的生产库遇到一个问题, 但是又不能十分确定是否是某个 bug 的时候,可以先考虑打 patch 看一下,如果 解决了更好,如果不能解决,把 patch 删掉即可。 这样可以把问题控制在可控 的范围内,避免把问题扩大化。 1.39 DBID,SID,DB_NAME,DB_DOMAIN,INSTANCE_NAME, DB_UNIQUE_NAME, SERVICE_NAMES 及监听参数的说明 Blog:http://blog.csdn.net/tianlesoftware/archive/2010/12/20/6086066.aspx 这篇文章中要讲的几个参数: DB 相关的: DBID, SID PFILE 中的参数:DB_NAME,DB_DOMAIN, INSTANCE_NAME, DB_UNIQUE_NAME,SERVICE_NAMES, GLOBAL_NAME,GLOBAL_NAMES Listener.ora 中参数: SID_NAME,GLOBAL_DBNAME Tnsnames.ora 中参数: Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 SERVICE_NAME,SID 1.39.1 与 DB 相关的 2 个参数 1.1 DBID(DataBase IDentifier) Oracle 官网对 DBID 的解释如下: An internal, uniquely generated number that differentiates databases. Oracle creates this number automatically when you create the database. DBID 可以看成是 db_name 在数据库内部的表示。 DBID 是在创建数据库 时,用 db_name 结合一种算法来创建的。 具体用什么算法,不太清楚。它存在 与数据文件和控制文件,用于表示数据文件的归属。 所以这个 DBID 是唯一的。 对于不同的数据库,DBID 是不同的,但是 db_name 有可能相同。 用身份证打个比方: 可以有同名的人,但是它的省份证号码肯定是不同的。 查看 DBID: SQL> select dbid from v$database; DBID ---------- 1262006473 我们可以用命令来修改 DBID, 这个官网有说明: Changing the DBID and DBNAME of a Database http://download.oracle.com/docs/cd/E11882_01/server.112/e16536/dbnewid.htm#SU TIL1543 修改的步骤如下: (1)将数据库启动到 mount 状态 (2)用 nid 命令修改:nid TARGET=/ DBNAME=tianlesoftware (3)修改之后,在启动到 mount:startup mount (4)resetlogs 打开数据库:ALTER DATABASE OPEN RESETLOGS; 要注意一点: 修改 DBID 之后,之前的备份和归档都将无效。 具体参考官网内容: Ramifications of Changing the DBID and DBNAME Changing the DBID of a database is a serious procedure. When the DBID of a database is changed, all previous backups and archived logs of the database become unusable. This is similar to creating a database except that the data is already in the datafiles. After you change the DBID, backups and archive logs that were created prior to the change can no longer be used because they still have the original DBID, which does not match the current DBID. You must open the database with the Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 RESETLOGS option, which re-creates the online redo logs and resets their sequence to 1 (see the Oracle Database Administrator's Guide). Consequently, you should make a backup of the whole database immediately after changing the DBID. Changing the DBNAME without changing the DBID does not require you to open with the RESETLOGS option, so database backups and archived logs are not invalidated. However, changing the DBNAME does have consequences. You must change the DB_NAME initialization parameter after a database name change to reflect the new name. Also, you may have to re-create the Oracle password file. If you restore an old backup of the control file (before the name change), then you should use the initialization parameter file and password file from before the database name change. From: Ramifications of Changing the DBID and DBNAME http://download.oracle.com/docs/cd/E11882_01/server.112/e16536/dbnewid.htm#SU TIL1541 1.2. SID(system identifier) 官网的说明如下: The system identifier (SID) is a unique name for an Oracle database instance on a specific host. On UNIX and Linux, Oracle Database uses the SID and Oracle home values to create a key to shared memory. Also, the SID is used by default to locate the parameter file, which is used to locate relevant files such as the database control files. On most platforms, the ORACLE_SID environment variable sets the SID, whereas the ORACLE_HOME variable sets the Oracle home. When connecting to an instance, clients can specify the SID in an Oracle Net connection or use a net service name. Oracle Database converts a service name into an ORACLE_HOME and ORACLE_SID. 查看 SID: SQL> select instance_name from v$instance; INSTANCE_NAME ---------------- orcl 尽管 v$instance 中字段 instance_name 看起来是实例名,但是实际上存储的 是 sid。 在 win 下, 不管 oracle_home 是否相同,sid 不能重复。 在 unix/linux 下只要不同版本的 oracle 安装在不同的 oracle_home 下就可以创 建相同 sid 的实例,但是 win 下不可以,主要是受到 windows 服务的限制,在服 务中不能存在服务名相同的 oracle 服务,服务名是由如下格式组成的: OracleServiceSID,因为服务名中包括了 sid,所以 sid 如果相同了,服务名就相同 了,这是 windows 所不允许的。因此在 win 下无法创建相同 sid 的不同实例。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 1.39.2 Pfile 中的参数 2.1. DB_NAME 官网的说明如下: DB_NAME specifies a database identifier of up to 8 characters. This parameter must be specified and must correspond to the name specified in the CREATE DATABASE statement. If you have multiple databases, the value of this parameter should match the Oracle instance identifier of each one to avoid confusion with other databases running on the system. The value of DB_NAME should be the same in both the standby and production initialization parameter files. The database name specified in either the STARTUP command or the ALTER DATABASE ... MOUNT statement for each instance of the cluster database must correspond to the DB_NAME initialization parameter setting. The following characters are valid in a database name: alphanumeric characters, underscore (_), number sign (#), and dollar sign ($). No other characters are valid. Oracle removes double quotation marks before processing the database name. Therefore you cannot use double quotation marks to embed other characters in the name. The database name is case insensitive. DB_NAME must be set to a text string of no more than eight characters. During database creation, the name provided for DB_NAME is recorded in the datafiles, redo log files, and control file of the database. If during database instance startup the value of the DB_NAME parameter (in the parameter file) and the database name in the control file are not the same, the database does not start. From: http://download.oracle.com/docs/cd/E11882_01/server.112/e17110/initparams062.htm #REFRN10041 DB_NAME 是数据库名,它的长度不能超过 8 个字节,超过 8 个会被截断。 对于 RAC 环境,各个节点之间的 DB_NAME 都是相同的,INSTANCE_NAME 不 同。 对于 Data Guard 环境,DB_NAME 相同,DB_UNIQUE_NAME 不同。 DB_NAME 记录在 datafile,redo log 和 control file 中。 这个记录方式就是通 过 DBID。 因为 DBID 就是用 DB_NAME 加算法来生成的。 还是借用身份证的比喻: DB_NAME 就是姓名,DBID 就是身份证。 所以如果要修改 DB_NAME,只能用 nid 命令来修改 DBID,然后修改相关 pfile 参数。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 查看 DB_NAME SQL> show parameter db_name NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ db_name string orcl SQL> select dbid,name from v$database; DBID NAME ---------- --------- 1262006473 ORCL db_name 还有一个非常重要的作用就是动态注册监听. 关于动态注册和静 态注册,参考 Blog: Oracle Listener 动态注册 与 静态注册 http://blog.csdn.net/tianlesoftware/archive/2010/04/30/5543166.aspx 不管是否指定了 service_name,或者说 service_name 的值是什么,pmon 都会 使用 db_name 动态注册监听的。 注册到监听器中的服务值从 init.ora 文件中的参数 service_names 取得。如果 该参数没有设定值,数据库将拼接 init.ora 文件中的 db_name 和 db_domain 的值 来注册自己。如果选择提供 service_names 值,您可以使用完全限定的名称(比 如 orcl.oracle.com)或缩写的名称(比如 orcl)。如果选择缩写的名称并设置了 db_domain 参数,注册到监听器中的服务将是 service_name 值和 db_domain 值的 拼接。 2.2. DB_DOMAIN 官网说明如下: Property Description Parameter type String Syntax DB_DOMAIN = domain_name Default value There is no default value. Modifiable No Range of values Any legal string of name components, separated by periods and up to 128 characters long (including the periods). This value cannot be NULL. Basic Yes Oracle RAC You must set this parameter for every instance, and multiple instances must have the same value. Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 In a distributed database system, DB_DOMAIN specifies the logical location of the database within the network structure. You should set this parameter if this database is or ever will be part of a distributed system. The value consists of the extension components of a global database name, consisting of valid identifiers (any alphanumeric ASCII characters), separated by periods. Oracle recommends that you specify DB_DOMAIN as a unique string for all databases in a domain. This parameter allows one department to create a database without worrying that it might have the same name as a database created by another department. If one sales department's DB_DOMAIN is JAPAN.ACME.COM, then their SALES database (SALES.JAPAN.ACME.COM) is uniquely distinguished from another database with DB_NAME = SALES but with DB_DOMAIN = US.ACME.COM. If you omit the domains from the name of a database link, Oracle expands the name by qualifying the database with the domain of your local database as it currently exists in the data dictionary, and then stores the link name in the data dictionary. The characters valid in a database domain name are: alphanumeric characters, underscore (_), and number sign (#). 2.3. DB_UNIQUE_NAME 官网说明如下: Property Description Parameter type String Syntax DB_UNIQUE_NAME = database_unique_name Default value Database instances: the value of DB_NAME Automatic Storage Management instances: +ASM Modifiable No Basic Yes Oracle RAC Multiple instances must have the same value. DB_UNIQUE_NAME specifies a globally unique name for the database. Databases with the same DB_NAME within the same DB_DOMAIN (for example, copies of a database created for reporting or a physical standby) must have a unique DB_UNIQUE_NAME. Every database's DB_UNIQUE_NAME must be unique within the enterprise. -- 对于 DB_NAME 系统的的数据库必须要有不同的 DB_UNIQUE_NAME。 Data Guard 就是这么回事。 The value of DB_UNIQUE_NAME can be up to 30 characters and is case insensitive. The following characters are valid in a database name: alphanumeric characters, underscore (_), number sign (#), and dollar sign ($). Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 DB_UNQUIE_NAME 的会影响到 Service_names,也会影响到动态监听的时 候的 service_name。 如在 Data Guard 环境下,如果采用动态注册,那么注册的 Service 就是 DB_UNIQUE_NAME。 但 instance 还是 instance_name,即 SID. 如: Service " orcl_st " has 1 instance(s). Instance "orcl", status BLOCKED, has 1 handler(s) for this service... Service " orcl_st _XPT" has 1 instance(s). Instance "orcl", status BLOCKED, has 1 handler(s) for this service... The command completed successfully 2.4. INSTANCE_NAME 官网说明如下: Property Description Parameter type String Syntax INSTANCE_NAME = instance_id Default value The instance's SID Note: The SID identifies the instance's shared memory on a host, but may not uniquely distinguish this instance from other instances. Modifiable No Range of values Any alphanumeric characters and the underscore (_) character Basic No In a Real Application Clusters environment, multiple instances can be associated with a single database service. Clients can override Oracle's connection load balancing by specifying a particular instance by which to connect to the database. INSTANCE_NAME specifies the unique name of this instance. In a single-instance database system, the instance name is usually the same as the database name. INSTANCE_NAME 的默认值就是 SID。 一般跟数据库库名称相同,也可以不 相同。 查看: SQL> show parameter db_name NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ db_name string racdb SQL> show parameter instance_name Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ instance_name string racdb1 INSTANCE_NAME 会影响进程的命名: [root@racnode1 ~]# ps -ef|grep pmon grid 7474 1 0 Dec16 ? 00:00:05 asm_pmon_+ASM1 oracle 8077 1 0 Dec16 ? 00:00:07 ora_pmon_racdb1 root 20204 20176 0 00:13 pts/1 00:00:00 grep pmon initSID.ora 和 orapwSID 文件要与 INSTANCE_NAME 保持一致: [oracle@racnode1 ~]$ cd $ORACLE_HOME/dbs [oracle@racnode1 dbs]$ ls hc_DBUA0.dat hc_racdb1.dat init.ora initracdb1.ora orapwracdb1 snapcf_racdb1.f 2.5 SERVICE_NAMES 官网说明如下: Property Description Parameter type String Syntax SERVICE_NAMES = db_service_name [, db_service_name [ ... ] ] Default value DB_UNIQUE_NAME.DB_DOMAIN if defined Modifiable ALTER SYSTEM Range of values Any ASCII string or comma-separated list of string names Basic No Oracle RAC Do not set the SERVICE_NAMES parameter for Oracle RAC environments. Instead, define services using Oracle Enterprise Manager and manage those services using Server Control (SRVCTL) utility. SERVICE_NAMES specifies one or more names by which clients can connect to the instance. The instance registers its service names with the listener. When a client requests a service, the listener determines which instances offer the requested service and routes the client to the appropriate instance. You can specify multiple service names in order to distinguish among different uses of the same database. For example: SERVICE_NAMES = sales.acme.com, widgetsales.acme.com You can also use service names to identify a single service that is available from Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 two different databases through the use of replication. If you do not qualify the names in this parameter with a domain, Oracle qualifies them with the value of the DB_DOMAIN parameter. If DB_DOMAIN is not specified, then no domain will be applied to the non-qualified SERVICE_NAMES values. 注意一点,服务名是复数, service_names 可以是多个值。 在 Data Guard 中, 如果采用动态注册,建议在 primary,standby 上使用相 同的 service_names,这样可能便于尽可能的实现透明切换。 如果配置了静态注册的监听在 primary,standby 上也务必保持在 listener 中要 求输入的服务名相同,尽可能的实现透明切换。 查看 service_names: SQL> show parameter service_names NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ service_names string orcl 2.6 GLOBAL_NAME global_name 是由 db_name.db_domain 构成。 查看 Global_name: SQL> SELECT * FROM GLOBAL_NAME; GLOBAL_NAME -------------------------------------------------------------------------------- RACDB 我们可以修改 GLOBAL_NAME. 如: ALTER DATABASE RENAME GLOBAL_NAME TO sales.us.example.com; 具体参考: Changing the Domain in a Global Database Name http://download.oracle.com/docs/cd/E11882_01/server.112/e17120/ds_admin001.htm #ADMIN12147 2.7 GLOBAL_NAMES 官网说明: Property Description Parameter type Boolean Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 Property Description Default value false Modifiable ALTER SESSION, ALTER SYSTEM Range of values true | false Basic No GLOBAL_NAMES specifies whether a database link is required to have the same name as the database to which it connects. If the value of GLOBAL_NAMES is false, then no check is performed. If you use or plan to use distributed processing, then Oracle recommends that you set this parameter to true to ensure the use of consistent naming conventions for databases and links in a networked environment. Global_names 是一个布尔值,global_names 的作用是创建 db link 时是否强 制使用远程数据库的 global_name,如果 global_names=true,则 db link name 必须要 求是 remote database 的 global_name,否则创建之后 db link 不能连同,缺省值是 false。多用于分布式系统。 SQL> show parameter global_names NAME TYPE VALUE ------------------------------------ ----------- ------- global_names boolean FALSE 1.39.3 Listener.ora 文件中的参数 先看一个 listener.ora 文件: [oracle@dg2 admin]$ cat listener.ora SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (SID_NAME = PLSExtProc) (ORACLE_HOME = /u01/app/oracle/product/10.2.0/db_1) (PROGRAM = extproc) ) (SID_DESC = (SID_NAME = orcl) (ORACLE_HOME = /u01/app/oracle/product/10.2.0/db_1) (GLOBAL_DBNAME = orcl) ) ) Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 3.1 SID_NAME SID_NAME 指数据库的运行的实例名,和 instance_name 保持一致。 3.2 GLOBAL_DBNAME 配置静态监听注册时,需要输入 SID 和 GLOBAL_NAME。 我上面贴出来 的内容,就是静态监听配置的内容。 SID 已经说过,和 Instance_name 保持一 致就可以了。 GLOBAL_DBNAME 是 listener 配置的对外网络连接名称,我们可以写成任 意值。 在客户端配置监听的 tnsnames.ora 文件中的 service_name 与这个 GLOBAL_DBNAME 保持一致就可以了。因为客户端访问数据库是通过监听来 实现的。 如果采用动态注册的话,PMON 进程会根据初始化参数 initSID.ora 中的 instance_name,service_names 两个参数将实例和服务动态注册到 listener 中,这时 自动注册的对外网络连接名称就是 initSID.ora 文件中 service_names. 因为 service_names 可以有多个值,如果有多个值,就会注册多个。 但是他 们对应都是同一个 instance_name。 这样,我们在客户端配置 tnsnames.ora 时, 在 service_name 写其中任意一个都可以正常连上数据库。 1.39.4 Tnsnames.ora 文件 先看一个 tnsnames.ora 文件: ORCL_PD = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.3.2)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = orcl) ) ) 4.1 SERVICE_NAME 如果服务器采监听采用了静态注册,那么这个参数就等于 Listener.ora 文件 中的 GLOBAL_DBNAME 的值。 如果是动态注册,那么这个值就是 initSID.ora 文件中 service_names 中的值。 Tianlesoftware 学习 Oracle Blog: http://blog.csdn.net/tianlesoftware DBA1 群:62697716(满); DBA2 群:62697977(满); DBA3 群:62697850(满); DBA 超级群:63306533 DBA4 群:83829929(满); DBA5 群:142216823 DBA6 群:158654907 4.2 SID 在 tnsnames.ora 文件中还可以使用 SID。 如果使用该参数,只需要把该参数 指定为 instance_name 就可以了。 1.40 Heap-Organized table 和 Index-Organized table 说明 Blog: http://blog.csdn.net/tianlesoftware/archive/2011/05/24/6443451.aspx 官网的两个连接如下: Tables and Table Clusters http://download.oracle.com/docs/cd/E11882_01/server.112/e16508/tablecls.htm#i204 38 Indexes and Index-Organized Tables http://download.oracle.com/docs/cd/E11882_01/server.112/e16508/indexiot.htm#CB BFIFAB 这 2 个文章讲的比较详细,