当前位置:网站首页>建议收藏 | 在openGauss上遇到慢SQL该怎么办?
建议收藏 | 在openGauss上遇到慢SQL该怎么办?
2022-07-01 10:08:00 【openGauss】
在数据库的日常使用中,难免会遇到慢SQL,遇到慢SQL本身并不可怕,困难之处在于如何识别慢SQL并对其优化,使它不至于拖慢整个系统的性能,避免危害到日常业务的正常进行。
对不同的数据库来说,由于其系统架构的差异、代码实现的不同,很多慢SQL解决“套路”往往是无法直接复用的。为此,我们梳理了在openGauss上进行慢SQL分析的经验,并总结了下来,希望能给openGauss的用户一些启发。openGauss的数据库自治运维系统DBMind也已经初步具备了慢SQL根因分析的能力,感兴趣的读者也可以尝试一下。
首先,我们可以通过设置GUC参数log_min_duration_statement 来指定openGauss系统监控的慢SQL阈值。同时,我们也应调大instr_unique_sql_count的数值,以免出现“missing SQL statement, GUC instr_unique_sql_count is too small.”的提示。这里以设置慢SQL检测阈值为5秒(默认数值单位是毫秒)为例:
gs_guc reload -D $PGDATA -c 'log_min_duration_statement = 5000' -c 'instr_unique_sql_count = 2000'
然后执行一个慢SQL,可以在dbe_perf.statement_history视图中查看到结果:
select pg_sleep(6); -- 构造的慢SQL
select * from dbe_perf.statement_history order by start_time desc;
有了上述方法,我们就可以轻易在openGauss数据库中监控到慢SQL了,接下来可以通过下文的方法来分析慢SQL的产生原因。
索引原因导致的慢SQL
由索引原因引起的慢SQL在绝大多数数据库系统中都是十分常见的,甚至可以列为第一大慢SQL问题来源。简单来说,大致存在以下几种情况:
1. 缺乏有效索引
2. 执行计划没有选择索引扫描,即索引失效
3.冗余索引
缺乏有效索引
对于缺乏有效索引的场景,在解决问题时,可以先从SQL语句本身入手,绝大多数此类SQL语句都是SELECT语句,且该类SQL语句涉及到的表数据量较多,且谓词上没有创建索引,导致数据库系统需要通过全盘扫描来获取数据。对于该情况,一般的做法往往比较“暴力”,即直接在WHERE子句、JOIN子句等涉及到的字段上创建索引。一般存在于WHERE子句中的简单比较都是可以使用索引扫描的,因此在该涉及到的字段上创建索引可能是有效的。但是,索引也并非是创建得越多越好(后面我们会提到冗余索引的情况),在创建索引时需要在选择度较高、数据量不是特别少的字段上创建索引,否则该索引收益不大。
对于单语句的索引推荐,openGauss数据库已经内置了该功能,用户可以通过调用系统函数gs_index_advise() 进行推荐,例如:
select * from gs_index_advise('select * from t1 where a > 1');
单语句索引推荐的核心逻辑可以表示为:
对于推荐出来的候选索引,用户可以自行决策是否创建,也可以通过openGauss的虚拟索引功能来评估索引收益,进行辅助决策。
对于单语句的索引推荐,业内也有不少开源的工具。不过,该类工具多数基于MySQL数据库实现(如美团开源的SQL Advisor)。同时,在索引推荐的层次上,该类工具使用的是对SQL语句进行语法解析后的结果,即根据SQL语句的抽象语法树(Abstract Syntax Tree, AST)进行索引推荐。然而,openGauss的索引推荐功能还可以建立在查询解析之后的查询树(Query Tree)的基础上进行索引推荐,也就是说,openGauss的索引推荐是建立在算子粒度上的。这样,某些被优化器改写的SQL语句(如exists, in 子查询),也可以被轻易地捕获并进行索引推荐,而前文提到的基于AST进行索引推荐的工具是很难实现的。
索引失效
就索引失效而言,一般存在以下六种情况:
1. 联合索引(又叫复合索引、多列索引)的最左匹配原则失效:同MySQL类似,openGauss的联合索引也满足最左匹配原则,如果查询不满足最左匹配原则,数据库优化器会倾向于放弃选择该索引扫描;
冗余索引
上面我们提到了创建索引的一般情况,对于绝大多数慢SQL场景,创建一个合适的索引就可以使得性能突飞猛进。但是,索引是不是就可以越多越好呢?显然不是。我们日常创建的索引中,使用最多的是B+ Tree索引,因此我们以B+ Tree为例,简单解释一下缘由。
众所周知,B+ Tree是一个多叉树,它的每一个子节点都是父节点的一个子“范围”。记录(或记录的位置)最终存储在B+ Tree的叶子节点中。因此,在进行数据检索时,只需要扫描匹配的子节点中的指定“范围”即可。但是,对于数据的删除,也需要付出相同的时间开销,进行B+ Tree节点的调整;如果被索引的数据修改了,还需要调整B+ Tree中原有的节点结构。由于B+ Tree的插入、删除、检索的算法时间复杂度都是相同的,因此当业务系统中的插入和删除操作更多时,索引维护的代价就会更大,甚至超过索引检索时带来的收益。与此同时,索引页也需要占用额外的磁盘空间,被索引数据量越大,索引页占据的空间就越大。而且,当前openGauss中的B+ Tree的实现仍然是有锁的,更多的索引页面有可能涉及更多的锁维护操作。
在openGauss数据库中,可以通过下述语句简单识别没有被使用过的索引:
SELECT s.schemaname,
s.relname AS tablename,
s.indexrelname AS indexname,
pg_relation_size(s.indexrelid) AS index_size
FROM pg_catalog.pg_stat_user_indexes s
JOIN pg_catalog.pg_index i ON s.indexrelid = i.indexrelid
WHERE s.idx_scan = 0 -- has never been scanned
AND 0 <>ALL (i.indkey)
AND NOT i.indisunique
AND NOT EXISTS
(SELECT 1 FROM pg_catalog.pg_constraint c
WHERE c.conindid = s.indexrelid)
ORDER BY pg_relation_size(s.indexrelid) DESC;
可以修改上述SQL语句中的 idx_scan 条件中的阈值,来调整返回结果。
对于workload中全量SQL语句进行索引创建其实是非常困难的,因为需要权衡全量SQL中增删查改语句的占比情况,同时需要估计索引的检索收益和维护代价,这个权衡过程十分复杂,一般的人工操作其实是很难的。因此,在日常数据库使用中,当需要创建索引时,最好进行全局业务的评估,衡量是否会干扰到其他业务,以及创建的总体收益是否为正,以免后期难以维护。
不过,对于openGauss数据库来说,可以使用系统级别的索引推荐功能来解决上述痛点问题,可以通过下述命令查看使用说明:
gs_dbmind component index_advisor --help
在系统配置中,最常见的配置项就是对资源的配置。这包括允许使用的最大资源(主要是内存)、以及资源的使用方式等。除了调整资源配置,有些情况下还需要配置数据库优化器Cost Model的代价值。下面我们重点看几个会影响SQL语句成为慢SQL的系统参数:
max_process_memory: 该参数与enable_memory_limit配合使用,用于限制一个openGauss实例可用的最大内存。需要将该参数值与宿主机系统的内存总量进行匹配,将宿主机用于操作系统正常运行所需的内存刨除后,剩下的内存空间就可以尽可能多地划分给openGauss实例使用了。否则,openGauss为了避免造成OOM问题,会通过该参数限制数据库允许使用的最大内存。因此,如果在客户端或者日志中出现类似“memory usage reach the max_dynamic_memory”的报错时,一般是由于该参数值太小导致的。
shared_buffers: 数据库系统使用的缓存池大小。一般来说,综合来看对数据库影响最大的参数就是它了,因为如果该参数设置得过小,会导致缓存不足,从而产生大量的磁盘I/O. 该参数在openGauss上的默认值很小,只有32MB,对于绝大多数的生产场景是不够的。一般的经验值是设置为系统内存的25%, 甚至在某些场景中还可以再大一点。不过openGauss的buffer没有通过DirectIO实现,仍然使用了系统缓存(cache),所以一般认为超过系统内存的40%也起不到再好的效果了。与此同时,checkpoint_segments 参数也需要随着shared_buffers的调大跟着变大一些。
work_mem: 显式指定内排序和哈希表能使用的内存空间大小,如果该值设得比较小,会向磁盘写入更多的临时文件。因此,我们可以适当地增加该值的大小。但是需要注意的是,业务系统可能存在并行执行的复杂语句,如果这些语句都占用非常多的work_mem大小的资源,则可能会导致内存使用占满(如前文所述,openGauss存在内存管控机制,一般不至于由于OOM导致系统重启)。故而,该值设置得很大的时候要关注系统的并发问题。该参数对ORDER BY, DISTINCT, JOIN (merge join, hash join), HASH Agg, 基于hash的IN子查询都有影响。
enable_nestloop: 开启该参数可以让优化器使用Nest Loop Join(NLJ), 但是关闭该参数也不会完全压制优化器选择NLJ. 对于某些复杂查询(如在TPC-H benchmark中的语句)来说,不应该选择NLJ, 但是优化器往往会出现规划错误。那么,在此场景下,可以通过禁用该参数来鼓励优化器选择使用其他JOIN方法。
random_page_cost: 一般与seq_page_cost配合调整。该参数调整数据库的CBO优化器中随机扫描的代价。该值设置得越大,数据库越认为随机扫描不可取,也就越不倾向于使用索引。该参数的默认值是4,对于机械硬盘来说,是合适的。但是,如果业务系统的磁盘是固态硬盘的话,就应该适当调小一下该参数值,一般的经验是调整为1.
default_statistics_target: 当前openGauss的默认优化器是CBO, 它高度依赖数据的统计信息。因此,对于复杂查询来说,更优质的统计信息往往可以获得更好的执行计划。通过增大该参数的值,可以获得更准确的统计信息,但是也会增加ANALYZE的时间。因此,对于复杂语句较多的场景,可以适当增加该参数值。
除了上述列出来的可能会影响SQL语句执行表现的系统参数外,还有很多参数可能会产生影响。不过,影响概率会小很多。如果用户希望检查一下数据库的参数配置是否合理,可以通过DBMind的参数推荐功能测试一下(该功能依赖当前正在运行的业务量,故不同时刻执行的效果可能会不同,建议在业务高峰时使用),相关使用帮助是:
gs_dbmind component xtuner recommend –help
如果用户希望针对自己的业务试探出最合适的参数,也可以使用离线模式(tune或train模式)。不过该场景一般是对未上线的业务系统进行初始调参,因为执行该功能可能会影响业务运行,故称之为离线模式。
当系统同时执行某些SQL语句的时候,它们可能会互相影响,进而导致某些SQL语句变为慢SQL, 这就是典型的资源竞争导致的慢SQL. 同时,不仅数据库中的语句们可能会进行资源竞争。在混合部署的环境中,操作系统上的其他任务也可能会影响数据库系统的表现。
对于一般的等待事件(wait event)来说,openGauss具备等待事件的记录视图,用户可以通过下列方法从宏观上查看Top级别的等待事件:
select * from dbe_perf.wait_events order by total_wait_time desc;
一般来说,对于数据库外部原因导致的资源竞争包括CPU、内存、IO的竞争,最典型的情况是IO风暴(Freeze IO)、CPU的计算资源的占用等。对于这种情况,一般不要将数据库与其他业务系统混合部署即可避免。
比较困难的是,数据库自己的某些任务之间互相影响,例如锁竞争、IO竞争等。
数据库中的不同SQL语句对锁资源进行占用,阻塞了其他语句的正常执行,导致SQL语句变慢了,甚至还会触发死锁检测。比较简单的排查当前锁占用情况的SQL语句是:
SELECT c.relkind,
d.datname,
c.relname,
l.mode,
s.query,
extract(epoch
FROM pg_catalog.now() - s.xact_start) AS holding_time
FROM pg_locks AS l
INNER JOIN pg_database AS d ON l.database = d.oid
INNER JOIN pg_class AS c ON l.relation = c.oid
INNER JOIN pg_stat_activity AS s ON l.pid = s.pid
WHERE s.pid != pg_catalog.pg_backend_pid();
值得一提的是,openGauss并不支持pg_blocking_pids 函数。所以,通过该函数是无法查看到锁等待情况的。
下图展示了通过DBMind提供的openGauss-exporter监控到的数据库持锁情况:

还有一种情况是IO使用受到影响,例如系统正在进行IO操作时,执行某条SQL语句,该SQL语句对磁盘的访问被阻塞了。典型的数据库系统IO操作包括Analyze, Vacuum以及checkpoint 等。openGauss为此做了很多优化,例如增量checkpoint, 使用更大的版本号等(可以避免大量的autovacuum for prevent wrap)。
当然,除了上面列出的情况外,还存在并发量接近或超过系统负荷导致的性能下降和拒绝服务。例如,大量复杂查询语句对CPU资源的竞争、大并发情况下引起数据库的响应时间变慢等。
就资源竞争引起的慢SQL来说,基本都可以通过系统指标来发现。例如监控慢SQL发生时刻的CPU、内存、IO、锁、网络等的使用情况,根据该慢SQL发生的背景信息即可推断出该慢SQL是否由资源竞争导致的,以及是何资源短缺导致的。对于openGauss来说,DBMind提供了非常强大的数据库指标采集功能,即DBMind与Prometheus平台适配的exporter. 用户可以直接通过下述命令查看exporter的启动参数:
openGauss-exporter: 用于采集数据库指标,除常规指标外,还能监控慢SQL、系统配置等。
gs_dbmind component opengauss_exporter --help
reprocessing-exporter: 可以对Prometheus中已经采集到的指标进行聚合,例如计算QPS、内存使用率等。
gs_dbmind component reprocessing_exporter --help
注意:openGauss对于采集指标也进行了权限隔离,必须要求openGauss-expoter连接的用户具有sysadmin, monadmin 权限才可以获取某些监控表的指标。
尽管openGauss对于大的行存表处理性能非常优秀,但表本身的数据情况依然是导致慢SQL的重要原因。一般来说,具有以下几种情况:
5. 频繁的数据修改,导致表中存在很多死元组(dead tuple),影响扫描性能;
表的数据量较大导致的慢SQL问题,一般需要从业务上进行入手,直接通过修改数据库来达到优化慢SQL的目的是很难实现的。因此,需要用户分析具体的业务,对业务数据进行冷热分离、分库分表、使用分布式中间件等。如果希望在数据库层进行优化,则可以通过增加宿主机的内存,进而增加max_process_memory、shared_buffers、work_mem等的大小;使用性能更佳的磁盘;适当创建索引;使用表空间调整磁盘布局等。
由SQL语句写法问题导致的慢SQL也相对多见,这类写得比较差的慢SQL也被俗称为“烂SQL”。多数情况都下,由“烂SQL”导致的索引失效的问题较多,对于这种情况,可参考前面的描述对SQL语句进行改写,使其能够使用到索引。
除了修改慢SQL使其能够使用索引,下面还列出了几种比较常见的、可能优化openGauss数据库性能的SQL改写规则:
改写规则 | 改写条件 | 改写说明 | 原始查询语句示例 | 改写后语句示例 |
将'select distinct *'改写为'select *' | 所查询表格含唯一列或主键 | 通过确定tuple无重复,去掉distinct,从而省去去重步骤,提升效率 | select distinct * from bmsql_customer limit 10; | select * from bmsql_customer limit 10; |
将having子句中条件放到where子句中 | - | 将谓词表达式提前,可有效缩减group时的数据集 | select cfg_name from bmsql_config group by cfg_name having cfg_name='1' | select cfg_name from bmsql_config where cfg_name = '1' group by cfg_name |
简化where子句中谓词表达式 | - | 某些复杂谓词无法有效触发openGauss内的rewrite逻辑,无法使用索引扫描 | select o_w_id, o_d_id, o_id, o_c_id from bmsql_oorder where o_w_id + 1> 3 | select o_w_id, o_d_id, o_id, o_c_id from bmsql_oorder where o_w_id > 2 |
将order by或group by中的无用列去掉 | group by或order by涉及的列包含在where子句中的等值表达式中 | 去掉无用字段,SQL更为简洁 | select cfg_name from bmsql_config where cfg_name='2' group by cfg_name order by cfg_name, cfg_value | select cfg_name from bmsql_config where cfg_name = '2' order by cfg_value |
去掉where子句中永为真的表达式 | - | 去掉无用字段,SQL更为简洁 | select * from bmsql_config where 1=1 and 2=2 limit 10 | select * from bmsql_config limit 10 |
将union转换为union all | - | 避免了去重带来的执行代价 | select * from bmsql_config union select * from bmsql_config | select * from bmsql_config union all select * from bmsql_config |
将delete语句转换为truncate语句 | 无where子句 | 将DML语句转换为DDL语句,一次性回收表空间,执行速度更快 | delete from bmsql_config | truncate table bmsql_config |
将where子句中'or'连接的等式转换为'in'结构 | - | 'in'结构可加快过滤速度 | select * from bmsql_stock where s_w_id=10 or s_w_id=1 or s_w_id=100 or s_i_id=1 or s_i_id=10 | select * from bmsql_stock where s_w_id in (1,10,100) or s_i_id in(1,10) |
将self join查询拆分为效率更高两个子查询 | 1) self join查询。 2) where子句包含相同列差值的范围查询。 例如1<a.id-b.id<10,其中a,b为同一个表的两个alias。 | 通过等值谓词加快查询速度 | select a.c_id from bmsql_customer a, bmsql_customer b where a.c_id - b.c_id <= 20 and a.c_id > b.c_id | select * from (select a.c_id from bmsql_customer as a, bmsql_customer as b where trunc((a.c_id) / 20) = trunc(b.c_id / 20) and a.c_id > b.c_id union all select a.c_id from bmsql_customer as a, bmsql_customer as b where trunc((a.c_id) / 20) = trunc(b.c_id / 20 + 1) and a.c_id - b.c_id <= 20) |
对于业务系统,SQL语句上线之前的审计工作基本都可以覆盖上述的场景,业内也具备很多对SQL语句进行改写的工具,不过这些工具的一些改写规则并不是绝对意义上的等值改写。而且,很多改写条件对于openGauss来说不见得有效,因为openGauss在数据库内部也存在rewrite逻辑。
DBMind平台会进一步演进SQL语句的智能改写功能,提供给用户在线的交互式智能查询改写能力,预计在未来的版本中与用户见面。
总结
我们在上面已经列出了能够导致慢SQL的原因,基本覆盖了在openGauss上造成慢SQL的大多数原因。不过,one-by-one 手动地进行慢SQL检查对于用户来说工作量确实太大。故而,openGauss的DBMind功能本身已经集成了对慢SQL进行智能根因识别的能力,用户可以通过运行下述命令在后台启动慢SQL根因分析功能(需要首先部署Prometheus以及expoter,以便能够采集到监控指标):
gs_dbmind service start -c confpath --only-run slow_query_diagnosis
注:显式指定 --only-run 参数可以仅启动被选择的DBMind服务项
被诊断后的慢SQL会存储在元数据库(存放诊断结果的数据库)中,用户可以通过下述命令查看:
gs_dbmind component slow_query_diagnosis show -c confpath --query SQL --start-time timestamps0 --end-time timestamps1
也可以通过与Grafana联合来展示慢SQL的分析结果,DBMind也提供了简单的Grafana配置模板,可供用户参考:
https://github.com/opengauss-mirror/openGauss-server/blob/master/src/gausskernel/dbmind/tools/misc/grafana-template-slow-query-analysis.json
由于openGauss官方网站的发行包中的DBMind可能滞后于代码托管平台(gitee或github)上的最新代码,直接编译openGauss又需要花费很多的时间。故而,如果用户只是想单纯提取最新的DBMind功能,可以通过下面的Linux命令来实现:
git clone -b master --depth 1 https://gitee.com/opengauss/openGauss-server.git
cd openGauss-server/src/gausskernel/dbmind/
mv tools dbmind
tar zcf dbmind.tar.gz gs_dbmind dbmind
将生成的dbmind.tar.gz 压缩包在合适的部署位置解压即可。
当然,如果用户希望手动检查一下慢SQL的原因,也可以根据附表的检查项来检查慢SQL的产生原因。
附表:慢SQL检查列表
检查项 | 检查方式(系统表或系统视图) | 检查方法 |
语句执行时存在锁竞争 | dbe_perf.statement_history(start_time,finish_time, query)、pg_locks(pid, mode, locktype, grant)、pg_stat_activity(xact_start, query_start, query, pid) | 查询在语句执行期间是否被阻塞。 |
表中死元组占比超过设定阈值 | dbe_perf.statement_history(query, dbname, schemaname) pg_stat_users_tables(relname, schemaname,n_live_tup, n_dead_tup) | n_dead_tup / n_live_tup,占比超过阈值则认为表过度膨胀 (默认阈值:0.2)。 |
语句扫描行数较多 | dbe_perf.statement_history(n_tuples_fetched, n_tuples_returned, n_live_tup, n_dead_tup) | n_tuples_fetched+n_tuples_returned,超过阈值则认为过大(默认阈值:10000)。 |
语句缓存命中率较低 | dbe_perf.statement_history(n_blocks_fetched, n_blocks_hit) | n_block_hit / n_block_fetched,小于阈值则认为较低(默认阈值:0.95) |
慢SQL(delete、insert、update)相关表存在冗余索引 | dbe_perf.statement_history(dbname, schemaname, query), pg_stat_user_indexes(schemaname, relname, indexrelname, idx_scan, idx_tup_read, idx_tup_fetch) pg_indexes(schemaname, tablename, indexname, indexdef) | SQL相关表满足:① 不是唯一索引;② (idx_scan, idx_tup_read,idx_tup_fetch)=(0,0,0);③ 索引不在数据库的('pg_catalog', 'information_schema','snapshot', 'dbe_pldeveloper')schema下。如果满足则认为次索引为冗余索引,否则为有效索引。 |
更新数据量较多 | dbe_perf.statement_history(query, n_tuples_updated) pg_stat_user_tables(n_live_tup, n_dead_tup) | n_tuples_updated超过阈值则认为更新数据量较多(默认阈值:1000)。 |
插入数据量较多 | dbe_perf.statement_history(query, n_tuples_inserted) pg_stat_user_tables(n_live_tup, n_dead_tup) | n_tuples_inserted超过阈值则认为插入数据量较多(默认阈值:1000)。 |
删除数据量较多 | dbe_perf.statement_history(query, n_tuples_deleted) pg_stat_user_tables(n_live_tup, n_dead_tup) | n_tuples_deleted超过阈值则认为删除数据量较多(默认阈值:1000)。 |
相关表索引个数较多 | pg_stat_user_indexes(relname,schemaname, indexrelname) | 如果表中索引数大于阈值并且索引与字段数比率超过设定阈值,则认为索引数较多(索引个数阈值:3,比率默认阈值:0.6)。 |
执行语句发生落盘(外排序)行为 | dbe_perf.statement(sort_count, sort_spilled_count, sort_mem_used, hash_count, hash_spilled_count, hash_ued_mem, n_calls) | 分析指标判断是否有hash或者order导致的落盘行为,主要逻辑为: 1 如果sort_count或者hash_count不为0,sort_mem_used或者hash_mem_used为0,则此SQL一定发生了落盘行为; 2 如果sort_spilled_count或者hash_spilled_count不为0,则执行可能发生落盘行为; |
语句执行期间相关表正在执行AUTOVACUUM或AUTOANALYZE操作 | dbe_perf.statement_history(start_time, finish_time, query) pg_stat_user_tables(last_autovacuum, last_autoanalyze) | 执行SQL期间,正在发生vacuum或者analyze行为。 |
数据库TPS较大 | dbe_perf.statement_history(start_time, finish_time) pg_stat_database(datname, xact_commit, xact_rolback) | 相对于正常业务时的TPS,当前TPS增长较大,则认为数据库TPS较大;TPS短期内增长异常则认为是业务风暴。 |
IOWait指标大于设定阈值 | 系统IOWait指标异常升高 | IOWait大于用户设定阈值(默认阈值:10%) |
IOPS指标大于设定阈值 | 系统IOPS指标异常 | IOPS指标大于用户设定阈值(默认阈值:1000)。 |
load average指标大于设定阈值 | 系统load average指标异常 | load average与服务器逻辑核数比率大于用户设定阈值(默认阈值:0.6)。 |
CPU USAGE指标大于设定阈值 | 系统CPU USAGE指标异常 | CPU USAGE指标大于用户设定阈值(默认阈值:0.6)。 |
IOUTILS指标大于设定阈值 | 系统IOUTILS指标异常 | IOUTILS(磁盘利用率)大于用户设定阈值(默认阈值:0.5)。 |
IOCAPACITY指标大于设定阈值 | 系统IO CAPACITY指标异常 | IOCAPACITY(IO吞吐量)大于用户设定阈值(默认阈值:50MB/s)。 |
IODELAY指标大于设定阈值 | 系统IO DELAY指标异常 | IO DELAY(IO延迟)大于用户设定阈值(默认阈值:50ms)。 |
网卡丢包率 | 系统网卡丢包率异常 | NETWORK DROP RATE大于用户设定阈值(默认0阈值:0.01)。 |
网卡错误率 | 系统网卡错误率异常 | NETWORK ERROR RATE大于用户设定阈值(默认阈值:0.01)。 |
线程池占用量异常 | dbe_perf.global_threadpool_status | 数据库线程池使用率大于阈值(默认阈值:0.95) |
连接池占用量异常 | pg_settings.max_connections,pg_stat_activity | 数据库连接池占用率大于阈值(默认阈值:0.8) |
双写延迟较大 | dbe_perf.wait_events | 双写延迟大于阈值(默认阈值:100us) |
表长时间未更新 | pg_stat_user_tables | 表未更新时长超过阈值(默认阈值:60s) |
checkpoint效率低(本规则仅作为粗略判断) | pg_stat_bgwriter | 数据库buffers_backend与(buffers_clean+buffers_checkpoint)占比小于阈值(默认阈值:1000) |
主备复制效率较低 | pg_stat_replication | 主备write_diff、replay_diff、sent_diff超过阈值(默认阈值:500000) |
执行计划存在异常seqscan算子 | 执行计划 | seqscan算子代价与总代价比率超过阈值(默认阈值:0.3),此特征也会判断是否缺少相关索引。 |
执行计划存在异常nestloop算子 | 执行计划 | nestloop算子代价与总代价比率超过阈值(默认阈值:0.3)并且进行nestloop的结果集行数超过阈值(默认阈值:10000)。 |
执行计划存在异常hashjoin算子 | 执行计划 | hashjoin算子代价与总代价比率超过阈值(默认阈值:0.3)并且进行hashjoin的结果集小于阈值(默认阈值:10000)。 |
执行计划存在异常groupagg算子 | 执行计划 | groupagg算子代价与总代价比率超过阈值(默认阈值:0.3)并且执行groupagg的行数超过阈值(默认阈值:10000)。 |
SQL写法不优 | SQL文本、pg_stat_user_tables | SQL写法不优导致执行性能较差 |
SQL执行被定时任务影响 | pg_job, dbe_perf.statement_history | 定时任务执行影响了SQL执行性能,考虑调整定时任务时间,避免产生影响。 |
执行计划生成时间较长 | dbe_perf.statement_history | SQL执行计划生成时间较长。 |
参考资料
[1].https://www.2ndquadrant.com/en/blog/managing-freezing/
[2]. http://mysql.taobao.org/monthly/2016/06/03/
[3].https://www.2ndquadrant.com/en/blog/basics-of-tuning-checkpoints/
[4]. https://lwn.net/Articles/591723/
[5].https://dev.mysql.com/doc/refman/8.0/en/glossary.html
[6].https://github.com/opengauss-mirror/openGauss-server/tree/master/src/gausskernel/dbmind
本文分享自微信公众号 - openGauss(openGauss)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
边栏推荐
- Zero foundation software testing must see, 10 years of testing old bird's conscience suggestions (a total of 15)
- 哪个券商公司炒股开户佣金低又安全又可靠
- Graduation summary of actual combat camp
- Japanese professor sues Intel FPGA and SOC products for infringing a design patent
- 一个悄然崛起的国产软件,低调又强大!
- 新数据库时代,不要只学 Oracle、MySQL
- CSDN's one-stop cloud service is open for internal testing, and new and old users are sincerely invited to grab the fresh
- Precautions for lvgl v8.2 string display on keil MDK (take little bear pie as an example)
- Introduction of uniapp wechat applet components on demand
- scratch大鱼吃小鱼 电子学会图形化编程scratch等级考试二级真题和答案解析2022年6月
猜你喜欢
Programmers want to go to state-owned enterprises? The technology is backward and the salary is low. I can't find a job after lying flat for several years
IDEA运行报错Command line is too long. Shorten command line for...
硬件中台项目
机器学习之线性回归详解
【黑马早报】俞敏洪称从来不看新东方股价;恒驰5将于7月开启预售;奈雪虚拟股票或涉嫌非法集资;7月1日起冰墩墩停产...
Packetdrill script analysis guide
Finally, someone made it clear what DRAM and NAND flash are
Wechat emoticons are written into the judgment, and the OK and bomb you send may become "testimony in court"
Kotlin 协程调度切换线程是时候解开真相了
SQL SERVER2014删除数据库失败,报错偏移量0x0000...
随机推荐
PHP code audit and File Inclusion Vulnerability
树莓派4B系统搭建(超详细版)
CSDN's one-stop cloud service is open for internal testing, and new and old users are sincerely invited to grab the fresh
请问有没有人知道clickhouse 中 limit语句执行的逻辑,图片中,上面的SQL可以执行成功
哪个券商公司炒股开户佣金低又安全又可靠
Eat a rich woman's melon...
Cortex M4 systick details
SQL 化是 ETL 增量生产的第一步,这样的架构的核心能力是什么?
CSDN一站式云服务开放内测,诚邀新老用户来抢鲜
机器学习之线性回归详解
【论文阅读】Trajectory-guided Control Prediction for End-to-end Autonomous Driving: A Simple yet Strong Ba
Network partition notes
在通达信上买基金安全吗?
What should I learn in the zero foundation entry test? It's the most comprehensive. Just learn from it
Flinkv1.13 implementation of financial anti fraud cases
这样理解mmap,挺有意思!
【黑马早报】俞敏洪称从来不看新东方股价;恒驰5将于7月开启预售;奈雪虚拟股票或涉嫌非法集资;7月1日起冰墩墩停产...
4hutool practice: dateutil format time [easy to understand]
SQL statement modify field type "suggestions collection"
Postgraduate entrance examination vocabulary 2023 sharing (1)