DBLINK的创建和使用(总结)
- DBLINK的创建和使用(总结)
- 一、什么是 DBLINK?
- 二、创建 DBLINK 的三种主要方式
- 方式一:使用 tnsnames.ora 文件(最常用、最推荐)
- 步骤 1:配置 tnsnames.ora 文件
- 步骤 2:创建 DBLINK
- 方式二:使用完整的连接字符串(不推荐)
- 方式三:使用 Oracle Net Services 命名方法(如 LDAP)
- 方式一:使用 tnsnames.ora 文件(最常用、最推荐)
- 三、如何使用 DBLINK
- 四、核心注意事项与最佳实践
- 1. 性能问题(最关键)
- 2. 安全问题
- 3. 维护与管理
- 连通性检测
- 删除 DBLINK:
- 4. 功能限制
- 五、总结
一、什么是 DBLINK?
DBLINK 是一个数据库对象,它允许一个 Oracle 数据库(本地数据库)访问另一个 Oracle 数据库(远程数据库)中的数据,就像访问本地数据一样。通过 DBLINK,你可以执行 SELECT、INSERT、UPDATE、DELETE 等操作,甚至可以调用远程数据库的存储过程。
它本质上是一个 “数据库连接字符串” 的别名,存储了连接到远程数据库所需的所有信息。
这是一个在 Oracle 中实现跨数据库数据访问的强大功能,但如果使用不当,也可能带来性能、安全和维护上的问题。
二、创建 DBLINK 的三种主要方式
创建 DBLINK 需要 CREATE DATABASE LINK 系统权限。根据连接信息的存储位置,主要分为以下三种方式:
方式一:使用 tnsnames.ora 文件(最常用、最推荐)
这是最标准和易于管理的方式。连接信息存储在本地数据库服务器的 $ORACLE_HOME/network/admin/tnsnames.ora 文件中。
步骤 1:配置 tnsnames.ora 文件
在本地数据库服务器上,编辑 tnsnames.ora 文件,为远程数据库添加一个条目。
-- 文件位置: $ORACLE_HOME/network/admin/tnsnames.oraREMOTE_DB =(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = remote_host_name_or_ip)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = remote_service_name) -- 注意:推荐使用 SERVICE_NAME-- (SID = remote_sid) -- 旧的方式,不推荐))eg:
-- 主备库tnsnames.ora:
RPTDBPRI =(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = 10.25.xxx.xxx)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = rptdb)))RPTDBSTD =(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = 10.25.xxx.xxx)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = rptdbstd)))-- REMOTE_DB: TNS 别名,稍后在创建 DBLINK 时会用到。
-- HOST: 远程数据库服务器的主机名或 IP 地址。
-- PORT: 远程数据库的监听端口,默认为 1521。
-- SERVICE_NAME: 远程数据库的服务名。可以通过在远程数据库执行 show parameter service_name; 查看。这是推荐的方式。
-- SID: 远程数据库的实例名。
步骤 2:创建 DBLINK
登录到本地数据库,执行 CREATE DATABASE LINK 语句。
-- 创建一个公共的 DBLINK (所有用户都可以使用)
CREATE PUBLIC DATABASE LINK dblink_to_remote
CONNECT TO remote_user IDENTIFIED BY remote_password
USING 'REMOTE_DB'; -- 'REMOTE_DB' 是 tnsnames.ora 中的 TNS 别名-- 创建一个私有 DBLINK (仅创建者可以使用)
CREATE DATABASE LINK dblink_to_remote_private
CONNECT TO remote_user IDENTIFIED BY remote_password
USING 'REMOTE_DB';-- dblink_to_remote: 你为这个 DBLINK 起的名字。
-- remote_user: 连接远程数据库所用的用户名。
-- remote_password: 连接远程数据库所用的密码。
-- USING 'REMOTE_DB': 指定使用 tnsnames.ora 文件中名为 REMOTE_DB 的连接描述符。
方式二:使用完整的连接字符串(不推荐)
这种方式不依赖 tnsnames.ora 文件,而是将所有连接信息直接写在 USING 子句中。
CREATE PUBLIC DATABASE LINK dblink_to_remote_direct
CONNECT TO remote_user IDENTIFIED BY remote_password
USING '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=remote_host_name_or_ip)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=remote_service_name)))';eg:
create database link db_link_name connect to user_name identified by "dbPassword" using '(DESCRIPTION =(ENABLE=BROKEN)(retry count=20)(retry delay=3)(ADDRESS_LIST =(ADDRESS =(PROTOCOL = TCP)(HOST = 192.xxx.xxx.xxx)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = orcl)))';
缺点:
- 连接信息分散在数据库对象中,不易统一管理和修改。如果远程数据库地址或端口变更,需要修改所有相关的 DBLINK。
- 可读性差。
方式三:使用 Oracle Net Services 命名方法(如 LDAP)
在大型企业环境中,可能会使用集中化的命名服务(如 LDAP)来管理所有数据库的连接信息。DBLINK 的创建方式与方式一类似,USING 子句中的别名会在 LDAP 服务器上进行解析。
CREATE PUBLIC DATABASE LINK dblink_to_remote_ldap
CONNECT TO remote_user IDENTIFIED BY remote_password
USING 'LDAP_ALIAS_FOR_REMOTE_DB';eg:
create database link hebtz connect to hebtz identified by "1" using '192.168.2xx:1521/hebtzstd';
三、如何使用 DBLINK
创建成功后,你可以在 SQL 语句中通过 @dblink_name 的方式来引用远程数据库的对象。
-- 查询远程数据库的表
SELECT * FROM employees@dblink_to_remote WHERE department_id = 10;-- 向远程数据库插入数据
INSERT INTO log_table@dblink_to_remote (log_id, log_message, log_time)
VALUES (100, 'Test from local DB', SYSDATE);-- 更新远程数据库的数据
UPDATE inventory@dblink_to_remote SET quantity = quantity - 1 WHERE product_id = 'P123';-- 删除远程数据库的数据
DELETE FROM old_records@dblink_to_remote WHERE created_date < SYSDATE - 365;-- 调用远程数据库的存储过程
BEGINremote_package.process_data@dblink_to_remote('some_data');
END;
/
四、核心注意事项与最佳实践
使用 DBLINK 时,有几个非常重要的点需要特别关注,否则可能导致严重的性能问题或安全漏洞。
1. 性能问题(最关键)
DBLINK 的性能是最常被诟病的地方,主要体现在以下几个方面:
- 逐行操作(Row-by-Row):当你在本地查询中包含一个远程表,并且没有有效的过滤条件时,Oracle 可能会将远程表的全部数据拉到本地,然后再进行连接或过滤。这会产生巨大的网络开销。
- 解决方法:尽可能在远程端完成数据过滤和聚合。
-- 不好的做法:可能导致全表扫描并将所有 employees 数据拉到本地
SELECT l.local_id, r.employee_name
FROM local_table l
JOIN employees@dblink_to_remote r ON l.emp_id = r.employee_id;-- 好的做法:使用子查询在远程端先过滤数据
SELECT l.local_id, r.employee_name
FROM local_table l
JOIN (SELECT employee_id, employee_name FROM employees WHERE department_id = 10)@dblink_to_remote rON l.emp_id = r.employee_id;
- 索引失效:本地数据库无法直接使用远程数据库的索引统计信息。这可能导致优化器做出糟糕的执行计划。
- 解决方法:确保远程查询的 WHERE 子句中的过滤字段在远程表上有索引。
- 事务开销:涉及 DBLINK 的事务是分布式事务。提交或回滚时需要协调本地和远程两个数据库,开销比本地事务大得多。
- 解决方法:避免在一个事务中频繁地对远程数据库进行大量的 DML(插入、更新、删除)操作。尽量批量处理。
2. 安全问题
- 密码明文存储:CREATE DATABASE LINK 语句中的密码是以加密的形式存储在数据字典中的(SYS.LINK$ 表)。虽然不是明文,但如果数据库被攻破,密码仍有泄露的风险。
- 解决方法:
- 1.使用专用的、权限最小化的账号创建 DBLINK。不要使用 SYS 或其他高权限账号。
- 2.定期修改远程账号的密码。修改后,需要重新创建 DBLINK 才能生效。
- 解决方法:
- 权限控制:
- CREATE PUBLIC DATABASE LINK 权限非常强大,会影响所有用户。请谨慎授予。
- 考虑使用私有 DBLINK,并通过 GRANT USAGE ON DATABASE LINK 来精确控制哪个用户可以使用它。
3. 维护与管理
连通性检测
- 依赖 tnsnames.ora:如果使用方式一,DBLINK 的可用性依赖于本地服务器上 tnsnames.ora 文件的正确性。任何网络或服务器变更都需要同步更新此文件。
- DBLINK 状态:Oracle 不会自动检测 DBLINK 是否可用。即使远程数据库宕机,DBLINK 对象本身依然存在。只有在执行查询时才会报错。
- 检查方法:可以写一个简单的脚本来测试 DBLINK 的连通性。
DECLAREv_count NUMBER;
BEGINSELECT 1 INTO v_count FROM dual@dblink_to_remote;DBMS_OUTPUT.PUT_LINE('DBLINK is working.');
EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('DBLINK is DOWN: ' || SQLERRM);
END;
/
删除 DBLINK:
-- 删除私有 DBLINK
DROP DATABASE LINK dblink_to_remote_private;-- 删除公共 DBLINK
DROP PUBLIC DATABASE LINK dblink_to_remote;
4. 功能限制
- 某些 Oracle 功能在 DBLINK 上是受限或行为不同的,例如:
- FLASHBACK QUERY 通常无法跨越 DBLINK。
- 对远程对象的 DDL(如 CREATE TABLE)操作是允许的,但需要额外的权限,且应极其谨慎。
- 自治事务 (Autonomous Transaction) 在 DBLINK 环境下的行为需要特别注意。
五、总结
DBLINK 是一个强大但需要小心使用的工具。遵循以下最佳实践可以帮助你规避大部分问题:
- 1.首选 tnsnames.ora:便于集中管理和维护。
- 2.最小权限原则:为 DBLINK 创建专用的、权限受限的远程账号。
- 3.优化查询:始终在远程端进行过滤和聚合,减少网络传输的数据量。
- 4.监控与维护:定期检查 DBLINK 的可用性,并在远程密码更改后及时更新。
- 5.考虑替代方案:对于频繁、大数据量的跨库访问,应考虑使用 Oracle GoldenGate、Data Guard 或 Streams 等技术进行数据同步,将数据复制到本地再进行查询,性能会好得多。DBLINK 更适合用于偶尔的、小数据量的跨库查询或操作。