查询统计
本文档主要介绍了 YMatrix 查询统计功能的部署、表结构、使用、配置及停止。当你发现数据库查询变得缓慢,或者想更合理地规划数据库资源使用的时候,可以通过此功能来实现优化。
mxstat 查询统计功能包括以下内容:
- SQL 语句执行情况,如查询耗时等。
- 计算资源消耗的统计信息。
启用查询统计功能
YMatrix 集群初始化后会默认创建 matrixmgr
数据库和 matrixmgr
扩展,默认启用该功能。
如需手动启用,则参考以下命令。
=# createdb matrixmgr
=# psql -d matrixmgr
matrixmgr=# CREATE EXTENSION matrixmgr CASCADE;
NOTICE: installing required extension "matrixts"
CREATE EXTENSION
可用视图
部署成功后,在 matrixmgr
数据库的 matrixmgr_internal
模式下会出现如下表和视图:
视图 | 描述 |
---|---|
mxstat_execute | 这张视图提供了 SQL 语句的执行情况,比如 SQL 语句执行的节点实例,用户,查询文本,执行的最长最短时间,以及最慢语句的各阶段时间戳。你可以通过这张表看来不同 SQL 语句执行时间,以及分析最慢语句的情况 |
mxstat_usage | 这张视图提供了SQL语句执行时计算资源的消耗情况 |
mx_query_execute_history | 这张视图是 mxstat_execute 视图的历史信息 |
mx_query_usage_history | 这张视图是 mxstat_usage 视图的历史信息 |
mx_querytext | 这张视图存储了 queryid 与 querytext 的映射,你可以通过这个映射获取 SQL 文本 |
mx_query_execute_history_with_text | 将 mx_query_execute_history 与 mx_querytext 通过 queryid 进行关联后的视图 |
每个视图的具体信息请见 matrixgmr 扩展。
示例
以下三个示例可以帮助你循序渐进地查看SQL语句的执行情况及其所消耗资源。
示例 1
- 执行如下 3 条 SQL 语句,让数据库服务器进程分别暂停 5、10 和 15 秒:
=# SELECT pg_sleep(5);
=# SELECT pg_sleep(10);
=# SELECT pg_sleep(15);
- 查询
mxstat_execute
视图里的统计信息。从查询结果可以看到:
- 查询开始 (
calls_begin
) 和结束(calls_end
) 都为3
,查询被调用了 3 次。 - 查询文本进行了归一化,将时间参数替换成了
$ +
参数序号。 - 根据最慢一次查询执行各个阶段的时间戳,前后两次查询中间休息了 15 秒,即跟
SELECT pg_sleep(15);
对应。
matrixmgr=# SELECT * FROM matrixmgr_internal.mxstat_execute WHERE query LIKE '%pg_sleep%';
seg | userid | dbid | queryid | nestlevel | query | calls_begin | calls_alive | calls_end | total_time | min_time
| max_time | mean_time | stddev_time | sample_planid | sample_start | sample_parse_done |
sample_plan_done | sample_exec_start | sample_exec_end
-----+--------+-------+----------------------+-----------+---------------------+-------------+-------------+-----------+------------+----------
+-----------+--------------------+-------------------+----------------------+-------------------------------+-------------------------------+--
-----------------------------+-------------------------------+-------------------------------
-1 | 10 | 16384 | -2007749946425010549 | 0 | select pg_sleep($1) | 3 | 0 | 3 | 30041 | 5009.054
| 15018.717 | 10013.666666666666 | 4086.427819588182 | -2693056513545111817 | 2022-03-25 13:58:58.503851-04 | 2022-03-25 13:58:58.503933-04 | 2
022-03-25 13:58:58.503994-04 | 2022-03-25 13:58:58.504008-04 | 2022-03-25 13:59:13.522725-04
(1 row)
- 用
queryid
做关联,通过mxstat_usage
查看该语句资源使用情况。从查询结果可以看到仅有一条seg = -1
的记录,代表该查询仅在 Master 上执行过。
matrixmgr=# SELECT * FROM matrixmgr_internal.mxstat_usage WHERE queryid = -2007749946425010549;
seg | userid | dbid | queryid | nestlevel | rows | shared_blks_hit | shared_blks_read | shared_blks_dirtied | shared_blks_writte
n | local_blks_hit | local_blks_read | local_blks_dirtied | local_blks_written | temp_blks_read | temp_blks_written | blk_read_time | blk_write
_time | ru_utime | ru_stime | ru_maxrss | ru_ixrss | ru_idrss | ru_isrss | ru_minflt | ru_majflt | ru_nswap | ru_inblock | ru_oublock | ru_msgs
nd | ru_msgrcv | ru_nsignals | ru_nvcsw | ru_nivcsw
-----+--------+-------+----------------------+-----------+------+-----------------+------------------+---------------------+-------------------
--+----------------+-----------------+--------------------+--------------------+----------------+-------------------+---------------+----------
------+----------+----------+-----------+----------+----------+----------+-----------+-----------+----------+------------+------------+--------
---+-----------+-------------+----------+-----------
-1 | 10 | 16384 | -2007749946425010549 | 0 | 3 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0.001297 | 0.000431 | 20568 | 0 | 0 | 0 | 6 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 122 | 0
(1 row)
示例 2
- 用以下命令创建一个
test1
表。
=# CREATE TABLE test1(
c1 int,
c2 int
)
USING MARS3
DISTRIBUTED BY(c1)
ORDER BY(c1);
- 查询
mxstat_execute
的统计信息。
matrixmgr=# SELECT * FROM matrixmgr_internal.mxstat_execute WHERE query LIKE '%create table test1%';
seg | userid | dbid | queryid | nestlevel | query | calls_begin | calls_alive |
calls_end | total_time | min_time | max_time | mean_time | stddev_time | sample_planid | sample_start | sample_parse_done | sa
mple_plan_done | sample_exec_start | sample_exec_end
-----+--------+-------+----------------------+-----------+-------------------------------------------------------+-------------+-------------+-
----------+------------+----------+----------+-----------+-------------+---------------+-------------------------------+-------------------+---
---------------+-------------------------------+-------------------------------
-1 | 10 | 16384 | -6276724884379903029 | 0 | create table test1(c1 int, c2 int) distributed by(c1) | 1 | 0 |
1 | 46.221 | 46.221 | 46.221 | 46.221 | 0 | 0 | 2022-03-25 14:08:51.754458-04 | |
| 2022-03-25 14:08:51.754735-04 | 2022-03-25 14:08:51.800956-04
(1 row)
- 用
queryid
做关联,通过mxstat_usage
查看该语句资源使用情况。从查询结果可以看到,所有节点都记录了资源使用状况,代表数据资源分布存储在不同数据节点实例中。
matrixmgr=# SELECT * FROM matrixmgr_internal.mxstat_usage WHERE queryid = -6276724884379903029;
seg | userid | dbid | queryid | nestlevel | rows | shared_blks_hit | shared_blks_read | shared_blks_dirtied | shared_blks_writte
n | local_blks_hit | local_blks_read | local_blks_dirtied | local_blks_written | temp_blks_read | temp_blks_written | blk_read_time | blk_write
_time | ru_utime | ru_stime | ru_maxrss | ru_ixrss | ru_idrss | ru_isrss | ru_minflt | ru_majflt | ru_nswap | ru_inblock | ru_oublock | ru_msgs
nd | ru_msgrcv | ru_nsignals | ru_nvcsw | ru_nivcsw
-----+--------+-------+----------------------+-----------+------+-----------------+------------------+---------------------+-------------------
--+----------------+-----------------+--------------------+--------------------+----------------+-------------------+---------------+----------
------+----------+----------+-----------+----------+----------+----------+-----------+-----------+----------+------------+------------+--------
---+-----------+-------------+----------+-----------
-1 | 10 | 16384 | -6276724884379903029 | 0 | 0 | 295 | 59 | 21 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0.004053 | 0 | 22744 | 0 | 0 | 0 | 429 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 6 | 0
1 | 10 | 16384 | -6276724884379903029 | 0 | 0 | 261 | 82 | 19 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0.001691 | 0.001558 | 19284 | 0 | 0 | 0 | 510 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 1
0 | 10 | 16384 | -6276724884379903029 | 0 | 0 | 314 | 34 | 19 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0.002537 | 0.000193 | 18508 | 0 | 0 | 0 | 574 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 1 | 1
2 | 10 | 16384 | -6276724884379903029 | 0 | 0 | 261 | 82 | 19 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0.003043 | 2.9e-05 | 19292 | 0 | 0 | 0 | 514 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 2
(4 rows)
示例 3
示例 1 和 2 里面,mxstat_execute
中的 nestlevel
值都为 0
,因为查询执行都没有嵌套。下面构造一种嵌套执行的例子。嵌套执行通常是通过调用用户定义函数(User Defined Functions,简称 UDF) 来实现。
- 创建名为
nest_query
的 UDF,函数定义了 SQL 语句SELECT 1
,然后调用该 UDF。
=# CREATE OR REPLACE FUNCTION nest_query() RETURNS SETOF RECORD
AS $$ SELECT 1;$$
LANGUAGE SQL;
注意!
mxstat 默认不会记录嵌套信息,需要将 mxstat_statements.track
参数设置为 'all'
。
- 查询内部语句
SELECT 1
的执行信息。从返回的结果中可以看到:
- 从返回的结果中可以看到查询文本为
SELECT $
,这是因为1
是常量,归一化后的查询会用$1
替换。 nestlevel
的值为1
,因为嵌套调用的深度为 1。如果嵌套更深的话,nestlevel
的值会更大,matrixmgr 最深会记录到第 31 层。
matrixmgr=# SELECT * FROM matrixmgr_internal.mxstat_execute WHERE query LIKE '%SELECT $1%';
seg | userid | dbid | queryid | nestlevel | query | calls_begin | calls_alive | calls_end | total_time | min_time | max_time
| mean_time | stddev_time | sample_planid | sample_start | sample_parse_done | sample_plan_done
| sample_exec_start | sample_exec_end
-----+--------+-------+----------------------+-----------+-----------+-------------+-------------+-----------+------------+----------+---------
-+-----------+-------------+---------------------+-------------------------------+-------------------------------+-----------------------------
--+-------------------------------+-------------------------------
-1 | 10 | 16384 | -4554727679305370053 | 1 | SELECT $1 | 1 | 0 | 1 | 0.031 | 0.031 | 0.031
| 0.031 | 0 | -382705668420232707 | 2022-03-25 14:35:30.668124-04 | 2022-03-25 14:35:30.668373-04 | 2022-03-25 14:35:30.668403-0
4 | 2022-03-25 14:35:30.668408-04 | 2022-03-25 14:35:30.668439-04
(1 row)
停用查询统计功能
注意!
停止查询统计功能无需停止或重启数据库。
- 停止 Master 上的后台采集进程。
$ psql -d matrixmgr -c "SELECT matrixmgr_internal.mxstat_stop_worker();"
- 全局关闭采集功能并使其生效。
$ gpconfig -s mxstat_statements.track
$ gpconfig -c mxstat_statements.track -v none
$ mxstop -u
注意!
使用以上两个步骤只是暂时停用了查询统计功能,再次启动集群还会默认启用。如果你要永久关闭,则需要在执行 mxstop -u
之后,执行 gpconfig -c mxstat_statements.start_reaper_on_start -v false
。
- 清空已经采集到的数据。
$ psql -d matrixmgr -c "SELECT matrixmgr_internal.mxstat_reset();"
- 如需重启后台采集进程,则执行以下命令。(可选)
$ psql -d matrixmgr -c "SELECT matrixmgr_internal.mxstat_start_worker();"
附录
统计结果分类
matrixmgr 在统计 SQL 语句执行情况的时候,并不会记录每条查询,而是将一类查询统一汇总记录,呈现的统计信息按照解析结果进行归类。
只有参数不同的 SQL语句归为一类。如下示例,三条 INSERT
语句都是向 test1
表插入数据,只是参数不同。这三条语句会归为同一类,生成相同的 queryid
。
=# INSERT INTO test1 VALUES(1);
=# INSERT INTO test1 VALUES(2);
=# INSERT INTO test1 VALUES(3);
如下查询只是条件参数不同,其他都一样,也会归为一类。
=# SELECT * FROM test1 WHERE c1 = 1;
=# SELECT * FROM test1 WHERE c1 = 2;
=# SELECT * FROM test1 WHERE c1 = 3;
如下查询虽然相似,但是查询的是不同的表,不能归为一类。
=# SELECT * FROM test1 WHERE c1 = 1;
=# SELECT * FROM test2 WHERE c1 = 1;
=# SELECT * FROM test3 WHERE c1 = 1;
配置
查询统计包含了如下参数,用来控制监控行为。
参数 | 类型 | 描述 |
---|---|---|
mxstat_statements.max | 整型 | 存储查询时间的哈希槽位。该参数代表最多在内存中可存储的查询数量,默认值为 5000 |
mxstat_statements.usage_multiple | 整型 | 存储查询资源信息的哈希槽位相对于查询时间哈希槽位的倍数。默认值为 2 |
mxstat_statements.track | 字符串 | top :只跟踪第一层,不进行嵌套跟踪(默认);all :跟踪全部;none :不跟踪,相当于关闭了该功能 |
mxstat_statements.track_utility | 布尔 | 是否跟踪 utility 语句的执行。默认为 true |
mxstat_statements.save | 布尔 | 当集群重启的时候是否将共享内存中的信息转储到文件。默认为 true |
mxstat_statements.harvest_interval | 整型 | 查询统计信息默认在共享内存里,会周期收集到历史表中,该参数用来设置采集周期。默认为 5 分钟 |
mxstat_statements.harvest_usage | 布尔 | 是否收集 usage 信息。默认为 true |
mxstat_statements.ignored_databases | 字符串 | 忽略的数据库,默认值为 template0,template1,matrixmgr |
mxstat_statements.start_reaper_on_start | 布尔 | 决定是否在启动集群的时候启动 reaper 进程。该进程周期性地将收集好的信息存入 mxstat_execute ,mxstat_usage,mx_query_execute_history ,mx_query_usage_history ,mx_querytext ,和 mx_query_execute_history_with_text 表 |