第5回:RAWデバイスでのOracleアップグレードエラー

技術者向け・データベースの技術情報発信

はじめに

皆様、こんにちは。マルチDBソリューション部の三浦です。

以前、Oracle Databaseのアップグレード対応を実施した際に、RAWデバイスに起因したエラーが発生しました。自社環境での検証時にそのエラーを発見することができた為、事前に手を打つことができたのですが、今回はその時のことを記載したいと思います(事前検証は本当に大事ですね・・・)。

なお今回は、アップグレードの詳細手順などについては、省略させて頂きます。ご了承ください。因みに、11gのアップグレードマニュアルは、以下サイトで参照できます。
https://docs.oracle.com/cd/E16338_01/server.112/b56310/toc.htm

RAWデバイスとは??

RAWデバイスとは、ファイルシステムを利用していない、ボリュームやパーティションなどのことです。

メリットは、ファイルシステムを経由しない為、データ更新のディスクI/Oが高速化できたり、OSのキャッシュを利用しないことで、無駄なメモリを消費しないことなどがあります。論理ボリューム上にファイルシステムを作成することで、「ファイル」や「フォルダ」を作成することができる為、人間にとって非常に管理しやすくなります。

しかし、RAWデバイスでは、論理ボリューム上にファイル・フォルダを作成することはできず、OSからもデータを参照することができません。つまり、RAWデバイスを使用するソフトウェアのみが理解できる状態で書き込まれる為、人間にとってみれば管理し難いというデメリットがあります。

※Oracle Database 12cからは、RAWデバイスへ直接データファイル作成することはサポート外となりました。

エラー内容

【アップグレード環境の前提情報】
  • 11.2.0.1 ⇒ 11.2.0.4へのアップグレードです。
  • ASMは利用していません。
  • REDOや制御ファイル、データファイルをRAWデバイス上へ作成しています。
  • アップグレードはout-of-place方式で行います。
  • DBUAを使用しないでアップグレードを行います。
新ORACLE_HOMEへProductionのインストール、及びパスワードファイル等のコピーが完了した後、 いざアップグレードを行う為に11.2.0.4のProductionでインスタンスを起動させました。 が、以下エラーが発生してしまいました・・・。
[oracle@test ~]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.4.0 Production on 月 xx月 xx xx:xx:xx xxxx

Copyright (c) 1982, 2013, Oracle.  All rights reserved.

アイドル・インスタンスに接続しました。

SQL>
SQL> startup upgrade
ORACLEインスタンスが起動しました。

Total System Global Area 1068937216 bytes
Fixed Size                  2260088 bytes
Variable Size             671089544 bytes
Database Buffers          390070272 bytes
Redo Buffers                5517312 bytes
データベースがマウントされました。
ORA-01157: データファイル4を識別/ロックできません - DBWRトレース・ファイルを参照してください ORA-01110: データファイル4: '/dev/raw/raw41'
※DBUAを使用したとしても、アップグレードモードでの起動を行いますので、同一エラーが発生します。

エラー内容

「ん?データファイルが壊れた?」と思い、確認の為に11.2.0.1のインスタンスを起動してみましたが、結果は・・・。
[oracle@test ~]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.1.0 Production on 日 xx月 xx xx:xx:xx xxxx

Copyright (c) 1982, 2009, Oracle.  All rights reserved.

アイドル・インスタンスに接続しました。

SQL>
SQL> startup
ORACLEインスタンスが起動しました。

Total System Global Area 1068937216 bytes
Fixed Size                  2220200 bytes
Variable Size             633343832 bytes
Database Buffers          427819008 bytes
Redo Buffers                5554176 bytes
データベースがマウントされました。
データベースがオープンされました。

問題なく起動しました。


そこで色々と調査をしてみると、以下のことが分かりました。

【11.2.0.1以前】
  • 制御ファイルの内容に問題がなければ、起動時にデータファイルのチェックは行われませんでした。
    ⇒データファイルのヘッダ情報に異常がある場合でも、データベースをオープンできます。
【11.2.0.2以降】
起動時に、必ずデータファイルのヘッダ情報をチェックするように、仕様変更されました。
⇒データファイルのヘッダ情報に異常がある場合、データベースをオープンできません。
では、実際にデータファイルのヘッダ情報(オフセットのバイト数)を確認してみましょう!
SQL> select
  2      t.name tablespace_name,
  3      d.name datafile_name,
  4      d.block1_offset,
  5      d.bytes/1024/1024 size_mb_current
 18  from v$datafile d,v$tablespace t
 19  where d.TS# = t.TS#
 20  /

TABLESPACE_NAME     DATAFILE_NAME         BLOCK1_OFFSET SIZE_MB_CURRENT
------------------- --------------------- ------------- ---------------
SYSTEM              /dev/raw/raw31                 8192            1023
SYSAUX              /dev/raw/raw32                 8192            1023
UNDOTBS1            /dev/raw/raw34                 8192            1023
DATA01              /dev/raw/raw41           4294967295      1023.99219
INDEX01             /dev/raw/raw42           4294967295      1023.99219
PERFSTAT            /dev/raw/raw43           4294967295      1023.99219

6行が選択されました。
データファイル(RAW41~RAW43)のオフセット値が4GBとなっています。
※データファイルは1GBしかないのに・・・。

そこで疑問が一つ出てきました。データファイルによって、正常なオフセット値が設定されているものと、されていないものに分かれるのは、なぜでしょうか?

原因は表領域の作成方法にありました。 下記は、データベース作成時に使用したクエリです。
--データベースの作成
CREATE DATABASE "ORCL"
MAXINSTANCES 8
MAXLOGHISTORY 1
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
DATAFILE '/dev/raw/raw31' SIZE 1023M REUSE
EXTENT MANAGEMENT LOCAL
SYSAUX DATAFILE '/dev/raw/raw32' SIZE 1023M REUSE SMALLFILE DEFAULT TEMPORARY TABLESPACE TEMP TEMPFILE '/dev/raw/raw33' SIZE 1023M REUSE SMALLFILE UNDO TABLESPACE "UNDOTBS1" DATAFILE '/dev/raw/raw34' SIZE 1023M REUSE
CHARACTER SET AL32UTF8
NATIONAL CHARACTER SET AL16UTF16
LOGFILE GROUP 1 ('/dev/raw/raw21', '/dev/raw/raw22') SIZE 511M,
GROUP 2 ('/dev/raw/raw23', '/dev/raw/raw24') SIZE 511M,
GROUP 3 ('/dev/raw/raw25', '/dev/raw/raw26') SIZE 511M
USER SYS IDENTIFIED BY "&&sysPassword" USER SYSTEM IDENTIFIED BY "&&systemPassword";

--ユーザー表領域の作成
CREATE SMALLFILE TABLESPACE "DATA01" LOGGING DATAFILE '/dev/raw/raw41' REUSE EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO / CREATE SMALLFILE TABLESPACE "INDEX01" LOGGING DATAFILE '/dev/raw/raw42' REUSE EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO / CREATE SMALLFILE TABLESPACE "PERFSTAT" LOGGING DATAFILE '/dev/raw/raw43' REUSE EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO /
サイズを指定してデータファイルを作成している場合は、正常なオフセット値が設定されており、指定していない場合は異常な値となっています。RAWデバイスの場合、サイズを指定しないでデータファイルを作成すると、自動的にRAWデバイスの使用可能領域ぎりぎりまでデータ保存ができるように作成されます。しかし、これが原因で、オフセット値に異常なバイト数が設定されていました。
SQL> select FILE_NAME,BYTES/1024/1024 from dba_data_files;

FILE_NAME                 BYTES/1024/1024
------------------------- ---------------
/dev/raw/raw31                       1023
/dev/raw/raw32                       1023
/dev/raw/raw34                       1023
/dev/raw/raw41                 1023.99219
/dev/raw/raw42                 1023.99219
/dev/raw/raw43                 1023.99219

6行が選択されました。

解決策

では、この問題を解決するには、どのような方法があるのでしょうか?

それは、データファイルのサイズを変更することで、ヘッダ情報が正常なバイト数に設定されます。 では実際にやってみましょう!
SQL> alter database datafile '/dev/raw/raw41' resize 1023M;

データベースが変更されました。

SQL> alter database datafile '/dev/raw/raw42' resize 1023M;

データベースが変更されました。

SQL> alter database datafile '/dev/raw/raw43' resize 1023M;

データベースが変更されました。

SQL>
SQL> select
  2      t.name tablespace_name,
  3      d.name datafile_name,
  4      d.block1_offset,
  5      d.bytes/1024/1024 size_mb_current
  6  from v$datafile d,v$tablespace t
  7  where d.TS# = t.TS#
  8  /

TABLESPACE_NAME     DATAFILE_NAME          BLOCK1_OFFSET SIZE_MB_CURRENT
------------------- ---------------------- ------------- ---------------
SYSTEM              /dev/raw/raw31                  8192            1023
SYSAUX              /dev/raw/raw32                  8192            1023
UNDOTBS1            /dev/raw/raw34                  8192            1023
DATA01              /dev/raw/raw41                  8192            1023
INDEX01             /dev/raw/raw42                  8192            1023
PERFSTAT            /dev/raw/raw43                  8192            1023

6行が選択されました。
上記の通り、データファイルのリサイズを行うと、正常なオフセット値がセットされたことが分かります。
※因みに、サイズを変更せず(上記例では「1023.99219MB」)にリサイズしても、問題は解消されません。

次は、11.2.0.4のインスタンスを起動してみましょう。
[oracle@test ~]$ sqlplus / as sysdba

SQL*Plus: Release 11.2.0.4.0 Production on 月 xx月 xx xx:xx:xx xxxx

Copyright (c) 1982, 2013, Oracle.  All rights reserved.

アイドル・インスタンスに接続しました。

SQL>
SQL> startup upgrade
ORACLEインスタンスが起動しました。

Total System Global Area 1068937216 bytes
Fixed Size                  2260088 bytes
Variable Size             671089544 bytes
Database Buffers          390070272 bytes
Redo Buffers                5517312 bytes
データベースがマウントされました。
データベースがオープンされました。
SQL>
ようやく、11.2.0.4で正常に起動することができました。これ以降は、ファイルシステムなどと同様の手順にてアップグレードを行うことができました。

最後に

アップグレード作業に限ったことではないですが、どこでハプニングが起こるかわかりません。なので、事前検証はしっかりと行いましょう!

また、データベース以外でも、何かお困りのことがありましたら弊社までご連絡下さい。 より良いソリューションを提供させて頂きます。