Transporting Oracle9i Tablespaces from Solaris to HP-UX

我们知道跨平台表空间传输是在Oracle10g以后实现的,用RMAN命令可以完成。

那么在Oracle9i数据库中到底跨平台表空间传输能不能够实现呢?Oracle官方文档中提到:

The source and target database must be on the same hardware platform. For example, you can transport tablespaces between Sun Solaris Oracle databases, or you can transport tablespaces between Windows NT Oracle databases. However, you cannot transport a tablespace from a Sun Solaris Oracle database to an Windows NT Oracle database.

必须要在同一硬件平台上,并且举例无法从Solaris平台传输表空间到Windows平台。

但是实际上,这样的约束仅仅是由于字符序的限制。

SQL> select * from v$transportable_platform order by PLATFORM_NAME;
 
PLATFORM_ID PLATFORM_NAME                            ENDIAN_FORMAT
----------- ---------------------------------------- --------------
          6 AIX-Based Systems (64-bit)               Big
         16 Apple Mac OS                             Big
         19 HP IA Open VMS                           Little
         15 HP Open VMS                              Little
          5 HP Tru64 UNIX                            Little
          3 HP-UX (64-bit)                           Big
          4 HP-UX IA (64-bit)                        Big
         18 IBM Power Based Linux                    Big
          9 IBM zSeries Based Linux                  Big
         10 Linux IA (32-bit)                        Little
         11 Linux IA (64-bit)                        Little
         13 Linux x86 64-bit                         Little
          7 Microsoft Windows IA (32-bit)            Little
          8 Microsoft Windows IA (64-bit)            Little
         12 Microsoft Windows x86 64-bit             Little
         17 Solaris Operating System (x86)           Little
         20 Solaris Operating System (x86-64)        Little
          1 Solaris[tm] OE (32-bit)                  Big
          2 Solaris[tm] OE (64-bit)                  Big

可以看到所有的Windows平台上Oracle数据库均是小字符序的,而Solaris SPARC平台是大字符序,因此Oracle官方文档笼统地说不支持跨平台传输表空间。

选择同样为大字符序的操作系统Solaris SPARC 64bit和HP-UX IA (64-bit),做Oracle9i数据库的跨平台表空间传输,实验证明是完全可行的。

Solaris平台配置:Solaris10,Oracle9.2.0.6
HP-UX平台配置:HP-UX11,Oracle9.2.0.8

无论是操作系统平台还是数据库小版本号都是不一样的。

在Solaris端,USERS表空间中有数据文件/dev/md/rdsk/d29(裸设备),并且存在两张表,KAMUS.T1和SYSTEM.T。

SQL> select segment_name,owner from dba_segments where tablespace_name='USERS';

SEGMENT_NAME                   OWNER
------------------------------ ------------------------------
T                              SYSTEM
T1                             KAMUS

将USERS表空间设置为READONLY之后,开始传输表空间。

$ exp TRANSPORT_TABLESPACE=y TABLESPACES=(users)
 TRIGGERS=n CONSTRAINTS=n GRANTS=n FILE=/install/expdat.dmp

Export: Release 9.2.0.6.0 - Production on Thu Nov 19 17:25:48 2009

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.


Username: SYS/oracle AS SYSDBA

Connected to: Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.6.0 - Production
Export done in US7ASCII character set and AL16UTF16 NCHAR character set
server uses ZHS16GBK character set (possible charset conversion)
Note: table data (rows) will not be exported
Note: grants on tables/views/sequences/roles will not be exported
Note: constraints on tables will not be exported
About to export transportable tablespace metadata...
For tablespace USERS ...
. exporting cluster definitions
. exporting table definitions
. . exporting table                              T
. . exporting table                             T1
. end transportable tablespace metadata export
Export terminated successfully without warnings.

然后通过dd命令将数据文件以及dmp文件copy到HP-UX机器上,在我的实验环境中,最终是dd到/dev/testvg/rlvol4上。

然后在HP-UX上导入metadata:

imp  PARFILE='par.f'

其中par.f文件的内容如下:

TRANSPORT_TABLESPACE=y 
FILE=/oracle/oradata/expdat.dmp
DATAFILES=('/dev/testvg/rlvol4')
TABLESPACES=(users) 
TTS_OWNERS=(system,kamus)  
FROMUSER=(system,kamus) 
TOUSER=(system,system)

成功导入之后,查看USERS表空间中的数据。

SQL> select segment_name,owner from dba_segments where tablespace_name='USERS';

SEGMENT_NAME                   OWNER
------------------------------ ------------------------------
T                              SYSTEM
T1                             SYSTEM

继续在该表空间中做其他操作,比如create table等,也一切正常。

只做了使用裸设备作为数据文件的测试,不确认是不是如果数据文件存储在文件系统上也同样可以成功。如果是AIX平台,要注意一下,在AIX中裸设备头部有4K的OS Reserved Area,dd的时候需要skip掉。

没有做更多平台的测试,但是可以推测,即使是Oracle9i,Linux,Windows这两个平台或者AIX,HP-UX,SOLARIS SPARC这三个平台之间都应该是可以顺利地完成表空间传输的。

Update@2009-12-28
朋友测试的结果,从HP-UX IA (64-bit)平台传输表空间到 AIX-Based Systems (64-bit)平台无法成功。即使dd了文件头也仍然会报错。

How to resolve ORA-01034 when RAC failover

今天在客户处测试Oracle 9.2.0.8 on HP-UX IA64的RAC Failover功能,遇到ORA-01034错误。

表现为:
当关闭RAC环境的某一个实例之后(无论是shutdown abort还是shutdown immediate),再用远程客户端通过tns连接RAC Service都会间歇性报ORA-01034错误。

$ sqlplus system/oracle@prod 

SQL*Plus: Release 9.2.0.8.0 - Production on Tue Nov 17 20:52:09 2009

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

ERROR:
ORA-01034: ORACLE not available
ORA-27101: shared memory realm does not exist
HPUX-ia64 Error: 2: No such file or directory

客户端的TNS配置是很常规的客户端failover。

PROD  =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = VIP1)(PORT = 1521))
      (ADDRESS = (PROTOCOL = TCP)(HOST = VIP2)(PORT = 1521))
      (LOAD_BALANCE = yes)
    )
    (CONNECT_DATA =
      (SERVICE_NAME = prod)
      (FAILOVER_MODE=
       (TYPE=SELECT)
       (METHOD=BASIC))
    )
  )

纳闷许久,仔细检查服务器端的listener.ora配置,才发现设置了GLOBAL_DBNAME,这是对于还没有往本地监听动态注册服务名功能的Oracle8和Oracle7才需要设置,在Oracle9i之后,如果设置了该参数,将会导致Failover失败。

将listener.ora中的配置从:

SID_LIST_LISTENER_PROD2 =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME=prod)
      (ORACLE_HOME = /oracle/product/9.2)
      (SID_NAME = prod2)
    )
  )

修改为:

SID_LIST_LISTENER_PROD2 =
  (SID_LIST =
    (SID_DESC =
      (ORACLE_HOME = /oracle/product/9.2)
      (SID_NAME = prod2)
    )
  )

再次测试Failover,一切正常。

结论:
1. 对于监听依然存在,然后数据库实例关闭的情况,必须是在监听中动态注册的服务,才可以实现Failover。
2. GLOBAL_DBNAME会影响Failover。

“Alter Database Recover” Vs “Recover Database”

操作系统版本:Solaris 5.8 Sparc 64bit
数据库版本:Oracle 9.2.0.1

一直以为”alter database recover”和”recover database”这两个命令除了前者是SQL命令后者是SQL*PLUS命令之外,其它都是相同的,实际上却有所出入。

在所有需要的归档日志都存在的相同前提下。alter database recover命令无法继续。

SQL> alter database recover using backup controlfile until cancel;
alter database recover using backup controlfile until cancel
*
ERROR at line 1:
ORA-00279: change 10402260063 generated at 10/31/2009 01:30:52 needed for
thread 1
ORA-00289: suggestion : /xf_arch1/log9565_1.arc
ORA-00280: change 10402260063 for thread 1 is in sequence #9565

但是recover database命令却可以让DBA继续输入log file的名称。

SQL> recover database using backup controlfile until cancel;
ORA-00279: change 10402260063 generated at 10/31/2009 01:30:52 needed for
thread 1
ORA-00289: suggestion : /xf_arch1/log9565_1.arc
ORA-00280: change 10402260063 for thread 1 is in sequence #9565


Specify log: {=suggested | filename | AUTO | CANCEL}
/xf_arch1/log9565_1.arc
ORA-00279: change 10402260063 generated at 10/30/2009 23:24:14 needed for
thread 2
ORA-00289: suggestion : /xf_arch1/log10763_2.arc
ORA-00280: change 10402260063 for thread 2 is in sequence #10763


Specify log: {=suggested | filename | AUTO | CANCEL}
/xf_arch1/log10763_2.arc
ORA-00279: change 10402782605 generated at 10/31/2009 06:21:30 needed for
thread 1
ORA-00289: suggestion : /xf_arch1/log9566_1.arc
ORA-00280: change 10402782605 for thread 1 is in sequence #9566
ORA-00278: log file '/xf_arch1/log9565_1.arc' no longer needed for this
recovery


Specify log: {=suggested | filename | AUTO | CANCEL}
CANCEL
Media recovery cancelled.
SQL> 
SQL> alter database open resetlogs;

Database altered.

在上例中如果要想alter database recover成功,需要如下的语法:

ALTER DATABASE RECOVER automatic database 
until change 10404040058 using backup controlfile;

或者:

alter database recover logfile '/xf_arch1/log9565_1.arc' using backup controlfile;

a) use ALTER DATABASE if you want to do the recoverying step by step, manually — issueing each and every single solitary command to recover the database (apply logfiles).
b) use the SQLPLUS ‘recover’ command to have sqlplus automate the steps in a) for you.

更加详细的描述可以参看AskTOM的解释

Execution Plan!

今天客户做系统升级,从原先的Oracle 8.1.7.4升级为Oracle 9.2.0.8 RAC,并且将应用系统从1.1版本升级为2.0版本,是一个很大的举动。

其中牵涉到数据转换,软件开发商用简单的insert into xxx select … from yyy@dblink a, zzz b where a.ccc=b.ccc这样的语句完成数据转换,之前已经在测试环境中多次运行过,但是今天却仍然发生了问题,本来在测试环境中只需要运行100秒的转换过程在生产环境中运行了将近1个小时也没有结束,因为转换过程是大量顺序执行的insert语句,因此其中一个语句堵塞了,下面的语句也无法运行。

包括客户、软件开发商在内的十数人站在身后,为什么测试环境中运行如此快的SQL在产品环境中变得如此缓慢?该如何解决?如果在已经严格计算过的时间窗口内无法解决,是否需要回退整个升级工作?情况看上去很紧急。

因为牵涉到dblink,因此检查网络,没有发现问题。

让软件开发商在测试环境中重新跑这个SQL,速度仍然很快,检查执行计划,发现在测试环境中是Full table scan + Hash Join,而生产环境中却是Index range scan + Merge Join,检查互相Join的表,一个只有几千条记录,一个有几十万,很明显Hash Join应该是明智的选择。

没有时间去检查为什么产品环境中Oracle选择了更差的执行计划,加Hint先去解决问题。

添加了/*+USE_HASH(C,B) ORDERED*/提示,重新检查执行计划,已经是想要的Hash Join了,再次执行SQL,40多秒就完成了数据转换。

不同的执行计划差异就是如此之大,CBO任重道远。

Update@2008-6-20

今天主要任务是检查为什么相同SQL的执行计划在不同的机器上会不一样。通过10053 trace看到的区别。

生产环境中:
***********************
Table stats Table: XXX Alias: D
TOTAL :: CDN: 0 NBLKS: 1 AVG_ROW_LEN: 0

测试环境中:
***********************
Table stats Table: XXX Alias: D
TOTAL :: (NOT ANALYZED) CDN: 2893269 NBLKS: 35422 AVG_ROW_LEN: 100

很明显,生产环境中认为这张表是0条记录,但是在测试环境中因为没有做过表分析,Oracle选择了2893269条记录作为猜测值。这就是导致执行计划差异巨大的真正原因。

询问软件开发商的工程师,确实之前的多次测试中,在数据转换之前都没有做表分析,而这次生产环境却做了表分析,XXX表中的数据是在数据转换过程中才插入的,而数据转换之前做的表分析则告诉Oracle这张表中没有数据(实际上却有超过120万条记录)。

这次的故障告诉我们:
1. 表分析不要随便做,做错了比不做还差。
2. 当有人告诉你,“没有任何差别啊、所有的步骤都是一模一样的啊”,不要相信。问题的产生一定有原因。

Issues about oracle bin file s bit not set

很早之前记录过一个问题 – oracle可执行文件s位导致的Cluster资源组无法正常启动的问题解决

今天在另外一个客户处又出现了同样的问题,解决方法一样,但是问题现象却不一样,着实折腾了很久。问题现象是,启动数据库没有任何报错,启动监听也没有任何问题,lsnrctl services命令显示一切正常,但是在远程客户端通过监听登陆数据库,第一次会报Oracle not available的错误,之后再次尝试会报TNS-12516错误, “TNS:listener could not find instance with matching protocol stack”,此时再次检查lsnrctl services,会发现监听的状态变为blocked。

同样是使用tar包安装的Oracle9i软件,同样是在Solaris 9中,似乎这是Solaris系统中tar命令的一个毛病。

最后执行chmod解决问题。

chmod u+s,g+s $ORACLE_HOME/bin/oracle

How to resolve “VCSIPC for Oracle: Minor version mismatch”

如果基于Veritas SF V4.1 MP2来安装Oracle 9.2.0.6 RAC for Solaris,不能完全按照Veritas官方文档“VERITAS Storage FoundationTM 4.1 for OracleRAC Installation and Configuration Guide”中提到的更新VCSIPC library的方法。

在文档中提到:

For a 32-bit version:
$ cp /opt/VRTSvcs/rac/lib/libskgxp92_32.so $ORACLE_HOME/lib/libskgxp9.so

For 64-bit version:
$ cp /opt/VRTSvcs/rac/lib/libskgxp92_64.so $ORACLE_HOME/lib/libskgxp9.so

但是实际上如果这样做的话,可能会在启动数据库以后在/var/adm/messages收到如下的警告信息,该警告信息会重复打印到终端窗口,比较烦人。

Jun 14 02:51:27 xxdb-server2 oracle[23169]: [ID 939233 user.alert] VCSIPC for Oracle: Minor version mismatch: oracle 4, ipc library 2,
Jun 14 02:51:27 xxdb-server2 VERITAS IPC 4.1MP2 05:35:21 Nov 21 2006

解决方法是使用版本号为9207的库文件:
$ cp /opt/VRTSvcs/rac/lib/libskgxp9207_64.so $ORACLE_HOME/lib/libskgxp9.so

那么如何判断到底是应该按照文档中所说cp libskgxp92_64.so还是应该cp libskgxp9207_64.so,则需要通过下面的命令来验证。

# /opt/VRTSvcs/rac/bin/ipc_version_chk_shared_64 $ORACLE_HOME/lib/libskgxpu.so
Required library version is: 22

如果命令返回结果需要的库版本是22或者24,那么则需要使用9207版本的库文件。

My little poor server

为什么一开始决定要在Windows Server 2003 64bit上安装Oracle9i呢?于是给服务器安装了Windows Server 2003 64bit操作系统。
可是为什么硬件架构是AMD64和Intel 64呢?Oracle9i没有这两个架构的64bit版本。于是格式化了重新安装Redhat Enterprise Linux 5。
可是又为什么不是正版的Redhat Enterprise Linux 5呢?于是格式化安装了Redhat Enterprise Linux 4 Update 2。
可是为什么RHEL4 Update 2不能在阵列上设置MPIO呢?于是格式化安装了Redhat Enterprise Linux 4 Update 4。

时间就这样在一遍一遍地折磨服务器和折磨群众的过程中悄然溜走,转眼就到了下班的时候,Yeah,明天再说了。

Oracle9i upgrade to Oracle10g RAC

从昨天开始,正式全程参与某客户的数据库系统升级工作。工作内容是将客户的关键应用从原先的Oracle9.2.0.6单实例升级为Oracle 10.2.0.3 双实例RAC。

更加详细的工作内容包括:
1. 将原先存储在JFS2文件系统上的文件转移到GPFS中
2. 将原先单实例模式的Shareplex转换为RAC模式的Shareplex
3. 将原先的高级复制转换为简单的物化视图刷新
4. 使用Oracle Clusterware替代HACMP负责Shareplex资源的切换

总的来说,是一个很大的工程,数据库大小在800G左右,升级使用DBUA,单实例转换为RAC则使用rconfig实用程序。

工作的几个难点在于:
1. DBUA是否能顺利将Oracle 9.2.0.6升级为Oracle 10.2.0.3?
2. rconfig是否能顺利将单实例数据库转换为RAC数据库?
3. 能否正常在Oracle Clusterware中添加Shareplex资源并且保证在各种异常情况下顺利切换到另外一台主机上?

之前已经做过多次测试,希望这两天的正式升级会一帆风顺。

Update@2008-4-3
升级工作圆满结束,有惊无险。

1. 本来一直到rconfig转换单实例到RAC之前,整个进度都是提前了4个小时左右的,敲完rconfig的命令之后大家欢欣鼓舞地去开会,结果开完会回来发现rconfig失败了,一直处于悬停状态,整个主机没有任何负载,数据库实例也完全无法登录。根据回退方案将数据库重新转换为之前的单实例模式,成功启动完数据库以后,开始检查转换为RAC失败的原因。最后发现是ntp服务配置有问题,RAC两个节点的时间差异在1小时。重新调整ntp服务,然后再次转换,成功结束。此时,落后进度计划大概1个小时。

2. 后续的工作一帆风顺,应用上的几个问题也相继迅速地修改了,上线当天上午观察了一下主机情况,一切正常。于是中午就离开客户处了,没过2小时,客户电话说,机房忽然断电,所有设备全部意外down机 。。。我问UPS呢?客户说,就是一台UPS短路导致机房断电的。我FT。再赶回客户处,等着加电,幻想着加电以后GPFS文件系统全部损坏,然后再从带库恢复数据的凄惨景象。幸运的是,加电以后全部设备都安然启动,数据库也正常。Shareplex丢失了一部分数据,也都成功恢复。

3. 到今天为止没有更点儿背的事情发生,应用完全正常,宣告这次升级工作圆满结束。