文档

SQL诊断

更新时间:

Hologres提供慢Query日志,默认采集大于100ms的DML和所有DDL。基于慢Query日志的数据,Hologres提供SQL诊断的能力,通过对不同维度的趋势、明细分析,可以辅助您了解实例的使用情况并做相应的优化,以达到更好的效果。本文为您介绍如何使用SQL诊断。

功能介绍与建议

当前SQL诊断支持的诊断内容如下:

诊断项

说明

Query总数

所选时间段的Query总数。

成功Query

所选时间段成功的Query总数。

失败Query

所选时间段失败的Query总数。

失败Query明细

展示错误码和对应的失败次数,方便治理错误的Query,同时展示出典型的Query和错误明细。

您可以跳转至Query洞察查看更详细的内容,也可以通过错误码对照表查看详细的错误原因,以提升实例稳定性。

成功和失败Query趋势

展示所选时间段的成功和失败的Query次数比例,方便了解当前实例的Query整体运行情况。

Query耗时占比趋势

展示所选时间段的Query耗时占比趋势。

默认只分析SELECTINSERTUPDATEDELETE这四类Query的耗时占比情况。

DML趋势

展示DML Query的执行次数趋势。

默认只分析SELECTINSERTUPDATEDELETE这四类Query。

DDL趋势

展示DDL Query的执行次数趋势。

仅包含CREATE TABLEDROP TABLETRUNCATE TABLEALTER TABLECALLCREATE EXTENSIONCREATE FOREIGN TABLEALTER FOREIGN TABLEIMPORT FOREIGN SCHEMADROP FOREIGN TABLECREATE SCHEMACREATE VIEWDROP VIEWGRANTCREATE ROLEALTER ROLECOMMENT这些DDL。

Query应用来源占比情况或趋势

展示application_name维度的Query占比情况或趋势。

可以从占比中分析占比较多的应用,同时也建议给不同的任务类型设置相关的application_name,这样可以更好的应用来源占比图和趋势图,观察异常任务。

用户维度的Query占比情况或趋势

展示usename维度的Query占比情况或趋势。

可以更加明显地分析出用户Query执行情况,同时也建议不同的任务使用不同的用户名,而不是使用同一个账号,以便更好地排查异常。

执行引擎的Query趋势

展示所选时间段内,不同执行引擎的Query执行趋势。

Hologres根据Query的特征,会有不同的执行引擎,包括HQE、PQE、SDK或FixedQE等,详情请参见产品架构。建议您尽量避免PQE的查询,而是改写成HQE的Query,以便获得更好的性能。

注意事项

  • SQL诊断的数据去除了系统相关的SQL,筛选条件如下:

    where
    usename != 'system'
    AND usename != 'holo_admin' 
    AND client_addr != '127.0.0.1' 
    AND (application_name IS NULL 
    OR application_name not in ('AutoPartition', 'holoweb_system', 'HgGenInQuery'))
  • hologres.hg_query_log表默认只能查询大于1s的DML和所有DDL,SQL诊断默认分析大于100ms的所有DML和DDL,如果您发现hologres.hg_query_log统计的数据少于SQL诊断时,一般是因为hologres.hg_query_log只统计了大于1s的Query,您可以通过修改log_min_duration_statement参数采集大于100ms的Query,详情请参见log_min_duration_statement

  • SQL诊断数据保留机制同慢Query日志,只能查看近一个月的数据。默认展示前一天的数据。可以根据业务情况进行时间维度的筛选。

  • SQL诊断的查询权限同慢Query日志,授予查看权限请参见授予查看权限

操作步骤

您可以通过HoloWeb可视化查看SQL诊断。

  1. 登录HoloWeb控制台,详情请参见连接HoloWeb

  2. 单击顶部导航栏的诊断与优化

  3. 在左侧导航栏,选择实例诊断>SQL诊断

  4. SQL诊断页面顶部,编辑查询条件。

    查询条件参数:

    参数

    是否必选

    说明

    实例名

    需要查询慢Query的实例名称,默认是当前登录的实例。

    时间范围

    慢Query的时间范围,默认选择昨天,最多只能选择过去一个月的数据。

  5. 单击提交,展示查询结果。

查询结果示例如下:image

错误码对照表

错误码

说明

常见的完整报错

解决方法

  • ERRCODE_UNIQUE_VIOLATION

  • pk violates

违反唯一性约束,常出现在写入时主键重复的场景。

duplicate key value violates unique constraint DETAIL: xxx already exists.

  • 处理主键重复的数据。

  • 若是INSERT语法报错 ,可以改写成insert into xx on conflict的语法,实现主键去重,详情请参见INSERT ON CONFLICT(UPSERT)

  • 若是insert into xx on conflict语法报错,为数据源有重复数据导致,解决方法请参见INSERT ON CONFLICT(UPSERT)

  • ERRCODE_CHECK_VIOLATION

  • partition constraint

违反检查约束,常发生在写入Hologres分区表时,写入的分区值与设置的分区值不一致。例如20240301的分区写入了0240229的分区数据。

new row for relation xx violates partition constraint DETAIL: Failing row contains (column1)=(xxxx).

需要检查分区数据和设置的分区值是否一致,并修改为一致。

  • ERRCODE_NOT_NULL_VIOLATION

  • not-null constraint

  • UsageProblem

违反非空约束。常发生在非空(not null)字段写入了空(null)数据。

null value in column xxx violates not-null constraint DETAIL: Failing row contains (null).

处理脏数据。

ERRCODE_UNDEFINED_TABLE

表不存在,一般出现在表刚刚创建未更新元数据或者Query执行过程中,表有TRUNCATE或DROP的场景。

Dispatch query failed: Table not found

可以使用Query洞察排查是否有同时TRUNCATE或DROP任务,然后重试任务,详情请参见Query洞察

  • ERRCODE_INTERNAL_ERROR

  • ERPC_ERROR_CONNECTION_CLOSED

内部非预期错误,实例可能出现过宕机或者Query被意外中断。

  • Transaction xx is not found or it was expired and cancelled.

  • Query is cancelled

  • ERPC_ERROR_CONNECTION_CLOSED

暂无。

  • ERRCODE_QUERY_CANCELED

  • User canceled

  • CANCELLED

  • Query Is Cancelled

  • InternalQueryIsClosed

查询被取消,一般是因为设置了客户端超时,或者表被TRUNCATE或DROP了。

  • ERROR: canceling statement due to statement timeout

  • canceling statement due to user request

解决方法请参见Query管理排查。

  • ERRCODE_FEATURE_NOT_SUPPORTED

  • Unsupported Feature

有某个功能不支持。

  • Dynamic partition selector is not supported

  • ALTER TABLE CHANGE OWNER is not supported in SPM (Simple Permission Mode)

  • Feature not supported: insert into parent table

解决方法请参见Hologres SQL语句的常见问题

ERRCODE_UNDEFINED_OBJECT

存在未定义的对象,一般是列不存在、Table Group不存在。

  • column xxx does not exist

  • Table group xxx does not exist.

  • 请先创建提示不存在的对象。

  • 确认报错不存在的对象在SQL中是否填写了正确名称。

  • ERRCODE_INSUFFICIENT_PRIVILEGE

  • permission denied

当前账号权限不足,需要授权。

  • ERROR: permission denied for schema xxx

  • ERROR: permission denied for foreign table table_info

解决方法请参见Hologres权限相关

  • ERRCODE_OUT_OF_MEMORY

  • OOM

Query因为内存不足,出现了OOM。

Total memory used by all existing queries exceeded memory limitation

解决方法请参见OOM常见问题排查指南

  • ERRCODE_DATATYPE_MISMATCH

  • Unmatched Data Row Schema Number

  • Dataset Schema Not Match

类型不匹配,通常为表达式需要的类型与字段的实际类型不匹配。

  • unmatched data row schema number

  • Datasets has different schema

检查SQL的列是否匹配。

  • ERRCODE_DIVISION_BY_ZERO

  • division by zero

SQL中存在除数为0的情况。

division by zero

处理脏数据,或者使用GUC使除以0不报错,详情请参见函数使用

ERRCODE_STRING_DATA_RIGHT_TRUNCATION

字符串右截断,多发生于VARCHAR字段的实际值超过了建表时VARCHAR指定的长度。

value too long for type character varying(xx)

重新建表修改VARCHAR字段的长度,或者将字段类型设置为TEXT。

  • ERRCODE_PROGRAM_LIMIT_EXCEEDED

  • Exceed Odps Scan Limit

超过Hologres允许的上限,通常发生在扫描外部表分区表数量、读的行数、读的字节等超过上限。

  • number of read rows (xxxxx) exceeds limit (xxxxxxx)

  • number of partitions (xxx) scanned for "xxxx" exceeds the maximum allowed (xxx)

  • scan (xxx GB) for "xxxxx" exceeds the maximum allowed (xxx GB)

外部表查询超过了限制,解决方法请参见对接MaxCompute常见问题与诊断

ERRCODE_SYNTAX_ERROR

SQL语法错误。

syntax error at or near "xxxxx"

请您重新检查SQL语法。

ERRCODE_UNDEFINED_FUNCTION

一般为不支持的函数功能,可能是因为函数语法使用错误,或者未创建Extension等,也可能是不支持某个函数。

  • function xxxxx does not exist

  • operator does not exist: xxxxxx

请根据函数的语法进行操作,避免语法错误或者Extension未创建等,详情请参见PostgreSQL兼容函数

ERRCODE_E_R_E_READING_SQL_DATA_NOT_PERMITTED

没有外部表的读权限。

check permission for foreign table scan failed: failed to check permission:MaxCompute error,Authorization Failed [4019], You have NO privilege 'odps:Select' on {xxxxxxxxxx}

解决方法请参见MaxCompute权限相关

  • ERRCODE_DUPLICATE_OBJECT

  • already exist

存在重复的对象,通常发生于创建重复的Extension、Publication、Role等。

  • publication "xxxxx" already exists

  • extension "xxxxx" already exists

  • role "xxxxxxxx" already exists

如果对象已经存在,不需要重复创建。

  • ERRCODE_INVALID_TEXT_REPRESENTATION

  • invalid input

非法的文本表达式,常发生于字符串转换为其他类型时,字符串的数据非法,比如空字符串("")转INT。

invalid input syntax for integer: xxx

处理脏数据。

ERRCODE_BAD_COPY_FILE_FORMAT

执行copy命令时文件或数据的格式不正确,多发生于数据本身就包含了copy指定的分割符(比如空格),导致列的数量对不上。

  • extra data after last expected column. failed to query next

  • missing data for column "xxx". failed to query next

处理脏数据。

ERRCODE_UNDEFINED_COLUMN

Query中有不存在的列。

column xxxxx does not exist

重新检查SQL语法。

ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE

数值类型超过范围:

  • numeric类型数据超过了numeric定义的范围,比如类型为decimal(4,2)numeric(4,2)时,整数部分最多两位,但实际数据为100。

  • int或bigint超过了表示范围。

  • value "xxxxx" is out of range for type bigint

  • numeric field overflow

  • bigint out of range

  • integer out of range

检查是否有脏数据或者类型定义错误,重新修改列类型。

ERRCODE_DATETIME_FIELD_OVERFLOW

timestamp、timestamptz、date、time、timetz等时间相关的字段存在值溢出,比如"877411-01-01 00:00:00+08"写入至timestamptz类型。

  • date/time field value out of range: "xxxxxx"

  • date out of range: "xxxxxx"

处理脏数据。

ERRCODE_INVALID_PARAMETER_VALUE

非法参数值,一般是各种情况下的参数不符合要求。根据具体报错信息改进。例如报错:column "col" with type "float4" cannot be set as "bitmap_columns" 表示float4类型不能设置为bitmap columns。

  • mismatched properties: table orientation is "column" but storage format is "sst"

  • resharding insert select table data failed : Dispatch query failed: internal error: Failed to get available shards for query

  • InsertOverwrite insert select table data failed : column a.unsign_type does not exist

重新检查SQL语法。

ERRCODE_INVALID_DATETIME_FORMAT

非法的日期格式,日期数据不符合格式要求,比如SELECT TO_DATE('aa', 'YYYY-MM-DD');,请检查数据。

  • invalid input syntax for type timestamp: ""

  • invalid input syntax for type date: ""

  • invalid value "" for "yyyy",Value must be an integer.

处理脏数据。

ERRCODE_CHARACTER_NOT_IN_REPERTOIRE

字符不在编码范围,常见于出现了UTF-8编码之外的非法字符。

invalid byte sequence for encoding "UTF8": 0xe9 0x80

处理脏数据。

ERRCODE_DUPLICATE_TABLE

重复的表,常见表已经存在时,又重复建同名表。

relation "xxxx" already exists

如果表已经存在,则不需要重复创建。

ERRCODE_UNTRANSLATABLE_CHARACTER

存在字符无法转化为目标格式。

character with byte sequence 0xe4 0x9e 0xab in encoding "UTF8" has no equivalent in encoding "GBK"

说明

表示UTF-8编码的字符在目标GBK格式中无等价项。

处理脏数据。

ERRCODE_GROUPING_ERROR

分组错误,group by相关的错误。

column "xxx" must appear in the GROUP BY clause or be used in an aggregate function

重新检查SQL语法,聚合函数的字段需要包含在group by内。

  • ERRCODE_INVALID_TRANSACTION_STATE

  • Usage Problem

非法的事务状态。涉及事务的相关操作非法。 比如CALL SET_TABLE_PROPERTY创建Distribution Key时和建表不在一个事务中。

SET_TABLE_PROPERTY and CREATE TABLE statement are not in the same transaction

create table语句需要和CALL SET_TABLE_PROPERTY在一个事务里(使用begin;commit;)。

ERRCODE_AMBIGUOUS_COLUMN

模棱两可的列。一般是SQL中同一列名可能是不同列时报错,例如select id from t1 inner join t2 on t1.id = t2.id语句中,查询的id字段没有指明是属于t1还是t2。

column reference "xxx" is ambiguous

重新检查SQL语法。

ERRCODE_DUPLICATE_COLUMN

重复列,常发生在建表时同一字段声明了多次。

column "xxx" specified more than once

重新检查SQL语法。

ERRCODE_AMBIGUOUS_FUNCTION

模棱两可的函数。一般是函数支持多种类型的入参,但传参的类型没有指定清楚。

如函数to_char有to_char(timestamp/timestamptz, text)

to_char(double precision, text)to_char(int, text)三种形式,当输入为to_char('2024-02-22', 'YYYY-MM-DD')时由于'2024-02-22'非以上三种形式类型,就会报错。 需要显式指定类型转换方可成功:to_char('2024-02-22'::timestamptz, 'YYYY-MM-DD')

重新检查SQL语法。

ERRCODE_INVALID_COLUMN_DEFINITION

非法的列定义,在Hologres中多是Numeric或Decimal类型未指明精度。

invalid definition of a numeric type

处理脏数据。

ERRCODE_INVALID_CATALOG_NAME

ERRCODE_UNDEFINED_DATABASE

指定的数据库不存在。

暂无

检查数据库是否存在。

ERRCODE_CANNOT_COERCE

两个类型数据之间无法转化时报错。

cannot cast type date to integer

重新检查SQL语法。

ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST

依赖的对象仍存在,常见于删除一个对象时,依赖其的对象仍然存在。比如删除一个Schema时, 该Schema下的表还未删除。

暂无

处理相关依赖,详情请参见删除账号

ERRCODE_UNDEFINED_SCHEMA 或

ERRCODE_INVALID_SCHEMA_NAME

指定的Schema不存在。

schema "xxxx" does not exist

检查Schema是否存在,不存在需要先创建。

ERRCODE_DUPLICATE_DATABASE

重复的数据库,创建一个已存在的数据库时报错。

暂无

如果数据库已经存在,无需重复创建。

AutoAnalyze-Failed

Auto Analyze因为某些原因失败。

  • query row count from analyze table

  • query from analyze table

Auto Analyze失败,一般为后端原因,请提工单排查。

Import Foreign Table Not Found

找不到外部表。

  • failed to get foregin table split:Table not found

  • Failed to get odps table:Not enable acid table

  • failed to get foregin table split:% not found

请检查访问的外部表的是否存在。

Cannot Acquire Lock In Time

这个异常通常是由于拿锁失败,高并发查询和删除(Drop)同一张表时,后端节点出现死锁,导致有关这张表的操作都卡住,从而报错。

internal error: Cannot acquire lock in time, current owners

解决方法请参见锁以及排查锁

  • OTHER

  • QueryNextFTEFailed

  • QueryNextPQEFailed

  • ForeignSplitOrSchemaConnectionClosed

  • ConnectionRefused

  • ERPC_ERROR_TIMEOUT

  • ERPC_ERROR_CONNECTION_CLOSED

非预期的报错。

  • kConnectError: channel is empty

  • ERPC_ERROR_CONNECTION_CLOSED

  • internal error: Connect timeout, err: std_exception: Connection refused

非预期的报错,可以提工单排查。

  • 本页导读 (1)