この記事では、主に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分離レベルでトランザクション並行競合が発生した場合に起こる可能性があります。 トランザクション分離レベルの詳細については、トランザクション分離レベルの概要を参照してください。 |
失敗 | 変更なし | ポリシー2 |
| 8001 〜 8004 | 08004 | 接続を回復できません | 失敗 | 不明 | ポリシー4 |
MySQL互換エラーコード
エラーコード値が4000以下のMySQLデータベース互換エラーコードについては、MySQLデータベースと同じ処理方法を遵守してください。特に、アプリケーションプログラムは以下のエラーコードに注意する必要があります。
| エラーコード | SQLSTATE | 意味 | 処理ポリシー |
|---|---|---|---|
| 1205 | HY000 | デッドロックが検出されました | 現在のトランザクションをロールバックしてリトライします |
| 1213 | 40001 | ロック待機でタイムアウトが発生しました | 現在のトランザクションをロールバックしてリトライします |