处理表的行迁移的问题

检测迁移和链接

使用ANALYZE 命令检测迁移和链接:

SQL> ANALYZE TABLE oe.orders COMPUTE STATISTICS;
Table Analyzed.
SQL> SELECT num_rows, avg_row_len, chain_cnt
2 FROM DBA_TABLES
3 WHERE table_name='ORDERS';
NUM_ROWS   AVG_ROW_LEN   CHAIN_CNT
---------- ----------- ----------
1171         67          83
使用Statspack/AWR 检测迁移和链接:
Statistic                                      Total       per Second    per Trans
table fetch continued row                      34,964            0.7          0.2

先执行utlchain.sql脚本来创建CHAINED_ROWS表

SQL> @D:\oracle\product\10.2.0\db_1\RDBMS\ADMIN\utlchain.sql
选择已迁移的行
SQL> ANALYZE TABLE oe.orders LIST CHAINED ROWS;
Table analyzed.
SQL> SELECT owner_name, table_name, head_rowid
2 FROM chained_rows
3 WHERE table_name = 'ORDERS';
OWNER_NAME TABLE_NAME HEAD_ROWID
---------- ---------- ------------------
SALES ORDER_HIST AAAAluAAHAAAAA1AAA
SALES ORDER_HIST AAAAluAAHAAAAA1AAB

消除已迁移的行
导出/导入:
– 导出表
– 删除或截断表
– 导入表
MOVE 表命令:

– ALTER TABLE EMPLOYEES MOVE

重新定义联机表
复制已迁移的行:
– 使用ANALYZE 查找迁移的行
– 将迁移的行复制到新表
– 从原始表删除迁移行
– 将行从新表复制到原始表
下面是采用MOVE表命令的方式

-- Created on 2012-5-24 by ADMINISTRATOR
declare
 cursor lj is SELECT table_name, num_rows, avg_row_len, chain_cnt FROM DBA_TABLES a where a.owner='SSCP2'
 and a.chain_cnt>0;
 cursor sy(p_tablename in varchar2) is
 select * from dba_indexes a where a.owner='SSCP2' and a.table_name=''||''||p_tablename||''||'';
 sql_c varchar2(200):=null;
 cl_flag number(2):=1;
begin
   for r in lj loop
     sql_c:=null;
     sql_c:='alter table sscp2.'||r.table_name||' move';
     begin
     execute immediate ''||sql_c;
     exception
       when others then
       dbms_output.put_line('执行表移动出错的表'||r.table_name);
       cl_flag:=0;
     end ;
     if cl_flag=1 then
         for l in sy(r.table_name) loop
           dbms_output.put_line(l.index_name);
           sql_c:=null;
           sql_c:='alter index sscp2.'||l.index_name||' rebuild';
           begin
           execute immediate ''||sql_c;
           exception
           when others then
           dbms_output.put_line('重建出错的索引'||l.index_name);
           end ;
         end loop;
         sql_c:='analyze table sscp2.'||r.table_name||' compute statistics';
         begin
          execute immediate ''||sql_c;
         exception
           when others then
           dbms_output.put_line('分析表出错'||r.table_name);
         end ;
      end if;
   end loop;
end;
SQL> SELECT table_name, num_rows, avg_row_len, chain_cnt FROM DBA_TABLES a where a.owner='SSCP2'
  2   and a.chain_cnt>0;

TABLE_NAME                       NUM_ROWS AVG_ROW_LEN  CHAIN_CNT
------------------------------ ---------- ----------- ----------
ABSB                              2479525         114       3041
ABS8                             29230869         149     195428
IDS2                               453402          60        132
ICSW                                78087          37         37
ICS1                               759167          49       5521
IC12                               729809         111          9
IC10                               256770         170         62
ADS3                             17472005         186       2221
ADS1                               544695         130         53
ACSN                                39821          90          4
ACS6                              1940197          82        162

丢失所有重做日志文件的恢复例子丢失所有重做日志文件的恢复例子

SQL> conn / as sysdba

已连接。
SQL> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。

删除所有重做日志文件

SQL> startup
ORACLE 例程已经启动。

Total System Global Area  612368384 bytes
Fixed Size                  1250428 bytes
Variable Size             100666244 bytes
Database Buffers          503316480 bytes
Redo Buffers                7135232 bytes
数据库装载完毕。
ORA-00313: 无法打开日志组 1 (用于线程 1) 的成员
ORA-00312: 联机日志 1 线程 1: 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\REDO01.LOG'

SQL> shutdown immediate
ORA-01507: ??????


ORACLE 例程已经关闭。
SQL> startup mount
ORACLE 例程已经启动。

Total System Global Area  612368384 bytes
Fixed Size                  1250428 bytes
Variable Size             100666244 bytes
Database Buffers          503316480 bytes
Redo Buffers                7135232 bytes
数据库装载完毕。
SQL> select group#,sequence#,members,bytes,status,archived from v$log;

    GROUP#  SEQUENCE#    MEMBERS      BYTES STATUS           ARC
---------- ---------- ---------- ---------- ---------------- ---
         1        104          1   52428800 INACTIVE         YES
         3        106          1   52428800 CURRENT          NO
         2        105          1   52428800 INACTIVE         YES

SQL> select * from v$logfile;

 GROUP#    STATUS  TYPE      MEMBER                                           IS_RECOVERY_DEST_FILE
---------- ------- -------  ------------------------------------------------  --------------------------------

         3         ONLINE   D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\REDO03.LOG   NO

         2 STALE   ONLINE   D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\REDO02.LOG   NO

         1         ONLINE   D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\REDO01.LOG   NO

增加一个新的重做日志组

SQL> ALTER DATABASE ADD LOGFILE GROUP 4
  2  ('D:\oracle\product\10.2.0\oradata\ocp\redo04a.log','D:\oracle\product\10.2
.0\oradata\ocp\redo04b.log')
  3  SIZE 512 M;

数据库已更改。

删除不是当前重做日志组的日志文件

SQL> alter database drop logfile group 1;

数据库已更改。

SQL> alter database drop logfile group 2;

数据库已更改。

SQL> select group#,sequence#,members,bytes,status,archived from v$log;

    GROUP#  SEQUENCE#    MEMBERS      BYTES STATUS           ARC
---------- ---------- ---------- ---------- ---------------- ---
         4          0          2  536870912 UNUSED           YES
         3        106          1   52428800 CURRENT          NO

然后从新创建的redo04a.log复制一份修改为丢失的redo03.log
然后再做介质恢复

SQL> recover database until cancel;
完成介质恢复。
SQL> alter database open resetlogs;

数据库已更改。

SQL> shutdown immediate;
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
SQL> startup
ORACLE 例程已经启动。

Total System Global Area  612368384 bytes
Fixed Size                  1250428 bytes
Variable Size             104860548 bytes
Database Buffers          499122176 bytes
Redo Buffers                7135232 bytes
数据库装载完毕。
数据库已经打开。

然后再做完全备份

在linux下安装oracle bbed

[oracle@localhost lib]$ cd $ORACLE_HOME/rdbms/lib

  [oracle@localhost lib]$ls ins_rdbms.mk
  ins_rdbms.mk
  [oracle@localhost lib]$ make -f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed

  Linking BBED utility (bbed)
  rm -f /opt/oracle/product/9.2.0/rdbms/lib/bbed
  gcc -o /opt/oracle/product/9.2.0/rdbms/lib/bbed -L/opt/oracle/product/9.2.0/rdbms/lib/ -L/opt/oracle/product/9.2.0/lib/ -L/opt/oracle/product/9.2.0/lib/stubs/ /opt/oracle/product/9.2.0/lib/s0main.o /opt/oracle/product/9.2.0/rdbms/lib/ssbbded.o /opt/oracle/product/9.2.0/rdbms/lib/sbbdpt.o `cat /opt/oracle/product/9.2.0/lib/ldflags` -lnsslb9 -lncrypt9 -lnsgr9 -lnzjs9 -ln9 -lnl9 /opt/oracle/product/9.2.0/rdbms/lib/defopt.o -ldbtools9 -lclntsh `cat /opt/oracle/product/9.2.0/lib/ldflags` -lnsslb9 -lncrypt9 -lnsgr9 -lnzjs9 -ln9 -lnl9 -lnro9 `cat /opt/oracle/product/9.2.0/lib/ldflags` -lnsslb9 -lncrypt9 -lnsgr9 -lnzjs9 -ln9 -lnl9 -lclient9 -lvsn9 -lwtc9 -lcommon9 -lgeneric9 -lwtc9 -lmm -lnls9 -lcore9 -lnls9 -lcore9 -lnls9 -lxml9 -lcore9 -lunls9 -lnls9 `cat /opt/oracle/product/9.2.0/lib/ldflags` -lnsslb9 -lncrypt9 -lnsgr9 -lnzjs9 -ln9 -lnl9 -lnro9 `cat /opt/oracle/product/9.2.0/lib/ldflags` -lnsslb9 -lncrypt9 -lnsgr9 -lnzjs9 -ln9 -lnl9 -lclient9 -lvsn9 -lwtc9 -lcommon9 -lgeneric9 -ltrace9 -lnls9 -lcore9 -lnls9 -lcore9 -lnls9 -lxml9 -lcore9 -lunls9 -lnls9 -lclient9 -lvsn9 -lwtc9 -lcommon9 -lgeneric9 -lnls9 -lcore9 -lnls9 -lcore9 -lnls9 -lxml9 -lcore9 -lunls9 -lnls9 `cat /opt/oracle/product/9.2.0/lib/sysliblist` -Wl,-rpath,/opt/oracle/product/9.2.0/lib:/lib:/usr/lib -lm `cat /opt/oracle/product/9.2.0/lib/sysliblist` -ldl -lm
  [oracle@localhost lib]$ ll bbed
  -rwxr-xr-x 1 oracle dba 301140 11月 17 15:18 bbed
  [oracle@localhost lib]$ bbed
  -bash: bbed: command not found
  [oracle@localhost lib]$ ./bbed
  Password:
   密码是blockedit
  BBED: Release 2.0.0.0.0 - Limited Production on Tue Nov 17 15:23:14 2009

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

  ************* !!! For Oracle Internal Use only !!! ***************

  BBED> help
  HELP [ | ALL ]

  BBED> help all
  SET DBA [ dba | file#, block# ]
  SET FILENAME 'filename'
  SET FILE file#
  SET BLOCK [+/-]block#
  SET OFFSET [ [+/-]byte offset | symbol | *symbol ]
  SET BLOCKSIZE bytes
  SET LIST[FILE] 'filename'
  SET WIDTH character_count
  SET COUNT bytes_to_display
  SET IBASE [ HEX | OCT | DEC ]
  SET OBASE [ HEX | OCT | DEC ]
  SET MODE [ BROWSE | EDIT ]
  SET SPOOL [ Y | N ]
  SHOW [ | ALL ]
  INFO
  MAP[/v] [ DBA | FILENAME | FILE | BLOCK ]
  DUMP[/v] [ DBA | FILENAME | FILE | BLOCK | OFFSET | COUNT ]
  PRINT[/x|d|u|o|c] [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ]
  EXAMINE[/Nuf] [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ]
  :
  N - a number which specifies a repeat count.
  u - a letter which specifies a unit size:
   b - b1, ub1 (byte)
   h - b2, ub2 (half-word)
   w - b4, ub4(word)
   r - Oracle table/index row
  f - a letter which specifies a display format:
   x - hexadecimal
   d - decimal
   u - unsigned decimal
   o - octal
   c - character (native)
   n - Oracle number
   t - Oracle date
   i - Oracle rowid
  FIND[/x|d|u|o|c] numeric/character string [ TOP | CURR ]
  COPY [ DBA | FILE | FILENAME | BLOCK ] TO [ DBA | FILE | FILENAME | BLOCK ]
  MODIFY[/x|d|u|o|c] numeric/character string
   [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ]
  ASSIGN[/x|d|u|o] =
   : [ DBA | FILE | FILENAME | BLOCK | OFFSET | symbol | *symbol ]
   : [ value | ]
  SUM [ DBA | FILE | FILENAME | BLOCK ] [ APPLY ]
  PUSH [ DBA | FILE | FILENAME | BLOCK | OFFSET ]
  POP [ALL]
  REVERT [ DBA | FILE | FILENAME | BLOCK ]
  UNDO
  HELP [ | ALL ]
  VERIFY [ DBA | FILE | FILENAME | BLOCK ]
  CORRUPT [ DBA | FILE | FILENAME | BLOCK ]

  BBED>

传输表空间特性复制数据

移动表空间

概念:可跨平台移动的表空间:
简化数据仓库和数据集市之间的数据分发
允许从一个平台向另一个平台移植数据库
受支持的平台:
Solaris[tm] OE(32 位) HP-UX(64 位) Microsoft Windows IA(64 位)
Solaris[tm] OE(64 位) HP Tru64 UNIX 基于IBM zSeries 的Linux
Microsoft Windows IA(32 位) HP-UX IA(64 位)适用于AMD 的64 位Linux
Linux IA(32 位) Linux IA(64 位) Apple Mac OS
基于AIX 的系统(64 位) HP Open VMS Microsoft Windows for AMD(64 位)
Solaris 操作系统(x86)

移动表空间
可以使用可移动表空间功能跨平台移动数据。此功能简化了从数据仓库环境向数据集市
(数据集市通常在较小的平台上运行)分发数据的过程。此功能还允许通过重建字典并
移动用户表空间的方式,将数据库从一个平台移植到另一个平台。
为了能够将数据文件从一个平台移动到另一个平台,必须确保源系统和目标系统都在支持
的平台上运行。
注:可跨平台移动的表空间功能要求两个平台使用相同的字符集。

概念:最低兼容级别
源数据库和目标数据库都必须将COMPATIBLE
设置为10.0.0 或更高。
数据文件头可以识别平台。
在移动前,请确保所有只读文件和脱机文件可以
识别平台

概念:最低兼容级别
源数据库和目标数据库都需要先将其数据库COMPATIBLE 初始化参数提高到10.0.0 或
更高,才能使用可跨平台移动的表空间功能。
数据文件第一次在COMPATIBLE 设置为10.0.0(或更高)的Oracle Database 10g 中打
开时,这些文件将设置为可识别平台。这一点由图表中的对勾标记表示。每个文件都可以
确定其所属的平台。这些文件在磁盘上有相同的文件头块格式,这些格式用于文件标识
和验证。只读文件和脱机文件只有在变为读/写状态或变为联机之后才能提高其兼容性。
这意味着在Oracle Database 10g 版本之前的数据库中处于只读状态的表空间必须至少变为
读/写状态一次才能使用可跨平台移动的功能。

可移动表空间过程
将表空间置于只读状态。
使用数据泵提取元数据。

目标是否使用相同的endian 格式是
传送数据文件并将文件转储到目标。
使用数据泵导入元数据。
将表空间置于读/写状态。

目标是否使用相同的endian 格式否
使用RMAN
转换数据文件。

传送数据文件并将文件转储到目标。
使用数据泵导入元数据。
将表空间置于读/写状态。

可移动表空间过程
要将表空间从一个平台移动到另一个平台(源到目标),必须将表空间集内的数据文件转
换为目标数据库可以理解的格式。虽然使用Oracle Database 10g,磁盘结构符合通用格式,
但源平台和目标平台还是可能使用不同的endian 格式(字节顺序)。转至不同的endian
平台时,必须使用RMAN 实用程序的CONVERT 命令来转换字节顺序。可以在源平台或
目标平台上执行此操作。对于endian 格式相同的平台,则不需要转换。
幻灯片中的图形描述了从源平台向目标平台移动表空间可能用到的步骤。但是,也可以在
将文件传送到目标平台后执行转换。必须在目标平台上执行最后两步。
一般情况下,此过程与使用Oracle 数据库的旧发行版时相同,除非两个平台使用不同的
endian 格式。此处假定两个平台都支持跨平台移动。
注:读写数据时,字节顺序会影响结果。例如,2 个字节的整数值1 在big-endian 系统
(如Sun SPARC Solaris)上写为0x0001,而在little-endian 系统(如兼容Intel 的PC)
上写为0x0100。

确定平台的Endian 格式

SELECT tp.endian_format
FROM v$transportable_platform. tp,
v$database d
WHERE tp.platform_name = d.platform_name;

确定平台的Endian 格式
可以查询V$TRANSPORTABLE_PLATFORM. 来确定两个平台上的endian 顺序是否相同。
V$DATABASE 有两个列可以用于确定您自己的平台名称和平台标识符。
在两个平台上使用幻灯片中的查询,然后比较结果。在Sun SPARC Solaris 系统上,
SELECT 语句生成以下输出:
ENDIAN_FORMAT
————-
Big
在Microsoft Windows 基于Intel 的平台上,SELECT 语句生成以下输出:
ENDIAN_FORMAT
————-
Little

移动数据库
概述可移动表空间功能。
可以轻松地从数据仓库环境向数据集市(数据集市通常
在较小的平台上运行)分发数据。
数据库可以非常迅速地从一个平台移植到另一个平台。

移动数据库
在不同平台之间移动数据时,使用可移动表空间功能可以将移动速度加快许多。但仍然
需要卸载元数据,因为无法移动系统表空间。
数据库移动功能的目的是在endian 格式相同的不同平台之间轻松快捷地移动数据库。
但是,源平台和目标平台的磁盘对齐可以不同。例如,HP-UX 和Solaris 都是big endian
格式,但HP-UX 上的磁盘对齐为八,而在Solaris 上为四。
要从一个平台向另一个平台移动数据库,必须确保源系统和目标系统都运行于
V$TRANSPORTABLE_PLATFORM. 中列出的一个平台上,并且具有相同的endian 格式。
例如,可以将在Linux IA(32 位)上运行的数据库移动到一个Windows 平台上。
如果两个数据库中至少有一个使用自动存储管理(ASM),则可能需要使用
DBMS_FILE_TRANSFER 程序包来将文件上传到FTP。
此功能与可移动表空间不同,可移动表空间有一个可以插入数据的目标数据库,而此功能
将在目标平台上创建新的数据库。新创建的数据库中包含的数据与源数据库中相同。除了
数据库名、实例名和文件位置等,新数据库与源数据库的设置也相同。
注:移动数据库比使用“数据泵”移动数据更快。

数据库移动过程:源系统转换
在只读模式下打开数据库
并且COMPATIBLE=10.0.0

数据库移动过程:源系统转换
必须先在只读模式下打开数据库,才能移动该数据库。然后使用RMAN 转换数据库的必
要数据文件。
在源平台上执行转换时,新的RMAN 命令CONVERT DATABASE 将生成一个包含正确的
CREATE CONTROLFILE RESETLOGS 命令的脚本,此命令用于在目标系统上创建新数
据库。然后CONVERT DATABASE 命令将转换识别出的所有数据文件,以便这些文件可
以在目标系统上使用。接着,您需要将已转换的数据文件和生成的脚本传送到目标平台。
通过在目标平台上执行生成的脚本,可以创建数据库的新副本。
注:源数据库必须在COMPATIBLE 初始化参数设为10.0.0 或更高的条件下运行。
自COMPATIBLE 设置为10.0.0 或更高以来,识别出的所有表空间必须至少被读写一次。

数据库移动过程:目标系统转换
在只读模式下打开数据库
并且COMPATIBLE=10.0.0

数据库移动过程:目标系统转换
必须先在只读模式下打开数据库,才能移动该数据库。然后使用RMAN 转换数据库的必
要数据文件。
在目标平台上执行转换时,(在源系统上执行的)CONVERT DATABASE 命令只生成两个
脚本,用于在目标系统上转换数据文件以及重新创建新数据库的控制文件。然后,请将识
别出的数据文件和两个脚本都传送到目标平台。完成后,请按正确的顺序执行这两个脚本。
第一个脚本使用现有的CONVERT DATAFILE RMAN 命令来进行转换,第二个脚本随已
转换的数据文件一起发出CREATE CONTROLFILE RESETLOGS SQL 命令来创建新数
据库。
注:源数据库必须在COMPATIBLE 初始化参数设为10.0.0 或更高的条件下运行。
自COMPATIBLE 设置为10.0.0 或更高以来,识别出的所有表空间必须至少被读写一次。

数据库移动:注意事项
在目标平台上创建口令文件。
移动在源数据库中使用的BFILE。
生成的pfile 和移动脚本使用OMF。
使用DBNEWID 来更改DBID。

数据库移动:注意事项
不会移动重做日志、控制文件和临时文件。将在目标平台上为新数据库重新创建这些
文件。因此,目标平台上的新数据库必须用RESETLOGS 选项打开。
使用口令文件时,不会移动该文件,需要您在目标平台上创建该文件。这是因为口令
文件支持的文件名类型是特定于操作系统的。但是,CONVERT DATABASE 命令的输出
将列出所有用户名及其系统权限,并且建议在目标平台上重新创建口令文件并为这些
用户添加条目。
CONVERT DATABASE 命令列出源数据库中的所有目录对象以及使用BFILE 数据类型
或外部表的对象。可能需要用新的目录名和文件名来更新这些对象。如果在数据库中
使用了BFILE,则必须移动BFILE。
生成的pfile 和移动脚本将Oracle Managed Files (OMF) 用于数据库文件。如果不想使用
OMF,则必须修改pfile 和移动脚本。
移动的数据库与源数据库具有相同的DBID。可以使用DBNEWID 实用程序来更改DBID。
在移动脚本以及CONVERT DATABASE 命令的输出中,系统将提示您使用DBNEWID
实用程序来更改数据库ID。

下面的使用参数说明来自网络
http://tech.it168.com/db/2007-12-19/200712191131170.shtml
对于oracle10g的可传输表空间特性而言,我觉着最另人兴奋的就是跨平台的传输了(尽管仍非所有平台都支持)。这意味着一旦数据库涉及到操作系统平台的变更,再不用像之前那样通过exp/imp这类慢的要死的应用来操作了。更加值的庆幸的是,转换这个操作并不复杂,归根结底,它只是一个命令(挠头,难道真的只有一个吗,不像oracle风格啊,oracle一向是喜欢出选择题的),是的,只有一个--CONVERT。
CONVERT是RMAN中提供的一个命令,专门用于进行字节顺序转换的解决方案,其语法如图所示:

由上图可见,CONVERT命令可以转换数据文件、表空间甚至整个数据库的字节顺序,
l CONVERT TABLESPACE:用于在源库转换指定表空间的数据文件(第3步执行)。
l CONVERT DATAFILE:用于在目标库转换数据文件到目标平台(第4步执行)。
l CONVERT DATABASE:用于从源平台转换及传输整个数据库到目标平台,并确保创建需要的数据文件,视你的需求即可以在源库执行也可以在目标库执行。

CONVERT DATAFILE和CONVERT TABLESPACE还可用于操作ASM(Automatic Storage Management自动存储管理)文件的移入移出,这项功能用处极大,因为众所周知通常操作系统的命令例如Unix系统的cp或Windows系统的copy等命令是不能直接读写ASM中文件。要想操作ASM中文件,只有RMAN,这可是真正的华山一条路,舍它其谁。

没有CONVERT是不行的,但是CONVERT也不是万能的。
1、对于CONVERT DATAFILE, CONVERT TABLESPACE以及CONVERT DATABASE的所有应用,需要注意:
l CONVERT操作并不会改变源文件,转换操作也并不是在本地完成,而是直接写入目的地。
l 源库和目标库的初始化参数中COMPATIBLE参数至少被设置为10.0
l 在10g之前,CLOB字段做为变长字符集创建,CONVERT命令并不会转换这些列,而直接将其传输到目标库。直到后续有读取操作时,自动将其转换为目标字节顺序格式并保存。10g之后CLOB列的字符集被设置为AL16UTF16,完全平台无关,所以就更加不用考虑了。
l CONVERT命令并不会转换用户自定义的数据类型。如果你希望在数据库之间传输平台指定格式的映射对象,应该调用Data Pump。
l 在传输到其它平台之前,要传输的表空间至少要被置为read-write状态一次(为什么因为数据文件的文件头必须能够识别其所属的原平台是什么)。因此对于那些read-only的待传输表空间,你必须先将其置为read-write,然后再置为read-only。

2、对于CONVERT DATAFILE和CONVERT TABLESPACE操作的一些注意事项:
l 如果在源库平台操作,必须使用CONVERT TABLESPACE… TO PLATFORM,不能使用CONVERT DATAFILE转换个别数据文件。而如果是在目标库平台操作,则必须使用CONVERT DATAFILE… FROM PLATFORM… TO PLATFORM而不能用CONVERT TABLESPACE。因为目标库还没有表空间的信息,自然也找到其对应的数据文件。
l FORMAT和DB_FILE_NAME_CONVERT参数可以同时使用,也可以都不使用,如果两个参数都不使用的话,目标平台中的文件路径会默认引用源平台中的路径。
l 并非所有的平台都支持CONVERT,通过查询V$TRANSPORTABLE_PLATFORM视图确认所操作的平台是否支持CONVERT命令。要跨平台的传输表空间必须源和目标平台都在视图中的平台列表才可以。
l 由于操作系统命令不支持直接操作文件到ASM,你可以通过CONVERT TABLESPACE或CONVERT DATAFILE移动文件到ASM中即使不涉及endian format的转换。使用CONVERT命令可以提供与操作系统的copy操作等同的功能,所不同的是CONVERT操作的是ASM。

3、对于CONVERT DATABASE的操作,除了上述第1条中的限制外,还有些其它的注意事项:
对于传输整个数据库而言最主要的一个限制是源平台和目标平台必须拥有相同的endian format(只能有限跨平台了)。例如,你可以从Windows系统传输数据库到Linux x86系统,或者从HP-UX到AIX,但是如果你想从Solaris传输整个数据库到Linux x86的话就不能应用这项特性了。当然如果必须在这种情况下传输的话,可以选择手工建库,然后通过CONVERT TABLESPACE或CONVERT DATAFILE命令传输。

提示:事实上,即使源平台和目标平台的endian formats完全相同,对于CONVERT DATABASE命令而言也仍然需要转换的过程。这主要是为了保证各种类型,比如回滚段等都被重新格式以确保与目标平台的兼容性。

下面是些其它方面不支持直接使用的限制:
l 控制文件和Redo log文件不会被传输。目标平台的控制文件和redo logs会在传输过程中自动创建,并且目标库建立后以open resetlogs方式打开新数据库。
提示:由于目标库的控制文件是在传输过程中创建,源库中的RMAN备份信息并不会被生成到新库中(即使有)。
l BFILE类型对应的文件不会被传输。不过RMAN在执行CONVERT DATABASE时会将引用BFILE类型的对象输出一个列表,用户可以根据列表手工操作BFILE的文件到目标平台。
l 本地管理的临时表空间数据文件不会被传输,而在传输过程中自动重建。
l 外部表以及Directories不会被传输。与BFILE一样,RMAN也会提供一个列表供你手工操作时参考。
l 密码文件不会被传输。不过RMAN也会在执行CONVERT DATABASE命令时输出用户以及其对应的权限,你可以对照输出手工创建新的密码文件。

CONVERT命令的参数并不多,而且也都比较容易理解,不再一一详细介绍,后面我们通过具体示例演示来辅助理解。
一、使用CONVERT TABLESPACE
前面提到,CONVERT TABLESPACE必须在源平台执行,用于转换表空间的endian format到目标平台,通常的调用形式是:

RMAN> CONVERT TABLESPACE ts_1, ts_2...
TO PLATFORM. 'platform_name';

并且可以在命令中指定FORMAT或DB_FILE_NAME_CONVERT参数来设置转换后数据文件的命名规则,PARALLELISM参数指定转换的并行度(用于提高转换效率的,有点类似rman备份恢复中的通道数概念)。例如:

RMAN> CONVERT TABLESPACE jssweb
TO PLATFORM. 'Linux IA (32-bit)'
db_file_name_convert 'E:\ora10g\oradata\jssweb','e:\oratmp\oradata'
PARALLELISM 3;

注意示例中的PARALLELISM参数,如果该参数值设置的不合理,有可能适得其反,花费的时间反而更长,一般而言,推荐并行度大小不要超过要转换的数据文件的数量。

另外对于FORMAT和DB_FILE_NAME_CONVERT参数前面介绍中也提到了,两个参数可以同时指定,如果同时指定了两个参数,则rman会以FORMAT参数的设定为准。如果两个参数都未指定的话,rman就会按照它自己的规则生成文件。具体规则呢这里就不描述了,总之就是数字和字母组合,如果你决定按照它的规则命令文件,那么我至少能确认一件事—单看文件名,你已经不能分辩这个文件是干嘛的了。

二、使用CONVERT DATAFILE
CONVERT DATAFILE则是必须在目标平台执行,用于转换指定数据文件到指定的endian format.通常的调用形式如下:

RMAN> CONVERT DATAFILE datafile_1, datafile_2...
FROM PLATFORM. 'platform_name';

可以通过指定TO PLATFORM参数设定转换到的字节顺序,如果不指定该参数,默认转换到当前平台。不过FROM PLATFORM参数的值必须是与其对应的源平台,不然convert可能会出错。同样CONVERT DATAFILE也可以指定FORMAT,DB_FILE_NAME_CONVERT,PARALLELISM等参数,如例:

RMAN> CONVERT DATAFILE
2> 'E:\ora10g\oradata\jssweb\jssweb1.dbf',
3> 'E:\ora10g\oradata\jssweb\jssweb2.dbf'
5> TO PLATFORM="Linux IA (32-bit)"
6> FROM PLATFORM="Microsoft Windows IA (32-bit)"
7> DB_FILE_NAME_CONVERT=
8> "E:\ora10g\oradata", "/opt/oar10g/oradata";

这些参数的功能的格式与CONVERT TABLESPACE中介绍的完全一致,这里就不多废话了。

三、使用CONVERT DATABASE
假设源平台与目标平台拥有相同的字节顺序,RMAN能够自动处理大多数在目标平台创建新库的操作。CONVERT DATABASE 传输数据库到新平台需要一个较长的过程,主要包含下面一些部分:

1、准备工作:使用DBMS_TDB包。
DMBS_TDB包提供了两个非常有用的函数:
提示:建议将SERVEROUTPUT设置为ON,以便能够查看到函数执行过程的输出。
l DBMS_TDB.CHECK_DB检查数据库状态
此函数检查数据库是否能被传输到目标平台以及数据库当前状态是否能够进行传输操作。拥有下列几个可选参数:
target_platform_name:目标平台的名称,可以通过V$DB_TRANSPORTABLE_PLATFORM视图查询获得。此参数并非必选,但如果你指定了skip_option参数,则本参数也必须指定。忽略此参数,则默认目标平台与源平台相同,
skip_option:非必选参数,指定待传输的数据库要跳过检查的选项(如果有)。支持字符或数值调用。
DBMS_TDB.SKIP_NONE或0:检查所有表空间
DBMS_TDB.SKIP_OFFLINE或2:跳过offline表空间的数据文件
DBMS_TDB.SKIP_READONLY或3:跳过read-only表空间的数据文件
例如:
提示:执行前先将数据库置为read-only模式。

SQL> set serveroutput on
SQL> declare
2 db_ready boolean;
3 begin
4 db_ready := dbms_tdb.check_db('Microsoft Windows IA (32-bit)', 2);
5 if (db_ready) then
6 dbms_output.put_line('True');
7 else
8 dbms_output.put_line('False');
9 end if;
10 end;
11 /
Database is not open in READ-ONLY mode. Open the database in READ-ONLY mode and retry.
False

如果数据库可被传输,DBMS_TDB.CHECK_DB会返回true,否则返回false,如果执行结果返回false,会自动输出数据库不能够传输的原因(如果SERVEROUTPUT被置为on的话),下表是一些可能遇到的问题以及解决方案:

提示信息
解决方案
Unrecognized target platform. name.
不能识别目标平台的名称
检查V$DB_TRANSPORTABLE_PLATFORM视图,确实目标平台在视图列表中,或者,你没敲错字母。
Target platform. has a different endian format.
目标平台拥有不同的字节顺序,不能被CONVERT DATABASE所支持,死了这条心吧。
Database is not open read-only.
源库未被以read only模式打开,shutdown了重开一遍再试试。
There are active or in-doubt transactions in the database.
源库存在活动事务,回滚或解决该事务然后打开数据库到read-only模式再重试。
Deferred transaction rollback needs to be done.
源库有未完成的延期事务,以正常模式打开数据库完成它,然后再read only模式打开数据库重试
Database compatibility version is below 10.
源库初始化参数中COMPATIBLE参数低于10,修改该参数,重启数据库到read only后重试
Some tablespaces have not been open read-write with compatibility version is 10 or higher.
源库初始化参数中COMPATIBLE参数修改后,表空间尚未被置为read-write过,还记得我们前面说过的吗表空间至少要被置为read-write一次。

在serveroutput被置为on的情况下,如果DBMS_TDB.CHECK_DB执行后除了pl/sql成功执行外没有其它输出信息,说明数据库状态正常,支持传输操作。

l DBMS_TDB.CHECK_EXTERNAL确认外部对象
必须使用DBMS_TDB.CHECK_EXTERNAL函数来检查是否存在外部表,directories或Bfiles,因为RMAN的CONVERT命令不能自动传输这些对象。DBMS_TDB.CHECK_EXTERNAL函数没有参数,直接执行即可。例如:

SQL> set serveroutput on
SQL> declare
2 external boolean;
3 begin
4 external := dbms_tdb.check_external;
5 end;
6 /
The following directories exist in the database:
SYS.DATA_PUMP_DIR

如果没有任何外部的对象,除了pl/sql成功执行外不会有其它输出信息,但一旦有输出信息,如上例中所示的你就需要注意,最好记录下来,当传输完成之后,根据需要手工创建这些对象到目标数据库中。听明白了吧,本函数成功执行与否并不会影响传输操作,这个函数说白了就是给你列个单儿,然后告诉你单子上有的这些它都不负责传送,如果确实需要那你就得自个干。

2、转换数据库
前面就已经提到过,转换操作即可以在源平台执行也可以在目标平台执行,并且我们推荐转换操作在目标平台执行,对于CONVERT DATABASE而言,源平台执行和目标平台执行还是有些区别,具体操作的时候还得根据实据情况做选择,下面分别说明:
对于在源平台执行转换操作而言,通常步骤如下:
启动数据库到read only模式。
DBMS_TDB.CHECK_DB检查数据库是否可被传输
DBMS_TDB.CHECK_EXTERNAL检查外部对象
执行CONVERT DATABASE命令,例如:

RMAN> convert database new database 'jsstts'
2> transport script. 'e:\oratmp\script\ts.sql'
3> to platform. 'Linux IA (32-bit)'
4> db_file_name_convert 'E:\ora10g\oradata\jssweb' 'e:\oratmp\oradata';

得到下列文件:
转换后的数据文件:已转换的待传输文件,本例中保存至:e:\oratmp\oradata’,文件名与源库中相同。
transport script:在目标平台执行的创建数据库的脚本,本例中名为ts.sql,该文件内容仅供参考,你需要再根据实际情况修改其中的参数值。
客户端初始化参数文件:文件名及路径包含在CONVERT DATABASE的输出内容中,在输出结果的最后。文件中的参数值多继承自源库,你可以根据需要进行适当修改。
转换完成(此时可将源库置为read-write了),然后将文件复制到目标数据库,在目标平台执行transport script,创建数据库即可。注意,如果前一步操作生成的文件复制到目标平台后路径发生修改,务必修改transport script文件中对应的参数值。

对于在目标平台执行转换操作:
前面的准备工作与在源平台进行转换操作是一样的,所不同的仅仅只是执行CONVERT DATABASE命令时调用的参数,如例:

RMAN> convert database on target platform
2> convert script. 'e:\oratmp\script\cs.rman'
3> transport script. 'e:\oratmp\script\ts.sql'
4> new database 'jsstts'
5> db_file_name_convert 'E:\ora10g\oradata\jssweb' 'e:\oratmp\oradata';

得到下列文件:
convert script:在目标平台执行的转换数据文件的脚本(实际内容就是前面讲到的convert datafile命令,不过这个是convert database命令自动生成的)。
transport script:在目标平台执行的创建数据库的脚本,本例中名为ts.sql,该文件内容仅供参考,你需要再根据实际情况修改其中的参数值。
客户端初始化参数文件:文件名及路径包含在CONVERT DATABASE的输出内容中,在输出结果的最后。文件中的参数值多继承自源库,你可以根据需要进行适当修改。

你大概也注意到了,此时并未生成数据文件,这是因为转换操作将在目标平台执行,所以你直接将源平台中的数据文件复制到目标平台即可。然后即可将源库置为read-write状态了。

远程客户端连接数据库时提示TNS-12541: TNS: 无监听程序

在windows环境下监听程序和本地服务文件配置如下

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
    )
  )

ocp =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST =localhost)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = ocp)
    )
  )

当在远程机器上使用tnsping ocp是会报TNS-12541: TNS: 无监听程序

D:\oracle\product\10.2.0\db_1\network\admin\sqlnet.ora

已使用 TNSNAMES 适配器来解析别名
Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)
(HOST = 10.138.135.114)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = ocp)))
TNS-12541: TNS: 无监听程序
原因在于当host=localhost或127.0.0.1时在远程客户端使用tnsping ocp时会解释成
ip加服务名比如:10.138.135.114:1521/ocp但当在监听程序中配置为localhost或
127.0.0.1时当远程连接时解释服务名时就不能映射到真正的ip所以远程连接时就会报
TNS-12541: TNS: 无监听程序 所以配置监听程序和本地服务文件时host这个参数最好使用真实的ip或机器名

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 10.138.135.114)(PORT = 1521))
    )
  )

ocp =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST =10.138.135.114)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = ocp)
    )
  )
  

使用exp/imp来移动表空间到另一个数据库中的例子

exp/imp还有一个TRANSPORT_TABLESPACE的功能,可以传输整个表空间的数据,就是把一个数据库上的数据文件加到另外一个数据库中,而不是把数据导出成Dmp文件。用这个传输还有一定的限制:

关于传输表空间有一些规则,即:
·源数据库和目标数据库必须运行在相同的硬件平台上。
·源数据库与目标数据库必须使用相同的字符集。
·源数据库与目标数据库一定要有相同大小的数据块
·目标数据库不能有与迁移表空间同名的表空间
·SYS的对象不能迁移
·必须传输自包含的对象集
·有一些对象,如物化视图,基于函数的索引等不能被传输

可以用以下的方法来检测一个表空间或一套表空间是否符合传输标准:

exec sys.dbms_tts.transport_set_check('tablespace_name',true);
select * from sys.transport_set_violation;

如果没有行选择,表示该表空间只包含表数据,可以传输。

其步骤:
1. 源数据库表空间设为只读:

alter tablespace hygeia read only;

2. 发出exp命令,用户必须是sysdba:

C:\Documents and Settings\Administrator>exp 'sys/ocp as sysdba' transport_tables
pace=y tablespaces=hygeia file=d:\oracle\hygeia.dmp log=d:\oracle\hygeia.log

3.将导出文件hygeia.dmp和表空间hygeia的数据文件hygeia01.dbf和hygeia02.dbf拷贝到目标机器上
4. 源数据库表空间设为可读写:

alter tablespace hygeia read write;

如果在修改表空间为读写后再复制数据文件和导出的dmp文件到目标数据库那么在执行imp导入时会报

IMP-00003:遇到ORACLE错误19722
ORA-19722:数据文件D:\oracle\hygeia版本错误
ORA-06512:在"SYS.DBMS_PLUGTS", line 2065
ORA-06512:在line 1
IMP-00000:未成功终止导入

5.在目数据库中创建一个hygeia用户不用指定缺省表空间

Create User insur_changde Identified By "changde"

6. 目标数据库imp文件:

C:\Documents and Settings\Administrator>imp 'sys/ocp as sysdba' file=d:\hygeia.d
mp  transport_tablespace=y tablespaces=hygeia datafiles=('D:\oracle\product\10.2
.0\oradata\ocp\HYGEIA01.DBF','D:\oracle\product\10.2.0\oradata\ocp\HYGEIA02.DBF'
)

7.修改目标数据库中insur_changde用户的缺省表空间为hygeia

Alter User insur_changde Default Tablespace hygeia

8. 目标数据库表hygeia空间设为可读写:

alter tablespace users read write;

rman备份数据库后到另一台机器上恢复的例子

rman备份数据库后到另一台机器上恢复的过程

1.先查询并记录源数据库的dbid号和数据文件名

SQL> select dbid from v$database;

      DBID
----------
2674069457

SQL> select file#,name from v$datafile
  2  ;

     FILE# NAME
---------- --------------------------------------------------------------------------------
         1 D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\SYSTEM01.DBF
         2 D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\UNDOTBS01.DBF
         3 D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\SYSAUX01.DBF
         4 D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\USERS01.DBF
         5 D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\EXAMPLE01.DBF
         6 D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\HYGEIA01.DBF
         7 D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\HYGEIA02.DBF

7 rows selected

2.在新机器上使用和源数据库版本相同的oracle安装软件创建一个和源数据库同名的实例使用dbca来创建(生成的数据文件删除掉)或 使用如下命令来创建

复制一个pfile文件,放到C:\oracle\product\10.2.0\db_1\database目录下,并启动数据库到nomount状态(需要设置内存参数, 否则无法unmount,会无法分内存,报ORA-04031错误)并修改initcc.ora文件的内容来达到你要的设置要求

C:\Documents and Settings\Administrator>e:
C:\>cd E:\oracle\product\10.2.0\db_1\BIN
C:\oracle\product\10.2.0\db_1\BIN>orapwd file=C:\oracle\product\10.2.0\db_1\data
base\pwdCC.ora password=oracle entries=5;

E:\oracle\product\10.2.0\db_1\BIN>oradim -new -sid CC -pfile C:\oracle\product\10.2.0\db_1\database\initcc.ora
执行处理已建立.

修改机器上的监听,以便能够对实例CC进行监听
原内容为:

SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = C:oracle92ora92)
(PROGRAM = extproc)
)
(SID_DESC =
(GLOBAL_DBNAME = logicdg)
(ORACLE_HOME = C:oracle92ora92)
(SID_NAME = logicdg)
)
)

更改以后的内容为:

SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = C:oracle92ora92)
(PROGRAM = extproc)
)
(SID_DESC =
(GLOBAL_DBNAME = logicdg)
(ORACLE_HOME = C:oracle92ora92)
(SID_NAME = logicdg)
)
(SID_DESC =
(GLOBAL_DBNAME = CC
(ORACLE_HOME = D:\ORADATA\OCP)
(SID_NAME = CC
)
)


C:\oracle\product\10.2.0\db_1\BIN>set ORACLE_SID=CC
C:\oracle\product\10.2.0\db_1\BIN>sqlplus "/as sysdba"

联机至闲置的执行处理.

可以连接DB了

3.启动实例到nomount状态

SQL>startup pfile='C:\oracle\product\10.2.0\db_1\database\initcc.ora' nomount;
ORACLE执行处理已启动.

Total System Global Area 163577856 bytes
Fixed Size                 1247852 bytes
Variable Size            104859028 bytes
Database Buffers          50331648 bytes
Redo Buffers               7139328 bytes
4.恢复控制文件
C:\Documents and Settings\Administrator>rman target/

恢复管理器: Release 10.2.0.1.0 - Production on 星期六 3月 17 10:53:10 2012

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

连接到目标数据库: ocp (未装载)

RMAN> startup nomount

数据库已经启动

RMAN> restore controlfile from 'D:\t\O1_MF_NCSNF_TAG20120316T161306_7P5Y9JQG_.BK
P';

启动 restore 于 17-3月 -12
使用目标数据库控制文件替代恢复目录
分配的通道: ORA_DISK_1
通道 ORA_DISK_1: sid=156 devtype=DISK

通道 ORA_DISK_1: 正在复原控制文件
通道 ORA_DISK_1: 恢复完成, 用时: 00:00:04
输出文件名=D:\ORADATA\OCP\CONTROL01.CTL
输出文件名=D:\ORADATA\OCP\CONTROL02.CTL
输出文件名=D:\ORADATA\OCP\CONTROL03.CTL
完成 restore 于 17-3月 -12

5. 将新数据库的dbid设置成源数据库的dbid

RMAN> set dbid=2674069457;

正在执行命令: SET DBID

6.启动数据库到mount状态

RMAN> alter database mount;

数据库已装载
释放的通道: ORA_DISK_1

7.将备份集的信息加入到catalog,因为从远端数据库拷贝过来的备份集存放于目录D:\t而不是和源数据库备份集在相同的目录下

RMAN>  catalog start with 'D:\t';

启动 implicit crosscheck backup 于 17-3月 -12
分配的通道: ORA_DISK_1
通道 ORA_DISK_1: sid=155 devtype=DISK
已交叉检验的 1 对象
完成 implicit crosscheck backup 于 17-3月 -12

启动 implicit crosscheck copy 于 17-3月 -12
使用通道 ORA_DISK_1
完成 implicit crosscheck copy 于 17-3月 -12

搜索恢复区域中的所有文件
正在编制文件目录...
没有为文件编制目录

搜索与样式 D:\t 匹配的所有文件

数据库未知文件的列表
=====================================
文件名: D:\t\O1_MF_NCSNF_TAG20120316T161306_7P5Y9JQG_.BKP
文件名: D:\t\O1_MF_NNNDF_TAG20120316T161306_7P5XJMHN_.BKP

是否确实要将上述文件列入目录 (输入 YES 或 NO)? yes
正在编制文件目录...
目录编制完毕

已列入目录的文件的列表
=======================
文件名: D:\t\O1_MF_NCSNF_TAG20120316T161306_7P5Y9JQG_.BKP
文件名: D:\t\O1_MF_NNNDF_TAG20120316T161306_7P5XJMHN_.BKP

8.恢复数据文件,因为恢复的路径跟源库的数据文件路径不一致,需要用set newname转换路径.

RMAN> run{
2> set newname for datafile 1 to 'D:\oradata\ocp\SYSTEM01.DBF';
3> set newname for datafile 2 to 'D:\oradata\ocp\UNDOTBS01.DBF';
4> set newname for datafile 3 to 'D:\oradata\ocp\SYSAUX01.DBF';
5> set newname for datafile 4 to 'D:\oradata\ocp\USERS01.DBF';
6> set newname for datafile 5 to 'D:\oradata\ocp\EXAMPLE01.DBF';
7> set newname for datafile 6 to 'D:\oradata\ocp\HYGEIA01.DBF';
8> set newname for datafile 7 to 'D:\oradata\ocp\HYGEIA02.DBF';
9> restore database;
10> switch datafile all;
11> }

正在执行命令: SET NEWNAME

正在执行命令: SET NEWNAME

正在执行命令: SET NEWNAME

正在执行命令: SET NEWNAME

正在执行命令: SET NEWNAME

正在执行命令: SET NEWNAME

正在执行命令: SET NEWNAME

启动 restore 于 17-3月 -12
使用通道 ORA_DISK_1

通道 ORA_DISK_1: 正在开始恢复数据文件备份集
通道 ORA_DISK_1: 正在指定从备份集恢复的数据文件
正将数据文件00001恢复到D:\ORADATA\OCP\SYSTEM01.DBF
正将数据文件00002恢复到D:\ORADATA\OCP\UNDOTBS01.DBF
正将数据文件00003恢复到D:\ORADATA\OCP\SYSAUX01.DBF
正将数据文件00004恢复到D:\ORADATA\OCP\USERS01.DBF
正将数据文件00005恢复到D:\ORADATA\OCP\EXAMPLE01.DBF
正将数据文件00006恢复到D:\ORADATA\OCP\HYGEIA01.DBF
正将数据文件00007恢复到D:\ORADATA\OCP\HYGEIA02.DBF
通道 ORA_DISK_1: 正在读取备份段 D:\T\O1_MF_NNNDF_TAG20120316T161306_7P5XJMHN_.BK
P
通道 ORA_DISK_1: 已恢复备份段 1
段句柄 = D:\T\O1_MF_NNNDF_TAG20120316T161306_7P5XJMHN_.BKP 标记 = TAG20120316T16
1306
通道 ORA_DISK_1: 恢复完成, 用时: 00:20:25
完成 restore 于 17-3月 -12

数据文件 1 已转换成数据文件副本
输入数据文件副本 recid=9 stamp=778160312 文件名=D:\ORADATA\OCP\SYSTEM01.DBF
数据文件 2 已转换成数据文件副本
输入数据文件副本 recid=10 stamp=778160312 文件名=D:\ORADATA\OCP\UNDOTBS01.DBF
数据文件 3 已转换成数据文件副本
输入数据文件副本 recid=11 stamp=778160312 文件名=D:\ORADATA\OCP\SYSAUX01.DBF
数据文件 4 已转换成数据文件副本
输入数据文件副本 recid=12 stamp=778160312 文件名=D:\ORADATA\OCP\USERS01.DBF
数据文件 5 已转换成数据文件副本
输入数据文件副本 recid=13 stamp=778160312 文件名=D:\ORADATA\OCP\EXAMPLE01.DBF
数据文件 6 已转换成数据文件副本
输入数据文件副本 recid=14 stamp=778160313 文件名=D:\ORADATA\OCP\HYGEIA01.DBF
数据文件 7 已转换成数据文件副本
输入数据文件副本 recid=15 stamp=778160313 文件名=D:\ORADATA\OCP\HYGEIA02.DBF

9.打开数据库

RMAN> alter database open resetlogs;
RMAN> alter database open resetlogs;
MAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: alter db 命令 (在 03/17/2012 11:41:10 上) 失败
ORA-00344: 无法重新创建联机日志 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\REDO01.LOG'

ORA-27040: 文件创建错误, 无法创建文件
OSD-04002: 无法打开文件
O/S-Error: (OS 3) 系统找不到指定的路径。

这里报找不到redo日志文件的错误,因为数据库是非归档的,日志文件没有备份,在新库中也没有redo日志文件,这里需要重新创建日志

SQL> alter database drop logfile group 1;
alter database drop logfile group 1
*
第 1 行出现错误:
ORA-01623: 日志 1 是实例 ocp (线程 1) 的当前日志 - 无法删除
ORA-00312: 联机日志 1 线程 1: 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\REDO01.LOG'


SQL> alter database drop logfile group 2;

数据库已更改。

SQL> alter database add logfile group 2 'D:\oradata\ocp\redo02.log';
alter database add logfile group 2 'D:\oradata\ocp\redo02.log'
*
第 1 行出现错误:
ORA-00301: 添加日志文件 'D:\oradata\ocp\redo02.log' 时出错 - 无法创建文件
ORA-17610: 文件 'D:\oradata\ocp\redo02.log' 不存在, 大小也未指定
ORA-27041: 无法打开文件
OSD-04002: 无法打开文件
O/S-Error: (OS 2) 系统找不到指定的文件。


SQL> alter database add logfile group 2 'D:\oradata\ocp\redo02.log' size 50M;

数据库已更改。

SQL> alter database drop logfile group 3;

数据库已更改。

SQL> alter database add logfile group 3 'D:\oradata\ocp\redo03.log' size 50M;

数据库已更改。

SQL> alter system switch logfile;
alter system switch logfile
*
第 1 行出现错误:
ORA-01109: 数据库未打开

下面试着修改日志文件的在控制文件中的路径(restore回来的控制文件中记录的日志文件路径是源端日志文件的路径)
由于redo01.log是当前重做日志组所要先复制一个重做日志文件命为’D:\oradata\ocp\redo01.log’再执行修改日志文件的路径

SQL> alter database rename file 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\OCP\REDO01.LOG
' to 'D:\oradata\ocp\REDO01.log';

SQL> alter database open resetlogs;

数据库已更改。

10.处理临时表空间文件
先创建一个新临时表空间

sql>CREATE TEMPORARY TABLESPACE hygeiatemp  Tempfile 'D:\oradata\ocp\hygeiatemp01.dbf' size 500M;

修改新建的临时表空间为缺省的临时表空间

sql> Alter Database  Default Temporary Tablespace hygeiatemp;

再删除原来的临时表空间

sql> Drop Tablespace  temp;

再新建原来的临时表空间

sql> CREATE TEMPORARY TABLESPACE temp Tempfile 'D:\oradata\ocp\temp01.dbf' size 500M;

再将新建的原来的临时表空间修改为缺省的临时表空间

sql> Alter Database  Default Temporary Tablespace temp;

使用oracle sqlldr导入文本数据的例子

一:sql loader使用例子

car.csv要导入的数据格式如下
姓名性 别身份证号码人员类别未登帐时间
张宏华男432401511011201有工作(区)2011.04-2012.03
胡祥胜男有工作(41市 2011.04-2012.03
杨长保男430702195111221011有工作(区)2011.04-2012.03
刘新翁男432401511125001有工作(41市2011.04-2012.03
周家胜男432401511123001有工作((市)2011.04-2012.03
顾春茂男432401510210301有工作(市)2011.04-2012.03
王跃志男432401195102200015有工作(41区2011.04-2012.03
潘伯伦男432401195112237516老市“4050”2011.04-2012.03
a.创建表(将上面的数据导入到这个表中)

create table jy_20120308
(
username varchar2(40),
sex      varchar2(10),
idcard   varchar2(20),
rylb     varchar2(50),
sj       varchar2(50)
)

a.创建SQL*Loader输入数据所需要的文件,均保存到C:\,用记事本编辑:
控制文件:input.ctl,内容如下:

   load data            --1、控制文件标识
   infile  'D:\sqlldr\tx.csv'    --2、要输入的数据文件名为car.csv
   append into table jy_20120308 --3、向表test中追加记录
   fields terminated by ","      --4、字段以逗号分隔
   (username,sex,idcard,rylb,sj) -----定义列对应顺序

a、insert,为缺省方式,在数据装载开始时要求表为空
b、append,在表中追加新记录
c、replace,删除旧记录,替换成新装载的记录
d、truncate,同上
在DOS窗口下使用SQL*Loader命令实现数据的输入

C:\>sqlldr userid=system/manager@orcl control=input.ctl

默认日志文件名为:input.log
默认坏记录文件为:input.bad

也可以使用下面形式

创建SQL*Loader输入数据所需要的文件,均保存到C:\,用记事本编辑:
控制文件:input.ctl,内容如下:

   load data            --1、控制文件标识
   infile  *                                               --2、可以在控制文件内或在执行命令时指定                                                                     --数据内容或数据文件名
   append into table jy_20120308 --3、向表test中追加记录
   fields terminated by ","      --4、字段以逗号分隔
   (username,sex,idcard,rylb,sj) -----定义列对应顺序
sqlldr 'DBUser/Password control=/export/home/imp.ctl'
data=  D:\sqlldr\tx.csv' log=port.log

C:\>sqlldr userid=system/manager@orcl control=input.ctl
data=/export/home/port.txt log=port.log

b)在控制文件中直接导入数据
1、控制文件test.ctl的内容

LOAD DATA
INFILE *
BADFILE 'C:\Documents and Settings\Jackey\桌面\WMCOUNTRY.BAD'
DISCARDFILE 'C:\Documents and Settings\Jackey\桌面\WMCOUNTRY.DSC'
INSERT INTO TABLE EMCCOUNTRY
Fields terminated by ";" Optionally enclosed by '"'
(
COUNTRYID NULLIF (COUNTRYID="NULL"),
COUNTRYCODE,
COUNTRYNAME,
CONTINENTID NULLIF (CONTINENTID="NULL"),
MAPID NULLIF (MAPID="NULL"),
CREATETIME DATE "MM/DD/YYYY HH24:MI:SS" NULLIF (CREATETIME="NULL"),
LASTMODIFIEDTIME DATE "MM/DD/YYYY HH24:MI:SS" NULLIF (LASTMODIFIEDTIME="NULL")
)
BEGINDATA
1;"JP";"Japan";1;9;"09/16/2004 16:31:32";NULL
2;"CN";"China";1;10;"09/16/2004 16:31:32";NULL
3;"IN";"India";1;11;"09/16/2004 16:31:32";NULL
4;"AU";"Australia";6;12;"09/16/2004 16:31:32";NULL
5;"CA";"Canada";4;13;"09/16/2004 16:31:32";NULL
6;"US";"United States";4;14;"09/16/2004 16:31:32";NULL
7;"MX";"Mexico";4;15;"09/16/2004 16:31:32";NULL
8;"GB";"United Kingdom";3;16;"09/16/2004 16:31:32";NULL
9;"DE";"Germany";3;17;"09/16/2004 16:31:32";NULL
10;"FR";"France";3;18;"09/16/2004 16:31:32";NULL
11;"IT";"Italy";3;19;"09/16/2004 16:31:32";NULL
12;"ES";"Spain";3;20;"09/16/2004 16:31:32";NULL
13;"FI";"Finland";3;21;"09/16/2004 16:31:32";NULL
14;"SE";"Sweden";3;22;"09/16/2004 16:31:32";NULL
15;"IE";"Ireland";3;23;"09/16/2004 16:31:32";NULL
16;"NL";"Netherlands";3;24;"09/16/2004 16:31:32";NULL
17;"DK";"Denmark";3;25;"09/16/2004 16:31:32";NULL
18;"BR";"Brazil";5;85;"09/30/2004 11:25:43";NULL
19;"KR";"Korea, Republic of";1;88;"09/30/2004 11:25:43";NULL
20;"NZ";"New Zealand";6;89;"09/30/2004 11:25:43";NULL
21;"BE";"Belgium";3;79;"09/30/2004 11:25:43";NULL
22;"AT";"Austria";3;78;"09/30/2004 11:25:43";NULL
23;"NO";"Norway";3;82;"09/30/2004 11:25:43";NULL
24;"LU";"Luxembourg";3;81;"09/30/2004 11:25:43";NULL
25;"PT";"Portugal";3;83;"09/30/2004 11:25:43";NULL
26;"GR";"Greece";3;80;"09/30/2004 11:25:43";NULL
27;"IL";"Israel";1;86;"09/30/2004 11:25:43";NULL
28;"CH";"Switzerland";3;84;"09/30/2004 11:25:43";NULL
29;"A1";"Anonymous Proxy";0;0;"09/30/2004 11:25:43";NULL
30;"A2";"Satellite Provider";0;0;"09/30/2004 11:25:43";NULL
31;"AD";"Andorra";3;0;"09/30/2004 11:25:43";NULL
32;"AE";"United Arab Emirates";1;0;"09/30/2004 11:25:43";NULL
33;"AF";"Afghanistan";1;0;"09/30/2004 11:25:43";NULL
34;"AG";"Antigua and Barbuda";7;0;"09/30/2004 11:25:43";NULL
35;"AI";"Anguilla";7;0;"09/30/2004 11:25:43";NULL
36;"AL";"Albania";3;0;"09/30/2004 11:25:43";NULL
37;"AM";"Armenia";3;0;"09/30/2004 11:25:43";NULL
38;"AN";"Netherlands Antilles";3;0;"09/30/2004 11:25:43";NULL
39;"AO";"Angola";2;0;"09/30/2004 11:25:43";NULL
40;"AP";"Asia/Pacific Region";2;0;"09/30/2004 11:25:43";NULL
41;"AQ";"Antarctica";8;0;"09/30/2004 11:25:43";NULL
42;"AR";"Argentina";5;0;"09/30/2004 11:25:43";NULL
43;"AS";"American Samoa";6;0;"09/30/2004 11:25:43";NULL
44;"AW";"Aruba";5;0;"09/30/2004 11:25:43";NULL
45;"AZ";"Azerbaijan";1;0;"09/30/2004 11:25:43";NULL
46;"BA";"Bosnia and Herzegovina";3;0;"09/30/2004 11:25:43";NULL
47;"BB";"Barbados";5;0;"09/30/2004 11:25:43";NULL
48;"BD";"Bangladesh";1;0;"09/30/2004 11:25:43";NULL
49;"BF";"Burkina Faso";2;0;"09/30/2004 11:25:43";NULL
50;"BG";"Bulgaria";3;0;"09/30/2004 11:25:43";NULL
51;"BH";"Bahrain";1;0;"09/30/2004 11:25:43";NULL
52;"BI";"Burundi";2;0;"09/30/2004 11:25:43";NULL
53;"BJ";"Benin";2;0;"09/30/2004 11:25:43";NULL
54;"BM";"Bermuda";4;0;"09/30/2004 11:25:43";NULL
55;"BN";"Brunei Darussalam";1;0;"09/30/2004 11:25:43";NULL
56;"BO";"Bolivia";5;0;"09/30/2004 11:25:43";NULL
57;"BS";"Bahamas";7;0;"09/30/2004 11:25:43";NULL
58;"BT";"Bhutan";1;0;"09/30/2004 11:25:43";NULL
59;"BV";"Bouvet Island";5;0;"09/30/2004 11:25:43";NULL
60;"BW";"Botswana";2;0;"09/30/2004 11:25:43";NULL
61;"BY";"Belarus";3;0;"09/30/2004 11:25:43";NULL

2、执行导入命令

C:\>sqlldr userid=system/manager control=test.ctl

c)复杂格式的导入
Sqlldr
sql loader可以把一些以文本格式存放的数据顺利的导入到oracle数据库中,
是一种在不同数据库之间进行数据迁移的非常方便而且通用的工具。
缺点就速度比较慢,另外对blob等类型的数据就有点麻烦了。
用法: SQLLDR keyword=value [,keyword=value,…]
有效的关键字:
userid — ORACLE username/password
control – 控制文件
log – 记录的日志文件
bad – 坏数据文件
data – 数据文件
discard – 丢弃的数据文件
discardmax – 允许丢弃数据的最大值 (全部默认)
skip — Number of logical records to skip (默认0)
load — Number of logical records to load (全部默认)
errors – 允许的错误记录数 (默认50)
rows — Number of rows in conventional path bind array or between direct path data saves
(每次提交的记录数,默认: 常规路径 64, 所有直接路径)
bindsize — Size of conventional path bind array in bytes(默认256000)
每次提交记录的缓冲区的大小(字节为单位,默认256000)
silent –禁止输出信息 (header,feedback,errors,discards,partitions)
direct – 使用直通路径方式导入 (默认FALSE) 某日读了一篇文章,说是如果选择导入方式为true或是y,则会绕过了SGA,直接写datafile,而且是直接在HWM以上写。这就导致了HWM会被不断抬高,这样即使后来delete掉了这批数据,HWM依然没有被降下来。HWM不断被抬高的直接表现就是在做全表扫描的时候会越来越慢
parfile — parameter file: name of file that contains parameter specifications
parallel — 并行导入 (默认FALSE)
file — File to allocate extents from
与bindsize成对使用,其中较小者会自动调整到较大者
sqlldr先计算单条记录长度,乘以rows,如小于bindsize,不会试图扩张rows以填充bindsize;如超出,则以bindsize为准。
external_table
— use external table for load; NOT_USED, GENERATE_ONLY, EXECUTE(默认NOT_USED)
columnarrayrows
— Number of rows for direct path column array(默认5000)
streamsize — Size of direct path stream buffer in bytes(默认256000)
multithreading
— use multithreading in direct path
resumable — enable or disable resumable for current session(默认FALSE)
resumable_name
— text string to help identify resumable statement
resumable_timeout
— wait time (in seconds) for RESUMABLE(默认7200)
date_cache — size (in entries) of date conversion cache(默认1000)
注意:有两种方式可以指定命令行参数:通过位置或者通过关键字。前者的例子:’sqlldr scott/tiger foo’;
后者的例子:’sqlldr control=foo userid=scott/tiger’;
不能前面使用关键字指定后面通过位置制定的混合方式;
比如:’sqlldr scott/tiger control=foo logfile=log’ 是允许的,
但’sqlldr scott/tiger control=foo log’不允许。
为清楚起见最好所有命令行参数都用关键字指定。
控制文件:
一个控制命令的脚本文件,通常以ctl结尾,内容如下:
LOAD DATA
INFILE ‘t.dat’ 要导入的文件
// INFILE ‘tt.date’ 导入多个文件
// INFILE * 表示要导入的内容就在control文件里 下面的BEGINDATA后面就是导入的内容
INTO TABLE table_name 指定装入的表
BADFILE ‘c:\bad.txt’ 可选,指定坏文件地址,缺省在当前目录下生成与原文件名一致的.bad文件
************* 以下是4种装入表的方式
APPEND 原先的表有数据 就加在后面
INSERT 装载空表 如果原先的表有数据 sqlloader会停止 默认值
REPLACE 原先的表有数据 原先的数据会全部删除
TRUNCATE 指定的内容和replace的相同 会用truncate语句删除现存数据
************* 指定分隔符
FIELDS TERMINATED BY ‘,’ OPTIONALLY ENCLOSED BY ‘”‘
// TERMINATED BY WRITESPACE 以空白分割
TRAILING NULLCOLS 表的字段没有对应的值时允许为空
************* 下面是表的字段
(
col_1 , col_2 ,col_filler FILLER // FILLER 关键字 此列的数值不会被装载
// 如: lg,lg,not 结果 lg lg
)
如果没声明FIELDS TERMINATED BY ‘,’ 时,可以用下面两种方式实现同样功能:
1.为每一列指定分隔符
(
col_1 [interger external] TERMINATED BY ‘,’ ,
col_2 [date “dd-mon-yyy”] TERMINATED BY ‘,’ ,
col_3 [char] TERMINATED BY ‘,’ OPTIONALLY ENCLOSED BY ‘lg’
)
2.用位置告诉字段装载数据
(
col_1 position(1:2),
col_2 position(3:10),
col_3 position(*:16), // 这个字段的开始位置在前一字段的结束位置
col_4 position(1:16),
col_5 position(3:10) char(8) // 指定字段的类型
)
BEGINDATA 对应开始的 INFILE * 要导入的内容就在control文件里
10,Sql,what
20,lg,show

启用约束时使用exceptions表来跟踪不符合约束的数据并修正

启用约束时使用exceptions表来跟踪不符合约束的数据并修正

使用 EXCEPTIONS 表
1. 创建 EXCEPTIONS 表 (utlexcpt.sql)
2. 使用 EXCEPTIONS 子句执行 ALTER TABLE
3. 使用 EXCEPTIONS 子查询查找包含无效数据的行
4. 纠正错误
5. 再次执行 ALTER TABLE 以启用约束

如何识别行违反
EXCEPTIONS 子句帮助识别任何违反已启用的约束的行按下列步骤检测违反
约束的行为纠正它们并重新启用约束
1 如果还未创建请在管理目录中运行 utlexcpt.sql 脚本以创建异常表

SQL> @?/rdbms/admin/utlexcpt
Statement processed.
SQL> DESCRIBE exceptions
Name Null?Type
-------------------------- ------- ----------------
ROW_ID UNDEFINED
OWNER VARCHAR2(30)
TABLE_NAME VARCHAR2(30)
CONSTRAINT VARCHAR2(30)

在 Windows NT 中该脚本位于

%ORACLE_HOME%\RDBMS\ADMIN 目录下

2 使用 EXCEPTIONS 子句执行 ALTER TABLE 命令

SQL> ALTER TABLE summit.employee
2 ENABLE VALIDATE CONSTRAINT employee_dept_id_fk
3 EXCEPTIONS INTO system.exceptions;
ALTER TABLE summit.employee
*
ORA-02298:cannot enable (summit.EMP_DEPT_FK) - parent keys not
found

如果 EXCEPTIONS 表未用所有者姓名限定则它必须属于正改变
的表的所有者
将行插入 EXCEPTIONS 表中如果重新运行该命令将截断
EXCEPTIONS 表以删除全部现有的行
3 使用 EXCEPTIONS 表上的子查询标识无效数据

SQL> SELECT rowid, id, last_name, dept_id
2 FROM summit.employee
3 WHERE ROWID in (SELECT row_id
4 FROM exceptions)
5 FOR UPDATE;
ROWID ID LAST_NAME DEPT_ID
------------------- ----- --------------- --------
AAAAeyAADAAAAA1AAA 1003 Pirie 50
1 row selected.

4 更正数据中的错误

SQL> UPDATE summit.employee
2 SET id=10
3 WHERE rowid='AAAAeyAADAAAAA1AAA';
1 row processed.
SQL> COMMIT;
Statement processed.

5 截断 EXCEPTIONS 表并重新启用约束

SQL> TRUNCATE TABLE exceptions;
Statement processed.
SQL> ALTER TABLE summit.employee
2 ENABLE VALIDATE CONSTRAINT employee_dept_id_fk
3 EXCEPTIONS INTO system.exceptions;
Statement processed