mysql_fdw(MySQL外部表)

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请联系我们处理。

使用指南

  1. 创建mysql_fdw插件。

    CREATE EXTENSION IF NOT EXISTS mysql_fdw;
    说明

    仅限高权限账号可以执行此命令。

  2. 创建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');
  3. 创建用户映射,将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!');
  4. 使用步骤3PolarDB 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');
  5. 测试读写。

    • 您可以通过外部表读写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)