PostgreSQLエンタープライズ・コンソーシアム 技術部会 WG#2

WG2活動報告書
移⾏ガイドブック

PostgreSQL Enterprise Consortium

⽬次
⽬次
1. 改訂履歴
2. ライセンス3. はじめに3.1. 本資料の概要と⽬的
3.2. 本資料の構成
3.3. 本資料で扱うRDBMS
4. PostgreSQL紹介
4.1. 概要
4.2. PostgreSQLライセンス
4.3. バージョン
4.4. 導⼊⽅法
4.5. 周辺ツール
5. データベース移⾏作業とは
5.1. データベース移⾏の考え⽅
5.2. データベース移⾏の進め⽅
5.3. 開発⼯程におけるデータベース移⾏
6. アセスメント
6.1. アセスメントとは
6.2. ⾮互換調査(製品⽐較)
6.2.1. アーキテクチャの違い
6.2.2. スキーマの違い
6.2.3. ユーザの違いについて
6.2.4. データベース・オブジェクトの違いについて
6.2.5. SQLの違い
6.2.5.1. データ型
6.2.5.2. 組み込み関数
6.2.5.3. SQL⽂6.2.5.4. 演算⼦・条件・結合・疑似列
6.2.5.5. その他
6.2.6. SQL⼿続き⾔語の違い
6.2.7. トランザクションの違い
6.3. コスト⾒積もり
7. 移⾏作業7.1. スキーマ移⾏
7.1.1. スキーマ移⾏の全体像
7.1.2. スキーマ移⾏⽅式
7.1.3. オブジェクト定義の変更
7.2. アプリケーション移⾏
7.2.1. アプリケーション移⾏の全体像
7.2.2. アプリケーション移⾏⽅式
7.2.3. 開発＆実⾏環境の変更
7.2.4. ソースコードの変更
7.2.5. 標準規格インタフェースの対応
7.2.5.1. JDBC系
7.2.5.2. Windows系
7.2.6. 分析⽀援ツールの利⽤
7.3. データ移⾏
7.3.1. データ移⾏の全体像
7.3.2. データ移⾏⽅式
7.3.2.1. データ移⾏フロー
7.3.2.2. データ抽出
7.3.2.3. データ変換
7.3.2.4. データ取込
Page 2 of 44

2
5
6
7
7
7
7
8
8
8
8
8
9
10
10
10
11
12
12
12
12
13
14
14
14
14
15
16
18
18
20
20
21
22
22
22
22
24
25
25
26
26
27
27
27
29
32
32
32
33
33
34
34
34

PostgreSQL Enterprise Consortium

7.3.2.5. データ確認
8. 運⽤
8.1. 運⽤の概要
8.2. バックアップ
8.3. 索引の保守
8.4. データベースのVACUUM
8.5. ログの管理
8.6. データベースの監視
8.7. パフォーマンス診断
8.8. アップグレード
9. 著者

35
36
36
36
37
38
40
41
42
43
44

Page 3 of 44

PostgreSQL Enterprise Consortium

Page 4 of 44

PostgreSQL Enterprise Consortium

1. 改訂履歴
版

改訂⽇

変更内容

1.0

2019/03/25

新規作成

1.1

2019/05/20「6.2.4 データベース・オブジェクトの違いについて」の、表6.2の内容を修
正

1.2

2020/03/23「6.2. アプリケーション移⾏」: 標準規格I/F対応の追加と全体構成の変更

Page 5 of 44

PostgreSQL Enterprise Consortium

2. ライセンス
本作品はCC-BYライセンスによって許諾されています。 ライセンスの内容を知りたい⽅は こちら でご確認ください。 ⽂書の内容、表記に関する誤り、ご要望、感想等につきましては、PGEConsのサイト を通じてお寄せいただきますようお願いいたします。
Eclipseは、Eclipse Foundation,Inc.の⽶国、およびその他の国における商標もしくは登録商標です。
IBMおよびDb2は、世界の多くの国で登録されたInternational Business Machines Corporationの商標です。
Intel、インテルおよびXeonは、⽶国およびその他の国における Intel Corporation の商標です。
Javaは、Oracle Corporation 及びその⼦会社、関連会社の⽶国及びその他の国における登録商標です。 ⽂中の社名、商品名等は各社の商標または登録商標である場合があります。
Linux は、Linus Torvalds ⽒の⽇本およびその他の国における登録商標または商標です。
Red HatおよびShadowman logoは、⽶国およびその他の国におけるRed Hat,Inc.の商標または登録商標です。
Microsoft、Windows Server、SQL Server、⽶国 Microsoft Corporationの⽶国及びその他の国における登録商標または商標です。
MySQLは、Oracle Corporation 及びその⼦会社、関連会社の⽶国及びその他の国における登録商標です。 ⽂中の社名、商品名等は各社の商標または登録商標である場合があります。
Oracleは、Oracle Corporation 及びその⼦会社、関連会社の⽶国及びその他の国における登録商標です。 ⽂中の社名、商品名等は各社の商標または登録商標である場合があります。
PostgreSQLは、PostgreSQL Community Association of Canadaのカナダにおける登録商標およびその他の国における商標です。
Windows は⽶国 Microsoft Corporation の⽶国およびその他の国における登録商標です。
TPC, TPC Benchmark,TPC-C, TPC-E, tpmC, TPC-H, QphHは⽶国Transaction Processing Performance Councilの商標です
その他、本資料に記載されている社名及び商品名はそれぞれ各社が 商標または登録商標として使⽤している場合があります 。

Page 6 of 44

PostgreSQL Enterprise Consortium

3. はじめに3.1. 本資料の概要と⽬的
本資料は異種DBMSからPostgreSQLへの移⾏を検討される⽅の参考にしていただくことを⽬的に、 PostgreSQLエンタープライズ・コンソーシ
アム(以下PGECons)が作成・公開をしています。
PGEConsは、PostgreSQL本体および各種ツールの情報収集と提供、整備などの活動を通じて、 ミッションクリティカル性の⾼いエンタープラ
イズ領域へのPostgreSQLの普及を 推進することを⽬的として設⽴された団体です。
PGEConsの技術部会では、PostgreSQLの普及に対する課題の検討を通じて活動テーマを挙げ、 そのテーマごとにワーキンググループを⽴ち上げて活動しています。その中の⼀つである WG2(移⾏ワーキンググループ)では、「異種DBMSからPostgreSQLへの移⾏」をテーマとして 調査・検証を⾏い、収集した技術ノウハウを成果として取り纏めた資料を公開してきました。
しかし、WG2の活動でこれまでに積み上げてきた資料は膨⼤なページ数になっており、 移⾏の検討をする初期段階に参考にするのは難しいのではないかという課題が挙がりました。 そこで、PostgreSQLへの移⾏を検討する⽅がはじめに読むにあたり、移⾏の全体像を つかむことができるような資料として、これまでに公開した資料の要素に加え、あまり 触れられていなかった運⽤⾯でのポイントを整理し、移⾏ガイドブックという形でまとめました。
本資料が皆様のPostgreSQL採⽤検討の⼀助になれば幸いです。

3.2. 本資料の構成
本資料の本⽂の構成は下表の通りです。
表 3.1 本資料の構成
章

概要

3 はじめに

本資料の位置づけと概要説明

4 PostgreSQL紹介

PostgreSQLの簡単な紹介

5 データベース移⾏作業とはデータベース移⾏の考え⽅や⼯程の概要について説明

6 アセスメント

データベース移⾏のアセスメントに必要となる観点について説明

7 移⾏作業

実際にデータベース移⾏開発を⾏うにあたり発⽣する作業について説明

8 運⽤

PostgreSQLの運⽤に必要となる作業の概要について説明

3.3. 本資料で扱うRDBMS
本資料ではデータベース移⾏作業の概要を5章で⽰し、6章以降の具体的な内容についてはOracleからPostgreSQLへの移⾏を題材として記載しています。 各RDBMSの情報については下表のバージョンをベースに記載をしていますが、極⼒バージョンに左右されない基本的・共通的な内容を中⼼にしています。 より新しいバージョンに関する内容については、本⽂中で補⾜をしています。
表 3.2 本書で扱うRDBMSRDBMS名称

バージョン

PostgreSQL

10

OracleDatabase

11gR2

Page 7 of 44

PostgreSQL Enterprise Consortium

4. PostgreSQL紹介
本章ではPostgreSQLについて簡単にご紹介します。

4.1. 概要
PostgreSQL（Postgres）はオープンソースソフトウェア（OSS）として開発されているRDBMSです。 年1回のペースで新しいバージョンをリリースし、年々機能強化・性能改善を⾏い進化を続けています。 最近のバージョンでは、パーティショニングやパラレルクエリなど、⼤規模
データベース向けの機能強化が進んでいます。 他にも多くの機能が実装されており、機能⾯では商⽤データベースに対しても遜⾊のないものになってきています。
PostgreSQLはThe PostgreSQL Global Development Group（PGDG）というコミュニティにより開発されています。 このコミュニティには
世界各国の開発者が参加しており、メーリングリストなどで活発な議論が⾏われています。 コミュニティとしての活動のため、特定の企業に依存するものではなく、開発の⽅向性は開発者による議論の中で決められていきます。
また、PostgreSQLのコミュニティとしては、世界各国にユーザコミュニティが存在しています。 ⽇本では早くから⽇本PostgreSQLユーザ会（JPUG）が設⽴され、PostgreSQL関連のセミナーを開催したり、 ⽇本語版マニュアルの翻訳・公開、Let's Postgresというポータルの運営などの活動をしています。
⽇本語マニュアルをはじめ、PostgreSQLについては⽇本語の情報が多く公開されており、 ⽇本では⽐較的PostgreSQLの普及が進んでいる傾向にありました。 近年、企業によるOSS採⽤が伸びていくにあたり、PostgreSQLの利⽤はさらに広がってきています。

4.2. PostgreSQLライセンス
PostgreSQLは「PostgreSQLライセンス」というライセンスの下に公開されています。 PostgreSQLライセンスはBSDやMITライセンスに似た
オープンソース・ライセンスであり、単純に使⽤する分には無償であることはもちろん、 著作権や免責事項などのライセンス条件の表記の複製を添付することで再頒布・再利⽤をすることが可能です。 PostgreSQLを改造して組み込み利⽤するようなケースにおいても、ソースコードを公開する必要はありません。
開発コミュニティはライセンスについて、今後変更する予定はないことを明⾔しています。 ライセンス条件が変わる可能性を意識せずに、⻑期
的に使⽤することができます。
また、PostgreSQLは無償で利⽤することができますが、商⽤データベースのように保守サポートが提供されるわけではありません。 安⼼して運⽤を続けるためには保守サポートについて別途検討する必要があります。 PostgreSQLに対しては、多くの企業が保守サポートをはじめとした様々なサービスを提供しています。

4.3. バージョン
PostgreSQLのバージョンは X.Y 形式（※）で表記されます。 Xがメジャーバージョンを、Yがマイナーバージョンを表し、2019年4⽉現在の最新メジャーバージョンは11です。
※ バージョン10より前のバージョンでは X.Y.Z 形式で表記され、X.Yの部分がメジャーバージョンを⽰していました。
PostgreSQLでは概ね年に1回、新しいメジャーバージョンがリリースされます。 メジャーバージョンのリリースでは、新機能の追加や性能改善などが主に実施され、互換性に影響のある内容を含みます。 メジャーバージョンアップを⾏う際には、旧バージョンのデータをそのまま使⽤することはできません。 バックアップリストア、もしくはツール（pg_upgrade）を使⽤して移⾏をする必要があります。
また、PostgreSQLは3か⽉に1回、計画的に新しいマイナーバージョンのリリースをしています。 それ以外にも、脆弱性などの重⼤な問題があれば、スケジュール外のリリースが⾏われる可能性があります。 マイナーバージョンのリリースでは主にバグの修正が取り込まれており、原則として互換性に影響のある修正は⾏われません。
コミュニティでは各メジャーバージョンについて、リリースされてから約5年間サポートを継続しています。 5年後に最終リリースを迎えたバー
ジョンについては、原則新しいリリースが⾏われることはありません。 （⾮常に影響の⼤きい問題の場合は対応される可能性はあります。） サ
ポートの終了に合わせて、計画的にバージョンアップを⾏うことを推奨します。

4.4. 導⼊⽅法
PostgreSQLは主要なCPUアーキテクチャ、およびOSでの動作をサポートしています。 主なプラットフォームに関しては、ビルドファームという検証⽤のサーバ群にて⽇々動作検証が⾏われています。

Page 8 of 44

PostgreSQL Enterprise Consortium

PostgreSQLのソースおよびバイナリパッケージは、下記PostgreSQLのWebサイトから⼊⼿することができます。
https://www.postgresql.org/download/
Linuxディストリビューション向けには、RPMなどのインストール⽤パッケージが提供されています。 Yumなどのパッケージ管理システム⽤のリポジトリも提供されているため、そちらを指定してインストールすることも可能です。 Windowsについてもインストーラが提供されており、PostgreSQLのインストール⽅法は⾮常に簡単です。
また、PostgreSQLはOSSであり、ソースコードが公開されているため、⾃らビルドをして導⼊することができます。 各プラットフォームにおいてバイナリパッケージが⽤意されているため、そちらを使⽤するのがシンプルではありますが、 ブロックサイズなどビルド時のみ変更可能なパラメータも存在するため、そのようなケースではソースからの導⼊が必要になります。

4.5. 周辺ツール
PostgreSQL本体以外にも、PostgreSQLの機能を補完する周辺ツールがOSSとして開発・提供されています。 PostgreSQLに組み込んで機能を拡張するものや、PostgreSQLと連携して動作するものなど、多岐にわたるツールが存在しています。 RDBMSの移⾏という点では、Oracleと同じような機能や運⽤性を提供するツール、Oracleからの移⾏作業を補助するツールなどが有⽤です。
PostgreSQL向けに提供されている周辺ツールの⼀部について、下表にてご紹介します。 ただし、Windowsではサポートされていないものが多いためご注意ください。
表 4.1 PostgreSQLの周辺ツール
分類
移⾏

性能

運⽤・監視

その他

ツール名

概要

ora2pgOracleからPostgreSQLへの移⾏ツール。移⾏評価レポート、定義・SQLの変換、データの移⾏などの機能を提供。

OrafceOracleが提供するパッケージや組み込み関数をPostgreSQL上で代替する拡張機能。

pg_dbms_stats PostgreSQLの統計情報を固定する拡張機能。通常ANALYZEで採取する統計情報をダミー情報で固定化することで、予期しない実⾏計画の変更を防ぐことが可能。
pg_hint_plan

PostgreSQLにヒントを実装する拡張機能。ヒント句を使⽤してスキャンや結合の⽅式を指定することで、SQLの実⾏計画を制御することが可能。

pgBadger

PostgreSQLのログファイルを解析して、SQL実⾏状況などのHTMLレポートを⽣成。

pg_monz

ZabbixによるPostgreSQL監視のためのテンプレートを提供。

pg_repack

通常は排他ロックを必要とするテーブルやインデックスの再編成を、排他ロックをかけずに実⾏可能とする拡張機能。

pg_rmanPostgreSQLのバックアップ・リカバリ実⾏の簡易化、バックアップの世代管理など、バックアップ運⽤を補助するツール。

pg_statsinfo

PostgreSQLの稼働統計情報のスナップショットを定期的に収集・蓄積し、データベースの処理状況、性能傾向などの確認に利⽤可能。レポート出⼒機能も提供。

pg_bigm

PostgreSQLに⽇本語対応の全⽂検索機能を提供する拡張機能。

pg_bulkload

PostgreSQLに対して⼤量データの⾼速ロードを可能とするツール。

pgpool-II

PostgreSQLのサーバ・クライアント間で動作するミドルウェア。コネクションプール、レプリケーション、
負荷分散などの機能を提供。

PostGIS

PostgreSQL上で地理情報データを取り扱うための拡張機能。

Page 9 of 44

PostgreSQL Enterprise Consortium

5. データベース移⾏作業とは
5.1. データベース移⾏の考え⽅
異種データベース間の移⾏ではデータベースの優劣を⽐較分析するのではなく、データベースを利⽤している業務システムの利⽤⽬線で「AsIs（現状）」と「To-Be（あるべき姿）」に対するFit&Gap分析をして、課題を明らかにします。
そして課題に対してどう対応するのか、つまりTo-Beに近づくために何をすれば良いのかを考えることになりますが、To-Beはあくまでも理想形であり、理想を追求して膨⼤な修正費⽤がかかっては意味がありません。
対応が必要な機能・作業に優先順位をつけ、現実的な落としどころ「Can-Be（現実的解）」を⾒つけることが重要です。

図 5.1 DB移⾏における課題と対応の考え⽅

5.2. データベース移⾏の進め⽅
データベース移⾏作業の⼤まかな流れは以下の図の通りです。
実際の移⾏作業に取り掛かる前に、前述の考え⽅に従って移⾏時の作業内容、作業量を調査する「アセスメント」を実施する必要があります。アセスメントの結果をもとに移⾏を⾏うかどうか判断し、実際の移⾏作業に取り掛かります。
移⾏作業は、移⾏対象であるスキーマ、アプリケーション、データに対する変換作業や代替作業などを実施し、その後移⾏検証、運⽤の流れで進めます。

図 5.2 データベース移⾏フロー

移⾏フローの各⼯程の作業⽬的と、主要な作業項⽬は下表の通りです。

Page 10 of 44

PostgreSQL Enterprise Consortium

表 5.1 移⾏フローと作業項⽬
移⾏⼯程

⽬的

主要な作業項⽬

アセスメント

移⾏⽬的の達成可能性を確認し、データベース移⾏の可否を判断する・システム品質要求の適合性の把握
・移⾏難易度の把握
・移⾏コストの⾒積り・移⾏可否判定

スキーマ移⾏

テーブル、ビュー、インデックス、ストアド・プロシージャなどのデータベース・オブジェクトを移⾏する

・データベースの構築
・データベースオブジェクトの定義移⾏
・他DB間の連携（データベースリンク）

アプリケーション移⾏

データベース変更によるAPI、SQL⽂等の差異を解消する

・データベース接続、ドライバの変更
・SQL、組み込み関数、ストアド・プロシージャの改修・コマンド、API、ツールの付け替え

データ移⾏

移⾏元DB上のデータを移⾏する

・データ型、⽂字コードの変換
・データクレンジング・データの抽出、投⼊⽅法検討

移⾏検証

データベース変更による影響確認を⾏う

・機能テスト、⾮機能テスト
・パフォーマンスチューニング

運⽤

データベース変更によるシステム運⽤保守を新たに構成する・運⽤保守設計の修正（運⽤処理、稼働監視）

5.3. 開発⼯程におけるデータベース移⾏
移⾏フローの各⼯程において、データベース移⾏作業をどのように進めるか、⼀般的な開発⼯程にマッピングした例を以下に⽰します。
アプリケーションの修正がなくSQLの⾮互換修正のみであっても、テスト⼯程は実施する必要があります。

図 5.3 開発⼯程におけるデータベース移⾏作業

Page 11 of 44

PostgreSQL Enterprise Consortium

6. アセスメント
6.1. アセスメントとはアセスメントとは、現⾏環境のSQLやアプリケーションに対して、 移⾏が必要な個所がどこなのか、どういった⾮互換があるのかを調査し、 移⾏の作業量や難易度を算出する作業を指します。
次の観点でアセスメントを実施します。
システム品質要求に適合するか
可⽤性
運⽤、保守性
性能、拡張性セキュリティ など
移⾏難易度はどの程度か
スキーマ
アプリケーション
データ
移⾏コストはどのくらいかかるか
⼯数
また、調査対象の例は次のとおりです。
要件定義書
各種設計書
DDLやPL/SQL、アプリケーションなどのソース
具体的な調査内容については次節を参考にしてください。
調査時にはデータベース部分だけではなく、OSや周辺ミドルウェアなどについても合わせて調査を⾏ってください。
そして、ここで実施したアセスメントの結果を基に、データベース移⾏を実施するかどうかの判断を⾏います。

6.2. ⾮互換調査(製品⽐較)
アセスメントをするにあたって、RDBMS間の違いを把握しておく必要があります。
以降では以下の主要な違いについて説明します。
アーキテクチャ
スキーマ
ユーザ
データベース・オブジェクト
SQL (データ型やSQL⽂、組み込み関数など)
SQL⼿続き⾔語
トランザクション

6.2.1. アーキテクチャの違い
アーキテクチャは各RDBMSごとに異なっており、それぞれ特⾊があります。 移⾏にあたり、その差異を理解しておく必要があります。本節では主なものをピックアップして説明します。
■プロセス構成
PostgreSQL、Oracle共にクライアント・サーバ型、マルチプロセス構成です。
細かなプロセス構成に違いはありますが、移⾏に影響することは特にありません。
■メモリ構成PostgreSQLは、共有メモリ領域とプロセス毎のメモリ領域から構成されます。メモリ管理は⼿動管理で、データベースクラスタの制御ファイル(postgresql.conf)のパラメータに指定した値が⽤いられます。
Oracleは、インスタンス内で共有されるメモリ領域(SGA)とプロセス毎に固有のメモリ領域(PGA)から構成されます。メモリ管理は⾃動管理と⼿動管理の2種類です。

Page 12 of 44

PostgreSQL Enterprise Consortium

メモリの管理⽅法は異なりますが、メモリ構成の違いが移⾏に影響することはありません。
■データ構成PostgreSQLとOracleでは、「データベース」、「インスタンス」の考え⽅が異なります。また図に⽰すように、データ構成も異なります。
データ構成の違いは移⾏の難易度を⼤きく左右するものではありませんが、データ移⾏の設計に関わるため、その差異を理解しておく必要があります。
PostgreSQL
データベースの集合を「データベースクラスタ」として管理します。これはOracleで「インスタンス」と呼ばれるものに相当します。
1つのデータベースクラスタは複数のデータベースを管理することが可能なため、データベースクラスタ(インスタンス)とデータ
ベースは1対Nの関係になります。
バックグラウンドプロセス、WAL、設定ファイルなどはデータベース間で共有されます。
Oracle
インスタンスとデータベースは1対1の関係で、1つのインスタンスにつきインスタンス構成情報とデータベース構成情報を1つずつ持ちます。
[Oracle12c以降] マルチテナントの場合、1つのCDB(インスタンスに対応)は複数のPDBを管理することが可能です。バックグラ
ウンドプロセス、REDOログ、制御ファイルなどはPDB間で共有されます。
表 6.1 データ構成⽐較
PostgreSQL

Oracle

データの
構成

データ
ファイル
の構造

6.2.2. スキーマの違い
PostgreSQLとOracleはともにスキーマを持ちますが、考え⽅などに違いがあります。
本節では主要な違いをピックアップして説明します。
■スキーマの考え⽅
表などのオブジェクトはスキーマに所属する形で管理されますが、OracleとPostgreSQLで違いがあります。
Oracleではユーザとスキーマが1対1で対応していますが、PostgreSQLではユーザとスキーマが対応づいていません。
■オブジェクト作成時に割り当てられるスキーマ
Oracleでは"ユーザ名"と同じ名前のスキーマが⾃動的に作成され、割り当てられます。
PostgreSQLでは"ユーザ名"のスキーマが⾃動的に作成されることはありません。CREATE SCHEMA⽂により明⽰的に定義することは可能です。
■検索時のスキーマの優先順位
Oracleでは"ユーザ名"のスキーマを検索します。
PostgreSQLではsearch_pathパラメータで設定します。デフォルトでは"ユーザ名"、"public"スキーマの順です。スキーマ名を指定していない
場合、search_pathに指定された順にオブジェクトの検索を⾏います。

Page 13 of 44

PostgreSQL Enterprise Consortium

6.2.3. ユーザの違いについて
PostgreSQLとOracleは共にユーザを作成して利⽤しますが、考え⽅などに違いがあります。
本節では主要な違いをピックアップして説明します。
■ユーザの考え⽅
PostgreSQLとOracleではユーザの考え⽅が異なります。
PostgreSQLではユーザはロールの⼀種で、LOGIN属性を持つロールを指します。 Oracleと同様に、LOGIN属性を持つロール（ユーザ）を別のロールに所属させることも可能です。
■事前定義されるユーザ・アカウント
Oracleでは、インストール時に事前定義済のアカウントが複数作成されますが、 PostgreSQLではデータベース作成時に指定したアカウントのみが管理者として作成されます。 また、データベースサーバを監視するロールを簡単に設定できるデフォルトロールが定義されています。
PostgreSQLで管理者以外のユーザ・アカウントが必要な場合は、CREATE ROLE⽂またはCREATE USER⽂で作成します。

6.2.4. データベース・オブジェクトの違いについて
表や索引などの基本的なオブジェクトはPostgreSQLでも使⽤可能です。 ⼀⽅、シノニムやデータベース・リンクなどのオブジェクトはPostgreSQLにありません。 これらのPostgreSQLにないオブジェクトを使⽤している場合は、移⾏⽅法の事前検討や移⾏⼯数を多く⾒積もるな
どの対応を⾏う必要があります。
データベース・オブジェクトの対応については以下のとおりです。
表 6.2 DBオブジェクトの対応表
OraclePostgreSQL

補⾜

テーブル

○

グローバル⼀時表は⾮対応。パーティショニングは、レンジ/リスト相当のみ。

インデックス○

逆キー索引、ビットマップ、ドメイン、クラスタ、索引構成表は⾮対応。

ビュー○

マテリアライズドビュー○

参照のみ。⾃動リフレッシュ⾮対応。

シノニム

×

ビューで代⽤可能。

シーケンス

○

トリガー

○

データベースリンク

×

FDW(Foreign Data Wrapper)またはdblink関数で代替可能。

ストアドプロシージャ○

⼿続き型⾔語の仕様相違の対処が必要。バージョン11よりサポート。

ストアドファン
クション○

トランザクション制御と⼿続き型⾔語の仕様相違の対処が必要。

パッケージ

×

代替⽅法はスキーマを使⽤して関数群をまとめる。パッケージレベルの変数はセッションごとの状態を⼀時テーブル内部に保存する。

ユーザ○

ユーザはロールに包括されている。

○

ロール権限とオブジェクト権限があり、⼀部を除き⾮互換のために対処が必要。

ロール〇：存在する×：存在しない

6.2.5. SQLの違い
PostgreSQLもOracleもどちらも標準SQL(Core SQL)に完全または部分的に準拠しています。 しかし、独⾃機能などの⾮互換があるため、調査を⾏う必要があります。
以降では詳細について説明します。

6.2.5.1. データ型
データ型についてはそのまま使⽤できるものもありますが、移⾏が必要なものも多くあります。 また、同じ名前のデータ型が存在する場合でPage 14 of 44

PostgreSQL Enterprise Consortium

も、有効桁数などに違いがある場合があるため注意が必要です。
主要なデータ型の対応については以下のとおりです。
表 6.3 データ型の対応表
Oracle属性

PostgreSQL

PostgreSQLのデータ型についての説明

VARCHAR2varchar

上限付き可変⻑

CHAR

char

空⽩で埋められた固定⻑

CLOB

text

可変⻑（最⼤１GB）

NUMBER

decimal

⼩数点前までは131072桁、⼩数点以降は16383桁

numeric

⼩数点前までは131072桁、⼩数点以降は16383桁

integer

整数(-2147483648〜+2147483647)

real

6桁精度

double precision

15桁精度

FLOAT

float

精度(2進数53桁)

DATE

timestamp

⽇付と時刻の両⽅（時間帯なし） 4713BC〜
294276AD（１μ秒、１４桁）

date

⽇付のみの場合

TIMESTAMP

timestamp

⽇付と時刻の両⽅（時間帯なし） 4713BC〜
294276AD（１μ秒、１４桁）

TIMESTAMP WITH TIMEZONE

timestamp [ (p) ] with timezone

⽇付と時刻の両⽅、時間帯付き、 4713BC〜
294276AD（１μ秒、１４桁）

INTERVAL YEAR TO MONTH

interval [ fields ] [ (p) ]-178000000年〜+178000000年（１μ秒、１４桁）

INTERVAL DAY TO SECOND

interval [ fields ] [ (p) ]-178000000年〜+178000000年（１μ秒、１４桁）

バイナリ

BLOB

bytea

可変⻑のバイナリ列（最⼤１GB）

その他

ROWID

対応なし

⽂字

真数

概数

⽇時

NUMBER

6.2.5.2. 組み込み関数
組み込み関数についてはそのまま使⽤できるものもありますが、移⾏が必要なものも多くあります。 また、同じ名前・機能の組み込み関数が存在する場合でも、 パラメータや結果のデータ型などに違いがある場合があるため注意が必要です。
以下に、主要な関数の対応例を⽰します。
表 6.4 組み込み関数の対応表
互換性

OraclePostgreSQLでの対応⽅法

ABS(n)○

MOD(m,n)○

ROUND(数値)○

TRUNC(数値)○

CHR(n)○

CONCAT(char1,char2)○

LOWER(char1)○

REGEXP_REPLACE(string,pattern[,replace[,pos[,occurrence[,match]]]])△

regexp_replace(string
text,pattern text,replacement
text[,flags text])

REGEXP_SUBSTR(source_char,pattern[,postion[,occurrence[,match_param[,subexpr]]]])△

regexp_matches(string
text,pattern text[,flags text])

REPLACE(char,search_string,replacement_string)○

SUBSTR(char,m,n)○TRIM([LEADING|TRAILING|BOTH] [trim_character] FROM trim_source)○

Page 15 of 44

PostgreSQL Enterprise Consortium

互換性

OraclePostgreSQLでの対応⽅法

UPPER(char)○

ASCII(char)○

INSTR(string,substring)△

LENGTH(char)○

ADD_MONTHS(date,integer)△

CURRENT_DATE○CURRENT_TIMESTAMP○SYSDATE△

current_date、
current_timestamp、
clock_timestamp

SYSTIMESTAMP△

systimestamp
current_timestamp、
clock_timestamp

CAST(expr AS type_name)○

CONVERT(char,dest_char_set,source_char_set)○

TO_CHAR(d,fmt)○

TO_CHAR(n,fmt)○

TO_DATE(char,fmt)○

TO_NUMBER(char,fmt)○

TO_TIMESTAMP(char,fmt)○

DECODE(expr,search,result)△case式で置き換える

NVL(expr1,expr2)△

coalesce(expr1,expr2)

AVG(expr)○

COUNT(expr)○

MAX(expr)○

MIN(expr)○

RANK() OVER (ODER_BY_clause)△

SUM(expr)○

strpos(string,substring)+演算⼦を使って書換え可能 例:
select date '2018-03-22' +interval '1 months'

convert(string
bytea,src_encoding
name,dest_encoding name)rank()○：あり、△：別の⽅法で代替可能

6.2.5.3. SQL⽂
1.データ定義⾔語(DDL)
PostgreSQLにも存在するオブジェクトについては、 CREATE⽂やDROP⽂、ALTER⽂などを使⽤する点はOracleと同様です。 ただし、⼀部の構⽂やオプションに違いがあるため、 実際のシステムで使⽤している構⽂を確認し、⾮互換があるかどうか調査を⾏う必要があります。

Page 16 of 44

PostgreSQL Enterprise Consortium

表 6.5 DDL対応表
Oracle

⽂の有無

備考

ALTER

○

PostgreSQLに存在するオブジェクトに対するもののみ

ANALYZE△

構⽂に違いありASSOCIATE STATISTICS

×

AUDIT

×

COMMENT○CREATE ...

○DISASSOCIATE STATISTICS×DROP ...

○FLASHBACK ...

×

GRANT

△

NOAUDIT

×

PURGE

×

RENAME×

REVOKE△

システム権限が対象外など取り消し可能な権限に違いあり

TRUNCATE○

省略可能な構⽂に違いあり

PostgreSQLに存在するオブジェクトに対するもののみ

PostgreSQLに存在するオブジェクトに対するもののみ

システム権限が対象外など付与可能な権限に違いあり○：あり、△：⽂はあるが書き換えが必要もしくは⼀部機能がない、×：なし
2.データ操作⾔語(DML)
基本的なSELECT⽂、INSERT⽂、UPDATE⽂、DELETE⽂はPostgreSQLでも使⽤可能です。 ただし、DDL同様に⼀部の構⽂やオプションに違いがあるため、 実際のシステムで使⽤している構⽂を確認し、⾮互換があるかどうか調査を⾏う必要があります。
表 6.6 DML対応表
Oracle

⽂の有無

備考

SELECT○UNIQUE句がないなど構⽂に違いあり

INSERT○ALL INTO句がないなど構⽂に違いあり

UPDATE○ONLY句がないなど構⽂に違いあり

DELETE○

FROM句の省略不可など構⽂に違いあり

MERGE

×

INSERT ON CONFLICTで代替するなどの対処が必要

CALL

×

PostgreSQL11で追加

EXPLAIN PLAN△

EXPLAIN⽂を使⽤する

LOCK TABLE○

PostgreSQLではLOCK⽂○：あり、△：⽂はあるが書き換えが必要もしくは⼀部機能がない、×：なし
3.その他制御⽂■トランザクション制御⽂
COMMIT⽂、ROLLBACK⽂、SAVEPOINT⽂についてはPostgreSQLでも使⽤可能です。 ただし、使⽤できない句があるなど違いがあるため、調査が必要です。
表 6.7 トランザクション制御⽂対応表
Oracle

⽂の有無

備考

COMMIT○

COMMENT句がないなど構⽂に違いあり

ROLLBACK○FORCE句がないなど構⽂に違いあり

SAVEPOINT○

同じ名前のセーブポイントを作成した場合の動作に違いあり

SET TRANSACTION△ISOLATION LEVEL句の場合のみ

SET CONSTRAINT○SET CONSTRAINTSのみ使⽤可能○：あり、△：⽂はあるが書き換えが必要もしくは⼀部機能がない、×：なし

Page 17 of 44

PostgreSQL Enterprise Consortium■セッション制御⽂
そのままでは使⽤できません。そのため、実現したい処理に応じた移⾏法を検討する必要があります。
■システム制御⽂そのままでは使⽤できません。そのため、実現したい処理に応じた移⾏法を検討する必要があります。

6.2.5.4. 演算⼦・条件・結合・疑似列
演算⼦や条件、結合、疑似列について説明します。
そのまま使⽤できる演算⼦や条件は多くありますが、 書き換えが必要なものや動作に違いのあるものも存在するため、 実際にどういったものを使⽤しているか調査を⾏います。
以下にそれぞれの例を⽰します。
■そのまま使⽤できる例
表 6.8 そのまま使⽤できる例
項⽬

例

演算⼦

+, -, *, / (算術演算⼦)
UNION, UNION ALL (集合演算⼦)

条件- =, <, >, <=, =>, !=, <>, ANY, SOME, ALL (⽐較条件)
NOT, AND, OR (論理条件)
LIKE (パターン⼀致条件)
IS NULL, IS NOT NULL (NULL条件)
BETWEEN, EXISTS, IN

結合

JOIN, INNER JOIN, LEFT [OUTER] JOIN, RIGHT [OUTER] JOIN, FULL OUTER
JOIN■書き換えが必要な例
表 6.9 書き換えが必要な例
項⽬

PostgreSQLでの書き換え例

例

演算⼦

MINUS (集合演算⼦)

EXCEPTに書き換え条件^= (⽐較条件)<>条件に書き換え結合(+) (外部結合演算⼦)

JOINに書き換え

疑似列

ROWNUM

LIMIT、OFFSETに書き換え■動作に違いのある例
表 6.10 動作に違いのある例
項⽬
演算⼦

例
|| (連結演算⼦)

差異
NULLが含まれる場合の結果に違いあり

6.2.5.5. その他
その他にもPostgreSQLとOracleには以下のような違いがあります。
1. NULLと空⽂字列
Oracleでは空の⽂字列はNULLと同値として扱われますが、これは標準SQLに準拠したものではありません。
PostgreSQLでは変換されず空⽂字列のまま格納されます。
PostgreSQLでOracleと同じように空⽂字列をNULLと⾒なしたい場合には、NULLIF関数を使って変換する⽅法があります。
・空⽂字列をNULLとみなす検索例
SELECT * FROM staff WHERE NULLIF(name, '') IS NOT NULL;
2. REGEXP_LIKE条件による正規表現マッチング

Page 18 of 44

PostgreSQL Enterprise Consortium

Oracleで、POSIX正規表現規格のマッチングを⾏う場合、REGEXP_LIKE条件を⽤います。
PostgreSQLでPOSIX正規表現のマッチングを⾏う場合には正規表現マッチ演算⼦を⽤います。
表 6.11 【正規表現マッチ演算⼦】
演算⼦

例 （結果はすべて真)説明~

正規表現に⼀致、⼤⽂字⼩⽂字の区別あり'thomas' ~ '.*thomas.*'~*

正規表現に⼀致、⼤⽂字⼩⽂字の区別なし'thomas' ~* '.*Thomas.*'!~

正規表現に⼀致しない、⼤⽂字⼩⽂字の区別あり'thomas' !~ '.*Thomas.*'!~*

正規表現に⼀致しない、⼤⽂字⼩⽂字の区別なし'thomas' !~* '.*vadim.*'

POSIX正規表現を使って p で始まるか e が２回現れる名前を検索する例は以下のとおりです。
・Oracleの例
SELECT * FROM staff WHERE REGEXP_LIKE(lower(name), '^p|(e.*){2}');・PostgreSQLの例
SELECT * FROM staff WHERE lower(name) ~ '^p|(e.*){2}';3. 除算を含む計算
PostgreSQLでは乗除算は前⽅より順に⾏われます。このため割り切れない除算は数値型の精度に依存し、丸め処理が⾏われた後に後⽅の計算が⾏われるため、Oracle と異なる結果になります。
PostgreSQL内では除算を含む計算をさせず、結果のみを格納するような変更が必要となります。
・Oracleの例
SQL> SELECT 1/3*3 AS result FROM dual;
RESULT---------1
SQL> SELECT (1/3 + 1/3 +1/3) AS result FROM dual;
RESULT---------1
・PostgreSQLの例
postgres=# SELECT 1/3*3 AS result;result-------0
postgres=# SELECT 1.0/3.0*3.0 AS result;result------------------------0.999999999999999999990
postgres=# SELECT (1/3 + 1/3 + 1/3) AS result;result-------0
postgres=# SELECT (1.0/3.0 + 1.0/3.0 + 1.0/3.0) AS result;result-----------------------0.99999999999999999999
4. SEQUENCEキャッシュ動作
PostgreSQLのSEQUENCEキャッシュは、セッション単位にあらかじめ番号を割り当て、メモリに格納することでアクセスを速くする仕組みで
Page 19 of 44

PostgreSQL Enterprise Consortium

す。そのために、複数のセッションで同時に使⽤すると連番にはなりません。
これを回避するためには、キャッシュを使⽤しないようにキャッシュサイズを 1 にします。
5. 複合⼀意制約のNULL動作
複合⼀意制約を設定した場合に、これらの１つの列がNULLとなるデータを重複して登録しようとした場合、Oracleは⼀意制約違反となります。
PostgreSQLでは重複して登録されます。これはNULLは未知の値を表し、2つの未知の値が等しいかどうかを判断することはできないからです。
6. 暗黙的な型変換
PostgreSQLは基本的に暗黙的な型変換をしないので、明⽰的にCASTする必要があります。
以下にCASTが必要な例を⽰します。
・NGの例
postgres=# SELECT 1 + '1.0' AS result;
ERROR: invalid input syntax for integer: "1.0"LINE 1: SELECT 1 + '1.0' AS result;・OKの例
postgres=# SELECT 1 + CAST('1.0' AS numeric) AS result;result-------2.0

6.2.6. SQL⼿続き⾔語の違い
OracleではSQLの⼿続き型拡張機能であるPL/SQLがよく使⽤されますが、PostgreSQLではPL/pgSQLを使⽤します。
PL/SQLとPL/pgSQLは似ている点も多いですが、以下の例のように⼤きな違いがあります。そのため、これらのPL/pgSQLにない機能を使⽤していないか、使⽤していた場合は代替処理が⾏えるのか検討が必要です。
PL/SQLとPL/pgSQLの違い(例)パッケージを作成できない
Oracle社が提供するPL/SQLパッケージが使⽤できない
トランザクション制御ができない (PostgreSQL10まで)
プロシージャが作成できない (PostgreSQL10まで)
コレクション型などの⼀部データ型がない
エラー・コードやエラー・メッセージが違い、関数ではなく変数から取得する

6.2.7. トランザクションの違い
PostgreSQLとOracleでは、読み取り⼀貫性保証の実現⽅法やエラー発⽣時の振る舞いなどに違いがあります。
本節では主要な違いをピックアップして説明します。
■同時実⾏性PostgreSQL・Oracleともに、複数ユーザがデータに対して同時アクセスすることを保証するために、MVCC(多版型同時実⾏制御)を使⽤して管理します。 そのため、表が同時に問合せおよび更新された際に、新旧の複数バージョンのデータを保持して、読み取り⼀貫性を保証します。
読み取り⼀貫性を維持する⽅法は、PostgreSQLとOracleで下記の通り異なります。
PostgreSQL
更新処理・削除処理が実⾏された場合、旧バージョンのデータを無効にして削除せず、新たにデータを追加します。
Oracle
更新処理・削除処理が実⾏された場合、旧バージョンのデータをUNDOデータとして保持します。
■COMMITの実⾏タイミング
PostgreSQL・Oracleともに、COMMITの実⾏により、トランザクションが実⾏したすべての更新を確定します。 COMMITの実⾏タイミング
は、PostgreSQLとOracleで下記の通り異なります。
PostgreSQLCOMMIT⽂を明⽰的に実⾏したとき
下記の場合で、暗黙的にCOMMITが実⾏されたときPage 20 of 44

PostgreSQL Enterprise Consortium

BEGINを明⽰的に実⾏せず、SQL⽂を実⾏したとき
OracleCOMMIT⽂を明⽰的に実⾏したとき
下記の場合で、暗黙的にCOMMITが実⾏されたとき
CREATE、DROP等のDDL⽂を実⾏したときほとんどのOracle Databaseユーティリティおよびツールを正常に終了するとき■トランザクション中のエラー処理
トランザクション中にエラーが発⽣した場合、破棄される処理の対象がPostgreSQLとOracleで異なります。
PostgreSQL
エラーの発⽣以前に実⾏した同⼀トランザクション内のSQL⽂は、全て破棄されます。
Oracle
エラーが発⽣した実⾏SQL⽂のみが破棄されます。

6.3. コスト⾒積もり
技術的に移⾏が可能であっても、莫⼤なコストがかかり移⾏を⾏うことが現実的ではない場合があります。 そのため、技術的な実現性だけではなく、移⾏コストを⾒積もり、移⾏の⽬的に⾒合うかどうか判断する必要があります。
主要な移⾏コストの例は以下のとおりです。 単純な移⾏費⽤だけでなく、PostgreSQLの開発・運⽤技術の教育費⽤などについても考慮することが必要です。

表 6.12 主要な移⾏コスト例
項⽬

例

コスト⼤

導⼊費⽤

・新DB基盤構築[開発/検証/本番]
・新DB開発/運⽤ツール導⼊[初期費⽤/ライセンス費⽤]

移⾏費⽤

・アセスメント・スキーマ/アプリケーション/データ移⾏
・本番移⾏
・運⽤切替

運⽤費⽤

・ハードウェア、ソフトウェア保守費⽤・サーバ/クラウド利⽤料やリース・レンタル料
・監視サービス費⽤
・障害対応
・チューニング・定期メンテナンス
・OSアップデート

教育費⽤・開発技術トレーニング[設計/SQL/DBA]・運⽤技術トレーニング[導⼊/運⽤管理/クラスタ構築]○○○：DB移⾏により特にコストが⾼くなる項⽬

Page 21 of 44

PostgreSQL Enterprise Consortium

7. 移⾏作業7.1. スキーマ移⾏
スキーマとはデータベースの内部構造を定義する⽤語であり、データの構造、性質やほかのデータとの関連、データベースを操作するときのルー
ルや表現法などを定義したもののことです。
⼀般的なRDBMSでは、データベース内のオブジェクトは「スキーマ」と呼ばれるセットに編成されていて、そのスキーマの中にテーブル、ビューなどのオブジェクト群で構成されています。
つまり、スキーマ移⾏とは、スキーマ内のオブジェクト定義を移⾏することです。

7.1.1. スキーマ移⾏の全体像異なるRDBMS間の移⾏では、機能差異や仕様差異があるので、各オブジェクトの移⾏可否の対応関係を理解することが重要です。
また、移⾏元DBのシステム情報を参照するオブジェクトが存在すれば、移⾏先DBのシステム情報と同等のものに置換するか、新規作成が必要となります。

図 7.1 スキーマ移⾏の全体像

7.1.2. スキーマ移⾏⽅式

Page 22 of 44

PostgreSQL Enterprise Consortium

スキーマ移⾏⽅式は、移⾏元DBからデータベースオブジェクト定義を抽出し、移⾏先DB⽤に定義の変換・作成・確認までが基本的な作業フローとなります。
移⾏元のデータベース・オブジェクト定義(DDL,DCL)を準備し、移⾏先の定義に合うように⾃動または⼿動による変換作業を⾏います。
その後に移⾏先DBで変換済みの定義を実⾏し、システム情報を取得して、データベース・オブジェクトの移⾏漏れがないかを確認しま
す。

※考慮事項
移⾏元のデータベース・オブジェクト定義の管理については、以下のような様々な状況が考えられます。
仕様書がない、または最新化されていない。
定義情報(DDL,DCL)がない、または最新化されていない。
仕様書・定義情報とDB上のオブジェクトが不⼀致となっている。
DB上のオブジェクトに⽤途不明なものが存在している。
本番環境と開発環境のDB上のオブジェクトが不⼀致となっている。

既存の仕様書や定義情報だけを鵜呑みにして作業すると、間違った古い定義を移⾏したり、移⾏漏れなどのリスクがあります。
DB上のオブジェクト情報を利⽤すれば、上記のリスクは軽減されます。ただし、本来不要なオブジェクも移⾏してしまい作業量に影響することもあるので、
この機会に上記の不整合な状況を解消することも念頭に⼊れて、以下の⼀般的な作業フローをベースに⼿直しすると良いでしょう。

図 7.2 スキーマ移⾏移⾏⽅式
1. 抽出
定義情報(DDL,DCL)をDBのシステム情報から抽出します。
なお、個別に定義情報をバージョン管理している場合は、抽出作業は本来は不要ですが、抽出した結果と差異が無いかを確認はします。
2. 変換
抽出した移⾏元のデータベース・オブジェクト定義(DDL,DCL)を移⾏先の定義に合わせて変換します。
この場合は、OracleからPostgreSQLへの移⾏ツール「ora2pg」を利⽤すると、DDLの⾃動変換が可能です。
ただし、PostgreSQLが有している範囲の⾃動変換だけであるために、それ以外は変換ツールの開発や⼿作業による対処が必要です。
※データモデリングツールによる⼀部変換
データモデリングツールなどでテーブル、インデックスなどを管理しているケースでは、ツール上のデータモデル定義を移⾏先に合わせたデータ
型、 桁数、名称に変更し、移⾏先⽤のデータベース・オブジェクト定義を出⼒します。この場合は、ツールがPostgreSQLに対応していることが前提となります。

Page 23 of 44

PostgreSQL Enterprise Consortium

3. 作成
オブジェクト間の依存関係を考慮して定義をPostgreSQLで順次実⾏します。
もし、依存関係を考慮できない場合には、オブジェクト定義を連続実⾏すると依存オブジェクトが存在しないためのエラーが多発しますが、何回も実⾏することで依存オブジェクトが徐々に作成されていき、エラーが無くなっていきます。
表 7.1 代⽤的なオブジェクト依存関係
オブジェクト

依存オブジェクト

テーブル

外部キー制約/シーケンス

インデックステーブル

ビュー

テーブル/ビュー

トリガー

テーブル

ストアドプロシージャ

テーブル/ビュー/ストアドプロシージャ/ストアドファンクション

ストアドファンクション

テーブル/ビュー/ストアドプロシージャ/ストアドファンクション※Oracleの場合は、PL/SQLパッケージなどの固有のシステム関数が多くあり、それらを利⽤するオブジェクトはエラーとなってしまいます。
4. 確認
移⾏漏れの確認のために、DBで管理しているオブジェクト情報を取得します。
オブジェクト単位の件数
オブジェクト種類と名称

表 7.2 オブジェクト情報の取得⽅法
抽出情報

データディクショナリ

システムカタログ

情報スキーマテーブル

ALL_TABLES

pg_class、pg_tables

information_schema.tables

ビュー

ALL_VIEWS

pg_class、pg_views

information_schema.tables

列

ALL_TAB_COLUMNS

pg_attributeinformation_schema.columns

制約定義

ALL_CONSTRAINTS

pg_constraint

information_schema.table_constraints

インデックス定義

ALL_INDEXES

pg_class、pg_indexes

information_schema.key_column_usage

インデックスの列情報

ALL_IND_COLUMNS

pg_attributeinformation_schema.key_column_usage

シーケンス

ALL_SEQUENCES

pg_class、pg_sequences

information_schema.sequences

プロシージャ・ファンクション

ALL_SOURCE

pg_proc

information_schema.routines

トリガー

ALL_TRIGGERS

pg_trigger

information_schema.triggers

マテリアライズドビュー

ALL_MVIEWS

pg_matviews

information_schema.tables※システムカタログとは、RDBMSがテーブルや列の情報などのスキーマメタデータと内部的な情報を格納する場所のことです。
※情報スキーマは、標準SQLで定義されている⽤語で、DBで定義されたオブジェクトについての情報を持つビューの集合から構成されます。

7.1.3. オブジェクト定義の変更
データベースオブジェクト定義の主要な変更箇所は以下のとおりです。
1. 命名規則
オブジェクトに付与できる名称に制約があるので、制約に該当する箇所を変更します。
使⽤可能⽂字と組み合わせ
使⽤禁⽌キーワード（予約語）
最⻑⽂字数

2. データ型
サポートしているのデータ型に変更します。
数値の精度による数値型
⽂字型の種類と範囲
⽇付型の種類と精度

3. 構⽂
基本的な構⽂はほぼ同じなので、オプションの仕様差部分は代替変更、または削除(利⽤中⽌）をします。

Page 24 of 44

PostgreSQL Enterprise Consortium

4. SQL
標準SQLの記述に従っていれば軽度な変更で済みますが、DB独⾃要素の記述箇所を変更します。
独⾃の外部結合式
演算⼦の⼀部
除算を含む計算
別名の付与
独⾃の仮想表独⾃の擬似列NULLと空⽂字列の扱い

5. システム関数
SQLで利⽤しているシステム関数を代替変更します。代替するものが存在しない場合には新規作成が必要となります。
データディクショナリのビューをシステムカタログのビューで代替する。
SQLファンクションを組込み関数で代替する。
PL/SQLパッケージの代替は存在しないが、「Orafce」を導⼊することで⼀部を代替する。

6. ⼿続き型⾔語
ストアドプロシージャの実装で利⽤するSQL⼿続き⾔語として、Oracleは「PL/SQL」であり、PostgreSQLは「PL/pgSQL」があります。
構⽂は似通っていますが、上記の対処に加えて、更に下記のような仕様差が多くあるために、⼿作業による書き換えが必要です。
サブルーチン構成の分離
トランザクション制御の相違
例外制御の相違
エラーコードの相違

7.2. アプリケーション移⾏
ここで⾔うアプリケ－ションとは、業務⽤プログラムの事だけではなく、シェルスクリプトやバッチファイル、DB専⽤コマンド、⽀援ツールなどのDB操作を⾏っている外部プログラム全般を指しています。
これらのアプリケーションからのDB操作には、多種多様な利⽤形態で実装されています。
つまり、アプリケーション移⾏とは、アプリケーションからのDB利⽤形態を移⾏先DBの仕様に合わせて変更することです。

7.2.1. アプリケーション移⾏の全体像
アプリケーションからのDB利⽤形態をおおまかに⼤別すると、「アプリケーションの実⾏形式」「アプリケーションの開発⾔語」「開発/保守運⽤⽀援ツール」となります。
これらを移⾏先DBが提供するインタフェースへ切り替えていくのが基本となります。
汎⽤的なDBインタフェースを利⽤している場合には、変更範囲は⽐較的軽度となります。
DB固有のAPIを利⽤している場合には、原則再作成となります。ただし、同程度のAPIの提供があり、それに置換することで流⽤可能な部分が増える可能性はあります。
SQLの記述は、移⾏先DBの仕様差異に合わせて変更します。詳細は「スキーマ移⾏」の章を参照してください。

アプリケーションからのDB利⽤形態としては、以下となります。
アプリケーションの実⾏形式は、各種プログラム⾔語、コマンド等からDB接続インタフェースを介して、DB接続を確⽴し、SQL⽂を実⾏している。
アプリケーションの開発⾔語は、JDBCなどのAPIを利⽤する形式、ソースコードにSQLを記述した(埋め込みSQL)を使⽤している形式があります。
特に埋め込みSQLを使⽤している場合には、プログラム⾔語専⽤のプリプロセッサでDB接続処理のソースコードを⽣成する必要があります。
開発/保守運⽤⽀援ツールからDB接続インタフェースを介して、DB接続を確⽴し、SQL⽂を実⾏しています。

Page 25 of 44

PostgreSQL Enterprise Consortium

図 7.3 アプリケーション移⾏の全体像

7.2.2. アプリケーション移⾏⽅式
アプリケーション移⾏⽅式は、DBの利⽤形態が多種多様なために⼀律のパターンは存在しません。
移⾏パターンとしては、以下に⼀例を⽰します。
表 7.3 プログラム⾔語
Oracle

⾔語
Java

PostgreSQLJDBC -Type2－

JDBC -Type4

JDBC -Type4C

Oracle Call Interface (OCI)

libpq

C++

Oracle C++ Call Interface（OCCI）

libpq++/Pgfe.NET

Oracle Data Provider for .NET（ODP.NET）

NpgsqlCOM

Oracle Provider for OLE DB

PSQL OLE DB

Oracle Objects for OLE(OO4O)

－

ODBC

Oracle ODBC

psqlODBC

PHP

php-oci8 PHP Data Objects (PDO)

php-pgsql PHP Data Objects (PDO)

Perl

DBI、DBD::Oracle

DBI、DBD::Pg

Ruby

ruby-oci8 DBI

ruby-pg DBI

Pythoncx_Oracle DB-API2

psycopg DB-API2

表 7.4 コマンド
OraclePostgreSQLSQL*Plus

psql

SQL*Loader

copy/pg_bulkload

exp

pg_dump

imp

pg_restore
表 7.5 プリプロセッサ

OraclePostgreSQL

Pro*C/C++ECPG

Pro*COBOLOpen Cobol
ESQL

7.2.3. 開発＆実⾏環境の変更

Page 26 of 44

PostgreSQL Enterprise Consortium

コンパイル、DB実⾏に必要なライブラリを⼊⼿して置換する必要があります。
DBドライバの置換、依存ライブラリのインストールをします。
プリコンパイラを置換します。
導⼊済み開発/運⽤ツールのDB接続先情報を変更します。
または、開発/運⽤ツールを新規導⼊します。
開発環境のビルドやコンパイルのライブラリパスや参照設定を変更します。

7.2.4. ソースコードの変更
1. DBの接続情報
DBの接続形式と接続先情報を変更します。
導⼊したドライバの種類やDBのバージョン、DBライブラリに応じて記述内容が異なります。
2. SQL⽂SQLの構⽂、データ型、組込み関数などの仕様差異を変更します。
プリコンパイラの仕様差異を変更します。
DDLもトランザクション扱いになるので、ROLLBACKさせない場合には明⽰的なCOMMITを追加します。
3. エラーの判定
エラーコードやエラーメッセージによる判定処理があれば変更します。
4. 例外ハンドリング
互換性のない例外による制御処理があれば変更します。
SQL実⾏途中にエラーが発⽣すると、後続のSQL実⾏はすべてエラーとなりROLLBACKするため、 エラー時に継続したい場合は、トランザク
ションを分離します。
5.DB実⾏コマンド
DB実⾏コマンドを変更します。

7.2.5. 標準規格インタフェースの対応
DB接続インタフェースには、プログラム⾔語専⽤のもの、共通的なオブジェクトやAPIなどの多種多様に存在しています。
ここでは、⼀般的に利⽤頻度の⾼い標準規格のインタフェースを利⽤した場合の変更点を取り上げます。

7.2.5.1. JDBC系
JDBCはJava⾔語専⽤のインタフェースです。このJDBCを前提としたAPIが⾔語仕様として標準で組み込まれているためにDBの接続⽅式の種類ごとに提供されているJDBCドライバを⽤意すれば、各種RDBMSに接続することができます。

Page 27 of 44

PostgreSQL Enterprise Consortium

図 7.4 JDBCの通信⽅式イメージ■変更範囲
アプリケーションが標準のJDBC API([java.sql]、[javaｘ.sql]パッケージ)を利⽤している場合には、軽度な変更で対応できます。
JDBCドライバの指定、DB接続情報、エラー値判定、例外ハンドリングの箇所を変更する必要が最低限はあります。
DBベンダー製のSQL例外サブクラスで制御している場合には、SQLExceptionまたはPSQLExceptionで例外を捕捉してエラー判定処理を追加に
なります。
■変更例
1. JDBCドライバのロード[Oracle]Class.forName("oracle.jdbc.driver.OracleDriver");[PostgreSQL]Class.forName(“org.postgresql.Driver”);
2. 接続⽂字列[Oracle]String path = "jdbc:oracle:thin:@//192.168.100.10:1521/orclpdb1.localdomain"; //接続パス
String id = “hr"; //ログインID
String pw = “hrpw"; //ログインパスワード
Connection conn = DriverManager.getConnection(path, id, pw);
[PostgreSQL]
String path = "jdbc:postgresql://192.168.100.10:5432/db01"; //接続パス
String id = “hr"; //ログインID

Page 28 of 44

PostgreSQL Enterprise Consortium

String pw = “hrpw"; //ログインパスワード
Connection conn = DriverManager.getConnection(path, id, pw);
3. エラー判定[Oracle]if (ex.getSQLState().equals("23000")) {if (ex.getSQLState().equals("61000")) {//重複エラー//リソースエラー[PostgreSQL]
if (ex.getSQLState().equals("23505")) {if (ex.getSQLState().equals("55P03")) {4. 例外ハンドリング[Oracle]} catch (SQLIntegrityConstraintViolationException ex) {//整合性制約エラー[PostgreSQL]} catch (SQLException ex) {if (ex.getSQLState().equals("55P03")) {7.2.5.2. Windows系
Windows向けの開発⾔語からアクセス可能なCOMオブジェクト、ActiveXオブジェクト、.NETオブジェクトがこれまで提供されています。
これらのオブジェクトのDB接続インタフェースとしてODBC/OLEDB/.NET Data Providerなどがあります。
このDB接続インタフェースに対応した各RDBMS専⽤のものを⽤意すれば、各種RDBMSに接続することができます。

図 7.5 Windows系のDBオブジェクトと通信⽅式イメージ①

Page 29 of 44

PostgreSQL Enterprise Consortium

図 7.6 Windows系のDBオブジェクトと通信⽅式イメージ②■変更範囲
アプリケーションが利⽤しているオブジェクトの種類により、変更範囲が変わってきます。
ODBC系のオブジェクトは、DB接続情報、エラー判定の箇所を変更する必要が最低限はあります。
OLEDB系のオブジェクトは、DBベンダー製のオブジェクトを利⽤することが多く、OLEDBのAPIに基本的には準拠していますが、部分的には仕様が異なる点や独⾃に拡張した部分もあり、実装の仕⽅により影響範囲が異なります。
■変更例① ADO/VBSの場合※ODBC Provider利⽤
1. 接続⽂字列[Oracle]connect.Open("Driver={Oracle in OraClient12home1};DBQ=ORCL;UID=hr;PWD=hrpw;")※DBQ：ネットサービス名 「tnsnames.ora」ファイルの内容
ORCL =(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.100.10)(PORT = 1521))(CONNECT_DATA=(SERVICE_NAME=orclpdb1.localdomain)))[PostgreSQL]
connect.Open("Driver=PostgreSQL Unicode(x64); Server=192.168.100.10;Port=5432;
Database=db01;UID=hr;PWD=hrpw")
2. エラー判定
Errオブジェクトのエラー番号の判定は影響なし
If Err.Number <> 0 Then
WScript.Echo(Err.Number)
WScript.Echo(Err.Source)
WScript.Echo(Err.Description)② ADO.NET/C#の場合※OLEDB Data Provider(ODP.NET/Npgsql) 利⽤
1. パッケージのインポート[Oracle]using Oracle.DataAccess.Client;using Oracle.DataAccess.Types;
またはusing Oracle.ManagedDataAccess.Client;[PostgreSQL]
using Npgsql;
2. 接続⽂字列

Page 30 of 44

PostgreSQL Enterprise Consortium[Oracle]using (var con = new OracleConnection("User ID=hr; Password=hrpw; Data Source=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.100.10)(PORT = 1521))(CONNECT_DATA=(SERVICE_NAME=orclpdb1.localdomain)));") {[PostgreSQL]
using (var con = new NpgsqlConnection("Server=192.168.100.10;Port=5432;
User Id=hr;Password=hrpw;Database=db01")) {3. SQLオブジェクト[Oracle]using (OracleConnection cnn = new OracleConnection(connectstring)){// 接続を開く
cnn.Open();string sql = ""UPDATE EMPLOYEES SET FIRST_NAME = :sei , LAST_NAME = :mei WHERE EMPLOYEE_ID = :id";OracleCommand cmd = new OracleCommand(sql, cnn);// パラメーターに値をバインドする
cmd.BindByName = true;
cmd.Parameters.Add(new OracleParameter(":id", OracleDbType.Int32, 204, ParameterDirection.Input));
cmd.Parameters.Add(new OracleParameter(":sei", OracleDbType.Varchar2, "織⽥", ParameterDirection.Input));
cmd.Parameters.Add(new OracleParameter(":mei", OracleDbType.Varchar2, "信⻑", ParameterDirection.Input));// クエリの実⾏
cmd.ExecuteNonQuery();// 接続を閉じる
cnn.Close();}[PostgreSQL]
using (NpgsqlConnection conn = new NpgsqlConnection(conn_str)){// 接続を開く
cnn.Open();string sql = ""UPDATE EMPLOYEES SET FIRST_NAME = :sei , LAST_NAME = :mei WHERE EMPLOYEE_ID = :id";NpgsqlCommand cmd = new NpgsqlCommand(sql, cnn);// パラメーターに値をバインドする
cmd.Parameters.Add(new NpgsqlParameter("id", DbType.Int32) { Value = 204 });cmd.Parameters.Add(new NpgsqlParameter("sei", DbType.String) { Value = "織⽥" });cmd.Parameters.Add(new NpgsqlParameter("mei", DbType.String) { Value = "信⻑" });// クエリの実⾏
cmd.ExecuteNonQuery();// 接続を閉じる
cnn.Close();}4. エラー判定[Oracle]switch (ex.Number){case 23000:
MessageBox.Show("重複エラー");
break;
case 61000:
MessageBox.Show("リソース・エラー");
break;
default:
MessageBox.Show("Database error: " + ex.Message.ToString());
break;}[PostgreSQL]
switch (ex.Code){case "23505":
MessageBox.Show("重複エラー");
break;
case "55P03":

Page 31 of 44

PostgreSQL Enterprise Consortium

MessageBox.Show("リソース・エラー");
break;
default:
MessageBox.Show("Database error: " + ex.Message.ToString());
break;}
5. 例外ハンドリング[Oracle]catch (OracleException ex) {[PostgreSQL]
catch (NpgsqlException ex) {7.2.6. 分析⽀援ツールの利⽤「db_syntax_diff」を利⽤し、JavaやCのソースコード、及びSQLファイルに記述されているSQL⽂の変更箇所をレポート出⼒します。
レポート結果は、おおよその影響可能性を⽰唆するレベルなので、あくまで参考値としての活⽤に留めてください。

図 7.7 分析ツール利⽤イメージ

7.3. データ移⾏
データ移⾏とは、移⾏元DBに格納されているデータを、移⾏先DBに取込むことです。
異なるDB間では、データ型の仕様やサイズ、使⽤する⽂字コードなどに差異があります。 したがいまして、データ移⾏では必要に応じて移⾏先
DBで取り込めるデータへの変換も⾏います。

7.3.1. データ移⾏の全体像異なるDB間の移⾏では、移⾏データとして特有のバイナリ形式であるバックアップデータを利⽤することができません。
標準的な移⾏では、⼀旦、移⾏元DBと移⾏先DBの両⽅で使⽤できるCSV(カンマ・セパレーテッド・バリュー)等のファイルにデータを抽出します。
そして、データ型や⽂字コードなどの変換を⾏い、移⾏先DBへ取り込みます。

Page 32 of 44

PostgreSQL Enterprise Consortium

図 7.8 データ移⾏の全体像「データ変換」の⼀部は状況によっては、移⾏元DB側や移⾏先DB側の移⾏前後で⾏うケースもあります。
また、ora2pgのようなデータ移⾏ツールでは、同時に両⽅のDBに接続して、データ型を変換しつつ投⼊を⾏うモードもありますが、意図したとおりに動作しない場合もありますので、⼀度中間ファイルに出⼒する⽅法をお勧めします。

7.3.2. データ移⾏⽅式
データ移⾏で実施する作業について説明します。
7.3.2.1. データ移⾏フロー
1. 標準的なデータ移⾏
標準的なデータ移⾏は、移⾏元DBからデータを抽出し、移⾏先DB⽤にデータの変換と、取込・確認を⾏うまでが基本的な作業フローとなります。

図 7.9 データ移⾏フロー
2. ⼤量データの場合
データ件数やデータサイズが⾮常に⼤きい場合、移⾏作業に時間がかかるうえ、既存システムへの影響も⾮常に⼤きくなる可能性あります。
したがいまして、移⾏作業における要件に応じて、移⾏の⼿段を選択する必要があります。
⼀括移⾏
移⾏元のシステム停⽌から新システムの開始までに⼗分な移⾏期間を確保することが出来、Page 33 of 44

PostgreSQL Enterprise Consortium

データ移⾏に必要なリソースをを確保できる場合には、移⾏作業に⼊ってからデータの抽出、加⼯、投⼊で問題ありません。
⼀部データの事前移⾏移⾏すべきデータを選別し、更新される可能性が無いデータは事前に移⾏し、更新がかかるデータの移⾏を移⾏
作業期間中に⾏います。
記事など蓄積型のデータは後で更新されることが少ないと考えられ、移⾏作業中に移⾏するデータ量を削減する
ことにより作業を短期間で完了させることができます。
ただし、事前にデータを抽出する際に既存システムへの負荷がかかる可能性があるため、性能への影響を考慮する必要があります。
また、事前に移⾏するデータと移⾏作業期間中のデータが明確に分かれているか、何らかのチェックポイントを設定して未反映のデータが判断できるようにしておく必要があるため、移⾏作業における設計が重要となります。
データ連携
移⾏元システムのDB と移⾏先のPostgreSQLを使⽤する新システムを並⾏運⽤したり、更新データを随時新シス
テムに反映することにより、データの移⾏期間を最⼩限にすることができます。
移⾏元システムのDBからデータを抽出、加⼯しPostgreSQLに投⼊するため、移⾏元のシステムにかかる負荷が課題となる可能性があるほか、
ETL／データ連携ツールや専⽤アプリケーションを構築する必要があるため、移⾏費⽤が⼤きくなる可能性があります。
7.3.2.2. データ抽出
主なデータ抽出⽅法としては、以下のような⽅法があります。
表 7.6 データ抽出⽅式
抽出⽅式

形式

導⼊

説明

SPOOLコマンド

CSV

不要

SQL*Plusで実⾏した問合せの結果をファイルに格納する

ora2pg

テキスト(DML)

必要

psqlなどで実⾏できるDMLとして出⼒される

7.3.2.3. データ変換
データ変換では、移⾏元DBと移⾏先DBとの差異により、データ型や⽂字コードの変換や外字への対応などを⾏います。
また、アプリケーションの変更などがあった場合は、データクレンジング(データの整形)が必要となる場合があります。
主な変換に以下のようなものがあります。
表 7.7 データ変換
項⽬

内容

データ型

以下のようなものを適切な値に変換する。
・0バイト⽂字列のように、DBによって格納する値の意味が異なるもの
・同じデータ型でも格納可能な限界値に差異があるもの

⽂字コード

PostgreSQLへ投⼊するテキストファイルがPostgreSQLに対応していない場合や、
pg_bulkloadを⽤いてデータ投⼊を⾏う場合、⽂字エンコーディングの変換を⾏う必要がある。

外字

移⾏元DBで外字が使⽤されていた場合、その外字を移⾏先DBで使⽤できる⽂字に変換する。
もしくは、移⾏先DBで外字を使⽤できるようにシステムに登録する。
注意：外字が使⽤できるようにシステムに登録されており、かつ、クライアントエンコーディングとデータベースエンコーディングとが異なる場合、 ⾃動エンコーディング変換を利⽤するためには、外字のマッピングを定義し、マッピングを再登録する必要がある。

データクレンジン
グ

移⾏と同時にデータフォーマットが変わるようなアプリケーションの変更が発⽣している場合、変更にあわせたデータの変換を⾏う。

7.3.2.4. データ取込
主なデータ取込⽅法としては、以下のような⽅法があります。

Page 34 of 44

PostgreSQL Enterprise Consortium

表 7.8 データ取込⽅式
取込⽅式

データ形式

速度

導⼊

制限事項

SQL

テキスト(DML)

低

不要

なし

COPY

CSV

中

不要

なし

pg_bulkload

CSV

⾼

必要

クラッシュ時にリカバリが必要。レプリケーション構成は再取得や再作成が必要。

7.3.2.5. データ確認
データが正しく移⾏されたことを確認するために、以下のような作業を⾏います。
表 7.9 データ確認
項⽬

内容

データロード時のエラー等の確認

実⾏したコマンドのエラーメッセージの有無を確認する。
エラーが表⽰された場合は、その問題点を確認し、対処してから再度データをロードする。
pg_bulkloadではロールバックされないので、データロードを再実⾏する際は、⼀旦テーブルのTRUNCATEが必要。

移⾏対象オブジェクト数および各オブジェクトの⾏数の確認データロード後のPostgreSQLデータベースのオブジェクト数と各オブジェクトの⾏数
が、移⾏元データベースの状態と⼀致するかどうか確認する。

CSV出⼒の結果照合DBに登録されたデータをCSVファイルとして抽出し、データ取込において使⽤したCSVファイルと、
内容や⾏数が⼀致するかどうかを確認する。

アプリケーションテスト

実際にアプリケーションから接続して⼀連の処理を⾏い、想定通りの動きをするかどうか、⽂字化けが発⽣していないか等を確認する。

データ取り込み後には、その他に以下のような作業を⾏います。
制約・索引の作成
ユーザのシステム権限およびオブジェクト権限の確認
VACUUMとANALYZEの実⾏初期状態でのテーブルサイズの確認

Page 35 of 44

PostgreSQL Enterprise Consortium

8. 運⽤
8.1. 運⽤の概要
PostgreSQLも他のRDBMS同様に安定的なデータベースの運⽤のためにいくつかの運⽤上のタスクが必要になります。データベース移⾏時にもPostgreSQLの特性に合致した運⽤タスクの移⾏が必要であり、移⾏元DBと同様な処理であっても機能差やコマンドの仕様差により修正または新規に構築する必要があります。運⽤要件によって必要なタスクは変わりますが、以下は共通的に実施するものになります。
⽇常のタスクバックアップ
索引の保守
データベースのVACUUM
ログの管理
データベースの監視
パフォーマンス診断
不定期に発⽣するタスク
アップグレード

8.2. バックアップ
データベースのバックアップは主に以下の２つの⽬的で使⽤されます。
ディスク障害によるデータ破損や操作ミスによるデータロストなど不測の事態が発⽣した場合に復元可能とするためバージョンアップやシステムの変更の検証などのためにデータの移出・移⼊を⾏うため
Oracleとはバックアップの⽅式、⼿順が異なるため移⾏においてはこれらを要件毎に新規に実装します。
公式の「PostgreSQL⽂書」ではデータをバックアップする⼿法として”SQLによるダンプ”、”ファイルシステムレベルのバックアップ”、”継続的アーカイブ”と３つの⽅式が説明されています。本項ではそれぞれの⽅式の特徴を移⾏元のOracleとの⽐較も合わせて簡潔に説明します。
バックアップの⽅式
以下ではそれぞれの⽅式と対応するOracleツールを表にしたものです。
表 8.1 バックアップ⽅式の⼀覧
⽅式

DB停⽌

対応するOracleツール

⽅法

バックアップ対象

リカバリ範囲SQLによるダンプ

pg_dumpツール"データベースク
ラスタ，データ
ベース, スキーマ,
テーブル"

バックアップ取得時点

不要

DataPump

ファイルシステム
レベルのバックアップ

OSコマンドデータベースクラスタ

バックアップ取得時点

要－(OSコマンド)

継続的アーカイブ・ベースバックアップ（全体バックアップ）+アーカイ
ブWAL+未アーカイブWAL
・pg_rman

データベースクラスタ

ベースバックアップ〜最新
状態

不要・Begin BackupとEnd
Backup+OSコマンドバック
アップ+アーカイブログ
・RMAN(リカバリ・マネー
ジャー）

バックアップ要件と対応する⽅式
バックアップの要件と上記の⽅式と対応を表にしたものです。
表 8.2 バックアップ要件と対応⽅式
要件選択する⽅式

想定するユースケース

最新のトランザクションまたは任意の時点の状態まで復元

継続的アーカイブ

ディスク障害等不測の事態に対する対応

バックアップ時点に復元

全ての⽅式で可能

定期保守

異なるバージョンへの移⾏

ＳＱＬによるダンプ

移⾏

スキーマ単位、テーブル単位など部分的なバックアップアップと復元

ＳＱＬによるダンプ

システム変更などの検証

Page 36 of 44

PostgreSQL Enterprise Consortium

バックアップ⽅式毎の特徴
SQLによるダンプ
メリット：唯⼀、テーブルやスキーマ単位で取得可能なバックアップであること。OracleのDataPumpをイメージすると分かりやすいです。また、コマンドはシンプルで習得も容易です。
デメリット：バックアップ時点までしか戻せないことです。
ファイルシステムレベルのバックアップ
メリット：OSファイルコピーのため⾼速にバックアップ、リストアができること。
デメリット：DBを停⽌する必要があり、バックアップ単位もデータベースクラスタ全体のみになります。
データベースクラスタが⼩規模で単純な構成かつバックアップ時にはDBが停⽌できるなど、限定的なケースでのみ選択したほうがよいでしょう。
継続的アーカイブ:
メリット：未アーカイブのWALが確保できれば障害発⽣時点のトランザクションまで復元できる唯⼀のバックアップです。
デメリット：設計および⼿順が他より複雑であるため運⽤には⼗分な知識と訓練が必要になります。具体的には以下の全てが該当します。
運⽤の前提としてWALのアーカイブ設定が必要であること。
WALアーカイブ先の空き領域監視、アーカイブされたWALの整理が必要であること。
リストア時間はベースバックアップの復元およびWALの適⽤時間となり、適⽤するWALが多ければ多いほど時間がかかること。
バックアップ設計は想定されるリストア時間からベースバックアップの実⾏間隔を決定する必要があること。
バックアップ、リストアの⼿順が複雑であること。
ただし、pg_basebackupを使うことでバックアップ時の⼿順の簡略化は可能です。LinuxOSであればpg_rmanを導⼊すること
でバックアップ、リストアの⼿順の⼤幅な簡略化、さらに差分バックアップ、世代管理、圧縮バックアップが可能となりバックアップ設計の⾃由度も向上可能です。

8.3. 索引の保守
索引はデータベースのパフォーマンスに強く影響を与えるもののひとつです。PostgreSQLの索引はいくつかの種類があり、最もよく使われるのがB-tree索引です。本項でもB-tree索引の保守について取り上げます。
テーブルの特定の⾏にアクセスする場合、テーブル全体をアクセスするより、索引を⽤いて必要なブロックのみアクセスすることで少ないアクセスで⽬的の⾏を取得できます。
反⾯、テーブル本体以外にも索引をアクセスする必要があるため、索引が断⽚化していたりすると索引そのもののアクセスが多くなりパフォーマ
ンスを劣化させてしまいます。また、テーブルの更新が発⽣すると索引もあわせて更新されるため更新処理の負荷を増加させます。（HOT機能を利⽤することで軽減可能）
このため、運⽤での索引の保守は「不要な索引の検出と削除」、「断⽚化された索引の再構築」の対応が必要になります。
不要な索引の検出と削除
索引毎の使⽤状況は情報スキーマのpg_stat_XXX_indexes,pg_statio_XXX_indexes（XXXはuserまたはall)により、使⽤回数、読み込
みブロック数などを確認することができます。定期的に監視を⾏い⼀定期間、使⽤回数等の増加がない索引がある場合は削除を検討します。
断⽚化された索引の再構築
断⽚化の監視索引の断⽚化は追加モジュールのpgstattupleをインストールすることでpgstatindex関数が使⽤可能になります。この関数でtree_levelが深すぎないか、leaf_fragmentationが⼤きすぎないかなど再構築の必要性を確認します。ただし、索引の監視⾃体も運⽤コストの増加になります。監視を⾏わずに定期的な再構築を⾏うという選択肢もあります。
索引の再構築索引の再構築にはいくつかの⽅法があります。それぞれにメリット、デメリットがありますので運⽤要件に応じて選択します。

Page 37 of 44

PostgreSQL Enterprise Consortium

表 8.3 索引の再構築の⽅式
NO

⽅式

メリット

デメリット

1

reindex

コマンドが容易かつDB単位、スキーマ単位、テーブ
ル単位で実⾏可能

処理中にテーブルの書き込みロックと対象の索引を使⽤する読み込みにブロックがかかる

2

drop index+createindex

1の⽅式よりロック影響は少ない

create indexでテーブルに書き込みロックがかかる

3

create index
concurrentry+drop
index+alter index
rename

運⽤中のDBへのロックの影響が最も⼩さい⼿順が多い。concurrentryオプションはテーブルを２回スキャンするため時間がかかる

4

pg_repack3の⽅式を1コマンドで実施可能

周辺ツールのインストールが必要。実⾏時に途中で停⽌した場合はリカバリ操作が必要

索引の再構築の組み込み基準
索引の再構築を運⽤に組み込む場合、⼩規模なDBであればDB全体の索引を再構築しても短時間で完了するため業務停⽌時間にreindex
で実施してしまうことが運⽤コストを最も⼩さくできます。また、⼤規模なDBであれば再構築時間も⻑くかかることから運⽤の影響を⼩さくする配慮も必要となります。
以下に運⽤保守のバッチ処理内に索引再構築を組み込む基準例を⽰します。表中の”推奨する⽅式”は前表の”NO”を表します。

表 8.4 索引再構築の⽅式選択例
DBの規模

保守時間が確保できるか推奨する⽅式（NO)

性能要求

⼩

できる

―

1(DBまたはスキーマ単位）

⼩

できない

⾼い

3or4

⼩

できない

低い

再構築しない中できる―

1(スキーマ単位またはテーブル単位）

中

できない

⾼い

3or4

⼤

できるが全て再構築する時間はない―

1(テーブル単位）で曜⽇毎に対象テーブルを分ける

⼤

できない

―

3or4で曜⽇毎に対象テーブルを分ける

8.4. データベースのVACUUM
PostgreSQLのデータベースはデータの更新に追記型のアーキテクチャを採⽤しているため、物理的にデータ量は拡⼤し続けます。このため、更新や削除によって不要となった領域の整理を⾏う必要があり、そのためにVACUUM処理が⽤意されています。
VACUUM処理はパラメタを指定しなければ不要となった領域の回収のみを⾏い、パラメタにFULLを指定することで完全なVACUUMを⾏います。
VACUUM FULLは拡⼤したデータ領域を縮⼩することができますが、処理中に表への排他ロックがかかるなど制限もあります。
実⾏⽅法は下記表のように⾃動で実⾏する⽅法と⼿動で実⾏する⽅法があります。DBクラスタの作成ではパラメタファイルの初期状態で⾃動的に実⾏されるように調整されており、ほとんどのケースではそのままで充分です。
表 8.5 VACUUM処理の実⾏⽅法
実⾏⽅法

実⾏範囲

備考

⾃動VACUUM

VACUUM+ANALYZE

パラメタファイルで⾃動実⾏を指定する(デフォルトで⾃動実⾏)。
ANALYZEの閾値は別に指定可能

⼿動VACUUM

コマンドで指定したパラメタによるコマンドで実⾏

運⽤におけるVACUUM処理の調整
基本として⾃動VACUUMを使⽤し、運⽤上不都合がある場合に⼿動VACUUMを使⽤します。
VACUUM処理はPostgreSQLにとって負荷の⾼い処理のひとつです。例えば、⼤きな表で前回VACUUM処理から多くの⾏が更新・削除された場合での⾃動VACUUM処理が動作すると、優先すべき他の処理のパフォーマンスに悪影響を与える可能性があります。そのような状況を回避する必要がある場合は、以下のような調整を⾏う必要があります。
⾃動VACUUMの実⾏タイミングを調整
⾃動VACUUMの実⾏タイミングは、テーブル毎に更新・削除により発⽣した不要⾏がPage 38 of 44

PostgreSQL Enterprise Consortium

autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor * テーブル⾏数 > 不要⾏（dead_tuple数）を超えたときに実⾏されます。例えばautovacuum_vacuum_thresholdが0、autovacuum_vacuum_scale_factorが0.2であったとすると１億件の表は2000万件更新・削除されないと⾃動VACUUMされません。⼤量件数分のVACUUM処理の負荷が⾼い場合、これらのパラメタを調整することで１回当たりの⾃動VACUUMの負荷を下げて他の処理への影響を⼩さくすることが可能です。この調整はDBインスタンス全体で⾏うか、以下のようにテーブル単位で⾏うことも可能です。
例１ 全体の10%の不要⾏が発⽣したら⾃動VACUUMする
alter table 表名 set (autovacuum_vacuum_threshold = 0);alter table 表名 set (autovacuum_vacuum_scale_factor = 0.1);
例２ 1,000件の不要⾏が発⽣したら⾃動VACUUMする
alter table 表名 set (autovacuum_vacuum_threshold = 1000);
alter table 表名 set (autovacuum_vacuum_scale_factor = 0.0);
特定の表に⾃動VACUUMを停⽌し任意に⼿動VACUUMを⾏う
特定の表のみ⾃動VACUUMを停⽌することも可能です。その場合、表には以下のような変更を実施します。
alter table 表名 set (autovacuum_enabled = false);
⾃動VACUUMを停⽌するとその後の更新により、データ領域に再利⽤可能な領域がなければデータ領域は拡⼤し続けますので、保守時間や業務負荷の低い時間帯に⼿動でVACUUMを実⾏する必要があります。（ほとんどの場合、バッチ処理にVACUUMを組
み込み、スケジュール実⾏となります）
VACUUMとVACUUM FULLの使い分け
基本的にはVACUUMを使⽤します。VACUUM FULLを使⽤することはほとんどありません。しかし、次のようなケースが発⽣する場合は
VACUUM FULLを検討する価値があります。
表全体の更新が⾏われ、かつ全件検索が多発する表の場合
追記型のアーキテクチャであるために１つカラムが表の”全件”更新されるだけでも、表全体の領域の使⽤率は５０％以下になります（再利⽤されない不要領域があると割合はさらに低下する）。この表の検索パターンが多く全件検索が多発する場合、表全体の領域をアクセスするために最良の状態に⽐較し、2倍以上の読み込みが発⽣することになります。この過剰な読み込みがもた
らす性能劣化を許容できない場合はVACUUM FULLを検討します。
業務アプリケーションのメンテナンス時
通常運⽤によるデータ更新と異なり、通常は発⽣しない表の全件更新を伴うケースもあります。この場合も表全体の領域の使⽤率を必要以上に悪化させる場合は、メンテナンスにVACUUM FULLを⾏う⼿順を組み込んでおきます。

図 8.1 表全体の更新とVACUUM（FULL）のイメージ
なお、表の領域の使⽤率は、pgstattupleのtuple_percentで確認できます。
まとめ
VACUUM処理の運⽤は以下の表のように調整します。

Page 39 of 44

PostgreSQL Enterprise Consortium

表 8.6 VACUUMの使い分け
⼤規模テーブルの有無

全件更新

VACUUM処理

性能要求

なし

なし

⾼い

⾃動VACUUM(調整)

なし

あり

⾼い

⾃動VACUUM(調整)+VACUUM FULLを検討

あり

なし

⾼い

⾃動VACUUM(調整)+テーブル毎の調整 or ⼿動VACUUM

あり

あり

⾼い

⾃動VACUUM(調整)+テーブル毎の調整 or ⼿動VACUUM+VACUUM
FULLを検討

上記以外

←

←

⾃動VACUUM(デフォルト)

8.5. ログの管理
本項でのログは、データベースの運⽤に伴い発⽣する情報やエラー等を含む情報を記録するサーバログになります。ログの出⼒設定を適切に⾏うことで以下のようなメリットがあります。
障害の発⽣を検知できる
性能問題の発⽣原因となる情報を取得することができる
ただし、詳細に出⼒すると運⽤によっては１⽇で数⼗キガバイト以上の量を出⼒する可能性もあります。ここでは⼀般的な業務システムのログの出⼒設定例を⽰します。
ログファイルの出⼒先等
ログファイルの出⼒指定になります。出⼒先はsyslogも指定できますが、syslogを出⼒するjounald,rsyslogプロセスのデフォルトで記録制限をかけているため短時間での⼤量ログは破棄される恐れがあることから、以下ではstderrとしています。
表 8.7 ログファイルの出⼒先指定
パラメタ名

設定例

備考

log_destinationstderr

標準エラーを指定

logging_collectorononを指定しログ収集を有効にする。offにするとログは出⼒されない

log_directory/var/log/postgresなど

絶対パスで指定しない場合はデータベースディレクトリ以下に相対パスとして作成される

log_filename

postgresql-%Y%m%d.log

ログのファイル名。⽇付毎の出⼒が運⽤しやすい

log_rotation_age

1d

1⽇でログを切替え

log_rotation_size0

ログファイルの最⼤サイズ。0はサイズ指定無効

ログファイルに出⼒する情報
業務システムの特性を考慮し設定値を調整する必要があります。性能要件が⾼い場合、性能欄が"○"の情報は出⼒を推奨します。

Page 40 of 44

PostgreSQL Enterprise Consortium

表 8.8 ログファイル出⼒情報
パラメタ名

設定例

性能

備考

log_min_error_statement

ERROR

－

エラー条件の原因となったSQL⽂を記録するか制御する。ERRORがデフォル
トlog_min_duration_statement3s(値は例)○

指定した時間以上に時間のかかった処理を記録する。問題のある処理の特定に役⽴つ。0を指定すると全ての⽂を出⼒（⼤量に出⼒されるのでログの肥⼤化に注意が必要）log_checkpointson○checkpoint starting: xlogが頻発する場合はWAL関連のパラメタを⾒直す

log_connections

on○

onでクライアント認証の記録の残す。⼤量の接続が発⽣する場合、ログの肥⼤化に注意が必要

log_line_prefix%t %u[%p:%l]－

各ログ⾏の先頭に出⼒する。%tの時刻と%pのプロセス番号は必須

log_lock_wait

on○

ロック待ちが発⽣しているか確認できる。あわせてdeadlock_timeoutを指定
する

deadlock_timeout

3s(値は例)○

デッドロック検査前の待ち時間。ロック待ちログメッセージの待機時間にも使われる

log_temp_files

10MB(値は例)○

最初は0として⼀時ファイルを使ったら全て出⼒させてwork_memのサイズを調整する⽬安にする。調整後は例のような⼀定サイズに変更する。運⽤中は⼤量の⼀時ファイルを使うSQL(=遅い）を特定できる

log_autovacuum_min_duration

3s(値は例)○

実⾏頻度、時間帯、実⾏時間を確認し、autovacuumの実⾏を調整する⽬安にする。調整しても性能要件を満たせない場合は⼿動VACUUMを検討

ログファイルの整理
ログファイル名を曜⽇としての出⼒するなど、設定の⽅法によってはPostgreSQL⾃⾝で周期的に古いログファイルを上書きしてログ
ファイルの増加を防ぐことができます。上記の”ログファイルの出⼒先指定”のように⽇付でログファイル名を指定した場合は、定期的に保存期間を超えたログファイルを削除するバッチ処理を組み込む必要があります。

8.6. データベースの監視
データベースの運⽤中に発⽣した問題に迅速に解決するため、または今後の問題発⽣の防⽌のため、リアルタイムおよび定期的にデータベースの監視を⾏います。
リアルタイムな監視
データベースの異常に対する即時対応のために実施します。
定期監視
データベースのピーク接続数やディスク所要量などの変化を経年的に監視することで将来的に不⾜するかなどの⽬安にします。
監視も運⽤コストの増加になりますので運⽤するシステムの重要性に応じて、どこまで実施するか検討します。以下に代表的な監視項⽬を列挙し
ます。
ログの監視
ログの監視は「8.5.ログの管理」により出⼒されたログを対象に監視するものとします。
ログ内のERROR,FATAL,PANIC（syslogではWARNING,ERR,CRIT、イベントログではERROR）の発⽣を監視し、データベースに異常が発⽣している場合、発⽣原因に応じて対策を実施します。
ディスクの空き領域監視
運⽤においてデータ量の拡⼤等によってディスク領域を不⾜させてしまうことがあります。発⽣時はデータベースの停⽌（＝業務停⽌）を伴う可能性が⾼いため、不⾜が発⽣しないように監視を⾏います。
データ格納先ディレクトリ、表領域格納先ディレクトリ
⻑期間のデータベース利⽤でデータ増加に伴い不⾜する可能性があります。不⾜する場合、不要なテーブルの削除、新規の表領
域格納先ディレクトリを⽤意して移動、索引の再構築、VACUUM FULLなど対応が必要です。
トランザクションログ格納先ディレクトリ
通常は⼀定量以上は拡⼤しませんが、アーカイブログ運⽤時にアーカイブ出来ない状況やレプリケーション運⽤でレプリケー
ション出来ない状態が発⽣するとトランザクションログは増え続けます。原因を取り除き領域を開放する必要があります。
アーカイブログ格納先ディレクトリ（アーカイブログ運⽤時）
アーカイブログは何もしなければ増え続けます。アーカイブログの格納領域が不⾜すると書き出せないトランザクションログがトランザクション格納領域に残るため、この領域の増加が発⽣します。通常、バックアップ計画に伴い、不要なアーカイブログを削除するようにします。緊急時はOSコマンドでアーカイブログを別の領域に移動するなどして空き領域を確保します。また、Page 41 of 44

PostgreSQL Enterprise Consortium

pg_rmanなどの利⽤で⾃動で整理することもできます。
接続数の監視利⽤者数の拡⼤や業務アプリケーションの追加、システム運⽤上の特性などにより接続数が増減する可能性があります。監視は統計情報
ビューの"pg_stat_activity"の件数をカウントして⾏います。なお、0件も異常です。少なくともバックグラウンドプロセスの接続があるためです。監視は⼀定の閾値（max_connectionsの90%など）を超えた時点でアラートを出⼒するようにします。アラートが出⼒される場合はmax_connectionsの増加とあわせ、リソースが不⾜する場合はリソース強化等の対応を⾏います。
プロセス監視接続数の監視を実施する場合は、データベースへのアクセス（統計情報ビュー）の応答が⾏われていることからプロセスの監視は不要です（新規の接続が可能なことも合わせて確認できます）。接続数の監視を実施しない場合、postgresのマスタープロセスが起動していることをOSコマンドで監視します。postgresの⼦プロセス（loggerやcheckpointerなど複数存在）の監視は不要です。⼦プロセスが起動できない場合はマスタープロセスも異常終了するためです。
上記の他にもシステム要件によっては監査ログ相当のログ（誰が、どこから、いつ、どのデータを取得したか）が必要な場合もあります。この場
合はpgauditとログ分析⽤ツールの導⼊も検討します。
まとめ
以下にデータベース監視について表にまとめます。リアルタイム監視、定期監視の"○"がついている部分が監視が必要な項⽬になります。
表 8.9 データベースの監視
監視項⽬

リアルタイム監視

定期監視

定期監視での分析観点

ログの監視

○

－

－

ディスクの空き領域監視○○

空き領域の減少具合から、いつ不⾜するか予測

接続数の監視○○接続数の変動を経年変化で観測しパラメタ変更、チューニング、リソース増強などの対策要否の検討

プロセス監視○－－アクセス監査（必要に応じて）－○

不正アクセスが発⽣していないか。pgauditを導⼊

8.7. パフォーマンス診断
データベースのパフォーマンスが正常かそうでないかを判断するには、ある⼀時点での評価ではなく「正常な状態」と「遅くなっている状態」の⽐較をすることで分析します。このため、パフォーマンス診断は継続的な診断情報の取得と定期的な分析が必要になります。また、定期的な診断を⾏うことで、将来発⽣しうる性能問題を事前に対策することも可能となります。
Oracleから移⾏する場合、以下の場合は移⾏先のPostgreSQLでもパフォーマンス診断を⾏う必要があります。
Oracleのエディションがエンタープライズ・エディションでかつ、オプション製品のDiagnostics Packがある場合
StatsPackがインストールされ、かつスナップショットの記録が⾏われている場合
Oracleの場合、上記で取得される情報よりそれぞれAWRレポート、StatsPackレポートを出⼒し⽐較・分析をします。PostgreSQLの場合は周辺ツールの利⽤も検討し同様な分析ができるようにします。
PostgreSQLでのデータベース診断
以下にデータベースの診断と対応する周辺ツールを表にします。

Page 42 of 44

PostgreSQL Enterprise Consortium

表 8.10 データベースの診断と周辺ツール
周辺ツール等

対応OS

診断情報

分析単位

分析⽅法

備考

pg_statsinfo

linux

リポジトリDB

任意の期間

テキスト形式の性能レ
ポート、HTML形式の性能レポート（別途
pg_stats_reporterが必
要）

専⽤のログ設定が必要

pgBadger

linux

ログファイル

ログ全体、
⽇単位、週
単位のサマ
リ

HTML形式の性能レポート

専⽤のログ設定が必要。運⽤
によっては数⼗GB/⽇のログが出⼒される

pg_stat_statement_reset データベー
実⾏後からのSQLの実⾏統 ス単位計を累積

pg_stat_statements
ビューの参照。例）クエ
リ実⾏時間,実⾏回数のトップ10調査などSQLで取得

データベースにエクステン
ションの追加とパラメ
タ:shared_preload_librariesにpg_stat_statemntを追加

情報スキーマや上記の
pg_stat_statementsなどの情報を⼀定間隔でテーブル等に蓄積蓄積されたテーブルの任意の期間の差分で分析するクエリを⾃作

仕組みを⾃作する必要がある

pg_stat_statements linuxとWindows

情報スキーマの情報から分析の仕組みを⾃作

linuxとWindows

任意の期間実装にあたってはPostgreSQLの提供する情報だけでなく、OSで取得できる情報はOSで定期取得、アプリケーションで独⾃に出⼒するアプリロ
グも存在すれば合わせて取得します。また、ベンダーが提供する有償版のPostgreSQLの場合は専⽤の診断ツールが提供される場合もあります。
これらのツールを含めより正確に現状と過去からの変化を把握し安定的に運⽤できるように診断を⾏います。

8.8. アップグレード
PostgreSQLのアップグレードはメジャーバージョンのアップグレードとマイナーバージョンのアップグレードがあります。（バージョンについては4.3.バージョンを参照）
メジャーバージョンのアップグレードでは機能追加、マイナーバージョンのアップグレードでは不具合やセキュリティホールへの対応が含まれます。運⽤としてのアップグレードはマイナーバージョンアップを対象とし、より新しいマイナーバージョンがリリースされている場合は適⽤を推奨します。
マイナーバージョンアップグレード
DBクラスタの内部格納形式はマイナーバージョン間で変更されることはありません。そのため、アップグレードに伴うバックアップ・リ
ストアは必要ではありません（バックアップは作業ミス等への対応として実施することには意味があります）。アップグレード⽅法の基
本は以下のようになります。
データベースクラスタの停⽌
実⾏ファイルの置き換え
データベースクラスタの起動
メジャーバージョンアップグレード
DBクラスタの内部格納形式やパラメータ、PostgreSQLの動作も異なります。移⾏するメジャーバージョン間で作業が異なりますが、共通作業として新機能の適⽤検討や動作確認、バージョン間の⾮互換対応を実施する必要があります。運⽤の作業ではなくバージョンアッ
プ移⾏という観点で捉える必要があります。

Page 43 of 44

PostgreSQL Enterprise Consortium

9. 著者（企業・団体名順）
版

所属企業・団体名

部署名

⽒名

⽇本電気株式会社

AIプラットフォーム事業部

⿊澤 彰

⽇本電⼦計算株式会社

技術本部

⽑塚 賢⼀

⽇本電⼦計算株式会社

技術本部

⾼橋 泰之

富⼠通株式会社

ミドルウェア事業本部

陶⼭ ⾹織

富⼠通株式会社

ミドルウェア事業本部

豊島 良美

富⼠通エフ・アイ・ピー株式会社

ソリューションサービス推進本部

多⽥明弘

三菱電機株式会社

情報技術総合研究所

⽥中

覚

第1.1版

富⼠通株式会社

ミドルウェア事業本部

豊島 良美

第1.2版
(2019年度WG2)

⽇本電⼦計算株式会社

技術本部

⽑塚 賢⼀

⽇本電⼦計算株式会社

技術本部

⾼橋 泰之

第1.0版
(2018年度WG2)Page 44 of 44