星期三 十月 23, 2013

Oracle 11g 新特性 – HM(Hang Manager)简介


在这篇文章中我们会对oracle 11g 新特性—hang 管理器(Hang Manager) 进行介绍。我们需要说明,HM 只在RAC 数据库中存在。



在我们诊断数据库问题的时候,经常会遇到一些数据库/进程 hang住的问题。对于hang的问题,一般来说,常见的原因有以下两种。


死锁(cycle)。对于这种hang, 除非循环被打破,问题会永远存在。


某个堵塞者(blocker) 进程在持有了某些资源后堵住了其他进程。当然,根据堵塞的情况,我们可以把blocker
分为直接堵塞进程(immediate blocker)和根堵塞进程(root blocker)。而root blocker 在通常情况下会处于两种状态。


2.1 根堵塞进程处于空闲状态,对于这种情况,终止这个进程能够解决问题。


2.2 根堵塞进程正在等待某些和数据库无关的资源(例如:等待I/O),对于这种情况,终止这个进程也许能解决问题。但是,从数据库的角度来讲,这已经超出了数据库的范畴。



而从数据库的角度来讲, oracle有几种死锁的发现机制。 在这篇文章中我们会介绍11g RAC的新特性 hang管理器。hang 管理器的基本步骤是。


1.分配一部分内存空间用于存放hang analyze dump 信息。


2.定期搜集hang analyze dump信息(本地和全局)


3. 分析搜集到的dump信息,并确认系统中是否存在hang


4. 利用分析的结果来解决hang问题。



接下来,我们对每个步骤进行具体的介绍。


步骤1: ORACLE 会分配一部分内存空间,我们称之为 hang analysis
cache
,用来存放搜集的hang analyze dump i信息。这部分内存空间在每个节点的数据库实例上都存在。


步骤2oracle 会定期搜集hang
analyze
信息,由于,HM特性是针对RAC数据库的特性,hang analyze的级别会包括本地和全局。另外,负责搜集这些dump 信息的后台进程是DIA0(这个进程从11g才被介绍)。默认情况下每3秒钟搜集本地级别hang analyze dump, 10 秒搜集全局级别hang analyze dump


步骤3:因为,每个节点都会搜集hang
analyze dump
信息,那么,意味着每个实例都会拥有自己的DIA0进程,负责完成本地的hang 分析。但是,对于RAC数据库,很多hang的情况会包含多个实例的进程。所以,我们需要一个实例上的DIA0 进程作为master,来对多个实例搜集到的信息进行分析。对于11g版本,节点号最小的实例的DIA0进程会成为HMmaster进程。当然,在实例级别发生了重新配置后,主(masterDIA0 进程会重新在存在的实例中重新被选举出来。



对于hang的问题,HM采用以下的机制来进行检测,当HM分析过几个hang analyze dump(每30秒进行一次分析,至少经过三次分析)后,就会发现有一些进程之间存在着等待关系(我们可以称之为open chain),而且在这段时间之内没有任何的改变(例如,一直等待相同的等待事件),那么,我们就可以怀疑,这些进程之间出现了hang的情况。而在进一步的验证之后,的确发现这些进程之间存在着等待关系,那么就会找到这个等待链(open chain)的根阻塞进程,并尝试通过终止阻塞进程的方式来解决这个hang.当然,对于死锁(dead lock)这种情况,我们采用的方式是,终止等待环中的一个进程。下面的图形说明了以上的基本逻辑。




步骤4: 在确认hang的确发生之后,根据hang的类型选择对应的解决方案。对于HM 来说,如果这个hang线管的进程满足以下条件之一,那么HM就无法解决这个hang.


1. 除数据库以外的其他层面的进程也和这个hang相关,例如:asm实例的进程。


2. 是由于用户应用层面导致的,例如:TX锁。


3. 并行查询


4. 需要用户手动干预。例如:阻塞进程在等待“log file switch ”(这种等待很可能是由于归档目录对应的filesystem空间不足导致的。即使HM中知道了阻塞进程,hang的情况也无法得到解决)。



如果,hangHM无法解决的类型,那么HM会继续跟踪这个问题。
而对于HM能够解决的问题,其解决的办法就是终止根阻塞进程。但是,如果这个阻塞进程是oracle 的主要后台进程,终止它就会导致实例crash。所以,HM在解决hang的时候,也存在解决范围。这个范围是由隐含参数"_hang_resolution_scope" 控制的,这个参数可以有三个值off(默认值,也就是说HM不会去解决hang)process(允许HM终止阻塞进程,如果该进程不是主要的后台进程),instance(允许HM终止阻塞进程,即使该进程是主要的后台进程。终止该进程会导致实例终止)。



最后,我们对和HM 相关的一些参数和trace 文件进行简单的介绍。


参数:


_hang_resolution=TRUE 或者 FALSE。这个参数用于控制HM是否解决hang


_hang_resolution_scope=OFF,PORCESS或者 INSTANCE。这个参数用于控制HM解决问题的范围。


_hang_detection= <number> HM检测hang的时间间隔,默认值为30(秒)。



参与此主题的后续讨论,可以访问我们的中文社区,跟帖“Oracle 11g 新特性 – HM(Hang Manager)简介"

星期四 五月 03, 2012

11g 新特性—— Active Database Duplication for A standby database

简介
------------
从11G开始oracle提供了一个新功能Active Database Duplication for A standby database来创建配置物理standby 数据库。
Active Database Duplication for A standby database这个功能主要从一个正在运行的数据库复制数据文件,控制文件等到一个物理备库(physical standby database)。
这个功能简化了创建standby database过程中在主库备份和备库恢复的环节,实现了自动拷贝主库的控制文件,数据文件等到备库,对比基于备份集的创建standby database过程中需要手动在主库备份,然后将备份集拷贝到备库再手动恢复来说,减少了dba的大量工作。

创建物理standby database过程中的其他环节,如打开主库的force logging,主库init参数的修改等,以及备库开始应用redo log这些环节还需手动来完成的,与以往的创建配置物理standby database 是相同的。

备库的init参数需要在duplicate命令中指定,没有特殊指定的,就会默认使用主库的init参数值。

下面以一个测试例子来具体说明
-----------------------------------
主库:11.2.0.1 单机数据库,db_unique_name=orcl,数据文件存放在文件系统
备库:11.2.0.1 单机数据库,db_unique_name=orabak,使用ASM存储
Data Guard保护模式(Protection mode)采用最大性能模式(MAXIMIZE PERFORMANCE)
redo log传输采用LGWR进程的异步传输方式

1. 打开主库force logging:
SQL>  ALTER DATABASE FORCE LOGGING;

查看主库当前是否为force logging:
SQL> select force_logging from v$database;
FOR
---
YES

2. 修改主库的初始化参数如下:
LOG_ARCHIVE_CONFIG='DG_CONFIG=(orcl,orabak)'
LOG_ARCHIVE_DEST_1=
  'LOCATION=/home/oracle/app/archdir
  VALID_FOR=(ONLINE_LOGFILE,PRIMARY_ROLE)
  DB_UNIQUE_NAME=orcl'
LOG_ARCHIVE_DEST_2=
  'SERVICE=orabak LGWR ASYNC
   VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE)   
   DB_UNIQUE_NAME=orabak'
LOG_ARCHIVE_DEST_STATE_1=ENABLE
LOG_ARCHIVE_DEST_STATE_2=ENABLE
REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE
LOG_ARCHIVE_MAX_PROCESSES=10

3. 在备库创建ASM 磁盘组 '+DATA',用来存放备库的数据文件,控制文件,standby redo文件等。

4. 在备库创建 adump 路径,与参数audit_file_dest的路径一致
$ mkdir -p /u01/app/admin/orabak/adump

5. 在备库创建init参数文件$ORACLE_HOME/dbs/initorabak.ora',
有了这个临时的init参数文件,我们就可以在duplicate命令运行前将备库的AUXILIARY实例启动到nomount状态,这也是运行duplicate命令的一个必要条件。

initorabak.ora文件只有一行信息:
DB_NAME=orcl

6. 将密码文件从主库服务器拷贝到备库服务器,并且重命名:
$ mv orapworcl orapworabak

7. 在主库服务器和备库服务器, 编辑添加下面信息到$ORACLE_HOME/network/tnsnames.ora
orabak =
 (DESCRIPTION =
   (ADDRESS_LIST =
     (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.113)(PORT = 1521))
   )
   (CONNECT_DATA =
     (SERVICE_NAME = orabak)
   ))

orcl =
 (DESCRIPTION =
   (ADDRESS_LIST =
     (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.112)(PORT = 1521))
   )
   (CONNECT_DATA =
     (SERVICE_NAME = orcl)
   ))

8. 在备库服务器, 添加静态注册信息到 $GRID_HOME/network/listener.ora文件,
这主要是由于AUXILIARY实例启动到nomount状态时,listener无法注册AUXILIARY实例,listener会标志Auxiliary实例为'blocked'状态,因此duplicate命令就无法通过TNS的方式连接到Auxiliary实例,为了解决这个问题,需要先手动静态注册数据库实例到listener上。
当Data Guard配置完成后,就可以删除静态注册的配置信息。
(本测试使用ASM,因此需要安装GRID,有效的listener.ora文件是在GRID_HOME下面)

LISTENER =
 (DESCRIPTION_LIST =
   (DESCRIPTION =
     (ADDRESS = (PROTOCOL = IPC)(KEY = ANYTHING))
     (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.113)(PORT = 1521))
   ) )

SID_LIST_LISTENER =
 (SID_LIST =
   (SID_DESC =
     (GLOBAL_DBNAME = orabak)
     (ORACLE_HOME = /home/oracle/app/product/11.2)
     (SID_NAME = orabak)
   ) )

9. 在备库服务器,执行duplicate命令前,先启动AUXILIARY实例到 nomount 状态:
$ export ORACLE_SID=orabak
$ sqlplus / as sysdba
SQL> startup nomount;

10. 在备库测试与AUXILIARY实例的连接和与主库的连接,如果连接成功,继续执行下面的步骤,
很多时候duplicate命令失败都是由于连接失败导致的。
$ sqlplus sys/oracle@orabak as sysdba
$ sqlplus sys/oracle@orcl as sysdba


11. 创建备库
在duplicate命令中指定关键字'FOR STANDBY'和'FROM ACTIVE DATABASE'表示从一个active的数据库来复制创建物理备库
参数'DORECOVER'表示duplicate命令会执行recover动作,否则duplicate命令只执行restore,
备库与主库不同的初始化参数,需要在duplicate命令中特殊指定,这样创建备库的spfile时就会用指定的值替换主库的参数值,
主库与备库的数据文件的路径不同,因此设置参数'DB_FILE_NAME_CONVERT'

% rman target sys/oracle@orcl AUXILIARY SYS/oracle@orabak
RMAN>
DUPLICATE TARGET DATABASE
FOR STANDBY
FROM ACTIVE DATABASE
DORECOVER
SPFILE
SET "db_unique_name"="orabak"
SET FAL_SERVER="orcl"
SET LOG_ARCHIVE_DEST_1='LOCATION=/u01/app/archdir_sbredo
                       VALID_FOR=(STANDBY_LOGFILE,STANDBY_ROLE) DB_UNIQUE_NAME=orabak'
SET CONTROL_FILES '+DATA/orabak/control01.ctl'
set diagnostic_dest='/u01/app'
set audit_file_dest='/u01/app/admin/orabak/adump'
set DB_FILE_NAME_CONVERT='/home/oracle/app/oradata/orcl','+DATA/orabak/datafile'
NOFILENAMECHECK;


以下是duplicate standby database过程中屏幕的log信息
-----------------------------------------------------
Starting Duplicate Db at 15-APR-12
using target database control file instead of recovery catalog
allocated channel: ORA_AUX_DISK_1
channel ORA_AUX_DISK_1: SID=19 device type=DISK

contents of Memory Script:

{
   backup as copy reuse
   targetfile  '/home/oracle/app/product/11.2/dbs/orapworcl' auxiliary format
 '/u01/app/product/11.2/dbs/orapworabak'   targetfile
 '/home/oracle/app/product/11.2/dbs/spfileorcl.ora' auxiliary format
 '/u01/app/product/11.2/dbs/spfileorabak.ora'   ;
   sql clone "alter system set spfile= ''/u01/app/product/11.2/dbs/spfileorabak.ora''";
}
executing Memory Script

Starting backup at 15-APR-12
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=38 device type=DISK
Finished backup at 15-APR-12

sql statement: alter system set spfile= ''/u01/app/product/11.2/dbs/spfileorabak.ora''

contents of Memory Script:
{
   sql clone "alter system set  db_unique_name =
 ''orabak'' comment=
 '''' scope=spfile";
   sql clone "alter system set  FAL_SERVER =
 ''orcl'' comment=
 '''' scope=spfile";
   sql clone "alter system set  LOG_ARCHIVE_DEST_1 =
 ''LOCATION=/u01/app/archdir_sbredo                       VALID_FOR=(STANDBY_LOGFILE,STANDBY_ROLE) DB_UNIQUE_NAME=orabak'' comment=
 '''' scope=spfile";
   sql clone "alter system set  CONTROL_FILES =
 ''+DATA/orabak/control01.ctl'' comment=
 '''' scope=spfile";
   sql clone "alter system set  diagnostic_dest =
 ''/u01/app'' comment=
 '''' scope=spfile";
   sql clone "alter system set  audit_file_dest =
 ''/u01/app/admin/orabak/adump'' comment=
 '''' scope=spfile";
   sql clone "alter system set  db_file_name_convert =
 ''/home/oracle/app/oradata/orcl'', ''+DATA/orabak/datafile'' comment=
 '''' scope=spfile";
   shutdown clone immediate;
   startup clone nomount;
}
executing Memory Script

sql statement: alter system set  db_unique_name =  ''orabak'' comment= '''' scope=spfile

sql statement: alter system set  FAL_SERVER =  ''orcl'' comment= '''' scope=spfile

sql statement: alter system set  LOG_ARCHIVE_DEST_1 =  ''LOCATION=/u01/app/archdir_sbredo                       VALID_FOR=(STANDBY_LOGFILE,STANDBY_ROLE) DB_UNIQUE_NAME=orabak'' comment= '''' scope=spfile

sql statement: alter system set  CONTROL_FILES =  ''+DATA/orabak/control01.ctl'' comment= '''' scope=spfile

sql statement: alter system set  diagnostic_dest =  ''/u01/app'' comment= '''' scope=spfile

sql statement: alter system set  audit_file_dest =  ''/u01/app/admin/orabak/adump'' comment= '''' scope=spfile

sql statement: alter system set  db_file_name_convert =  ''/home/oracle/app/oradata/orcl'', ''+DATA/orabak/datafile'' comment= '''' scope=spfile

Oracle instance shut down

connected to auxiliary database (not started)
Oracle instance started

Total System Global Area     238530560 bytes

Fixed Size                     1335724 bytes
Variable Size                 83889748 bytes
Database Buffers             150994944 bytes
Redo Buffers                   2310144 bytes

contents of Memory Script:
{
   backup as copy current controlfile for standby auxiliary format  '+DATA/orabak/control01.ctl';
}
executing Memory Script

Starting backup at 15-APR-12
using channel ORA_DISK_1
channel ORA_DISK_1: starting datafile copy
copying standby control file
output file name=/home/oracle/app/product/11.2/dbs/snapcf_orcl.f tag=TAG20120415T185859 RECID=8 STAMP=780692341
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:10
Finished backup at 15-APR-12

contents of Memory Script:
{
   sql clone 'alter database mount standby database';
}
executing Memory Script

sql statement: alter database mount standby database

contents of Memory Script:
{
   set newname for tempfile  1 to
 "+DATA/orabak/datafile/temp01.dbf";
   switch clone tempfile all;
   set newname for datafile  1 to
 "+DATA/orabak/datafile/system01.dbf";
   set newname for datafile  2 to
 "+DATA/orabak/datafile/sysaux01.dbf";
   set newname for datafile  3 to
 "+DATA/orabak/datafile/undotbs01.dbf";
   set newname for datafile  4 to
 "+DATA/orabak/datafile/users01.dbf";
   backup as copy reuse
   datafile  1 auxiliary format
 "+DATA/orabak/datafile/system01.dbf"   datafile
 2 auxiliary format
 "+DATA/orabak/datafile/sysaux01.dbf"   datafile
 3 auxiliary format
 "+DATA/orabak/datafile/undotbs01.dbf"   datafile
 4 auxiliary format
 "+DATA/orabak/datafile/users01.dbf"   ;
   sql 'alter system archive log current';
}
executing Memory Script

executing command: SET NEWNAME

renamed tempfile 1 to +DATA/orabak/datafile/temp01.dbf in control file

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

Starting backup at 15-APR-12
using channel ORA_DISK_1
channel ORA_DISK_1: starting datafile copy
input datafile file number=00001 name=/home/oracle/app/oradata/orcl/system01.dbf
output file name=+DATA/orabak/datafile/system01.dbf tag=TAG20120415T185922
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:24
channel ORA_DISK_1: starting datafile copy
input datafile file number=00003 name=/home/oracle/app/oradata/orcl/undotbs01.dbf
output file name=+DATA/orabak/datafile/undotbs01.dbf tag=TAG20120415T185922
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:13
channel ORA_DISK_1: starting datafile copy
input datafile file number=00002 name=/home/oracle/app/oradata/orcl/sysaux01.dbf
output file name=+DATA/orabak/datafile/sysaux01.dbf tag=TAG20120415T185922
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:13
channel ORA_DISK_1: starting datafile copy
input datafile file number=00004 name=/home/oracle/app/oradata/orcl/users01.dbf
output file name=+DATA/orabak/datafile/users01.dbf tag=TAG20120415T185922
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:01
Finished backup at 15-APR-12

sql statement: alter system archive log current

contents of Memory Script:
{
   backup as copy reuse
   archivelog like  "/home/oracle/app/archdir/1_46_778869623.dbf" auxiliary format
 "/u01/app/archdir_sbredo/1_46_778869623.dbf"   archivelog like
 "/home/oracle/app/archdir/1_47_778869623.dbf" auxiliary format
 "/u01/app/archdir_sbredo/1_47_778869623.dbf"   ;
   catalog clone archivelog  "/u01/app/archdir_sbredo/1_46_778869623.dbf";
   catalog clone archivelog  "/u01/app/archdir_sbredo/1_47_778869623.dbf";
   switch clone datafile all;
}
executing Memory Script

Starting backup at 15-APR-12
using channel ORA_DISK_1
channel ORA_DISK_1: starting archived log copy
input archived log thread=1 sequence=46 RECID=45 STAMP=780692365
output file name=/u01/app/archdir_sbredo/1_46_778869623.dbf RECID=0 STAMP=0
channel ORA_DISK_1: archived log copy complete, elapsed time: 00:00:01
channel ORA_DISK_1: starting archived log copy
input archived log thread=1 sequence=47 RECID=46 STAMP=780692416
output file name=/u01/app/archdir_sbredo/1_47_778869623.dbf RECID=0 STAMP=0
channel ORA_DISK_1: archived log copy complete, elapsed time: 00:00:01
Finished backup at 15-APR-12

cataloged archived log
archived log file name=/u01/app/archdir_sbredo/1_46_778869623.dbf RECID=1 STAMP=780696505

cataloged archived log
archived log file name=/u01/app/archdir_sbredo/1_47_778869623.dbf RECID=2 STAMP=780696505

datafile 1 switched to datafile copy
input datafile copy RECID=8 STAMP=780696506 file name=+DATA/orabak/datafile/system01.dbf
datafile 2 switched to datafile copy
input datafile copy RECID=9 STAMP=780696506 file name=+DATA/orabak/datafile/sysaux01.dbf
datafile 3 switched to datafile copy
input datafile copy RECID=10 STAMP=780696506 file name=+DATA/orabak/datafile/undotbs01.dbf
datafile 4 switched to datafile copy
input datafile copy RECID=11 STAMP=780696506 file name=+DATA/orabak/datafile/users01.dbf

contents of Memory Script:
{
   set until scn  303787;
   recover
   standby
   clone database
    delete archivelog
   ;
}
executing Memory Script

executing command: SET until clause

Starting recover at 15-APR-12
allocated channel: ORA_AUX_DISK_1
channel ORA_AUX_DISK_1: SID=25 device type=DISK

starting media recovery

archived log for thread 1 with sequence 46 is already on disk as file /u01/app/archdir_sbredo/1_46_778869623.dbf
archived log for thread 1 with sequence 47 is already on disk as file /u01/app/archdir_sbredo/1_47_778869623.dbf
archived log file name=/u01/app/archdir_sbredo/1_46_778869623.dbf thread=1 sequence=46
archived log file name=/u01/app/archdir_sbredo/1_47_778869623.dbf thread=1 sequence=47
media recovery complete, elapsed time: 00:00:01
Finished recover at 15-APR-12


ORACLE error from auxiliary database: ORA-19527: physical standby redo log must be renamed
ORA-00312: online log 1 thread 1: '/home/oracle/app/oradata/orcl/redo01.log'

RMAN-05535: WARNING: All redo log files were not defined properly.
ORACLE error from auxiliary database: ORA-19527: physical standby redo log must be renamed
ORA-00312: online log 2 thread 1: '/home/oracle/app/oradata/orcl/redo02.log'

RMAN-05535: WARNING: All redo log files were not defined properly.
ORACLE error from auxiliary database: ORA-19527: physical standby redo log must be renamed
ORA-00312: online log 3 thread 1: '/home/oracle/app/oradata/orcl/redo03.log'


RMAN-05535: WARNING: All redo log files were not defined properly.
Finished Duplicate Db at 15-APR-12
---------------------------------------------------------------

以上创建完成了物理standby数据库(最后的错误警告信息可以忽略,我们在后面的附录1详细解释这个错误信息)。但是备库数据库还没有开始应用redo log。

12. 创建standby redo log,standby redo log大小等于主库online redo log大小:
ALTER DATABASE ADD STANDBY LOGFILE GROUP 11
   ('+data/redo_sb_01.log') SIZE 52428800;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 12
   ('+data/redo_sb_02.log') SIZE 52428800;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 13
   ('+data/redo_sb_03.log') SIZE 52428800;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 14
   ('+data/redo_sb_04.log') SIZE 52428800;

13. 运行下面的命令开始应用redo log:
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;


以上的全部步骤就配置完成了物理standby数据库,并且开始应用redo log。

附录1
----------
在创建备库时最后报出的错误警告信息ORA-19527和在MRP开始应用redo log时,alert log中报出下面的错误信息:

Errors in file /u01/app/diag/rdbms/orabak/orabak/trace/orabak_mrp0_7644.trc:
ORA-00313: open failed for members of log group 1 of thread 1
ORA-00312: online log 1 thread 1: '/home/oracle/app/oradata/orcl/redo01.log'
ORA-27037: unable to obtain file status
Linux Error: 2: No such file or directory
.....
Errors in file /u01/app/diag/rdbms/orabak/orabak/trace/orabak_mrp0_7644.trc:
ORA-19527: physical standby redo log must be renamed
ORA-00312: online log 1 thread 1: '/home/oracle/app/oradata/orcl/redo01.log'

以上错误的原因:
oracle为了加快备库与主库switchover的速度,从10.2开始增加了一个增强的功能,就是当MRP启动时会去清理备库上online redo log。造成以上2个错误有2个原因,第一个是备库没有创建online redo log,第二个是备库没有设置log_file_name_convert参数。

解决方法:
方法#1:如果不考虑switchover(备库上不创建online reod log),那么可以忽略这个错误,因为这个错只是一个提示性的信息,不会影响备库的MRP的工作。
方法#2:如果考虑switchover,在备库上创建online reod log,并且设置log_file_name_convert参数:
SQL> shutdown immediate;
SQL> startup mount;
SQL> ALTER DATABASE ADD LOGFILE GROUP 4 ('+DATA/redo01.log') SIZE 52428800;
SQL> ALTER DATABASE ADD LOGFILE GROUP 5 ('+DATA/redo02.log') SIZE 52428800;
SQL> ALTER DATABASE ADD LOGFILE GROUP 6 ('+DATA/redo03.log') SIZE 52428800;
SQL> alter system set log_file_name_convert='/home/oracle/app/oradata/orcl','+data' scope=spfile;
SQL> shutdown immediate;
SQL> startup mount;
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;


11g 新特性 Member Kill Escalation 简介


    首先我们介绍一下历史。在oracle 9i/10g 中,如果一个数据库实例需要驱逐(evict, alert 文件中会出现ora-29740错误)另一个实例时,需要通过LMON进程在控制文件(以下简称CF)中写入相应信息,当目标实例的LMON进程读取到相应的信息后,该实例shudown。但是,如果目标实例的LMON进程挂起而无法完成CF I/O的话,eviction将无法成功,这种情况有可能导致整个数据库挂起,需要dba手工干预。
    所以,从oracle 11gR1 开始,Member Kill Escalation的出现成功的解决了前面提到的情况。当实例eviction在指定的时间内(默认20秒)不能成功完成时,oracle会在css层面上(因为lmon进程会作为成员注册到css上,相应的内容会在今后的文章中介绍)产生一个新的进程 Kill Daemon(以下简称KD), 终止目标实例的LMON进程以保证eviction 能够成功结束。如果情况更糟,KD进程也无法在指定的时间内(默认30秒)终止LMON进程,css 会把member kill升级为node kill,目标节点的css会重新启动本节点,以确保数据库的一致性。当然,如果您的版本是11.2.0.2或更高,由于新特性Rebootless restart的引入,node kill首先会尝试重新启动GI stack,如果不能够完成,才会重新启动节点。
    接下来我们用下面的例子说明Member Kill Escalation是如何工作的。
1.实例2发现实例1的LMS1进程出现问题,并发出member kill request.
实例2 Alert log:
Sat Jul 24 10:37:37 2010
LMS1 (ospid: 22636) has detected no messaging activity from instance 1
LMS1 (ospid: 22636) issues an IMR to resolve the situation
Please check LMS1 trace file for more detail.
Sat Jul 24 10:37:37 2010 <======= 实例2发出reconfiguration请求
Communications reconfiguration: instance_number 1
Sat Jul 24 10:38:25 2010
Evicting instance 1 from cluster
Waiting for instances to leave:
1
Sat Jul 24 10:38:45 2010 <===== 在reconfiguration请求发出20秒之后实例1仍然没有离开集群,实例2发出了member kill的请求。
Remote instance kill is issued with system inc 10
Remote instance kill map (size 1) : 1
Sat Jul 24 10:38:55 2010
Waiting for instances to leave:
1

2. 节点2的ocssd.bin收到member kill请求之后,向节点1的KD发出了请求,要求终止节点1的lmon进程。
节点2 ocssd.log:
2010-07-24 10:38:45.112: [    CSSD][1091119424]clssgmExecuteClientRequest: Member kill request from client (0x2aaab4178470)
2010-07-24 10:38:45.113: [    CSSD][1091119424]clssgmReqMemberKill: Kill requested map 0x00000001 flags 0x2 escalate 0xffffffff <========= member kill escalation还没有发生。
2010-07-24 10:38:45.113: [    CSSD][1281349952]clssgmMbrKillThread: Kill requested map 0x00000001 id 2 Group name DBOR08P flags 0x00000001 start time 0x98117058 end time 0x9811e77c time out 30500 req node 2 <======= member kill 需要在30秒内完成。

如果节点1能够在指定的时间内(30秒)终止本地lmon进程,member kill 就不会被escalation 成为node kill。

3.由于member kill 没有在指定的时间内完成,被escalate 为node kill,即节点1 重启。
节点2 ocssd.log:
2010-07-24 10:39:15.619: [    CSSD][1281349952]clssgmMbrKillThread: Time up: Start time -1743687592 End time -1743657092 Current time -1743657092 timeout 30500
2010-07-24 10:39:15.619: [    CSSD][1281349952]clssgmMbrKillThread: Member kill request complete.
2010-07-24 10:39:15.619: [    CSSD][1281349952]clssgmMbrKillSendEvent: Missing answers or immediate escalation: Req member 1 Req node 2 Number of answers expected 0 Number of answers outstanding 1
2010-07-24 10:39:15.620: [    CSSD][1281349952]clssgmMbrKillEsc: Escalating node 1 Member request 0x00000001 Member success 0x00000000 Member failure 0x00000000 Number left to kill 1
2010-07-24 10:39:15.620: [    CSSD][1281349952]clssnmKillNode: node 1 (ghlx062ptlge) kill initiated <====== 节点1被重启

注意:member kill escalation不仅适用于database 实例,同时也适用于ASM实例。

星期六 三月 31, 2012

11g 新特性:Active Data Guard

  在Oracle 11g之前,物理备库(physical Standby)在应用redo的时候,是不可以打开的,只可以mount。从11g开始,在应用redo的时候,物理备库可以处于read-only模式,这就称为Active Data Guard 。通过Active Data Guard,可以在物理备库进行查询或者导出数据,从而减少对主库的访问和压力。

   Active Data Guard适用于一些只读性的应用,比如,有的应用程序只是查询数据,进行一些报表业务,不会产生redo数据,这些应用可以转移到备库上,避免对主库资源的争用。


 Oracle Active Data Guard 是Oracle Database Enterprise Edition的一个功能,需要额外付费来使用这个功能。

   如需启用Active Data Guard, 只需要将备库以 read-only 模式打开,而且执行 ALTER DATABASE RECOVER MANAGED STANDBY DATABASE语句就可以。需要注意的是:主库和备库的COMPATIBLE 参数至少要设置为11.0.0。


   如下:在备库执行:  
   SQL>startup mount;
   SQL>alter database open read only;
   SQL>ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;


  如果已经启用了Active Data Guard,备库的V$DATABASE会显示为"READ ONLY WITH APPLY':

      SQL> SELECT open_mode FROM V$DATABASE;
      OPEN_MODE
      --------------------
      READ ONLY WITH APPLY


  注意:使用Active
Data Guard
要求主库和备库的COMPATIBLE 参数至少设置为11.0.0


  为了保证备库数据的实时性,需要在备库启动real-time apply:
   SQL>ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE;

  下面的功能是允许在read-only的数据库上执行的:
    • Issue SELECT statements, including queries that require multiple sorts that leverage TEMP
segments
    • Use ALTER SESSION and ALTER SYSTEM statements
    • Use SET ROLE
    • Call stored procedures
    • Use database links (dblinks) to write to remote databases
    • Use stored procedures to call remote procedures via dblinks
    • Use SET TRANSACTION READ ONLY for transaction level read consistency
    • Issue complex queries (such as grouping SET queries and WITH CLAUSE queries)

  下面的功能是不允许在read-only的数据库上执行的:
    • Any DMLs (excluding simple SELECT statements) or DDLs
    • Query accessing local sequences
    • DMLs to local temporary tables

    比较典型的Active Data Guard 分为:
  • 单实例的物理主库和单实例的物理备库
  • 主库为Oracle Real Application Clusters (Oracle RAC) ,备库为单实例
  • RAC主库和RAC备库

    Oracle Data Guard 的配置方法,,请参考下面的文档:


   * 单实例的物理主库和单实例的物理备库:
     http://docs.oracle.com/cd/B28359_01/server.111/b28294/create_ps.htm

  * 主库为Oracle Real Application Clusters (Oracle RAC) ,备库为单实例:
     http://www.oracle.com/technetwork/database/features/availability/maa-wp-10g-racprimarysingleinstance-131970.pdf

 * RAC 主库和RAC 备库:
   10g: http://www.oracle.com/technetwork/database/features/availability/maa-wp-10g-racprimaryracphysicalsta-131940.pdf
   11g: http://www.oracle.com/technetwork/database/features/availability/dataguard11g-rac-maa-1-134639.pdf

* 关于Active Data Guard的最佳实践经验,请参考文档:
    http://www.oracle.com/technetwork/database/features/availability/maa-wp-11gr1-activedataguard-1-128199.pdf


* 关于Oracle Maximum Availability Architecture Best Practices的更多文档,请参考:
   http://www.oracle.com/goto/maa


星期三 三月 07, 2012

11g 新特性—— Active Database Duplication

简介
---------
Active database duplication功能是从11g开始引入的一个新功能,它是对比以前版本中的基于备份集的复制数据库功能。

下面简单的回顾一下关于ORACLE Duplicate Database功能,Duplicate database可以按照用途分为2种,一种是duplicate database,第二种是duplicate standby database,本文主要介绍duplicate database功能,会在以后介绍duplicate standby database。

Duplicate Database又可以按照复制数据的来源不同分为2种方式:Active Database Duplication(从正在运行的数据库上复制数据)和Backup-based duplication(基于备份集的数据复制)

1. Backup-based duplication 又分为下面3中形式:
o 复制的过程不连接到源数据库,RMAN从Catalog 数据库取得备份信息。

o 复制的过程不连接到源数据库,也不连接到Catalog数据库,RMAN从已有的备份集取得备份信息。

o 复制的过程连接到源数据库,RMAN从源数据库的控制文件取得备份信息。

2. Active Database Duplication
这种复制数据库要求源数据库是open状态或者mount状态,复制的过程一定要连接到源数据库,RMAN直接从源库复制数据库到Duplication服务器,这种方式不需要提前备份源库。

Duplicate Database 特点
------------------------
1. 复制的Database会自动分配一个新的DBID,与源数据库的DBID不同,这样Duplicate数据库和源库可以注册到同一个catalog 数据库。
如果使用操作系统的命令来做异机复制恢复的话,新创建的数据库和源库是相同的DBID。

2. 复制的数据库可以是源库的一个完全镜像,也可以是源库的一个子集。

3. 复制的数据库和源库必须是相同的操作系统平台,我们认为同平台下的32-bit 和 64-bit是同一个平台,例如Linux IA (32-bit) 和Linux IA (64-bit),认为是相同的平台,可以实施duplicate 功能,但是最后一定要运行下面的脚本来转换PL/SQL:
ORACLE_HOME/rdbms/admin/utlirp.sql

Active Database Duplication 和 Backup-based duplication对比
-------------------------------------------------------------
Active database duplication 直接复制源数据库,通过网络传输数据库到复制服务器,因此复制时对源库有一定的压力,而且数据传输时对网络条件要求较高。简单的概括为:
Backup-based duplication :需要提前备份数据库,磁盘空间大小能够满足备份的需要。
Active Database Duplication 不需要提前备份,但在复制的过程中,对源库有一定的压力,需要一定的网络带宽。源数据库一定是规定模式。

Active Database Duplication 原理
-------------------------------------
1. 手动创建一个临时的pfile文件,pfile文件至少包括一个参数DB_NAME,然后启动到nomount状态。
2. RMAN从源库拷贝spfile文件到复制数据库上,并且修改spfile的名字。
3. RMAN从源库拷贝最新的control file到复制数据库,并且mount 复制数据库。
4. RMAN从源库拷贝datafile和必要的归档日志到复制数据库。
5. RMAN执行不完全的恢复。
6. RMAN创建新的control file,并且设置新的DBID。
7. 以RESETLOGS方式打开复制的database。

下面以一个测试例子来具体说明
------------------------------
source database    :11gR2 standalone db, db_name=orcl,  ip=192.168.1.112
duplicate database :11gR2 standalone db, db_name=dupdb, ip=192.168.1.113
source 和 duplicate database 使用相同的目录结构。
source 数据库必须是配置为归档模式。

1. 将密码文件从source服务器拷贝到duplicate服务器,并且重命名:
$ mv orapworcl orapwdupdb

2. 在duplicate服务器,创建init参数文件'initdupdb.ora',文件中添加一行信息:
DB_NAME=dupdb

3. 在duplicate服务器, 创建 adump 目录和数据文件所在的目录:
$ mkdir -p /home/oracle/app/admin/orcl/adump
$ mkdir -p /home/oracle/app/oradata

4. 在duplicate服务器和source服务器, 编辑添加下面信息到$ORACLE_HOME/network/tnsnames.ora
dupdb =
 (DESCRIPTION =
   (ADDRESS_LIST =
     (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.113)(PORT = 1521))
   )
   (CONNECT_DATA =
     (SERVICE_NAME = dupdb)
   ))


orcl =
 (DESCRIPTION =
   (ADDRESS_LIST =
     (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.112)(PORT = 1521))
   )
   (CONNECT_DATA =
     (SERVICE_NAME = orcl)
   ))


5. 在duplicate服务器, 编辑添加下面的信息到 $GRID_HOME/network/listener.ora文件(本测试是11.2数据库,并且安装了GRID,因此listener.ora文件是在GRID_HOME下面)

LISTENER =
 (DESCRIPTION_LIST =
   (DESCRIPTION =
     (ADDRESS = (PROTOCOL = IPC)(KEY = ANYTHING))
     (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.113)(PORT = 1521))
   ) )


SID_LIST_LISTENER =
 (SID_LIST =
   (SID_DESC =
     (GLOBAL_DBNAME = dupdb)
     (ORACLE_HOME = /home/oracle/app/product/11.2)
     (SID_NAME = dupdb)
   ) )

6. 在duplicate服务器,启动AUXILIARY实例到 nomount 状态:
$ export ORACLE_SID=dupdb
$ sqlplus / as sysdba
SQL> startup nomount pfile='/home/oracle/app/product/11.2/dbs/initdupdb.ora'

7. 测试 connetion:
$ sqlplus sys/oracle@dupdb as sysdba
$ sqlplus sys/oracle@orcl as sysdba

8. duplicate database
% rman target sys/oracle@orcl AUXILIARY SYS/oracle@dupdb
RMAN> DUPLICATE TARGET DATABASE TO dupdb FROM ACTIVE DATABASE nofilenamecheck SPFILE;



以下�������试过程中屏幕上的输出信息 ================================================================================


[oracle@bakserver ~]$ rman target sys/oracle@orcl AUXILIARY SYS/oracle@dupdb

Recovery Manager: Release 11.2.0.1.0 - Production on Sun Mar 25 18:14:13 2012

Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.

connected to target database: ORCL (DBID=1306650359)
connected to auxiliary database: DUPDB (not mounted)

RMAN> DUPLICATE TARGET DATABASE TO dupdb FROM ACTIVE DATABASE nofilenamecheck SPFILE;

Starting Duplicate Db at 25-MAR-12
using target database control file instead of recovery catalog
allocated channel: ORA_AUX_DISK_1
channel ORA_AUX_DISK_1: SID=19 device type=DISK

contents of Memory Script:
{
   backup as copy reuse <=========================复制spfile
   targetfile  '/home/oracle/app/product/11.2/dbs/spfileorcl.ora' auxiliary format
 '/home/oracle/app/product/11.2/dbs/spfiledupdb.ora'   ;
   sql clone "alter system set spfile= ''/home/oracle/app/product/11.2/dbs/spfiledupdb.ora''";
}
executing Memory Script

Starting backup at 25-MAR-12
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=34 device type=DISK
Finished backup at 25-MAR-12

sql statement: alter system set spfile= ''/home/oracle/app/product/11.2/dbs/spfiledupdb.ora''

contents of Memory Script:
{
   sql clone "alter system set  db_name =
 ''DUPDB'' comment=
 ''duplicate'' scope=spfile";
   shutdown clone immediate;
   startup clone nomount;
}
executing Memory Script

sql statement: alter system set  db_name =  ''DUPDB'' comment= ''duplicate'' scope=spfile

Oracle instance shut down

connected to auxiliary database (not started)
Oracle instance started

Total System Global Area     238530560 bytes

Fixed Size                     1335724 bytes
Variable Size                 83889748 bytes
Database Buffers             150994944 bytes
Redo Buffers                   2310144 bytes

contents of Memory Script:
{
   sql clone "alter system set  db_name =
 ''ORCL'' comment=
 ''Modified by RMAN duplicate'' scope=spfile";
   sql clone "alter system set  db_unique_name =
 ''DUPDB'' comment=
 ''Modified by RMAN duplicate'' scope=spfile";
   shutdown clone immediate;
   startup clone force nomount
   backup as copy current controlfile auxiliary format  '/home/oracle/app/oradata/orcl/control01.ctl'; <=========================复制控制文件
   restore clone controlfile to  '/home/oracle/app/oradata/orcl/control02.ctl' from
 '/home/oracle/app/oradata/orcl/control01.ctl';
   alter clone database mount;
}
executing Memory Script

sql statement: alter system set  db_name =  ''ORCL'' comment= ''Modified by RMAN duplicate'' scope=spfile

sql statement: alter system set  db_unique_name =  ''DUPDB'' comment= ''Modified by RMAN duplicate'' scope=spfile

Oracle instance shut down

Oracle instance started

Total System Global Area     238530560 bytes

Fixed Size                     1335724 bytes
Variable Size                 83889748 bytes
Database Buffers             150994944 bytes
Redo Buffers                   2310144 bytes

Starting backup at 25-MAR-12
using channel ORA_DISK_1
channel ORA_DISK_1: starting datafile copy
copying current control file
output file name=/home/oracle/app/product/11.2/dbs/snapcf_orcl.f tag=TAG20120325T183209 RECID=3 STAMP=778876330
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:03
Finished backup at 25-MAR-12

Starting restore at 25-MAR-12
allocated channel: ORA_AUX_DISK_1
channel ORA_AUX_DISK_1: SID=19 device type=DISK

channel ORA_AUX_DISK_1: copied control file copy
Finished restore at 25-MAR-12

database mounted
RMAN-05538: WARNING: implicitly using DB_FILE_NAME_CONVERT

contents of Memory Script:
{
   set newname for datafile  1 to
 "/home/oracle/app/oradata/orcl/system01.dbf";
   set newname for datafile  2 to
 "/home/oracle/app/oradata/orcl/sysaux01.dbf";
   set newname for datafile  3 to
 "/home/oracle/app/oradata/orcl/undotbs01.dbf";
   set newname for datafile  4 to
 "/home/oracle/app/oradata/orcl/users01.dbf";
   backup as copy reuse <=========================复制数据文件
   datafile  1 auxiliary format
 "/home/oracle/app/oradata/orcl/system01.dbf"   datafile
 2 auxiliary format
 "/home/oracle/app/oradata/orcl/sysaux01.dbf"   datafile
 3 auxiliary format
 "/home/oracle/app/oradata/orcl/undotbs01.dbf"   datafile
 4 auxiliary format
 "/home/oracle/app/oradata/orcl/users01.dbf"   ;
   sql 'alter system archive log current';
}
executing Memory Script

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

executing command: SET NEWNAME

Starting backup at 25-MAR-12
using channel ORA_DISK_1
channel ORA_DISK_1: starting datafile copy
input datafile file number=00001 name=/home/oracle/app/oradata/orcl/system01.dbf
output file name=/home/oracle/app/oradata/orcl/system01.dbf tag=TAG20120325T183219
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:25
channel ORA_DISK_1: starting datafile copy
input datafile file number=00003 name=/home/oracle/app/oradata/orcl/undotbs01.dbf
output file name=/home/oracle/app/oradata/orcl/undotbs01.dbf tag=TAG20120325T183219
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:16
channel ORA_DISK_1: starting datafile copy
input datafile file number=00002 name=/home/oracle/app/oradata/orcl/sysaux01.dbf
output file name=/home/oracle/app/oradata/orcl/sysaux01.dbf tag=TAG20120325T183219
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:07
channel ORA_DISK_1: starting datafile copy
input datafile file number=00004 name=/home/oracle/app/oradata/orcl/users01.dbf
output file name=/home/oracle/app/oradata/orcl/users01.dbf tag=TAG20120325T183219
channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:01
Finished backup at 25-MAR-12

sql statement: alter system archive log current

contents of Memory Script:
{
   backup as copy reuse <=========================复制归档日志
   archivelog like  "/home/oracle/app/archdir/1_17_778869623.dbf" auxiliary format
 "/home/oracle/app/archdir1_17_778869623.dbf"   ;
   catalog clone archivelog  "/home/oracle/app/archdir1_17_778869623.dbf";
   switch clone datafile all;
}
executing Memory Script

Starting backup at 25-MAR-12
using channel ORA_DISK_1
channel ORA_DISK_1: starting archived log copy
input archived log thread=1 sequence=17 RECID=3 STAMP=778876388
output file name=/home/oracle/app/archdir1_17_778869623.dbf RECID=0 STAMP=0
channel ORA_DISK_1: archived log copy complete, elapsed time: 00:00:01
Finished backup at 25-MAR-12

cataloged archived log
archived log file name=/home/oracle/app/archdir1_17_778869623.dbf RECID=3 STAMP=778875343

datafile 1 switched to datafile copy
input datafile copy RECID=3 STAMP=778875343 file name=/home/oracle/app/oradata/orcl/system01.dbf
datafile 2 switched to datafile copy
input datafile copy RECID=4 STAMP=778875343 file name=/home/oracle/app/oradata/orcl/sysaux01.dbf
datafile 3 switched to datafile copy
input datafile copy RECID=5 STAMP=778875343 file name=/home/oracle/app/oradata/orcl/undotbs01.dbf
datafile 4 switched to datafile copy
input datafile copy RECID=6 STAMP=778875343 file name=/home/oracle/app/oradata/orcl/users01.dbf

contents of Memory Script:
{
   set until scn  229779;
   recover <=========================不完全恢复
   clone database
    delete archivelog
   ;
}
executing Memory Script

executing command: SET until clause

Starting recover at 25-MAR-12
using channel ORA_AUX_DISK_1

starting media recovery

archived log for thread 1 with sequence 17 is already on disk as file /home/oracle/app/archdir1_17_778869623.dbf
archived log file name=/home/oracle/app/archdir1_17_778869623.dbf thread=1 sequence=17
media recovery complete, elapsed time: 00:00:01
Finished recover at 25-MAR-12

contents of Memory Script:
{
   shutdown clone immediate;
   startup clone nomount;
   sql clone "alter system set  db_name =
 ''DUPDB'' comment=
 ''Reset to original value by RMAN'' scope=spfile";
   sql clone "alter system reset  db_unique_name scope=spfile";
   shutdown clone immediate;
   startup clone nomount;
}
executing Memory Script

database dismounted
Oracle instance shut down

connected to auxiliary database (not started)
Oracle instance started

Total System Global Area     238530560 bytes

Fixed Size                     1335724 bytes
Variable Size                 83889748 bytes
Database Buffers             150994944 bytes
Redo Buffers                   2310144 bytes

sql statement: alter system set  db_name =  ''DUPDB'' comment= ''Reset to original value by RMAN'' scope=spfile

sql statement: alter system reset  db_unique_name scope=spfile

Oracle instance shut down

connected to auxiliary database (not started)
Oracle instance started

Total System Global Area     238530560 bytes

Fixed Size                     1335724 bytes
Variable Size                 83889748 bytes
Database Buffers             150994944 bytes
Redo Buffers                   2310144 bytes
sql statement: CREATE CONTROLFILE REUSE SET DATABASE "DUPDB" RESETLOGS ARCHIVELOG
  MAXLOGFILES     16 <=========================重建控制文件
  MAXLOGMEMBERS      3
  MAXDATAFILES      100
  MAXINSTANCES     8
  MAXLOGHISTORY      292
 LOGFILE
  GROUP  1 ( '/home/oracle/app/oradata/orcl/redo01.log' ) SIZE 50 M  REUSE,
  GROUP  2 ( '/home/oracle/app/oradata/orcl/redo02.log' ) SIZE 50 M  REUSE,
  GROUP  3 ( '/home/oracle/app/oradata/orcl/redo03.log' ) SIZE 50 M  REUSE
 DATAFILE
  '/home/oracle/app/oradata/orcl/system01.dbf'
 CHARACTER SET ZHS16GBK


contents of Memory Script:
{
   set newname for tempfile  1 to
 "/home/oracle/app/oradata/orcl/temp01.dbf";
   switch clone tempfile all;
   catalog clone datafilecopy  "/home/oracle/app/oradata/orcl/sysaux01.dbf",
 "/home/oracle/app/oradata/orcl/undotbs01.dbf",
 "/home/oracle/app/oradata/orcl/users01.dbf";
   switch clone datafile all;
}
executing Memory Script

executing command: SET NEWNAME

renamed tempfile 1 to /home/oracle/app/oradata/orcl/temp01.dbf in control file

cataloged datafile copy
datafile copy file name=/home/oracle/app/oradata/orcl/sysaux01.dbf RECID=1 STAMP=778875365
cataloged datafile copy
datafile copy file name=/home/oracle/app/oradata/orcl/undotbs01.dbf RECID=2 STAMP=778875365
cataloged datafile copy
datafile copy file name=/home/oracle/app/oradata/orcl/users01.dbf RECID=3 STAMP=778875365

datafile 2 switched to datafile copy
input datafile copy RECID=1 STAMP=778875365 file name=/home/oracle/app/oradata/orcl/sysaux01.dbf
datafile 3 switched to datafile copy
input datafile copy RECID=2 STAMP=778875365 file name=/home/oracle/app/oradata/orcl/undotbs01.dbf
datafile 4 switched to datafile copy
input datafile copy RECID=3 STAMP=778875365 file name=/home/oracle/app/oradata/orcl/users01.dbf

contents of Memory Script:
{
   Alter clone database open resetlogs; <=========================open db
}
executing Memory Script

database opened
Finished Duplicate Db at 25-MAR-12

RMAN>

RMAN> exit


Recovery Manager complete.


================================================================================

星期二 三月 06, 2012

Oracle 11g 针对SQL性能的新特性(三)- SQL Plan Management

SQL Plan Management (SPM)


历史


SQL的执行效率,取决于它的执行计划是否高效。 优化器的算法是一个平衡,需要收集尽量少的信息,用尽量快的速度试图去得到一个最优的执行计划,这也决定了它不是万能的。 所以Oracle提供了一些辅助手段来“修复”优化器可能产生的错误,并不断改进这些方法。 

Oracle 8: hint
Oracle 8i&9: stored outline
Oracle 10: sql profile
Oracle 11: sql plan manangement




简介


在Oracle 11g之前,执行计划一直是作为“运行时”生成的对象存在。虽然oracle提供了一些方法去指导它的生成,但Oracle一直没有试图去保存完整的执行计划。 从11g开始,执行计划就可以作为一类资源被保存下来,允许特定SQL语句只能选择“已知”的执行计划。 


同其他方法相比,SPM更加的灵活。如我们所熟知的,一条带有绑定变量的SQL语句,最好的执行计划会根据绑定变量的值而不同,11g以前的方法都无法解决这个问题。在11g中,与adaptive cursor sharing配合,SPM允许你同时接受多个执行计划。执行时,根据不同的变量值,SPM会花费很少的运算从中选择一条最合适的。 


概念


SQL Plan Management SPM:oracle 11g 中提供的新特性,用来更好地控制执行计划。 
Plan History: 优化器生成的所有执行计划的总称
SQL Plan Baseline: Plan History里那些被标记为“ACCEPTED”的执行计划的总称
Plan Evolution: 把一条执行计划从Plan History里标记为“ACCEPTED”的过程
SQL Management Base SMB: 字典表里保存的执行计划的总称,包括Plan History,SQL Plan Baseline和SQL profile。


SPM的特点


o 与profile和outline相比,更加灵活的控制手段
  + 可以有很多的计划被保存下来,只有"ENABLED"并且"ACCEPTED"的执行计划才可以被选择。 
  + 允许有多个"ACCEPTED"的执行计划,根据实际情况进行选择。 
  + 可以用手工或者自动的方式,把执行计划演化(evolve)为"ACCEPTED"。 还可以控制只让性能更好的计划被接受。
  + 允许设置"FIXED"的计划。这样其他的计划将不会被选择。


o SPM使计划真正的稳定。 outline的缺点是太过死板,当数据量大幅度变化时无法做出相应的改变。 SQL proifle的缺点是,当数据量变化时,STA(SQL Tuning Advisor)会不可预知地去更改执行计划。 而SPM则会提供几个完整的plan供选择。 


SPM的控制方式


SPM通过几个标记来实现对执行计划的控制:


o Enabled (控制活动)
  + YES (活动的,但不一定会被使用)
  + NO (可以理解为被标记删除)
o Accepted (控制使用)
  + YES (只有 “Enabled” 并且 “Accepted” 的计划才会被选择使用)
  + NO (如果是“Enabled” 那么只有被evolve成“Accepted”才有可能被执行)
o Fixed (控制优先级)
  + YES (如果是“Enabled”并且“Accepted”,会优先选择这个计划,这个计划会被视为不需要改变的)
  + NO (普通的计划,无需优先)

另有一个被动的标记:
o Reproduced (有效性)
  + YES (优化器可以使用这个计划)
  + NO (计划无效,比如索引被删除)


SPM如何捕捉执行计划


o 自动捕捉
  1. 首先把OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES设置成TRUE
  2. 从这个时刻开始,所有执行两次以上的SQL语句会被观测,执行计划会进入Plan History。有个别例外的,参见note 788853.1
  3. 生成的第一个执行计划被标记为ENABLED并且是ACCEPTED,后续的执行计划会被标记为ENABLED但不是ACCEPTED。
  4. 这时把OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES设置会FALSE,新的语句将不会创建Baseline。
  5. 需要注意的是,即使关闭了自动捕捉,针对存在baseline的SQL,由于ACS的作用,仍旧会有新的PLAN生成,新的Plan仍会进入Plan History,标记为ENABLED但不是ACCEPTED。参见“执行计划的选择”。 


o 批量导入 (这些导入的baseline都会被自动标记为ACCEPTED) 
   Oralce提供四种方式把计划导入到sql plan baseline中。 
   + 从 SQL Tuning Set STS 导入
      DBMS_SPM.LOAD_PLANS_FROM_SQLSET
   + 从Stored Outlines 中导入 
      DBMS_SPM.MIGRATE_STORED_OUTLINE
   + 从内存中存在的计划中导入
      DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE;
   + 通过staging table从另外一个系统中移植
      DBMS_SPM.CREATE_STGTAB_BASELINE
      DBMS_SPM.PACK_STGTAB_BASELINE
      DBMS_SPM.UNPACK_STGTAB_BASELINE




执行计划的选择过程


在OPTIMIZER_USE_SQL_PLAN_BASELINES被设置成默认值TRUE,SQl Plan Baseline就会起作用。 


1. 首先,无论是否存在baseline,oracle都会正常进行硬解析或者软解析,为SQL生成一个执行计划。 由于ACS和bind peeking的作用,存在baseline的SQL有可能在这时生成一个不同于baseline的执行计划。
2. 如果baseline不存在,就按生成的计划执行。如果baseline存在,那么要查看history里是否有这个计划,如果没有,就将这个计划插入,并标记为ENABLED,NON-ACCEPTED. 
3. 在baseline中查看是否有FIXED的计划存在,如果存在,执行FIXED的计划,如果存在多个FIXED的计划,根据统计信息重新计算cost,选择cost小的那个。
4. 如果FIXED的计划不存在,就选择ACCEPTED的计划执行。 如果存在多个ACCEPTED的计划,根据统计信息重新计算cost,选择cost小的那个。


* 注意这里每次重新计算cost的代价不大,因为执行计划是已知的,优化器不必遍历所有的可能,只需根据算法计算出已知计划的cost便可


执行计划的演化(evolution)


执行计划的演化指Plan History里的执行计划从NON-ACCEPTED,变成ACCEPTED的过程。 如果上所述,由于ACS和Bind Peeking的作用,存在baseline的SQL有可能生成新的执行计划,被保存到Plan History中。 Oracle提供了API,通过自动或手工的方式,将一个计划标记为ACCEPTED,这个计划就会被后续的执行所选择。 


使用DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE这个API来控制执行计划的演化。语法:
DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE (
  sql_handle IN VARCHAR2 := NULL, --> NULL 表示针对所有SQL
  plan_name  IN VARCHAR2 := NULL,
  time_limit IN INTEGER  := DBMS_SPM.AUTO_LIMIT,
  verify     IN VARCHAR2 := 'YES',
  commit     IN VARCHAR2 := 'YES' )
RETURN CLOB;


这里由两个标记控制:
o Verify 
  + YES (只有性能更好的计划才会被演化)
  + NO (演化所有的计划)
o Commit
  + YES (直接演化)
  + NO (只生成报告)


这里可以通过不同的排列组合,达到不同的效果:
o 自动接收所有性能更好的执行计划 (Verify->YES, Commit->YES)
o 自动接收所有新的执行计划 (Verify->NO, Commit->YES)
o 比较性能,生成报告,人工确认是否演化 (Verify->NO, Commit->NO)


* 对于性能的验证的方式,oracle会去实际执行来比较buffer gets


修改已有的Baseline


通过DBMS_SPM.ALTER_SQL_PLAN_BASELINE来完成。 


DBMS_SPM.ALTER_SQL_PLAN_BASELINE (
  sql_handle      IN VARCHAR2 := NULL,
  plan_name       IN VARCHAR2 := NULL,
  attribute_name  IN VARCHAR2,
  attribute_value IN VARCHAR2 )
RETURN PLS_INTEGER;


比如,把某个baseline 标记为FIXED,更多属性请参见官方文档


SET SERVEROUT ON;
DECLARE
  x NUMBER;
BEGIN
  x := DBMS_SPM.ALTER_SQL_PLAN_BASELINE (
    sql_handle      => '&&sql_handle',
    plan_name       => '&&plan_name',
    attribute_name  => 'FIXED',
    attribute_value => 'YES' );
END;
/


常见应用


o 我们常见的一个场景是,一条SQL在使用hint时会生成一个好的计划,我们需要以此在原SQL上创建一个baseline。 具体方法请参加note 787692.1


注意


o 当您使用多种方式控制执行计划时:
  + Stored Outline存在时,它具有最高的优先级。
  + 已经实施的SQL profile会被自动加入到SQL plan baseline中
  + STA(SQL Tuning Advisor) 会自动接收新的profile,意味着它会生成新的baseline
o 如果可能话,尽量移植到SPM,混合多种方式会变得复杂


相关参数


optimizer_capture_sql_plan_baselines
optimizer_use_sql_plan_baselines
create_stored_outline
use_stored_outlines


参考文档


White paper: SQL Plan Management in Oracle Database 11g


How to Use SQL Plan Management (SPM) - Example Usage (Doc ID 456518.1)
Plan Stability Features (Including SPM) Start Point (Doc ID 1359841.1)
HOW TO LOAD SQL PLANS INTO SPM FROM AWR (Doc ID 789888.1)
Sql Plan Baseline Not always created (Doc ID 788853.1)
Transporting SQL PLAN Baselines from one database to another. (Doc ID 880485.1)








星期一 十月 03, 2011

Oracle 11g 针对SQL性能的新特性(一)- Adaptive Cursor Sharing

    Oracle 11g对SQL执行计划的生成过程做了很多改变,我们经常看到有客户抱怨,数据库在升级到11g以后,执行计划变得很不稳定,甚至难以预测。实际上,Oracle在最新版本中致力于让优化器变得更加“智能”,通过自我学习的方式,来改进目前体系上所存在的缺陷。

    我们将分章节为您粗略介绍下面几个新特性,这些很可能是造成您执行计划改变的原因。

    · Adaptive Cursor Sharing (ACS)
    · Cardinality Feedback (CFB)
    · SQL Plan Management (SPM)


Adaptive Cursor Sharing (ACS)


背景


众所周知,Oracle一直鼓励使用绑定变量,以帮助SQL去共享,减少硬解析带来的开销。 共享SQL的好处显而易见:

    · 减少共享池(Shared Pool)的使用
    · 减少SQL的解析(Parse)时间

共享SQL坏处呢? 是的,无论绑定变量如何变化,执行计划在第一次生成之后(bind peeking),就不再改变。所以,针对同一条SQL文本,我们无法针对每一组绑定变量,使用最合适的计划。这对于条件里包括范围查询的语句来说(大于, 小于, between等),影响很大。 Oracle曾试图用CURSOR_SHARING=SIMILAR来解决,但带来了更多的问题,“similar”也在11.1中被废弃。

在这种情况下,Adaptive Cursor Sharing 的引入,就是试图用统计的方法,提供一种介于“共享”和“非共享”之间的解决方案。


适用的SQL语句



考虑到开销,Oracle只针对下面情况使用ACS,这类CURSOR叫做bind sensitive

    · 相应列上有直方图,操作符: =:B,!=:B
    · 列上没有直方图,操作符: > :B,<:B,>=:B ,<= :B,like(11.2.0.2新增)




过程描述

1. 对于Bind Sensitive的SQL,从第一次执行开始,Oracle会额外做如下工作:
    · 根据实际执行所操作的总行数(Row Source Processing),生成直方图。直方图有3个bucket: Bucket 0: 小于1K行 ,Bucket 1:大于1K小于1M,Bucket 2:大于1M。 每次执行,就会在相应的bucket上加一。

2. 当Oracle 发现Child0有两个Bucket的高度相同且大于0,也就是说,目前计划所造成的行操作变化很大,那么就开始实施ACS。所以SQL必须要执行两次以上才有可能。

3. ACS被触发以后,优化器会重新生成执行计划,相应的,会有新的Child生成。新的Child标记为bind aware,意思是这个Child是根据绑定变量生成的。所以,Oracle又会额外做一件事:
    · 针对每个Child,记下所执行的每组绑定变量的选择率(Selectivity),并用设计好的算法生成一个范围(high value 和 low value)。

4. 针对后续的每一次执行,Oracle会做如下处理:
    · 先查看本次绑定变量的选择率是不是落在已知的范围内。
    · 如果是,那么就使用之前的plan,并在直方图中相应的位置+1。
    · 如果不是,就会生成新的执行计划。再查看这个计划是不是已经存在的:
        · 如果计划不存在,生成新的Child。
        · 如果计划存在,同样会生成新的Child,并把之前生成相同执行计划的选择率移动到新的Child上,最后再把之前的Child标记为不可重用(is_sharable=no)


通过这种方式,Oracle试着实现更智能的共享。

监控视图


    · V$SQL
        ·is_bind_sensitive  是否适用于ACS
        ·is_bind_aware 是否针对变量的值来选择计划
        ·is_shareable  是否可用
    · V$SQL_CS_HISTOGRAM   根据所操作的行数,记录每个Child执行的次数
    · V$SQL_CS_SELECTIVITY  记录每个Child的每组变量的选择率范围
    · V$SQL_CS_STATISTICS   每个Child的执行情况,类似v$sqlarea


缺点



    · 更多的硬解析带来额外的开销。
    · 更多的Child会对共享池产生压力。
    · 偶尔,更准确的统计信息没有生成最好的plan

从上面过程我们可以看到,ACS是有比较大的开销,所以我们只针对一部分SQL进行监控(bind sensitive)。 这部分SQL中,只有一部分会启动ACS(Child0的两个bucket高度相同)。在启用ACS的SQL中,只有一部分会生成多于一个的计划。 以此,来降低ACS带来的额外开销。


注意


     上述描述是基于11.2.0.2,没有任何补丁的情况。ACS的运行效率还在不停改进中 。


参考

    · Adaptive Cursor Sharing Overview (Doc ID 740052.1)
    · Introduction to Adaptive Cursor Sharing concepts in 11G and mutimedia demo [Video] (Doc ID 1115994.1)
    · Adaptive Cursor Sharing in 11G (Doc ID 836256.1)
    · 11.2官方文档


星期四 九月 15, 2011

Oracle 11g 诊断新特性——ADR 简介


    ADR(Automatic Diagnostic Repository)是一个基于文件的档案库,用于存放数据库的诊断信息,例如跟踪文件,意外dump文件,IPS包,警告日志文件,健康监控报告,核心dump文件以及其它诊断信息。ADR的根目录叫做ADR base, 位置通过参数DIAGNOSTIC_DEST设置。ADR拥有统一的目录结构,在数据库之外存储多个产品和实例的诊断信息,因此即使在数据库关闭时仍然可以进行问题诊断。
    从Oracle 11gR1 开始,ADR用于存储数据库,ASM,CRS和其它产品或组件(如listener)的诊断信息。每一个实例或者产品拥有各自的ADR home路径。例如在一个RAC环境下,ASM, 数据库实例拥有单独的ADR home。

名词解释
严重错误(Critical Error)是指会产生跟踪文件的Oracle内部错误。Oracle把他们划分为不同的类别,内部错误(ORA-600),系统访问异常(ora-7445,ora-3113),锁相关的错误,坏块(ORA-1578)和内存不足(ORA-4030/4031)等。
事件(Incident)是指一次严重错误,每出现一次严重错误,就会产生一次事件。ADR会跟踪每一个事件并产生唯一的事件ID。
问题(Problem)是一组严重错误,他们拥有一组共同的属性。ADR跟踪每一个问题,并且给每一个问题产生一个唯一的问题ID.

改变
    从11gR1开始,所有的诊断信息都保存在ADR中。ADR是一个外部的,迷你的XML数据库。
跟踪文件和进程的1:1对应不再存在。虽然进程跟踪文件仍然存在,但是它只记录每个事件的trc和trm文件的位置。Oracle为每一个事件产生一对儿文件——trc和trm文件。trc文件存放诊断信息,而trm文件存放元数据。
另外,文件的内部结构也发生了改变。例如一个XML格式的文件被引入,存放在ADR home的alert路径下(ADR_BASE/diag/rdbms/<db_name>/<SID>/alert/log.xml)。trc文件由若干个标记过的XML记录构成,每个记录都是分层排序过的。这种改变更加容易找到文件中我们感兴趣的部分的信息。

Diagnostic Frame Work(DFW)是如何工作的

1.    当一个严重错误发生时,DDE(diagnostic data extractor)被出发,并将相应的诊断信息写入到事件跟踪文件。
2.    ADR中的诊断信息可以通过ADRCI(命令行工具)或者SWB(Support WorkBench,图形界面)被访问。
3.    通过ADRCI或SWB从ADR中抽取诊断信息并创建包,这称之为事件打包服务(IPS)。查看诊断信息或上传IPS包到MOS。IPS包包含对应事件的所有诊断信息。

使用ADRCI或SWB创建IPS包的步骤
ADRCI
1. 进入ADRCI
# adrci
2.  显示存在的ADR home
adrci>show home
4.  设定ADR home
adrci>set home
5.  显示所有问题
adrci>show problem
6.  显示所有事件
adrci>show incident
7.  打包事件的诊断信息
adrci>ips pack incident <incident id>
SWB
1.  登录到企业管理器
2.  单击链接‘support workbench’
3.  选择‘all active’的问题
4.  单击‘问题id’查看对应的事件
5.  选择相应的事件
6.  单击 ‘quick package’
7.  输入包名,描述信息,选择是否上传到oracle support
8.  查看包中的信息
9. 选择‘立即’创建包,并单击按钮‘submit’

更多信息
请阅读下面的note获得更多的信息。
Note 422893.1 - 11g Understanding Automatic Diagnostic Repository.
Note 1091653.1 - "11g Quick Steps - How to create an IPS package using Support Workbench" [Video]
Note 443529.1 - 11g Quick Steps to Package and Send Critical Error Diagnostic Information to Support[Video]

您还可以在MOS上下载相关的中文培训录音:
Note 1268733.1 - Database Manageability: Diagnosibility archived Webcasts

About

本博客由Oracle全球技术支持中国区的工程师维护。为中文用户提供数据库相关的技术支持信息,包括常用的诊断工具、诊断方法、产品新特性、案例分析等。此外,MOS也陆续推出各类中文内容:技术通讯统一发布在Note 1529795.1 中,中文文档列表更新在Note 1533057.1 中,网上讲座请查看MOS文档 1456176.1,在"Archived"中可以下载历史的录音和文档。

Search

Archives
« 四月 2014
星期日星期一星期二星期三星期四星期五星期六
  
1
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
今天