16
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Oracle Database 疎通確認したときのあれこれ

16
Posted at

はじめに

Oracle Databaseへの疎通確認でよく遭遇する「Connection reset by peer」エラーの原因と対処法について、実際のトラブルシューティング経験を基にまとめました。
最近のAIは本当に優秀なのでコーディングのほとんどは生成したもので事足りました。自分で確認する必要があったのは接続情報の確認くらいでした

よくあるエラーパターン

1. Connection reset by peer

java.sql.SQLRecoverableException: IO Error: Connection reset by peer, connect lapse 10 ms., Authentication lapse 0 ms.

原因: ネットワーク接続は成功しているが、JDBC接続URLのサービス名/SIDが正しくない

2. Connection timed out

java.sql.SQLRecoverableException: IO Error: The Network Adapter could not establish the connection

原因: ネットワーク接続の問題(IPアドレス、ポート、ファイアウォール)

3. ORA-01017: ユーザー名/パスワードが無効

原因: 認証情報が正しくない

疎通確認に必要な情報

必須情報

  • IPアドレス: データベースサーバのIPアドレス
  • ポート番号: 通常は1521(デフォルト)または1522
  • サービス名: (SERVICE_NAME)またはSID
  • ユーザー名: 接続するスキーマ名
  • パスワード: 接続するスキーマのパスワード

接続情報の確認方法

1. サーバ上でリスナーの状態を確認

lsnrctl status

出力例:

Service "ORCL" has 1 instance(s).
Service "ORCLPDB1" has 1 instance(s).

2. tnsnames.oraを確認

cat $ORACLE_HOME/network/admin/tnsnames.ora

出力例:

ORCL =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = xxx.xxx.xxx.xxx)(PORT = 1522))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = ORCL)
    )
  )

3. SQLPlusで確認

-- インスタンス名を確認
SELECT INSTANCE_NAME FROM V$INSTANCE;

-- データベース名を確認
SELECT NAME FROM V$DATABASE;

-- サービス名を確認
SELECT NAME FROM V$SERVICES;

JDBC接続URLの形式

サービス名形式

jdbc:oracle:thin:@IPアドレス:ポート/サービス名
例: jdbc:oracle:thin:@192.168.1.100:1522/ORCL

SID形式

jdbc:oracle:thin:@IPアドレス:ポート:SID
例: jdbc:oracle:thin:@192.168.1.100:1522:ORCL

疎通確認用Javaツールの作成

基本的な疎通確認ツール

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class OracleConnectionChecker {
    
    // 接続情報(実際の値に変更)
    private static final String IP = "xxx.xxx.xxx.xxx";
    private static final String PORT = "1522";
    private static final String SERVICE_NAME = "ORCL";
    private static final String USERNAME = "your_schema";
    private static final String PASSWORD = "your_password";
    
    // 疎通確認用SQL
    private static final String TEST_SQL = 
        "SELECT 'Connection OK' as status FROM DUAL";
    
    public static void main(String[] args) {
        String jdbcUrl = String.format("jdbc:oracle:thin:@%s:%s/%s", 
            IP, PORT, SERVICE_NAME);
        
        System.out.println("接続先: " + jdbcUrl);
        
        try (Connection conn = DriverManager.getConnection(jdbcUrl, USERNAME, PASSWORD);
             PreparedStatement pstmt = conn.prepareStatement(TEST_SQL);
             ResultSet rs = pstmt.executeQuery()) {
            
            System.out.println("✓ 接続成功!");
            
            if (rs.next()) {
                System.out.println("結果: " + rs.getString("status"));
            }
            
        } catch (SQLException e) {
            System.err.println("✗ 接続失敗");
            System.err.println("エラー: " + e.getMessage());
        }
    }
}

複数パターンを自動試行するツール

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;

public class OracleConnectionTester {
    
    private static final String IP = "xxx.xxx.xxx.xxx";
    private static final String PORT = "1522";
    private static final String USERNAME = "your_schema";
    private static final String PASSWORD = "your_password";
    
    // よくあるサービス名/SIDのパターン
    private static final List<String> SERVICE_PATTERNS = Arrays.asList(
        "ORCL", "orcl",
        "XE", "xe",
        "ORCLPDB1", "ORCLCDB",
        "your_schema",  // スキーマ名と同じ場合もある
        "PROD", "DEV", "TEST"
    );
    
    public static void main(String[] args) {
        System.out.println("複数の接続パターンを試行します...");
        
        // サービス名形式を試行
        for (String serviceName : SERVICE_PATTERNS) {
            String jdbcUrl = String.format("jdbc:oracle:thin:@%s:%s/%s", 
                IP, PORT, serviceName);
            
            if (testConnection(jdbcUrl, USERNAME, PASSWORD)) {
                System.out.println("✓ 接続成功!");
                System.out.println("正しいサービス名: " + serviceName);
                System.out.println("JDBC URL: " + jdbcUrl);
                return;
            }
        }
        
        // SID形式を試行
        for (String sid : SERVICE_PATTERNS) {
            String jdbcUrl = String.format("jdbc:oracle:thin:@%s:%s:%s", 
                IP, PORT, sid);
            
            if (testConnection(jdbcUrl, USERNAME, PASSWORD)) {
                System.out.println("✓ 接続成功!");
                System.out.println("正しいSID: " + sid);
                System.out.println("JDBC URL: " + jdbcUrl);
                return;
            }
        }
        
        System.out.println("✗ すべてのパターンで接続失敗");
    }
    
    private static boolean testConnection(String jdbcUrl, String username, String password) {
        System.out.print("試行: " + jdbcUrl + " ... ");
        
        try (Connection conn = DriverManager.getConnection(jdbcUrl, username, password)) {
            System.out.println("成功");
            return true;
        } catch (SQLException e) {
            System.out.println("失敗");
            return false;
        }
    }
}

Maven設定(pom.xml)

<dependencies>
    <!-- Oracle JDBC Driver -->
    <dependency>
        <groupId>com.oracle.database.jdbc</groupId>
        <artifactId>ojdbc8</artifactId>
        <version>21.9.0.0</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <!-- 実行可能JARを作成 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.5.1</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <transformers>
                            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <mainClass>OracleConnectionChecker</mainClass>
                            </transformer>
                        </transformers>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

トラブルシューティングの手順

1. ネットワーク疎通の確認

# pingで疎通確認
ping xxx.xxx.xxx.xxx

# ポートの疎通確認
telnet xxx.xxx.xxx.xxx 1522

2. ファイアウォール設定の確認

  • サーバ側のファイアウォールでOracleポートが開放されているか
  • クライアント側のファイアウォールでアウトバウンド接続が許可されているか

3. Oracleリスナーの状態確認

# リスナーの状態確認
lsnrctl status

# リスナーの起動(必要に応じて)
lsnrctl start

4. 接続文字列の検証

  • サービス名/SIDが正しいか
  • 接続形式(サービス名形式 vs SID形式)が適切か
  • 大文字小文字が正しいか

よくあるサービス名のパターン

デフォルトパターン

  • ORCL - 一般的なOracle Database
  • XE - Oracle Express Edition
  • ORCLPDB1 - Pluggable Database(デフォルト)
  • ORCLCDB - Container Database

カスタムパターン

  • プロジェクト名や環境名(例: MYAPP_PROD, DEV_DB
  • スキーマ名と同じ名前
  • 会社名やシステム名を含む名前

まとめ

  1. ネットワーク疎通 → ping、telnetで確認
  2. サービス名/SID → lsnrctl status、tnsnames.oraで確認
  3. 接続文字列 → サービス名形式またはSID形式で試行
  4. 認証情報 → ユーザー名/パスワードの確認

参考リンク


16
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?