排查错误

使用 BigQuery 时,您会遇到两种类型的错误,即 HTTP 错误代码或作业错误。 作业错误会在调用 jobs.get 时通过 status 对象表示。

错误表

下表列出了向 BigQuery API 发送请求时可能返回的错误代码。API 响应包含 HTTP 错误代码和错误对象。下面的“错误代码”列与错误对象中的 reason 属性相对应。

如果您使用 bq 命令行工具检查作业状态,则默认情况下,系统不会返回错误对象。要查看错误对象及与下表对应的 reason 属性,请使用 -- format=prettyjson 标志,例如 bq --format=prettyjson show -j <job id>

如果收到的 HTTP 响应代码未显示在以下列表中,则该响应代码表示 HTTP 请求存在问题或结果符合预期。例如,502 错误表示您的网络连接存在问题。如需查看 HTTP 响应代码的完整列表,请参阅 HTTP 响应代码

错误代码 HTTP 代码 说明 问题排查
accessDenied 403 当您尝试访问自己无权访问的数据集或作业等资源时,系统会返回此错误。如果您尝试修改只读对象,也会返回此错误。 请联系资源所有者,并申请该资源的访问权限
backendError 500 或 503 当存在临时服务器故障(例如网络连接问题或服务器过载)时,系统会返回此错误。 通常,您需要等待几秒钟,然后再重试一次。不过,排查此错误时有两种特殊情况:jobs.get 调用和 jobs.insert 调用。

jobs.get 调用

  • 如果您在轮询 jobs.get 时收到 503 错误,请等待几秒钟再重新轮询。
  • 如果作业完成,但出现包含 backendError 的错误对象,则表示作业失败。您可以安全地重试作业,而不用担心数据一致性的问题。

jobs.insert 调用

如果您在进行 jobs.insert 调用时收到此错误,则无法确定作业是否成功。在这种情况下,您需要重试作业。

billingNotEnabled 403 当项目未启用结算功能时,系统会返回此错误。 请在 Google Cloud Console 中为项目启用结算功能。
blocked 403 当 BigQuery 暂时将您尝试执行的操作列入黑名单(通常是为了防止服务中断)时,会返回此错误。此错误极少发生。 如需了解详情,请与支持团队联系
duplicate 409 当尝试创建的作业、数据集或表已存在时,系统会返回此错误。如果作业的 writeDisposition 属性设置为 WRITE_EMPTY,且作业访问的目标表已存在,也会返回此错误。 请重命名您尝试创建的资源,或更改作业的 writeDisposition 值。
internalError 500 当 BigQuery 发生内部错误时,系统会返回此错误。 请重试操作;如果错误仍然存在,请与支持团队联系,或使用 BigQuery 问题跟踪器提交错误报告
invalid 400 当存在无效查询之外的任何种类无效输入(例如,缺少必填字段或表架构无效)时,系统会返回此错误。无效查询则会返回 invalidQuery 错误。
invalidQuery 400 当您尝试运行无效查询时,系统会返回此错误。 请仔细检查您的查询是否存在语法错误。查询参考文档中包含有关如何构造有效查询的说明和示例。
notFound 404 当您引用的资源(数据集、表或作业)不存在时,系统会返回此错误。如果使用快照修饰器引用最近执行过流式插入操作的表,但该表已被删除,也可能会发生此错误。 请修复资源名称,或是在执行流式插入操作后至少等待 6 个小时再查询已删除的表。
notImplemented 501 当您尝试访问未实现的功能时,系统会返回此作业错误。 如需了解详情,请与支持团队联系
quotaExceeded 403 如果您的项目超过 BigQuery 配额自定义配额,或者如果您尚未设置结算功能并超过查询的免费层级,则系统会返回此错误。 请查看错误对象的 message 属性,详细了解超出了哪一项配额。要重置或提高 BigQuery 配额,请与支持团队联系。要修改自定义配额,请通过 Google Cloud Console 页面提交申请。如果您在使用 BigQuery 沙盒时收到此错误,则可以执行升级
rateLimitExceeded 403 如果您的项目在很短时间内发送的请求过多,导致超出并发速率限制API 请求限制,则系统会返回此错误。 请降低请求速率。

如果您确信项目未超过其中任何一项限制,请与支持团队联系

resourceInUse 400 当尝试删除包含表的数据集或当前正在运行的作业时,会返回此错误。 请先清空数据集,然后尝试删除该数据集;或者先等待作业完成,然后再删除该作业。
resourcesExceeded 400 如果查询使用的资源过多,则系统会返回此错误。
  • 请尝试将查询分解为多个较小的查询。
  • 请尝试移除 ORDER BY 子句。
  • 如果您的查询使用 JOIN,请确保较大的表位于子句左侧。
  • 如果您的查询使用 FLATTEN,请确定它对于您的用例来说是否必要。 如需了解详情,请参阅嵌套重复的数据
  • 如果您的查询使用 EXACT_COUNT_DISTINCT,建议改用 COUNT(DISTINCT)
  • 如果您的查询使用 COUNT(DISTINCT <value>, <n>) 和较大的 <n> 值,建议改用 GROUP BY。如需了解详情,请参阅 COUNT(DISTINCT)
  • 如果您的查询使用 UNIQUE,建议改用 GROUP BY,或子选择内的窗口函数
responseTooLarge 403 当查询结果超过响应大小上限时,系统会返回此错误。某些查询会分多个阶段执行。当任何阶段返回的响应大小过大时,系统便会返回此错误,即使最终结果未超过大小上限也是如此。如果查询使用 ORDER BY 子句,系统通常会返回此错误。 请添加 LIMIT 子句(有时会有所帮助),或移除 ORDER BY 子句。如要确保大型结果能够顺利返回,您可以将 allowLargeResults 属性设置为 true 并指定目标表。
stopped 200 当作业被取消时,系统会返回此状态代码。
tableUnavailable 400 某些 BigQuery 表由其他 Google 产品团队管理的数据提供支持。此错误表示其中一个表不可用。 收到此错误消息时,您可以重试请求(请参阅 internalError 问题排查建议),或联系授予您数据访问权限的 Google 产品团队。

错误响应示例

GET https://www.googleapis.com/bigquery/v2/projects/12345/datasets/foo
Response:
[404]
{
  "error": {
  "errors": [
  {
    "domain": "global",
    "reason": "notFound",
    "message": "Not Found: Dataset myproject:foo"
  }],
  "code": 404,
  "message": "Not Found: Dataset myproject:foo"
  }
}

身份验证错误

根据 OAuth2 规范的定义,OAuth 令牌生成系统引发的错误会返回以下 JSON 对象。

{"error" : "description_string"}

此错误会伴随着 HTTP 400 Bad Request 错误或 HTTP 401 Unauthorized 错误。description_string 是由 OAuth2 规范定义的其中一个错误代码。例如:

{"error":"invalid_client"}

返回页首

排查流式插入问题

以下部分讨论如何排查在将数据流式插入到 BigQuery 时发生的错误。

失败 HTTP 响应代码

如果收到失败的 HTTP 响应代码(如网络错误),则无法确定流式插入是否成功。如果只是尝试重新发送请求,则可能导致最终表中出现重复的行。为了避免表中出现重复的内容,请在发送请求时设置 insertId 属性。BigQuery 会使用 insertId 属性执行去重操作。

如果您收到权限错误、表名称无效错误或超出配额错误,则系统不会插入任何行,并且整个请求都会失败。

成功 HTTP 响应代码

即使您收到成功 HTTP 响应代码,也需要检查响应的 insertErrors 属性才能确定是否成功插入行,因为 BigQuery 可能只是成功插入了部分行。

如果 insertErrors 属性是空列表,则表示所有行均已成功插入。如果该属性不是空列表,则表示 insertErrors 属性中指示的行并未插入,而其他所有行则已成功插入(除非任何行中存在架构不匹配的情况)。errors 属性详细说明了每个未成功插入行的失败原因。index 属性指示请求中与错误对应的行索引(从 0 开始)。

如果 BigQuery 在请求的个别行上遇到架构不匹配的情况,则系统不会插入任何行,并会针对每一行(即使是架构匹配的行)返回一个 insertErrors 条目。对于架构匹配的行,在其所收到的错误中,reason 属性会设置为 stopped,因此您可以按原样重新发送这些行。而对于插入失败的行,其会包含有关架构不匹配情况的详细信息。

流式插入的元数据错误

由于 BigQuery 的流式传输 API 可以实现高插入速率,因此在与流式传输系统进行交互时,对底层表元数据展示的修改最终将保持一致。在大多数情况下,元数据更改会在几分钟内完成传送,但在此期间,API 响应可能会反映表的不一致状态。

部分情况包括:

  • 架构更改 - 针对最近接收了流式插入内容的表修改架构时,响应可能会指出架构不匹配错误,因为流式插入系统可能不会立即反映架构更改。
  • 表创建/删除 - 如果将数据流式插入到不存在的表,则系统将返回 notFound 响应的变体。如果在响应中创建表,则后续流式插入作业可能无法立即识别该表。同样地,删除和/或重新创建表,可能造成在一段时间内流式插入实际上传输到旧表,而不会出现在新表中。
  • 表截断 - 同样地,如果截断表的数据(例如,查询作业使用 WRITE_TRUNCATE 的 writeDisposition ),则可能导致后续插入操作的一致性出现落差。

数据丢失/不可用

流式插入临时驻留在流式缓冲区中,该缓冲区具有不同于托管存储空间的可用性特征。BigQuery 中的某些操作不与信息流缓冲区交互,例如表复制作业和 tabledata.list 等 API 方法。因此,最近流式插入的数据将不会出现在目标表或输出中。

返回页首