このセクションでは、MySQL互換アプリケーションのエラー処理規範について説明します。
OceanBaseデータベースはV1.0バージョンからMySQLデータベースとの完全な互換性を提供しています。エラーコードについては、エラーコード、SQLSTATE、エラーメッセージの3つの情報においてMySQLデータベースとの一貫性を可能な限り保証しています。そのため、当社の製品設計原則に基づき、アプリケーションのエラー処理方法はMySQLデータベースの処理規範を参考にすることができます。ただし、分散データベースとして、OceanBaseデータベースはスタンドアロンのMySQLデータベースとは本質的に異なり、分散環境特有の一部のエラーはMySQLデータベースのエラーコードでは表現できません。一般的に、エラーコードの値が4000を超える場合、そのエラーコードはOceanBaseデータベース固有のエラーコードであることを意味します。エラーコードの値が4000以下の場合、それはMySQLデータベースと互換のエラーコードであることを意味します。OceanBaseデータベースサーバー側のMySQLテナントモードにおける完全なエラーコードリストについては、エラー情報の概要を参照してください。
アプリケーションプログラムが検出するエラーは、データベースサーバー側から返されるエラーの他に、ドライバーライブラリがローカルで返すエラー(例:データベース接続の確立失敗)も含まれる場合があります。OceanBaseデータベースのMySQLテナントを使用するアプリケーションはMySQLのドライバーライブラリ(例:MySQL JDBC Driver)を使用できるため、このようなエラーコードについては、OceanBaseデータベースはMySQLデータベースと完全に互換性があります。この種のクライアントエラーコードの値域は通常2000~3000です。
エラー情報の取得
各言語のドライバーは、エラー情報を取得するための異なるAPIを提供しています。各ドライバーの詳細については、OceanBaseデータベース公式ドキュメントおよびMySQLデータベース公式ドキュメントを参照してください。
Javaドライバーライブラリ
JDBCを使用するJavaアプリケーションがSQLステートメントの実行に失敗した場合、SQLException例外をキャッチできます。この例外には、エラーコード、SQLSTATE、エラーメッセージの3種類の情報が含まれています。SQLException例外の詳細については、JDBC APIドキュメントを参照してください。
SQLException例外をキャッチする方法は以下のとおりです:
- getErrorCode() を呼び出してエラーコードを取得する
- getSQLState() を呼び出してSQLSTATEを取得する
- getMessage() を呼び出してエラーメッセージを取得する
libmysql Cドライバーライブラリ
libmysqlを使用するC言語アプリケーションがSQLステートメントの実行に失敗した場合、以下の方法でエラー情報を取得できます:
- mysql_errno() を呼び出してエラーコードを取得する
- mysql_sqlstate() を呼び出してSQLSTATEを取得する
- mysql_error() を呼び出してエラーメッセージを取得する
エラー処理の規範
OceanBaseデータベースのMySQLテナントモードにおけるほとんどのエラーコードについて、アプリケーションは特別な処理を行う必要がなく、直接外部にエラーを報告できます。フォールトトレランスとアプリケーションの堅牢性を高めるため、特定のエラーコードについては、異なるシナリオやエラーの性質に応じて、以下の4つの異なる戦略を採用できます:
戦略1:ステートメントのタイプに基づいて処理します。
SELECTステートメントの実行時にタイムアウトエラーが発生した場合、副作用がないため、再試行できます。リモートまたは分散実行による
UPDATEなどの変更ステートメントでタイムアウトエラーが発生した場合、ステートメントが実際に実行されたかどうかは不確定であるため、トランザクションをロールバックする必要があります(変更ステートメントのセマンティクスが冪等である場合、そのステートメントの再試行を試みることができます)。COMMITまたはROLLBACKステートメントの実行時にタイムアウトエラーが発生した場合、トランザクションの状態が不明であるため、直接外部にエラーを報告する必要があります。
戦略2:任意のステートメント実行でエラーが発生した場合、現在のトランザクションをロールバックしてから、トランザクションを再試行します。
戦略3:任意のステートメント実行でエラーが発生した場合、現在のステートメントを再試行します。
戦略4:任意のステートメント実行でエラーが発生した場合、現在の接続を閉じてから、接続を再確立します。
OceanBaseデータベース固有のエラーコード
以下のエラーコードは、一般的なOceanBaseデータベースサーバー固有のランタイム例外のエラーコードです。下表の異なるタイプのエラーコードに基づき、アプリケーションは「処理ポリシー」の推奨に従って処理できます。
エラーコード |
SQLSTATE |
説明 |
ステートメントの実行結果 |
トランザクションステータス |
対処方法 |
|---|---|---|---|---|---|
| 4012 | HY000 | 実行タイムアウト | 不明 | 不明 | ポリシー1 |
| 4038 | HY000 | 現在のレプリカがプライマリレプリカではないため、サービスを提供できません。一般的にレプリカのプライマリ切り替え時に発生する可能性があります。 | 失敗 | 不変 | ポリシー3 |
| 4138 | HY000 | 読み取ったスナップショットバージョンが古すぎます | 失敗 | 不変 | ポリシー3 |
| 4225 | HY000 | パーティションが存在しません。一般的にパーティション移行時に発生する可能性があります。 | 失敗 | 不変 | ポリシー3 |
| 6002 | 40000 | トランザクションがシステム内部でロールバックされました | 失敗 | ロールバック済み | ポリシー2 |
| 6231 | HY000 | レプリカデータが読み取り不可です。一般的にレプリカ移行時に発生する可能性があります。 | 失敗 | 不変 | ポリシー3 |
| 6235 | 25000 | 現在のトランザクションを直列化できません。一般的にRR(Repeatable Read)およびSerializable分離レベルでトランザクションの並行競合が発生した場合に起こる可能性があります。 トランザクション分離レベルの詳細については、トランザクション分離レベルの概要を参照してください。 |
失敗 | 不変 | ポリシー二 |
| 8001~8004 | 08004 | 接続が回復不能です | 失敗 | 不明 | ポリシー四 |
MySQL互換エラーコード
エラーコードが4000以下のMySQLデータベース互換エラーコードについては、MySQLデータベースと同じ処理方法を遵守してください。特に、アプリケーションは以下のエラーコードに注意する必要があります。
エラーコード |
SQLSTATE |
説明 |
対処方法 |
|---|---|---|---|
| 1205 | HY000 | デッドロックが検出されました | 現在のトランザクションをロールバックして再試行します |
| 1213 | 40001 | ロック待機タイムアウト | 現在のトランザクションをロールバックして再試行します |