在使用異構數據庫構建數據平臺的過程當中,異構數據庫之間的訪問一直是比較複雜的問題。咱們使用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;
複製代碼