こんにちは。utsugiです。今回は、オンプレミスのOracleのデータを、SQL∗Loaderを利用してRDS for Oracleに移行する方法について考えていきたいと思います。
基盤担当者が直接使用することは少ない(?)かもしれませんが、ファイル連携後にロードジョブを実行する等のパターンでお馴染みのユーティリティです。
目次
∗ SQL∗Loaderについて ∗ OracleからRDSへのSQL∗Loaderを利用したデータ移行の流れ ∗ SQL∗Loaderを利用した移行のメリット ∗ ∗ データを柔軟に変更できる ∗ ∗ オンプレミス環境の設定を変更する必要がない ∗ ∗ オンプレミス環境と直接繋ぐ必要がない ∗ SQL∗Loaderを利用した移行のデメリット ∗ ∗ データ抽出に手間がかかる ∗ ∗ 制御ファイルの作成に手間がかかる ∗ ∗ ダウンタイムが長くなる ∗ まとめ
SQL∗Loaderについて
既にご存知の方も多いでしょうが、SQL∗LoaderはOracle純正のデータロード用ユーティリティです。主としてバッチ処理や、少数テーブルのデータ移行等で実行されることが多いユーティリティかもしれません。
【SQL∗Loaderの特徴】 ・基本的(※1)にデータロード用の制御ファイルを作成する必要がある ・クライアント側(SQL∗Loaderの実行環境)のデータをロードする ・移行元/先のオンプレミス/クラウド環境の組み合わせに制限はない ・異種間のデータベースの移行に対応していない(※2) ・対象データの一括移行に対応している ・更新差分のレプリケーションには対応していない ・定義情報の移行に対応していない ※1: 12cからはエクスプレス・モードというものに対応しており、制御ファイルを利用しなくても大丈夫なケースも出てきました。 ※2: ロード対象はテキストデータなので、別製品のロードツールを利用することにより、異種間のデータ移行は可能です。
SQL∗Loaderは更新差分のレプリケーションには対応していないため、基本的に、データ更新を停止してデータの抽出とロードを行う必要があります。
また、エクスプレス・モードというものを利用する場合を除き、「どのようにデータをロードするか」ということを定義した制御ファイルを1つのロードにつき1つ作成する必要があります。
このように、どうしても、手間が増えたり、ダウンタイムが長くなったりしてしまいますが、抽出データの変更や、ロード方法の細やかな定義に対応しています。
OracleからRDSへのSQL∗Loaderを利用したデータ移行の流れ
それでは、おおよその流れについて見ていきます。テーブルは既に存在する想定です。SQL∗Loaderの場合、ロードに利用するデータはクライアント側に存在すれば良いため、データ移行には、EC2経由とRDS直接の2パターンが存在します。要件や次第で選択可能です。
図: SQL∗Loaderを利用してデータを移行する(EC2経由)
図:SQL∗Loaderを利用してデータを移行する(RDS直接)
※以下はEC2経由での説明になりますが、RDS直接でも、同じ項目名のものは同じことを実施しています。
①更新停止 SQL∗Loaderはレプリケーション機能を持っていないため、データ移行中にデータ変更が発生しないよう、移行作業開始前に更新を停止します。
②アンロード SPOOLや標準出力のリダイレクト、あるいは、アンロードツール等を利用して、データファイルを作成します。ロード用のデータを作成する際には、csvファイルにすることが多いように思われます。
・SPOOLを利用してcsv形式のデータファイルを作成するSQLの例
WHENEVER SQLERROR EXIT FAILURE WHENEVER OSERROR EXIT FAILURE SET TERMOUT OFF SET ECHO OFF SET PAGESIZE 0 SET LINESIZE 32767 SET TRIMSPOOL ON SET HEADING OFF SET FEEDBACK OFF SET ARRAYSIZE 100 SPOOL /tmp/data.csv SELECT col1 || ',' || col2 || ',' || col3 || ',' || col4 || ',' || col5 FROM schema.table ; SPOOL OFF EXIT
③データファイル取得
④データファイル送信 ②で作成したデータファイルを、中継用の端末を経由してEC2に持っていきます。また、Tsunami UDP Protocolを利用することで、転送速度の向上を期待することもできます。
⑤制御ファイル作成 どのようにデータをロードするかを定義する制御ファイルを作成します。詳細はSQL∗Loader制御ファイル・リファレンスをご参照いただければと存じますが、まっさらな状態へのデータの移行ケースで設定しておいた方が良いと個人的に思ったオプションを記載致します。 ロード時間を短縮するため、ダイレクト・パス・ロードを利用しています。ダイレクト・パス・ロードを利用すると、一般的にロード時間は短縮されます。 利用可能であれば、PARALLELオプションを指定するのも良いかもしれません。
OPTIONS ( DIRECT = TRUE EMPTY_LOBS_ARE_NULL = TRUE ERRORS = 0 LOAD = -1 MULTITHREADING = TRUE SKIP = 0 SKIP_INDEX_MAINTENANCE = TRUE )
⑥SQL∗Loader SQL∗Loaderを利用してデータをロードします。PARALLELオプションを指定している場合、バックグラウンドで並列処理させることで、ロード時間の短縮が見込まれます。 ・sqllderのコマンド例
sqlldr userid=<接続ユーザ>/<接続パスワード>@<接続識別子> control=<制御ファイル> data=<ロード対象データ> log=<出力ログファイル> bad=<ロード失敗データ格納ファイル> discard=<ロードも失敗もされなかったデータ格納ファイル>
⑦index再構築 ロード時間短縮のため「SKIP_INDEX_MAINTENANCE」を有効化していたため、インデックスの再構築を行い、メンテナンスを実施します。 ・index再構築のコマンド例
ALTER INDEX schema.index REBUILD ;
⑧整合性確認 ロードが正常に終了した時点で、対象テーブルのデータは移行元と移行先で同期がとれた状態になりますが、欠落やロジックエラー等が発生していないか、データの整合性を確認します。
⑨更新再開 データの整合性まで確認出来たら、アプリケーションの更新先を移行先に変更します。
SQL∗Loaderを利用した移行のメリット
データを柔軟に変更できる
一度、データをテキストとして抽出するので、データを手動で変更して移行することもできます。タイムスタンプの値、フラグ列の値等、容易に修正して移行することができます。 例えば、移行を機にデータに対して特定の変換処理を行うような場合、変換はロード後にSQLを実施して行うのではなく、ロード前にテキスト編集で行えるようになるため、非常に容易になります。
オンプレミス環境の設定を変更する必要がない
Oracle純正のユーティリティであり、特別な設定等を行わずとも、ツール自体を利用することができます。 現行システムの動作に対する影響を最小限にしたいと考えた際、これは大きなメリットになるものと思われます。
オンプレミス環境と直接繋ぐ必要がない
原則として、オンプレミス環境と直接繋いで作業を行う必要はありません。データを抽出し、そのデータをクライアント側からサーバ側にロードするという流れになるためです。 ただし、直接繋いでデータのロードを行うことは可能です。その場合、中間端末的なものを利用して、クラウド環境側にデータを転送する必要はなくなります。
SQL∗Loaderを利用した移行のデメリット
データ抽出に手間がかかる
SQL∗Loaderを利用するには、まずはロード対象のデータを用意する必要があります。原則として、1テーブルにつき、1つ、または複数のデータです。 特別なアンロードツールは使わず、SPOOLやリダイレクトを用いてデータを用意する場合、この抽出だけでも多くの時間と手間がかかってしまいます。
制御ファイルの作成に手間がかかる
SQL∗Loaderを利用するには、エクスプレスモードを除いて、データのロード方法を定義した制御ファイルというものが必要になります。1つのロードにつき、1つの制御ファイルが必要です。 移行するテーブルの量が少なければそこまで手間にはなりませんが、数十~数百ものテーブルを移行するとなると、それだけでも非常に手間になってしまいます。
ダウンタイムが長くなる
基本的に、完全に移行元と移行先のデータを同期させる場合(通常の移行ケース)、移行開始から移行終了までの間、システムは利用できない状態になります。 また、ダウンタイムは移行データ量に比例して長くなるため、最小限のダウンタイムを求める移行には向きません。
まとめ
今回は、少し例を挙げつつSQL∗Loaderでのデータ移行について見てきました。
データの抽出だけでなく制御ファイルの作成まで含めると非常に手間がかかりますが、柔軟性を重視したり、移行テーブル数が少なかったりした場合には、有力候補となり得るのではないでしょうか。