【完全ガイド】ORA-01033: ORACLE initialization or shutdown in progress の原因と解決方法|PDB MOUNTED・STARTUP 3段階 徹底解説

【完全ガイド】ORA-01033: ORACLE initialization or shutdown in progress の原因と解決方法|PDB MOUNTED・STARTUP 3段階 徹底解説

目次

Oracle 開発者・アプリユーザーがタイミング悪く遭遇する典型的エラー:

$ sqlplus scott/tiger@ORCL
ERROR:
ORA-01033: ORACLE initialization or shutdown in progress
Process ID: 0
Session ID: 0 Serial number: 0

**「起動中 or 停止中です」**というシンプルなメッセージ。DB は動いているが利用可能状態ではないを意味します:

  • DB は完全停止ではない(それなら ORA-01034)
  • 起動プロセス途中 or 停止プロセス途中
  • SYSDBA なら接続可能、一般ユーザーは待機必要
  • PDB が MOUNTED 状態(12c+ で最頻出)
  • 数秒〜数分の待機で解決する場合が多い

このエラーの本質は、Oracle 公式ドキュメントが明確に述べています:

Cause: An attempt was made to log on while Oracle is being 
       started up or shutdown.
Action: Wait a few minutes. Then retry the operation.

**「Oracle が起動中 or 停止中の遷移状態」**での接続試行が原因。

起動時 vs 停止時の DB 状態

STARTUP の 3 段階:

NOMOUNT: インスタンス起動(メモリ + プロセス)
   ↓
MOUNT:   コントロールファイル読み取り
   ↓
OPEN:    データファイル open ← ここで初めて一般接続可能

SHUTDOWN の 4 種類:

SHUTDOWN NORMAL:        既存接続完了待ち
SHUTDOWN IMMEDIATE:     即座に切断
SHUTDOWN TRANSACTIONAL: 現行トランザクション完了待ち
SHUTDOWN ABORT:         強制切断(recovery 必要)

NOMOUNT/MOUNT 状態 or SHUTDOWN 中に一般ユーザーが接続 → ORA-01033

接続系エラー7種の完全比較

Oracle 接続系エラーの位置づけ:

ORA-12541: Listener 未起動
ORA-12154: TNS 名前解決失敗
ORA-12514: Service 未登録
ORA-12170: 接続タイムアウト
ORA-01034: DB 完全停止
ORA-01033: DB 遷移中(起動 or 停止中) ← 本記事
ORA-01109: DB not open(MOUNT 状態)
ORA-01017: 認証失敗

現場で最も典型的なパターン:

  • DB 起動中(NOMOUNT/MOUNT)
  • PDB が MOUNTED 状態(12c+、最頻出)
  • DB シャットダウン中(SHUTDOWN IMMEDIATE 進行中)
  • MEDIA RECOVERY 実行中(アーカイブログ適用)
  • Instance Recovery(前回 SHUTDOWN ABORT)
  • RAC ノード起動中(Listener 動的登録タイムラグ)
  • Startup Trigger 実行中(AFTER STARTUP ON DATABASE)
  • STARTUP 失敗中途(COMPATIBLE パラメータ不整合等)
  • Standby DB リカバリ(Data Guard)
  • 前回異常終了(クラッシュリカバリ中)

多くの日本語記事が「待つべし」で終わりますが、実務では:

  • 接続系エラー7種の厳密な区別
  • STARTUP の 3 段階 (NOMOUNT → MOUNT → OPEN)
  • SHUTDOWN の 4 種類 (NORMAL/IMMEDIATE/TRANSACTIONAL/ABORT)
  • PDB の open_mode 判定(v$pdbs
  • ALTER PLUGGABLE DATABASE OPEN の必須知識
  • STARTUP FORCE による強制起動
  • 自動起動 Trigger(AFTER STARTUP ON DATABASE)
  • ALTER PLUGGABLE DATABASE SAVE STATE(19c+ 推奨)
  • RAC 環境での特殊挙動
  • Rails / Java アプリのリトライロジック

さらに、12c+ のマルチテナントでは特に PDB 対応が必須:

-- CDB は OPEN、PDB は MOUNTED(初期状態)
SELECT name, open_mode FROM v$pdbs;
-- PDB1: MOUNTED   ← 一般ユーザー接続で ORA-01033

-- PDB 手動 OPEN
ALTER PLUGGABLE DATABASE pdb1 OPEN;

-- 自動起動設定(19c+ 推奨)
ALTER PLUGGABLE DATABASE pdb1 SAVE STATE;

19c 以前は起動 Trigger で対応が必要でした。

本記事では、ORA-01033: ORACLE initialization or shutdown in progress完全な原因と解決方法を、リファレンスとして実用的に整理します。10大発生パターン、STARTUP/SHUTDOWN 仕組み、6つの解決策、PDB 対応、Rails/Java/Python 対応、実践シナリオ、FAQまで完全網羅。この1本で ORA-01033 に冷静に的確に対処できるようになります。


結論:SYSDBA で状態確認 → OPEN

時間がない方向けに、最速の対処を先に示します。

エラーメッセージの読み方

ORA-01033: ORACLE initialization or shutdown in progress
                    ↑                       ↑
             起動プロセス中       停止プロセス中

= DB は動いているが利用可能ではない
  SYSDBA 接続なら状態確認可能

最速の診断と対処

# STEP 1: SYSDBA で状態確認
$ sqlplus / as sysdba

SQL> SELECT status FROM v$instance;
-- STARTED / MOUNTED / OPEN

SQL> SELECT open_mode FROM v$database;
-- READ WRITE / MOUNTED

-- STEP 2: PDB 状態(12c+)
SQL> SELECT name, open_mode FROM v$pdbs;

-- STEP 3: 対処
-- MOUNTED なら:
SQL> ALTER DATABASE OPEN;

-- PDB MOUNTED なら:
SQL> ALTER PLUGGABLE DATABASE pdb1 OPEN;

-- 全 PDB OPEN:
SQL> ALTER PLUGGABLE DATABASE ALL OPEN;

6つの解決策

#手法使う場面
待機(数分)起動/停止中
SYSDBA 状態確認全ケース
ALTER DATABASE OPENMOUNT で停止
ALTER PLUGGABLE DATABASE OPENPDB MOUNTED
STARTUP FORCE停止中スタック
自動起動 Trigger / SAVE STATE予防

接続系エラー 7 種

エラー意味
ORA-12541Listener 未起動
ORA-12154TNS 名前解決失敗
ORA-12514Service 未登録
ORA-12170接続タイムアウト
ORA-01034DB 完全停止
ORA-01033DB 遷移中 ← 本記事
ORA-01109DB not open
ORA-01017認証失敗

詳細は以下で解説します。


Oracle STARTUP/SHUTDOWN の仕組み

STARTUP の 3 段階詳解

1. NOMOUNT
   - SGA(メモリ)確保
   - バックグラウンドプロセス起動(PMON, SMON, DBWR 等)
   - init.ora / spfile 読み込み
   
   → 一般ユーザー接続不可(ORA-01033)
   → SYSDBA のみ可

2. MOUNT
   - コントロールファイル読み取り
   - データファイル/REDO ログの情報取得
   - lk<SID> 排他ロック取得
   
   → 一般ユーザー接続不可(ORA-01033)
   → SYSDBA のみ可

3. OPEN
   - データファイル open
   - REDO ログ open
   - リカバリ実行(必要なら)
   - service_names 登録
   
   → 一般ユーザー接続可能

SHUTDOWN の 4 種類

NORMAL(デフォルト):

- 新規接続禁止
- 既存接続完了待ち
- 全接続終了後シャットダウン
- 最も安全、時間かかる

IMMEDIATE(推奨):

- 新規接続禁止
- 既存 SQL 中断
- 未 COMMIT トランザクションロールバック
- Instance recovery 不要

TRANSACTIONAL:

- 新規接続禁止
- 現行トランザクション完了待ち
- その後 IMMEDIATE と同じ

ABORT(緊急のみ):

- 即座にプロセス停止
- Instance recovery 必要
- 最終手段

PDB の open_mode(12c+)

SELECT name, open_mode, restricted FROM v$pdbs;

NAME       OPEN_MODE     RESTRICTED
---------- ------------- ----------
PDB$SEED   READ ONLY     NO
PDB1       MOUNTED       ---        ← 未 OPEN、ORA-01033 発生
PDB2       READ WRITE    NO         ← OPEN、接続可能
PDB3       READ ONLY     NO         ← 読み取り専用

【原因①】DB 起動中(NOMOUNT/MOUNT)

シナリオ

1. DBA が STARTUP 実行中
2. NOMOUNT フェーズ完了
3. MOUNT フェーズ実行中
4. アプリユーザーが接続試行
5. → ORA-01033

診断

$ sqlplus / as sysdba
SQL> SELECT status FROM v$instance;
-- STARTED (NOMOUNT)
-- MOUNTED
-- OPEN

解決

A. OPEN まで待機(自動遷移中なら)。

B. 手動遷移:

-- NOMOUNT → MOUNT
SQL> ALTER DATABASE MOUNT;

-- MOUNT → OPEN
SQL> ALTER DATABASE OPEN;

【原因②】PDB MOUNTED 状態(12c+、最頻出)

症状(超典型)

# CDB は OPEN
$ sqlplus scott/tiger@localhost:1521/pdb1
ERROR:
ORA-01033: ORACLE initialization or shutdown in progress

診断

$ sqlplus / as sysdba
SQL> SELECT name, open_mode FROM v$pdbs;

NAME       OPEN_MODE
---------- ----------
PDB$SEED   READ ONLY
PDB1       MOUNTED     ← ここが問題

解決

A. 手動 OPEN:

SQL> ALTER PLUGGABLE DATABASE pdb1 OPEN;

-- 全 PDB OPEN
SQL> ALTER PLUGGABLE DATABASE ALL OPEN;

B. 自動起動設定(19c+ 推奨):

-- PDB を SAVE STATE
SQL> ALTER PLUGGABLE DATABASE pdb1 SAVE STATE;

-- 全 PDB
SQL> ALTER PLUGGABLE DATABASE ALL SAVE STATE;

C. 起動 Trigger(12c/18c):

CREATE OR REPLACE TRIGGER open_pdbs 
  AFTER STARTUP ON DATABASE
BEGIN
  EXECUTE IMMEDIATE 'ALTER PLUGGABLE DATABASE ALL OPEN';
END;
/

PDB 関連は ORA-12514: TNS listener does not know service の記事も参照してください。


【原因③】DB シャットダウン中

シナリオ

1. DBA が SHUTDOWN IMMEDIATE 実行
2. 既存接続の切断中
3. アプリが接続試行
4. → ORA-01033

診断

$ sqlplus / as sysdba
SQL> SELECT status FROM v$instance;
-- 該当 SQL 自体が失敗する場合あり

解決

A. SHUTDOWN 完了まで待機B. 完了後 STARTUP:

SQL> STARTUP;

【原因④】MEDIA RECOVERY 実行中

シナリオ

1. 障害後の復旧作業
2. RECOVER DATABASE 実行中
3. アーカイブログ適用中
4. アプリ接続 → ORA-01033

診断

SQL> SELECT * FROM v$recover_file;
SQL> SELECT * FROM v$recovery_progress;

解決

リカバリ完了まで待機完了後 OPEN:

SQL> ALTER DATABASE OPEN;

Recovery 関連は ORA-00376: file cannot be read の記事、ORA-01578: data block corrupted の記事も参照してください。


【原因⑤】Instance Recovery(前回 ABORT)

シナリオ

1. 前回 SHUTDOWN ABORT or クラッシュ
2. 再起動時に自動 Instance Recovery
3. SMON プロセスが実行
4. 接続 → ORA-01033

診断

alert.log 確認:

Instance recovery: looking for dead threads
Instance recovery: starting recovery from log sequence #123
Instance recovery: completed

解決

Instance Recovery 完了まで待機、通常自動。


【原因⑥】RAC ノード起動中

シナリオ(実例)

RAC で 2 ノード運用
1. ノード 1 起動完了、Listener に service 登録
2. ノード 2 起動中(MOUNT 段階)
3. ノード 2 の Listener には service あり(前回残存)
4. クライアントが Load Balance でノード 2 に接続
5. → ORA-01033

解決

A. ノード起動完了待ちB. 特定ノード指定(一時的):

tnsnames.ora:
ORCL =
  (DESCRIPTION =
    (ADDRESS = (HOST=node1)(PORT=1521))   ← 特定ノードのみ
    (CONNECT_DATA = (SERVICE_NAME=orcl))
  )

【原因⑦】Startup Trigger 実行中

シナリオ

CREATE OR REPLACE TRIGGER after_startup
  AFTER STARTUP ON DATABASE
BEGIN
  -- 重い処理(例: PDB 全 OPEN + 統計収集)
  EXECUTE IMMEDIATE 'ALTER PLUGGABLE DATABASE ALL OPEN';
  DBMS_STATS.gather_database_stats;   -- 遅い!
END;
/

-- STARTUP 後、Trigger 実行中に接続 → ORA-01033

解決

A. Trigger 軽量化(重い処理を分離)。 B. Trigger 実行完了待ち


【原因⑧】STARTUP 失敗中途

シナリオ

SQL> STARTUP;
ORACLE instance started.
Total System Global Area 5000000000 bytes
...
ORA-00821: Specified value of sga_target is too small
-- MOUNT や OPEN に到達せず、NOMOUNT で停止

-- アプリ接続 → ORA-01033

解決

STARTUP FORCE で再試行:

SQL> STARTUP FORCE;

-- または SHUTDOWN + パラメータ修正 + STARTUP
SQL> SHUTDOWN ABORT;
-- パラメータ修正
SQL> STARTUP;

DB 起動関連は ORA-01102: cannot mount database in EXCLUSIVE mode の記事も参照してください。


【原因⑨】Standby DB リカバリ中

シナリオ

Data Guard 環境:

Primary: 通常稼働
Standby: MOUNT 状態でリカバリ実行中

Standby へアプリ接続 → ORA-01033

解決

A. Primary へ接続(read-write 用途)。 B. Active Data Guard 有効化(read-only 可能):

-- Standby で
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
ALTER DATABASE OPEN READ ONLY;
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE 
  USING CURRENT LOGFILE DISCONNECT;

【原因⑩】前回異常終了(クラッシュリカバリ)

シナリオ

1. 電源断 or OS crash
2. Oracle 異常終了
3. 再起動
4. SMON が Instance Recovery 実行
5. リカバリ完了まで数分〜数十分
6. その間 ORA-01033

解決

リカバリ完了待ち、alert.log で進捗確認。


診断ツール完全リファレンス

V$INSTANCE

SELECT instance_name, status, database_status, active_state
FROM v$instance;

-- STATUS:
-- STARTED (NOMOUNT)
-- MOUNTED
-- OPEN
-- OPEN MIGRATE

V$DATABASE

SELECT name, open_mode, log_mode, database_role
FROM v$database;

-- OPEN_MODE:
-- READ WRITE (通常)
-- READ ONLY
-- MOUNTED

V$PDBS(12c+)

SELECT name, open_mode, restricted, open_time
FROM v$pdbs;

-- OPEN_MODE:
-- READ WRITE (通常)
-- READ ONLY
-- MOUNTED (ORA-01033 原因)
-- MIGRATE

V$RECOVERY_PROGRESS

SELECT type, item, units, sofar, total
FROM v$recovery_progress;
-- リカバリ進捗確認

alert.log

$ tail -200 $ORACLE_BASE/diag/rdbms/*/*/trace/alert_*.log

V$SESSION

SELECT COUNT(*) FROM v$session WHERE type = 'USER';
-- 接続数確認

6つの解決策 完全リファレンス

解決策① 待機

多くの場合、数分待てば自動解決:

# 1 分待ってリトライ
sleep 60
sqlplus scott/tiger@ORCL

解決策② SYSDBA で状態確認

$ sqlplus / as sysdba

SQL> SELECT status FROM v$instance;
SQL> SELECT open_mode FROM v$database;
SQL> SELECT name, open_mode FROM v$pdbs;

解決策③ ALTER DATABASE OPEN

-- MOUNT で停止している場合
SQL> ALTER DATABASE OPEN;

-- Recovery 必要な場合
SQL> RECOVER DATABASE;
SQL> ALTER DATABASE OPEN;

解決策④ ALTER PLUGGABLE DATABASE OPEN

-- 特定 PDB
SQL> ALTER PLUGGABLE DATABASE pdb1 OPEN;

-- 全 PDB
SQL> ALTER PLUGGABLE DATABASE ALL OPEN;

-- 自動起動保存(19c+ 推奨)
SQL> ALTER PLUGGABLE DATABASE pdb1 SAVE STATE;

解決策⑤ STARTUP FORCE

-- 停止中スタック
SQL> STARTUP FORCE;
-- 実質: SHUTDOWN ABORT + STARTUP

-- ⚠️ 業務中は慎重に、Instance Recovery 発生

解決策⑥ 自動起動 Trigger(12c/18c、19c は SAVE STATE 推奨)

CREATE OR REPLACE TRIGGER open_pdbs 
  AFTER STARTUP ON DATABASE
BEGIN
  EXECUTE IMMEDIATE 'ALTER PLUGGABLE DATABASE ALL OPEN';
END;
/

19c+ では SAVE STATE:

ALTER PLUGGABLE DATABASE ALL OPEN;
ALTER PLUGGABLE DATABASE ALL SAVE STATE;
-- 次回 CDB 起動時に自動 OPEN

Rails / Java / Python 対応

Rails ActiveRecord

リトライロジック:

module OracleStartupRetry
  MAX_RETRIES = 10
  RETRY_INTERVAL = 30  # 秒
  
  def self.with_retry
    retries = 0
    begin
      yield
    rescue ActiveRecord::StatementInvalid => e
      if startup_in_progress?(e) && retries < MAX_RETRIES
        retries += 1
        Rails.logger.warn "DB starting up, retry #{retries}/#{MAX_RETRIES}"
        sleep(RETRY_INTERVAL)
        retry
      end
      raise
    end
  end
  
  def self.startup_in_progress?(e)
    e.message.include?("ORA-01033") ||
      e.message.include?("ORA-01034") ||
      e.message.include?("ORA-01109")
  end
end

起動時ヘルスチェック:

class DatabaseStartupCheck
  def self.wait_for_ready(timeout: 300)
    Timeout.timeout(timeout) do
      loop do
        begin
          ActiveRecord::Base.connection.execute("SELECT 1 FROM DUAL")
          Rails.logger.info "DB ready"
          return
        rescue ActiveRecord::StatementInvalid => e
          if e.message.include?("ORA-01033")
            Rails.logger.info "DB starting up, waiting..."
            sleep 10
          else
            raise
          end
        end
      end
    end
  end
end

Rails 8 系の詳細は Rails 8 アップグレードガイドの記事も参照してください。

Java (JDBC)

public class OracleConnectionRetry {
    private static final int MAX_RETRIES = 10;
    private static final int RETRY_INTERVAL = 30_000; // ms
    
    public static Connection getConnection(String url, String user, String pw) 
            throws SQLException {
        for (int i = 0; i < MAX_RETRIES; i++) {
            try {
                return DriverManager.getConnection(url, user, pw);
            } catch (SQLException e) {
                if (e.getErrorCode() == 1033 && i < MAX_RETRIES - 1) {
                    logger.warn("DB starting up, retry " + (i + 1));
                    Thread.sleep(RETRY_INTERVAL);
                    continue;
                }
                throw e;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new SQLException("Interrupted", e);
            }
        }
        throw new SQLException("Max retries exceeded");
    }
}

Python (oracledb)

import oracledb
import time
import logging

def connect_with_retry(dsn, user, pw, max_retries=10, retry_interval=30):
    for attempt in range(max_retries):
        try:
            return oracledb.connect(user=user, password=pw, dsn=dsn)
        except oracledb.DatabaseError as e:
            error_obj, = e.args
            if error_obj.code == 1033 and attempt < max_retries - 1:
                logging.warning(f"DB starting up, retry {attempt + 1}")
                time.sleep(retry_interval)
                continue
            raise
    raise Exception("Max retries exceeded")

実践シナリオ

シナリオ1:本番起動確認

# 1. SYSDBA 接続
$ sqlplus / as sysdba

# 2. インスタンス状態
SQL> SELECT status FROM v$instance;

# 3. DB 状態
SQL> SELECT open_mode FROM v$database;

# 4. PDB 状態
SQL> SELECT name, open_mode FROM v$pdbs;

# 5. 必要に応じて対処
SQL> ALTER DATABASE OPEN;
SQL> ALTER PLUGGABLE DATABASE ALL OPEN;

シナリオ2:PDB 自動起動設定(19c+)

-- 1. 全 PDB OPEN
SQL> ALTER PLUGGABLE DATABASE ALL OPEN;

-- 2. 状態保存
SQL> ALTER PLUGGABLE DATABASE ALL SAVE STATE;

-- 3. 確認
SQL> SELECT con_name, instance_name, state 
     FROM dba_pdb_saved_states;

-- 4. CDB 再起動テスト
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP;

-- 5. PDB が自動 OPEN されているか
SQL> SELECT name, open_mode FROM v$pdbs;

シナリオ3:12c での起動 Trigger

-- 12c/18c 向け(19c 以前)
CREATE OR REPLACE TRIGGER open_all_pdbs 
  AFTER STARTUP ON DATABASE
BEGIN
  EXECUTE IMMEDIATE 'ALTER PLUGGABLE DATABASE ALL OPEN';
EXCEPTION
  WHEN OTHERS THEN
    -- ログに記録、失敗しても STARTUP 継続
    DBMS_OUTPUT.PUT_LINE('Failed to open PDBs: ' || SQLERRM);
END;
/

-- Trigger 確認
SELECT trigger_name, status, triggering_event
FROM dba_triggers
WHERE trigger_name = 'OPEN_ALL_PDBS';

シナリオ4:Rails 起動シーケンス

# config/initializers/database_wait.rb
Rails.application.config.after_initialize do
  if Rails.env.production?
    DatabaseStartupCheck.wait_for_ready(timeout: 300)
  end
end

シナリオ5:Docker Compose 依存管理

services:
  oracle:
    image: gvenzl/oracle-xe:21-slim
    healthcheck:
      test: ["CMD", "sqlplus", "-L", "sys/pw@//localhost/XEPDB1 as sysdba", "@healthcheck.sql"]
      interval: 10s
      retries: 30
  
  app:
    depends_on:
      oracle:
        condition: service_healthy

Docker 関連は docker daemon 接続エラーの記事、Docker no space left on device の記事も参照してください。

シナリオ6:STARTUP FORCE で停止中スタック解消

-- 停止中でスタック
SQL> SHUTDOWN IMMEDIATE;
-- 応答なし

-- 強制対処
SQL> SHUTDOWN ABORT;
SQL> STARTUP;

-- または一発
SQL> STARTUP FORCE;

DB 起動関連は ORA-01102: cannot mount database in EXCLUSIVE mode の記事も参照してください。

シナリオ7:Standby DB リカバリ

-- Data Guard 環境
-- Primary で
SQL> SELECT database_role, open_mode FROM v$database;
-- PRIMARY, READ WRITE

-- Standby で
SQL> SELECT database_role, open_mode FROM v$database;
-- PHYSICAL STANDBY, MOUNTED

-- Active Data Guard 有効化
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
SQL> ALTER DATABASE OPEN READ ONLY;
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE 
     USING CURRENT LOGFILE DISCONNECT;

シナリオ8:Kubernetes での対応

apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      initContainers:
      - name: wait-for-db
        image: my-app:latest
        command: ['sh', '-c', 'until sqlplus -s scott/tiger@oracle:1521/pdb1 <<< "SELECT 1 FROM DUAL;" | grep -q "SELECTED"; do echo waiting; sleep 10; done']
      containers:
      - name: app
        image: my-app:latest

シナリオ9:Python 監視スクリプト

import oracledb
import time
import logging
from datetime import datetime, timedelta

def wait_for_db_open(dsn, user, pw, timeout=300):
    start = datetime.now()
    while (datetime.now() - start) < timedelta(seconds=timeout):
        try:
            with oracledb.connect(user=user, password=pw, dsn=dsn) as conn:
                cursor = conn.cursor()
                cursor.execute("SELECT 1 FROM DUAL")
                logging.info("DB is open")
                return True
        except oracledb.DatabaseError as e:
            error_obj, = e.args
            if error_obj.code == 1033:
                logging.info("DB starting up, waiting...")
                time.sleep(10)
            else:
                logging.error(f"Unexpected error: {error_obj.message}")
                raise
    logging.error(f"Timeout after {timeout}s")
    return False

シナリオ10:Autonomous DB での対応

Autonomous DB は Oracle 管理
- 通常 ORA-01033 発生しない
- メンテナンスウィンドウ中のみ
- Oracle Cloud Console で状態確認
- OCI CLI: oci db autonomous-database get

トラブルシューティング

数分待っても解消しない

SYSDBA で状態確認、MOUNTED なら手動 OPEN。

PDB が SAVE STATE できない

19c+ で使用可能、18c 以前は Trigger 使用。

RAC で断続的

Load Balance 除外、特定ノード指定で回避。

STARTUP FORCE の副作用

Instance Recovery 実行、業務中は影響大。

起動 Trigger 実行が遅い

Trigger 軽量化、重い処理は分離。

PostgreSQL からの移行

PG は pg_ctl start シンプル、Oracle は 3 段階起動 + PDB。


よくある質問(FAQ)

Q1. ORA-01033 と ORA-01034 の違い

  • 01033: DB 起動中/停止中(遷移状態)
  • 01034: DB 完全停止

Q2. ORA-01109 との違い

  • 01109: database not open(MOUNTED 状態明示)
  • 01033: 起動/停止プロセス中

Q3. PDB MOUNTED を防ぐには

19c+: SAVE STATE18c 以前: Trigger

Q4. STARTUP の 3 段階

NOMOUNT → MOUNT → OPEN

Q5. SHUTDOWN の推奨

IMMEDIATE が実用的、NORMAL は時間かかる。

Q6. STARTUP FORCE のリスク

SHUTDOWN ABORT + STARTUP、Instance Recovery。

Q7. Rails での対応

リトライロジック + 起動待機

Q8. Java での対応

errorCode == 1033 + リトライ。

Q9. Python での対応

oracledb.DatabaseError.code + リトライ。

Q10. RAC での対応

Load Balance で他ノード試行、リトライ。

Q11. Autonomous DB での挙動

通常発生しない、メンテナンス中のみ。

Q12. 予防策

  • PDB SAVE STATE 設定
  • リトライロジック実装
  • Docker/K8s ヘルスチェック
  • 監視スクリプト

参考リンク

Oracle 公式


まとめ

ORA-01033: ORACLE initialization or shutdown in progress の要点を再整理します。

エラーの本質

DB は動いているが利用可能状態ではない
→ 起動プロセス中(NOMOUNT/MOUNT)
→ 停止プロセス中
→ PDB MOUNTED(12c+ 頻出)
→ Recovery 実行中
→ 待機 or 手動 OPEN で解決

エラーメッセージの読み方

ORA-01033: ORACLE initialization or shutdown in progress
                    ↑                       ↑
             起動プロセス中          停止プロセス中

SYSDBA なら接続可能、一般ユーザーは待機必要

接続系エラー 7 種

エラー意味
ORA-12541Listener 未起動
ORA-12154TNS 名前解決失敗
ORA-12514Service 未登録
ORA-12170接続タイムアウト
ORA-01034DB 完全停止
ORA-01033DB 遷移中
ORA-01109DB not open
ORA-01017認証失敗

STARTUP の 3 段階

NOMOUNT: メモリ + プロセス起動
   ↓
MOUNT:   コントロールファイル読み取り
   ↓
OPEN:    一般ユーザー接続可能

SHUTDOWN の 4 種類

種類特徴
NORMAL既存接続完了待ち
IMMEDIATE即座切断(推奨)
TRANSACTIONAL現行TX 完了待ち
ABORT強制(Recovery 必要)

10大原因

#原因対処
DB 起動中待機 or OPEN
PDB MOUNTEDALTER PLUGGABLE OPEN
DB シャットダウン中待機
MEDIA RECOVERY待機
Instance Recovery待機
RAC ノード起動中別ノード
Startup Trigger軽量化
STARTUP 失敗STARTUP FORCE
Standby DBADG 有効化
前回異常終了待機

6つの解決策

# ① 待機
sleep 60
-- ② SYSDBA 状態確認
sqlplus / as sysdba
SELECT status FROM v$instance;
SELECT name, open_mode FROM v$pdbs;

-- ③ ALTER DATABASE OPEN
ALTER DATABASE OPEN;

-- ④ ALTER PLUGGABLE DATABASE OPEN
ALTER PLUGGABLE DATABASE ALL OPEN;

-- ⑤ STARTUP FORCE
STARTUP FORCE;

-- ⑥ 自動起動保存(19c+)
ALTER PLUGGABLE DATABASE ALL SAVE STATE;

PDB 自動起動(19c+ 推奨)

-- 1. 全 PDB OPEN
ALTER PLUGGABLE DATABASE ALL OPEN;

-- 2. 状態保存
ALTER PLUGGABLE DATABASE ALL SAVE STATE;

-- 3. 確認
SELECT con_name, state FROM dba_pdb_saved_states;

-- 次回 CDB 起動時に自動 OPEN

各言語での対応

Rails:  リトライロジック(30 秒間隔 x 10 回)
Java:   errorCode == 1033 + Thread.sleep
Python: oracledb.DatabaseError.code + time.sleep
共通:   起動待機ヘルパー、Docker/K8s ヘルスチェック

予防のポイント

1. PDB は SAVE STATE で自動起動
2. リトライロジック実装
3. Docker/K8s ヘルスチェック設定
4. 監視スクリプト
5. アプリ起動時の DB 待機
6. Standby DB は ADG 有効化
7. 起動 Trigger 軽量化
8. STARTUP FORCE は最終手段
9. Autonomous DB では通常発生しない
10. 定期的な alert.log 確認

これらの知識は、Oracle DBA の本番運用・障害対応・PDB 管理・Rails / Java / Python アプリ運用・Docker/Kubernetes デプロイ・Autonomous DB 運用・Data Guard 環境・RAC 運用など、あらゆる場面で活用できます。本記事をブックマークしておけば、ORA-01033 に出会っても冷静に的確に対処できるようになります。


本記事は2026年6月時点の情報をもとに、Oracle Database 19c〜26ai での動作確認・公式ドキュメントに基づき作成しています。Oracle のバージョンにより挙動が異なる場合があるため、最新の情報は Oracle 公式ドキュメント(docs.oracle.com)もあわせてご確認ください。