Prisma Accelerateの問題のトラブルシューティング
Prisma Accelerateを使用する際、開発および運用中に特定のエラーコードによって強調されるエラーに遭遇することがよくあります。アプリケーションの円滑な動作を確保するためには、これらのエラーの意味、発生理由、そして解決方法を理解することが重要です。このガイドは、Prisma Accelerateで遭遇する特定のエラーコードのトラブルシューティングに関する洞察と手順を提供することを目的としています。
P6009
(ResponseSizeLimitExceeded
)
このエラーは、データベースクエリからの応答サイズが設定されたクエリ応答サイズ制限を超過したときに発生します。この制限は、複数のネットワーク層のために5MBを超えるデータ取得がアプリケーションのパフォーマンスを著しく低下させる可能性があるため、アプリケーションのパフォーマンスを保護するために実装されました。通常、5MBを超えるデータの送信は、ETL(Extract, Transform, Load)操作を実行する際によく見られます。ただし、トランザクションクエリ、ユーザーインターフェース向けのリアルタイムデータフェッチ、バルクデータ更新、ETLコンテキスト外での分析のための大規模データセットの集約など、その他のシナリオでは一般的に避けるべきです。これらのユースケースは、不可欠ではありますが、設定されたクエリ応答サイズ制限内で動作するように最適化できることが多く、よりスムーズなパフォーマンスと優れたユーザーエクスペリエンスを保証します。
[`P6009`](/docs/orm/reference/error-reference#p6009-responsesizelimitexceeded)の考えられる原因
応答における画像/ファイルの転送
このエラーは、テーブルに保存されている画像やファイルがフェッチされ、その結果、応答サイズが大きくなる場合に発生する可能性があります。アセットをデータベースに直接保存することは、データベースのパフォーマンスとスケーラビリティに大きく影響するため、一般的に推奨されません。パフォーマンスに加えて、データベースのバックアップが遅くなり、定期的なバックアップの保存コストが大幅に増加します。
推奨される解決策: クエリ応答サイズ制限を大きく設定してください。それでも制限を超える場合は、画像またはファイルを[Cloudflare R2](https://developers.cloudflare.com/r2/)、[AWS S3](https://aws.amazon.com/pm/serv-s3/)、または[Cloudinary](https://cloudinary.com/)のようなBLOBストアに保存することを検討してください。これらのサービスを使用すると、アセットを最適に保存し、アクセス用のURLを返すことができます。アセットをデータベースに直接保存する代わりに、URLを保存することで、応答サイズを大幅に削減できます。
データの過剰取得
特定の場合において、意図せず多数のレコードやフィールドが取得され、その結果、設定されたクエリ応答サイズ制限を超えることがあります。これは、クエリのwhere
句が誤っているか、完全に欠落している場合に発生する可能性があります。
推奨される解決策: クエリ応答サイズ制限を大きく設定してください。それでも制限を超える場合は、where
句が期待どおりにデータをフィルタリングしていることを再確認してください。取得するレコードが多すぎるのを防ぐために、ページネーションの使用を検討してください。さらに、応答サイズを削減するために、select
句を使用して必要なフィールドのみを返すようにしてください。
大量データの取得
多くのデータ処理ワークフロー、特にETL(Extract-Transform-Load)プロセスやスケジュールされたCRONジョブを含むものにおいては、分析、レポート作成、またはさらなる処理のためにデータソース(データベース、API、ファイルシステムなど)から大量のデータを抽出する必要があります。分析処理のために大量のデータを取得するETL/CRONワークロードを実行している場合、この制限にぶつかる可能性があります。
推奨される解決策: クエリ応答サイズ制限を大きく設定してください。制限を超える場合は、クエリをバッチに分割することを検討してください。このアプローチにより、各バッチがデータの一部のみを取得し、単一操作でのサイズ制限超過を防ぐことができます。
P6004
(QueryTimeout
)
このエラーは、データベースクエリが設定されたクエリタイムアウト制限内に応答を返さない場合に発生します。クエリタイムアウト制限には、プールからの接続待ち時間、データベースへのネットワーク遅延、およびクエリ自体の実行時間が含まれます。この制限は、システムリソースを過負荷にする意図しない長時間実行クエリを防ぐために強制されます。
Accelerateのクロスリージョンネットワークにかかる時間は、設定されたクエリタイムアウト制限から除外されます。
[`P6004`](/docs/orm/reference/error-reference#p6004-querytimeout)の考えられる原因
このエラーは、様々な原因で発生する可能性があります。主なものとしては以下のとおりです。
高トラフィックと接続不足
アプリケーションが非常に高いトラフィックを受信しており、データベースに十分な数の接続が利用できない場合、クエリは接続が利用可能になるまで待機する必要があります。この状況により、クエリが設定されたクエリタイムアウト制限よりも長く接続を待機することになり、この期間内に処理されない場合、最終的にタイムアウトエラーがトリガーされます。
推奨される解決策: プラットフォーム環境でAccelerateをセットアップする際に、接続文字列パラメーターで指定されたconnection_limit
を見直し、可能であれば増やしてください(参照)。この制限は、データベースの最大接続数と一致させる必要があります。
デフォルトでは、データベース接続文字列で異なるconnection_limit
が指定されていない限り、接続制限は10に設定されています。
長時間実行されるクエリ
クエリが応答に時間がかかり、接続が利用可能であっても設定されたクエリタイムアウト制限に達する可能性があります。これは、単一のクエリで非常に大量のデータが取得されている場合や、テーブルに適切なインデックスが不足している場合に発生する可能性があります。
推奨される解決策: クエリタイムアウト制限を大きく設定してください。制限を超える場合は、実行の遅いクエリを特定し、必要なデータのみを取得してください。select
句を使用して特定のフィールドを取得し、不要なデータを取得しないようにしてください。さらに、クエリの効率を向上させるために適切なインデックスの追加を検討してください。また、長時間実行されるクエリを別の環境に分離して、トランザクションクエリに影響を与えないようにすることもできます。
データベースのリソース競合
一般的でありながら難しい問題として、同じデータベース上で動作する他のサービスが重い分析やデータ処理タスクを実行し、データベースリソースを大幅に消費する場合があります。これらの操作はデータベース接続と処理能力を独占し、単純なクエリでさえタイムリーに実行できない状況を引き起こす可能性があります。このような「ビジー」または「ノイジー」なデータベース環境は、通常は高速なクエリが遅くなったり、タイムアウトしたりする原因となります。特に、他のサービスからのアクティビティが高い期間に発生しやすいです。
ユーザーはデータベースの負荷を測るためにCPUとメモリの使用状況メトリクスに頼ることが多いですが、これは誤解を招く可能性があります。これらは重要な指標ではありますが、データベースの運用状態を完全に表しているとは限りません。読み取り数、書き込み数、待機時間などの直接的なメトリクスは、データベースのパフォーマンスをより明確に示しており、綿密に監視する必要があります。特にクエリやデータモデルに変更がない場合にこれらのメトリクスで顕著な劣化が見られる場合、外部からの圧力がデータベースのパフォーマンスに影響を与えていることを示唆しています。
推奨される解決策: 通常は高速なクエリが、何の変更も加えていないのに断続的に遅くなったりタイムアウトしたりする場合、競合するクエリが同じデータベーステーブルに圧力をかけている可能性があります。これを診断するには、監視ツールを導入するか、データベース固有の機能を利用して、読み取り、書き込み、および待機時間を観察してください。このような監視により、観察されたパフォーマンス低下と一致するアクティビティパターンやスパイクが明らかになるでしょう。
さらに、重要なクエリを定期的に精査・改善し、テーブルが適切にインデックス化されていることを確認することが重要です。この予防的なアプローチにより、競合するワークロードによってこれらのクエリが遅延する脆弱性を最小限に抑えることができます。
[`P6009`](/docs/orm/reference/error-reference#p6009-responsesizelimitexceeded)および[`P6004`](/docs/orm/reference/error-reference#p6004-querytimeout)エラーに関する考慮事項
Prisma ORMをネイティブにサポートするランタイムの場合、2つのPrismaClient
インスタンスを作成することを検討できます。1つはAccelerate接続文字列(prisma://
で始まる)を使用し、もう1つは直接データベース接続文字列(postgres://
、mysql://
などで始まる)を使用します。このアプローチの主な目的は、特定のクエリに対してAccelerateをバイパスすることです。
ただし、利用可能な接続は両方のPrismaClient
インスタンス間で分割されることに注意してください。複数のインスタンスを管理することの意味、特に直接データベース接続に関して理解することが重要です。直接データベース接続文字列を持つPrismaClient
インスタンスを利用することは、この接続がデータベースと直接対話することを意味します。
このアプローチは、直接接続とAccelerateによって管理される接続が同じ基盤となるデータベース接続プールを共有するため、慎重な検討が必要です。これにより、リソースの競合が発生し、データベースサービスのパフォーマンスと可用性に影響を与える可能性があります。
さらに、直接接続はデータベースのパフォーマンスと可用性に重大な影響を与える可能性があります。かなりのリソースを消費する操作は、同じデータベースに依存する他のユーザーやプロセスのサービスを低下させる可能性があります。
アプリケーションのランタイム環境がPrisma ORMをネイティブにサポートしており、P6009およびP6004エラーを回避するためにこの戦略を検討している場合、2つのPrismaClient
インスタンスを作成することができます。
- 一般操作にはAccelerate接続文字列(
prisma://
で始まる)を使用するインスタンス。 - 設定されたクエリ制限タイムアウトを超える、または設定されたクエリ応答サイズ制限よりも大きな応答を返すことが予想される特定の操作には、直接データベース接続文字列(例:
postgres://
、mysql://
などで始まる)を使用する別のインスタンス。
export const prisma = new PrismaClient({
datasourceUrl: process.env.DIRECT_DB_CONNECTION,
})
export const prismaAccelerate = new PrismaClient({
datasourceUrl: process.env.ACCELERATE_CONNECTION,
}).$extends(withAccelerate())
このセットアップにより、特定の操作を直接接続経由で戦略的に指示することができ、前述のエラーに遭遇するリスクを軽減できます。ただし、この決定は、潜在的な結果を包括的に理解し、データベースインフラストラクチャが全体的なパフォーマンスと可用性を損なうことなくこの追加負荷をサポートできるかどうかを評価した上で下されるべきです。
以下も参照してください: サービス中断中にAccelerateが直接接続文字列にフォールバックしないのはなぜですか?
P6008
(ConnectionError|EngineStartError
)
このエラーは、Prisma Accelerateがデータベースへの接続を確立できないことを示しており、いくつかの理由が考えられます。
[`P6008`](/docs/orm/reference/error-reference#p6008-connectionerrorenginestarterror)の考えられる原因
データベースが公開されていない
データベースがVPC内にある、または特定のIPアドレスにアクセスが制限されている場合、Accelerateに静的IPが有効になっていないか、静的IPがデータベースファイアウォールで許可されていない場合に、このエラーが発生する可能性があります。
推奨される解決策: Accelerateの静的IPを有効にし、提供された静的IPアドレスからのアクセスを許可するようにデータベースファイアウォールを設定してください。
到達不可能なデータベースホスト/ポート
データベースのサーバーアドレス(ホスト名)とポートが間違っているか、到達できない場合にこのエラーが発生する可能性があります。
推奨される解決策: Prisma Accelerateプロジェクト作成時に提供されたデータベース接続文字列のホスト名/ポートを確認してください。さらに、さらなる調査のために、データベースGUIツール(例:[Prisma Studio](https://prisma.dokyumento.jp/studio)、[TablePlus](https://tableplus.com/)、または[DataGrip](https://www.jetbrains.com/datagrip/))を使用してデータベースへの接続を試みてください。
不正なユーザー名/パスワード/データベース名
このエラーは、Prisma Accelerateに誤った認証情報が提供され、データベースへの接続を確立できない場合に発生します。
推奨される解決策: Prisma Accelerateに提供された接続文字列内のデータベースのユーザー名、パスワード、および名前が正しいことを確認してください。これらの認証情報がデータベースで必要なものと一致していることを確認してください。直接データベースGUIツールを使用して接続をテストすることも、提供された認証情報が正しいかどうかの確認に役立ちます。
データベースの応答に時間がかかりすぎる
データベースが接続要求に応答するのに時間がかかりすぎる場合、Prisma Accelerateはタイムアウトし、このエラーをスローする可能性があります。これは、データベースがアクティブでない場合や、スリープモードから起動している場合に発生する可能性があります。
推奨される解決策: データベースがアクティブで到達可能であることを確認してください。データベースがスリープモードの場合は、直接データベースGUIツールを使用して要求を送信するか、データベースの管理コンソールを使用して起動してみてください。
P5011
(TooManyRequests
)
このエラーは、Prisma Accelerateが許容しきい値を超える大量のリクエストを検出した場合に発生します。これは、Prisma Accelerateと基盤となるデータベースの両方を過負荷から保護するための予防策として機能します。
[`P5011`](/docs/orm/reference/error-reference#p5011-too-many-requests)の考えられる原因
積極的なリトライループ
アプリケーションが、特定のタイプのエラーを受信した後、すぐに、または最小限の遅延でクエリを再試行すると、リクエストが急速に蓄積され、しきい値を超過する可能性があります。
推奨される解決策
- 指数バックオフ戦略を実装してください。即座に、または固定の遅延で再試行するのではなく、失敗した試行ごとに徐々に遅延期間を増やしてください。
- これにより、システムが回復する時間を確保し、Prisma Accelerateとデータベースに過度の負荷がかかる可能性を減らすことができます。
突然のトラフィックスパイク
予期しないトラフィックの急増(例:製品リリース時、フラッシュセール時、またはバイラル成長イベント時)により、しきい値に達し、P5011
が発生する可能性があります。
推奨される解決策
- Prisma Accelerateとデータベースの両方について、予防的なスケーリング戦略を検討してください。
- トラフィックとリソースの使用状況を監視してください。急増が予想される場合は、容量計画と潜在的な設定調整についてサポートにお問い合わせください。
長期間または計画された高負荷ワークロード
バルクデータインポート、ETL操作、長時間のCRONジョブなどの特定のプロセスは、時間の経過とともに継続的に高いクエリボリュームを生成する可能性があります。
推奨される解決策
- バッチ処理またはチャンキング技術を使用して、大規模な操作をより小さな部分に分割してください。
- 負荷をより均等に分散するために、スロットリングまたはスケジューリングを確立してください。
その他のエラー
MySQL(Aiven)でのエラー: 「リクエストを処理できませんでした。ページを再読み込みして、もう一度お試しください。」
問題
?ssl-mode=REQUIRED
パラメーターを含むAiven MySQL接続文字列を使用している場合、次のエラーが発生する可能性があります。
We were unable to process your request. Please refresh and try again.
原因
ssl-mode=REQUIRED
パラメーターはAccelerateと互換性がなく、接続の問題を引き起こします。
推奨される解決策
このエラーを解決するには、MySQL接続文字列から?ssl-mode=REQUIRED
パラメーターを削除してください。
例
- 元の接続文字列:
mysql://username:password@host:port/database?ssl-mode=REQUIRED
- 更新された接続文字列:
mysql://username:password@host:port/database