关于db link权限分配的苦旅(一)
生活随笔
收集整理的這篇文章主要介紹了
关于db link权限分配的苦旅(一)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
昨天接到一個(gè)開發(fā)的需求,內(nèi)容看起來非常簡單。
申請(qǐng)數(shù)據(jù)庫192.168.1.118:1522:TEST下用戶APP_TE_FLOW_128賦予對(duì)表testore_log的查詢權(quán)限。。。
貌似這個(gè)語句也就幾秒鐘就可以搞定,直接賦予對(duì)象權(quán)限,或者角色都可以,
類似grant select on test.testore_log to APP_TE_FLOW_128;
但是這個(gè)看似簡單的案例,我想用兩篇日志來總結(jié),因?yàn)槔锩嬗性S多的內(nèi)容量,中間的過程也是異常曲折,而且最開始的推論很可能是錯(cuò)誤的,然后還可以上升到業(yè)務(wù)層面。
所以我會(huì)按照真實(shí)的分析思路來說這個(gè)問題,看完之后大家就會(huì)明白了。原諒我分析中的錯(cuò)誤先。
我直接使用dba賬號(hào)登錄,然后直接使用alter session set current_schema=APP_TE_FLOW_128;然后觸發(fā)了下面的sql語句。
sys@TEST> select count(*) from testore_log;
select count(*) from testore_log
???????????????????? *
ERROR at line 1:
ORA-00942: table or view does not exist
ORA-02063: preceding line from GCDB
從這個(gè)錯(cuò)誤可以看出,是使用了db link,但是訪問的時(shí)候貌似沒有訪問到。
整個(gè)訪問的流程類似下面的形式,在ip為118和128都存在一個(gè)test用戶,兩個(gè)test用戶的數(shù)據(jù)不同,118庫中的APP_TE_FLOW_128訪問的一部分?jǐn)?shù)據(jù)是118中的test用戶,另外一部分是128總的test用戶,當(dāng)然是間接通過flow0這個(gè)用戶以db link的形式來訪問。
在118服務(wù)器端做檢查
sys@TEST> select * from dba_synonyms where synonym_name=upper('testore_log');
OWNER????????????????????????? SYNONYM_NAME?????????????????? TABLE_OWNER??????????????????? TABLE_NAME???????????????????? DB_LINK
------------------------------ ------------------------------ ------------------------------ ------------------------------ ---------
APP_TE_FLOW_128??????????????? testore_log???????????????? TEST?????????????????????????? testore_log???????????????? GCDB
可以看到這個(gè)同義詞很明顯是使用了db link為gcdb
進(jìn)一步查看db link的情況,發(fā)現(xiàn)存在這一些和gcdb相關(guān)的db link,都是位于不同的用戶下。
sys@TEST> SELECT * FROM DBA_DB_LINKS WHERE DB_LINK='GCDB';
OWNER?????????????? DB_LINK? USERNAME? HOST?????????????? CREATED
------------------- -------- --------- ------------------ ------------
PUBLIC????????????? GCDB???? TLCS0???? TEST_TEST_CENTER??? 23-MAY-11
TEST??????????????? GCDB???? TEST0???? TEST_TEST_CENTER??? 09-JUN-10
APP_TEST_QUERY_128? GCDB???? QUERY0??? TEST_TEST_CENTER??? 09-JUN-10
APP_TE_FLOW_128???? GCDB???? FLOW0???? TEST_TEST_CENTER??? 09-JUN-10
APP_TE_SDE_128????? GCDB???? SDE0????? TEST_TEST_CENTER??? 02-JUL-10
然后來得到db link最終的服務(wù)信息,最終得到服務(wù)器ip即128的服務(wù)器
$ tnsping TEST_TEST_CENTER
Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = TESTcenter.cyou.com)(PORT = 1525))) (CONNECT_DATA = (SERVICE_NAME = GCDB)))
$ cat /etc/hosts|grep TESTcenter.cyou.com
192.168.1.128? TESTcenter.cyou.com
好了,簡單的檢查完成,我們繼續(xù)測(cè)試。
切換到APP_TE_FLOW_128下。
sys@TEST> alter session set current_schema=APP_TE_FLOW_128;
Session altered.
然后查看all_synonyms沒有得到任何結(jié)果,這是一個(gè)疑點(diǎn)。
sys@TEST>? select * from all_synonyms where owner='APP_TE_FLOW_128' and synonym_name=upper('testore_log');
no rows selected
嘗試得到表結(jié)構(gòu)信息,竟然報(bào)錯(cuò)了,說明還是可以訪問,只是最終訪問不通。
sys@TEST> desc testore_log
ERROR:
ORA-04043: object "TEST"."testore_log" does not exist
ORA-02063: preceding line from GCDB
在128服務(wù)器端,切換到flow0這個(gè)用戶
sys@GCDB> alter session set current_schema=FLOW0;
Session altered.
查看權(quán)限都沒有問題,都是存在的。
sys@GCDB> SELECT * FROM DBA_TAB_PRIVS WHERE TABLE_NAME=upper('testore_log');
GRANTEE??????????? OWNER?? TABLE_NAME??? GRANTOR?? PRIVILEGE??? GRA HIE
------------------ ------- ---------------- --------- ------------ --- ---
FLOW0????????????? TEST??? testore_log?? TEST????? SELECT?????? NO? NO
這是一個(gè)疑問,
然后下面的情況就更奇怪了。
在118服務(wù)器端,我嘗試通過db link來查看gcdb中的數(shù)據(jù)表的情況。cat基本類似于user_tables
發(fā)現(xiàn)118的服務(wù)器中存在一個(gè)同義詞。
sys@TEST> select table_name,table_type from cat@gcdb;
TABLE_NAME???????????????????? TABLE_TYPE
------------------------------ -----------
USER_POINT???????????????????? SYNONYM
然后我通過dba_synonyms去查看這個(gè)同義詞,竟然又沒有db link的關(guān)聯(lián),著實(shí)奇怪。
sys@TEST> select * from dba_synonyms where synonym_name='USER_POINT';
OWNER????????????????????????? SYNONYM_NAME?????????????????? TABLE_OWNER??????????????????? TABLE_NAME???????????????????? DB_LINK
------------------------------ ------------------------------ ------------------------------ ------------------------------ ------------------------------
APP_TE_FLOW_128??????????????? USER_POINT???????????????????? TEST?????????????????????????? USER_POINT
為了更進(jìn)一步驗(yàn)證,直接查看gcdb中的表user_point的rowid,也沒有任何問題,如果想進(jìn)一步驗(yàn)證,其實(shí)會(huì)發(fā)現(xiàn)還是在128庫中的。
sys@TEST> select rowid from user_point@gcdb where rownum<2;
ROWID
------------------
AAAPNRAAHAABdzUAAw
那么這個(gè)問題就很奇怪了,看起來解釋不通啊。所以這個(gè)關(guān)系理不清楚,壓根沒法去賦權(quán)限。
繼續(xù)檢查。
在128服務(wù)器端繼續(xù)查看,發(fā)現(xiàn)確實(shí)有對(duì)應(yīng)的這個(gè)表,而且賦予了基本的查詢權(quán)限。
SQL>SELECT * FROM DBA_TAB_PRIVS WHERE TABLE_NAME='USER_POINT';
GRANTEE??????????????????????? OWNER????????????????????????? TABLE_NAME?????????? GRANTOR??????????????????????? PRIVILEGE??????????????????????????????? GRA HIE
------------------------------ ------------------------------ -------------------- ------------------------------ ---------------------------------------- --- ---
FLOW0????????????????????????? TEST?????????????????????????? USER_POINT?????????? TEST?????????????????????????? SELECT?????????????????????????????????? NO? NO
那么這個(gè)問題怎么解釋呢,看起來確實(shí)是很費(fèi)神。如果仔細(xì)查看前面的線索,其實(shí)就會(huì)發(fā)現(xiàn)一個(gè)public的db link其實(shí)在暗中操作。
就是最開始我們給出的檢查結(jié)果。在118的庫中確實(shí)存在一個(gè)public的db link為gcdb.
gc端sys@TEST> SELECT * FROM DBA_DB_LINKS WHERE DB_LINK='GCDB';
OWNER?????????????? DB_LINK? USERNAME? HOST?????????????? CREATED
------------------- -------- --------- ------------------ ------------
PUBLIC????????????? GCDB???? TLCS0???? TEST_TEST_CENTER??? 23-MAY-11
當(dāng)然我們就會(huì)發(fā)現(xiàn)那個(gè)用戶TLCS0在128的庫中也確實(shí)存在,一切手續(xù)都齊全。
sys@GCDB SELECT * FROM DBA_SYNONYMS WHERE OWNER='TLCS0';
OWNER????????????????????????? SYNONYM_NAME?????????????????? TABLE_OWNER??????????????????? TABLE_NAME?????????? DB_LINK
------------------------------ ------------------------------ ------------------------------ -------------------- ------------------------------
TLCS0????????????????????????? USER_POINT???????????????????? TEST?????????????????????????? USER_POINT
所以大體通過這個(gè)Public的db link我們基本明白了,為什么會(huì)出現(xiàn)這種奇怪的現(xiàn)象。
那么問題來了,為什么APP_TE_FLOW_128中的db link沒有起作用呢,一種很大的可能性就是這個(gè)db link有問題。
首選從dba_users中查到加密后的密碼。
sys@GCDB select username,password from dba_users where username='FLOW0';
USERNAME?????????????????????? PASSWORD
------------------------------ ------------------------------
FLOW0????????????????????????? BCF5E83CF6EF0269
因?yàn)檫@個(gè)db link創(chuàng)建的時(shí)間確實(shí)很早了,我也壓根沒法得最終的密碼,所以有一種看似不錯(cuò)的方案,那就是使用values的方式來重新創(chuàng)建一個(gè)db link來驗(yàn)證一下。這樣也不用重新動(dòng)原來的密碼了。
CREATE DATABASE LINK APP_TE_FLOW_128.GC_NEW_LINK CONNECT TO FLOW0 IDENTIFIED BY VALUES 'BCF5E83CF6EF0269' USING 'TEST_TEST_CENTER'
自認(rèn)為已經(jīng)解決問題在望,但是做了一個(gè)簡單的查詢,馬上讓我有些措手不及。持續(xù)了十多秒沒有反應(yīng),我感覺有些問題,馬上終止,然后就收到一個(gè)600錯(cuò)誤。
sys@TEST> select count(*)from test_20151208@APP_TE_FLOW_128.GC_NEW_LINK;
select count(*)from test_20151208@APP_TE_FLOW_128.GC_NEW_LINK
????????????????????????????????? *
ERROR at line 1:
ORA-00600: internal error code, arguments: [kzdlk_zt2 err], [18446744073709551603], [], [], [], [], [], []
這個(gè)問題在mos上查看了一番,發(fā)現(xiàn)是一個(gè)bug,對(duì)于values的方式還是存在一定的問題,也是有驚無險(xiǎn)。
ORA-00600: [Kzdlk_zt2 Err] While Selecting Using a Database Link (Doc ID 456320.1)
所以使用values的方式創(chuàng)建db link不通,那么我們只能DIY,重新在128的服務(wù)器上創(chuàng)建一個(gè)用戶,做權(quán)限分配,然后鏈接到118的庫中。
假設(shè)128中創(chuàng)建的用戶為flow
sys@GCDB> grant connect to flow0_new;
Grant succeeded.
然后創(chuàng)建了一個(gè)新的db link
sys@TEST> conn cydba/cydba
Connected.
cydba@TEST> create database link flow0_128 connect to flow0_new identified by flow0_new using 'TEST_TEST_CENTER';
Database link created.
但是訪問有些問題
select count(*) from test_20151208@flow0_128
就馬上調(diào)整為了public 的db link
?create public database link flow0_128 connect to flow0_new identified by flow0_new using 'TEST_TEST_CENTER';
?然后再次驗(yàn)證。這次就沒有問題了。
?alter session set current_schema=APP_TE_FLOW_128;
?cydba@TEST> select count(*)from TEST.testore_log@flow0_128 where rownum<2;
? COUNT(*)
----------
???????? 1
這個(gè)過程的問題明天再來解讀。 與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖
申請(qǐng)數(shù)據(jù)庫192.168.1.118:1522:TEST下用戶APP_TE_FLOW_128賦予對(duì)表testore_log的查詢權(quán)限。。。
貌似這個(gè)語句也就幾秒鐘就可以搞定,直接賦予對(duì)象權(quán)限,或者角色都可以,
類似grant select on test.testore_log to APP_TE_FLOW_128;
但是這個(gè)看似簡單的案例,我想用兩篇日志來總結(jié),因?yàn)槔锩嬗性S多的內(nèi)容量,中間的過程也是異常曲折,而且最開始的推論很可能是錯(cuò)誤的,然后還可以上升到業(yè)務(wù)層面。
所以我會(huì)按照真實(shí)的分析思路來說這個(gè)問題,看完之后大家就會(huì)明白了。原諒我分析中的錯(cuò)誤先。
我直接使用dba賬號(hào)登錄,然后直接使用alter session set current_schema=APP_TE_FLOW_128;然后觸發(fā)了下面的sql語句。
sys@TEST> select count(*) from testore_log;
select count(*) from testore_log
???????????????????? *
ERROR at line 1:
ORA-00942: table or view does not exist
ORA-02063: preceding line from GCDB
從這個(gè)錯(cuò)誤可以看出,是使用了db link,但是訪問的時(shí)候貌似沒有訪問到。
整個(gè)訪問的流程類似下面的形式,在ip為118和128都存在一個(gè)test用戶,兩個(gè)test用戶的數(shù)據(jù)不同,118庫中的APP_TE_FLOW_128訪問的一部分?jǐn)?shù)據(jù)是118中的test用戶,另外一部分是128總的test用戶,當(dāng)然是間接通過flow0這個(gè)用戶以db link的形式來訪問。
在118服務(wù)器端做檢查
sys@TEST> select * from dba_synonyms where synonym_name=upper('testore_log');
OWNER????????????????????????? SYNONYM_NAME?????????????????? TABLE_OWNER??????????????????? TABLE_NAME???????????????????? DB_LINK
------------------------------ ------------------------------ ------------------------------ ------------------------------ ---------
APP_TE_FLOW_128??????????????? testore_log???????????????? TEST?????????????????????????? testore_log???????????????? GCDB
可以看到這個(gè)同義詞很明顯是使用了db link為gcdb
進(jìn)一步查看db link的情況,發(fā)現(xiàn)存在這一些和gcdb相關(guān)的db link,都是位于不同的用戶下。
sys@TEST> SELECT * FROM DBA_DB_LINKS WHERE DB_LINK='GCDB';
OWNER?????????????? DB_LINK? USERNAME? HOST?????????????? CREATED
------------------- -------- --------- ------------------ ------------
PUBLIC????????????? GCDB???? TLCS0???? TEST_TEST_CENTER??? 23-MAY-11
TEST??????????????? GCDB???? TEST0???? TEST_TEST_CENTER??? 09-JUN-10
APP_TEST_QUERY_128? GCDB???? QUERY0??? TEST_TEST_CENTER??? 09-JUN-10
APP_TE_FLOW_128???? GCDB???? FLOW0???? TEST_TEST_CENTER??? 09-JUN-10
APP_TE_SDE_128????? GCDB???? SDE0????? TEST_TEST_CENTER??? 02-JUL-10
然后來得到db link最終的服務(wù)信息,最終得到服務(wù)器ip即128的服務(wù)器
$ tnsping TEST_TEST_CENTER
Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = TESTcenter.cyou.com)(PORT = 1525))) (CONNECT_DATA = (SERVICE_NAME = GCDB)))
$ cat /etc/hosts|grep TESTcenter.cyou.com
192.168.1.128? TESTcenter.cyou.com
好了,簡單的檢查完成,我們繼續(xù)測(cè)試。
切換到APP_TE_FLOW_128下。
sys@TEST> alter session set current_schema=APP_TE_FLOW_128;
Session altered.
然后查看all_synonyms沒有得到任何結(jié)果,這是一個(gè)疑點(diǎn)。
sys@TEST>? select * from all_synonyms where owner='APP_TE_FLOW_128' and synonym_name=upper('testore_log');
no rows selected
嘗試得到表結(jié)構(gòu)信息,竟然報(bào)錯(cuò)了,說明還是可以訪問,只是最終訪問不通。
sys@TEST> desc testore_log
ERROR:
ORA-04043: object "TEST"."testore_log" does not exist
ORA-02063: preceding line from GCDB
在128服務(wù)器端,切換到flow0這個(gè)用戶
sys@GCDB> alter session set current_schema=FLOW0;
Session altered.
查看權(quán)限都沒有問題,都是存在的。
sys@GCDB> SELECT * FROM DBA_TAB_PRIVS WHERE TABLE_NAME=upper('testore_log');
GRANTEE??????????? OWNER?? TABLE_NAME??? GRANTOR?? PRIVILEGE??? GRA HIE
------------------ ------- ---------------- --------- ------------ --- ---
FLOW0????????????? TEST??? testore_log?? TEST????? SELECT?????? NO? NO
這是一個(gè)疑問,
然后下面的情況就更奇怪了。
在118服務(wù)器端,我嘗試通過db link來查看gcdb中的數(shù)據(jù)表的情況。cat基本類似于user_tables
發(fā)現(xiàn)118的服務(wù)器中存在一個(gè)同義詞。
sys@TEST> select table_name,table_type from cat@gcdb;
TABLE_NAME???????????????????? TABLE_TYPE
------------------------------ -----------
USER_POINT???????????????????? SYNONYM
然后我通過dba_synonyms去查看這個(gè)同義詞,竟然又沒有db link的關(guān)聯(lián),著實(shí)奇怪。
sys@TEST> select * from dba_synonyms where synonym_name='USER_POINT';
OWNER????????????????????????? SYNONYM_NAME?????????????????? TABLE_OWNER??????????????????? TABLE_NAME???????????????????? DB_LINK
------------------------------ ------------------------------ ------------------------------ ------------------------------ ------------------------------
APP_TE_FLOW_128??????????????? USER_POINT???????????????????? TEST?????????????????????????? USER_POINT
為了更進(jìn)一步驗(yàn)證,直接查看gcdb中的表user_point的rowid,也沒有任何問題,如果想進(jìn)一步驗(yàn)證,其實(shí)會(huì)發(fā)現(xiàn)還是在128庫中的。
sys@TEST> select rowid from user_point@gcdb where rownum<2;
ROWID
------------------
AAAPNRAAHAABdzUAAw
那么這個(gè)問題就很奇怪了,看起來解釋不通啊。所以這個(gè)關(guān)系理不清楚,壓根沒法去賦權(quán)限。
繼續(xù)檢查。
在128服務(wù)器端繼續(xù)查看,發(fā)現(xiàn)確實(shí)有對(duì)應(yīng)的這個(gè)表,而且賦予了基本的查詢權(quán)限。
SQL>SELECT * FROM DBA_TAB_PRIVS WHERE TABLE_NAME='USER_POINT';
GRANTEE??????????????????????? OWNER????????????????????????? TABLE_NAME?????????? GRANTOR??????????????????????? PRIVILEGE??????????????????????????????? GRA HIE
------------------------------ ------------------------------ -------------------- ------------------------------ ---------------------------------------- --- ---
FLOW0????????????????????????? TEST?????????????????????????? USER_POINT?????????? TEST?????????????????????????? SELECT?????????????????????????????????? NO? NO
那么這個(gè)問題怎么解釋呢,看起來確實(shí)是很費(fèi)神。如果仔細(xì)查看前面的線索,其實(shí)就會(huì)發(fā)現(xiàn)一個(gè)public的db link其實(shí)在暗中操作。
就是最開始我們給出的檢查結(jié)果。在118的庫中確實(shí)存在一個(gè)public的db link為gcdb.
gc端sys@TEST> SELECT * FROM DBA_DB_LINKS WHERE DB_LINK='GCDB';
OWNER?????????????? DB_LINK? USERNAME? HOST?????????????? CREATED
------------------- -------- --------- ------------------ ------------
PUBLIC????????????? GCDB???? TLCS0???? TEST_TEST_CENTER??? 23-MAY-11
當(dāng)然我們就會(huì)發(fā)現(xiàn)那個(gè)用戶TLCS0在128的庫中也確實(shí)存在,一切手續(xù)都齊全。
sys@GCDB SELECT * FROM DBA_SYNONYMS WHERE OWNER='TLCS0';
OWNER????????????????????????? SYNONYM_NAME?????????????????? TABLE_OWNER??????????????????? TABLE_NAME?????????? DB_LINK
------------------------------ ------------------------------ ------------------------------ -------------------- ------------------------------
TLCS0????????????????????????? USER_POINT???????????????????? TEST?????????????????????????? USER_POINT
所以大體通過這個(gè)Public的db link我們基本明白了,為什么會(huì)出現(xiàn)這種奇怪的現(xiàn)象。
那么問題來了,為什么APP_TE_FLOW_128中的db link沒有起作用呢,一種很大的可能性就是這個(gè)db link有問題。
首選從dba_users中查到加密后的密碼。
sys@GCDB select username,password from dba_users where username='FLOW0';
USERNAME?????????????????????? PASSWORD
------------------------------ ------------------------------
FLOW0????????????????????????? BCF5E83CF6EF0269
因?yàn)檫@個(gè)db link創(chuàng)建的時(shí)間確實(shí)很早了,我也壓根沒法得最終的密碼,所以有一種看似不錯(cuò)的方案,那就是使用values的方式來重新創(chuàng)建一個(gè)db link來驗(yàn)證一下。這樣也不用重新動(dòng)原來的密碼了。
CREATE DATABASE LINK APP_TE_FLOW_128.GC_NEW_LINK CONNECT TO FLOW0 IDENTIFIED BY VALUES 'BCF5E83CF6EF0269' USING 'TEST_TEST_CENTER'
自認(rèn)為已經(jīng)解決問題在望,但是做了一個(gè)簡單的查詢,馬上讓我有些措手不及。持續(xù)了十多秒沒有反應(yīng),我感覺有些問題,馬上終止,然后就收到一個(gè)600錯(cuò)誤。
sys@TEST> select count(*)from test_20151208@APP_TE_FLOW_128.GC_NEW_LINK;
select count(*)from test_20151208@APP_TE_FLOW_128.GC_NEW_LINK
????????????????????????????????? *
ERROR at line 1:
ORA-00600: internal error code, arguments: [kzdlk_zt2 err], [18446744073709551603], [], [], [], [], [], []
這個(gè)問題在mos上查看了一番,發(fā)現(xiàn)是一個(gè)bug,對(duì)于values的方式還是存在一定的問題,也是有驚無險(xiǎn)。
ORA-00600: [Kzdlk_zt2 Err] While Selecting Using a Database Link (Doc ID 456320.1)
所以使用values的方式創(chuàng)建db link不通,那么我們只能DIY,重新在128的服務(wù)器上創(chuàng)建一個(gè)用戶,做權(quán)限分配,然后鏈接到118的庫中。
假設(shè)128中創(chuàng)建的用戶為flow
sys@GCDB> grant connect to flow0_new;
Grant succeeded.
然后創(chuàng)建了一個(gè)新的db link
sys@TEST> conn cydba/cydba
Connected.
cydba@TEST> create database link flow0_128 connect to flow0_new identified by flow0_new using 'TEST_TEST_CENTER';
Database link created.
但是訪問有些問題
select count(*) from test_20151208@flow0_128
就馬上調(diào)整為了public 的db link
?create public database link flow0_128 connect to flow0_new identified by flow0_new using 'TEST_TEST_CENTER';
?然后再次驗(yàn)證。這次就沒有問題了。
?alter session set current_schema=APP_TE_FLOW_128;
?cydba@TEST> select count(*)from TEST.testore_log@flow0_128 where rownum<2;
? COUNT(*)
----------
???????? 1
這個(gè)過程的問題明天再來解讀。 與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖
總結(jié)
以上是生活随笔為你收集整理的关于db link权限分配的苦旅(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 方差学习总结
- 下一篇: nginx1.9基于端口的四层负载均衡实