本記事は、Brian Spendolini による “Easy Oracle Database Migration with SQLcl” を翻訳したものです。
2022年 1月 15日
データベース移行は楽しくなく、簡単な作業でもありません。大抵はこのプロセスに慣れていない開発者にとって、データベースを扱う上で大きなハードルとなるものです。ぼんやりとしたタスクに変わり、暗雲が立ち込めるかのように開発者を脅かします。やらなければいけないことですが、前向きには取り組めません。
Oracle Databaseの移行に役立つツールは数多くありますが、移行を単純な1つのコマンドへと落とし込めないものでしょうか。そして、その伝説のツールで、そこらにあるエクスポート・ファイルを他の魔法の国、たとえばクラウドに移行できるとすれば。このような容易なデータベース移行という恐ろしい幻影を一網打尽にできるようなツールは存在するのでしょうか。
それができるのがSQLclです(もうこの記事のタイトルからお分かりだったと思いますが)。私たち開発ツール・チームは2021年12月のSQLcl 21.4リリースの際に、この冒険の役に立つData Pump機能を追加しました。
気軽に移行を
一般的な移行シナリオを想像してみましょう。たとえば、何らかの理由でローカル・データベースをあるサーバーから別のサーバーへと移行する必要があるなら、Data Pumpを利用してみてはいかがでしょうか。もっと良い点を挙げると、SQLclのData Pumpを使用して運用中のデータベースに接続し、単純なコマンド2つだけでこのタスクを実行してみてはいかがでしょうか。
SQLclプロンプトでは、dpコマンドでData Pumpを呼び出すことができます。
データベースへの接続には、以下のようにconnコマンドとJDBC接続文字列を使用します。
conn dpdemo@cooldemo:1521/demodatabase.demos.oraclevcn.com
このように、データベース内に接続し、コマンドを実行し、その後すぐに別のデータベースに接続して他のコマンドを実行できるのです。
まずは単純なローカル・エクスポートを実行してみましょう。コマンドは以下のようになります。
SQL> dp export -dumpfile db_dumpfile.dmp
これだけで、現在ログイン中のスキーマがエクスポートされます。
また、単純なローカル・インポートを実行する場合も、
SQL> dp import -dumpfile db_dumpfile.dmp
これだけで実行できます。私たちがSQLclにData Pump機能を導入した目的は、コマンドを簡単に、直接ワークフローに統合できるようにすることでした。また、SQLclはバッチ・プログラムの実行にも適しており、この新しいData Pump機能によって多くの可能性が開かれています。
さあ、クラウドへ!
基本についてはさておき、あるシナリオを設定しましょう。ローカルのデータセンターからOracle Cloudへとデータベースを移行する作業を担当しているとします。最終的な目標はVM DBでもAutonomous Databaseでも、あるいはExadata Cloud Serviceでもかまいません。今はただ、移行を無事完了させる必要があります。
ここからはこのシナリオに沿って進めていきますが、この記事の最後に、同じ操作を実行するための環境準備に使用できるセットアップ手順を紹介しています。
エクスポート
SQLclを使用するにあたり、まずは/nologオプション付きで実行します。
sql /nolog
これにより、SQLcl がデータベースへのロギング機能なしで起動します。

次に、JDBC接続文字列を使用してデータベースに接続します。JDBC接続文字列の形式は以下のようになります。
username@host_name:port/sid_or_service_name_of_the_database

例での値は次の通りです。
- usernameはdpdemo
- データベースが稼働するホストのhostnameはcooldemo
- ポート番号は1521
- データベースのサービス名はcooldatabase.publicsubnet.demos.oraclevcn.com
これらの情報をまとめてSQLclから接続する場合のコマンドは、以下のようになります。
conn dpdemo@cooldemo:1521/cooldatabase.publicsubnet.demos.oraclevcn.com
次に、dpdemoユーザーのパスワードの入力が求められます。入力すると、データベースに接続します。接続文字列に精通している方は、そこにパスワードを含めることができるのもご存じでしょう。しかし、セキュリティやプライバシーの理由から、それは必ずしも賢明とは言えません。
データベースに接続できましたので、次にエクスポートを実行できます。ただし、ここではエクスポート先として直接OCI Object Storeを指定したいと思います。まず、使用するOCIプロファイルをSQLclで指定します。OCI設定ファイルのDEFAULTプロファイルを使用するようにするため、以下のコマンドを実行します。
SQL> oci profile DEFAULT
以下のように出力されます。
Region set to: eu-frankfurt-1
OCI Profile set to DEFAULT
Transfer method set to oci
次に、エクスポート先として使用するObject StoreバケットをSQLclで指定します。このコマンドの構文は以下のとおりです。
ここで使用するバケットの名前はdatapumpDemo、OCIテナンシーはcooltenancyであるため、コマンドは以下のようになります。
SQL> cs https://swiftobjectstorage.eu-frankfurt-1.oraclecloud.com/v1/cooltenancy/datapumpDemo/
以下のように出力されます。
DBMS_CLOUD Credential: Not Set
OCI Profile: DEFAULT
Transfer Method: oci
URI as specified: https://swiftobjectstorage.eu-frankfurt-1.oraclecloud.com/v1/cooltenancy/datapumpDemo/

これでData Pumpエクスポートを作成して、それを自動的にクラウドに保存できるようになりました。エクスポートのコマンドは以下のようになります。
SQL> dp export -copycloud -dumpfile dpdemo.dmp
この結果、以下のように出力されます。
** Datapump Command Start ** at 2022.01.12-12.55.22
Initiating DATA PUMP
DATABASE TIME ZONE: VERSION:32 CON_ID:0
Log Location: DATA_PUMP_DIR:ESQL_1738.LOG
Starting "DPDEMO"."ESQL_1738":
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
…
DataPump Operation Status 'COMPLETED'
Jobname = ESQL_1738
File DATA_PUMP_DIR/dpdemo.dmp copied to https://swiftobjectstorage.eu-frankfurt-1.oraclecloud.com/v1/cooltenancy/datapumpDemo/dpdemo.dmp
** Datapump Command End ** at 2022.01.12-12.57.21
-copycloudフラグは、エクスポート・ファイルをデータベースからクライアントへストリーミングした後、先ほど指定したバケットを使用して、そのファイルをすぐにObject Storeに保存するよう指定するものです。
この処理の速さはユーザーによって異なります。OCIへの接続が極めて堅牢であり、エクスポートが適度のサイズである(数GB)場合は、このプロセスは急速に実行されます。ここではネットワーク関連でいくつかの変数が関係するため、実行速度をよく確認して、その期待値に合ったサイズを正しく設定するようにしてください。
OCI Webコンソールで、datapumpDemoバケットの内容を表示すると、このエクスポートがあることを確認できます。

簡単でしたね。では次に、ファイルをクラウド・データベース内にインポートしてみましょう。
インポート
インポートについては、いくつかの処理方法があります。OCIの場所やプロファイルをすべて設定したまま、SQLclセッションを継続してクラウド・データベースにログインする方法もあれば、新しいセッションを開始して再度OCI変数を設定する方法もあります。この例では、設定内容や使用したコマンドを思い出しながら、同じSQLclセッションを継続して使用することにします。
エクスポートで最初のSQLclセッションを開始したときに使用した前提条件は以下のとおりです。
# OCI プロファイルの設定
SQL> oci profile DEFAULT
および
# 使用する OCI Object Store bucket の場所の設定
SQL> cs https://swiftobjectstorage.eu-frankfurt-1.oraclecloud.com/v1/cooltenancy/datapumpDemo/
接続先となるクラウド・データベースはmTLSを有効にしたAlways Free Autonomous Databaseです。このデータベースに接続するクライアントは、信頼できるクライアントCA証明書を使用する必要があります。
この証明書をSQLclセッションで使用するには、set cloudconfigでウォレットの場所を指定します。
SQL> set cloudconfig /Users/bspendol/Keys/Wallet_dpdemo.zip

Autonomous Database用にcloudconfigを一度設定すれば、サービス名、管理ユーザー、highのコンシューマ・グループを指定して接続できます。
SQL> conn admin@dpdemo_high
管理ユーザーのパスワードを入力すると、データベースに接続した状態になります。

エクスポートの場合と同様に、インポートも即座に実行できます。今は管理ユーザーとしてAutonomous Databaseにログイン中であるため、このインポートを実行できます。そうすると、スキーマとオブジェクトが自動的に作成されます。
OCI Object StoreからのData Pumpエクスポートをインポートするには、以下のコマンドを使用します。-rt(remap tablespace:表領域の再マッピング)フラグを渡しているのは、このスキーマでは元のデータベースでUSERS表領域が使用されていましたが、Autonomous DatabaseではDATA表領域が使用されるからです。表領域の再マッピング・オプションによって、この変換を自動的に実行するようData Pumpインポート・ジョブに指定しています。
SQL> dp import -copycloud -dumpuri dpdemo.dmp -rt USERS=DATA
以下のように出力されます。
** Datapump Command Start ** at 2022.01.12-13.36.18
File https://swiftobjectstorage.eu-frankfurt-1.oraclecloud.com/v1/adexacs2/datapumpDemo/dpdemo.dmp copied to DATA_PUMP_DIR/ISQL_454.DMP
Initiating DATA PUMP
…
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type SCHEMA_EXPORT/STATISTICS/MARKER
DataPump Operation Status 'COMPLETED'
Jobname = ISQL_454
** Datapump Command End ** at 2022.01.12-13.40.50
これで、わずか数ステップの簡単な操作だけで、オンプレミスのローカル・データセンターからOracle Cloud Databaseへとデータベースを移行できました。
他にもある、Data Pump でできること
CICD
簡単なデータベース移行も1つのユースケースとなりますが、SQLclのData Pumpでは他に何ができるでしょうか。SQLclはほぼどこにいても簡単にインストールできるため、CICDパイプラインに組み込むというユースケースが考えられます。データベース開発者がコードをコミットする、あるいはpullリクエストを送信するときに実行されるパイプラインについて考えてみましょう。ビルド・スクリプト内で、SQLclをダウンロードしてData Pumpエクスポートをインポートするために使用し、データベースを本番環境のレベルに近づけることで、現実に即した環境をCICDテストに反映させることができます。
筆者がOCI DevOpsとビルド・ランナーを使用するとすれば、build_spec.ymlファイルに以下のような設定を追加することになります。
- type: Command
name: "terraform work"
command: |
wget https://download.oracle.com/otn_software/java/sqldeveloper/sqlcl-latest.zip
unzip sqlcl-latest.zip
この上で、Terraformスクリプト内でSQLclを使用してテスト・データベースにログインし、Data Pumpエクスポートをインポートして、開発者が直前にコミットしたコードを適用します。
<div contenteditable="false" data-code="resource "null_resource" "sqlcl-liquibase" { provisioner "local-exec" { command = <resource "null_resource" "sqlcl-liquibase" {
provisioner "local-exec" {
command = <<-EOT
./sqlcl/bin/sql -cloudconfig wallet.zip admin/${random_string.password.result}@TESTDB_high @lb.sql
EOT
}















