ORACLE数据库部署方案设计_建设银行

sky_heaven

贡献于2011-03-14

字数:73224 关键词: Oracle 数据库服务器 方案 RAC

5a1a43a381f6d8b4024a8b35fc9e690e.doc.0 ORACLE数据库部署方案设计 和安装配置指南 (V1.6) 北京数据中心开放系统平台管理部 2008年4月 修改记录 编号 日期 描述 版本 作者 审核 发布日期 1 2008-04-15 建立文档 1.0 聂大威 开放系统平台管理部 北京数据中心 开放平台管理部 第 页 共 146 页 5a1a43a381f6d8b4024a8b35fc9e690e.doc.0 2 2008-04-21至23 版本更新 1.1 聂大威 开放系统平台管理部 3 2008-05-12至14 版本更新 1.3 聂大威 开放系统平台管理部 4 2008-05-26至27 版本更新 1.4 聂大威 开放系统平台管理部 5 2008-06-18 版本更新 1.5 聂大威 开放系统平台管理部 6 2009-03-19 版本更新:细化了参数设置等 1.6 贺耀东 开放系统平台管理部 本文档中所包含的信息属于jimi信息,如无中国建设银行的书面许可,任何人都无权复制或利用。 ®Copy Right 2005 by China Construction Bank 北京数据中心 开放平台管理部 第 页 共 146 页 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 目录 1 前言 7 1.1 编写目的 7 1.2 预期读者 8 1.3 数据库部署模式 8 1.4 单机模式 8 1.5 HA热备模式 9 1.6 RAC模式 10 1.7 DATAGUARD模式 11 1.8 RAC+DATAGUARD模式 11 2 数据库部署模式选择建议 12 2.1 部署模式的选择建议 12 2.2 各部署模式应用建议 12 2.3 RAC部署模式应用建议 13 2.4 操作系统参数建议 14 2.4.1 AIX 14 2.4.2 HP 15 3 数据库设计考虑的因素 15 3.1 数据库类型特点分析 15 3.1.1 OLTP(联机事务处理) 15 3.1.2 OLAP(联机分析处理) 16 3.1.3 BATCH(批处理系统) 16 3.1.4 DSS(决策支持系统) 16 3.1.5 Hybrid(混合类型系统) 16 3.2 数据库规模 17 4 数据库部署前提建议 17 4.1 数据库产品选择建议 17 4.2 磁盘阵列布局原则 17 5 数据库物理结构设计 18 5.1 软件安装路径及环境变量 18 5.2 数据库实例的命名规则 19 5.3 表空间设计 19 5.3.1 业务数据量的估算 19 5.3.2 表空间的使用规则 20 5.3.2.1 表空间的类型 20 5.3.2.2 表空间及其文件的命名规则 22 5.3.3 表空间的物理使用规则 24 5.3.3.1 表空间的物理分布 24 5.3.3.2 表空间的存储参数的设置 25 5.3.4 表空间的参数设置原则 26 5.3.4.1 Extent的管理 26 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 5.3.4.2 Segemnt的管理 27 5.3.4.3 Autoextend_Clause 29 5.3.5 表的参数设置原则 30 5.3.5.1 Undo/temp表空间的估算 30 5.3.6 索引的使用原则 31 5.4 文件设计 32 5.4.1 RAC配置文件 32 5.4.2 参数文件 33 5.4.2.1 参数文件命名规则 33 5.4.3 控制文件 34 5.4.3.1 控制文件命名规则 34 5.4.4 重做日志文件 35 5.4.4.1 日志文件命名规则 35 6 数据库应用 36 6.1 数据库用户设计 36 6.1.1 数据库用户的权限 36 6.1.1.1 用户权限控制原则 36 6.1.1.2 用户及其权限规范 37 6.1.1.3 各用户类型的角色命名规范 39 6.1.2 数据库用户安全的实现 39 6.1.2.1 数据库特权 39 6.1.2.2 角色 40 6.1.2.3 授予权限和角色 42 6.1.2.4 数据库默认用户 44 6.1.2.5 数据库用户密码 44 6.2 数据库分区 44 6.2.1 数据库分区介绍 44 6.2.2 逻辑分割 44 6.2.3 物理分割 45 6.2.4 分区后对数据库管理的好处 45 6.2.5 分区对数据库规划、创建带来的负面影响 45 6.2.6 Oracle分区技术 46 6.2.7 分区使用选择 46 6.2.8 分区索引 47 6.2.8.1 全局索引(GLOBAL index ) 47 6.2.8.2 本地索引(LOCAL index) 47 6.3 数据库实例配置 48 6.3.1 数据库字符集 48 6.3.2 数据库版本和补丁集 49 6.4 数据库参数设置 49 6.4.1 必须修改的初始化参数 49 6.4.1.1 DB_CACHE_SIZE 49 6.4.1.2 SHARED_POOL_SIZE 50 6.4.1.3 LARGE_POOL_SIZE 51 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6.4.1.4 DB_BLOCK_SIZE 51 6.4.1.5 SP_FILE 52 6.4.1.6 PGA_AGGREGATE_TARGET 52 6.4.1.7 PROCESSES 53 6.4.1.8 OPEN_CURSORS 53 6.4.1.9 MAX_DUMP_FILE_SIZE 53 6.4.1.10 RECOVERY_PARALLELISM 53 6.4.1.11 PARALLEL_EXECUTION_MESSAGE_SIZE 54 6.4.1.12 INSTANCE_GROUPS(RAC) 54 6.4.1.13 PARALLEL_INSTANCE_GROUP(RAC) 54 6.4.1.14 与DRM有关的隐藏参数(RAC) 55 6.4.2 系统优化建议修改的初始化参数 55 6.4.2.1 SESSION_CACHED_CURSORS 55 6.4.2.2 BACKUP_TAPE_IO_SLAVES 55 6.4.2.3 JAVA_POOL_SIZE 56 6.4.2.4 OPTIMIZER_INDEX_COST_ADJ 56 6.4.3 不得修改的初始化参数 57 6.4.3.1 COMPATIBLE 57 6.4.3.2 CURSOR_SHARING 57 6.4.3.3 SGA_TARGET 57 6.4.3.4 SGA_MAX_SIZE 58 6.4.4 建议不修改的初始化参数 58 6.4.4.1 UNDO_RETENTION 58 6.4.4.2 SESSIONS 58 6.4.4.3 TRANSACTIONS 59 6.4.4.4 DB_KEEP_CACHE_SIZE 59 6.4.4.5 LOCK_SGA 60 6.4.4.6 DB_FILES 60 6.4.4.7 DB_FILE_MULTIBLOCK_READ_COUNT 60 6.4.4.8 LOG_BUFFER 61 6.4.4.9 FAST_START_MTTR_TARGET 61 6.4.5 与并行操作有关的参数 62 6.5 数据库连接服务 62 6.5.1 专用服务器连接 62 6.5.2 共享服务器连接 63 6.5.3 连接服务建议 64 6.5.3.1 专用服务器连接 64 6.6 数据库安全建议 64 6.6.1 采用满足需求的最小安装 64 6.6.2 安装时的安全 64 6.6.2.1 删除或修改默认的用户名和密码 64 6.6.2.2 安装最新的安全补丁 65 6.7 数据库备份和恢复 65 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6.7.1 RMAN 备份 65 6.7.2 Export/import备份 66 6.7.3 存储级备份—虚拟带库 66 6.7.4 数据库恢复 67 6.7.4.1 实例故障的一致性恢复 67 6.7.4.2 介质故障或文件错误的不一致恢复 67 6.8 ORACLE NETWORK 配置 68 6.8.1 监听器的使用配置原则 68 6.8.2 TNSNAMES的使用配置原则 68 6.8.3 RAC环境下TNSNAMES的配置 69 6.8.3.1 各节点启用负载均衡 69 6.8.3.2 各节点不启用负载均衡 69 7 数据库开发建议 70 7.1 数据库模型设计规范 70 7.1.1 命名规则 70 7.1.2 表 72 7.1.2.1 建表的参数设置 72 7.1.2.2 主外键设计 72 7.1.2.3 列设计 72 7.1.2.4 临时表 73 7.1.3 索引 73 7.1.4 视图 73 7.1.5 存储过程、函数和包 73 7.1.6 触发器 74 7.1.7 序列 74 7.1.8 Directory 74 7.1.9 别名 74 7.1.10 Database Link 74 7.2 PLSQL开发规则 75 7.2.1 总体开发原则 75 7.2.2 程序编写规则 75 7.2.2.1 在PL/SQL中使用SQL 75 7.2.2.2 变量声明原则 77 7.2.2.3 游标 78 7.2.2.4 集合 82 7.2.2.5 动态PL/SQL 87 7.2.2.6 对象 90 7.2.2.7 大对象类型(LOB) 92 7.2.2.8 包(PACKAGE ) 101 7.2.3 故障处理规则 102 7.3 SQL语句编写规则 105 7.3.1 查询语句的使用原则 105 7.3.1.1 索引的正确使用 105 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 7.3.1.2 使用连接方式的原则 108 7.3.1.3 进行复杂查询的原则 112 7.3.2 DML语句的调整原则 116 7.3.2.1 Oracle存储参数的影响 116 7.3.2.2 大数据类型的影响 117 7.3.2.3 DML执行时约束的开销 118 7.3.2.4 DML执行时维护索引所需的开销 118 8 附件 119 8.1 部分系统数据库参数配置 119 8.2 部分系统参数配置 119 8.3 Oracle参数说明 119 1 前言 1.1 编写目的 为总结我中心开放系统建设的成果,加强开放系统平台建设工作的规范化管理,我们梳理了开放系统平台基础设施设计的相关文档,并进行了深化、细化,力求结合实际的设计、实施工作,对设计、实施起到规范、指导作用。 本指南主要从一个设计者的角度进行阐述,相关章节也按此思路编写。作为一个设计者,首先要了解产品可实现的部署模式,如何选择部署模式,其次要考虑设计涉及到的因素,有针对性地做好数据库的设计等;为提高数据库的性能,对程序开发提出了的要求。 在界线的划分上,基础产品只涉及本产品的设计,上层应用产品对基础产品的需求放在应用产品中,例如,ORACLE部署对AIX的要求,放在ORACLE设计指导中。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 在编写过程中,特别关注可操作性,不仅仅是要求,而是提出建议,尽量覆盖设计工作中涉及的工作要点。本指南中参数建议值是对系统设计时的指导,是合理的经验值,但由于应用系统的复杂性,每个系统有自己的特点,建议按建议值进行系统的初始配置,在压力测试和系统上线后根据实际需要做相应的调整。附件中列出了ERP/CLPM/CCBSBS/EBANK四个系统的oracle数据库配置参数以及相应的AIX、HP系统配置参数,作为系统设计的参考。 1.2 预期读者 项目基础设施可行性研究、设计和实施人员,项目组应用系统设计人员,相关运行维护技术人员。 1.3 数据库部署模式 1.4 单机模式 数据库服务器采用单服务器模式,满足对可用性和性能要求不高的应用, 具备以下特点: 1、 硬件成本低。单节点,硬件投入较低,满足非重要系统的需求。 2、 安装配置简单。由于是单节点、单实例,所以安装配置比较简单。 3、 管理维护成本低。单实例,维护成本低。 4、 对应用设计的要求较低。由于是单实例,不存在RAC系统应用设计时需要注意的事项,所以应用设计的要求较低。 5、 可用性不高。由于是单服务器、单实例,所以服务器和实例的故障都会导致数据库的不可用。 6、 扩展性差。无法进行横向扩展,只能进行纵向扩展。当应用对性能有更高的要求时,该模式的数据库服务器无法进行增加节点、实例等横向扩展,只能进行增加硬件配置等纵向扩展,且扩展性有局限。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 7、 根据该模式的特点有如下要求: 1) 硬件配置方面预留扩展量。由于该模式无法进行横向扩展,所以在选择硬件配置时要为以后的纵向扩展预留扩展量,避免硬件无法满足性能需求的情况。 2) 充分考虑该模式是否满足应用未来一段时间的需求。需要考虑应用在未来一段时间是否会发生变化,该模式是否满足应用变化的需求。 1.5 HA热备模式 数据库服务器采用HA热备模式,可以满足对可用性有一定要求的应用, 具备以下特点: 1、 需要冗余的服务器设备。该模式需要有冗余的服务器硬件,以满足一备一或者一备多的需求。硬件成本较高。 2、 需要HA软件的支持。该模式需要配合HA软件才可以实现。 3、 安装配置相对简单。该模式比单节点、单实例的模式配置复杂一些,需要更多的配置步骤,但相比较RAC、DATAGUARD等模式要简单。 4、 管理维护成本低。单实例,对维护人员的要求较低,维护成本低。 5、 对应用设计的要求较低。由于是单实例,不存在RAC系统应用设计时需要注意的事项,所以应用设计的要求较低。 6、 具备一定的高可用性。由于是多服务器、单实例,所以服务器和实例有故障时会发生实例在不同服务器上的切换,导致数据库的暂时不可用。无法满足对可用性有严格要求的应用类型。 7、 扩展性差。无法进行横向扩展,只能进行纵向扩展。当应用对性能有更高的要求时,该模式的数据库服务器无法进行增加节点、实例等横向扩展,只能进行增加硬件配置等纵向扩展,且扩展性有局限。 根据该模式的特点有如下要求: 1) 硬件配置方面预留扩展量。由于该模式无法进行横向扩展,所以在选择硬件配置时要为以后的纵向扩展预留扩展量,避免硬件无法满足性能需求的情况。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 2) 充分考虑该模式是否满足应用未来一段时间的需求。需要考虑应用在未来一段时间是否会发生变化,该模式是否满足应用变化的需求。 1.6 RAC模式 数据库服务器采用RAC模式,满足对高可用性要求高的应用类型, 具备以下特点: 1、 需要多个硬件服务器。根据节点的个数,相应的需要多个硬件服务器。硬件成本较高。 2、 某些数据库版本需要HA软件的支持。该模式下,某些数据库版本需要配合HA软件才可以实现。 3、 安装配置复杂。该模式比起单实例模式,安装配置相对复杂,安装配置周期长。 4、 管理维护成本高。该模式的管理维护,对管理维护人员的要求较高,管理维护成本较高。 5、 对应用设计的要求较高。需要充分考虑业务的逻辑性,以避免在多节点之间的信息交换和全局锁的产生。 6、 具备较高的高可用性。由于是多服务器、多实例,单服务器和实例有故障不会影响数据库的可用性。可以满足对可用性有严格要求的应用类型。 7、 扩展性好。既可以进行横向扩展,也可以进行纵向扩展。当应用对性能有更高的要求时,该模式的数据库可以通过增加节点的方式进行横向扩展,也可以通过增加硬件配置等纵向扩展,具备良好的扩展性。 根据该模式的特点有如下要求: 1、 硬件配置方面预留扩展量。预留一定的硬件扩展量,可以更灵活的进行扩展。 2、 在应用设计时,充分考虑业务逻辑,减少多节点间的信息交换量,更好的发挥RAC的优点。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 1.7 DATAGUARD模式 数据库服务器采用DATAGUARD灾备模式,可以满足对可用性有特殊需求的应用,具备以下特点: 1、 需要冗余的服务器设备。该模式需要有冗余的服务器硬件。硬件成本较高。 2、 需要冗余的存储设备。主机和备机都需要同样的存储空间,成本较高。 3、 安装配置比较复杂。该模式比单节点、单实例的模式配置复杂一些,需要更多的配置步骤。 4、 管理维护成本高。该模式对维护人员的要求较高,维护成本高。 5、 具备一定的容灾特性。当主机整个数据库系统不可用并短期内无法恢复时,可以把数据库系统切换到备机上,具备容灾的功能。 6、 备机可以用作只读查询。备机可以切换到只读状态供报表之类的查询操作,减轻主机的压力。 根据该模式的特点有如下要求: 1、 主机与备机在物理上要分开。为了实现容灾的特性,需要在物理上分割主机和备机。 2、 进行合理的设计,充分实现DATAGUARD的功能。 1.8 RAC+DATAGUARD模式 数据库服务器采用RAC+DATAGUARD模式,可以满足对可用性和容灾都有特定需求的应用,具备以下特点: 1、 需要冗余的服务器设备。该模式需要有冗余的服务器硬件。硬件成本较高。 2、 需要冗余的存储设备。主机和备机都需要同样的存储空间,成本较高。 3、 安装配置比较复杂。该模式既需要配置RAC又需要配置DATAGUARD,配置过程比较复杂,配置周期长。 4、 管理维护成本高。该模式对维护人员的要求较高,维护成本高。 5、 具备很高的可用性和容灾性。该模式既满足高可用性也满足容灾的需求。 6、 备机可以用作只读查询。备机可以切换到只读状态供报表之类的查询操作,减轻主机的压力。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 根据该模式的特点有如下要求: 1、 主机与备机在物理上要分开。为了实现容灾的特性,需要在物理上分割主机和备机。 2、 进行合理的设计,充分实现DATAGUARD的功能。 2 数据库部署模式选择建议 2.1 部署模式的选择建议 在设计数据库时必须考虑系统的可用性、业务连续性要求,针对系统的可用性需求,采用不同的数据库部署模式: 1、 对RTO=0、RPO=0的系统,建议数据库采用RAC或 RAC+DataGuard模式,数据库单台设备故障时对业务没有影响,并考虑灾备系统的设计。 2、 对RTO<=4小时,RPO<15分钟的系统,建议数据库采用HA热备或DataGuard的模式,设备故障时通过HA技术切换到备用设备,保证系统的可用性,对重要的系统要考虑灾备的设计。 3、 对4小时1G时默认为8192 67584 设定打开索引节点的最大数量,此值最小值为14,最大值则限于系统内存大小。 (8*NPROC+2048) MAXUPRC 256 7374 设定用户进程数量的最大值,此值必须设置为:3到nproc-5之间 ((NPROC*9)/10)+1 MSGMNI 512 8192 设定系统允许消息队列标识符的最大数,必须设置为:1到1000000之间 (NPROC) MSGTQL 1024 8192 设定系统允许消息的最大数,此值必须设置为:1到2147483647之间 (NPROC) NCSIZE 8976 68608 设定索引节点所需的目录名查找高速缓存(DNLC)空间 (NINODE+1024) 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 NFLOCKS 此值根据系统内存大小初定默认值,当内存<=1G时默认为1200;当内存>1G时默认为4096 8192 设定系统上可用文件锁的最大数量。此值须设置为50-16777216 (NPROC) SEMMNI 2048 8192 设定整个系统信号量集的最大数量。此值须设置为:2到semmns之间, (NPROC) SEMMNS 4096 16384 设定整个系统信号量的数量.此值须设置为:semmni到335534080之间 (SEMMNI*2) SEMMNU 256 8188 设定信号量undo结构的数量。此值须设置为:1到nproc-4之间。 (NPROC - 4) SHMMAX 1G 可用内存数量 设定一个共享内存段的最大允许尺寸。SHMMAX设定值应足够大,以便在一个共享内存段中装下整个SGA。设置过低的结果是创建多个共享内存段,这样会降低性能。此值须设置为:2k到4TB之间,此值的设定请根据系统内存容量以及应用需要综合考虑设置。   SHMMNI 400 512 设定整个系统中共享内存段的最大数量。此值须设置为:3到32768之间   VPS_CEILING 16(KB) 64 设定由系统选择的页面的最大尺寸,以KB为单位。此值须设定为4(KB)到4194304(KB)之间。   以上参数针对HP 11.31 3 数据库设计考虑的因素 3.1 数据库类型特点分析 在创建和规划一个Oracle数据库之前,首要任务应确定将来投产的数据库属于何种业务类型。目前的应用业务有以下类型: 1、 OLTP(Online Transaction Processing) 2、 OLAP(Online Analytiacl Processing) 3、 BATCH 4、 DSS(Decision Support System) 5、 Hybrid 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 3.1.1 OLTP(联机事务处理) OLTP数据库支持某种特定的操作,OLTP系统是一个包含繁重及频繁执行的DML应用,其面向事务的活动主要包括更新,同时也包括一些插入和删除。经典的例子是预定系统或在线时时交易系统,例如网上银行和ATM自动取款机系统。OLTP系统可以允许有很高的并发性(在这种情况下,高并发性通常表示许多用户可以同时使用一个数据库系统)。 3.1.2 OLAP(联机分析处理) OLAP系统可提供分析服务。这意味着数学、统计学、集合以及大量的计算,一个OLAP系统并不永远适合OLTP或DSS模型,有时它是两者之间的交叉。另外,也可以把OLAP看作是在OLTP系统或DSS之上的一个扩展或一个附加的功能层次。通常,地理信息系统或有关空间的数据库和OLAP数据库相集成,提供图表的映射能力。用于社会统计的人口统计数据库就是一个很好的例子。 3.1.3 BATCH(批处理系统) 批作业处理系统是作用于数据库的非交互性的自动应用。它通常含有繁忙DML语句并有较低的并发性(在这种情况下,较低的并发性通常表示少数几个用户能够同时使用一个数据库系统),该业务系统会在某一时段,大批量数据(少则几万,多则几十万,几百万条数据)更新/插入/删除该数据库。事务查询的比率决定了如何物理地设计它,经典的例子是与DW有关的成品数据库和可操作数据库,如:操作型数据存储系统(ODS)。 3.1.4 DSS(决策支持系统) DSS系统通常是一个大型的、包含历史性内容的只读数据库,通常用于简单的固定查询或特别查询。DSS常常按某种方式变成一个VLDB(Very Large Database)或DW(Data Warehouse)。VLDB的例子如:企业资源管理财务系统(ERP)数据库,该数据库是一个长期存储数据库的历史数据库;DM的例子如:整个集团的工资和人事数据库。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 3.1.5 Hybrid(混合类型系统) 同时数据库系统的应用类型可能是OLTP、OLAP、BATCH等的混合体。也意味着同时拥有上述业务类型特征,这就要求数据库管理员、应用系统分析员、操作系统管理员整体统筹考虑各种业务性能需求及功能需求,对这个系统制定出满足各种业务类型需求的规划,如:企业客户信息整合(ECIF)系统。 3.2 数据库规模 对于数据库的规模,仅从数据量来衡量其规模的大小。因为数据量的规模是反映数据库规模的主要指标。具体如下: 1、 数据库业务数据量小于100GB 属小规模数据库 2、 数据库业务数据量100GB-600GB属中等规模数据库 3、 数据库业务数据量600GB-1TB 属大规模数据库 4、 数据库业务数据量大于1TB 属超大规模数据库 4 数据库部署前提建议 4.1 数据库产品选择建议 Oracle数据库产品推出新的主要版本后,要经历一个版本不稳定期。在此期间新版的数据库产品存在较多的bug。在安装和运行过程中,会存在数据库部署安装困难和运行出现不稳定现象。因此在选择版本时,要选择成熟稳定的版本。具体安装要求须参照‘Oracle版本策略最新版’。 4.2 磁盘阵列布局原则 随着硬件技术的发展,目前磁盘阵列的使用变得越来越普遍,由于磁盘阵列和单个磁盘具有较大的不同,故此在数据库的物理划分上也有较大的不同。对于磁盘阵列系统,由于RAID的划分,不存在一个个真实的物理盘,对应的是物理卷(PV),逻辑卷组(VG),逻辑卷(LV)。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 在这种情况下Oracle推荐使用SAME技术,即全部镜像和条带化(Stripe And Mirror Everything)。在对磁盘阵列做SAME处理后,所有的逻辑卷都分布在所有的物理磁盘上,每个逻辑卷的读写都能够利用的到所有的物理磁盘的吞吐能力,同时获得较高的可靠性。同时我们在使用磁盘设备的时候不需要考虑各个不同文件的IO情况,因为它们都使用同样的全部磁盘的吞吐能力,这进一步简化了数据库系统的文件管理工作,避免一些意外的操作。 对较重要、并且效率要求较高的系统推荐使用RAID0+1的磁盘配置而不使用RAID5,因为RAID5的校验技术会降低应用数据库系统的效率。但使用RAID0+1,比RAID5需要更多物理磁盘。 不同的类型对象,尽量分布在不同的卷组上,建议: 1、 表对应的数据和索引分别放置在不同的物理磁盘上; 2、 控制文件的多个备份分别放置在不同的物理磁盘上; 3、 REDO日志组的多个成员放置在不同的物理磁盘上; 4、 建议将Oracle文件、SYSTEM表空间、TEMPORARY表空间、UNDO表空间放置在不同的物理磁盘上; 5 数据库物理结构设计 5.1 软件安装路径及环境变量 建立单独的文件系统来安装数据库软件,且文件系统的mount点不要直接建立在根目录下。 安装路径: /home/db/oracle 各种环境变量设置: ORACLE_BASE=/home/db/oracle CRS_HOME=/home/db/oracle/crs/{数据库release版本},如/home/db/oracle/crs/10.2.0 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 ORACLE_HOME=/home/db/oracle/product/{数据库release版本},如/home/db/oracle/product/10.2.0 当前(2010.3)推荐版本为10gR2,写为10.2.0,下一个版本(计划从2011.5开始推荐)为11gR2,写为11.2.0, 5.2 数据库实例的命名规则 普通使用模式的Oracle数据库的服务名和实例名(SID)是相同的;RAC模式下的Oracle数据库的服务名与实例名不同。 数据库服务名的命名格式为:XXXYYdb{m} 数据库的SID的命名格式为:XXXYYdb{m}{n} 说明: 1、 其中XXX表示长度为3个字符的应用项目缩写,具体的见相关设计文档。 2、 YY:代表数据库用途,pd代表生产库,hi代表历史库,rp代表报表库,cf代表配置库; 3、 m表示数据库序号,从0-9,根据项目的数据库数量进行编号。 4、 n表示RAC节点实例序号1,2,3……。用以区分多节点的RAC数据库的不同实例。对于普通模式的数据库,该位不指定。 5.3 表空间设计 5.3.1 业务数据量的估算 估算所有业务SCHEMA下的所有table的尺寸。 数据量估算的前提: l 数据库的物理表结构已经确定,并且设计已凝固。 l 用户方提供较为准确的估算依据,例如业务变动的频率、数据需要保存的周期等。 该表是一个示例,可根据业务的不同有所变化。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 序号 表名 增长量 (/小时/天/周) 增长量 (/月/半年) 年数据量 数据库生命周期内的总计 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 合计 新上线或扩容时,对所申请的存储不得全部一次性挂上,应该预留出30%左右的空间用于追加,以防止出现业务发展和预期不一致时剩余空间多寡不均,调整困难。 操作系统上应该预先做好几个合适大小的lv备用,包括用于system/sysaux等表空间的小尺寸的lv和用于数据表空间、索引表空间的大尺寸lv,这些lv要求在HA两边主机都可见,不必单纯因为数据库增加数据文件而需要重新同步HA。 5.3.2 表空间的使用规则 目前多数数据库系统采用数据“大集中”原则,对数据库的性能要求较高。这就要求对数据库进行必要的优化配置。表现在表空间的配置上,应遵循以下原则: 1、 最小化磁盘I/O。 2、 在不同的物理磁盘设备上,分配数据。 3、 尽可能使用本地管理表空间。 多数系统采用RAID1+0 或 RAID0+1,该技术很好的解决了最小化磁盘I/O。基本不必考虑在不同的物理磁盘设备上,分配数据的原则。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 5.3.2.1 表空间的类型 按照表空间所包含的数据文件类型,Oracle表空间类型有三类: 1、 数据表空间(permanence tablespace)-用来保存永久数据,包含永久数据文件。强烈建议在永久表空间内创建永久数据文件,不要创建临时数据文件。 2、 临时表空间(temporary tablespace)-用来保存临时数据,多用于数据的磁盘排序。强烈建议在临时表空间内创建临时数据文件,不要创建永久数据文件。 3、 回滚表空间(rollback/undo tablespace)-仅用来保存回退信息。不能在该表空间创建其他类型的段(如表、索引等)。 为了更好的管理表空间,同时提高Oracle数据库系统性能,在上述三类基础上,针对数据的业务功能,进一步对其加以分类。因此Oracle数据库的表空间划分为基本表空间和应用表空间。如下表: (1) 基本表空间:是指Oracle数据库系统为其自身运行而使用的表空间。 表空间类别 表空间名称 存储内容 说明 数据表空间 SYSTEM表空间 存储oracle数据库系统数据字典对象 Oracle数据库系统自身生成的和使用—基本表空间 数据表空间 SYSAUX 存储SYSAUX数据 Oracle数据库系统自身生成的和使用—基本表空间 回滚表空间 UNDO表空间 容纳回滚数据 如果UNDO表空间是自动管理,则Oracle数据库系统自身生成的。 生产数据库不得有如TOOLS、XDB、EXAMPLE等oracle默认安装表空间。 (2) 应用表空间:是指业务应用数据保存在此类表空间中。它由DBA或相关的数据库规划设计人员创建和规划。 表空间类别 表空间名称 存储内容 说明 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 临时表空间 TEMP表空间 容纳排序数据 由DBA设定—应用表空间 数据表空间 TABLES表空间 存储小数据表公用业务数据 由DBA设定—应用表空间 数据表空间 TABLES PARTITION表空间 存储巨型表数据 由DBA设定—应用表空间 数据表空间 INDEXS表空间 存储小数据表的索引 由DBA设定—应用表空间 数据表空间 INDEXS PARTITION表空间 存储巨型数据表的索引 由DBA设定—应用表空间 数据表空间 LOB表空间 存储LOB的数据 由DBA设定—应用表空间 5.3.2.2 表空间及其文件的命名规则 数据文件都使用裸设备方式,使用固定大小,不得设置为自动扩展。 5.3.2.2.1 基本表空间及其文件的使用规则 (1) 基本表空间及其文件命名规范如下表 表空间名称 裸设备连接文件名 普通文件名 说明 SYSTEM rsystem_nn_size systemnn.dbf 总空间大小设置为2G SYSAUX rsysaux_nn_size sysauxnn.dbf Oracle10g中必须有的表空间。总空间大小设置为4G,如果空间非常紧张,可设置为2G UNDOTBS1 rundotbs_nn_size undotbsnn.dbf 总空间不小于8G TEMP rtemp_nn_size tempnn.dbf 总空间不小于4G 说明: l 裸设备连接文件名 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 Ø nn为从01开始计数的序号,表示文件的个数。如:01,02,03,04。。。。。。 Ø size表示了设备的大小,由数字部分和单位部分组成:XU。其中,X是一个正整数,取值范围从1~1023,U是单位标识位,是1位的字符,取值范围为k、m、g、t,分别表示了KByte、MByte、GByte、TByte,size的值应该根据设备的数据大小指定。 l 普通文件名(即创建在文件系统上的文件) Ø nn为从01开始计数的两位整数序号。如:01,02,03,04。。。。。。 Ø 各表空间根据需求在建库时确定。 (2) 数据文件路径:/home/db/oracle/oradata/{DB_NAME}/ (3) 数据文件的使用方式: 裸设备:适用于RAC及共享磁盘双机热备数据库架构。创建数据库前,在指定的目录下创建指向裸设备的软连接文件。命令如下: ln -s /dev/rxxxxx /home/db/oracle/oradata/{DB_NAME}/xxxxx.dbf 5.3.2.2.2 应用表空间及其文件使用规则 (1) 应用表空间及其文件命名规范: 应用表空间分为如下种类:参见节5.2.2.1- (2)应用表空间 表空间种类 表空间命名规则 裸设备连接文件名 普通文件名 TABLES公用表空间 D_<功能模块名称>_nn r+表空间名称_nn_size 表空间名称_nn.dbf TABLES PARTITION分区表空间 D_<数据表名>_nn r+表空间名称_nn_size 表空间名称_nn.dbf INDEXS公用索引表空间 I_<功能模块名称>_nn r+表空间名称_nn_size 表空间名称_nn.dbf INDEXS PARTITION大表索引空间 I_<数据表名>_nn r+表空间名称_nn_size 表空间名称_nn.dbf LOB表空间 B_<功能模块名称>_nn r+表空间名称_nn_size 表空间名称_nn.dbf TEMP表空间 T_<功能模块名称>_nn r+表空间名称_nn_size 表空间名称_nn.dbf 说明: 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 l 表空间的命名规则 nn为从01开始计数的两位整数序号,表示表空间的数目。如:01,02,03,04。。。。。。 l 裸设备连接文件名 Ø nn为从01开始计数的两位整数序号,表示数据文件的数目。如:01,02,03,04。。。。。。 Ø size表示了设备的大小,由数字部分和单位部分组成:XU。其中,X是一个正整数,取值范围从1~1023,U是单位标识位,是1位的字符,取值范围为k、m、g、t,分别表示了KByte、MByte、GByte、TByte,size的值应该根据设备的数据大小指定。 l 普通文件名(即创建在文件系统上的文件) Ø nn为从01开始计数的两位整数,表示数据文件的数目。如:01,02,03,04。。。。。。 Ø 各表空间根据需求在建库时确定。 (2) 数据文件路径:/home/db/oracle/oradata/{DB_NAME}/ (3) 数据文件的使用方式: Ø 裸设备:适用于RAC及共享磁盘双机热备数据库架构。创建数据库前,在指定的目录下创建指向裸设备的连接文件。命令如下: ln -s /dev/rxxx /home/db/oracle/oradata/{DB_NAME}/r+表空间名称_nn_size 其中:xxx为裸设备的名称。该名规则相关命名规范。 5.3.3 表空间的物理使用规则 5.3.3.1 表空间的物理分布 对于小规模数据库,I/O不是主要的性能瓶颈,可以不考虑物理分布的问题。 对于中规模数据库及大规模数据库,应当考虑: 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 1、 尽可能把应用数据表空间、应用的索引表空间以及相应得分区表空间分布在独立的物理卷上。 2、 其次把UNDO、TEMP、REDOLOG分布在不同的物理卷上。 3、 对于hp-ux 系统,应该为不同用途的数据建立独立的卷组。 5.3.3.2 表空间的存储参数的设置 在规范表空间存储参数之前有必要澄清关于数据块(data block)、区(extent)、段(segment)的概念及其之间的关系。如下图: 数据块(data block):Oracle存储数据最细粒度是数据块,它是操作系统文件块的整数倍(有时也称逻辑块,Oracle块,或页)。一个数据块大小有2k、4k、8k、16k等,并以此单位大小保存在物理磁盘中。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 区(extent):是由一序列相邻连续的数据块组成的区域叫区。区存储特定类型的数据。它比数据块高一级别。 段(segment):比区(extent)高一逻辑存储级别的称作段(segment)。段是由一系列区组成。用来存储一个特定的数据结构,并且该段只能分配在同一表空间中,不能跨越表空间。如:每个表(table)的数据保存在自己的数据段中;而每个索引保存在自己的索引段中;如果表或索引是分区的,则每个分区拥有自己的段。 5.3.4 表空间的参数设置原则 对于数据库的存储空间管理Oracle有以下的选择: 5.3.4.1 Extent的管理 对Extent的管理有两种方式。一般情况下,我们推荐数据库管理员使用本地管理中的指定大小(Uniform Size)的方式创建表空间。 1. 数据字典管理(Dictionary Management) 在数据字典的管理方式中,数据库使用数据字典来跟踪数据对象的存储分配,这样当出现数据对象的存储变化时,数据库需要更新数据字典以保证系统可以跟踪数据库对象的存储变化,这在某种程度上会造成系统性能的下降。 2. 本地管理(Local Management) 在本地管理方式中,数据库使用每一个数据文件的前面8个数据块中的每一位来代表数据块的占用方式。由于这种方式跟踪数据对象的存储分配不需要访问数据字典,这在一定程度上避免了递归调用的出现,提高了系统存储管理的效率。 对于本地的Extent管理有两种方式: (1) 自动分配(Autoallocate) 自动分配的方式指由数据库系统按照数据对象的大小决定该对象的每一个EXNENT的大小。一般情况下,由于数据库系统并不能预先的确定该对象的总的大小,数据库总是倾向于在初始的几个Extent使用较小的值,然后按照8-128-1024-8192个数据块的方式急剧的增大。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 这通常会造成系统过多的碎片和较低的存储空间的利用效率。 (2) 指定大小(Uniform Size) 指定大小的方式指由数据库管理员在创建表空间时间指定该表空间的所有的EXNENT的大小,这样该表空间的所有的Extent具有同样的大小。 一般情况下,由于数据库管理员能够预先的估计出该表空间的数据对象的大小,所以数据库管理员通常能够确定合适的UNIFORM SIZE来创建数据表空间。 通过指定合适的数据表空间,可以避免系统出现过多的碎片和提高存储空间的利用效率。 一般情况下,建议数据库管理员能够使用指定大小的方式来创建表空间,除非明确知道表空间中仅仅存储较小的数据对象,否则不要使用自动的EXTENT管理方式。 5.3.4.2 Segemnt的管理 对Segment的管理可分为两种。我们推荐使用ASSM方式。 1. 手工管理方式(Manual) 手工管理方式是指用户创建表空间时使用手工指定参数Freelist, Freelist Group来控制表空间的段的空闲块。 手工的管理管理可以带来更多的灵活性。 2. 自动管理方式(ASSM) 自动的管理方式指数据库系统使用BITMAP的方式来管理空闲块。在这种情况下如果多个对象需要分配空间,可能会造成对某一块的竞争。 5.3.4.2.1 数据表空间的存储参数(Oracle9i/10g) 数据表空间的区(extent)管理:表空间是以区为单位进行分配空间的。自从9i及以后版本推荐使用本地管理表空间,并且本地管理表空间是默认的。对应的create tablespace语句子句为EXTENT MANAGEMENT LOCAL。Oracle已不推荐使用字典管理的表空间。如下图: 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 如果表空间包含各种不同大小的数据库对象,而这些对象拥有不同尺寸的区,则选择AUTOALLOCATE是最好的选择。即字句EXTENT MANAGEMENT LOCAL AUTOALLOCATE 。让Oracle来管理EXTENT的分配。如下例: CREATE TABLESPACE test DATAFILE '/u02/oracle/data/test01.dbf' SIZE 50M EXTENT MANAGEMENT LOCAL AUTOALLOCATE; 如果能够预先估算出单个对象或一系列对象的所分配的空间及EXTENTS的尺寸,则选择UNIFORM 是个比较好的选择。即字句UNFORM SIZE M。如下例: CREATE TABLESPACE test DATAFILE '/u02/oracle/data/test01.dbf' SIZE 50M EXTENT MANAGEMENT LOCAL UNIFORM SIZE 128K; 表空间的段(segment)管理:段管理分为自动段空间管理(缺省参数)和手动段空间管理,对应的子句如下图: 自动段管理是一种相对简单而有效的段空间的管理方式。该方式完全摒除了PCTUSED, FREELISTS, FREELISTS GROUPS等物理存储参数的设置。即使这些参数被指定,Oracle仍然会忽略它。自动段管理可根据用户数和实例数自动调整,对于大多数标准负载和应用性能来说,要比手动调整管理段要更好。因此多数情况下推荐使用段管理。如下列: CREATE TABLESPACE test DATAFILE '/u02/oracle/data/test01.dbf' SIZE 50M 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO; 下面是完整的例子: 例1:本地管理表空间+自动段空间管理sql(ORACLE9i/10g) CREATE TABLESPACE TEST DATAFILE '/ORACLE/PRODUCT/10.2.0/ORADATA/ORCL\TEST.DBF' SIZE 5M EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO; 例2:本地管理表空间+自动统一尺寸段空间管理sql(ORACLE9i/10g) CREATE TABLESPACE TEST DATAFILE '/ORACLE/PRODUCT/10.2.0/ORADATA/ORCL\TEST.DBF' SIZE 5M EXTENT MANAGEMENT LOCAL UNIFORM SIZE 2M SEGMENT SPACE MANAGEMENT AUTO; 5.3.4.2.2 临时表空间的存储参数(Oracle9i/10g) Oracle9i/10g推荐使用本地表空间管理+统一区尺寸管理1M,分别对应得子句是EXTENT MANAGEMENT LOCAL和UNIFORM SIZE 1M。 例:SQL(Oracle10.2) CREATE TEMPORARY TABLESPACE TEMP1 TEMPFILE '/ORACLE/PRODUCT/10.2.0/ORADATA/ORCL/temp1.dbf' SIZE 5M EXTENT MANAGEMENT LOCAL UNIFORM SIZE 1M; 5.3.4.3 Autoextend_Clause 自动扩展语句会造成数据文件的自动增长,在使用裸设备的情况下可能造成文件越界,在使用文件系统的情况下可能造成文件系统无空闲空间。 不应使用自动扩展的功能。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 5.3.5 表的参数设置原则 1. Pctfree、Pctused 存储参数pctfree和pctused决定了一个数据块在不同的数据库操作下的可用性,它与数据对象的操作性质密切相关。 对于主要操作为insert的数据对象,可以考虑设定较小pctfree和较大的pctused,如pctfree=5 Pctused=60。对于更新较为频繁的系统,可以设定较大的pctfree和较小的pctused来避免行的迁移,如pctfree=20 Pctused=40。对于银行系统,由于数据的保留时间较长,同时数据的删除较少可以考虑设定较小的pctfree和较大的pctused,如:Pctfree=10 Pctused=50。 2. Initrans、Maxtrans 存储参数initrans和maxtrans决定了数据对象的同一个数据块中能够并发进行的事务数。 由于目前的数据块由逐步变大的趋势,故此同一个数据块中发生并发事务的几率在上升。 对于db_Block_Size=8192的OLTP系统,可以设定initrans=4,Maxtrans=10 5.3.5.1 Undo/temp表空间的估算 l Undo设置原则 oracle9i以后的版本,推荐使用UNDO TABLESPACE,让系统自动管理回滚段。 须考虑以下几个问题: Ø 系统并发事务数有多少? Ø 系统是否存在大查询或者大是事务?频繁与否? Ø 能提供给系统的回滚段表空间的磁盘空间是多少? l Temp设置原则 可创建缺省临时表空间temp,取数据库的缺省参数。一般情况下,生产数据库系统的临时表空间不是用缺省的。应另外创建临时表空间,以供较大的排序事务使用。可设置每个 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 Transaction类别用户,对应一个临时表空间。 5.3.6 索引的使用原则 1. 基本使用原则 (1) 当查询的行数占整个表总行数的比例<=5%时,建立b*树索引效果比较明显。(普通索引就是b*数索引) (2) 在频繁进行排序或分组(即进行group By或order By操作)的列上建立索引。 (3) 在频繁使用distinct关键字进行查询的列上面建立索引。 (4) 进行表连接时,在连接字段上面建立索引。 (5) 对于键值频繁更新的索引,需要定期的进行重建。 2. 基本存储参数设置原则 (1) 物理属性子句(Physical_Attributes_Clause) 参见表的物理属性参数设置原则 (2) Storage_Clause 参见表空间的存储参数设置原则 (3) Blevel 索引的blevel代表了索引中从根节点到叶节点的深度,对于索引来说,由于索引键值的频繁更新可能造成该索引的节点的过度分裂,使得索引的层次较多。因此系统管理人员应该定期的对索引进行分析,对索引深度较深的的索引进行重建工作。 3. 复合索引的使用原则 一般情况下,对于经常同时使用多个数据项进行查询的对象可以创建复合索引,使用复合索引时特别要考虑的各个数据项在索引中的相对位置。 一般情况下,我们把最常用的列放在第一位而不太常用的列放在稍后面的位置。 在复合索引创建后,我们要求用户在查询数据的时候也遵循同样的方式来使用索引。 虽然目前的Oracle数据库版本能够使用复合索引中的后面的数据项,但是按序使用复合索引可以给我们带来较高的效率。 4. 函数索引的使用原则 (1) 在使用函数索引(Function-based INDEX)时,需要设置初始化参数QUERY_REWRITE_ENABLED=TRUE,创建该索引的用户需要有CREATE INDEX和QUERY REWRITE权限。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 (2) 对于经常进行运算比较的一些列,可以考虑建立函数索引,但是也可以通过在表中使用原来的列的函数形式来实现 (3) 在OLTP系统中,一般情况下我们不建议使用函数索引。 5. B树索引的使用原则 (1) 当查询的行数占整个表总行数的比例<=5%时,建立B*树索引效果比较明显。否则,就要慎重考虑是否需要建立B*索引。 (2) 索引列包含的不同值很多时,应该建立B*树索引。使用B*树索引时候应该注意的是,它对AND/OR等条件逻辑组合查询的效率很低。 6. 位图索引的使用原则 (1) 索引列包含的不同值很少时,应该建立位图索引。位图索引对AND/OR等条件逻辑组合查询的效率很高。 (2) 修改表的代价很大,适用于只读性,或更新很少的表 5.4 文件设计 如果使用裸设备作为数据库设备,则在该目录下建立到相应的裸设备的链接文件。如果使用文件作为数据库设备,则根据存储空间的需求,建立独立的文件系统,挂接到该目录下。 5.4.1 RAC配置文件 srvconfig_Size Size表示了文件/设备的大小,由数字部分和单位部分组成:XU,其中,X是一个正整数,取值范围从1~1023,U是单位标识位,是1位的字符,取值范围为k、m、g、t,分别表示了KByte、MByte、GByte、TByte,Size的值应该根据文件/设备的数据大小指定。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 5.4.2 参数文件 l 对于共享磁盘的双机热备的系统,发生失效接管(failover)时,应使用pfile参数文件设置;在没有发生失效接管情况下,使用spfile参数文件。 l 对于单机或RAC方式的系统,可使用共享的spfile参数文件设置; 5.4.2.1 参数文件命名规则 Oracle数据库系统在启动时,先读取初始化参数文件,根据该文件的设置,系统才能启动成功。从Oracle9i以后的版本,Oracle系统使用spfile文件和pfile参数文件。数据库系统启动时,首先查找$ORACLE_HOME/dbs/目录的spfile文件,如果无此文件,系统在查找pfile文件。spfile文件是二进制文件,而pfile文件是ASCII文件。 l pfile初始化参数文件:该文件是ASCII码文件,可用文本编辑器编辑(注:在编辑前,一定要先备份)。 文件命名:init{SID}.ora 文件路径:/home/db/{OS_oracle_user}/admin/{DB_NAME}/pfile/ 以及$ORACLE_HOME/dbs/ l spfile初始化参数文件:该文件是二进制文件,不可以直接编辑。只能通过Oracle SQL语句进行创建。方法如下(注:在创建前,一定预先备份spfile及pfile): SQL〉show parameter spfile SQL〉create spfile from pfile; spfile的两种使用方式: 文件系统:spfile{DB_NAME}.ora 裸设备:rspfile{DB_NAME}_size 保存路径:/home/db/oracle/oradata/{DB_NAME}/; 缺省路径:$ORACLE_HOME/dbs/ 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 size表示了文件/设备的大小,由数字部分和单位部分组成:XU,其中,X是一个正整数,取值范围从1~1023,U是单位标识位,是1位的字符,取值范围为k、m、g、t,分别表示了KByte、MByte、GByte、TByte,Size的值应该根据文件/设备的数据大小指定。 5.4.3 控制文件 每个数据库实例应至少有两个控制文件,且每个文件存储在独立的物理磁盘上。如果有一个磁盘失效而导致控制文件不可用,与其相关的数据库实例必须关闭。一旦失效的磁盘得到修复,可以把保存在另一磁盘上的控制文件复制到该盘上。这样数据库实例可重新启动。并通过非介质恢复操作使数据库得到恢复。 因此,为了使整个系统的高可靠地运行,建议系统设置2-3个控制文件。 5.4.3.1 控制文件命名规则 (1) 保存路径:/home/db/oracle/oradata/{DB_NAME}/ (2) 控制文件的使用方式: l 裸设备:创建数据库前,在指定的目录下创建指向裸设备的连接文件。 rcontrol_n_size 其中:n为从1 开始计数的整数,表示控制文件序号。如:1,2…… size表示了文件/设备的大小,由数字部分和单位部分组成:XU,其中,X是一个正整数,取值范围从1~1023,U是单位标识位,是1位的字符,取值范围为k、m、g、t,分别表示了KByte、MByte、GByte、TByte,Size的值应该根据文件/设备的数据大小指定。 l 文件系统: controlnn.ctl 其中:nn为从01开始计数的两位整数,表示控制文件序号。如:01,02,03…… 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 (3) 控制文件数量:为2-3个。如果控制文件所在存储已作镜像,建议2个控制文件。如果没有做镜像,建议3个控制文件。 (4) 控制文件大小 l 裸设备:一个物理分区大小,一般为256MB。 l 文件系统:系统缺省大小。 5.4.4 重做日志文件 重做日志文件的尺寸会对数据库的性能产生重要影响,因为它的尺寸大小决定着数据库的写进程(DBWn)和日志归档进程(ARCn)。一般情况下,较大的日志文件提供较好的数据库性能,较小的重做日志文件会增加核查点(checkpoint)的活动,从而导致性能的降低。当然为了防止I/O争用,还应把各个重做日志文件分布到不同的物理磁盘上。 不可能为重做日志文件提供特定大小的建议,重做日志文件在几百兆字节到几GB字节都被认为是合理的。欲确定数据库重做日志文件的大小,应根据该系统产生重做日志的数量,并依据最多每二十分钟发生一次日志切换这个大致原则来决定。在系统运行后,我们从alert文件获取日志的切换时间,并根据切换的间隔来调整重组日志的大小。初始大小建议不低于50M,小于1G。 5.4.4.1 日志文件命名规则 归档日志(archivelog )文件,建议放在独立物理磁盘上。 (1) 重做日志保存路径:/home/db/oracle/oradata/{DB_NAME}/ (2) 归档日志保存路径:/home/db/oracle/orarch# #表示实例号,1,2,3,…… 通常要求归档日志备份文件系统大小可以保证容纳2天产生的归档日志。AIX操作系统还要求该文件系统设置rbrw属性,以避免归档日志被放入操作系统内存。 (3) 日志文件的使用方式: 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 l 裸设备 创建数据库前,在指定的目录下创建指向裸设备的连接文件。 rlog#_n_m_size(单机) rlog#_n_m_size(RAC) l 文件系统 redon_m.log #表示实例号,1,2,3,…… n表示日志组的编号,取值范围为01-06 m表示日志组成员的编号,取值范围为01-02 size表示了设备的大小,由数字部分和单位部分组成:XU,其中,X是一个正整数,取值范围从1~1023,U是单位标识位,是1位的字符,取值范围为k、m、g、t,分别表示了KByte、MByte、GByte、TByte,size的值应该根据设备的数据大小指定。 l 日志组数量:为3-6,具体日志组数量根据各项目情况确定,每个日志组包括2个成员。 l 日志文件大小:为512,1024,2048M,……根据各项目情况选择此区间值。 6 数据库应用 6.1 数据库用户设计 6.1.1 数据库用户的权限 6.1.1.1 用户权限控制原则 业务功能的安全分配是指开发团队定义的用户、角色、特权,它是面向应用程序和开发的。它在数据库部署是几乎是不可修改的。 数据库用户安全分配往往取自前台应用设计开发团队的交付生产时的定义。这种安全定义了用户、角色、系统特权、对象特权分配等等。它往往是面向开发的,没有细致考虑用户权限的控制。在数据库系统上线时,才发现有不妥之处。而这种用户安全分配多数情况下不能修改,否则对前台应用造成运行错误。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 但在交付生产时,投产方和用户方必须对其安全性进行审计。因为这时提供的用户安全往往是面向开发的,而不是面向末端用户的。主要检查一下几个方面: 1、 每个业务用户不得授予DBA角色。 2、 取消一些系统特权。但必须之前征询开发者的意见,否则可能对前台应用运行带来不可预测的错误。 3、 坚持最小化特权原则。 6.1.1.2 用户及其权限规范 根据数据库管理、数据维护、开发、功能等方面分为以下类型用户: 序号 用户类型 描述 1. DBA 该类用户拥有DBA角色,只有数据库管理员能够使用。其他用户不要授予该角色。 2. DATA OWNER 该类用户拥有数据库业务schema 对象,特别是tables及其他对象。不对末端用户开放。只有通过对象授权和系统授权,Transaction类型用户才可访问DATA OWNER类型用户;表空间的使用,要通过空间授权配额,才可访问;CREATE SESSION特权使用时方可临时授权,使用完毕后,取消授权。 3. Transaction 该类型用户拥有数据库最小权限。只有通过明确的系统和对象授权才可访问DATA OWNER中的对象(如CREATE SESSION,ALTER SESSION等)。一般用于末端用户的访问。 4. Monitor 该类型用户一般用于监控数据库性能,或者是第三方工具使用。 作为监控软件,如QUEST监控软件、patrol、statspack、rman等; 5. 其他 作为普通用户使用,使用权限严格限制,并服从DBA管理。如执行一般的查询sql语句等。为非DBA用户使用。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 对象(如:表、索引、触发器、过程等)管理权限归数据中心,应用(属记录级别,创建临时表权限)权限归项目组 6.1.1.2.1 用户命名规则 1、 DBA类型命名格式: DBA 注:XXX为长度为3个字符的项目英文简称 2、 DATA OWNER类型的命名格式:DB 注:X为长度为2-4个字符的业务功能简称. 3、 Transaction类型命名格式:T 注:X为长度为4-8个字符的业务功能简称 4、 Monitor类型命名 注:监控软件用户应按照第三方的供应商提供的方式命名。 5、 其他类型命名格式:SQL 注:XXX为长度3个字符的功能英文简称。 6.1.1.2.2 用户权限分配方式 对于一个IT数据库项目,在应用系统开发过程中,就开始对数据库用户权限进行严格的控制。即按照该系统未来生产时的方式进行分配,尽管此时数据库还处在开发服务器之中,尽管给开发项目的控制带来更多的工作,但数据库的安全性大大提高了。 对数据库用户(user)的授权,应通过数据库角色(role)进行分配。而不要把对象特权和系统特权直接授权给数据库用户。其带来的优势参见小结“5.3.2数据库用户安全的实现”。 具体授权特权参见: 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6.1.1.3 各用户类型的角色命名规范 1、 DATA OWNER类型用户分配的角色命名规则:R__DB 注:X为长度为2-4个字符的业务功能简称。 2、 Transaction类型用户分配的角色命名规则:R__T 注:X为长度为4-8个字符的业务功能简称。 3、 Monitor类型用户分配的角色命名规则: 注:应按照第三方厂商提供的方式命名。 4、 其他类型用户分配的角色命名规则:R__SQL。 注:XXX为长度为三个字符的业务功能简称。 6.1.2 数据库用户安全的实现 6.1.2.1 数据库特权 Oracle数据库是通过“特权”(Privilege)这个概念来实现数据安全的。所谓特权指用一种指定的方式访问xxx数据库数据对象的一个许可,如查询一个数据表的许可等。这个特权能够被授予某个实体,因此这个授予实体特权(privilege)的过程,称之为“授权”(Grant)。 涉及Oracle数据库系统安全的实体有两个,分别是系统特权(System Privileges)和对象特权(Object Privileges)。 1、 系统特权 系统特权是指登录到ORACLE数据库系统的用户,执行数据库系统级别的某种操作或者是某一数据库对象的创建、修改、删除。在ORACLE数据库系统中有一系列的系统内置预定义特权,系统用这些特权去控制数据的安全。 不得授予普通用户额外的全局权限,如select any/delete any/execute any等,应用有特殊需求的除外。 2、 对象特权 对象特权是指登录到ORACLE数据库系统的用户,有权执行数据库对象级别的某种操作。例如表的INSERT,DELETE,UPDATE操作等。同样,在ORACLE数据库系统中有一系列的对象内置预定义特权,系统用这些特权去控制数据的安全。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6.1.2.2 角色 由于ORACLE数据库系统业务处理的复杂性,对ORACLE数据库的系统特权和对象特权的分配也就变得十分复杂。因此,为了方便管理系统特权和对象特权,需要引入角色这个基本概念。 所谓角色是指系统特权和对象特权的集合。通过对角色的管理,使得ORACLE数据库的系统特权和对象特权管理变得更加方便和容易。 基于角色的安全管理主要有以下几点优势: 1、 减少授权工作量:可以通过授权给与一组用户相关联的角色,再由该角色授权给该用户组的成员用户。 2、 动态特权管理:如果授权给某个xxx用户的特权需要改变,只须修改相关角色的授权,那么与这个角色相关的用户的特权会自动改变,不须修改授权给用户特权。 3、 设置特权的可用性:当某个被授予用户的角色,需要取消,只须对相应的角色设置禁用(DISABLED)。因此,在任何特定的情况下,都可对用户的授权进行必要的控制。 4、 应用程序级的设置可用性:前台应用程序在试图以某个数据库用户的身份与后台数据库相连接时,可以对角色设置可用性。这种做法可以把非应用程序例如SQL*PLUS或第三方的数据库操作工具等,屏蔽在数据库系统之外,以保证数据库的安全。 角色可以根据业务的需求自由定义,系统特权和对象特权可以授权给角色,角色也可授权给另外的角色,角色也可授权给用户。基于上面描述的角色安全管理的优点和特点,ORACLE数据库系统选择角色来实施数据库用户的授权管理,并根据ORACLE的业务需求从不同的角度实现业务的权限分配。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 根据需求,设置不同级别的角色,某一级别体现对某一项业务的特权。各角色级别之间或是子集关系,或是交集关系;同一级别的角色之间,或是交集,或是互为独立集合的关系。随着对业务需求的增加或变化,不断增加、完善访问控制的粒度,并坚持最小化特权原则。如下图: 1、 通过存储过程管理特权(stored procedures) 使用存储过程(stored procedures)来限制数据库的操作,客户端用户只需有权执行存储过程,并通过存储过程来实现对数据库表的访问。因而就屏蔽了用户直接对数据库表的操作。 2、 通过视图(VIEWS)管理特权 通过视图(VIEWS)来控制ORACLE数据库系统的安全。即只分配给用户查询视图的特权,而对基表(定义视图的相关的数据表)则进行屏蔽,禁止对数据表的直接操作。 视图可以实现以下两种安全级别: 1、 使用视图可以限制对数据表中的特定的列的访问。 2、 使用视图可以限制对数据表中的特定的行的访问。 如:对于某一基表,要求只显示部分行,则可通过创建实体的WHERE子句来控制行的显示。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6.1.2.3 授予权限和角色 6.1.2.3.1 授予系统权限和角色 可以用SQL语句GRANT来授予系统权限和角色给其它角色和用户。有GRANT ANY ROLE系统权限的任何用户可以授予数据库里的任何角色。 下面的语句授予系统权限CREATE SESSION和角色ACCTS_PAY给用户JWARD: GRANT CREATE SESSION, ACCTS_PAY TO JWARD; 注意:对象权限不能跟系统权限和角色在同一句GRANT语句里授予。 当一个用户创建一个角色,会把自动这个角色带关键字ADMIN OPTION地授予给它的创建者。一个带有关键字ADMIN OPTION的被授予者有几项扩展性能: Ø 被授予者可以对数据库的其它用户或角色进行授予或撤销系统权限或角色的操作。(用户不可以撤销它本身的角色。) Ø 被授予者可以进一步授予有关键字ADMIN OPTION系统或角色。 Ø 拥有一个角色的被授予者可以改变或卸载这个角色。 在下面的语句中,安全管理员把NEW_DBA角色授予给MICHAEL: GRANT NEW_DBA TO MICHAEL WITH ADMIN OPTION; 用户MICHAEL不但可以使用隐含在角色NEW_DBA里的所有权限,当有需要时还可以授予,撤销或卸载NEW_DBA角色。 只有在对安全管理员进行相关权限和角色授予时,才允许带有关键字ADMIN OPTION。 6.1.2.3.2 授予对象权限和角色 同样可以使用GRANT语句来授予对象权限给角色和用户。要授予对象权限,必须要具备下面任意一个条件: Ø 拥有被授予的对象 Ø 被授予过有关键字GRANT OPTION的对象权限。 注意:系统权限和角色不能和对象权限在同一句GRANT语句中授予。 下面的语句授予了对应EMP表所有列的SELECT,INSERT和DELETE的对象权限给用户JFEE和TSMITH: 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 GRANT SELECT, INSERT, DELETE ON EMP TO JFEE, TSMITH; 要授予只对应EMP表的ENAME列和JOB列的INSERT的对象权限给用户JFEE和TSMITH,声明下面的句子: GRANT INSERT (ENAME, JOB) ON EMP TO JFEE, TSMITH; 要把对应于SALARY视图的所有对象权限给用户JFEE,要使用ALL关键字,正如下面的例子所示: GRANT ALL ON SALARY TO JFEE; 拥有对象的用户会自动授予所有相关的有关键字GRANT OPTION的对象权限。这几个权限让被授予者有以下几个扩展权限: Ø 被授予者可以授予有或没有关键字GRANT OPTION的对象权限给数据库里的任何用户或者任何角色。 Ø 如果在带有关键字GRANT OPTION情况下授予,被授予者得到一个表的对象权限,并且被授予者有CREATE VIEW 或 CREATE ANY VIEW的系统权限,那么被授予者就可以在这个表上建视图和把这个视图相应的权限授予给数据库的任何用户或角色。 Ø 当把一个对象权限授予给一个角色时,关键字GRANT OPTION是不起作用的。Oracle防止通过角色来传播对象权限,因此有某角色的被授予者不能通过角色来传播拥有的对象权限。 6.1.2.3.3 授予列的权限 可以授予对应于表里单独一列的INSERT,UPDATE或REFERENCES的权限。 警告:在授予对应列的INSERT权限之前,观察这个表是否有许多定义了NOT NULL约束的列,如果是就终止授予。选择性的把插入特性授予给那些没有NOT NULL特性的列,防止了用户插入任何列到表里。要避免这种情形,就要确定每一个NOT NULL的列既可以插入又有非空的默认值。否则,被授予者插入记录就会不成功并出现错误。 把ACCOUNTS表的ACCT_NO列的INSERT权限授予给用户SCOTT: GRANT INSERT (ACCT_NO) ON ACCOUNTS TO SCOTT; 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6.1.2.4 数据库默认用户 除了sys、system、rman用户,其他oracle默认用户都应该置为expire或lock状态,除非有特殊需求; 6.1.2.5 数据库用户密码 数据库所有活动状态用户的密码不得设置为已知的默认密码(如:sys用户密码也不能设置为manager); 数据库用户的密码应该定期修改 6.2 数据库分区 6.2.1 数据库分区介绍 分区技术是为解决数据库中巨大的表或索引读写速度过慢而提出的解决方案。分区技术是利用物理上和逻辑上对数据进行分割来提高处理速度的。 同时,合理的分区也提高了数据库数据的可管理性。 Partition表和索引考虑使用分区的条件: 1、 数据损坏的故障隔离 2、 支持在线增加、删除 3、 特定分区上的批处理 4、 按分区备份 5、 维护时可访问正常分区 6、 恢复最关键的数据分区 6.2.2 逻辑分割 根据分区策略,一张表的数据可以逻辑上分布于多个分区、子分区中,对数据的查询如果利用分区策略就可以缩小访问的范围,在一定量级上提高查询速度。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 同样,对于索引分区也是一样的,从逻辑上分割表,缩小处理中的范围,能够极大地提高Oracle本身的处理速度。 6.2.3 物理分割 对于逻辑分割后的分区,可以通过策略分布到不同的表空间中,从而分布到不同的数据文件中,而数据文件又可以分配到不同的存储介质空间中,这样就可以充分利用操作系统的并行访问,同时也利用存储介质的并行访问,极大地同时提高写入和读取速度。 同样,对于索引分区也是一样的机制。 6.2.4 分区后对数据库管理的好处 1、 分区允许数据库管理员进行数据管理操作:数据装载,索引的创建和重建,在分区级别的备份与恢复。因此可节省数据库管理员大量的操作时间。 2、 分区可大幅度减少因维护引起的宕机时间。分区的独立性使数据库管理员对同一表或索引的各个分区进行并发的维护管理操作;也可对分区表并行的执行SELECT 和DML操作。 3、 分区可增加数据库的可用性。减少维护窗口,恢复次数以及系统失效的影响。 4、 分区不要求修改任何应用程序。如,数据库管理员可把非分区表转换为分区表,而不必修改或重写SELECT 语句或DML语句。同时也不必重写前端的应用程序代码。 6.2.5 分区对数据库规划、创建带来的负面影响 当然,任何事物都具两面性,分区带来了数据库创建方面的复杂度。即维护操作原来是面向一个表或索引对象,现在则要面向几十至上百个分区。但后台工作复杂度的加大换来了前台数据操作的效率提高,也是值得的。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6.2.6 Oracle分区技术 Oracle提供以下五种分区技术: 1、 范围分区 范围分区是对某个可度量的字段在可以预见的范围内进行划分的分区方式,例如:日期字段。 2、 枚举值分区 枚举值分区是对某个可列举确定值的字段按照不同值进行划分的分区方式,例如:区县代码字段。 3、 散列分区 散列分区是对某个离散性很大的字段按照根据散列算法计算出的散列值进行分区,例如:证件号码。 4、 组合范围-散列分区 组合范围-枚举值分区是按照范围做主分区,在主分区的基础上再次进行按照枚举值分区的组合分区。例如:日期-区县。 5、 组合枚举-散列分区 组合范围-散列分区是按照范围做主分区,在主分区的基础上再次进行按照散列分区的组合分区。例如:日期-证件号码。 6.2.7 分区使用选择 如果数据按照某个(某些)值分区,那么range分区就最合适,比如按照“销售定额”、“财务年度”、“月份”等等,在这种情况下,range分区可以利用分区消除,这包括应用中使用“=”、“>”、“<”等作为条件。 如果不能找到其他合适的自然条件进行分区,那么HASH 分区就比较合适,这是我们建议选择唯一列或者几乎唯一的列作为分区键值。这种情况下,分区数据是均匀的,使用分区键值“=”或者in(value1,value2…)时,hash分区可以利用分区消除,但是使用其他条件时,hash无法利用分区消除。 如果分区后,每个分区的数据量还是很大,建议使用组合分区,例如,首先按照自然条件做range分区,之后,对分区再进行分区。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6.2.8 分区索引 6.2.8.1 全局索引(GLOBAL index ) 1、 指向任何一个分区中的记录 2、 索引可以被分区或不分区 3、 表可以被分区或不分区 4、 分区键值可以是有前缀后没有前缀 6.2.8.2 本地索引(LOCAL index) 1、 每个本地索引分区只包含本分区的记录 2、 二种类型的本地索引 Ø 前缀(prefixed ):唯一或非唯一列,可有效的使用分区消除,适于索引并行查询,适用于OLTP Ø 非前缀(non-prefixed):适合于索引并行查询,可有效的使用分区消除,唯一索引受限,适用于DSS 3、 分区键值可以与索引键值不同 Ø 本地分区索引:每个表分区都有一个索引分区,而且只索引该表分区的数据。一个给定索引分区中的所有条目都指向一个表分区,表分区中的所有行都表示在一个索引分区中。 优点: 容易维护; 适合并行索引扫描 缺点: 对少量记录查询相对效率不高 Ø 全局非分区索引:一个索引可以指向多个分区的数据 优点: 对单个或少量记录的访问比较有效 缺点: 管理维护上有额外成本 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 Ø 全局分区索引:索引有独立的分区键值,每个索引分区可能指向多个不同的表分区数据 优点: 可用性和管理性 缺点: 对新数据的导入不会太有效 6.3 数据库实例配置 对于Oracle各个版本的参数优化,随版本的区别而有所不同。但万变不离其宗,大部分的参数设置原理是相同的,其优化原则也一致。 6.3.1 数据库字符集 数据库字符集的确定非常重要,如果选择不当,会给业务数据的保存带来麻烦。如在现实中,有的汉字保存到数据库时发生乱码,从而使客户的信息不能正常保存和显示。 数据库字符集在系统设计开发阶段就应当确定。在数据库系统上线后,再更改数据库字符集,代价会非常大。因为不同的字符集设置之间,存在转换操作,如果不兼容,只能逐条转换。一般选择原则是要适中,满足当前和未来业务数据的保存。既不要选择太大,也不要过小。现有支持汉字的字符集包括 : ZHS16CGB231280:此字符集较小,不建议使用 ZHS16GBK: 此字符包含了大部需要的汉字字符,由于目前已经有了新的国标GB18030-2005,而GB18030不是GBK的严格超集,部分字符编码有改动,如果要升级到GB18030只能是将库导出导入重建,因此不建议使用该字符集。 ZHS32GB18030: 此字符集是最新国家标准字符集,包含字符较全,如果系统将来不会有其他国家字符被使用,可以使用此字符集。注意10g的DBCA工具建库时,选不到该字符集,要使用该字符集只能手工建库。 AL32UTF8:此字符集是oracle推荐使用的字符集,对汉字支持也较好。如果系统可能会有其他国家字符录入,建议选用此字符集。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 对于其他字符集的选择,请查询应用安装手册。 6.3.2 数据库版本和补丁集 开放平台管理部每季度会推出oracle版本建议,包括使用的oracle版本和补丁集建议,新上线系统安装时应该按最新的版本建议安装。 6.4 数据库参数设置 数据库参数的设置与业务应用密不可分。不同的业务类型,决定着关键参数的值,同时合理参数值也就决定着数据库系统的性能优劣。不仅如此,业务数据的需求也决定着数据库系统的设置。对于实例创建成功而不可更改的或者修改代价比较大的参数,必须慎重考虑,在充分调研各个方面的需求后,方可确定参数值,以满足业务的正常健康的运行。 6.4.1 必须修改的初始化参数 6.4.1.1 DB_CACHE_SIZE 数据库缓冲高速缓存用来存储最近使用的数据。处理查询时,服务器进程在数据库缓冲高速缓存中查找任何所需的块。如果未在数据库缓冲高速缓存中找到这个块,服务器进程就从数据文件读取这个块并且在数据库缓冲高速缓存中放置一个副本。由于对同一个块的后续请求可能在内存中找到这个块,因此这些后续请求可以不需要再次进行物理读取。 Oracle使用最近最少使用算法来释放近期未被访问的缓冲区,以便在缓冲高速缓存中为新块腾出空间。 衡量一个系统的的数据缓冲区设定效果的的一个重要指标是数据的缓存命中率。 对于OLAP系统,由于大量的数据访问使用全表扫描的方式来运行,回答的是一些统计结果和“如果”“那么”之类的分析和预测,其数据缓存的利用率较低,此时主要应该考虑的是规划系统的IO分布以提高系统IO效率,而不是提高系统缓存的命中率。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 对于OLTP系统,由于每次处理的数据量较小而且大量的数据是可以重复使用的,所以数据的共享对提高系统的效率非常重要。下面的说明是针对OLTP应用系统的。 对于一个设计良好的应用系统,其数据库的缓存命中率应该在85%以上。对于DB_CACHE_SIZE的最终确定,需要依靠对实际系统的运行分析。 建议值:该参数一般取物理内存的30%-50%左右。以后根据运行分析,再作调整。 6.4.1.2 SHARED_POOL_SIZE 共享池是用来存放可供全局共享的对象,比如可重用的SQL语句执行计划,PL/SQL包、存储过程、函数和游标等信息。 共享池的大小是由SHARED_POOL_SIZE参数决定的,而且可以使用ALTER SYSTEM SET语句来动态改变,但总的SGA区大小不能超过SGA_MAX_SIZE。 设置的一般性原则 一般情况下,共享池大小的设定与应用的类型和并发用户的数量有关系。其实际设定值与系统的可用内存相关。 对于复杂的应用系统――指每个功能拥有较多的SQL语句同时每个SQL语句的执行计划又比较复杂的情况下,可以适当的增加SHARED_POOL_SIZE的值,随着并发用户的增加应当适当的调整SHARED_POOL_SIZE的值。 对于较小的应用系统,共享池的大小和数据缓冲区的比例可以为1:2,随着内存的增加,该比例可以进一步的减小,一般地共享池不必超过4GB。 对于一个正常的OLTP系统SQL语句的缓存命中率在95%就是一个比较好的系统了,对于OLAP系统80%的缓存命中率也是可以接受的。 对于一个具有4GB物理内存300个并发用户的C/S应用体系的OLTP应用系统可以设定SHARED_POOL_SIZE=800M,而对于一个具有8GB物理内存600个并发用户的C/S应用体系的OLTP应用系统则可以设定SHARED_POOL_SIZE=1200M。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 建议值:建议此参数设置为512M,至少在200M-2G之间。 对于SHARED_POOL_SIZE的最终确定,需要依靠对实际系统的运行分析。 6.4.1.3 LARGE_POOL_SIZE 大池用来存储和SQL语句处理无直接关系的大内存结构。如在备份和恢复过程中复制的数据块。 大池是SGA区的可选选项,目的为了减轻共享池的压力。大池不使用最近最少使用(LRU)算法来进行管理。 大池的大小由参数文件中的LARGE_POOL_SIZE设置。能被ALTER SYSTEM语句动态改变。 设置的一般性原则 大池一般用来存放并行查询的相关信息和RMAN的磁盘IO缓冲区。对于为RMAN所分配的大池,其设定与RMAN分配的通道数有关,公式为: 通道数 * (16 MB + ( 4 * size_of_tape_buffer ) ) 硬盘备份时,size_of_tape_buffer为0,磁带备份时,该值默认为256k 建议值:OLTP:100M OLAP:256M 6.4.1.4 DB_BLOCK_SIZE DB_BLOCK_SIZE参数决定数据库系统的性能和使用。 关于数据库的业务应用,该文档已在“4.1数据库类型特点分析”中已讨论。数据库参数DB_BLOCK_SIZE的设置与原则: 1、 OLTP类型的业务应用数据库系统,则DB_BLOCK_SIZE=4k或8k; 2、 DSS类型的业务应用数据库系统,则DB_BLOCK_SIZE=16k或32k; 3、 Hybrid类型的业务应用数据库系统,则DB_BLOCK_SIZE=8k或16k;在oracle9i 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 之后已经可以建立不同block size的表空间,根据不同的业务特性将不同的表放置于不同block size的表空间中,这个特性对于Hybrid系统会有性能的提升。 针对不同业务类型的数据库系统,以上设置方式,不是绝对的,要取决于业务具体情况。 6.4.1.5 SP_FILE 参数设置文件的绝对路径。 默认值:ORACLE_HOME/dbs/spfile.ora 建议值:根据命名规范命名,文件文件应该放入存储,特别是在HA环境中。 6.4.1.6 PGA_AGGREGATE_TARGET 使用该参数的前提是,必须WORKAREA_SIZE_POLICY=AUTO,并且数据库运行方式是Dedicate sever和连接时Dedicate方式时,这个参数才可生效。此时参数SORT_AREA_SIZE,HASH_AREA_SIZE,BITMAP_AREA_SIZE会被忽略失效。但如果使用MTS和SHARE SERVER连接方式时,则PGA_AGGREGATE_TARGET会被忽略失效,此时*_AREA_SIZE就会生效。 PGA_AGGREGATE_TARGET是系统自动管理*_AREA_SIZE的大小,因此推荐使用这个参数。其设置原则为: 1、 OLTP:PGA_AGGREGATE_TARGET = (total_mem * 80%) * 20% 2、 DSS:PGA_AGGREGATE_TARGET = (total_mem * 80%) * 50% 其中:total_mem为系统的物理内存。该原则是经验值,对于实际运行系统可视情况适当浮动调整。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6.4.1.7 PROCESSES 根据实际连接数据库的连接数的1.2-1.4倍进行设置,不得低于500。 6.4.1.8 OPEN_CURSORS 该参数设定了一个会话一次可以打开的游标的最大数量, 并且限制使用的 PL/SQL游标高速缓存的大小, 以避免用户再次执行语句时重新进行语法分析。 如果初始化参数CURSOR_SPACE_FOR_TIME设为TRUE,则OPEN_CURSORS也需要相应的增大。 1) 值范围:1 ~ 4GB-1。 2) 默认值:50 3) 推荐值:该值与应用类型相关,设置值不得低于200 6.4.1.9 MAX_DUMP_FILE_SIZE 建议不要使用默认值(UNLIMITED),最大设置100M。以避免数据库多次dump出trc文件时迅速撑满整个文件系统。 6.4.1.10 RECOVERY_PARALLELISM 参与实例恢复(RECOVERY)的进程数量,0或1意味着串行。 默认值:操作系统相关,通常为0 取值范围:操作系统相关,不超过PARALLEL_MAX_SERVER设置值 推荐值: 物理CPU个数-1 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6.4.1.11 PARALLEL_EXECUTION_MESSAGE_SIZE 并行操作(并行查询,并行DML,并行恢复、复制)时消息的大小,设置较大值对并行查询时有并行进程间大量数据传输时比较有利。 默认值:2148 取值范围:2148 to 65535 推荐值: 8192,超过1T的系统可以更大 6.4.1.12 INSTANCE_GROUPS(RAC) 描述当前实例所属的资源组,RAC中并行操作模式时用到,和下面的PARALLEL_INSTANCE_GROUPS共同使用,可以限制并行操作使用的实例资源。 默认值:无 取值范围:无 推荐值:数据中心通常只使用两节点的RAC,因此只有两个设置值,RAC两个节点各使用一个(和两个实例的instance_name中的顺序保持一致): node_01,node_both node_02,node_both 6.4.1.13 PARALLEL_INSTANCE_GROUP(RAC) 描述当前实例并行操作时可使用的资源组,RAC中并行操作模式时用到,和上面的INSTANCE_GROUPS共同使用,可以限制并行操作使用的实例资源。 默认值:无 取值范围:其设置名称必须在RAC节点的INSTANCE_GROUPS中曾出现。 推荐值:数据中心通常只使用两节点的RAC,需要保证日常并行仅在本节点进行,避免同时耗尽两台实例的所有资源。设置时应根据INSTANCE_GROUPS来设置: INSTANCE_GROUPS设置为node_01,node_both则PARALLEL INSTANCE_GROUP设置为node_01; 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 INSTANCE_GROUPS设置为node_02,node_both则PARALLEL INSTANCE_GROUP设置为node_02。 node_both在通常情况下不会被使用,除非应用有非常大的并行操作需要同时使用两个节点上的资源,此时需要在应用中显式调用alter session set PARALLEL INSTANCE_GROUPS =‘node_both’; 6.4.1.14 与DRM有关的隐藏参数(RAC) 10g的RAC中引入的DRM(Dynamic Resource Mastering)的概念,在RAC的不同节点间根据资源使用情况决定master节点。由于该功能并不十分完善,常常造成节点间master节点不断转换,触发bug,而且数据中心中所有的RAC都是两节点的,使用该功能意义不大,因此应该屏蔽该功能。屏蔽时需要配置如下两个默认参数: _gc_undo_affinity=FALSE _gc_affinity_time=0 6.4.2 系统优化建议修改的初始化参数 6.4.2.1 SESSION_CACHED_CURSORS 设置该参数有助于减少系统parse SQL的时间,提高系统效率。10g中该参数的默认值为20。 建议设置session_cached_cursors=50,对于实际运行系统可视情况适当浮动调整。 6.4.2.2 BACKUP_TAPE_IO_SLAVES 该参数指定了恢复管理器(Recovery Manager)所使用的从属进程的数目,这些从属进程被用来备份,拷贝或恢复数据到磁带上。当此参数为TRUE时,一个I/O从属进程被用来从磁带设备读取或写入数据。如果此参数为FALSE(默认情况下),在备份中不会使用I/O从属进程,而是由备份的阴影进程(shadow process)来存取磁带设备。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 该参数设置为true后,通过模拟AIO的行为,主进程可以不必等待磁带写完成后就能继续处理其他数据块,会启动子进程来等待,从而加快了备份速度。 建议值:备份到磁带上的系统,设置该参数为true以加快速度。 6.4.2.3 JAVA_POOL_SIZE 参数JAVA_POOL设定了数据库用来存放JAVA代码的缓冲池的大小。 设置的一般性原则 对于使用了数据库中的JAVA的应用系统,该参数的大小取决于应用的类型,我们可以通过查询数据库系统中关于SGA的动态视图V$SGASTAT来确定数据库中是否使用了JAVA和合理的JAVA_POOL的值。 建议: 对于没有使用数据库中的JAVA的应用,不设置,使用系统默认值。 对于使用了数据库中的JAVA的应用,JAVA_POOL_SIZE的大小由应用的类型和数量确定。 6.4.2.4 OPTIMIZER_INDEX_COST_ADJ 控制优化器是否会更倾向于使用索引。 默认值:100, 推荐值: OLTP:50,即优化器评估时将走索引的代价评估为标准状况下(默认值100时)走索引代价的50%。 OLAP:不设置,使用默认值 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6.4.3 不得修改的初始化参数 6.4.3.1 COMPATIBLE 该参数设定了Oracle的版本,建库时取默认值。 只有在数据库upgrade(升级更高版本)时修改,该参数一旦设置为高版本后,不能回退到旧版本设定数值。 6.4.3.2 CURSOR_SHARING 控制可以共享相同的共享游标的 SQL 语句类型。 (1) 值范围:FORCE | SIMILAR | EXACT EXACT:完全相同的 SQL 语句才能共享一个游标。 SIMILAR:让语句类似并且执行计划相同的语句共享一个游标。 FORCE:强制表达方式不同但语句意思相同的语句共享一个游标。 (2) 默认值:EXACT 该参数设置为SIMILAR、FORCE对共享SQL执行计划,避免共享池碎片有一定好处,但是这样设置容易触发ORACLE的BUG,从保证系统稳定运行的角度来讲,不建议修改数据库默认设置,应该尽量从应用开发的角度来解决SQL共享问题。 6.4.3.3 SGA_TARGET 在Oracle 9i中,必须手工调整和设置各种数据库缓存区的大小。在Oracle 10g中,新增加了一个SGA_TARGET参数,该参数的作用是通过设置一个总值,让数据库根据实际需要,动态调整各块缓存区的大小,且每块缓存区的大小不会小于手动设置的参数值。 但在实际使用过程中,如果只是设置SGA_TARGET,而不手动设置各种缓存区的参数值,在系统繁忙时由于动态调整不同区域内存占用将将有可能会引发Oracle内部的一些bug。因此,建议SGA区内存管理通过手工设置,不设置该参数,维持默认值0 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 。 6.4.3.4 SGA_MAX_SIZE SGA_MAX_SIZE为SGA的最大允许设置值,系统会自动根据DB_CACHE_SIZE /SHARED_POOL_SIZE /JAVA_POOL_SIZE /LARGE_POOL_SIZE 的值扩大,动态修改以上参数设置值时,以上参数设置值的总和不得超过本参数指定值。 设置该值大于以上pool的总和或SGA_TA RGET的设置值,会造成多余值无法被自动利用而造成浪费。应该尽量通过测试确实合适的pool设置值,避免系统自动扩展或临时扩展。 6.4.4 建议不修改的初始化参数 6.4.4.1 UNDO_RETENTION 以秒为单位设置UNDO争用值的下限。对自动扩展的UNDO表空间有价值,对固定大小的UNDO表空间(数据中心推荐做法),系统根据UNDO使用情况、UNDO表空间大小自动确定该值,除非启用了retention guarantee。 默认值:900, 6.4.4.2 SESSIONS 指定用户会话和系统会话的总量。默认数量大于 PROCESSES, 以允许递归会话。 1) 值范围: 任何整数值。 2) 默认值: 派生 (1.1 * PROCESSES + 5) 3) 建议值:该值无需特意指定,建议在指定PROCESS后使用系统计算值。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6.4.4.3 TRANSACTIONS 指定并行事务处理的最大数量。如果将该值设置得较大, 将增加 SGA 区的大小, 并可增加实例启动过程中分配的回滚段的数量。默认值大于 SESSIONS, 以实现递归事务处理。 对于连接到Oracle数据库的应用,根据其连接方式可以分为: 1. 直接连接到数据库应用。如:客户前台直接通过SQL*NET,JDBC,OCI,IIOP连接到数据库应用,这类应用中由于用户的操作关系,一般的并发事务数较小,远远的小于连接到数据库的会话数; 2. 用户前台并不直接与数据库相连而是通过中间件与数据库相连,这类应用中连接到数据库的会话数等于中间件的服务器的数量。由于应用服务器的集中作用,这时每个连接到数据库的会话为多个最终客户服务,会话的负荷较重,事务较多,极限情况下每个会话都可能出现由活动事务的情况,考虑到系统的递规调用的情况,最大值可能为1.1倍的会话数。 1) 值范围:4 到4G 2) 默认值:派生 (1.1 * SESSIONS) 对于第一类应用, TRANSACTIONS最好为1/10到1/5的PROCESS的值;对于第二类应用, TRANSACTIONS最好为1.1倍的PROCESS的值. 不建议修改默认值,由ORACLE根据SESSIONS/PROCESS的设的设置自动计算。 6.4.4.4 DB_KEEP_CACHE_SIZE 建议对频繁使用的较小的字典表将其放入到KEEP池中。 通常情况下,系统新上线时如果开发部门没有明确要求,不进行设置。运维过程中觉得有必要设置时,可以进行修改。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6.4.4.5 LOCK_SGA 决定设置数据库参数lock_sga将目前数据库SGA索住在物理内存中。 同时,对于AIX,上述从操作还需要修改操作系统参数v_pinshm从缺省的0设置为1;对于HPUX,还需修改数据库hpux_sched_noage=178。 由于行内系统DB机器通常都是专用的,平时不会被交换至硬盘,可以不设置。 6.4.4.6 DB_FILES 该参数定义了数据库可以打开的数据文件的数目,此参数默认值为200,在创建实例的时指定,在RAC、DATAGUARD等环境要求各实例保持一致,修改时要求重启实例。 10g及以上版本中,该值重启实例就能修改,从数据中心的实践来看,通常数据文件都不会超过150个,设置过大的值会浪费一定内存,因此不必过早设置过大数值。 6.4.4.7 DB_FILE_MULTIBLOCK_READ_COUNT 该参数指定了在涉及一个全表连续扫描的一次I/O操作过程中读取的数据块(其大小由数据库初始化参数DB_BLOCK_SIZE决定)的最大数量。只有在系统对数据库的一个表进行全表扫描时(db file scattered read)该参数才起作用。 一般的情况下,该参数的设定与系统的应用类型相关,对于做大量数据查询的OLAP系统可以设定较大的值,如32,对于一般的OLTP系统设定为8或16是一个较好的选择。 值范围:此参数只适合Oracle9i,Oracle10g对此参数已不要求。 默认值:8 建议值:9i对OLAP系统推荐使用32,对OLTP系统推荐使用16,10g不必设置 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6.4.4.8 LOG_BUFFER 重做日志文件跟踪服务器进程和后台进程对数据库进行的更改。该缓冲区是循环使用的,包含对数据文件所做的各种修改动作的信息,例如:INSERT,UPDATE,DELETE,CREATE,ALTER和DROP等操作。 重做日志缓冲区大小由参数文件中的LOG_BUFFER设置。 较大的日志缓冲区有助于降低日志文件的读写频率,提高系统的效率。 设置的一般性原则 由于系统的写日志进程(LGWR)在日志缓冲区中的重做条目(redo entry)达到1MB的时候,会把日志缓冲区的数据写入日志文件,同时当日志缓冲区1/3满的时候也会写日志文件,所以过大的日志缓冲区是没有意义的。 10g中该参数的值一般接近SGA设置值决定的粒度值(通常为16M),不必专门设置增大。 6.4.4.9 FAST_START_MTTR_TARGET 控制快速检查点的参数,指定从单个数据库例程崩溃中恢复所需的时间 (估计秒数)。该参数设置较低会造成数据库频繁执行检查点(checkpoint),对系统运行效率有影响。 在系统设定以下参数后该参数失效: FAST_START_IO_TARGET LOG_CHECKPOINT_INTERVAL 值范围:[0, 3600]。 默认值:0 推荐值:一般系统可以不设置该值,除非AWR报告显示估计MTTR时间(Estd MTTR)超过300s。对不可用时间有严格要求的系统可设置为120或更低,但不得小于30 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6.4.5 与并行操作有关的参数 PARALLEL_MIN_SERVER PARALLEL_MAX_SERVER PARALLEL_MIN_PERCENT PARALLEL_ATUOMATIC_TUNING PARALLEL_EXECUTION_MESSAGE_SIZE 一般情况下,除了PARALLEL_EXECUTION_MESSAGE_SIZE,以上参数都使用默认值,系统会根据CPU个数、表设置等自动选择并行。 在执行SQL语句操纵的数据对象中指定相应的参数,其优先次序依次为:语句中的提示最优先,其次为对象中的并行定义参数,最后为数据库的初始化参数。 有建议在OLTP系统上关闭oracle并行,以免并行任务对日常业务的冲击,考虑到数据中心各实例系统资源一般比较充足、数据量都比较大,在统计信息收集、索引重建维护等过程中充分利用并行还会大大提高效率,因此建议系统通常按默认设置打开并行。日常运维过程中,需要注意的是当我们使用并行时,最好由系统来自行决定并行度,如果没有充足的把握,尽量不要指定过高的并行度,以尽量避免并行操作对日常业务的影响。 6.5 数据库连接服务 6.5.1 专用服务器连接 在专用服务器模式下,客户连接和服务器进程(或者有可能是线程)之间会有一个一对一的映射。如果一台UNIX主机上有100条专用服务器连接,就会有相应的100个进程在执行。下图显示了专有服务器连接时的体系结构。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6.5.2 共享服务器连接 共享服务器连接强制要求必须使用Oracle Net,即使客户和服务器都在同一台机器上也不例外。如果不使用Oracle TNS监听器,就无法使用共享服务器。如前所述,客户应用会连接到Oracle TNS监听器,并重定向或转交给一个调度器。调度器充当客户应用和共享服务器进程之间的“导管”。下图显示了共享服务器连接时的体系结构。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6.5.3 连接服务建议 6.5.3.1 专用服务器连接 1、 服务器只要有足够的资源(CPU和RAM)就使用专用服务器连接 6.5.3.1.1 共享服务器连接 1、 共享服务器只适用于OLTP系统,只在资源(CPU和RAM)不足的情况下使用 2、 其他高级连接特性需要使用共享服务器连接 6.6 数据库安全建议 6.6.1 采用满足需求的最小安装 随着Oracle数据库版本的不断升级,Oracle的功能也越来越多,因此安全检查点也越来越多。因此最好根据需求只安装所需内容。如:不需要web 功能,就不要安装相应组件。 6.6.2 安装时的安全 Oracle软件的安装目录要和系统盘分开。在Unix下,Oracle数据库系统的帐号和组的权限也要作相应设置。创建数据库管理员组(DBA)并分配root 和Oracle 软件拥有者的用户ID 给这个组。DBA 能执行的程序只有“710” 权限。在安装过程中SQL*DBA 系统权限命令被自动分配给DBA 组。 6.6.2.1 删除或修改默认的用户名和密码 Oracle 的默认安装会建立很多缺省的用户名和密码,而大部分的数据库管理员都不清楚到底有多少数据库用户,从而留下了很大的安全隐患。因此数据库软件应以定制方式安装。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6.6.2.2 安装最新的安全补丁 Oracle 数据库虽然被称为“Unbreakable”,但还是存在不同程度的安全漏洞。保证ORACLE数据库安全性的一个比较好的办法是时刻关注Oracle公司的安全公告,并及时安装安全补丁。安全公告和补丁位置如下: http://otn.Oracle.com/deploy/security/alerts.htm 6.7 数据库备份和恢复 6.7.1 RMAN 备份 该类备份是最为完善的备份恢复解决方案。对于从几百M至TB级的数据库,都可选择其作为备份方案。正因其完善,相关的备份架构相对复杂,维护操作也复杂。对于小型数据库(如几十M)来说,硬件和软件成本以及维护代价过高。其逻辑架构如下图: 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6.7.2 Export/import备份 该类备份是用于小型数据库备份作为合适。硬件和软件成本以及维护代价比较低。因其备份方式灵活,可以进行表级、模式级备份,常作为rman备份方案的补充。另外,对于跨操作系统平台迁移数据库,也经常使用其作为首选方案。 6.7.3 存储级备份—虚拟带库 数据块级虚拟磁带库相对其它备份设备具备了显著优势: Ø 性能大幅提高——可支持接近磁盘阵列极限的备份/恢复速度。 Ø 免疫病毒——应用安全性等同物理磁带库。 Ø 去除磁盘碎片——保障性能持续性及磁盘效率。 Ø 无转译数据传输——良好的对数据结构损坏的承受力。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 通用于主机软硬件环境——免除适配、维护和管理风险。 6.7.4 数据库恢复 6.7.4.1 实例故障的一致性恢复 当实例意外地(如掉电、后台进程故障等)或预料地(发出SHUTDOUM ABORT语句)中止时出现实例故障,此时需要实例恢复。实例恢复将数据库恢复到故障之前的事务一致状态。如果在在线后备发现实例故障,则需介质恢复。在其它情况Oracle在下次数据库起动时(对新实例装配和打开),自动地执行实例恢复。如果需要,从装配状态变为打开状态,自动地激发实例恢复,由下列处理: 1、 为了解恢复数据文件中没有记录的数据,进行向前滚。该数据记录在在线日志,包括对回滚段的内容恢复。 2、 回滚未提交的事务,按步1重新生成回滚段所指定的操作。 3、 释放在故障时正在处理事务所持有的资源。 4、 解决在故障时正经历一阶段提交的任何悬而未决的分布事务。 6.7.4.2 介质故障或文件错误的不一致恢复 介质故障是当一个文件、一个文件的部分或磁盘不能读或不能写时出现的故障。文件错误一般指意外的错误导致文件被删除或意外事故导致文件的不一致。这种状态下的数据库都是不一致的,需要DBA手工来进行数据库的恢复,这种恢复有两种形式,决定于数据库运行的归档方式和备份方式。 1、 完全介质恢复可恢复全部丢失的修改。一般情况下需要有数据库的备份且数据库运行在归档状态下并且有可用归档日志时才可能。对于不同类型的错误,有不同类型的完全恢复可使用,其决定于毁坏文件和数据库的可用性。 2、 不完全介质恢复是在完全介质恢复不可能或不要求时进行的介质恢复。重构受损的数据库,使其恢复介质故障前或用户出错之前的一个事务一致性状态。不完全介质恢复有不同类型的使用,决定于需要不完全介质恢复的情况,有下列类型:基于撤消、基于时间和基于修改的不完全恢复。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 Ø 基于撤消(CANCEL)恢复:在某种情况,不完全介质恢复必须被控制,可撤消在指定点的操作。基于撤消的恢复地在一个或多个日志组(在线的或归档的)已被介质故障所破坏,不能用于恢复过程时使用,所以介质恢复必须控制,以致在使用最近的、未损的日志组于数据文件后中止恢复操作。 Ø 基于时间(TIME)和基于修改(SCN)的恢复:如果希望恢复到过去的某个指定点,是一种理想的不完全介质恢复,一般发生在恢复到某个特定操作之前,恢复到如意外删除某个数据表之前。 6.8 ORACLE NETWORK 配置 6.8.1 监听器的使用配置原则 1、 创建监听器时,每个实例必须有一个监听器。不能服务于多个实例。 2、 listener port 端口为安全起见,不使用缺省1521。和网络部协商后,该端口统一使用11521。 6.8.2 TNSNAMES的使用配置原则 1、 数据库连接别名,推荐选择专用连接。如果是中间层应用服务器作为连接数据库的客户端,出于性能的考虑强烈推荐使用专用连接。 2、 对于Oracle9i以上的数据库,推荐使用数据库服务名(service name),而不是实例名(SID)。 3、 数据库连接的主机名,推荐使用数据库服务器的IP地址。如果是Oracle10g RAC,推荐使用虚拟IP(Virtual IP)。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6.8.3 RAC环境下TNSNAMES的配置 6.8.3.1 各节点启用负载均衡 可以通过Oracle自身的负载均衡功能,对应用发起的事务请求进行负载均衡。启用此功能必须对各客户端的TNSNAMES.ORA文件进行相关配置,通过设置TNSNAMES.ORA文件的LOAD_BALANCE参数为ON来启用负载均衡功能,配置如下: ODSPDDB1 = (DESCRIPTION = (load_balance = on) (failover = on) (ADDRESS = (PROTOCOL = TCP)(Host = 11.156.111.42)(Port = 1521)) (ADDRESS = (PROTOCOL = TCP)(Host = 11.156.111.40)(Port = 1521)) (CONNECT_DATA = (SERVICE_NAME = odspddb) (FAILOVER_MODE = (BACKUP = odspddb2) (TYPE = SESSION) (METHOD = BASIC) ) ) ) 6.8.3.2 各节点不启用负载均衡 如果不需要Oracle平均的处理应用发起的请求,而是RAC各节点执行不同客户端发起的请求,必须通过设置TNSNAMES.ORA文件的LOAD_BALANCE参数为OFF来取消负载均衡功能,配置如下: 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 ODSPDDB1 = (DESCRIPTION = (load_balance = off) (failover = on) (ADDRESS = (PROTOCOL = TCP)(Host = 11.156.111.40)(Port = 1521)) (ADDRESS = (PROTOCOL = TCP)(Host = 11.156.111.42)(Port = 1521)) (CONNECT_DATA = (SERVICE_NAME = odspddb) (FAILOVER_MODE = (BACKUP = odspddb2) (TYPE = SESSION) (METHOD = BASIC) ) ) ) 7 数据库开发建议 7.1 数据库模型设计规范 7.1.1 命名规则 数据库对象如表、列、序列、过程、函数等在命名时要遵循如下规则: Ø 命名要使用富有意义英文词汇,避免使用缩写。 Ø 数据库、数据库对象的名称可由多个单词组成的。 Ø 数据库对象名称由如下部分组成:范围、类型、名称实体,各词汇间采用"_" 连接。 Ø 其中各数据库对象的范围和类型的具体含义及取值详见各数据库对象的命名规则。 Ø 数据库对象的名称不允许是Oracle SQL、Oracle PL/SQL的保留字和关键字。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 数据库对象 格式 样例 说明 表 <模块名称>_T_<表名称> ODS_T_SYSCONFIG 同一个模块的表使用相同前缀,长度不超过15个字符   普通索引 IND_<表名>_N<序号> IND_ORDER_N1 ORDER表第一个普通索引 位图索引 IND_<表名>_B<序号> IND_ORDER_B1 ORDER表第一个位图索引 唯一索引 IND_<表名>_U<序号> IND_ORDER_U1 ORDER表第一个唯一索引   普通视图 V_<视图名> V_ORDER   物化视图 MV_<视图名> MV_ORDER     存储过程 P_存储过程名 P_get_sysdata 获取系统时间 函数 F_函数名 F_reception 业务受理 包 PKG_包名 PKG_print 打印发票   触发器 TRG_触发器名称 TRG_initial 初始化数据触发器   序列 SEQ_序列名称 SEQ_register_number 受理编号序列 别名 <用户名>_<表名>     北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 7.1.2 表 7.1.2.1 建表的参数设置 Ø 不允许将表建立在SYSTEM表空间上。 Ø 表和索引建立在不同表空间上。 Ø 建表时必须指明所存储的表空间。 Ø 生成建表脚本时非空的列放在表的前部,可空的列放置在表的后部。 Ø 数据缓冲池的类型:查询频繁且数据量较小的参数表采用buffer pool keep。 Ø INITIAL:对于初始化数据量大的表,设置的值要大于初始化数据。 Ø PARALLEL:对于OLTP系统,不允许使用该参数。 7.1.2.2 主外键设计 Ø 必须设置主键,通常不使用存在实际意义的列做主键,具体情况应结合业务特性综合考虑。 Ø 由Sequence产生的ID列,不作为组合PK中的列。 Ø 删除约束时使用keep index参数。 Ø 唯一性约束用于限定表中记录的唯一性,允许为空,允许对创建唯一性约束的列进行修改操作。 Ø 检查(check),一般使用于列的取值受限于一些特定值的情况下,如员工的性别,年龄,贷款的状态等。 Ø 触发子约束,一般情况下不要使用。 7.1.2.3 列设计 Ø 定长字符型列使用CHAR类型,不定长字符型列使用VARCHAR2类型。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 Ø DATE精确到微秒。 Ø 使用NUMBER型时必须指定长度。 7.1.2.4 临时表 Ø 对于只对本事务有效的临时表使用ON COMMIT DELETE ROWS关键字创建该表。 Ø 对于只对本会话有效的临时表使用ON COMMIT PRESERVE ROWS关键字创建该表。 7.1.3 索引 Ø 选择使用普通B树索引。 Ø 小表(数据量小于5000条记录为标准)不需要创建索引。 Ø 对于OLTP应用,分区表使用分区索引。 Ø 分区索引必须包含分区列,分区列按序放置在分区索引的末尾。 Ø 建立分区索引必须指明表空间,不允许只写一个LOCAL。 Ø 单个表上索引的个数不超过5个。 Ø 将记录差别数最多的列放在索引顺序的最前面。 Ø 索引数据的重复率不能超过20%。 Ø 进行order by column desc排序时,创建column desc索引。 7.1.4 视图 Ø 物化视图的刷新间隔时间最小为3分钟。 Ø 物化视图的基表必须创建主键。 7.1.5 存储过程、函数和包 Ø 存储过程、函数和包中不允许使用DML或DDL语句。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 Ø 存储过程、函数和包必须有相应的出错处理功能。 7.1.6 触发器 Ø 触发器的的选择必须与应用程序事务属性保持一致,以避免死锁发生。 Ø 在有大量数据导入表中的情况下,不使用触发器。 7.1.7 序列 Ø 加大序列的cache值,可以减少对于X$SEQ等基表的锁争用,但是会造成序列的不连续性。 Ø 应用程序不要将任何商业逻辑建立在序列的完全连续性上。 Ø 不要设置序列为循环使用,防止数据覆盖现象。 7.1.8 Directory Ø 目录设置要求与Oracle系统用户目录分开。 Ø Directory使用权限只赋予需要使用的数据库用户。 Ø 对应的操作系统目录必须对oracle操作系统用户开放读写权限。 Ø 定期清理和备份Directory对应的操作系统目录。 7.1.9 别名 Ø 对于只读用户,必须创建与表相同名字的别名。 Ø 别名的访问顺序:public别名 -> private别名 -> 与表同名的对象。 7.1.10 Database Link Ø 只允许从其它数据库中查询少量数据时使用dblink。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 不使用dblink更新其它数据库中的数据。 7.2 PLSQL开发规则 7.2.1 总体开发原则 1. 完全按照设计文档进行开发; 2. 程序模块内聚度要高;外联度要低。 3. 要有正确、全面的故障对策。 4. 程序编写结构合理,条理清晰。 5. 程序名称要按照统一的命名规则进行命名。 6. 要充分考虑程序的运行效率,包括程序的执行效率和数据库的查询、存储效率。在保证应用的同时要尽量使用效率高的处理方法。 7. 程序注释要详细、正确、规范。 8. 除非应用特别需要控制commit和rollback的提交时机,否则必须在存储过程结束时执行显式的commit或者rollback操作。 9. 程序处理尽量支持7×24小时;对于中断,应用程序提供安全、简单的断点再续处理; 10. 提供标准、简单的应用输出,为应用维护人员提供明确的进度显示、错误描述和运行结果;为业务人员提供明确、直观的报表、凭证输出。 7.2.2 程序编写规则 7.2.2.1 在PL/SQL中使用SQL 知识点描述 PL/SQL是Oracle公司对SQL的过程化扩展。在标准SQL的基础上面增加了流程控制、游标、异常处理等机制。PL/SQL是一种第四代的高级编程语言,它可以单独使用,也可以嵌入其他宿主语言一起使用。PL/SQL使得用户对Oracle数据库的操作变得非常简单。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 使用原则 1. 相关参数 (1) CURSOR_SHARING 该参数可以设为exact,force和similar,缺省值为exact。 (2) 使用情况 只有在用户的应用已经投入使用的并且SQL语句的共享效果不好,出现library cache latch的情况下,我们推荐使用cursor_sharing作为一种补救手段。 在进行开发的过程中,设定cursor_sharing=exact 2. 如何使用可以提高效率 (1) 尽量使用变量绑定 (2) 尽量使用RETURNING子句 (3) 使用NOCOPY的编译提示。默认情况下,OUT和IN OUT参数都是按值传递的。为参数NOCOPY的编译提示表示按照引用传递。 举例 1. 使用变量绑定的例子:在sqlplus中定义变量,使用变量做为查询条件。 SQL>DEFINE c=1; SQL>SELECT * FROM t1 WHERE c1=&c; 2. 使用RETURNING子句的例子:更改某员工工资水平的同时返回更改员工的姓名和更改后的薪水。 PROCEDURE update_salary (emp_id NUMBER) IS name VARCHAR2(15); new_sal NUMBER; BEGIN UPDATE emp SET sal = sal * 1.1 WHERE empno = emp_id RETURNING ename, sal INTO name, new_sal; END; 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 3. 当参数包含大数据结构(如集合,对象类型等),使用按值传递将会消耗过多的内存资源。为了避免这种情况,我们在参数传递时使用NOCOPY的编译提示。 DECLARE TYPE Platoon IS VARRAY(200) OF Soldier; PROCEDURE reorganize (my_unit IN OUT NOCOPY Platoon) IS …… BEGIN …… END; 7.2.2.2 变量声明原则 1. 使用%TYPE声明 变量类型声明时,如果其含义和应用表某字段含义或某变量相同时,使用%TYPE声明。如: credit REAL(7,2); debit credit%TYPE; my_dname scott.dept.dname%TYPE; 2. 使用%ROWTYPE声明 记录类型声明时,如果其含义和某应用表行数据或某cursor定义相同时,使用%ROWTYPE声明,如: DECLARE r_emp emp%ROWTYPE; CURSOR c1 IS SELECT deptno, dname, loc FROM dept; r_dept c1%ROWTYPE; 3. 变量声明格式 每行至多包含一条语句,例如: 正确写法: v_valid BOOLEAN; v_area VARCHAR2(20); 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 错误写法: v_valid BOOLEAN; v_area VARCHAR2(20); 7.2.2.3 游标 知识点描述 为了处理SQL语句,Oracle必须分配一片内存区域,用来存储完成该处理所必需的信息,这就是上下文区域(CONTEXT AREA)。游标(CURSOR)就是一个指向上下文区域的句柄(handle)或指针。必须首先通过游标定位某个位置,然后才能处理该位置的内容。 显式游标用来处理返回多于一行的select语句。显式游标可以由用户自定义,并通过open,fetch,close步骤来调用。 隐式游标用于处理insert,update,delete和单行select…into语句。隐式游标是系统自定义的,通过PL/SQL引擎打开和关闭,因此,隐式游标不需要用户open,fetch,close。 游标变量动态地指向sql语句。它类似于pl/sql变量,在运行时刻可以拥有不同的取值,因此可以实现在运行时刻与不同的语句相关联。 游标属性附加在游标名字的后面,但游标属性返回的不是类型,它返回的是在表达式中可以使用的数值。游标属性分以下四种: %FOUND:这是一个布尔属性。如果前一个fetch语句返回一个行,那么它就会返回true,否则,返回false。 %NOTFOUND:这是一个布尔属性,如果前一个FETCH语句返回一个行,返回FALSE。仅当前一个FETCH语句没有返回任何行,才返回TRUE。 %ISOPEN:这是一个布尔属性,用来确定相关的游标是否被打开。如果已打开,返回TRUE,否则,返回FALSE。 %ROWCOUNT:这是个数字属性,它返回到目前位置,由游标返回的行的数目。 使用原则 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 1. 相关参数 (1) cursor_space_for_time (2) open_cursors (3) session_cached_cursors 2. 如何使用可以提高效率 (1) 尽量使用变量 对于经常使用的SQL语句,推荐在语句中使用变量来代替常量 ,这样SQL语句可以在SGA中共享,避免了每次执行对语句的分析,提高了内存和CPU的使用效率。 (2) 空记录测试 在应用开发的过程中,经常需要测试表中是否含有符合某种条件的记录,一种常见的错误的做法是使用count(*)的方式判断其值是否为0,这是一个极端低效率的做法,因为它要对全部数据扫描一遍。 推荐使用判断游标属性的方法。 原来的代码: SELECT count(*) INTO :v_tmp FROM … WHERE …. IF v_tmp >0 THEN ……………. END IF; 改进的代码: CURSOR c1 is SELECT FROM … WHERE … OPEN c1; If c1%NOTFOUND THEN …………… END IF; 3. 使用过程之中会经常出现的错误以及解决方案 (1) “ora-01555” a. 原因: 以下处理流程,是Oracle开发的经典错误: 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 step1:先打开cursor(以综合前置为例:select 当日所有交易 from 联机表,十多万条); step2:从游标中fetch记录,insert入历史表,delete联机表,如此循环,到达若干条记录后commit; step3:再接着如此处理,直到所有记录处理完毕; step4:处理结束后关闭cursor。 按照ANSI标准,cursor在提交时无效,必须重新打开。但是Oracle允许编写非标准的SQL,应用程序可以跨commit从cursor中获取行,不过commit后rbs段是可以被重用的,而cursor本身又必须保持读一致性,所以容易出现“rollback too old”的错误。 b. 解决建议: 方案1:若干记录commit后立即关闭cursor,再重新打开cursor,继续处理。 方案2:只commit一次或尽量减少commit,但需要较大rbs空间。 (2) “PLS-00382: expression is of wrong type” a. 原因: 有相同的返回类型,但是变量类型不一样的两个游标变量之间赋值,会产生类型不匹配的错误。 例如: DECLARE TYPE EmpCurTyp IS REF CURSOR RETURN emp%ROWTYPE; TYPE TmpCurTyp IS REF CURSOR RETURN emp%ROWTYPE; emp_cv1 EmpCurTyp; emp_cv2 TmpCurTyp; BEGIN emp_cv2 := emp_cv1; --会产生类型不匹配的错误 …… END; 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 b. 解决建议: 将两个游标变量改为相同类型。 上面的例子改为如下: DECLARE TYPE EmpCurTyp IS REF CURSOR RETURN emp%ROWTYPE; emp_cv1 EmpCurTyp; emp_cv2 EmpCurTyp; BEGIN emp_cv2 := emp_cv1; …… END; 举例 1. 打开游标时,通过游标属性判断游标纪录是否为空的方法。 DECLARE CURSOR c1 IS SELECT app_id FROM app_def WHERE app_enname = p_app_enname; BEGIN OPEN c1; EXCEPTION WHEN no_data_found THEN BEGIN ...... END; END; 2. 打开游标前判断游标纪录是否为空的方法。 DECLARE CURSOR c1 IS SELECT app_id FROM app_def WHERE app_enname = p_app_enname; 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 v_count NUMBER; BEGIN SELECT COUNT(*) INTO v_count FROM app_def WHERE app_enname = p_app_enname; IF v_count = 0 THEN OPEN c1; ...... END IF; END; 7.2.2.4 集合 知识点描述 集合是一组类型相同的元素。每个元素有一个唯一的下标,下标确定元素在集合中的位置。 数组:数组包含固定数目(数组长度)的元素,可以在运行过程中改变数组长度。 嵌套表:嵌套表可以包含任意数目的元素,嵌套表使用顺序数字做为下标。 索引表:类似于其他编程语言中的散列表,索引表的下标可以是数字或者字符串。 使用原则 1. 使用情况 (1) 嵌套表和索引表的比较: 在许多方面嵌套表和索引表有相似之处,例如:两种表数据类型拥有相同的结构,他们都使用下标记号进行访问。 但是两者还是有一些不同之处: a. 嵌套表存储可以为数据库的列,但是索引表不行。 b. 嵌套表适合于重要的数据关系需要持久保存的情况。索引表适合于相对较小的集合,这些集合可以在内存构建。索引表还有一个优点在于下标的灵活性。索引表的下标可以是负数,可以不是顺序的,而且可以是字符串而非数字。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 (2) 嵌套表和数组的比较: a. 如果预先知道元素的数目而且数组中的元素经常需要一起顺序访问,数组是一个很好的选择。数组可以是行内存储,也可以是行外存储,可以一次更新或返回数组中所有的元素。 b. 在嵌套表中,可以删除任意元素,而不仅仅只能去掉最后一个元素。嵌套表存储在行外,每个嵌套表和一个系统产生的数据库表相关联。嵌套表适用于查询和更新只影响集合中某些元素。 2. 如何使用可以提高效率 使用批量绑定提高性能所谓绑定就是指为SQL语句中的PL/SQL变量赋值。PL/SQL引擎执行过程控制语句而将SQL语句传给SQL引擎,SQL引擎执行SQL语句并将执行的结果返回给PL/SQL引擎。在PL/SQL引擎和SQL引擎之间进行频繁的上下文切换会严重影响性能。如下面的PL/SQL块所示,循环执行某个SQL语句,该SQL语句是单独处理集合的一个元素。FOR循环的每一次迭代,DELETE语句都会发往SQL引擎。Oracle提供一下一些途径来减少PL/SQL引擎和SQL引擎之间的上下文切换。 (1) 使用FORALL语句。 FORALL关键字通知PL/SQL引擎在将PL/SQL变量值传入SQL语句前进行批量绑定。虽然FORALL语句在形式上是循环迭代,但在实质上它不是FOR循环语句。FORALL的语法格式如下,其中index只能是集合的下标,sql_statement必须有引用集合元素的INSERT,UPDATE或者DELETE语句: FORALL index IN lower_bound..upper_bound sql_statement; (2) 使用BULK COLLECT子句将查询结果返回到集合中。 关键字BULK COLLECT通知SQL引擎在将结果返回到PL/SQL引擎前进行批量绑定,这里的批量绑定是指将输出结果绑定到集合中。BULK COLLECT可以用在SELECT INTO,FETCH INTO和RETURNING INTO语句中。BULK COLLECT的语法如下所示: ... BULK COLLECT INTO collection_name[, collection_name] ... 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 3. 使用过程之中会经常出现的错误以及解决方案 (1) ORA-06531: Reference to uninitialized collection a. 范例一: DECLARE TYPE NumList IS TABLE OF NUMBER; nums NumList; -- atomically null BEGIN nums(1) := 1; -- raises COLLECTION_IS_NULL (1) END; 该例会报ora-06531的错误。 b. 原因: 定义集和之后,要求初始化集合。该语句在对集合中的元素操作(语句1)之前,没有对集合进行初始化。 c. 解决建议: 对集合或集合中的元素进行操作前,首先初始化集合,例如,在语句(1)之前加上初始化语句:nums := NumList(null,null); (2) ORA-06502: PL/SQL: numeric or value error: NULL index table key value a. 范例二: DECLARE TYPE NumList IS TABLE OF NUMBER; nums NumList; -- atomically null BEGIN nums := NumList(1,3,6); -- initialize table nums(null) := 3 ; END; 该例会报错:ORA-06502: PL/SQL: numeric or value error: NULL index table key value b. 范例三: DECLARE 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 TYPE NumList IS TABLE OF NUMBER; nums NumList; -- atomically null a VARCHAR2(2); BEGIN nums := NumList(1,3,6); -- initialize table a:='a'; (1) nums(a) := 3 ; (2) END; 该例会报错:ORA-06502: PL/SQL: numeric or value error: character to number conversion error. c. 原因: 下标的类型不对,或者下标的转换未成功。 例如范例二中下标为”null”,不是number类型,也不能转换成number类型,因此会报以上错误。 例如范例三中下标a的值为’a’,该值不能转换成number类型,因此会报以上错误。 d. 解决建议: 将下标的值改为数字,或者number型变量,或者可以转换为number型变量的字符型变量。例如,将范例三中的语句(1)改为a:=’2’,或者直接将语句(2)改为nums(2):=3。 (3) ORA-06532: Subscript outside of limit a. 范例四: DECLARE TYPE NumList IS TABLE OF NUMBER; nums NumList; -- atomically null BEGIN nums := NumList(0,0); -- initialize table(1) nums(0) := 3; -- (2) nums(3) := 3; -- (3) 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 END; 语句(2)和(3)都会报这个错误。 b. 原因: 初始化语句初始了n个元素,则下标的范围就是1~n,超出该范围就会报错。 范例四中,初始化语句(1)初始化该集合有两个元素,因此,下标的范围为1~2,超出这个范围就会报错。 c. 解决建议: 将下标的值改为正确的范围以内。 (4) ORA-01403: no data found a. 范例五: DECLARE TYPE NumList IS TABLE OF NUMBER; nums NumList; -- atomically null BEGIN nums := NumList(0,0); -- initialize table nums.DELETE(1); -- delete element 1 (1) IF nums(1) = 1 THEN dbms_output.put_line('successful!');--(2) END IF; END; 该语句会报ora-01403的错误。 b. 原因: 语句(1)中已将nums(1)元素删去,nums(1)元素已经没有数据了,因此语句(2)中读num(1)元素的值就会报错。 c. 解决建议: 如果想让某元素中没有数据,可以给它赋空值,以后对该值的读取就不会出错。例如范例五中,语句(1)可以换为:nums(1):=null。 举例 1. 下面的DELETE语句只发往SQL引擎一次,即使它执行了三次DELETE操作。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 DECLARE TYPE NumList IS VARRAY(20) OF NUMBER; depts NumList := NumList(10, 30, 70); -- department numbers BEGIN FORALL i IN depts.FIRST..depts.LAST DELETE FROM emp WHERE deptno = depts(i); END; 2. 在下面的例子的例子中,SQL引擎将EMP表中所有的EMPNO,EMPNAME数据装载到嵌套表中,然后将嵌套表返回给PL/SQL引擎。 DECLARE TYPE NumTab IS TABLE OF emp.empno%TYPE; TYPE NameTab IS TABLE OF emp.ename%TYPE; enums NumTab; -- no need to initialize names NameTab; BEGIN SELECT empno, ename BULK COLLECT INTO enums, names FROM emp; ... END; 7.2.2.5 动态PL/SQL 知识点描述 大多数PL/SQL程序所做的工作都是特定的、预知的工作。例如,一个存储过程可能接受一个员工号码做为输入参数,然后更新该员工的薪水。在这种情况下,UPDATE语句的全文在编译时是确定的。这样的语句是不会在执行阶段发生变化的,这种SQL语句我们称之为静态SQL语句。 但是有些时候,程序必须在执行阶段处理一个变化的SQL语句。例如,一个通用的报表程序为了产生不同的报表必须运行不同的SQL语句。这种语句很可能在执行阶段发生改变,这种SQL语句我们称之为动态SQL语句。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 动态SQL语句存储在字符串中,程序在执行阶段建立这个语句。这些字符串必须包含合法的SQL语句,要绑定的变量前要加冒号,变量的名称是无关的。例如,下面两个语句是没有区别的: 'DELETE FROM emp WHERE sal > :my_sal AND comm < :my_comm' 'DELETE FROM emp WHERE sal > :s AND comm < :c' 拼装SQL语句执行的性质与动态SQL语句相同。如果拼装SQL语句的源如果有些是别人输入的、外部文件读取的,则不能直接拼上去,必须先检查,防止攻击。 防止攻击的办法有: 1. 尽量使用绑定变量的的动态sql; 2. 对输入条件进行字符检查 使用原则 1. 使用限制 由于使用动态sql,在编译阶段是分析不出该语句的。因此每次执行都需要编译,对系统运行产生额外的性能开销。所以,不建议联机系统的交易程序使用动态SQL。 2. 使用情况 由于在通常的PL/SQL中只能使用数据操作语言DML和事务控制语言TCL而不能使用其它一些命令如数据定义语言DDL和系统控制命令,当出现这种需求是一个做法是调用外部任务,另外一个做法就是使用动态的SQL。 动态 SQL并不在客户端被解释转换,而是由客户端的程序传输到服务器端后在服务器端解释并执行。 使用动态SQL的最常见的用法有:使用truncate table命令代替delete from table的操作、在系统进行日结、月结、年终结算时创建新的数据表,创建应用系统使用的临时表等, 下面是通过动态SQL来使用truncate table命令的方法: ... CREATE OR REPLACE PROCEDURE p_truncate_table (table_name varchar2(30)) as 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 cursor_handle INTEGER; no_query_sql_command VARCHAR2(200); BEGIN no_query_sql_command := 'truncate table ’||table_name; cursor_handle:=dbms_sql.open_cursor; dbms_sql.parse(cursor_handle,no_query_sql_command,1); cursor_handle:=dbms_sql.execute(cursor_handle); dbms_sql.close_cursor(cursor_handle); END; / ... 也可以直接使用EXECUTE IMMEDIATE来执行,如: ... BEGIN EXECUTE IMMEDIATE 'truncate table ’||table_name;; END; ... 应当说明的是动态SQL的使用在不同的版本间稍有不同,在使用是需要在不同的版本上做测试。 3. 如何使用可以提高效率 (1) 尽量使用变量绑定 联机交易的事务特点是执行的频度高,执行时间短。此类交易的sql语句都建议使用变量绑定。因为使用变量绑定的方式编写的sql语句,能大大减少sql语句硬分析的性能消耗。 (2) 使用批量动态SQL(BULK FETCH语句, BULK EXECUTE IMMEDIATE语句, FORALL语句, COLLECT INTO语句, RETURNING INTO子句) 4. 使用过程之中会经常出现的错误以及解决方案 (1) “ORA-00903: invalid table name” 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 a. 原因: 在动态PL/SQL中数据对象名称不能使用变量绑定。 例如:下面的存储过程 CREATE PROCEDURE drop_table (table_name IN VARCHAR2) AS BEGIN EXECUTE IMMEDIATE 'DROP TABLE :tab' USING table_name; END; b. 解决方法: 将变量绑定改为直接字符串拼凑。 CREATE PROCEDURE drop_table (table_name IN VARCHAR2) AS BEGIN EXECUTE IMMEDIATE 'DROP TABLE ' || table_name; END; 举例 1. 在动态SQL中使用变量绑定的例子 CREATE PROCEDURE fire_employee (emp_id NUMBER) AS BEGIN EXECUTE IMMEDIATE 'DELETE FROM emp WHERE empno = :num' USING emp_id; END; 7.2.2.6 对象 知识点描述 对象(object)是一个用户定义的复杂的数据类型,其数据结构包含一些变量,以及对这些变量进行处理的函数和过程。组成数据结构的变量,称为“属性”(attributes)。对属性进行操作的过程和函数,称为“方法”(methods)。当创建一个对象时,实际上是创建了一个对真实世界中的对象的抽象模板。例如,对一个雇员创建对象,这个对象包括的属性有:姓名,部门,职位,等等;包括的方法有:工资计算,考勤计算,等等。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 使用对象时,需要创建实例(instance),通过实例来调用对象中的方法。在真实世界中,不难理解这样做的目的。还是以雇员对象为例,只有一个对象,确有很多个雇员,每个雇员的属性都不相同,所以,要为每个雇员创建实例,他们可以共享“雇员对象”这个数据结构,而分别拥有自己的数据。 使用原则 1. 使用过程之中会经常出现的错误以及解决方案 (1) ORA-30625: method dispatch on NULL SELF argument is disallowed a. 范例: DECLARE Eagle employee; --创建实例 Jacky employee; --创建实例 BEGIN Dbms_output.put_line(Eagle.salary(eagle.rank,eagle.dept)); --通过实例调用对象中的方法 END; 该语句会报ora-30625的错误。 b. 原因: 实例已创建,但没有初始化。 c. 解决建议: 在调用方法前,初始化实例。以上范例中,加上初始化语句: Eagle := NEW employee('EAGLE',24,7,'TACH'); 举例 例一:创建对象 CREATE OR REPLACE TYPE employee AS OBJECT ( -- 定义属性(attribute) Name VARCHAR2(40), -- 定义方法(method) MEMBER FUNCTION salary 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 (rank NUMBER,dept VARCHAR2) RETURN NUMBER, ); CREATE OR REPLACE TYPE BODY employee AS MEMBER FUNCTION salary (rank NUMBER,dept VARCHAR2) RETURN AGE IS BEGIN ………… END salary; END; 例二:使用对象 DECLARE Eagle employee; --创建实例 Jacky employee; --创建实例 BEGIN Eagle := NEW employee('EAGLE',24,7,'TACH'); --初始化实例 Jacky := NEW employee('JACKY',36,1,'MANAGE'); --初始化实例 Dbms_output.put_line(Eagle.salary(eagle.rank,eagle.dept)); --通过实例调用对象中的方法 END; 7.2.2.7 大对象类型(LOB) 知识点描述 一个LOB是一个存储大量数据的数据库字段,例如图形文件或长的文本形式的文档。Oracle提供了四种不同类型的LOB:CLOB、NCLOB、BLOB、BFILE。 LOB类型 说明 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 CLOB 用于存储单字节字符数据 BLOB 存储没有结构的二进制数据 NCLOB 用于存储定宽的多字节国家字符集数据 BFILE 用于对Oracle数据库以外存储的大型二进制文件进行只读形式的访问。 LOB数据不是以内联的方式(inline)存储在数据库表中。LOB数据是存储在一个单独的位置上,同时一个“LOB定位符”存储在原始表中。该定位符是一个指向实际数据的指针,实际数据可以存储在和原始数据有不同存储参数的表空间中。 使用原则 1. 使用情况 LOB是用于存储非结构化数据的。所谓非结构化数据是指不能被分解为标准组件的数据。例如,一个员工可以分解为姓名(字符串),标识(数字),薪水等等。但是,如果给的是一张图片,会发现数据是由一长串0和1的数字流,在数据存储方面,他们不能分解为良好的结构。非结构化的数据往往是非常大的,如文本、图片、视频片断或者音乐等等。一个典型的员工纪录可以有几百个字节,但是即使是少量的多媒体数据也可能有它几千倍那么大。 LOB类型帮助支持Internet应用,随着Internet和内容丰富应用的发展,数据支持这样一种数据类型是非常有需要的:1)可以存储非结构化数据;2)优化处理大量的非结构化数据;3)为存储在数据库内或者数据库外非结构化数据提供统一的访问方式。 由于BLOB没有字符集转换,因此当几种LOB都能满足应用要求时,推荐使用BLOB。 2. 如何使用可以提高效率 (1) SQL*Loader性能:加载数据到内部LOB。 下表我们可以看到加载数据到内部LOB的各种方法的相对性能的比较,在后面我们将一一列举每种加载方法。 加载方法 相对性能 字段长度预先确定 最高 字段之间由分隔符分隔 低 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 长度-值对字段 高 每个文件一个LOB 高 (2) 选择内联存储和外联存储的比较。 一般情况下,当LOB的容量小于4K时,Oracle建议对LOB进行内联存储。内联存储在数据操作时效率更高。但是当需要进行大量的基本表操作时,我们不希望LOB进行内联存储,如全表扫描、范围扫描或者在表的非LOB列上面有大量的更新、查询操作。 (3) 提高JDBC驱动加载BLOB和CLOB的性能 使用JDBC Thin驱动向LOB中加载数据是比较慢的,因为JDBC Thin驱动实际上是使用DBMS_LOB包。而使用JDBC OCI和JDBC server-side internal驱动使用本地的LOB API,加载数据会比JDBC Thin驱动快。因为使用本地LOB API没有JDBC Thin驱动实现带来的一些额外消耗。 Oracle建议使用InputStream和OutputStream来访问和操作LOB数据。因为使用流的方式,JDBC驱动可以合理的控制缓存以减少网络的数据往返。 DBMS_LOB.LOADFROMFILE()加载LOB数据的效率比DBMS_LOB.WRITE()高,但使用DBMS_LOB.LOADFROMFILE()加载数据要求数据必须放在服务端。 (4) 适时的释放临时LOB。 在PL/SQL,C (OCI)和Java中,当SQL语句在LOB列上面操作时会返回临时LOB作为结果,临时LOB在PL/SQL块结束时会自动释放。 可以在任何时候释放不需要的临时LOB,以释放系统系统资源和临时表空间。如果不合理的释放SQL语句返回的临时LOB,临时表空间将会被过度的消耗,而系统性能将会下降。 3. 使用过程之中会经常出现的错误以及解决方案 (1) 更改LOB段的存储参数时出现ORA-904错误。 a. 问题描述: 更改一个LOB对象的MAXEXTENTS存储参数时得到904错误, SQL> CREATE TABLE t_lob 2 (DOCUMENT_NR NUMBER(16,0) NOT NULL, 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 3 DOCUMENT_BLOB BLOB NOT NULL 4 ) 5 STORAGE (INITIAL 100k 6 NEXT 100K 7 PCTINCREASE 0 8 MAXEXTENTS 100 9 ) 10 TABLESPACE users; Table created. SQL> SELECT SEGMENT_NAME, SEGMENT_TYPE, INITIAL_EXTENT, 2 NEXT_EXTENT, PCT_INCREASE, MAX_EXTENTS 3 FROM USER_SEGMENTS; SEGMENT_NAME SEGMENT_TYPE INITIAL NEXT_EXTENT PCT MAX_EXTENTS ------------------------- ------------ ------- ----------- --- ----------- T_LOB TABLE 106496 106496 0 100 SYS_IL0000030066C00002$$ LOBINDEX 40960 40960 50 2147483645 SYS_LOB0000030066C00002$$ LOBSEGMENT 40960 40960 50 505 SQL> ALTER TABLE T_LOB MODIFY LOB (SYS_LOB0000030066C00002$$) 2 (STORAGE (MAXEXTENTS 200)); ALTER TABLE T_LOB MODIFY LOB (SYS_LOB0000030066C00002$$) * ERROR at line 1: 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 ORA-00904: "SYS_LOB0000030066C00002$$": invalid identifier b. 解决办法:更改LOB对象的列名而不要直接使用LOB段的名字 SQL> SELECT TABLE_NAME, COLUMN_NAME FROM USER_LOBS 2 WHERE SEGMENT_NAME = 'SYS_LOB0000030066C00002$$'; TABLE_NAME COLUMN_NAME ------------- --------------------------------- T_LOB DOCUMENT_BLOB SQL> ALTER TABLE T_LOB MODIFY LOB (DOCUMENT_BLOB) 2 (STORAGE (MAXEXTENTS 200)); Table altered. Explanation ----------- The ALTER TABLE is a command that allows you to modify logical entities, not physical entities. (2) 更改LOB时出现ORA-22853错误。 a. 问题描述 在执行下属语句时出现错误 MODIFY LOB lobitem (storage_clause pctversion cache logging) ORA-22853: invalid LOB storage option specification Cause: A LOB storage option was not specified Action: Specify one of CHUNK, PCTVERSION, CACHE, NOCACHE, TABLESPACE, STORAGE, INDEX as part of the LOB 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 storage clause. b. 解决办法:把LOB对象的名字放在括号内,正确的命令是: MODIFY LOB (lobitem) (storage_clause pctversion cache logging) 举例 1. 加载字段长度预先确定的LOB数据 在控制文件中,加载入列的LOB的数据长度是确定的,字段长度预先确定可以使数据解析器非常高效的工作。不幸的是,通常我们很难保证所有的LOB的数据长度是相等的。 Control File: LOAD DATA INFILE 'sample4.dat' INTO TABLE Multimedia_tab FIELDS TERMINATED BY ',' (Clip_ID INTEGER EXTERNAL(5), Story LOBFILE (CONSTANT 'FirstStory1.txt') CHAR(32)) Data File (sample4.dat): 007, 008, Secondary Data File (FirstStory1.txt): Once upon the time ... The end, Upon another time ... The end, 2. 字段之间由分隔符分隔的数据的加载 在LOBFILE文件中,LOB数据由分隔符分隔,这样就允许不同长度的LOB加载入相同的列。当然,高度的灵活性是以牺牲性能为代价的。加载这种格式的数据相对而言是比较慢的,因为加载器必须扫描所有数据并查找分隔符字符串。 Control File LOAD DATA 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 INFILE 'sample5.dat' INTO TABLE Multimedia_tab FIELDS TERMINATED BY ',' (Clip_ID INTEGER EXTERNAL(5), Story LOBFILE (CONSTANT 'FirstStory2.txt') CHAR(2000) TERMINATED BY "\n") Data File (sample5.dat) 007, 008, Secondary Data File (FirstStory2.txt) Once upon a time... The end. Once upon another time... The end. 3. 加载字段是长度-值对的LOB数据 每个LOB数据前有一个数字标识该LOB的长度。这种方式的性能会比分隔符分隔数据的方式高效,但是这种方式要求在加载数据之前知道每个LOB的长度。 Control File LOAD DATA INFILE 'sample6.dat' INTO TABLE Multimedia_tab FIELDS TERMINATED BY ',' ( Clip_ID INTEGER EXTERNAL(5), Story LOBFILE (CONSTANT 'FirstStory3.txt') VARCHARC(4,2000) ) Data File (sample6.dat) 007, 008, Secondary Data File (FirstStory3.txt) 0031 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 Once upon a time ... The end. 0000 4. 每个LOBFILE仅包含一个LOB的加载方式。 Control File LOAD DATA INFILE 'sample3.dat' INTO TABLE Multimedia_tab REPLACE FIELDS TERMINATED BY ',' ( Clip_ID INTEGER EXTERNAL(5), ext_FileName FILLER CHAR(40), Story LOBFILE(ext_FileName) TERMINATED BY EOF ) Data File (sample3.dat) 007,FirstStory.txt, 008,/tmp/SecondStory.txt, Secondary Data File (FirstStory.txt) Once upon a time ... The end. 5. 将一个GIF文件john.gif写入BLOB的例子。 /**将一个GIF文件john.gif写入BLOB的例子。*/ import java.sql.*; import java.io.*; import java.util.*; import Oracle.jdbc.driver.*; import Oracle.sql.*; public class LobExample { public static void main (String args []) throws Exception 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 { DriverManager.registerDriver(new Oracle.jdbc.driver.OracleDriver()); // Connect to the database Connection conn=DriverManager.getConnection ("jdbc:Oracle:oci9:@", "scott", "tiger"); conn.setAutoCommit (false); Statement stmt = conn.createStatement (); try { stmt.execute ("drop table persons"); // Create a table containing a BLOB and a CLOB stmt.execute ("create table persons (name varchar2 (30), picture blob)"); stmt.execute ("insert into persons values ('John', EMPTY_BLOB())"); }catch (SQLException e){ // An exception could be raised here if the table did not exist already. } // Select the BLOB ResultSet rset = stmt.executeQuery ("select picture from persons where name = 'John'"); if (rset.next ()) { // Get the BLOB locator from the table 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 BLOB blob = ((OracleResultSet)rset).getBLOB (1); OutputStream ostream = blob.getBinaryOutputStream (); // Declare a file handler for the john.gif file File binaryFile = new File ("john.gif"); FileInputStream istream = new FileInputStream (binaryFile); // Create a tempory buffer byte[] buffer = new byte[1024]; int length = 0; // Use the read() method to read the GIF file to the byte array buffer, //then use the write() method to write it to the BLOB. while ((length = istream.read(buffer)) != -1) ostream.write(buffer, 0, length); // Close the inputstream and outputstream istream.close(); ostream.close(); } // Close all resources rset.close(); stmt.close(); conn.close(); } } 7.2.2.8 包(PACKAGE ) 知识点描述 包是一个可以将相关对象存储在一起的PL/SQL结构,包含了两个分离的部件:规范(specification)和主体(body),每个部件都单独被存储在数据字典中。包中可以包含过程、函数、游标和变量。将这些对象放入一个包中的一个好处就是可以从其他的PL/SQL快中引用它们,这样包也提供了用于PL/SQL的全局变量。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 使用原则 1. 使用情况 有以下情况发生时,需要使用包: (1) 存在私有函数(或过程)或私有变量,只能被某一函数(或过程)调用时,将这个私有的函数(或过程)或私有变量放入调用主函数(或过程)所在的包内。 (2) 函数(或过程)的参数里有自定义的类型时,应该建立包,将该类型的定义和该函数(或过程)的定义都放入包中。 (3) 直观的说,当具有一些能够处理相关的任务的程序代码同时希望包装共享该代码时可以使用包。 2. 如何使用可以提高效率 (1) 使包尽量大众化,使其可以在未来的应用中被重用。 (2) 尽量使用Oracle提供的包,注意不要重复创建Oracle已有的包。 (3) 包头反映出应用的设计。应该在包头只声明用户或其他开发人员必须用到的类型,项和子程序,而将包自己用的对象作为私有变量放在包体中。 (4) 当代码改变时,为减少重编译,除非必要,尽量少在包头中声明对象。因为对包体做改变时,不要求重编译,而对包头做改变时,要求重编译。 (5) 减少包中静态的全局变量的使用,避免操作的相互影响。 7.2.3 故障处理规则 知识点描述 PL/SQL中,一个警告或错误条件被称为“异常”,这个条件可以是系统本身的,也可以由用户自定义。当满足条件时,程序从当前块中跳出,进入异常处理块,程序的异常处理由用户自己定义。 使用异常处理的目的:防止错误的结果被带到外部程序,并且使出错的程序异常处理后退出,而不是中断后直接返回操作系统,从而提高应用程序的健壮性。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 使用情况 在使用的PLSQL块中,如果使用了不能返回的确定结果的SQL语句,应用要在EXCEPTION中对程序可能出现的异常进行处理,避免出现未处理的出错被传递到外层块,导致程序逻辑错误。 对于系统已经定义了的异常,应用可以直接使用,对于用户自行定义的异常需要使用pragma exception_init(exception_name,-SQLCODE)方式来初始化。 对于继续处理的EXCEPTION,可以不记录错误堆栈,对于无法继续处理的程序,EXCEPTION中至少要获取程序的返回码,返回错误码,错误描述,其名称分别定为out_retcode, out_errcode, out_errm。为了能够进一步分析程序出现异常的原因,最好能够获得出现异常时的调用错误堆栈。 常见错误及解决方案 很多情况下,特别是含有DML语句的程序中,系统希望一个存储过程是一个原子操作,要么不执行,要么完全执行。由于出错后程序跳出当前块,进入异常处理块,所以有可能因为程序只执行了一半而造成数据不一致。为防止这种情况发生,可以将commit尽量放在块的末尾,或者可能发生出错的地方之后。并在异常处理中使用rollback。将没做完的事务回滚。 在应用设计时应该设置一个错误信息表,出错后,必须向这个表写入错误信息。写入的方式建议使用独立会话,把错误信息插入到错误信息表。具体独立会话的使用请参考下面“批量程序内部代码运行监控”章节。 举例 EXCEPTION WHEN NO_DATA_FOUND THEN ROLLBACK; out_retcode:='L9003'; out_errcode:=SQLCODE; out_errm:=SQLERRM; <把错误代码插入到错误信息表> RETURN; 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 WHEN OTHERS THEN ROLLBACK; out_retcode:='L9000'; out_errcode:=SQLCODE; out_errm:=SQLERRM; <把错误代码插入到错误信息表> RETURN; 7.3 SQL语句编写规则 7.3.1 查询语句的使用原则 7.3.1.1 索引的正确使用 合理的使用正确的索引是提高系统执行效率的关键因素,对索引的使用需要注意以下一些问题: 1. 过度索引 一般情况下,使用索引可以缩短查询语句的执行时间,提高系统的执行效率,但是要避免以下两种过度索引的情况出现: (1) 对一个表建立了过多的索引,从而造成维护索引所需要的时间超过使用索引所降低的时间,从而造成整个系统效率的下降,这一般发生在对一些进行大量更新的表上面。因此一个联机表上的索引,最多不要超过5个。 (2) 由于索引数据的区分度不够,造成了使用索引而引起的效率的下降,这一般发生在对数据进行大的统计分析的时候。可以通过指定全表扫描等提示(hint)来避免。 2. LIKE运算符 在应用程序中为了使用方便,对字符型变量进行比较时经常使用LIKE运算符进行字符模式的匹配。 需要注意的是对于LIKE运算,如果通配符%出现在字符串的尾部或中间,LIKE运算符将可以使用索引进行字符串的匹配,否则如果通配符%出现在字符串的开始,则LIKE必须使用全表扫描的方式去匹配字符串,这将产生较大的系统负荷。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 一般情况下,为了提高系统的效率,我们希望用户能够在通配符的左端提供较多的数据信息以降低查询的数量。 3. NULL值 NULL值是系统中目前尚无法确定的值,在Oracle数据库系统中NULL是一个比所有的确定值都大的值,然而又不能用大于小于等于运算符来比较,对NULL值的处理只能用是与否来判定,所有的对NULL值的判定都会引起全表扫描,除非同时使用其它的查询条件。 4. 复合索引 复合索引是使用多个数据列的索引,第一个字段的数据区分度非常重要,也是影响一个联合索引效率的关键所在。 7.3.1.1.1 改写查询语句 1. 关联子查询与非关联子查询 对于一个关联子查询,子查询是每行外部查询的记录都要计算一次,然而对于一个非关联子查询,子查询只会执行一次,而且结果集被保存在内存中。 因此,通常在外部查询返回相对较少的记录时,关联子查询比非关联子查询执行得更快;而子查询中只有少量的记录的时候,则非关联子查询将会比关联子查询执行得更快。 2. 尽量用相同的数据类型的数据进行比较,以避免发生数据转换 SQL语言对于数据类型不像JAVA和C++那样进行严格的数据类型检查,不同种数据间可以进行某些运算,但是在做数据操作时需要数据库进行隐含的类型转换,在大数据量的查询中,由于要对每一个数据项做同样的操作,会造成时间和CPU处理能力的浪费。 实际应用中通常发生的隐含的数据类型的转换有: (1) 字符型到数字型的转换,如:SELECT ‘1234’ +3 FROM DUAL等 (2) 数字型到字符型的转换,如:UPDATE DEPT SET EMPNO=5678等 (3) 日期型到字符型的转换,如:UPDATE EMP SET DNAME=SYSDATE等 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 上述的转换都是隐含发生的,在实际使用中要避免使用不同类型的数据操作。 7.3.1.1.2 减少排序的发生 排序是数据库中执行频度比较大的一种操作,根据排序执行的范围不同又可以分为内排序和外排序。我们希望数据库中的排序操作的数量能够被尽量的减少同时每个排序的时间能够缩短。为此我们可以: 1. 使用UNION ALL来代替UNION 2. 添加索引。在表连接的时候使用索引可以避免排序的发生,比如添加了合适的索引,可以使连接方式由排序合并连接(Sort Merge Join)转变为索引的嵌套循环连接(Indexed Nestted Loop Join)。 3. 在DISTINCT,GROUP BY,ORDER BY子句涉及到的列上创建索引。 4. 使用较大SORT_AREA_SIZE 5. 在用户的临时表空间上使用大的extent大小。 7.3.1.1.3 使用并行查询 并行查询适合下列情况: 1. 全表扫描的查询语句 2. 返回大数据量的查询所改造的语句 3. 其它一些数据操作中的查询子句 对于较大的数据量的查询,我们可以使用提示(hint)来强制数据库使用并行查询,在Oracle数据库中,并行查询的优先级为语句提示(hint),表的定义,数据库初始化参数。 7.3.1.1.4 减少死锁的发生 在Oracle数据库中大量的数据库的锁都是行级锁,不同的会话间竞争同一条记录的可能性较小,同时Oracle数据库中提供了自动的死锁检测机制来避免数据库的死锁,保证数据库系统的可用性。因此一般情况下应用系统不需要特殊的设计来解决系统的死锁问题,但是在下列情况下系统可能出现死锁: 1. 表A上的列n上有一个索引,表B上的列m使用A上的列n作为外键,然后表A的列n上的索引被删除,此时更新表B上列m将造成对表A的表级锁,会导致死锁的发生。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 2. 应用大量的使用SELECT ……FOR UPDATE语句造成系统不必要的加锁。 对于第一种情况要对出现死锁的相关表进行检查,确认是否相关索引被错误的删除。对于第二种情况要修改应用,避免对数据的不必要的加锁。 7.3.1.1.5 集合运算符的使用 Oracle数据库的集合运算包括: UNION, UNION ALL, INTERSECT和MINUS操作。 一般情况下当两个集合中的数据都比较多时,集合运算都是比较耗时的操作,使用时需要谨慎小心。如果可能,可以使用UNION ALL操作代替UNION操作。 7.3.1.2 使用连接方式的原则 7.3.1.2.1 嵌套循环连接(NESTED LOOP JOIN) 1. 知识点描述 嵌套循环连接操作关系到两个表,一个内部表和一个外部表。Oracle比较内部数据集的每一条记录和外部数据集的每一条记录,并返回满足条件的记录。 嵌套循环连接通常会产生巨大的数据量,所以对嵌套循环连接的使用要有严格的限制。 当一个嵌套循环连接的内部表中存在索引的情况,嵌套循环连接变为改进的有索引的嵌套循环连接(INDEXED NESTED LOOP JOIN),通常有索引的嵌套循环连接在产生较小的数据量的情况下可以较快的执行。 在使用有索引的嵌套循环连接是必须确保在查询中使用了正确的驱动表和正确的驱动数据集,通常情况下我们使用包含数据量较小的表作为驱动表。 一般如果我们使用基于成本的优化器,系统会自动选择驱动表,如果是使用基于规则的优化器,则后表作为驱动表。 2. 应用原则 一般的嵌套循环连接的速度较慢,产生的数据量较大,应该严格控制其使用。 在使用有索引的嵌套循环连接时,必须保证其驱动表有合适的索引,最好为主键或唯一键,同时希望在另外一张表在相同的列上有索引。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 3. 举例 下面给出了两种连接的例子: 对于不存在索引的表EMP和DEPT执行以下操作: SELECT count(*) FROM dept,emp WHERE dept.deptno=emp.deptno and empno=30 为NESTED LOOP JOIN,因为数据库需要对表DEPT中所有的行进行处理。如果此时JOB表的JOBNO列上有索引则上述查询的方式转变为有索引的嵌套循环连接(Indexed Nested Loop Join) *************************************************** * Nested Loop Join * -- table emp has index on jobno column * -- table job has index on jobno column ***************************************************** SQL> SET AUTOT ON EXP SQL> SELECT JOBNAME,SUM(SAL) 2 FROM EMP E,JOB J 3 WHERE E.JOBNO=J.JOBNO 4 AND J.JOBNO <3 5 GROUP BY J.JOBNAME; JOBNAME SUM(SAL) ---------------------------------------- ---------- job name 1 27725 job name 2 26025 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 SORT (GROUP BY) 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 2 1 TABLE ACCESS (BY INDEX ROWID) OF 'EMP' 3 2 NESTED LOOPS 4 3 TABLE ACCESS (BY INDEX ROWID) OF 'JOB' 5 4 INDEX (RANGE SCAN) OF 'IND_JOB_JOBNO' (UNIQUE) 6 3 INDEX (RANGE SCAN) OF 'IND_EMP_JOBNO' (NON-UNIQUE) 7.3.1.2.2 散列连接(Hash Join) 1. 知识点描述 散列连接将驱动表加载进内存,使用散列技术将驱动表与较大的表进行连接,连接过程中,对大表的访问使用了散列访问。散列连接可以提高等连接的速度。 如果可用的散列空间内存足够大,可以加载构建输入,那么散列连接算法能够很好地运行简单的散列连接,但是并不需要将整个输入放入hash_area_size内存。如果散列连接中较小的驱动表无法放入hash_area_size,那么Oracle将拆分该散列连接,并使用temp表空间中的临时段来管理这个溢出。 Oracle推荐将驱动表的hash_area_size设置为驱动表字节总数的1.6倍。 2. 应用原则 一般的散列连接发生在一个大表和一个小表做连接的时候,此时小表中的数据全部被读入内存,其处理的速度较快。 3. 举例 **************************************************** * Hash Join * -- table emp has 450000+ rows * -- table dept has round 1000 rows ***************************************************** SQL> SET AUTOT ON EXP SQL> SELECT COUNT(*) "NUMBER OF DEPT",SUM(SAL) "TOTAL SALARY" 2 FROM EMP E,DEPT D 3 WHERE E.DEPTNO=D.DEPTNO 4 AND DNAME LIKE 'DNAME LINE 100%' 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 5 ; number of dept total salary -------------- ------------ 260 2609357.21 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=281 Card=1 Bytes=32) 1 0 SORT (AGGREGATE) 2 1 HASH JOIN (Cost=281 Card=1062 Bytes=33984) 3 2 TABLE ACCESS (FULL) OF 'DEPT' (Cost=4 Card=106 Bytes=2650) 4 2 TABLE ACCESS (FULL) OF 'EMP' (Cost=265 Card=458752 Bytes=3211264) 7.3.1.2.3 排序合并连接(Sort Merge Join) 1. 知识点描述 排序合并连接是指从目标表中读取两个记录数据集,并使用连接字段将两个记录集分别排序的操作。合并过程将来自一个数据集的每一条记录同来自另一个数据集与之匹配的记录相连接,并返回记录数据集的交集。 排序合并连接有几种不同的排序方法:外部合并连接,反合并连接和半合并连接。这些不同的排列方法使得合并步骤服务于不同的目的,可以是找到记录数据集的交集,也可以是找到满足SQL语句中WHERE子句条件的那些记录。 2. 应用原则 一般的排序合并连接是在散列连接不能达到应用的要求或Oracle优化器认为排序合并连接效率更高的情况下使用。在下述的条件下排序合并连接被使用: (1) 数据表之间的连接不是等值连接而是其它连接 (2) 数据库使用的优化模式是基于RBO而不是CBO 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 3. 举例 在下述的查询中 ***************************************************** * Sort Merge Join * -- table emp has no index on deptno column * -- table dept has no index on deptno column ***************************************************** SQL> set autot on exp SQL> select dname,sum(sal) 2 from dept d,emp e 3 where d.deptno=e.deptno 4 and d.deptno <5 5 group by dname; DNAME SUM(SAL) ---------------------------------------- ---------- DNAME LINE 1 20475 DNAME LINE 2 19475 DNAME LINE 3 22400 DNAME LINE 4 22675 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 SORT (GROUP BY) 2 1 MERGE JOIN 3 2 SORT (JOIN) 4 3 TABLE ACCESS (FULL) OF 'EMP' 5 2 SORT (JOIN) 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 6 5 TABLE ACCESS (FULL) OF 'DEPT' 7.3.1.3 进行复杂查询的原则 7.3.1.3.1 限制表连接操作所涉及的表的个数 对于数据库的连接操作操作,我们可以简单的将其想象为一个循环匹配的过程,每一次匹配相当于一次循环,每一个连接相当于一层循环,则N个表的连接操作就相当于一个N-1层的循环嵌套。 一般的情况下在数据库的查询中涉及的数据表越多,则其查询的执行计划就越复杂,其执行的效率就越低,为此我们需要尽可能的限制参与连接的表的数量。 1. 3-5个表的处理方法 对于较少的数据表的连接操作,需要合理的确定连接的驱动表,从某种意义上说,确定合理的驱动表就是确定多层循环嵌套中的最外层的循环,可以最大限度的提高连接操作的效率,可见选择合适的驱动表的重要性。 RBO模式下,在SQL语句中FROM子句后面的表就是我们要进行连接操作的数据表,Oracle 按照从右到左的顺序处理这些表,让它们轮流作为驱动表去参加连接操作,这样我们可以把包含参与连接的数据量最少的表放在FROM子句的最右端,按照从右到左的顺序依次增加表中参与连接数据的量。 CBO模式下,则不需要考虑表放置的位置。 2. 5个表以上的处理方法 对于涉及较多的表(>5+)的数据连接查询,其查询的复杂度迅速增加,其连接的存取路径的变化更大,存取路径的个数与连接的表的个数的阶乘有关:当n=5时存取路径=1X2X3X4X5=120个,而当连接的表的个数为6时存取路径变为1X2X3X4X5X6=720个,数据库优化器对于数据的存取路径的判断近乎为不可能,此时完全依赖与用户的语句书写方式。 对于较多的表的连接,要求开发人员查询返回的结果能够有所预测,同时判断出各个参与连接的表中符合条件的记录的数量,从而控制查询的运行时间。 同时为了提高查询的效率,此时可以把部分表的一些连接所形成的中间结果来代替原来的连接表,从而减少连接的表的数目。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 3. 对表连接操作涉及的表数目不应多于8个表 如果查询语句拥有过多的表连接,那么它的执行计划过于复杂且可控性降低,容易引起数据库的运行效率低下,即使在开发测试环境中已经经过充分的测试验证,也不能保证在生产系统上由于数据量的变化而引发的相关问题。应该在应用设计阶段就避免这种由于范式过高而导致的情况出现。 7.3.1.3.2 限制嵌套查询的层数 应用中影响数据查询的效率的因素除了参与查询连接的表的个数以外,还有查询的嵌套层数。对于非关联查询,嵌套的子查询相当于使查询语句的复杂度在算术级数的基础上增长,而对于关联查询而言,嵌套的子查询相当于使查询语句的复杂度在几何级数的基础上增长。 因此,降低查询的嵌套层数有助于提高查询语句的效率。 对嵌套查询层数的限制要求:如果查询语句拥有过多的嵌套层数,那么会使该查询语句的复杂度高速增加,应该在数据库设计阶段就避免这种情况出现,不应多于5层。 7.3.1.3.3 灵活应用中间表或临时表 在对涉及较多表的查询和嵌套层数较多的复杂查询的优化过程中,使用中间表或临时表是优化、简化复杂查询的一个重要的方法。 通过使用一些中间表,我们可以把复杂度为M*N的操作转化为复杂度为M+N的操作,当M和N都比较大时M+N < CREATE TABLE LOC1 AS SELECT * FROM LOC2; Table created. Elapsed: 00:00:00.19 SQL> DELETE FROM LOC1 2 WHERE ROWID IN 3 (SELECT ROW_ID FROM 4 (SELECT ROWID ROW_ID,ROWNUM ROW_NUM FROM LOC1) 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 5 WHERE ROW_NUM >10000); 121088 rows deleted. Elapsed: 00:00:12.37 SQL> COMMIT; Commit complete. Elapsed: 00:00:00.00 SQL> DROP TABLE LOC1; Table dropped. Elapsed: 00:00:00.32 SQL> CREATE TABLE LOC1 AS SELECT * FROM LOC2; Table created. Elapsed: 00:00:00.22 SQL> CREATE GLOBAL TEMPORARY TABLE ROWID_ROWNUM 2 (ROW_ID ROWID, ROW_NUM NUMBER); Table created. Elapsed: 00:00:00.01 SQL> INSERT INTO ROWID_ROWNUM SELECT ROWID,ROWNUM FROM LOC1; 131088 rows created. Elapsed: 00:00:00.25 SQL> DELETE FROM LOC1 WHERE ROWID IN 2 (SELECT ROW_ID FROM ROWID_ROWNUM WHERE ROW_NUM >10000); 121088 rows deleted. Elapsed: 00:00:10.42 7.3.1.3.4 使用一些改写复杂查询的技巧 1. 转换连接类型 参见上文的改写查询语句部分 2. 把OR转换为UNION ALL 3. 区分不同的情况使用IN或EXISTS 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 对于主查询中包含较多条件而子查询条件较少的表使用EXISTS,对于主查询中包含较少条件而子查询条件较多的表使用IN。 4. 使用合理的连接方式 在不同的情况下使用不同的连接方式:散列连接适用于一个较小的表和较大的表的连接,排序合并连接需要对小表进行排序操作,索引的嵌套循环连接对于一般连接是有效的,但是需要在连接的关键字上有索引的存在。 应用开发人员应该根据不同的情况选取合适的连接方式。 1. 使用并行查询 如果查询的数据在表中所占的比例较大,可以考虑使用并行查询来提高查询的执行速度。 对于UPDATE/INSERT/DELETE操作的查询部分也可以同样做并行查询的处理。 2. 使用PL/SQL过程和临时表代替复杂查询。 对于涉及巨大的表的连接的统计查询,由于可能会造成大量的排序统计工作,使得查询的速度变慢,此时可以考虑使用PLSQL替代原来的查询。 7.3.2 DML语句的调整原则 DML语句包括Insert、Update、Delete和Merge。在使用DML语句的时候,我们也会遇到性能低下的情况,可以参考以下的内容来做出调整。 7.3.2.1 Oracle存储参数的影响 Oracle的DML语句出现性能问题的一些情况: 1. Insert操作缓慢并且占用过多的I/O资源。 这种情况发生在PCTFREE较高且行记录较大,频繁地寻找新的空闲数据块的时候。 在数据对象有(多个)索引的情况下,Insert 操作还需要对索引进行维护,这额外的增加了数据插入的成本,所以对于没有过度索引的表的维护是比较花费资源的。 2. Update操作缓慢。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 Update操作需要获得操作对象上的独占锁,如果其它的用户已经占有了该对象的非兼容的锁,那么Update操作就需要等待,通常这是非常短的时间,但是如果该用户在操作时被打断,则该用户持有这个锁的时间就可能变长,造成其它用户的等待,这是一个管理上的问题。 如果Update操作扩展了一个Varchar或Blob列导致发生了行迁移的时候,其更新也会变慢。 3. Delete操作缓慢。 通常发生在记录被删除,而且Oracle必须将数据块重新连接到该表的Freelist的时候。 由于删除操作会产生大量的undo和redo信息,所以对系统的性能的影响较大。如果可能可以使用更改状态标志和在另外的表中插入新的记录来代替删除操作。 对于删除全表的操作可以用truncate table等命令来实现,在PL/SQL等不支持truncate命令的环境中可以使用动态SQL来实现truncate的功能。对于碎片比较多的系统,删除操作在某些时候涉及到数据块的回收。 另外,当有多个任务想要对一张数据表进行Insert或Update操作的时候,这张数据表的段头可能会产生冲突情况,这种冲突可以表现为出现等待事件:Buffer Busy Waits,此时对于数据库表的处理办法是提高Pctfree的值,降低一个数据块中数据的行数,对于冲突的索引可以使用倒排索引来避免同一数据块中的数据的索引存放在同一索引块中。 调整原则 请参考上文相关部分以适当地对这几个参数进行设置,以在有效空间利用和高性能之间获得一个平衡点。 一般情况下对于并发更新比较频繁的对象要降低同一数据块中的数据行数以减少系统对于同一数据块的竞争,以空间换时间以提高性能。对于并发更新竞争不是那么频繁的对象要提高同一数据块中的数据行数,以提高系统空间的利用效率,同时提高缓存的利用率以达到提高系统整体效率的目的。 作为队列使用的表的竞争会比较剧烈,这类表中包含的总的数据行数不会太多,所以可以使用空间来换取效率。 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 7.3.2.2 大数据类型的影响 使用大数据类型(RAW,LONG,BLOB,CLOB等)的时候,主要问题在于它们常常会超出普通的数据块大小,导致数据列分散到相邻的数据块。这样,每行记录被访问时,Oracle都会产生两次以上的I/O操作。 调整原则 对于使用大数据类型的表,一般情况下其数据的行连接是不可避免的,我们能够做的就是尽量的降低这种事件发生的频率。 一般情况下,对于单独存储的LOB对象,我们可以指定其使用较大的db_block_size的表空间以控制其使用的数据块的个数,同时减少对LOB对象的访问次数,其中数据块的大小根据各个不同的LOB的平均大小有所不同。 小于4k的LOB对象可以和数据存储在一起,这样对数据访问速度的影响较大,这种情况下我们可以按照LOB对象的实际大小而选择不同表空间来存储数据。 7.3.2.3 DML执行时约束的开销 约束会对DML操作的性能产生影响。 1. 完整性约束:时间会耗费在验证每一个数据值是否合法上。 2. 主键约束:主键约束是由唯一索引来强制实施的,而且这个索引在插入和更新操作上的开销使大容量的插入操作和更新操作运行变慢,因为每个值都必须从索引中查询一次。 3. 外键约束:强制实施了交互表之间的数据关系,必须访问外部的数据表以确认当前值是否合法,才能进行插入。 4. 其它约束:对于其它检查的,数据也需要做相应的检查 5. 触发器:触发器对DML的执行效率也有较大的影响,特别当触发器的类型为for each row的时候。 调整原则 1. 在执行大容量的插入或更新任务时,可以暂时禁用所有与所影响的数据表有关的约束、触发器,装载数据,最后才重新启用约束 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 2. 在启用约束时,需要考虑非法的数据。 7.3.2.4 DML执行时维护索引所需的开销 在记录被插入和修改时,表上所有的参与索引都必须实时地进行更新。这通常会产生由于大量排序而增加的系统开销,严重降低系统的执行性能。 调整原则 1. 在大型的DML批操作中,在更改数据表之前,删除全部索引。在批操作之后,重新建立起索引。 2. 如果索引因为不平衡而产生拆分等额外操作,那么可以通过重建索引操作,也会减少维护索引所需的时间。 3. 如果在数据被加载到数据库之前其数据已在外部完成排序,则在创建索引是可以使用NOSORT 选项,需要注意的是NOSORT只能使用升序而不能使用降序,并且不能使用在倒排、分区、位图索引中。 在批量数据加载后的创建索引的过程中,可以指定用来排序的表空间已提高排序的效率,在指定排序表空间是需要注意该表空间的extent的大小,一般情况下该值越大越好。 8 附件 8.1 部分系统数据库参数配置 北京数据中心 开放系统平台管理部 Page of 146 5a1a43a381f6d8b4024a8b35fc9e690e.doc6 8.2 部分系统参数配置 8.3 Oracle参数说明 北京数据中心 开放系统平台管理部 Page of 146

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 20 金币 [ 分享文档获得金币 ]
39 人已下载

下载文档

相关文档