LIUBINGLIN

很多时候不在于你技术有多高,更重要的是你够不够细心、耐心和静心。

  • 博客访问: 5092536
  • 博文数量: 493
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-05 23:06
  • 认证徽章:
个人简介

Oracle数据库管理员,Oracle数据库系统构架员;2012年7月出版《构建最高可用Oracle数据库系统:Oracle 11gR2 RAC管理、维护与性能优化》一书;Oracle 10g OCM。

文章分类

全部博文(493)

分类: Linux

2013-11-21 10:25:31


    在以往的实施中,如果客户没有购买第三方备份软件,通常就使用系统级别的调度器调度数据库备份脚本实现数据库的自动化备份。Linux、AIX平台使用crontab,Windows平台使用管理工具下的计划任务,但这里会存在一个问题,现在的数据库很少运行一台独立的服务器上,要么运行在HA环境下,要么是RAC数据库,如果只是某一台服务器上部署备份计划,当这台服务器上的实例被切换或出现故障后,那么备份就可能被中断;如果在多台服务器都部署上备份计划,会出现重复备份等情况。

    解决这个问题的最简单方法就是使用Oracle数据库自身的调度计划,从10g之后推荐使用DBMS_SCHEDULER包实施调度,当然也可以使用早期的DBMS_JOBS包完成这个工作。

    下面的例子将演示如何使用DBMS_SCHEDULER包调度存储在操作系统的shell脚本,我们在实际的部署中可以将这里的shell脚本替换成备份脚本。


1.数据库版本:
SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bi
PL/SQL Release 10.2.0.1.0 - Production
CORE    10.2.0.1.0      Production
TNS for Linux: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production

2.创建PROGRAM:
SQL> exec dbms_scheduler.create_program( -
> program_name=>'backup_level0', -
> program_type=>'EXECUTABLE', -
> program_action=>'/home/oracle1/backup_level0.sh', -
> enabled=>true, -
> comments=>'oracle database rman level 0 backup');

PL/SQL procedure successfully completed.

3.创建SCHEDULE:
SQL> exec dbms_scheduler.create_schedule( -
> schedule_name=>'bl0s', -
> repeat_interval=>'FREQ=MINUTELY; INTERVAL=0;', -
> comments=>'oracle database rman level 0 backup schedule 1');

PL/SQL procedure successfully completed.

4.创建JOB:
SQL> exec dbms_scheduler.create_job( -
> job_name=>'backup0', -
> program_name=>'backup_level0', -
> schedule_name=>'bl0s', -
> enabled=>true);

PL/SQL procedure successfully completed.

5.测试JOB:
SQL> exec dbms_scheduler.run_job(job_name=>'backup0');

PL/SQL procedure successfully completed.

6.SHELL脚本内容:
[oracle1@redhat5 ~]$ more backup_level0.sh 
#!/bin/sh
/bin/echo `date` >> /tmp/rman_level0.log

    注意:shell脚本的最开始一定要加上#!/bin/sh,在使用命令的时候最好写上全路径,如果是备份脚本还应该定义ORACLE_SID、ORACLE_HOME、ORACLE_BASE环境变量。

7.自动JOB创建成功之后,跟踪/tmp/rman_level0.log日志:
[oracle1@redhat5 tmp]$ tail -f rman_level0.log
Tue Nov 19 14:51:04 CST 2013
Tue Nov 19 14:55:01 CST 2013
Tue Nov 19 14:55:22 CST 2013
Tue Nov 19 14:56:22 CST 2013
Tue Nov 19 14:57:22 CST 2013
Tue Nov 19 14:58:22 CST 2013
Tue Nov 19 14:59:22 CST 2013
Tue Nov 19 15:00:22 CST 2013

    Oracle JOB每分钟执行一次backup_level0.sh脚本。

    对于HA数据库来说,只需要在两台服务器上的相同位置放上同样的shell脚本,不管数据库实例在哪台服务器上运行,备份脚本都会被成功调度,备份的内容会被放置在相同位置的共享存储下。

    对于RAC数据库而言,我会产生这样的疑问,RAC的所有数据库实例是并行工作的,部署在两台服务器相同位置的shell脚本是由哪台服务器实例调度的呢?如何控制JOB在哪个实例运行呢?又如何让Oracle根据服务器的负载自动选择运行实例呢?

    简单的说,对于使用DBMS_SCHEDULER产生的调度来说,是通过JOB关联JOB_CLASS,JOB_CLASS关联Service来控制的,Service有自己的首选实例和备用实例,相关联的JOB默认会由关联Service的首选实例调度,当首选实例出现问题,JOB会由备用实例调度。如果JOB没有跟任何JOB_CLASS关联,这样的JOB是和默认的Service关联,默认的Service具有负载均衡的功能,所以这种情况下的JOB会随机的被RAC实例调度,默认是根据服务器资源消耗情况进行分配,且始终会被资源消耗更低的服务器实例调度。更详细的原理请参考如下文章:
http://www.remote-dba.net/t_advanced_job_services_instance_stickiness.htm

    如果使用DBMS_JOB包调度操作系统shell脚本的执行,那么在DBMS_JOB.SUBMIT中有个INSTNACE参数:
    DBMS_JOB.SUBMIT ( 
    job       OUT BINARY_INTEGER,
    what      IN  VARCHAR2,
    next_date IN  DATE DEFAULT sysdate,
    interval  IN  VARCHAR2 DEFAULT 'null',
    no_parse  IN  BOOLEAN DEFAULT FALSE,
    instance  IN  BINARY_INTEGER DEFAULT any_instance,
    force     IN  BOOLEAN DEFAULT FALSE);

   instance参数的含义是:When a job is submitted, specifies which instance can run the job.
   可以为instance参数指定运行实例的实例号,JOB只会在指定的实例运行,即使出现故障也不会在其他实例运行。instance本身具有默认值,默认可能在任何实例运行,节点出现故障会在另外的节点运行此JOB。对于HA环境下的数据库该参数是没有意义的,对于RAC而言,推荐也不设置该参数,这样的JOB才能在节点出现故障的时候被failover。

--end--


阅读(7869) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册