Oracle 实用技巧之不知道密码情况下 dblink 的迁移

d2105e9978e0ae0444238c9f81b86c1f.png
巩飞(网名Morinson)

“大家好,我是巩飞,网名 Morinson,现在是服务于云和恩墨西北区的一名工程师,有14年在IT公司的技术类工作经验,特别是在 ORACLE 数据库管理领域方面,有12年的工作经验,先后从事了软件开发,团队技术负责人,数据库高级顾问,但总的来说,在数据库方面得到了大家的更多认可。今天准备分享一个工作中得到的小技巧,希望借此机会多跟大家沟通交流。”

在 Oracle 数据库的运维过程中,常常会有一些特殊场景,需要我们灵活运用知识去解决问题,今天,就和大家一起探讨分析一种情况。我们需要将一个数据库从一个环境迁移到另外一个,但因为种种限制因素,只能采用数据导入导出的方式来进行。在梳理环境编写迁移方案的时候,遇到了一个难题,数据库里有大量的 dblink,大家知道这些 dblink 是在使用的,但是没有人知道密码。下面,我们使用模拟环境来表达分析解决过程。

数据库版本:

a4a6f61e3772695ea615ccb490481e9a.png

数据库链接:

17672f20224d9376c3443ff42ee422a6.png

知识点:当 GLOBAL_NAMES 参数设置为 TRUE 时,使用 DATABASE LINK 时,DATABASE LINK 的名称必须与被连接库的 GLOBAL_NAME 一致。有兴趣的同学可以详细参考老熊的博客文章 http://www.laoxiong.net/database_link_global_names.html

在模拟环境中共有3数据库链接,我们以 source 这个为例。首先,我们确定这个 dblink 是可用的:

223429fe21ada278fc6ba9cd37c29ce9.png

这个时候,很多同学可能就想到了,既然数据库链接 source 可以用,那就说明本地库(9i,服务名 firefox)是知道访问远程库(11g,服务名 source)时用到的用户名和密码的,那么 Oracle 会把它存在哪里呢?难道是 dba_db_links 的其它列?我们一起来看看:

327de21304d86e7aff25180e5d1db387.png

owner 列存储 dblink 的所有者,值 public 代表是公共的;

db_link 列存储 dblink 的名字;

username 列存储 dblink 访问远程库的用户名;

host 列存储 dblink 远程库的连接字符串,或者本地服务名;

create 列存储列 dblink 的创建时间;

dba_db_links 中对于 dblink 以哪个用户访问哪个库都做了详细的保存,但就是没有密码信息。到这里我们不要失望,因为我们知道所有的数据字典其实都不是真正的表格,而是基于内部表的一系列视图。我们去看看 dba_db_links 的定义:

f33ee476c625bb3332af0801f3cc829c.png

知识点:其实数据字典严格的名字应该叫数据字典视图,它提供了数据库的一些系统信息,数据字典是基于数据字典基表(也叫内部表,以$结尾)所建立的一系列视图,数据字典视图主要包括三种类型: user_xxx,all_xxx 和 dba_xxx。

原来 dba_db_links 的数据来自于 link$ 和 user$ 两个内部表,那么密码会不会在这两个表里保存?我们去看看它们的结构:

8f866217fc1d063df0f8770e44c3286f.png

203aaf0e0339f4f44e632ddb959a9bd7.png

知识点:内部表,sys 用户下以$结尾的一系列表,是数据库内核的组成部分,用户只能在上面执行查询操作,其维护和修改是系统自动完成的,对其的不当操作可能会造成数据库宕机、甚至永久性损坏。

在 link$ 和 user$ 中我们发现都有一个 password 字段,那么哪一个是我们要找的 dblink 的密码呢?我们先来看看其中的内容:

3eacadbfd17f875a78b5678ce88f8b48.png

30a3dde6e2372474cf336e733a3c5125.png

内容太多,只选取相关的部分。

10067f755d29c37746acddda49400a2d.png

我们发现 link$ 中的密码以明文保存,user$ 中的密码以加密后的字符串保存。但到底哪个才是我们要找的密码呢?其实 Oracle 在设计内部表时每个都有明确的作用和定义,其中 link$ 是用来保存 dblink 相关信息的(包括密码),user$ 是用来数据库本地用户相关信息的。

那么现在我们就找到了数据库链接 source 的密码:tiger,再根据其它信息,可以很快写出其迁移重建语句:

bd47cc4bb641746cb2154316ffca0297.png

知识点:在 10gR1 及之前的版本里,所有 dblink 的密码都是以明文方式在 sys.link$ 中存储,但是在 10gR2 及之后版本,Oracle 进行了改良,以加密方式存储。

针对 10gR2 及之后版本,我们虽然不能直接取得密码,但也可以通过更新内部表的方式来实现迁移。Oracle 对于直接修改内部表是严格禁止的,因为不当操作可能会造成数据库宕机、甚至永久性损坏。因为 dblink 是数据库里比较独立关联性小的一个功能,因此我们才有可能采取这种方式。但即便如此,也要求在做好备份后,由经验丰富掌握相关知识的工程师进行操作。

同样,先来看看数据库版本:

ae260521d59edadeb63ce166ebe229cc.png

数据库链接

bcf6ca44ddae9bc5dd7a5323f3316a2c.png

还是以数据库链接 source 为例,我们先测试其可用性:

646db0cb059a527ea426ca249d415aec.png

接下来我们看看 sys.link$ 在 10gR2 及之后的表结构变化,并直接从其中查询密码:

02596991bda01dc6c3c4a444af27e98a.png

与上面的9i对比,多了两个列,其中 PASSWORDX 列就是用来存储加密之后的密码。

40c8c597d9d81b256a6c8c9d043913e6.png

通过查询我们发现,password 列虽然还在,但是内容为空,passwordx 列则保存了加密之后的密码。

我们可以通过 pl/sql dev 之类的工具,将 sys.link$ 的内容导出为 sql 语句,每个 insert 语句对应一个 dblink 信息。对导出文件进行编辑,保留我们需要迁移的 dblink 语句,删掉其它。

24bca8f2e809b496ee515d4ed4dc076d.png

在目标环境上以 sys 身份执行脚本,然后对迁移后的 dblink 进行测试。

2faa0226ec996f4817c7b0de54aadb18.png

f87a7b01d8fe093ef0ba3ddd1e2c277d.png

至此,完成了在不知道密码情况下对 dblink 的迁移。另外,这里再插入个小知识点:还有另外的技巧能够简单快速的实现这个事情,使用 dbms_metadata 包,抽取 dblink 的 ddl,会生成包含加密密码的创建语句,在目标库跑这个 ddl,也能实现创建。但是这个方法,在11.2.0.4版本及以后被 Oracle 禁用了,不再支持。所以这里就不演示啦。那个 ddl 抽取出来的样子,基本是这样:

850e8dbd254166efb83bf4cf1f8524c0.png

因为是用加密字符串表达密码,所以比平时多了个 values 关键字。

最后,再谈谈本文的编写思想,其实就是盖老师推崇的学习方法:“由点及面,穷就根本”。

当遇到一个问题后,一定是深入下去,穷究根本,这样你会发现,一个简单的问题也必定会带起一大片的知识点,如果你能对很多问题进行深入思考和研究,那么在深处,你会发现,这些面逐渐接合,慢慢的延伸到 Oracle 的所有层面,逐渐的你就能融会贯通。这时候,你会主动的去尝试全面学习 Oracle,扫除你的知识盲点,学习已经成为一种需要。由实践触发的学习才最有针对性,才更能让你深入的理解书本上的知识,正所谓:"纸上得来终觉浅,绝知此事要躬行",实践的经验于我们是至为宝贵的。与同学们共勉。

如何加入云和恩墨大讲堂微信群

搜索盖国强(Eygle)微信号:eeygle,或者扫描下面二维码,备注:云和恩墨大讲堂,即可入群。每周与千人共享免费技术分享,与讲师在线讨论。

eacf09315e64ff296e61ba78cf385bdd.png

往期大讲堂精彩主题回顾

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值