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