1.在线方式迁移
通过dblink的方式远程克隆。帮我们做了很多工作,这个也是简单的迁移方式。该方式对于相同版本的pdb之间的迁移没问题。如果是跨版本的,比如从12.1到19c也可以使用。在19c上clone完之后,需要运行dbupgrade脚本。
2.离线方式迁移
将原库离线或只读方式打开,将文件复制到目标库,然后再创建PDB。如果使用了ASM(默认使用了OMF这个特性,OMF这个特性贼棒),会变得比较复杂。
在线方式迁移
在新的容器数据库上执行以下操作
1.在目标库上创建到源库的dblink
create database link clone_link connect to system identified by oracle using '(description=(address=(protocol=tcp)(host=192.168.10.21)(port=1521))(connect_data=(service_name=pdb1)))';
2.执行远程创建
create pluggable database pdb1 from pdb1@clone_link
下面是在通过dblink远程克隆时alert日志对应的输出
This instance was first to open pluggable database PDB1 (container=3) Database Characterset for PDB1 is ZHS16GBK Deleting old file#319 from file$ Deleting old file#320 from file$ Deleting old file#321 from file$ Deleting old file#325 from file$ Deleting old file#326 from file$ Deleting old file#327 from file$ Deleting old file#328 from file$ Deleting old file#329 from file$ Adding new file#73 to file$(old file#319) Adding new file#74 to file$(old file#320) Adding new file#75 to file$(old file#321) Adding new file#76 to file$(old file#325) Adding new file#77 to file$(old file#326) Adding new file#78 to file$(old file#327) Adding new file#79 to file$(old file#328) Adding new file#80 to file$(old file#329) Successfully created internal service pdb1 at open ALTER SYSTEM: Flushing buffer cache inst=1 container=3 local **************************************************************** Post plug operations are now complete. Pluggable database PPDBETC with pdb id - 3 is now marked as NEW. **************************************************************** Completed: create pluggable database pdb1 from pdb1@clone_link如果源端和目标端对应的patch不一致或者出现一些无效的组件等,PDB会处以restricted模式。
SQL> show pdbs CON_ID CON_NAME OPEN MODE RESTRICTED ---------- ------------------------------ ---------- ---------- 2 PDB$SEED READ ONLY NO 3 PDB1 READ WRITE YES常用的用来检查补丁或冲突的SQL语句
select patch_id, patch_uid, version, status, description from dba_registry_sqlpatch;
select inst_id,name,open_mode,restricted from gv$pdbs order by 1,2;
select name,con_id,con_uid,open_mode,restricted,guid from v$pdbs order by 1,2;
select status, message, action from pdb_plug_in_violations where status !='RESOLVED';
如果是补丁不一致,通过datapatch一般能解决大部分问题
[oracle@xd08dbadm01 OPatch]$ ./datapatch -verbose -pdbs PDB1
如果datapatch成功执行后,数据库还处于restricted模式,那么大部分情况下,是因为一些无效对象导致的。在这个模式下,数据库时不正常的,千万不要切换和运行业务。
查询无效对象
select owner,object_name,object_type,status from dba_objects where status='INVALID' and OWNER IN ('PUBLIC','SYS','SYSTEM','XDB','ORDSYS','ORDPLUGINS','ORDDATA','MDSYS','CTXSYS');
SQL> select owner,object_name,object_type,status from dba_objects where status='INVALID' and OWNER IN ('PUBLIC','SYS','SYSTEM','XDB','ORDSYS','ORDPLUGINS','ORDDATA','MDSYS','CTXSYS'); OWNER OBJECT_NAME OBJECT_TYPE STATUS --------- ----------------- --------------- -------- XDB DBMS_XDBUTIL_INT PACKAGE BODY INVALID XDB DBMS_XDBT PACKAGE BODY INVALID CTXSYS DRILOAD PACKAGE BODY INVALID CTXSYS DRVDOC PACKAGE BODY INVALID MDSYS SDO_OLS PACKAGE BODY INVALID查询组件状态
select substr(comp_name,1,30) comp_name, substr(comp_id,1,10) comp_id,substr(version,1,12) version,status from dba_registry;
查询后会发现,一些组件可能也是无效的
通过dba_errors去下钻出现问题的根本原因
SQL> select text from dba_errors where name='DBMS_XDBUTIL_INT' and owner='XDB'; TEXT ------------------------------------------------------------------------------ PLS-00201: identifier 'DBMS_SQL' must be declared PL/SQL: Statement ignored PLS-00201: identifier 'DBMS_SQL' must be declared PL/SQL: Statement ignored PLS-00201: identifier 'DBMS_SQL' must be declared PL/SQL: Statement ignored PLS-00201: identifier 'DBMS_SQL' must be declared PL/SQL: Statement ignored PLS-00201: identifier 'DBMS_SQL' must be declared PL/SQL: Statement ignored 10 rows selected. SQL> select text from dba_errors where name='DBMS_XDBT' and owner='XDB'; TEXT ------------------------------------------------------------------------ PLS-00201: identifier 'CTX_DOC' must be declared PL/SQL: Statement ignored 2 rows selected. SQL> select text from dba_errors where name='DRILOAD' and owner='CTXSYS'; TEXT ------------------------------------------------------------------------- PLS-00201: identifier 'DBMS_SQL' must be declared PL/SQL: Statement ignored PLS-00201: identifier 'DBMS_SQL' must be declared PL/SQL: Statement ignored 4 rows selected. SQL> select text from dba_errors where name='DRVDOC' and owner='CTXSYS'; TEXT ------------------------------------------------------------------------ PLS-00201: identifier 'DBMS_SQL' must be declared PL/SQL: Statement ignored PLS-00201: identifier 'DBMS_SQL' must be declared PL/SQL: Statement ignored PLS-00201: identifier 'DBMS_SQL' must be declared PL/SQL: Statement ignored PLS-00201: identifier 'DBMS_SQL' must be declared PL/SQL: Statement ignored PLS-00201: identifier 'DBMS_SQL' must be declared PL/SQL: Statement ignored 10 rows selected. SQL> select text from dba_errors where name='SDO_OLS' and owner='MDSYS'; TEXT ----------------------------------------------------------------------- PLS-00201: identifier 'UTL_HTTP' must be declared PL/SQL: Item ignored PLS-00201: identifier 'UTL_HTTP' must be declared PL/SQL: Item ignored PLS-00201: identifier 'UTL_HTTP' must be declared PL/SQL: Statement ignored PLS-00320: the declaration of the type of this expression is incomplete or malformed PL/SQL: Statement ignored 10 rows selected. SQL>通过以上,可以发现这些无效对象是因为权限的问题,导致无法正常编译。
SQL> grant execute on dbms_sql to XDB,CTXSYS;
SQL> grant execute on CTX_DOC to XDB;
SQL> grant execute on UTL_HTTP to MDSYS;
授权后,可以通过这下面的命令进行编译
SQL> exec dbms_pdb.exec_as_oracle_script('alter package XDB.DBMS_XDBT compile body');
SQL> exec dbms_pdb.exec_as_oracle_script('alter package CTXSYS.DRVDOC compile body');
SQL> exec dbms_pdb.exec_as_oracle_script('alter package CTXSYS.DRILOAD compile body');
SQL> exec dbms_pdb.exec_as_oracle_script('alter package XDB.DBMS_XDBUTIL_INT compile body');
SQL> exec dbms_pdb.exec_as_oracle_script('alter package MDSYS.SDO_OLS compile body');
也可以通过catcon.pl脚本进行批量编译
$ORACLE_HOME/perl/bin/perl -I$ORACLE_HOME/perl/lib -I$ORACLE_HOME/rdbms/admin $ORACLE_HOME/rdbms/admin/catcon.pl -l /home/oracle/logs -b comp_invalid_objs -- --x"@$ORACLE_HOME/rdbms/admin/utlrp.sql"
重启数据库后,就正常了。打开PDB数据库
SQL> alter pluggable database pdb1 open instances=all;
启用并行,收集数据库和用户的统计信息
SQL> select dbms_stats.get_prefs('CONCURRENT') from dual;
如果输出是FALSE,通过下面的命令启用
exec dbms_stats.set_global_prefs('CONCURRENT','TRUE');
收集统计信息
SQL> exec dbms_stats.gather_dictionary_stats;
SQL> exec dbms_stats.gather_schema_stats(ownname=>'ABC',degree=>6);
如果是RAC环境,可能会出现下面的问题。如果出现下面的问题,请确保所有的节点都处于打开状态,并能访问dblink正常工作
ORA-65028: Unable to open plugin data file at path
ORA-17503: ksfdopn:2 Failed to open file
ORA-07202: sltln: invalid parameter to sltln.
2.离线方式迁移对于使用文件系统的迁移来说,比较简单。可参考链接https://www.oracle.com/webfolder/technetwork/tutorials/obe/db/12c/r1/pdb/pdb_unplug_plug/pdb_unplug_plug.html
如果使用了ASM,这种方式相对来说复杂一些,因为ASM默认使用了OMF,从源端复制到目标端时不能使用后面的文件编号信息,这些是系统自动生成的。想通过复制文件到目标端会比较不方便。我们可以通过asmcmd cp命令来传输数据文件
首先,以只读方式打开可插拔数据库
sqlplus / as sysdba
alter pluggable database pdb1 open read only;
其次,在线生成pdb的描述文件
如果用unplug into,必须删除、重建PDB后,PDB才能正常使用。建议用dbms_pdb.describe生成描述文件,效果是一样的。
exec dbms_pdb.describe('/home/oracle/pdbxj01.xml','pdb1');其次,生成传输到目标端的命令行
如果使用了bigfile tablespace,下面可以通过。如果不是,需要调整
set lines 160select 'asmcmd cp '||file_name||' --port 1525 sys/oracle@192.168.10.X.+ASM2:+DATA/stage/'||tablespace_name from dba_data_files;
asmcmd cp可参考How to Copy asm files between remote ASM instances using ASMCMD command (Doc ID 785580.1)
注意:如果出现出现以下错误,主要是因为GI的版本导致的,需要应用补丁,请参考1918906.1。如果要跟踪asmcmd,可以设置export DBI_TRACE=1
ORA-15056: additional error message
ORA-17630: Mismatch in the remote file protocol version client 2 server 3
ORA-06512: at "SYS.X$DBMS_DISKGROUP", line 486
ORA-06512: at line 3 (DBD ERROR: OCIStmtExecute)
再次,修改pdb描述文件中的位置,并传到目标端
最后,在目标端创建可插拔数据库
create pluggable database pdb_plug_copy using '/home/oracle/pdb1.xml' copy;
Reference
https://www.oracle.com/webfolder/technetwork/tutorials/obe/db/12c/r1/pdb/pdb_unplug_plug/pdb_unplug_plug.html
https://docs.oracle.com/en/database/oracle/oracle-database/18/obeze/index.html
How to Copy asm files between remote ASM instances using ASMCMD command (Doc ID 785580.1)
Copying File Across Remote Servers: ASMCMD-8016, ORA-17628, ORA-17630, ORA-06512 (Doc ID 1918906.1)
Datapatch: Database 12c or later Post Patch SQL Automation (Doc ID 1585822.1)
Complete checklist for 12c R1 PDB upgrade (Upgrading single/multiple Pluggable database (PDB)) (Doc ID 1933391.1)