不知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
---------------------
GINNA
seven >select * from dba_db_links;
OWNER DB_LINK USERNAME HOST CREATED
------------------------------ ------------------------------ ------------------------------ ------------------------------ ---------
PUBLIC TEST SCOTT ginna 06-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/oracle
Connected.
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 privileges
seven >create table trans2 as select * from sys.trans1;
Table created.
seven >select count(*) from trans2;
COUNT(*)
----------
1
seven >
OK,中間表trans2建立成功。
目標端操做:
在目標端建立名爲test2的Public db link。
ginna >show user
USER is "SYS"
ginna >select * from dba_db_links;
no rows selected
ginna >create public database link test2 connect to seven identified by oracle using 'seven';
Database link created.
ginna >select * from global_name@test2;
GLOBAL_NAME
----------------------
SEVEN
ginna >set line 200
ginna >col db_link for a30
ginna >col host for a30
ginna >select * from dba_db_links;
OWNER DB_LINK USERNAME HOST CREATED
------------------------------ ------------------------------ ------------------------------ ------------------------------ ---------
PUBLIC TEST2 SEVEN seven 06-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;
OWNER DB_LINK USERNAME HOST CREATED
------------------------------ ------------------------------ ------------------------------ ------------------------------ ---------
PUBLIC TEST SCOTT ginna 06-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;
OWNER DB_LINK USERNAME HOST CREATED
------------------------------ ------------------------------ ------------------------------ ------------------------------ ---------
PUBLIC TEST SCOTT ginna 06-MAR-15
PUBLIC TEST2 SEVEN seven 06-MAR-15
ginna >
固然若是不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 error
ORA-00600: internal error code, arguments: [16500], [kqdDBLinkUpdate], [3], [0], [TEST2], [], [], [], [], [], [], []
Process ID: 11165
Session ID: 152 Serial number: 359
SQL>
SQL> create public database link test2 connect to seven identified by oracle using 'seven';
ERROR:
ORA-03114: not connected to ORACLE
SQL> conn / as sysdba
Connected.
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>
固然咱們也能夠不建立test2這個db link,主要就是將trans1這張中間表遷移至ginna庫就能夠了,這有不少方法,能夠直接使用exp/imp或者數據泵均可以。條條大道通羅馬,方法有不少種,主要就是將seven端的sys.link$基表遷移至ginna端並替換掉ginna端的sys.link$。