Amazon Web Services ブログ

S3_INTEGRATION を使用して Amazon RDS for Oracle を Amazon S3 と統合する

Amazon RDS for Oracle では、マネージドサービスソリューションのあらゆる利点を活用できます。リフトアンドシフトアプローチを使用してレガシー Oracle データベースを Amazon RDS for Oracle に移行すると、既存のアプリケーションコンポーネントをリファクタリングしたり変更したりする必要性を減らすことができます。

データウェアハウス (DW) 抽出は、ほとんどのデータベースにおいて不可欠な部分です。データベースのホストと社内データベース用 DW サーバーとの間で、ネットワークファイルシステム (NFS、Network File System) などの共有ファイルシステムに抽出ファイルを保持するのが一般的な方法です。

DW ロード用の共有ファイルシステムを使用してオンプレミスの Oracle から Amazon RDS for Oracle への移行を行う際には、既存の共有転送メカニズムがスムーズに移行できるかという点に特に注意する必要があります。そのことを念頭に置いて、AWS は 2019 年 2 月に、Amazon S3 統合により Amazon RDS for Oracle を強化しました。このオプションにより、Amazon RDS for Oracle Database を Amazon Simple Storage Service (Amazon S3) にシームレスに統合することができます。

この記事では、アプリケーションホストとAmazon RDS for Oracle ホスト間の共有ファイルシステムの代替となる Amazon S3 統合について説明します。また、代替ソリューションとして外部テーブルを使用して Amazon S3 に保存されたデータにアクセスする方法についても説明します。この記事では、オンプレミスデータベースのソース Oracle の代わりに Amazon EC2 インスタンスで実行されている Oracle データベースを使用します。

前提条件

Amazon RDS for Oracle に、データベースを格納できるスペースと、Amazon S3 からのファイルのアップロードやダウンロードができるスペースを確保してください。

この記事では、RDS インスタンスから IAM ロール経由でアクセスできる Amazon S3 バケットを使用します。

共有ファイルシステムの代替としての Amazon S3 統合

Oracle データベースアプリケーションの多くは、フラットファイルを使用してデータベースにデータをロードします。これらのファイルは通常、アプリケーションと Oracle データベースサーバーの両方にマウントされている共有ファイルシステムボリュームに保存されます。

Amazon S3 統合により、S3 バケットを安全に使用し、共有ファイルシステムの代替としてファイルを安全に共有することができます。ユーザーは Amazon RDS for Oracle と他のアプリケーションホストの両方からアクセスできます。Amazon S3 は耐久性と信頼性に優れたオブジェクトストレージサービスであり、そのライフサイクルルールによって、あるストレージクラスから別のストレージクラスへのオブジェクトの移行を自動化してコストを削減することができます。

ソリューションの概要

この記事では、アプリケーションサーバーからデータベースランディングテーブルにファイルをロードする方法を説明します。このランディングテーブルは後で変換され、データは S3 バケットを介して共有ファイルシステムボリュームに出力フラットファイルとして保存されます。

このソリューションの手順は次の通りです。

  1. Amazon RDS for Oracle Database で Amazon S3 統合を設定します。
  2. Amazon RDS for Oracle Database の IAM ロールを設定します。
  3. sqlloader を使用してデータをテーブルにロードします。
  4. データを Oracle テーブルに変更します。
  5. ローカルの Amazon RDS for Oracle ストレージにテキストファイルを作成します。
  6. テキストファイルに正しいデータが含まれているか確認します。
  7. スクリプトを実行して、ローカルストレージから S3 バケットにテキストファイルをアップロードし、S3 バケットから EC2 インスタンスファイルシステムにファイルをダウンロードします。
  8. ファイルが正しくダウンロードされたか確認します。

下の図は、共有ファイルシステムの代わりに Amazon S3 統合を使用する構成を表したもので、共有ファイルシステムを使用したオンプレミスソリューションの設計の図解です。エンドユーザーから入力ファイルとして受信したデータを、共有ファイルシステムに入力ファイルとして保存するプロセスがわかります。このデータはその後データベース内にロードされ、変換されて、出力ファイルとして共有ファイルシステムに保存され、最終的に再びエンドユーザーに送り返されます。

下の図は、Amazon S3 統合オプションを使用した Oracle RDS ソリューションの設計を表しています。エンドユーザーから入力ファイルとしてデータを受信し、共有ファイルシステムに入力ファイルとして保存するプロセスが説明されています。このデータはその後 RDS Oracle データベースにロードされ、変換されて、出力ファイルとして RDS Oracle ローカルファイルシステムに保存されます。そして、この出力ファイルは RDS ローカルストレージから共有ファイルシステムにコピーされ、そのデータはエンドユーザーに再び送信されます。

Amazon RDS for Oracle Database で Amazon S3 統合を設定する

Amazon S3 統合を設定するには、次の手順を実行します。

  1. Amazon RDS コンソールを開きます。
  2. 下のスクリーンショットを参考に [オプショングループ] を選択します。
  3. [グループの作成] を選択します。
  4. [名前] に、グループ名を入力します。
    この記事では S3-Integration-group という名前を入力しています。
  5. [説明] には、グループについての説明を簡潔に入力します。
    この記事では RDS-Oracle を S3 と統合して S3 バケットからファイルをダウンロードおよびアップロードするという説明を入力しています。
  6. [エンジン] ドロップダウンメニューから、Oracle エンジンを選択します。
  7. [メジャーエンジンのバージョン] ドロップダウンメニューから、Oracle データベースのバージョンを選択します。
  8. [作成] を選択します。
  9. RDS コンソールで [オプショングループ] を選択します。
  10. 作成したグループを選択します。
  11. [オプションの追加] を選択します。
  12. [オプション] の中から [S3_INTEGRATION] を選択します。
  13. [バージョン] は [0] を選択します。
  14. [すぐに適用] で [はい] を選択します。
  15. [オプションの追加] を選択します。
  16. オプショングループの情報が正しいか確認します。[オプショングループのプロパティ] に記載されている Oracle のバージョンが正しいかどうか、S3_INTEGRATION オプションが [オプション] に追加されているかどうか、確認します。

オプショングループをデータベースに追加する

  1. RDS ダッシュボードにあるデータベース識別子をクリックしてお使いのデータベースを選択します。
  2. [変更] を選択します。
  3. [データベースの設定] セクションまでスクロールダウンして、[オプショングループ] の中から S3_INTEGRATION オプショングループを選択します。
  4. ページの一番下までスクロールダウンし、[次へ] をクリックします。
  5. [DB インスタンスの変更] を選択します。
  6. インスタンスの変更が正常に完了してデータベースが使用可能になったら、[設定] タブを選択して、オプショングループがインスタンス設定のリストにあることを確認します。

Amazon RDS for Oracle Database の IAM ロールを設定する

IAM ロールを設定するには、次の手順を実行します。

  1. RDS コンソールから、お使いの DB インスタンスを選択します。
  2. [IAM ロールの管理] を選択します。
  3. [このインスタンスに IAM ロールを追加] の中から [rds-s3-integration-role] を選択します。
  4. [機能] の中から [S3_INTEGRATION] を選択します。

sqlloader を使用して入力データをテーブルにロードする

Oracle クライアントバイナリファイル sqlplus へのアクセス権のあるユーザーとして EC2 インスタンスにログインします。以下はデータベースに入力ファイルとしてロードできる入力ファイルのサンプルです。

$ cat tabledataforuploadtoRDS.txt
SYS|ICOL$|TABLE|17-JAN-19|VALID|
SYS|I_USER1|INDEX|17-JAN-19|VALID|
SYS|CON$|TABLE|17-JAN-19|VALID|
SYS|UNDO$|TABLE|17-JAN-19|VALID|
SYS|C_COBJ#|CLUSTER|17-JAN-19|VALID|
SYS|I_OBJ#|INDEX|17-JAN-19|VALID|
SYS|PROXY_ROLE_DATA$|TABLE|17-JAN-19|VALID|
SYS|I_IND1|INDEX|17-JAN-19|VALID|
SYS|I_CDEF2|INDEX|17-JAN-19|VALID|
SYS|I_OBJ5|INDEX|17-JAN-19|VALID|

sqlplus にログインし、以下のコマンドを使用してサンプルデータロードテーブルを作成します。

$sqlplus oraadmin@orclauth
SQL> create table BIGTAB_FROMTEXTFILE as select owner,object_name,object_type,created,status from dba_objects where 1=2;

Table created.

SQL> desc BIGTAB_FROMTEXTFILE
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 OWNER                                     NOT NULL VARCHAR2(128)
 OBJECT_NAME                               NOT NULL VARCHAR2(128)
 OBJECT_TYPE                                        VARCHAR2(23)
 CREATED                                   NOT NULL DATE
 STATUS                                             VARCHAR2(7)

.dat ファイルを作成し、入力ファイルからデータベースにデータをロードします。

$ cat loaddata.dat
load data
INFILE 'tabledataforuploadtoRDS.txt'
INTO TABLE BIGTAB_FROMTEXTFILE
APPEND
FIELDS TERMINATED BY '|'
(
 OWNER,
 OBJECT_NAME,
 OBJECT_TYPE,
 CREATED,
 STATUS)

以下の sqlldr コマンドを使用し、データベースにデータをロードします。

$ sqlldr oraadmin@orclauth control=loaddata.dat log=loaddata.log
Password:

SQL*Loader: Release 12.1.0.2.0 - Production on Mon Jun 17 04:07:24 2019

Copyright (c) 1982, 2014, Oracle and/or its affiliates. All rights reserved.

Path used:      Conventional
Commit point reached - logical record count 10
Commit point reached - logical record count 10

Table BIGTAB_FROMTEXTFILE:
  10 Rows successfully loaded.

Check the log file:
  loaddata.log
for more information about the load.

SQL*PLUS にログインし、以下の SQL コマンドを使用して、データがテーブルに正常にロードされたことを確認します。

SQL> select * from BIGTAB_FROMTEXTFILE;

OWNER                OBJECT_NAME                    OBJECT_TYPE     CREATED   STATUS
-------------------- ------------------------------ --------------- --------- -------
SYS                  ICOL$                          TABLE           17-JAN-19 VALID
SYS                  I_USER1                        INDEX           17-JAN-19 VALID
SYS                  CON$                           TABLE           17-JAN-19 VALID
SYS                  UNDO$                          TABLE           17-JAN-19 VALID
SYS                  C_COBJ#                        CLUSTER         17-JAN-19 VALID
SYS                  I_OBJ#                         INDEX           17-JAN-19 VALID
SYS                  PROXY_ROLE_DATA$               TABLE           17-JAN-19 VALID
SYS                  I_IND1                         INDEX           17-JAN-19 VALID
SYS                  I_CDEF2                        INDEX           17-JAN-19 VALID
SYS                  I_OBJ5                         INDEX           17-JAN-19 VALID

データベーステーブルにデータをアップデートする

以下の SQL*PLUS コマンドを使用して、所有者を SYSTEM、ステータスを INVALID としてアップデートします。

SQL> update BIGTAB_FROMTEXTFILE set owner='SYSTEM',status='INVALID';

10 rows updated.

SQL> select * from BIGTAB_FROMTEXTFILE;

OWNER                OBJECT_NAME                    OBJECT_TYPE     CREATED   STATUS
-------------------- ------------------------------ --------------- --------- -------
SYSTEM               ICOL$                          TABLE           17-JAN-19 INVALID
SYSTEM               I_USER1                        INDEX           17-JAN-19 INVALID
SYSTEM               CON$                           TABLE           17-JAN-19 INVALID
SYSTEM               UNDO$                          TABLE           17-JAN-19 INVALID
SYSTEM               C_COBJ#                        CLUSTER         17-JAN-19 INVALID
SYSTEM               I_OBJ#                         INDEX           17-JAN-19 INVALID
SYSTEM               PROXY_ROLE_DATA$               TABLE           17-JAN-19 INVALID
SYSTEM               I_IND1                         INDEX           17-JAN-19 INVALID
SYSTEM               I_CDEF2                        INDEX           17-JAN-19 INVALID
SYSTEM               I_OBJ5                         INDEX           17-JAN-19 INVALID

SQL> commit;

Commit complete.

ローカルの Amazon RDS for Oracle ストレージにテキストファイルを作成する

以下の SQL*PLUS コマンドを使用して、RDS Oracle インスタンスにローカルディレクトリを作成します。

SQL> exec rdsadmin.rdsadmin_util.create_directory(p_directory_name => 'ORCLAUTHUTLFILES');

PL/SQL procedure successfully completed.

以下の SQL*PLUS コードを使用し、UTL_FILE で RDS Oracle ローカルストレージに出力テキストファイルを作成します。

SQL> declare
  ltype utl_file.file_type;
  ldir  varchar2(100) := 'ORCLAUTHUTLFILES';
  lfile  varchar2(100) := 'BIGTAB_FROMTEXTFILE_FromRDSOracle.txt';
  s varchar2(10) := '|';
begin
  ltype := utl_file.fopen(ldir,lfile,'w');
  for i in (select OWNER,OBJECT_NAME,OBJECT_TYPE,CREATED,STATUS from BIGTAB_FROMTEXTFILE)
     loop
       utl_file.putf(ltype,i.OWNER||s||i.OBJECT_NAME||s||i.OBJECT_TYPE||s||i.CREATED||s||i.STATUS);
	   UTL_FILE.NEW_LINE(ltype);
    end loop;
   utl_file.fclose(ltype);
 end;
 /

PL/SQL procedure successfully completed.

テキストファイルが正しいか確認する

以下のコードを使用して、テキストファイル内のデータが正しいか確認します。

SQL> col filename format a40
SQL> set lines 1000 pages 100
SQL> select * from table(rdsadmin.rds_file_util.listdir(p_directory => 'ORCLAUTHUTLFILES')) where filename='BIGTAB_FROMTEXTFILE_FromRDSOracle.txt';

FILENAME                                 TYPE         FILESIZE MTIME
---------------------------------------- ---------- ---------- ---------
BIGTAB_FROMTEXTFILE_FromRDSOracle.txt    file             4020 17-JUN-19

以下のコードは、RDS Oracle ローカル出力テキストファイルの内容を表示しています。

SQL> col text format a80
SQL> select text from table(rdsadmin.rds_file_util.read_text_file('ORCLAUTHUTLFILES','BIGTAB_FROMTEXTFILE_FromRDSOracle.txt'));

 TEXT
--------------------------------------------------------------------------------
SYSTEM|ICOL$|TABLE|17-JAN-19|INVALID
SYSTEM|I_USER1|INDEX|17-JAN-19|INVALID
SYSTEM|CON$|TABLE|17-JAN-19|INVALID
SYSTEM|UNDO$|TABLE|17-JAN-19|INVALID
SYSTEM|C_COBJ#|CLUSTER|17-JAN-19|INVALID
SYSTEM|I_OBJ#|INDEX|17-JAN-19|INVALID
SYSTEM|PROXY_ROLE_DATA$|TABLE|17-JAN-19|INVALID
SYSTEM|I_IND1|INDEX|17-JAN-19|INVALID
SYSTEM|I_CDEF2|INDEX|17-JAN-19|INVALID
SYSTEM|I_OBJ5|INDEX|17-JAN-19|INVALID

テキストファイルを S3 バケットにアップロードし、EC2 インスタンスファイルシステムにダウンロードする

以下のスクリプトを実行して、出力テキストファイルを RDS Oracle ローカルストレージから S3 バケットにアップロードし、そのファイルをバケットから EC2 インスタンスファイルシステムにダウンロードします。

以下のコード例を使用して、パラメータ値を設定します。

# In Oracle userid create required directories and save files.
$ mkdir -p scriptAWS/log
$ mkdir /u01/filestr

#Copy below file as base script in /home/oracle/scriptAWS folder 

$ cat bscr_rdss3ft.sh
#!/usr/bin/bash
#Script which will call the rds transfer main script and maintains variable details
export SCRIPTPATH=/home/oracle/scriptAWS
export SCRIPTLOG=/home/oracle/scriptAWS/log
export DBUSERNAME=oraadmin
export DBPASSWD=oraadmin123
export DBTNSSTRG=orclauth
export RDSDIRNAME=ORCLAUTHUTLFILES
export RDSFILNAME=BIGTAB_FROMTEXTFILE_FromRDSOracle.txt
export S3BUCKETNAME=rdsarchivedata
export FILELFSPATH=/u01/filestr

source $SCRIPTPATH/rdss3integration.sh

echo "Script Retrun"
echo "Script is again back to base script"
echo "move log files"
mv $SCRIPTLOG/downloadtolfs-$UPLOADTASK.log $SCRIPTLOG/downloadtolfs-$UPLOADTASK-`date +%m%d%Y%H%M%S`.log
mv $SCRIPTLOG/uploadstatus-$UPLOADTASK.log $SCRIPTLOG/uploadstatus-$UPLOADTASK-`date +%m%d%Y%H%M%S`.log
mv $SCRIPTLOG/filetext-$UPLOADTASK.log $SCRIPTLOG/filetext-$UPLOADTASK-`date +%m%d%Y%H%M%S`.log
mv $SCRIPTLOG/file_taskid_$UUID.log $SCRIPTLOG/file_taskid_$UUID-$UPLOADTASK-`date +%m%d%Y%H%M%S`.log
mv $SCRIPTLOG/rdslfsdelete-${UPLOADTASK}-${RDSFILNAME}.log $SCRIPTLOG/rdslfsdelete-${UPLOADTASK}-${RDSFILNAME-}-`date +%m%d%Y%H%M%S`.log
mv $SCRIPTLOG/rdss3integration_$UUID.log $SCRIPTLOG/rdss3integration_$UUID-${UPLOADTASK}-`date +%m%d%Y%H%M%S`.log

以下のコードは、Amazon S3 にアップロードし、ファイルシステムにダウンロードする実際のベーススクリプトです。

#Copy below file in /home/oracle/scriptAWS folder 
$ cat rdss3integration.sh
#!/usr/bin/bash

UUID=$(uuidgen)

getTaskId()
{
sqlplus -s $DBUSERNAME/$DBPASSWD@$DBTNSSTRG <<EOF > ${SCRIPTLOG}/rdss3integration_$UUID.log  2>&1
set heading off
set pages 0
set feedback off
set echo off
set lines 100
set trimspool on
set trimout on
spool ${SCRIPTLOG}/file_taskid_$UUID.log
SELECT rdsadmin.rdsadmin_s3_tasks.upload_to_s3(
        p_bucket_name    =>  '$S3BUCKETNAME',
        p_prefix         =>  '$RDSFILNAME',
        p_s3_prefix      => '',
        p_directory_name =>  '$RDSDIRNAME')
   AS TASK_ID FROM DUAL;
spool off
EOF
}

ERRCOUNT=0

runTask()
{
while :
do

UPLOADTASK=`tail -1 ${SCRIPTLOG}/file_taskid_$UUID.log`
sqlplus -s $DBUSERNAME/$DBPASSWD@$DBTNSSTRG <<EOF >> ${SCRIPTLOG}/rdss3integration_$UUID.log  2>&1
set heading off
set pages 0
set feedback off
set echo off
set lines 500
col text format a500
set trimspool on
set trimout on
spool ${SCRIPTLOG}/filetext-${UPLOADTASK}.log REPLACE
SELECT text FROM table(rdsadmin.rds_file_util.read_text_file('BDUMP','dbtask-$UPLOADTASK.log'));
spool off
EOF

FILESTATUS=`tail -1 ${SCRIPTLOG}/filetext-${UPLOADTASK}.log|awk '{ print $8}'`
echo `date`':'$FILESTATUS >> ${SCRIPTLOG}/uploadstatus-${UPLOADTASK}.log
if [[ $FILESTATUS = "finished" ]]
        then
        echo "file upload to s3 is finished "
        echo
        date  >> ${SCRIPTLOG}/downloadtolfs-${UPLOADTASK}.log
        aws s3 cp s3://$S3BUCKETNAME/$RDSFILNAME $FILELFSPATH >> ${SCRIPTLOG}/downloadtolfs-${UPLOADTASK}.log

###############################################################################################################
#Uncoment below code if you want to delete the file automatically
#sqlplus -s $DBUSERNAME/$DBPASSWD@$DBTNSSTRG <<EOF >> ${SCRIPTLOG}/rdss3integration.log  2>&1
#set heading on
#set pages 0
#set feedback on
#set echo on
#set lines 300
#set trimspool on
#set trimout on
#set serveroutput on
#spool $SCRIPTLOG/rdslfsdelete-${UPLOADTASK}-${RDSFILNAME}.log
#exec utl_file.fremove('$RDSDIRNAME','$RDSFILNAME');
#spool off
#EOF
##############################################################################################################
        return
elif [[ $FILESTATUS = "failed." ]]
        then
        echo "file upload to s3 is failed "
        exit 1
elif [[ $FILESTATUS = "Uploading" ]]
        then
        echo "file upload to s3 is in progress, please wait while the upload complete successfully"
else
if [[ $ERRCOUNT -le 180 ]]
        then
        echo "This is incrementing error $ERRCOUNT as task status was $FILESTATUS  " >> ${SCRIPTLOG}/errorcount-${UPLOADTASK}.log
        ERRCOUNT=`expr $ERRCOUNT + 1`
else
        echo "The S3 integration process encounter error from parent script which is causing this script to fail"
        echo "Please review your source script to ensure everything is working as expected"
        exit 1
fi
fi
        sleep 5
        done
}

getTaskId
runTask

上記で作成した .sh ファイルに追加の実行権限を付与し、以下のコマンドを使用して実行します。

$chmod 755 *.sh
$sh bscr_rdss3ft.sh

Amazon S3 統合を使用して Amazon S3 にアップロードするプロセスはシリアル化されています。一度にアップロードできるファイルは 1 つだけです。同時プロセスがファイルのアップロードを試行する場合、1 つのプロセスは他のアップロードが完了するまで待機します。

ファイルが Amazon S3 にアップロードされファイルシステムに正常にダウンロードされたか確認する

ファイルが Amazon S3 にアップロードされたかどうかは、S3 コンソールで確認できます。

ファイルがローカル EC2 ファイルシステムにダウンロードされたか確認するには、以下のコードを入力します。

$ cd /u01/filestr/
$ ls -lt BIGTAB_FROMTEXTFILE_FromRDSOracle.txt
-rw-r--r--.1 oracle oinstall 4020 Jun 17 05:04 BIGTAB_FROMTEXTFILE_FromRDSOracle.txt
$

まとめ

この記事では、共有ファイルシステムの安全な代替手段として Amazon S3 統合を使用する方法について説明しました。共有スクリプトが特定の Oracle ディレクトリに限定されることはありません。ディレクトリ名とファイル名を変更して同じスクリプトを使用することができます。たとえば、このスクリプトを使用して Amazon RDS for Oracle Data Pump Export ダンプを S3 バケットに移行できますし、その逆も可能です。いつものように、AWS はフィードバックを歓迎します。以下の欄にコメントをお寄せください。

 


本稿の執筆者について

 

Bhavesh Rathod は Oracle データベースクラウドアーキテクトで、アマゾン ウェブ サービスのプロフェッショナルサービスチームに所属しています。データベース移行のスペシャリストとして、Amazon のお客様によるオンプレミスデータベース環境から AWS クラウドデータベースソリューションへの移行を支援しています。

 

 

 

Samujjwal Roy はデータベース専門アーキテクトで、アマゾン ウェブ サービスのプロフェッショナルサービスチームの一員です。Amazon に 15 年以上勤続し、Amazon 内外のお客様の移行プロジェクトを主導して、オンプレミスデータベース環境から AWS クラウドデータベースソリューションへの移行を手がけてきました。

 

 


Amishi Shah は DevOps コンサルタントで、アマゾン ウェブ サービスのプロフェッショナルサービスチームに所属しています。お客様とともに、AWS クラウドでスケーラブルで可用性の高い、安全なソリューションを構築しています。技術、組織、SDLC の大規模な変革を通じてエンタープライズのお客様を手引きすることに取り組んでいます。