一、开场白

因为工作需要,把PG数据同步到MySQL。实现这个需求有多种方式:
1、Kettle 成熟的ETL工具
2、Python 开发效率高的变成语言
3、Golang 个人很喜欢,开发效率不比pyhton查,而且性能堪比C
4、MySQL FDW 实现简单

今天我们聊一聊MySQL_FDW的使用入门。
一个工具、一种技能或是一门知识的学习,归纳成三点:
1、这玩意是什么
2、这玩意能干什么
3、这玩意怎么用

二、是什么以及能干什么

  1. This PostgreSQL extension implements a Foreign Data Wrapper (FDW) for MySQL.

Github上关于MySQL_FDW的说明:实现了FDW(MySQL)的PG扩展。
简单说下就是可以在PG中操作和读取MySQL数据。
GitHub上MysQL_FDW地址 Postgresql FDW的介绍

三、怎么用

3.1 安装部署
配置PG的环境变量和MySQL的环境变量
MYSQL需要C client的支持
然后就是make && make install了 ,注意参数

export PATH=/usr/local/pgsql/bin/:$PATH
export PATH=/usr/local/mysql/bin/:$PATH
make USE_PGXS=1
make USE_PGXS=1 install

3.2 使用语法

-- load extension first time after install
CREATE EXTENSION mysql_fdw;

-- create server object
CREATE SERVER mysql_server
    FOREIGN DATA WRAPPER mysql_fdw
    OPTIONS (host '127.0.0.1', port '3306');

-- create user mapping 注意此处的postgres是你的schema
-- 例如你的数据库如果是testdb,那么你需要\c testdb 连接到testdb
-- 如果关联到public schema ,那么连接到testdb后,把下面的postgres改为public即可
CREATE USER MAPPING FOR postgres
    SERVER mysql_server
    OPTIONS (username 'foo', password 'bar');

-- create foreign table
CREATE FOREIGN TABLE warehouse
    (
        warehouse_id int,
        warehouse_name text,
        warehouse_created timestamp
    )
    SERVER mysql_server
    OPTIONS (dbname 'db', table_name 'warehouse');

-- insert new rows in table
INSERT INTO warehouse values (1, 'UPS', current_date);
INSERT INTO warehouse values (2, 'TV', current_date);
INSERT INTO warehouse values (3, 'Table', current_date);

-- select from table
SELECT * FROM warehouse ORDER BY 1;

warehouse_id | warehouse_name | warehouse_created
-------------+----------------+-------------------
           1 | UPS            | 10-JUL-20 00:00:00
           2 | TV             | 10-JUL-20 00:00:00
           3 | Table          | 10-JUL-20 00:00:00

-- delete row from table
DELETE FROM warehouse where warehouse_id = 3;

-- update a row of table
UPDATE warehouse set warehouse_name = 'UPS_NEW' where warehouse_id = 1;

-- explain a table with verbose option
EXPLAIN VERBOSE SELECT warehouse_id, warehouse_name FROM warehouse WHERE warehouse_name LIKE 'TV' limit 1;

                                   QUERY PLAN
--------------------------------------------------------------------------------------------------------------------
Limit  (cost=10.00..11.00 rows=1 width=36)
    Output: warehouse_id, warehouse_name
    ->  Foreign Scan on public.warehouse  (cost=10.00..1010.00 rows=1000 width=36)
        Output: warehouse_id, warehouse_name
        Local server startup cost: 10
        Remote query: SELECT `warehouse_id`, `warehouse_name` FROM `db`.`warehouse` WHERE ((`warehouse_name` LIKE BINARY 'TV'))
-- 
CREATE SERVER mysql_crm
FOREIGN DATA WRAPPER mysql_fdw
OPTIONS (host '127.0.0.1', port '8809');
--
CREATE USER MAPPING FOR public
SERVER mysql_crm
OPTIONS (username 'pgread', password 'pg');

GRANT USAGE ON FOREIGN SERVER mysql_crm TO public;
GRANT ALL PRIVILEGES ON mysql_crm TO public;
--

CREATE FOREIGN TABLE tb_card_info
(
mer_id int,
user_id bigint,
card_no varchar(100)
)
SERVER mysql_crm
OPTIONS (dbname 'crmdb', table_name 'tb_card_info');

--如果需要对foreign table 做DML操作,需要第一个字段是主键或者唯一键