不知DBA有时候是否会遇到这样的尬尴局面,做某些Schema的迁移的时候,由于用到Public的db link,然而由于不知道db link中目标端账号的密码,因此无法在新环境重新创建DB link。
本次实验的思路是将视图dba_db_links的基表link$迁移到出来并替换到新环境。因为用户的password密文保存在link$基表中。
—-首先交代两边环境,都是Linux上11.2.0.3的版本,在10.2.0.4上也测试过。
一边数据库seven,一边数据库ginna。假设在不知道scott的密码情况下将seven端的名为test的db link迁移至ginna端。
源端操作:
首先还在源端创建一个public 的db link 名为test。
seven >create public database link test connect to scott identified by tiger using 'ginna';Database link created.seven >select * from global_name@test;GLOBAL_NAME———————GINNAseven >select * from dba_db_links;OWNERDB_LINKUSERNAMEHOSTCREATED—————————— —————————— —————————— —————————— ———PUBLICTESTSCOTTginna06-MAR-15创建中间表trans1,CTAS基表sys.link$。
seven >create table trans1 as select * from sys.link$;Table created.seven >select count(*) from trans1; COUNT(*)———-1然后在seven用户下创建第二个中间表trans2,(seven 有dba权限)。
seven >conn seven/oracleConnected.seven >create table trans2 as select * from sys.link$; —–当然不能直接CTAS基表的。create table trans2 as select * from sys.link$*ERROR at line 1:ORA-01031: insufficient privilegesseven >create table trans2 as select * from sys.trans1;Table created.seven >select count(*) from trans2; COUNT(*)———-1seven >OK,中间表trans2创建成功。
目标端操作:
在目标端创建名为test2的Public db link。
ginna >show userUSER is "SYS"ginna >select * from dba_db_links;no rows selectedginna >create public database link test2 connect to seven identified by oracle using 'seven';Database link created.ginna >select * from global_name@test2;GLOBAL_NAME———————-SEVENginna >set line 200ginna >col db_link for a30ginna >col host for a30ginna >select * from dba_db_links;OWNERDB_LINKUSERNAMEHOSTCREATED—————————— —————————— —————————— —————————— ———PUBLICTEST2SEVENseven06-MAR-15
通过test2的db link将seven端的trans2表CTAS到表trans3。
ginna >create table trans3 as select * from trans2@test2;Table created.ginna >select count(*) from trans3; COUNT(*)———-1
truncate掉基表sys.link$,为了安全起见也可以先备份下基表,并将表trans3插入到基表link$中。
ginna >truncate table sys.link$;Table truncated.ginna >insert into sys.link$ select * from trans3;1 row created.ginna >commit;Commit complete.现在再查一下dba_db_links就可以发现名为test的db link已经成功迁移在ginna端。
ginna >select * from dba_db_links;OWNERDB_LINKUSERNAMEHOSTCREATED—————————— —————————— —————————— —————————— ———PUBLICTESTSCOTTginna06-MAR-15测试db link 的有效性:
ginna >select * from global_name@test;GLOBAL_NAME——————GINNA
OK,现在还有一个问题,之前名为test2的db link现在还是否存在?是否能重建?
显然是不能的:
ginna >create public database link test2 connect to seven identified by oracle using 'seven';create public database link test2 connect to seven identified by oracle using 'seven'*ERROR at line 1:ORA-02011: duplicate database link name前提需要刷新下shared pool。之后再重建就可以了。
ginna >alter system flush shared_pool;System altered.ginna >create public database link test2 connect to seven identified by oracle using 'seven';Database link created.ginna >select * from dba_db_links;OWNERDB_LINKUSERNAMEHOSTCREATED—————————— —————————— —————————— —————————— ———PUBLICTESTSCOTTginna06-MAR-15PUBLICTEST2SEVENseven06-MAR-15ginna >当然如果不flush shared pool的话直接删除db link则会遭遇ora-600内部报错:
SQL> drop public database link test2;drop public database link test2*ERROR at line 1:ORA-00603: ORACLE server session terminated by fatal errorORA-00600: internal error code, arguments: [16500], [kqdDBLinkUpdate], [3], [0], [TEST2], [], [], [], [], [], [], []Process ID: 11165Session ID: 152 Serial number: 359SQL> SQL> create public database link test2 connect to seven identified by oracle using 'seven';ERROR:ORA-03114: not connected to ORACLESQL> conn / as sysdbaConnected.SQL> create public database link test2 connect to seven identified by oracle using 'seven';Database link created.SQL> drop public database link test2;Database link dropped.SQL>
,再回头,便生出无限羁绊。那是彼此的刺在对方心里留下的痕迹,