mysql_fdw
是一个开源第三方插件,该插件支持在PolarDB PostgreSQL版中读写PolarDB MySQL版、RDS MySQL以及自建MySQL实例中的数据。
前提条件
支持的PolarDB PostgreSQL版的版本如下:
PostgreSQL 14(内核小版本14.11.19.0及以上)
PostgreSQL 11(内核小版本1.1.34及以上)
您可通过如下语句查看PolarDB PostgreSQL版的内核小版号:
PostgreSQL 14
SELECT version();
PostgreSQL 11
SHOW polar_version;
注意事项
使用之前需要将PolarDB PostgreSQL版的专有网络网段(例如,
172.xx.xx.xx/16
)添加到MySQL实例的白名单中,允许PolarDB PostgreSQL版访问MySQL实例。不能在PolarDB PostgreSQL版的OPTIONS中指定host、port等关键字,请使用channel_name替代。每个集群默认配置一个channel为localhost ,即连接本地的channel。如果需要连接其他数据库集群,请先建立channel,配置channel请联系我们处理。
使用指南
创建mysql_fdw插件。
CREATE EXTENSION IF NOT EXISTS mysql_fdw;
说明仅限高权限账号可以执行此命令。
创建MySQL服务器定义。
CREATE SERVER <server名称> FOREIGN DATA WRAPPER mysql_fdw OPTIONS (channel_name 'channel名称');
说明PolarDB PostgreSQL版在OPTIONS中只能使用channel_name指定MySQL实例的连接信息。
示例如下(已经提前配置好名为mysqlchannel的polar_channel):
CREATE SERVER mysql_server FOREIGN DATA WRAPPER mysql_fdw OPTIONS (channel_name 'mysqlchannel');
创建用户映射,将MySQL服务器定义映射到PolarDB PostgreSQL版的某个用户上,后续使用该用户访问MySQL实例的数据。
CREATE USER MAPPING FOR <PolarDB PostgreSQL用户名> SERVER <server名称> OPTIONS (username '<MySQL用户名>', password '<MySQL用户对应密码>');
示例如下:
CREATE USER MAPPING FOR pgtest SERVER mysql_server OPTIONS (username 'mysqltest', password 'Test1234!');
使用步骤3中PolarDB PostgreSQL版用户创建MySQL实例的外部表。
说明外部表的字段名要与MySQL数据库中表的字段名相同,同时可以仅创建您想要查询的字段。例如,MySQL数据库中的表有3个字段ID、NAME、AGE,您可以仅创建其中2个字段ID、NAME。
CREATE FOREIGN TABLE <表名> (<字段名> <数据类型>,<字段名> <数据类型>...) server <server名称> options (dbname '<MySQL数据库名>', table_name '<MySQL表名>');
示例如下:
CREATE FOREIGN TABLE ft_test (id1 int, name1 text) server mysql_server options (dbname 'test123', table_name 'test');
测试读写。
您可以通过外部表读写MySQL实例的数据。
说明MySQL实例对应的表必须有主键才可以写入数据,否则会出现如下错误:
ERROR: first column of remote table must be unique for INSERT/UPDATE/DELETE operation.
SELECT * FROM ft_test ; INSERT INTO ft_test VALUES (2,'abc'); INSERT 0 1 INSERT INTO ft_test SELECT generate_series(3,100),'abc'; INSERT 0 98 SELECT count(*) FROM ft_test ; count ------- 99 (1 row)
检查执行计划,即PolarDB PostgreSQL版查询MySQL实例的数据的请求在MySQL中是如何执行的。
explain verbose SELECT count(*) FROM ft_test ; QUERY PLAN ------------------------------------------------------------------------------- Aggregate (cost=1027.50..1027.51 rows=1 width=8) Output: count(*) -> Foreign Scan on public.ft_test (cost=25.00..1025.00 rows=1000 width=0) Output: id, info Remote server startup cost: 25 Remote query: SELECT NULL FROM `test123`.`test` (6 rows) explain verbose SELECT id FROM ft_test WHERE id=2; QUERY PLAN ------------------------------------------------------------------------- Foreign Scan on public.ft_test (cost=25.00..1025.00 rows=1000 width=4) Output: id Remote server startup cost: 25 Remote query: SELECT `id` FROM `test123`.`test` WHERE ((`id` = 2)) (4 rows)