Oracle に遊ばれる修行

最初の挑戦

RHEL3 上の 9i で exp したダンプファイルを CentOS 5 上の 10g に imp しようとしてる。一見できたようだが、キャラクターセット周りでうまくいっていない。

Database Configuration Assistant*1 を使って DB インスタンスを作ろうとしたとき、「カスタム」を選ぶと途中で DB インスタンスに接続できない旨表示されて失敗する。いろいろ試したのだが、結局「汎用」を選んで進めた。この場合、OEM 関係でエラーが出るものの DB インスタンスはできる。

文字化け発覚

とりあえず exp してきたファイルを imp できたし、その後のリスナの設定もうまくいったので安心していたら文字化けが発生した。おそらく内部コードの問題だろうと調べてみると、DB パラメータの NLS_CHARACTERSET が us7ascii になっている。9i 側は JA16EUC になっているから、そこが問題なんだろう。

いろいろ調べてみると、次のことがわかった(全部噂だなあ、原典あたれ、自分)。

  • DB パラメータの NLS_CHARACTERSET は、環境変数 LANG (NLS_LANG でなくて)の値に依存するらしい、との噂がある。
  • デフォルトの DB インスタンスは削除して、新たに作るのいいよん的記事がネット上にいくつかある。
  • DB インスタンス生成スクリプトを使って作ったらいいんじゃない的な噂も。

確かに RHEL3 は ja_JP.eucJP がデフォルトだったし、CentOS 5 は ja_JP.UTF-8 だ。なもんで LANG をいろいろ変えつつ dbca を走らせて見た。でも NLS_CHARACTERSET は変わらず us7ascii のまま。 CentOS 5 には EUC-JP なロケールとして ja_JP.eucjp しかなく、RHEL3 の ja_JP.eucJP と微妙に違うのが影響しているのかもしれない。ロケール作ればいいのかなぁ、と思いつつ、やったことがないので尻込み。

DB 生成スクリプトを生成

しばらくネットを漂っていたら、dbca で最初に「カスタム」を選んだ場合は、直接 DB を作成するほか、DB を作成するスクリプトを生成することもできるらしいことがわかった。ので、とりあえず「カスタム」を選択し、DB は作成せずにスクリプトだけを吐き出させた。

できたシェルスクリプトSQL をざっと眺めると、全体の構成は素直なわかりやすい形。とりあえず、そのまま実行してみた。ただし、-x オプションつきで。しかも Emacs の *shell* バッファで。

[oracle@doronuma] $ sh -x ./sokonasi.sh

GUI(dbca)から実行したときと同じように途中で失敗したが、どこで失敗したのかはわかる。どうやら Ultra Search 周りらしい。Ultra Search 自体よくわからなかったが、ざっとググった感じでは、今回移行する DB を使っている案件では使っていない機能っぽい。

ということで、Ultra Search 周りと、危険な香りのする OEM (Oracle Enterprise Manager) 周りはスキップし、それ以降の処理を実行するシェルスクリプトを書いて実行した*2
すると、何事もなかったようにシェルスクリプトが正常終了した。NLS_CHARACTERSET もきちんと JA16EUC になった。

おそるおそる(でもないけど)imp を実行してみると、文字化けせずきちんと EUC でストアされたようだ。
結果的には、これで成功したっぽい。

教訓

  • ウィザードでの作業手順を残すよりも、シェルスクリプト群を残したほうが、DB の再構築には便利だ。
    • 似たような、でもちと違うインスタンス生成時にも調整が容易
    • DB インスタンス生成時にしかいじれない値のチューニングも容易
    • 記録し忘れることがない。
  • 後々ウィザードを使う作業の必要が想定される場合には、その作業の手順を残すことも重要。
    • 作業メモ:「こんな感じ、流れでやるんだよ」という概要を人間に知らせるための資料
    • スクリプト:「実際にはこんなことをしました」という詳細であり、そのまま再現できるプログラム

*1:だったか? dbca とかいうヤツ。ヤツってゆーな。

*2:本当は生成された DB インスタンス周りのファイルを消し、回避する部分だけスキップするシェルスクリプトを書いて、それを実行すべき。よいこのみんなはまねしちゃだめだよ。