关于db link权限分配的苦旅(二)

在几天前说过关于db link分配权限的问题,当时也折磨了我好一会儿
http://blog.itpub.net/23718752/viewspace-1869425/

大体的情况还是在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的使用还是建议需要尽量减少甚至不用。

时间: 2024-10-13 04:10:36

关于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; 但是这个看似简单的案例,我想用两篇日志来总结,因为里面有许多的内容量,中间的过程也是异常曲折,而且最开始的推论很可能是错误的,然后还可

link中如何对一个变量二次分配内存?二次分配的效率和一次分配是不是有损失?

问题描述 link中如何对一个变量二次分配内存?二次分配的效率和一次分配是不是有损失? link中如何对一个变量二次分配内存?二次分配的效率和一次分配是不是有损失? 解决方案 看情况,如果初始化的变量没有用到,可以先指向null 解决方案二: 先释放,然后就可以指向新的对象了,.net clr会自动垃圾回收

[20130701]db link与事务.txt

[20130701]db link与事务.txt 昨天帮别人修复数据库,安全起见,我先启动read only模式,叫他们检查一些相关数据是否正常,但是在程序界面上出现:ORA-16000: database open for read-only access. 我跟踪发现执行的实际上通过db_link访问远程数据库的语句,不是dml语句(注:实际上执行dml,发生的事务也在远端,不在本地).按照这个道理如果数据库在只读的情况下,是不能访问远端的数据库的. google 发现如下链接: 我回来后在

Shiro系列(2) - 权限模型以及权限分配的两种方式

1. 顶级账户分配权限用户需要被分配相应的权限才可访问相应的资源.权限是对于资源的操作一张许可证.给用户分配资源权限需要将权限的相关信息保存到数据库.这些相关内容包含:用户信息.权限管理.用户分配的权限信息(数据模型) 2. 权限模型设计主体(user.password)权限(权限名称.资源id)/资源(资源名称.访问url)角色(角色名称)角色和权限关系(角色id.权限id)主体和角色关系(主体id.角色id)   3. 权限分配有两种  ​     ​3.1 基于角色的权限控制 这些角色包含

php权限分配的实现

小编今天写下关于后台管理员权限的分配自己的思路想法 <?php /**reader * 小编的思想比较简单实现的功能 * 首先每个栏目的id号是固定不变的 然后 总管理员 * 创建个管理员之后 给该管理员分配权限的时候 把相应的栏目勾选上 * 这样把栏目的 id 号 就插入到数据库里面了,当这个管理员登录之后 * 获得这个管理员 应有的的栏目id 号 .左边的导航 根据当前的栏目id在不在该管理员的 * 栏目id号里 来判断显示或者不显示呢.. */ header("Content-typ

Oracle的DB Link

数据库之间的链接建立在DATABASE LINK上.要创建一个DB LINK,必须先在每个数据库服务器上设置链接字符串. 1. 配置TNS , $ORACLE_HOME/NETWORK/ADMIN/tnsname.ora 10gstandby = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = HFCC-KF-3068)(PORT = 1522)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NA

link中如何颠倒一个二维数组?二维数组不支持revses吧?

问题描述 link中如何颠倒一个二维数组?二维数组不支持revses吧? link中如何颠倒一个二维数组?二维数组不支持revses吧? 解决方案 可以用select Enumerable.Range(0 arr.GetLength(1)).Select(x => Enumerable.Range(0 arr.GetLength(1)).Select(y => arr[x y]).Reverse().ToArray()).Reverse().ToArray(); 解决方案二: 长方形的矩阵有上

mysql 新增、删除用户和权限分配_Mysql

1. 新增用户 复制代码 代码如下: mysql>insert into mysql.user(Host,User,Password) values("localhost","lionbule",password("hello1234"));mysql>flush privileges; 2. 修改用户密码 复制代码 代码如下: mysql>update mysql.user set password=password('new

基于php权限分配的实现代码_php实例

小编今天写下关于后台管理员权限的分配自己的思路想法 复制代码 代码如下: <?php /**reader * 小编的思想比较简单实现的功能 * 首先每个栏目的id号是固定不变的 然后 总管理员 * 创建个管理员之后 给该管理员分配权限的时候  把相应的栏目勾选上 * 这样把栏目的 id 号 就插入到数据库里面了,当这个管理员登录之后 * 获得这个管理员 应有的的栏目id 号 .左边的导航 根据当前的栏目id在不在该管理员的  * 栏目id号里 来判断显示或者不显示呢.. */ header(&quo