使用高级 Query Insights 监控查询性能

选择文档版本:

借助高级 Query Insights,您可以检测、诊断和避免 AlloyDB Omni 数据库中的查询性能问题。它会捕获数据库遥测数据,包括标准化查询统计信息、等待事件、客户端 IP 地址、标记和实例负载,并保留 30 天的历史指标。

您可以使用高级 Query Insights 执行以下任务:

  • 通过分析执行时间、I/O 时间、等待时间、共享缓冲区活动和行数,识别高延迟和资源密集型查询。
  • 通过将慢速查询与等待事件和等待事件类相关联,排查瓶颈问题。
  • 通过使用 SQLCommenter 元数据标记查询 ,将查询性能跟踪到特定应用组件。
  • 实时监控活跃查询和打开的事务,并停止有问题的会话。

准备工作

在启用高级 Query Insights 之前,请验证是否满足以下要求:

  • 您在容器中运行的是独立 AlloyDB Omni 实例。

  • 您拥有对数据库实例的 postgres 超级用户访问权限,以及重启容器的管理员权限。

  • 您的实例上存在 alloydbadmin 数据库。 AlloyDB Omni 在初始化期间默认创建此数据库。

启用高级 Query Insights

如需启用高级 Query Insights,请按以下步骤操作:

  1. 以 postgres 超级用户的身份连接到 postgres 数据库:

    Docker

    docker exec -it CONTAINER_NAME psql -U postgres -d postgres
    

    Docker

    docker exec -it CONTAINER_NAME psql -U postgres -d postgres
    

    Podman

    podman exec -it CONTAINER_NAME psql -U postgres -d postgres
    

    Podman

    podman exec -it CONTAINER_NAME psql -U postgres -d postgres
    

    将 CONTAINER_NAME 替换为您的 AlloyDB Omni 容器的名称,例如 my-omni-1。

  2. 检查 shared_preload_libraries 中加载的库,将高级 Query Insights 添加到预加载列表,启用扩展程序,然后退出 psql:

    SHOW shared_preload_libraries;
    ALTER SYSTEM SET shared_preload_libraries = 'LIBRARY_1','LIBRARY_2','google_insights_v2';
    ALTER SYSTEM SET google_insights_v2.enabled = on;
    \q
    

    将 LIBRARY_1、LIBRARY_2 和任何其他现有库替换为 SHOW shared_preload_libraries 返回的库名称。将每个库条目用 单引号括起来,例如 'g_stats','google_columnar_engine','google_insights_v2',并包含 AlloyDB Omni 所需的所有 现有库,以免 覆盖它们。

  3. 重启 AlloyDB Omni 服务器以应用预加载设置:

    Docker

    docker restart CONTAINER_NAME
    

    Docker

    docker restart CONTAINER_NAME
    

    Podman

    podman restart CONTAINER_NAME
    

    Podman

    podman restart CONTAINER_NAME
    
  4. 以 postgres 超级用户的身份连接到 alloydbadmin 数据库:

    Docker

    docker exec -it CONTAINER_NAME psql -U postgres -d alloydbadmin
    

    Docker

    docker exec -it CONTAINER_NAME psql -U postgres -d alloydbadmin
    

    Podman

    podman exec -it CONTAINER_NAME psql -U postgres -d alloydbadmin
    

    Podman

    podman exec -it CONTAINER_NAME psql -U postgres -d alloydbadmin
    
  5. 在 alloydbadmin 数据库中创建高级 Query Insights 扩展程序:

    CREATE EXTENSION IF NOT EXISTS google_insights_v2;
    
  6. 验证库是否已加载,扩展程序是否已启用,以及 google_insights_v2 扩展程序是否已安装在 alloydbadmin 中:

    SHOW shared_preload_libraries;
    SHOW google_insights_v2.enabled;
    SELECT extname, extversion FROM pg_extension WHERE extname = 'google_insights_v2';
    

    确认 shared_preload_libraries 包含 google_insights_v2, google_insights_v2.enabled 返回 on,并且 pg_extension 为 google_insights_v2 返回一行。

维度和功能参数

在 AlloyDB Omni 中,高级 Query Insights 会将数据库遥测数据记录到 alloydbadmin 数据库中的 SQL 表、视图和函数中,涵盖以下维度和功能:

  • 查询:用于在查询延迟时间增加时识别慢速或资源密集型 SQL 语句。
  • 等待事件类型:用于确定 CPU、磁盘 I/O 或锁争用是否会导致工作负载瓶颈。
  • 等待事件:用于识别延迟查询执行的特定 PostgreSQL 等待事件,例如 DataFileRead 或 WALWrite。
  • 数据库:用于比较逻辑数据库之间的资源消耗,并隔离共享实例上的高负载数据库。
  • 用户和客户端 IP 地址:用于将查询负载归因于特定数据库角色或客户端 IP 地址,并识别有问题的应用客户端。
  • 标记:用于将数据库负载与使用 SQLCommenter标记的特定 应用服务、路由或 ORM 操作相关联。
  • 活跃查询:用于实时诊断实时性能峰值、被阻止的事务和长时间运行的会话。

当您将 google_insights_v2.enabled 设置为 on 时,AlloyDB Omni 会自动收集查询、等待事件类型、等待事件、数据库和用户的指标。

如需在运行时更新任何 google_insights_v2.* 参数,而无需重启数据库服务器,请运行 ALTER SYSTEM SET 并重新加载配置:

ALTER SYSTEM SET PARAMETER_NAME = VALUE;
SELECT pg_reload_conf();

替换以下内容:

  • PARAMETER_NAME:要配置的高级 Query Insights 参数的名称,例如 google_insights_v2.qi_track_active_queries、google_insights_v2.qi_track_tag 或 google_insights_v2.qi_track_client_address。
  • VALUE:参数的新值,例如 on。

如需了解每个参数的说明、相应的可观测性视图,以及 每个视图返回的指标和列,请参阅高级 Query Insights 参考文档。

时间粒度

每个历史 observability_service_* 视图都有三种时间粒度:

  • 基本视图 (*_view):15 秒刷新间隔。使用这些视图调查最近 1 到 6 小时内的峰值或突发事件。
  • 粗略级别 1 视图 (*_coarse_1_view):前 2,000 个查询的 5 分钟汇总间隔。使用这些视图分析 6 到 24 小时内的性能趋势。
  • 粗略级别 2 视图 (*_coarse_2_view):前 2,000 个查询的 30 分钟汇总间隔。使用这些视图分析多日趋势,最长可达 30 天的保留期限。

历史可观测性视图以微秒为单位存储所有执行时间、等待时间和 I/O 时间列,包括 total_execution_time、total_wait_time、total_read_time、total_write_time 和 time_spent。

查询历史效果指标

连接到 alloydbadmin 数据库,针对历史可观测性视图运行诊断查询。如需了解详情,请参阅运行并连接到 AlloyDB Omni。

本部分中的 SQL 语句是针对各个维度常见问题排查场景的查询示例。您可以自定义这些示例,例如更改 recorded_on 时间窗口、按特定数据库或角色过滤,或者查询 *_coarse_1_view 和 *_coarse_2_view 以进行多日分析,从而适应您的工作负载。

识别高延迟查询

如需查找过去一小时内总执行时间最长的 10 个标准化查询,请针对 google_insights_v2.observability_service_query_view 运行以下示例查询:

SELECT
  query_id,
  database,
  username,
  left(query, 100) AS normalized_query,
  sum(count) AS total_executions,
  sum(total_execution_time) AS total_execution_time_us,
  round((sum(total_execution_time)::numeric / NULLIF(sum(count), 0)), 2) AS avg_execution_time_us,
  sum(total_rows) AS total_rows,
  sum(total_shared_blocks_hit) AS shared_blocks_hit,
  sum(total_shared_blocks_read) AS shared_blocks_read
FROM google_insights_v2.observability_service_query_view
WHERE recorded_on >= now() - INTERVAL '1 hour'
GROUP BY query_id, database, username, left(query, 100)
ORDER BY total_execution_time_us DESC
LIMIT 10;

按查询分析等待事件

如需确定哪些等待事件类别 (wait_class) 和细粒度等待事件 (wait_event) 对特定 query_id 的等待时间贡献最大,请针对 google_insights_v2.observability_service_wait_event_stats_by_query_view 运行以下示例查询:

SELECT
  query_id,
  database,
  username,
  wait_class,
  wait_event,
  sum(count) AS wait_occurrences,
  sum(time_spent) AS total_wait_time_us
FROM google_insights_v2.observability_service_wait_event_stats_by_query_view
WHERE recorded_on >= now() - INTERVAL '1 hour'
  AND query_id = QUERY_ID
GROUP BY query_id, database, username, wait_class, wait_event
ORDER BY total_wait_time_us DESC;

将 QUERY_ID 替换为 observability_service_query_view 返回的 query_id 值。

分析数据库、用户和客户端 IP 负载

如需比较过去一小时内逻辑数据库和数据库角色之间的总执行时间、等待时间和查询量,请针对 google_insights_v2.observability_service_db_load_conn_view 运行以下示例查询:

SELECT
  database,
  username,
  sum(count) AS total_executions,
  sum(total_execution_time) AS total_execution_time_us,
  sum(total_wait_time) AS total_wait_time_us
FROM google_insights_v2.observability_service_db_load_conn_view
WHERE recorded_on >= now() - INTERVAL '1 hour'
GROUP BY database, username
ORDER BY total_execution_time_us DESC;

如果您启用 google_insights_v2.qi_track_client_address,还可以使用以下示例查询针对 google_insights_v2.observability_service_client_address_stats_by_query_view 运行,以确定哪些连接的客户端 IP 地址生成了最多的查询时间:

SELECT
  client_address,
  username,
  database,
  query_id,
  sum(count) AS total_executions,
  sum(time_spent) AS total_time_spent_us
FROM google_insights_v2.observability_service_client_address_stats_by_query_view
WHERE recorded_on >= now() - INTERVAL '1 hour'
GROUP BY client_address, username, database, query_id
ORDER BY total_time_spent_us DESC
LIMIT 10;

按标记跟踪查询性能

当 google_insights_v2.qi_track_tag 设置为 on 且您的查询包含 SQLCommenter 注释时,请运行 以下示例查询,以使用 google_insights_v2.observability_service_tag_view 按应用标记元数据汇总执行时间:

SELECT
  application,
  framework_name,
  framework_controller,
  framework_action,
  framework_route,
  database,
  username,
  sum(count) AS total_executions,
  sum(total_execution_time) AS total_execution_time_us,
  round((sum(total_execution_time)::numeric / NULLIF(sum(count), 0)), 2) AS avg_execution_time_us
FROM google_insights_v2.observability_service_tag_view
WHERE recorded_on >= now() - INTERVAL '1 hour'
GROUP BY
  application,
  framework_name,
  framework_controller,
  framework_action,
  framework_route,
  database,
  username
ORDER BY total_execution_time_us DESC
LIMIT 10;

监控活跃查询

当您将 google_insights_v2.qi_track_active_queries 设置为 on 时,您可以通过查询 alloydbadmin 数据库中的 google_insights_v2.stat_activity 和 google_insights_v2.stat_activity_v3,实时监控正在运行的查询和打开的事务。

这些视图会显示活跃客户端连接、会话和事务时长以及当前等待事件,同时排除后台工作器和 alloydbadmin 连接。

查询活跃会话和事务时长

如需确定哪些查询目前在实例上处于活跃运行状态,以及哪些事务运行时间最长,请在 alloydbadmin 中运行以下示例查询:

SELECT
  pid AS "Process ID",
  left(normalized_query, 40) AS "Query",
  state AS "Status",
  round(EXTRACT(EPOCH FROM (clock_timestamp() - backend_start))::numeric, 2) AS "Session duration (secs)",
  CASE
    WHEN xact_start IS NOT NULL
    THEN round(EXTRACT(EPOCH FROM (clock_timestamp() - xact_start))::numeric, 2)
    ELSE NULL
  END AS "Transaction duration (secs)",
  CASE
    WHEN query_start IS NOT NULL
    THEN round(EXTRACT(EPOCH FROM (clock_timestamp() - query_start))::numeric, 2)
    ELSE NULL
  END AS "Query duration (secs)",
  COALESCE(wait_event_type, '') AS "Wait event type",
  COALESCE(wait_event, '') AS "Wait event",
  database AS "Database",
  COALESCE(application_name, '') AS "Application name",
  username AS "Username",
  COALESCE(client_addr::text, '') AS "Client address"
FROM google_insights_v2.stat_activity_v3
WHERE state = 'active'
ORDER BY query_start ASC;

停止长时间运行的查询或事务

如需停止在 google_insights_v2.stat_activity_v3 中识别出的长时间运行的查询或被阻止的事务,请将其进程 ID 传递给 pg_terminate_backend:

SELECT pg_terminate_backend(PROCESS_ID);

将 PROCESS_ID 替换为 google_insights_v2.stat_activity_v3 返回的 Process ID (pid) 值。

停用高级 Query Insights

如需停止遥测数据收集,而无需重启 AlloyDB Omni 实例,请将 google_insights_v2.enabled 设置为 off 并重新加载配置:

ALTER SYSTEM SET google_insights_v2.enabled = off;
SELECT pg_reload_conf();

如需从 alloydbadmin 数据库中移除扩展程序对象和存储的历史数据,请连接到 alloydbadmin 并删除扩展程序:

DROP EXTENSION IF EXISTS google_insights_v2 CASCADE;

后续步骤