跳到主要内容

故障排除

在使用 Prisma Accelerate 时,您可能会在开发和运营期间遇到错误,这些错误通常由特定的错误代码突出显示。了解这些错误的含义、发生原因以及如何解决它们对于确保应用程序的顺利运行至关重要。本指南旨在提供关于使用 Prisma Accelerate 时遇到的特定错误代码的见解和故障排除步骤。

P6009 (ResponseSizeLimitExceeded)

当数据库查询的响应大小超过配置的查询响应大小限制时,会触发此错误。我们实施此限制是为了保护您的应用程序性能,因为检索超过 5MB 的数据可能会由于多个网络层而显着降低应用程序的速度。通常,当执行 ETL(提取、转换、加载)操作时,传输超过 5MB 的数据是很常见的。但是,对于其他场景,例如事务性查询、用户界面的实时数据获取、批量数据更新或在 ETL 上下文之外聚合大型数据集以进行分析,通常应避免这种情况。这些用例虽然必不可少,但通常可以优化为在配置的查询响应大小限制内工作,从而确保更流畅的性能和更好的用户体验。

P6009的可能原因

在响应中传输图像/文件

如果提取存储在表中的图像或文件,导致响应大小过大,则可能会出现此错误。通常不建议直接在数据库中存储资产,因为它会严重影响数据库的性能和可伸缩性。除了性能之外,它还会使数据库备份变慢,并显着增加存储例行备份的成本。

建议的解决方案: 配置查询响应大小限制使其更大。如果仍然超过限制,请考虑将图像或文件存储在 BLOB 存储中,例如Cloudflare R2AWS S3Cloudinary。这些服务允许您以最佳方式存储资产并返回 URL 以进行访问。与其直接在数据库中存储资产,不如存储 URL,这将大大减小响应大小。

过度获取数据

在某些情况下,会无意中获取大量记录或字段,从而导致超出配置的查询响应大小限制。当查询中的where子句不正确或完全缺失时,可能会发生这种情况。

建议的解决方案: 配置查询响应大小限制使其更大。如果仍然超过限制,请仔细检查where子句是否按预期过滤数据。为了防止获取过多记录,请考虑使用分页。此外,使用select子句仅返回必要的字段,从而减小响应大小。

获取大量数据

在许多数据处理工作流程中,特别是涉及 ETL(提取-转换-加载)过程或计划的 CRON 作业的工作流程中,需要从数据源(如数据库、API 或文件系统)中提取大量数据,以进行分析、报告或进一步处理。如果您正在运行 ETL/CRON 工作负载,该工作负载提取大量数据以进行分析处理,那么您可能会遇到此限制。

建议的解决方案: 配置查询响应大小限制使其更大。如果超过限制,请考虑将查询拆分为批次。这种方法确保每个批次仅提取一部分数据,从而防止您超出单个操作的大小限制。

P6004 (QueryTimeout)

当数据库查询未能在配置的查询超时限制内返回响应时,会发生此错误。查询超时限制包括等待从连接池获取连接的持续时间、到数据库的网络延迟以及查询本身的执行时间。我们强制执行此限制是为了防止意外的长时间运行查询,这些查询可能会使系统资源过载。

Accelerate 跨区域联网的时间不包括在配置的查询超时限制限制中。

P6004的可能原因

此错误可能是由多种原因引起的。一些突出的原因包括

高流量和连接不足

如果应用程序接收到非常高的流量,并且没有足够的连接可用于数据库,则查询将需要等待连接可用。这种情况可能会导致查询等待连接的时间超过配置的查询超时限制,如果它们在此持续时间内未得到服务,最终会触发超时错误。

建议的解决方案:查看并可能增加在平台环境中设置 Accelerate 时连接字符串参数中指定的 connection_limit (参考)。此限制应与数据库的最大连接数保持一致。

默认情况下,连接限制设置为 10,除非在数据库连接字符串中指定了不同的 connection_limit

长时间运行的查询

即使连接可用,查询也可能响应缓慢,达到配置的查询超时限制。如果单个查询中提取了大量数据,或者表中缺少适当的索引,则可能会发生这种情况。

建议的解决方案:配置查询超时限制使其更大。如果超过限制,请识别运行缓慢的查询,并仅提取必要的数据。使用 select 子句检索特定字段,避免提取不必要的数据。此外,考虑添加适当的索引以提高查询效率。您还可以将长时间运行的查询隔离到单独的环境中,以防止它们影响事务性查询。

数据库资源争用

一个常见但具有挑战性的问题是,在同一数据库上运行的其他服务执行繁重的分析或数据处理任务,从而大量消耗数据库资源。这些操作可能会占用数据库连接和处理能力,导致即使是简单的查询也无法及时执行的情况。这种“繁忙”或“嘈杂”的数据库环境可能会导致通常运行速度很快的查询运行缓慢甚至超时,尤其是在其他服务活动频繁的时期。

用户经常依赖 CPU 和内存使用率指标来衡量数据库负载,这可能会产生误导。虽然这些是重要的指标,但它们可能无法完全代表数据库的运行状态。读取、写入和等待时间等直接指标可以更清晰地了解数据库的性能,应密切监控。这些指标的明显下降,尤其是在查询或数据模型没有变化的情况下,表明外部压力正在影响数据库性能。

建议的解决方案:如果通常快速的查询间歇性地变慢或超时,而没有任何修改,则可能是竞争查询正在对同一数据库表施加压力。为了诊断这一点,请采用监控工具或利用数据库的固有功能来观察读取、写入和等待时间。此类监控将揭示与观察到的性能下降相符的活动模式或峰值。

此外,定期审查和优化基本查询,并验证表是否已正确索引至关重要。这种主动方法最大限度地减少了这些查询因竞争工作负载而导致速度减慢的脆弱性。

P6009P6004错误的注意事项

对于原生支持 Prisma ORM 的运行时,您可以考虑创建两个 PrismaClient 实例。一个使用 Accelerate 连接字符串(前缀为 prisma://),另一个使用直接数据库连接字符串(前缀为 postgres://mysql:// 等)。此方法背后的主要思想是绕过 Accelerate 以进行某些特定查询。

但是,请注意,可用连接将在您的两个 PrismaClient 实例之间分配。了解管理多个实例的影响至关重要,尤其是在直接数据库连接方面。使用带有直接数据库连接字符串的 PrismaClient 实例意味着此连接将直接与您的数据库交互。

此方法需要仔细考虑,因为直接连接和 Accelerate 管理的连接共享相同的底层数据库连接池。这可能会导致资源竞争,从而可能影响数据库服务的性能和可用性。

此外,直接连接可能会对数据库的性能和可用性产生重大影响。消耗大量资源的操作可能会降低依赖于同一数据库的其他用户或进程的服务质量。

如果您的应用程序运行时环境原生支持 Prisma ORM,并且您正在考虑使用此策略来规避 P6009 和 P6004 错误,则可以创建两个 PrismaClient 实例

  1. 一个实例使用 Accelerate 连接字符串(前缀为 prisma://)用于常规操作。
  2. 另一个实例使用直接数据库连接字符串(例如,前缀为 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的可能原因

数据库不可公开访问

如果您的数据库位于 VPC 中,或者访问权限仅限于特定 IP 地址,则如果未为 Accelerate 启用静态 IP,或者数据库防火墙中不允许静态 IP,您可能会遇到此错误。

建议的解决方案: 为 Accelerate 启用静态 IP,并将数据库防火墙配置为允许来自提供的静态 IP 地址的访问。

无法访问的数据库主机/端口

如果数据库的服务器地址(主机名)和端口不正确或无法访问,则您可能会遇到此错误。

建议的解决方案: 验证创建 Prisma Accelerate 项目时提供的数据库连接字符串的主机名/端口。此外,尝试使用数据库 GUI 工具(例如Prisma StudioTablePlusDataGrip)连接到数据库以进行进一步调查。

用户名/密码/数据库名称不正确

当向 Prisma Accelerate 提供的凭据错误时,可能会发生此错误,从而阻止其建立与数据库的连接。

建议的解决方案: 验证提供给 Prisma Accelerate 的连接字符串中数据库的用户名、密码和名称是否正确。确保这些凭据与数据库所需的凭据匹配。使用直接数据库 GUI 工具测试连接也有助于确认提供的凭据是否正确。

数据库响应时间过长

如果数据库响应连接请求的时间过长,Prisma Accelerate 可能会超时并抛出此错误。如果数据库未激活或正在从休眠模式中唤醒,则可能会发生这种情况。

建议的解决方案: 验证数据库是否已激活且可访问。如果数据库处于休眠模式,请尝试使用直接数据库 GUI 工具向其发送请求来唤醒它,或使用数据库的管理控制台唤醒它。

P5011 (TooManyRequests)

当 Prisma Accelerate 检测到大量请求超过允许的阈值时,会发生此错误。它充当一种保护措施,以保护 Prisma Accelerate 和您的底层数据库免受过度负载的影响。

P5011的可能原因

激进的重试循环

如果您的应用程序立即或以最小延迟重试查询,尤其是在收到某些错误后,请求的快速累积可能会超过阈值。

建议的解决方案

  • 实施指数退避策略。与其立即或以固定延迟重试,不如在每次尝试失败后逐渐增加延迟时间。
  • 这使系统有时间恢复,并降低了使 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