6/11/2007

Oracle数据库恢复管理器及特殊包的应用

摘要:多数Oracle数据库管理员会遇到数据库的备份恢复和将某表中数据定期备份形成历史流水数据以便今后查询统计等问题,本文通过对Oracle数据库实用工具恢复管理器及DBMS_JOB包工作机制的分析,提出了应用Oracle数据库恢复管理器和利用DBMS_JOB包实现存储过程自动执行来解决问题的方法。
关键词:DBA、备份恢复、恢复管理器、DBMS_JOB包

一. 引言:
  随着Oracle大型数据库系统在企业的广泛应用,系统数据量的快速增长,相信为数不少的Oracle DBA每天都在忙于做着重复的工作--对数据库进行备份。如果一旦哪一天疏忽了,而这一天系统又恰恰发生了故障,需要进行数据恢复,那么此时对 DBA来说可能就是一场灾难, 因为他可能无法完整地恢复数据库中的数据。此外,在数据库的应用中我们会经常碰到这样的需求:将一些重要数据表中的数据定期备份到另一些数据表中去。例如在企业员工工资管理系统中,每月工资报表打印完毕后,应将当月工资数据保存到工资历史库中去,以便今后查询及统计使用。通常我们采用存储过程来完成对数据的处理,这个过程由人工定期执行完成,操作起来很不方便。对于第一种情况,现在我们可利用Oracle数据库实用工具恢复管理器来完成DBA每天必须做的备份工作,而且可设定一个固定的时间, 让系统自动进行备份。对后一种情况,我们可以使用DBMS_JOB包结合存储过程来实现数据处理的自动执行。下面笔者结合实践经验,分别介绍其实现方法。

二. Oracle数据库备份与恢复方式及特点
ORACLE 数据库备份分为物理备份和逻辑备份。物理备份是数据库文件拷贝的备份, 冷
备份、热备份属于物理备份。 导出/导入(EXPORT/IMPORT)工具用于进行逻辑备份。
导出(EXPORT)备份可拷贝数据与数据库定义,并以Oracle的内部格式保存为二进制文件。相反,利用Import则可将数据从二进制文件放回到Oracle数据库中。但是导出(EXPORT)备份机制不能提供时间点恢复,而且不能和归档重做日志文件一起使用。
冷备份是在数据库被正常关闭之后进行的数据文件的物理备份。当数据库被关闭时,被
数据库使用的每一个文件都被备份下来。这些文件因而保持着数据关闭时的完整的映象。
热备份是在数据库运行的情况下,采用archivelog mode方式备份数据的方法。 这涉及到将每个表空间设置为备份状态,然后备份其数据文件,最后将表空间恢复成正常的状态。
数据库可以从这个备份中完全地恢复过来,也可以通过归档的重做日志回滚到前面时间的任
一个点上。
上述几种备份方法的特性比较
方法 类型 恢复特性
----------- --------- ----------------------------------------------
Export导出 逻辑型 可以将任何数据库对象恢复到它被导出时的状态
冷备份 物理型 可将数据库恢复到它被关闭时的状态
热备份 物理型 可将数据库恢复到任一时间点的状态

以上几种备份方式都需要依赖DBA人工操作完成,从而增加了DBA维护系统的负担。当
DBA需要维护多个Oracle数据库系统时,还容易导致操作失误,而且备份的数据不便于集中统一管理。
三. Oracle数据库恢复管理器及DBMS_JOB包概述
恢复管理器(RMAN)是一个使DBA能很方便地对数据库执行备份和恢复任务的Oracle
应用工具,与以上介绍的几种方式不同,它能够提供DBA针对企业数据库备份与恢复操作
的集中控制。RMAN可以将备份记录保存在恢复目录中,Oracle服务器保持对备份的跟踪
。实际的物理备份拷贝将被存储在指定的存储系统上,可以是磁带或磁盘。RMAN将全部备
份数据以Oracle特有的格式写入到"备份集"文件中,通过RMAN应用工具来读取。RMAN支持建立除逻辑备份以外的所有类型的备份。
下图显示了RMAN的功能框图。

利用RMAN进行备份恢复的条件是:
1.建立一个recovery_catalog,存放RMAN使用和维护着的目标数据库的信息,RMAN
使用这些信息去决定如何执行备份和恢复的请求。通常是把它建在另一个Oracle数据库的一个模式里,即需要建立一个用户,该用户需要有recovery_catalog_owner权限。
2.目标数据库必须是在archivelog模式下运行,因为这样,日志才能归档,而RMAN
正是利用归档日志进行数据恢复,所以这是一个必备条件。同时archivelog模式也是数据库在线备份的必备条件。
3.RMAN备份中,如果采用磁带机备份,需要安装第三方介质管理库(MML)。
恢复管理器保存在RMAN中注册的全部数据库的记录。当RMAN被用来启动备份或恢复数据库时,它将目标数据库与恢复目录中可用的数据库ID进行验证。如果条件一致,RMAN对目标数据库至少建立两个通道,其中一个通道只是对目标数据库的一个远程调用,使用PL/SQL接口来执行备份与恢复操作。RMAN使用它自己的PL/SQL引擎编译这些用户命令,并在目标数据库上执行这些命令。执行过程不需要用户干预,RMAN记录追踪在数据库上执行的全部备份与恢复操作,因而在很大程度上避免了DBA错误导致的危险。 同时RMAN提供了多种命令用于检查和测试数据库备份集与拷贝,并确保备份文件完整无缺且能够用于实现恢复。由上述可见,采用恢复管理器做备份与恢复的管理与其他方式相比较具有明显的优势,
可大大减少DBA做备份工作的工作量和操作失误。
DBMS_JOB包是Oracle提供的内部函数包,提供了管理和调度作业队列中的作业定时执行的控制机制。所有作业由SNP后台进程执行。 当SNP进程运行一个作业时,进程将首先创建会话,并恢复作业运行时的环境参数,再调度作业运行。DBMS_JOB包的主要功能有:提交Submit(),执行Run(),删除Remove()等。这样,我们就可以用这个包将创建的存储过程放入Oracle数据库系统的作业队列中去,由系统按时调度运行。

四. 应用实例
4.1 RMAN做数据库在线备份应用实例
这里以某公司业务处理计算机中心数据库为例。用户系统配置为:两台HP9000小型机(host1、host2),操作系统为HP-UX11.0,Oracle数据库版本为8.0.5。两台机上各有一个Oracle数据库实例,分别运行不同的业务处理系统。用户要求设备7X24小时在线工作,原则上运行时不允许数据库关闭。这就使得我们只能采用在线备份方式解决问题。为安全起见,我们在另一台IBM服务器(host3)上安装Windows2000及一个独立的Oracle数据库,恢复目录就建在这个数据库中,这台服务器还配置了一台磁带加载机,备份数据存放在磁带上,这样即便哪台机器出现故障我们也能够实现数据库的完全恢复,不过DBA应注意定期做恢复目录数据库的备份。在备份策略上,我们采用了全备份与归档日志备份相结合的方式,既不占用过多的系统时间,也相应减少了备份的数据量。备份策略如下:
(1) 每周日晚11:00做数据库在线全备份。
(2) 每天12:00,18:00 做数据库归档日志文件的在线备份。

建立备份机制的操作如下(以host1机为例):
(1) 建立恢复目录并注册目标数据库。
SVRMGR> create tablespace rmanspace datafile 'rmandata' size 500m;
SVRMGR> create user rman identified by rman default tablespace
Rmanspace temporary tablespace temp;
SVRMGR> grant connect,resource,recovery_catalog_owner to rman;
以上为建立RMAN表空间和用户。
$ sqlplus rman/rman
sql> start "/ora_01/app/oracle/product/8.0.5/rdbms/admin/catrman";
--执行创建恢复目录操作
$ rman target system/manager@host1 rcvcat rman/rman@host3;
--连接目标数据库和恢复目录
rman> register database; --将目标数据库注册到恢复目录中
rman> resync catalog; --进行同步目录操作
(2) 将目标数据库改为归档模式运行。
SVRMGR> connect internal
SVRMGR> startup mount [dbname]
SVRMGR> alter database [dbname] archivelog; --起用归档模式
SVRMGR> archive log start --启动自动归档模式
SVRMGR> alter database [dbname] open; --打开数据库
修改数据库初始化参数文件init.ora,定义归档模式(自动)、归档日志文件保存
路径、归档日志文件命名方法,重新启动数据库。


---------------------------------------------------------------

(3)建立全备份脚本文件hotbackup.rcv。
connect target internal/oracle@host1
connect rcvcat rman/rman@host3
run { allocate channel t1 type 'SBT_TAPE';
backup
incremental level 0
skip inaccessible
tag hot_db_bk_level0
filesperset 5
format 'bk_%s_%p_%t' (database);
--备份全部数据库控制文件和数据文件
sql 'alter system archive log current';
backup
filesperset 20
format 'al_%s_%p_%t' (archivelog all delete input);
--备份归档日志,备份成功后删除归档日志。若不成功,则不做删除。
}

归档日志备份脚本hotarcbackup.rcv文件如下:
connect target internal/oracle@host1
connect rcvcat rman/rman@host3
run { allocate channel t1 type 'SBT_TAPE';
sql 'alter system archive log current';
backup
filesperset 20
format 'al_%s_%p_%t' (archivelog all delete input);
}

(4) 利用UNIX的crontab命令定期自动执行备份脚本
crontab命令用于指定一个文件,其行计划命令以固定时间间隔执行。Cron是一个
永久进程,它由/etc/rc.local启动执行。Cron程序读取、解释并执行crontab文件。
我们将需自动定期执行备份的脚本文件写成shell命令行方式存入crontab文件中,由
系统定期调度执行。
  Crontab文件的每一行由六个域(minutes、hours、day of month、month、day of
week、command)组成,域之间用空格或Tab分开。
  现在,我们在目标机上编写一个文件,用以启动自动备份进程。文件名定为Oracle,
文件将放在/var/spool/cron/crontabs 目录下。
  Oracle文件内容:
  0 23 * * 0 /oracle/rman/rman cmdfile ‘hotbackup.rcv’
  # 星期天23点对数据库执行在线全备份
  0 12,18 * * * /oracle/rman/rman cmdfile ‘hotarcbackup.rcv’
  # 每天12点,18点执行归档文件备份
  经过以上的操作后,系统每天自动产生两个归档日志备份,每个星期天产生一个数
据库完全备份。DBA需要做的是,隔几天换一盘磁带(更换磁带的周期取决于备
份文件的大小和磁带的容量)和用RMAN定期检查备份执行情况。

执行恢复操作的RMAN脚本文件restore.rcv如下(在host1上运行):
connect target
connect rcvcat rman/rman@host3
run { allocate channel t1 type 'SBT_TAPE';
allocate channel t2 type 'SBT_TAPE';
restore controlfile;
sql 'alter database mount';
restore database;
recover database;
sql 'alter database open resetlogs';
}

4.2 存储过程定期自动执行的实例
以下为将Salary表数据定时转入Salary_history表的应用实例:
创建存储过程
SQL> create or replace procedure ProcEmp
IS
begin
insert into Salary_history (EmpId,EmpName,DptName,Salary,Month)
select EmpId,EmpName,DptName,Salary,to_char(sysdate,'yyyy-mm') from Salary;
commit;
end ProcEmp;
/

提交作业
SQL> variable jobno number;
SQL> begin
DBMS_JOB.SUBMIT(:jobno,
'ProcEmp;',
SYSDATE, 'SYSDATE + 30'); --每30天运行一次
commit;
end;
/

运行作业
SQL>begin
dbms_job.run(:jobno);
end;
/

五. 结语
Oracle实用工具RMAN的应用为DBA管理多个Oracle数据库提供了集中备份管理与恢复控制的机制,大大地减轻了DBA的工作压力,而DBMS_JOB包的使用增强了存储过程的应用功能,这样,他们就可以从备份数据及重复处理数据的繁琐中解脱出来,去做其它更有意义的工作。而数据库既实现了在线磁带备份,又实现了异机备份集中管理,相应提高了系统运行的安全性。

6/07/2007

Oracle数据库锁的种类及研究

本文通过对Oracle数据库锁机制的研究,首先介绍了Oracle数据库锁的种类,并描述了实际应用中遇到的与锁相关的异常情况,特别对经常遇到的由于等待锁而使事务被挂起的问题进行了定位及解决,并对死锁这一比较严重的现象,提出了相应的解决方法和具体的分析过程。

数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。

加锁是实现数据库并发控制的一个非常重要的技术。当事务在对某个数据对象进行操作前,先向系统发出请求,对其加锁。加锁后事务就对该数据对象有了一定的控制,在该事务释放锁之前,其他的事务不能对此数据对象进行更新操作。

在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两种基本的锁类型来对数据库的事务进行并发控制。

在实际应用中经常会遇到的与锁相关的异常情况,如由于等待锁事务被挂起、死锁等现象,如果不能及时地解决,将严重影响应用的正常执行,而目前对于该类问题的解决缺乏系统化研究和指导,本文在总结实际经验的基础上,提出了相应的解决方法和具体的分析过程。

Oracle数据库的锁类型

根据保护的对象不同,Oracle数据库锁可以分为以下几大类:DML锁(data locks,数据锁),用于保护数据的完整性;DDL锁(dictionary locks,字典锁),用于保护数据库对象的结构,如表、索引等的结构定义;内部锁和闩(internal locks and latches),保护数据库的内部结构。

DML锁的目的在于保证并发情况下的数据完整性,本文主要讨论DML锁。在Oracle数据库中,DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为事务锁或行级锁。

当Oracle执行DML语句时,系统自动在所要操作的表上申请TM类型的锁。当TM锁获得后,系统再自动申请TX类型的锁,并将实际锁定的数据行的锁标志位进行置位。这样在事务加锁前检查TX锁相容性时就不用再逐行检查锁标志,而只需检查TM锁模式的相容性即可,大大提高了系统的效率。TM锁包括了SS、SX、S、X等多种模式,在数据库中用0-6来表示。不同的SQL操作产生不同类型的TM锁。如表1所示。

在数据行上只有X锁(排他锁)。在 Oracle数据库中,当一个事务首次发起一个DML语句时就获得一个TX锁,该锁保持到事务被提交或回滚。当两个或多个会话在表的同一条记录上执行DML语句时,第一个会话在该条记录上加锁,其他的会话处于等待状态。当第一个会话提交后,TX锁被释放,其他会话才可以加锁。

当Oracle数据库发生TX锁等待时,如果不及时处理常常会引起Oracle数据库挂起,或导致死锁的发生,产生ORA-60的错误。这些现象都会对实际应用产生极大的危害,如长时间未响应,大量事务失败等。

TX锁等待的分析

在介绍了有关地Oracle数据库锁的种类后,下面讨论如何有效地监控和解决锁等待现象,及在产生死锁时如何定位死锁的原因。

监控锁的相关视图 数据字典是Oracle数据库的重要组成部分,用户可以通过查询数据字典视图来获得数据库的信息。和锁相关的数据字典视图如表2所示。

TX锁等待的监控和解决在日常工作中,如果发现在执行某条SQL时数据库长时间没有响应,很可能是产生了TX锁等待的现象。为解决这个问题,首先应该找出持锁的事务,然后再进行相关的处理,如提交事务或强行中断事务。

死锁的监控和解决在数据库中,当两个或多个会话请求同一个资源时会产生死锁的现象。死锁的常见类型是行级锁死锁和页级锁死锁,Oracle数据库中一般使用行级锁。下面主要讨论行级锁的死锁现象。

当Oracle检测到死锁产生时,中断并回滚死锁相关语句的执行,报ORA-00060的错误并记录在数据库的日志文件alertSID.log中。同时在user_dump_dest下产生了一个跟踪文件,详细描述死锁的相关信息。

在日常工作中,如果发现在日志文件中记录了ora-00060的错误信息,则表明产生了死锁。这时需要找到对应的跟踪文件,根据跟踪文件的信息定位产生的原因。

如果查询结果表明,死锁是由于bitmap索引引起的,将IND_T_PRODUCT_HIS_STATE索引改为normal索引后,即可解决死锁的问题。

表1 Oracle的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




表2 数据字典视图说明
视图名 描述 主要字段说明
v$session 查询会话的信息和锁的信息。 sid,serial#:表示会话信息。

program:表示会话的应用程序信息。

row_wait_obj#:表示等待的对象。

和dba_objects中的object_id相对应。

v$session_wait 查询等待的会话信息。 sid:表示持有锁的会话信息。

Seconds_in_wait:表示等待持续的时间信息

Event:表示会话等待的事件。

v$lock 列出系统中的所有的锁。 Sid:表示持有锁的会话信息。

Type:表示锁的类型。值包括TM和TX等。

ID1:表示锁的对象标识。

lmode,request:表示会话等待的锁模式的信

息。用数字0-6表示,和表1相对应。

dba_locks 对v$lock的格式化视图。 Session_id:和v$lock中的Sid对应。

Lock_type:和v$lock中的type对应。

Lock_ID1: 和v$lock中的ID1对应。

Mode_held,mode_requested:和v$lock中

的lmode,request相对应。

v$locked_object 只包含DML的锁信息,包括回滚段和会话信息。 Xidusn,xidslot,xidsqn:表示回滚段信息。和

v$transaction相关联。

Object_id:表示被锁对象标识。

Session_id:表示持有锁的会话信息。

Locked_mode:表示会话等待的锁模式的信

息,和v$lock中的lmode一致。

6/03/2007

表空间的创建

ORACLE中,表空间是数据管理的基本方法,所有用户的对象要存放在表空间中,也就是用户有空间的使用权,才能创建用户对象.否则是不充许创建对象,因为就是想创建对象,如表,索引等,也没有地方存放,Oracle会提示:没有存储配额.

  因此,在创建对象之前,首先要分配存储空间.
  分配存储,就要创建表空间:
  创建表空间示例如下:
CREATE TABLESPACE "SAMPLE"
LOGGING
DATAFILE 'D:\ORACLE\ORADATA\ORA92\LUNTAN.ora' SIZE 5M
EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO
上面的语句分以下几部分:
第一: CREATE TABLESPACE "SAMPLE"  创建一个名为 "SAMPLE" 的表空间.
对表空间的命名,遵守Oracle 的命名规范就可了.
ORACLE可以创建的表空间有三种类型:
(1)TEMPORARY: 临时表空间,用于临时数据的存放;
创建临时表空间的语法如下:
CREATE TEMPORARY TABLESPACE "SAMPLE"......
(2)UNDO : 还原表空间. 用于存入重做日志文件.
创建还原表空间的语法如下:
CREATE UNDO TABLESPACE "SAMPLE"......
(3)用户表空间: 最重要,也是用于存放用户数据表空间
可以直接写成: CREATE TABLESPACE "SAMPLE"
TEMPORARY 和 UNDO 表空间是ORACLE 管理的特殊的表空间.只用于存放系统相关数据.
第二: LOGGING
有 NOLOGGING 和 LOGGING 两个选项,
NOLOGGING: 创建表空间时,不创建重做日志.
LOGGING 和NOLOGGING正好相反, 就是在创建表空间时生成重做日志.
用NOLOGGING时,好处在于创建时不用生成日志,这样表空间的创建较快,但是没能日志,数据丢失后,不能恢复,但是一般我们在创建表空间时,是没有数据的,按通常的做法,是建完表空间,并导入数据后,是要对数据做备份的,所以通常不需要表空间的创建日志,因此,在创建表空间时,选择 NOLOGGING,以加快表空间的创建速度.
第三: DATAFILE 用于指定数据文件的具体位置和大小.
如: DATAFILE 'D:\ORACLE\ORADATA\ORA92\LUNTAN.ora' SIZE 5M
说明文件的存放位置是 'D:\ORACLE\ORADATA\ORA92\LUNTAN.ora' , 文件的大小为5M.
如果有多个文件,可以用逗号隔开:
DATAFILE 'D:\ORACLE\ORADATA\ORA92\LUNTAN.ora' SIZE 5M,
'D:\ORACLE\ORADATA\ORA92\dd.ora' SIZE 5M
但是每个文件都需要指明大小.单位以指定的单位为准如 5M 或 500K.
对具体的文件,可以根据不同的需要,存放大不同的介质上,如磁盘阵列,以减少IO竟争.
指定文件名时,必须为绝对地址,不能使用相对地址.
第四: EXTENT MANAGEMENT LOCAL 存储区管理方法
在Oracle 8i以前,可以有两种选择,一种是在字典中管理(DICTIONARY),另一种是本地管理(LOCAL ),从9I开始,只能是本地管理方式.因为LOCAL 管理方式有很多优点.
在字典中管理(DICTIONARY): 将数据文件中的每一个存储单元做为一条记录,所以在做DM操作时,就会产生大量的对这个管理表的Delete和Update操作.做大量数据管理时,将会产生很多的DM操作,严重影响性能,同时,长时间对表数据的操作,会产生很多的磁盘碎片,这就是为什么要做磁盘整理的原因.
本地管理(LOCAL): 用二进制的方式管理磁盘,有很高的效率,同进能最大限度的使用磁盘. 同时能够自动跟踪记录临近空闲空间的情况,避免进行空闲区的合并操作。
第五: SEGMENT SPACE MANAGEMENT
磁盘扩展管理方法:
SEGMENT SPACE MANAGEMENT: 使用该选项时区大小由系统自动确定。由于 Oracle 可确定各区的最佳大小,所以区大小是可变的。
UNIFORM SEGMENT SPACE MANAGEMENT:指定区大小,也可使用默认值 (1 MB)。
第六: 段空间的管理方式:
AUTO: 只能使用在本地管理的表空间中. 使用LOCAL管理表空间时,数据块中的空闲空间增加或减少后,其新状态都会在位图中反映出来。位图使 Oracle 管理空闲空间的行为更加自动化,并为管理空闲空间提供了更好的性,但对含有LOB字段的表不能自动管理.
MANUAL: 目前已不用,主要是为向后兼容.

第七: 指定块大小. 可以具体指定表空间数据块的大小.


创建例子如下:
1 CREATE TABLESPACE "SAMPLE"
2 LOGGING
3 DATAFILE 'D:\ORACLE\ORADATA\ORA92\SAMPLE.ora' SIZE 5M,
4 'D:\ORACLE\ORADATA\ORA92\dd.ora' SIZE 5M
5 EXTENT MANAGEMENT LOCAL
6 UNIFORM SEGMENT SPACE MANAGEMENT
7* AUTO
SQL> /

表空间已创建。

要删除表空间进,可以

SQL> DROP TABLESPACE SAMPLE;

表空间已丢弃。