💨
CentOS7にtds_fdwを導入してpostgresからSQL Serverを参照する
目的
DBサーバー・DBMS変更を伴う移行案件で、データ移行のため、新DBであるCentOS7のpostgresから、旧DBである外部SQL Serverのデータを直接参照したい。
方法
tds_fdwという拡張を導入すると、参照出来る(更新は不可)ようなので試す。
導入の参考にさせていただいたページ
- https://dbsguru.com/access-the-mssql-database-from-postgresql-using-tds-foreign-data-wrapper-tds_fdw/
- https://github.com/tds-fdw/tds_fdw/blob/master/InstallRHELandClones.md
tds_fdwの導入〜有効化迄
CREATE EXTENSION tds_fdw(失敗)
事前準備を何もせずにpostgresにログオンして以下実行しても、もちろんエラーになる
CREATE EXTENSION tds_fdw
# 機能拡張の制御ファイル"/usr/pgsql-14/share/extension/tds_fdw.control"をオープンできませんでした
# そのようなファイルやディレクトリはありません
tds_fdwが依存するfreetdsをまずはインストールする必要がある。freetdsはepelから取得出来る。
あと、makeに必要なツールもいくつか導入する。
freetds導入
インストールの準備として、epelの設定。
cd /etc/yum.repos.d/
vi epel-yum-ol7.repo
以下を最下部に挿入。
"ol7_epel"
name=Oracle Linux $releasever EPEL ($basearch)
baseurl=http://yum.oracle.com/repo/OracleLinux/OL7/developer_EPEL/$basearch/
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-oracle
gpgcheck=0
enabled=1
インストールする。
yum search freetds
yum install -y freetds freetds-devel
centos-release-scl(LLVM7)導入
yum install centos-release-scl
postgresql14-devel導入
yum install postgresql14-devel
tds_fdw(本丸)導入
cd /tmp
wget https://github.com/GeoffMontee/tds_fdw/archive/master.zip
unzip master.zip
PATH=/usr/pgsql-14/bin:$PATH
which psql
whereis psql
whereis pg_config
cd tds_fdw-master
make USE_PGXS=1
make USE_PGXS=1 install
CREATE EXTENSION tds_fdw(成功)
tds_fdw拡張が導入済状態でpostgresにログオンして以下実行すると、拡張の有効化が成功する
CREATE EXTENSION tds_fdw
# 0 件のレコードを操作しました。(成功)
tds_fdwの活用(データ移行実施)
1. 接続先となるSQL Serverのユーザーアクセスの確認
tsql -H '{OLD-IP-ADDRESS}' -p 1433 -U {OLD-USER-NAME} -P {OLD-PASSWORD}
1> use "{OLD-DB-NAME}"
2> select * from testa
3> go
{結果}
1> quit
2. 接続元となるPostgreSQL14のユーザーアクセスの確認
psql -h{NEW-IP-ADDRESS} -U{NEW-USER-NAME} -W {NEW-DB-NAME}
パスワード:
{NEW-DB-NAME}=# select * from testb;
{結果}
{NEW-DB-NAME}=# exit;
3. 外部サーバー、ユーザマッピング、外部サーバー利用権限の定義
psql -h{NEW-IP-ADDRESS} -U{NEW-USER-NAME} -W {NEW-DB-NAME}
{NEW-PASSWORD}
CREATE SERVER old_mssqlsrv FOREIGN DATA WRAPPER tds_fdw OPTIONS (servername '{OLD-IP-ADDRESS}', port '1433', database '{OLD-DB-NAME}');
CREATE USER MAPPING FOR postgres SERVER old_mssqlsrv OPTIONS (username '{OLD-USER-NAME}', password '{OLD-PASSWORD}');
grant usage on foreign server old_mssqlsrv to postgres;
4. 外部表を設置するスキーマの作成
CREATE SCHEMA oldmssql;
5. 外部表の定義
CREATE FOREIGN TABLE oldmssql."testc" (
"testcolumn1" float8
, "testcolumn2" int
)
SERVER old_mssqlsrv
OPTIONS (schema_name 'dbo', table_name 'testc');
6. 移行先とする内部表の定義
create table public."testc" (
"testcolumn1" float8
, "testcolumn2" int
, created_at timestamp(6) with time zone default CURRENT_TIMESTAMP
, updated_at timestamp(6) with time zone default CURRENT_TIMESTAMP
)
7. 移行先とする内部表で利用するトリガーの定義
CREATE TRIGGER refresh_attestc_updated_at_step1
BEFORE UPDATE ON public."testc" FOR EACH ROW
EXECUTE PROCEDURE refresh_updated_at_step1();
CREATE TRIGGER refresh_attestc_updated_at_step2
BEFORE UPDATE OF updated_at ON public."testc" FOR EACH ROW
EXECUTE PROCEDURE refresh_updated_at_step2();
CREATE TRIGGER refresh_attestc_updated_at_step3
BEFORE UPDATE ON public."testc" FOR EACH ROW
EXECUTE PROCEDURE refresh_updated_at_step3();
※CREATE FUNCTION refresh_updated_at_step1()などもしておく。
参考させていただいたページ
8. セレクトインサートを用いたデータ移行
insert into public."testc" (
"testcolumn1"
,"testcolumn2"
)
"testcolumn1"
,"testcolumn2"
from
oldmssql."testc"
データ移行が出来た。
Discussion