dblink 是 PostgreSQL 的一个核心扩展,允许在当前数据库中访问其他 PostgreSQL 数据库的数据,实现跨数据库查询功能。
-- 使用超级用户安装
CREATE EXTENSION dblink;
-- 查看已安装扩展
SELECT * FROM pg_extension WHERE extname = 'dblink';
-- 查看扩展函数
SELECT proname FROM pg_proc WHERE proname LIKE 'dblink%';
-- 创建持久连接(需超级用户权限)
SELECT dblink_connect('myconn', 'host=192.168.1.100 dbname=remote_db user=user password=pass');
-- 创建一次性连接
SELECT dblink_connect('host=192.168.1.100 dbname=remote_db user=user password=pass');
-- 基本查询
SELECT * FROM dblink('myconn', 'SELECT id, name FROM users') AS t(id int, name text);
-- 带参数查询
SELECT * FROM dblink('myconn', 'SELECT * FROM accounts WHERE balance > $1', ARRAY[1000])
AS t(account_id int, balance numeric);
-- 关闭指定连接
SELECT dblink_disconnect('myconn');
-- 关闭所有连接
SELECT dblink_disconnect_all();
-- 开始事务
SELECT dblink_exec('myconn', 'BEGIN');
-- 执行更新
SELECT dblink_exec('myconn', 'UPDATE accounts SET balance = balance - 100 WHERE id = 1');
-- 提交或回滚
SELECT dblink_exec('myconn', 'COMMIT');
-- 或
SELECT dblink_exec('myconn', 'ROLLBACK');
-- 批量插入
SELECT dblink_send_query('myconn', 'INSERT INTO log_entries VALUES (1, ''message1''), (2, ''message2'')');
-- 检查结果
SELECT dblink_get_result('myconn');
-- 查看当前连接
SELECT * FROM dblink_get_connections();
-- 获取连接状态
SELECT dblink_get_pkey('myconn');
-- 使用外部文件存储凭据
SELECT dblink_connect('myconn', 'host=192.168.1.100 dbname=remote_db user=user password=' || pg_read_file('/secure/path/password.txt'));
-- 创建安全视图
CREATE VIEW remote_users AS
SELECT * FROM dblink('myconn', 'SELECT id, name FROM public.users')
AS t(id int, name text);
-- 限制访问权限
REVOKE ALL ON remote_users FROM PUBLIC;
GRANT SELECT ON remote_users TO reporting_role;
-- 强制SSL连接
SELECT dblink_connect('myconn', 'host=192.168.1.100 dbname=remote_db user=user password=pass sslmode=require');
-- 保持持久连接
SELECT dblink_connect('myconn', '...');
-- 在应用中复用连接
-- 而不是每次查询都新建连接
-- 使用游标获取大数据集
SELECT dblink_open('myconn', 'mycursor', 'SELECT * FROM large_table');
SELECT * FROM dblink_fetch('myconn', 'mycursor', 1000) AS t(...); -- 每次获取1000行
SELECT dblink_close('myconn', 'mycursor');
-- 发送异步查询
SELECT dblink_send_query('myconn', 'SELECT * FROM large_table');
-- 稍后获取结果
SELECT * FROM dblink_get_result('myconn') AS t(...);
错误:
ERROR: could not establish connection
解决方案:
-- 检查网络连通性
-- 验证凭据是否正确
-- 检查pg_hba.conf是否允许连接
-- 使用完整连接字符串
SELECT dblink_connect('hostaddr=192.168.1.100 port=5432 dbname=remote_db user=user password=pass');
错误:
ERROR: return type mismatch in column 1
解决方案:
-- 明确指定返回类型
SELECT * FROM dblink('myconn', 'SELECT id FROM users') AS t(id int);
-- 需要特殊处理大对象
SELECT lo_import(dblink('myconn', 'SELECT lo_get(oid) FROM large_objects WHERE id=1'));
特性 | dblink | postgres_fdw | 逻辑复制 |
---|---|---|---|
实时性 | 实时 | 实时 | 近实时 |
性能 | 中等 | 较高 | 高 |
使用复杂度 | 中等 | 低 | 高 |
事务支持 | 有限 | 有限 | 完整 |
适用场景 | 点查询 | 频繁查询 | 数据同步 |
dblink 最适合需要灵活执行远程查询的场景,而 postgres_fdw 更适合频繁访问远程表的场景。
通过合理使用dblink扩展,可以实现PostgreSQL数据库之间的灵活数据交互,满足复杂的跨数据库查询需求。