在使用异构数据库构建数据平台的过程当中,异构数据库之间的访问一直是比较复杂的问题。咱们使用PostgeSQL的过程当中,遇到须要访问MySQL实时数据的场景。可供咱们选择的方案包括mysql
FDW(Foreign Data Wrapper)是咱们选用的开源方案,这个方案明显的优势是使用统一的接口方式实现多种数据库的远程访问,包括但不限于PostgreSQL, MySQL, MongoDB, HDFS 等等。git
本次咱们专一于MySQL _FDW的使用,软件环境以下github
CentOS 7 x64sql
PostgreSQL 11.1数据库
MySQL_FDW 11bash
源库和目标库的具体搭建过程再也不描述。咱们须要使用的DB和用户信息以下服务器
CentOS下经过yum能够直接安装FDW的最新版本,此次测试的版本是11app
yum install -y mysql_fdw_11
复制代码
很是重要:工具
### 进入PostgreSQL。 admin是咱们创建的超级用户, demo是咱们创建的测试DB
psql --username=admin --dbname=demo --password
复制代码
为了更好的进行演示,代码片断中我会把提示符和操做结果信息也显示出来。拷贝脚本的时候要注意!post
-- 确认本身的用户和DB信息
demo=# \c
You are now connected to database "demo" as user "admin".
-- 创建FDW,必定要在目标DB中操做,这里是demo库。
-- mysql_fdw 名称是固定的
demo=# create extension mysql_fdw;
-- 给目标用户demo受权
demo=# grant usage on foreign data wrapper mysql_fdw to demo;
-- 查看一下已经创建的FDW信息
demo=# \dew
List of foreign-data wrappers
Name | Owner | Handler | Validator
-----------+-------+-------------------+---------------------
mysql_fdw | admin | mysql_fdw_handler | mysql_fdw_validator
复制代码
由于前面已经进行了受权,因此除非特别说明,下面的操做都使用普通用户(demo)执行。
### demo是咱们创建的普通用户, demo是咱们创建的测试DB
psql --username=demo --dbname=demo --password
复制代码
-- server_lhb 是远程服务器的别名,随便取
create server server_lhb foreign data wrapper mysql_fdw options (host '172.16.x.x',port '3306');
-- 查看一下
demo=> \des
List of foreign servers
Name | Owner | Foreign-data wrapper
---------+-------+----------------------
server_lhb | demo | mysql_fdw
复制代码
在目标库定义用户映射,即本地的用户能够映射为源库的指定用户。
-- 本地的PUBLIC用户映射为源库的lhb用户,xxx是源库的密码
create user mapping for public server server_lhb options (username 'lhb',password 'xxx');
-- 查看一下
demo=> \deu+
List of user mappings
Server | User name | FDW options
---------+-----------+----------------------------------
server_lhb | public | (username 'lhb', password 'xxx')
复制代码
在真正能访问源库数据以前,咱们还须要把源库的表结构同步到目标库上。根据不一样的场景会有不一样的方法。
-- 创建一个新的schema来存放外部表
demo=> create schema src_lhb;
-- 查看一下
demo=> \dn
List of schemas
Name | Owner
---------+----------
src_lhb | demo
public | postgres
复制代码
当源表有不少字段,可是我仅仅需求几个的时候,我能够明肯定义一个外部表来指定字段。这种场景下,只有源表中的指定字段发生变化才会影响查询。
-- 创建一个account_ft表,映射为源库lahuobao下的account表。这里表名称能够不一样于源库
create foreign table src_lhb.account_ft (
account_id int not null,
bank_card_no varchar(30)
)server server_lhb
options (dbname 'lahuobao', table_name 'account');
-- 查看一下数据
demo=> select * from src_lhb.account_ft limit 3;
account_id | bank_card_no
------------+----------------------
1 |
2 | 6228481722089439218
3 | 62252546325498753698
(3 rows)
复制代码
更多的时候,咱们仅须要直接使用源表的结构。这种场景下,经过直接导入的方式便可批量创建外部表。
注意:若是源表的结构发生变化,大几率可能会形成查询失败。须要从新导入一次表结构。
-- 仅导入指定的表,lahuobao库下的account,waybill两张表到src_lhb 模式(schema)下
import foreign schema lahuobao limit to (account,waybill) from server server_lhb into src_lhb;
复制代码
-- 一次性导入指定DB下的全部表
import foreign schema lahuobao from server server_lhb into src_lhb;
复制代码
-- 查看一下已经有哪些外部表
demo=> select * from information_schema.foreign_tables;
foreign_table_catalog | foreign_table_schema | foreign_table_name | foreign_server_catalog | foreign_server_name
-----------------------+----------------------+--------------------+------------------------+---------------------
demo | src_lhb | account_ft | demo | server_lhb
demo | src_lhb | account | demo | server_lhb
demo | src_lhb | waybill | demo | server_lhb
(3 rows)
复制代码
-- 指定表名称,删除多个表
drop foreign table src_lhb.account_ft, src_lhb.account, src_lhb.waybill;
-- 或者构造sql语句批量删除
select
'drop foreign table ' || t.table_schema || '.' || t.table_name || ';' as drop_sql
from information_schema.tables t
where t.table_type in ('FOREIGN')
and t.table_schema in ('src_lhb', 'public')
;
复制代码
-- 或者直接删除FDW扩展来删除全部外部表(必须是owner,这里就是admin用户)
drop extension mysql_fdw cascade;
复制代码