本文转载自微信公众号《数据与云》,作者高云龙。转载本文请联系数据和云公众号。前提当我们在压力测试中收到数据库响应慢或者数据库报错的反馈时,第一步就是收集数据库服务器的资源使用情况。该步骤是处理所有故障的前提。--loadtopcommandhtopcommand--cpulscpucommand--memorysizefree-g--disksizedf-Th--diskusagetrackingnohupiostat-xmt1>iostat.log2>&1&--networkdelaybetweenapplicationanddatabase网络延迟,集群内主库和同步备库之间的网络延迟nohuppingtargetip|awk'{print$0"\t"strftime("%Y-%m-%d%H:%M:%S",systime())}'>ping.log2>&1&*模拟网络延迟知识*模拟同城机房网络延迟为0.7ms~0.9ms;添加网络延迟模拟:tcqdiscadddevenp23s0f1(networkcard)rootnetemdelay0.8ms0.1ms;删除网络延迟模拟:tcqdiscdevdevenp23s0f1(网卡)rootnetemdelay0.8ms0.1ms。常见问题1.Xlog目录磁盘空间不足。Xlog日志目录满,原因如下:集群中有备节点宕机,或者主备节点之间网络断开;无效的复制槽没有及时清理;归档已启用,但归档失败;太多的Xlog保留。备节点故障:利用网络和数据库日志信息判断节点故障原因,尽快恢复主备节点之间的复制关系。当故障不能快速解决时,建议修改数据库参数,改变主库的Xlog保留大小。enable_xlog_prune=onmax_size_for_xlog_prune:默认2T,建议修改为104857600(100GB),或者根据磁盘空间调整无效复制槽:检查是否有无效复制槽导致Xlog被及时清理,需要删除延迟最大的复制槽。--查看复制槽selectslot_name,coalesce(plugin,'_')asplugin,slot_type,datoid,coalesce(database,'_')asdatabase,active,coalesce(xmin,'_')asxmin,pg_size_pretty(pg_xlog_location_diff(CASEWHENpg_is_in_recovery()THENpg_last_xlog_receive_location()ELSEpg_current_xlog_location()END,restart_lsn))ASretained_bytesfrompg_replication_slots;--清理复制槽selectpg_drop_replication_slot('slot_name');归档失效:首先检查归档目录下是否有归档日志,如果没有则需要检查数据库日志归档失败的原因。Xlog参数不合理:检查数据库Xlog保留参数wal_keep_segments的值是否合理。2、CPU占用率高除了数据库bug等程序占用CPU高影响数据库外,大部分原因是SQL执行速度慢,并发量大。1.当前执行的SQL汇总selectquery,count(*)frompg_stat_activitygroupbyqueryorderby2desclimit5;2.检查SQL执行计划解释(分析、成本、缓冲区、时间)QUERY3。SQL中涉及的表是否有扩表、索引失效或缺失或重复这种情况,这一步可以处理80%的慢SQL--表结构\d+表名--表和索引空间大小(pg_relation_size(rel.oid))ASrelsize,pg_size_pretty(pg_indexes_size(rel.oid))ASindexsize,pg_size_pretty(pg_total_relation_size(reltoastrelid))AStoastsizeFROMpg_namespacenspJOINpg_classrelONnsp.oid=rel.relnamespaceWHEREnspnameNOTIN('pg_catalog','information_schema')ANDrel.relkindglation_size_size=.oid)desclimit20;--表扩展selectschemaname,relname,n_live_tup,n_dead_tup,round((n_dead_tup::numeric/(case(n_dead_tup+n_live_tup)when0then1else(n_dead_tup+n_live_10)end,2)*asdead_ratefrompg_stat_user_tableswheren_live_tup(n_dead_tup>0and:ad:ad:numeric/(n_dead_tup+n_live_tup))>0orderby5desclimit50;--索引使用选择tschemaname||'.'||relnametablename||'.'||indexrelnameindexname,idx_scan,idx_tup_read,idx_tup_fetchfrommpg_stat_user_indexes;--重复索引SELECTpg_size_pretty(SUM(pg_relation_size(idx))::BIGINT)ASSIZE,(array_agg(idx))[1]ASidx1,(array_agg(idx))[2]ASidx2,(array_agg(idx))[3]ASidx3,(array_agg(idx))[4]ASidx4FROM(SELECTindexrelid::regclassASidx,(indrelid::text||E'\n'||indclass::text||E'\n'||indkey::文本||E'\n'||COALESCE(indexprs::text,'')||E'\n'||COALESCE(indpred::text,''))ASKEYFROMpg_index)subGROUPBYKEYHAVINGCOUNT(*)>1ORDERBYSUM(pg_relation_size(idx))描述;4、根据执行计划判断是否需要重写SQL3、内存不足①。查看服务器物理内存总体使用情况②。检查数据库内存参数设置是否合理:max_process_memory建议设置物理内存的80%;shared_buffers建议设置为物理内存的40%。数据库内存使用分布:查看整体内存使用情况。当dynamic_used_memory的值接近max_dynamic_memory时,说明动态内存可能不足。如果dynamic_peak_memory超过了max_dynamic_memory,就说明发生了OOM。选择*fromgs_total_memory_detail;连接太多会耗尽内存。主要规则是连接太多导致内存不足。查看连接的分布。fromgs_session_memory_detailm,pg_stat_activityawheresubstring_inner(sessid,position('.'insessid)+1)=a.sessionidgroupbystate;单会话占用内存排序selectsessid,pg_size_pretty(sum(totalsize)),pg_size_pretty(sum(freesize))fromgs_session_groupbysumtosize_detail0;存档机制session的缓存机制不合理也会导致内存不能快速释放,可能与参数local_syscache_threshold有关。内存上下文使用内存分配selectcontextname,pg_size_pretty(sum(totalsize)),pg_size_pretty(sum(freesize))fromgs_session_memory_detailgroupbycontextnameorderbysum(totalsize)desclimit10;动态内存一般偏高有以下几个原因:总结:①连接过多会导致动态内存耗尽,如果IDLE连接很多,可能是开发端预留的长连接数不合理;如果有很多ACTIVE连接,可能是硬件内存不足,需要扩内存。②.单个session占用内存较多,需要根据SQL分析内存占用情况。作者简介云和恩墨服务总监高云龙。长期从事PG运维,目前支持openGauss生态发展。
