排查错误

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

如果您认为项目未超过这些限制,请与支持团队联系

resourceInUse 400 当尝试删除包含表的数据集或当前正在运行的作业时,会返回此错误。 在清空数据集后再尝试删除该数据集,或者等待作业完成后再删除该作业。
resourcesExceeded 400 查询使用太多资源时,会返回此错误。
  • 尝试将查询分解为多个较小的查询。
  • 尝试移除 ORDER BY 子句。
  • 如果查询使用 JOIN,请确保较大的表位于子句左侧。
  • 如果查询使用 FLATTEN,请确定它对于您的用例来说是否必要。如需了解详情,请参阅嵌套和重复的数据
  • 如果查询使用 EXACT_COUNT_DISTINCT,请考虑改为使用 COUNT(DISTINCT)
  • 如果查询使用 <n> 值较大的 COUNT(DISTINCT <value>, <n>),请考虑改为使用 GROUP BY。如需了解详情,请参阅 COUNT(DISTINCT)
  • 如果查询使用 UNIQUE,请考虑改为使用 GROUP BY 或子选择内的窗口函数
responseTooLarge 403 当查询结果大于最大响应大小时,会返回此错误。某些查询分多个阶段执行,当任何阶段返回的响应大小过大时,即使最终结果小于最大值,也会返回此错误。当查询使用 ORDER BY 子句时,通常会返回此错误。 添加 LIMIT 子句有时会有所帮助,也可以移除 ORDER BY 子句。如果要确保能够返回较大的结果,可以将 allowLargeResults 属性设置为 true,并指定目标表。
已停止 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 方法。因此,最近的流式数据将不会出现在目标表或输出中。

返回页首

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
需要帮助?请访问我们的支持页面