Oracle Database 11gへの移行計画の立案とそのポイント
パナソニック ソリューションテクノロジー株式会社 ITインフラ事業本部 西日本技術グループ 主任 大西 仁

この記事は、実際に私がOracle Database 11gへの移行を行った際の経験を元に、移行計画をたてる際のポイント、移行作業時のテクニック、問題への対処方法を記事にしたものです。データベースの移行作業に携わるDBAやエンジニアを読者対象としており、皆様がOracle Database 11g移行を実施する際に少しでも助けになればと思います。
目次
Oracle Database 11gへの移行計画の立案とそのポイント
実際のデータベース移行(バージョンアップ)の際には、OSもあわせて移行することが多いと思います。OSの移行をおこなう場合は、それに伴い、開発環境の移行やアプリのコンバージョンが必要になってきます。実際に私がおこなった移行作業では、ハードウェア移行とOS移行を同時におこないました。
環境・条件
- データベース: Oracle Database 10g Release 2(10.2.0.2) 4ノードReal Application Clusters(RAC)環境から、Oracle Database 11g Release 1(11.1.0.6) 4ノードRACへ移行
- OS: Linux(x86_64)からSolaris 10へ移行
移行作業の計画をたてる際には、いくつか押さえるべきポイントがあります。たとえば、データベース移行に特化した視点で考えると、次の点が重要になってきます。
- 移行時間を一定の範囲におさめるための工夫
- 移行によるパフォーマンスアップ・パフォーマンスダウンの検証
移行時間については、すでに本番環境で稼働しているシステムの移行の場合には、とくに短縮が求められます。私の場合は、移行作業に掛けられる時間は最大2時間という制約がありました。
今回の移行作業はこれまでの経験から、次のように計画しました。
- 移行後のOracle Database 11g環境では、現行サイズと同じ表領域を定義する。
- テーブルおよびインデックスは、現行環境のdbms_spaceの結果からブロック使用率を確認し、initialエクステントサイズを見直す。テーブルは事前に定義する。
- 移行時には、移行ツールとしてスキーマ・モードのDataPump Export/Importを使用する。
- テーブルは事前に定義するため、CONTENT=DATA_ONLYを使用する。
- 4ノード 各インスタンスでexpdpを実行する。
※移行方法としてTRANSPORT_TABLESPACESを採用しなかった理由
Oracle Database 10g Release 2より、異なるOS間でのTRANSPORT_TABLESPACESが使用可能になりました。今回のケースでも移行方法の一つとして当初検討しましたが、下記の理由のため、今回は採用しませんでした。
- 今回の移行作業でのLinux→Solaris間では、エンディアンが異なるためrmanによる変換作業が必要
- エクステントサイズの見直しや変換処理がテストできなかったこと、変換後のデータファイルを一時保管する領域確保の問題など、乗り越える課題が多かった
このため、最終的にdmpファイルによる移行をおこなうこととなりました。
移行作業時間を短縮するための工夫
事前の移行テストを実施した結果を踏まえ、当初 4ノードRACの各インスタンス上でexpdp(PARALLEL=8)を実行し、4ノード x 8パラレル = 32パラレルで処理しようと考えていました。しかし、expdpは同一RAC上では複数実行出来ない仕様となっているため、1ノードのみexpdp(PARALLEL=8)実行しました。そのため、expdpの処理で1時間半かかってしまう状態となってしまいました。
この問題の対処方法として、
- NetApp社のFlexCloneを使用したホット・バックアップからのexpdpの実行
- 現行本番環境からのexpdpの実行
を並列稼動させることで、トータルの作業時間を2時間以内におさめることが出来ました。
移行後のパフォーマンス変化への対応
テスト環境でオンライン処理やバッチ処理などファンクション面でのテストは十分に実施していましたが、やはりパフォーマンスについては実際にデータを本番環境へ移行してからのテストとなります。移行作業後に本番のシステム環境でパフォーマンステストをおこなったところ、想定通りのパフォーマンスが出ず、調査の結果、システムの中心である表のインデックスが使用されていないことが判りました。移行時に統計情報がImportされていなかったのが原因であり、そのため正しいSQL実行計画を作成できなかったためでした。
調査の結果判明したことですが、impdpの仕様が下記のとおりとなっているためでした。
impdpで旧環境の統計情報をImportする場合は、TABLE_EXISTS_ACTION=REPLACEを指定する必要がある。CONTENT=DATA_ONLYやTABLE_EXISTS_ACTION=append を指定した場合、統計情報はImportされない。
この内容は、マニュアルにも十分に書かれておらず、また、従来のimpとは異なる動作となりますのでご注意ください。なお、MetaLink Note:277010.1 にこの内容の記載があります。サポート契約をおもちの方はご参考になさってください。
本番移行時には、データ移行後に統計情報を収集し、無事問題を回避できました。
移行時に判明したチューニングテクニック:暗黙のデータ型変換への対応
データベース移行のポイントとは若干はずれた話題となりますが、統計情報がインポートされない原因を調査していた際にパフォーマンス・チューニングにして判明したことがありますので、みなさんと共有します。
コスト・ベース・オプティマイザの環境では、たとえルール・ベース・オプティマイザではインデックスが使われないような環境であっても、暗黙的なデータ型変換によりINDEX FAST FULL SCANが使用されることがあります。その結果、思った以上にパフォーマンスがでない場合があります。
では実際の動きとしてはどのようになるか、検証環境を作成して確認してみましょう。
- まず検証用の表を作成します
SQL> CREATE TABLE EMP2 2 (EMPNO VARCHAR2(6) CONSTRAINT PK_EMP2 PRIMARY KEY, 3 ENAME VARCHAR2(10)); - 次に、検証用の表にダミーデータを追加します
SQL> begin 2 for i in 1..999999 LOOP 3 insert into emp2(EMPNO,ENAME) values(i,'AAAA'); 4 end loop; 5 end; 6 / PL/SQLプロシージャが正常に完了しました。 SQL> commit; - ダミーデータを追加したので、インデックス(PK_EMP2)を再構築します
alter index pk_emp2 rebuild online; - 統計情報を収集します
SQL> BEGIN 2 DBMS_STATS.GATHER_SCHEMA_STATS ( 3 OWNNAME => 'SCOTT' 4 ,OPTIONS => 'GATHER AUTO' ); 5 end; 6 / PL/SQLプロシージャが正常に完了しました。 - 実行計画を確認してみます
SQL> select count(1) from emp2 where empno = 20 ; COUNT(1) ---------- 1 経過: 00:00:00.18 実行計画 ---------------------------------------------------------- Plan hash value: 3718846230 --------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 7 | 647 (2)| 00:00:08 | | 1 | SORT AGGREGATE | | 1 | 7 | | | |* 2 | INDEX FAST FULL SCAN| PK_EMP2 | 1 | 7 | 647 (2)| 00:00:08 | --------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - filter(TO_NUMBER("EMPNO")=20)このSQL実行計画では、まずPK_EMP2に対するINDEX FAST FULL SCANを使用し、その後EMPNO列に対するTO_NUMBER("EMPNO")の暗黙変換を実行したうえで、EMPNOが20の行が返されていることがわかります。INDEX FAST FULL SCANが事前に実行されているわけですから、その分、本来求めていた処理よりも余計に処理がなされていることになります。
最初に表を作成する際にEMPNOはVARCHAR2型と定義しましたので、データ型をマッチさせたSQLを記述するとすれば、このようになります。
SQL> select count(1) from emp2 where empno = '20'; COUNT(1) ---------- 1 経過: 00:00:00.00 実行計画 ---------------------------------------------------------- Plan hash value: 1940746513 ------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | 7 | 2 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | 7 | | | |* 2 | INDEX UNIQUE SCAN| PK_EMP2 | 1 | 7 | 2 (0)| 00:00:01 | ------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("EMPNO"='20')非常に簡単なSQLの書き換えですが、これにより8倍(8秒→1秒)速度向上が出来ました。
プログラム作成の際には、当然SQL解析の効率化のためバインド変数の利用や実行計画の確認を実施されていると思いますが、パフォーマンス・チューニングの実施を検討される際には、SQLのチューニングを開始する前にまず上位言語から受け渡すデータ型がOracleデータ型と互換性のある型となっているかを確認し、デフォルトでOracle Database のオプティマイザが正しく解釈できるSQLを記述することが、非常に重要です。
もちろんデータ件数や環境によっては、マルチブロック読込みのINDEX FAST FULL SCANの方が速い場合もありますので一概にどちらが速いと言い切ることはできませんが、今回のケースのように型変換の確認を怠ると、コスト・ベース・オプティマイザのおせっかい(?)で不必要な処理がおこなわれている可能性もあります。
実際の環境に近いデータで検証環境をつくり、十分にテストして試してみてください。
Copyright © 2008, Oracle Corporation Japan. All rights reserved.
無断転載を禁ず
この文書はあくまでも参考資料であり、掲載されている情報は予告なしに変更されることがあります。日本オラクル社は本書の内容に関していかなる保証もいたしません。また、本書の内容に関連したいかなる損害についても責任を負いかねます。
Oracleは米国Oracle Corporationの登録商標です。文中に参照されている各製品名及びサービス名は米国Oracle Corporationの商標または登録商標です。その他の製品名及びサービス名はそれぞれの所有者の商標または登録商標の可能性があります。