关于db link权限分配的苦旅(二)(r7笔记第45天)

时间:2022-05-04
本文章向大家介绍关于db link权限分配的苦旅(二)(r7笔记第45天),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

在几天前说过关于db link分配权限的问题,当时也折磨了我好一会儿

关于db link权限分配的苦旅(一) (r7笔记第42天)

大体的情况还是在118的服务器中去访问128中的某个表的时候存在一些访问的问题,最后是重建了一个public的db link得以修复,当时对于这个问题的临时处理也是一波三折,还触发了一个oracle的bug,也算是有惊无险。 但是对于之前操作中的疑问在解释之后统一进行解答。 第二天的时候,开发的同事反馈说线上进行测试提dblink不到,这个解释听起来很模糊,到底是不是问题自己感觉还有待确认,于是向开发同学了解更多细节。 开发的同学提供的信息如下: 程序访问的时候报错:nested exception is java.sql.SQLException: ORA-24777: use of non-migratable database link not allowed 麻烦看一下是不是database link的问题 对于这个错误,看起来是比较陌生的,自己首先查看了数据库日志层面没有发现任何的报错。说明这个问题的报错应该仅仅是客户端中可能会存在。 为了更进一步明确问题,我尝试从开发那边了解到底是什么样的语句触发了这样一个问题,他们回复说就是一个简单的查询,拿到的语句为: select count(CN) from TESTORE_LOG where CN = '586480450' and BUY_TIME >= to_date('2015-12-02 00:00:00', 'yyyy-mm-dd hh24:mi:ss') order by BUY_TIME desc 自己也测试了一下,得到的执行计划如下:


> explain plan for select count(CN) from TESTORE_LOG where CN =  '586480450' and BUY_TIME >= to_date('2015-12-02 00:00:00',  'yyyy-mm-dd hh24:mi:ss') order by BUY_TIME desc;
> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
Plan hash value: 2100402862
--------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name                     | Rows  | Bytes | Cost (%CPU)| Time     | Inst   |
-------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT REMOTE      |                          |     1 |    32 |     2   (0)| 00:00:01 |        |
|   1 |  SORT AGGREGATE              |                          |     1 |    32 |            |          |        |
|*  2 |   TABLE ACCESS BY INDEX ROWID| TESTORE_LOG              |     1 |    32 |     2   (0)| 00:00:01 |   GCDB |
|*  3 |    INDEX RANGE SCAN          | IND_TESTORE_LOG_BTIME    |     2 |       |     1   (0)| 00:00:01 |   GCDB |
-----------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - filter("A1"."CN"='586480450')
   3 - access("A1"."BUY_TIME">=TO_DATE('2015-12-02 00:00:00', 'yyyy-mm-dd hh24:mi:ss'))
Note
-----
   - fully remote statement

其中标黄的部分也是亮点,这个testore_log是通过db link来间接访问的。但是从执行计划来看访问肯定是没有问题的,而且走了索引,效率应该也不会差多少。 自己也切换到指定的用户下,执行了同样的语句,已经能够说明目前的情况下通过sqlplus是没有问题的。 自己也在怀疑是否是public的db link是否存在一些问题,不支持一些使用场景。 于是在mos上查了一圈,发现有一篇文章还是很符合的。 Error "ORA-24777: Use Of Non-Migratable Database Link Not Allowed" Using Oracle XA Datasource When Executing a Select via Database Link. (Doc ID 879543.1) 对于这个问题在10g版本中确实存在,而且workaround是把专用服务器模式改为共享服务器模式。 从目前我的了解来看,为了这个问题修改连接模式还是一个需要谨慎的操作,尤其是核心库,这种操作牵一发而动全身,没有全面的测试是不敢提前出手的。 所以我开始琢磨起这个语句来,看看能不能找出别的思路,所幸的是,这个查询是一个单表的查询,所以还是有机会把这部分功能单独挪到本地,而且如果执行频繁,老在远端做这个操作感觉也是怪怪的。 于是我就给他们做了详细的解释,然后建议他们把这个查询的操作挪到128的服务器上去,没想到谈得还很顺利,一些权限的事情我都能够cover,所以把这个访问入口调整到128的服务器上之后,再没有反馈过这类的错误了。 但是问题虽然解决了,我对于db link还是存在着一些疑问,简单总结一下。 ##问题1 起初查看all_synonyms没有得到任何结果,而使用dba_synonyms就可以查出来, sys@TEST> select * from all_synonyms where owner='APP_TE_FLOW_128' and synonym_name=upper('testore_log'); no rows selected 其实不光是这个128的用户查不出来,使用sysdba查看all_synonyms也是一样的效果。 > select *from all_synonyms where db_link is not null; no rows selected 可以再稍微扩展一下,如果查看dba_objects,各种类型的对象,只有db link是object_id为null的,最有范儿 >select object_type,count(*)from dba_objects where object_id is null group by object_type; OBJECT_TYPE COUNT(*) ------------------- ---------- DATABASE LINK xxx ##问题2 在查看表数据的时候,使用current_schema来切换是没有问题的,但是使用db link似乎还是会碰到一些意料之外的问题。 > alter session set current_schema=APP_TE_FLOW_128; Session altered. 尝试得到表结构信息,竟然报错了,说明还是可以访问,只是最终访问不通。 sys@TEST> desc testore_log ERROR: ORA-04043: object "TEST"."testore_log" does not exist ORA-02063: preceding line from GCDB 这个时候,如果使用对应的用户来查看,这个问题就不会存在,所以current_schema的操作还是在db link使用中受限。而不是最开始推理得出的db link的密码错误。 说到这个,再提一个低级错误,就是使用下面的方式,创建出的db link名字就是APP_TE_FLOW_128.GC_NEW_LINK而不是位于用户APP_TE_FLOW_128下。 CREATE DATABASE LINK APP_TE_FLOW_128.GC_NEW_LINK CONNECT TO FLOW0 IDENTIFIED BY VALUES 'BCF5E83CF6EF0269' USING 'TEST_TEST_CENTER' ##问题3 如果不知道密码,使用identified by values这种方式创建db link. CREATE DATABASE LINK APP_TE_FLOW_128.GC_NEW_LINK CONNECT TO FLOW0 IDENTIFIED BY VALUES 'BCF5E83CF6EF0269' USING 'TEST_TEST_CENTER' 就很可能触发一个oracle的bug,可能查询时间极长,而且风险极大。 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], [], [], [], [], [], [] ##问题4 为什么118的服务器端使用db link,发现118的服务器中存在一个同义词。 sys@TEST> select table_name,table_type from cat@gcdb; TABLE_NAME TABLE_TYPE ------------------------------ ----------- USER_POINT SYNONYM 这个地方其实确实是用到了db link,不过是使用到了public的db link,然后问题又来了,为什么会用到public db link而普通的db link不可以呢,这个其实就是第2个问题的解答,因为我使用了alter session set current_schema=xxx尝试做切换,以为切换过来了,其实没有,这个时候其实还是使用public db link在做查询。 而且db link确实还会有一定的限制,触发一些bug,对于这类问题,想必大家都碰到不少了,所以对于db link的使用还是建议需要尽量减少甚至不用。