GaussDB 等待事件为LockMgrLock处理方法
1 问题现象
通过查询各个线程的阻塞等待状态,从而更容易定位进程停止响应问题以及类似现象的原因:
- 分布式版:
select wait_event,count(*) from pgxc_thread_wait_status group by 1 order by 2 desc;
- 集中式版:
select wait_event,count(*) from pg_thread_wait_status group by 1 order by 2 desc;
出现大量的LockMgrLock等待事件,造成线程池满,业务执行慢。
查询线程池使用率:
select node_name,worker_info from dbe_perf.global_threadpool_status;
2 业务影响
数据库无法响应业务请求或响应超时。
3 有关LockMgrLock等待事件
用于保护常规锁结构信息。如果此Event出现 在异常等待事件内,代表常规锁的管理器的分区锁产生热点
4 处理步骤
3.1 调整num_internal_lock_partitions参数中FASTPATH_PART值
步骤1:使用gsql连接数据库。
gsql -d postgres -p 8000 -U user -r
- user需替换为实际的系统管理员账号,此处需要输入密码。
- 分布式CN端口和集中式DN默认端口是8000,分布式DN端口可通过cm_ctl query -Cvdp查询获取。
步骤2:查看num_internal_lock_partitions参数值。
show num_internal_lock_partitions;
分布式实例需要分别查看CN及DN参数值,集中式仅查看DN参数值。
如果未查询到此参数,则说明当前版本不支持,执行9~10,降低压力快速恢复业务。
如果正常查询到此参数值,且num_internal_lock_partitions参数值中如果FASTPATH_PART≥200,则不进行修改且执行9~10,其他情况则执行6.c。
步骤3:修改num_internal_lock_partitions参数值。
num_internal_lock_partitions参数说明:FASTPATH_PART部分适用于事务内访问分区表分区数量过多的场景,建议调整值为(事务内分区数*(1+本地索引数量)+全局索引数量+10),在应急场景中,如果无法快速计算FASTPATH_PART值,可先将FASTPATH_PART调整为200。
- 分布式:
gs_guc set -Z coordinator -Z datanode -N all -I all -c "num_internal_lock_partitions='CLOG_PART=256,CSNLOG_PART=512,LOG2_LOCKTABLE_PART=4,TWOPHASE_PART=1,FASTPATH_PART=200'"
- 集中式:
gs_guc set -Z datanode -N all -I all -c "num_internal_lock_partitions='CLOG_PART=256,CSNLOG_PART=512,LOG2_LOCKTABLE_PART=4,TWOPHASE_PART=1,FASTPATH_PART=200'"
步骤4:重启实例,可选择按实例重启,或选择按节点滚动重启。
- 按实例重启
cm_ctl stop && cm_ctl start
- 按节点滚动重启。
cm_ctl stop -n nodeid && cm_ctl start -n nodeid
注:
- nodeid为节点ID,可通过cm_ctl query -Cvd查看获取node值
- 设置GUC参数、重启实例为高危操作,要协商停服务窗口。
步骤5:若以上步骤执行完成之后还存在问题,请执行3.2节
3.2 查看SQL执行时长,收集统计信息分布式版
select current_timestamp - query_start as runtime, datname, usename, pid, sessionid, substr(query,0,100) from pgxc_stat_activity where state != 'idle' and datname !='postgres' order by runtime desc limit 20;
- 集中式版
select current_timestamp - query_start as runtime, datname, usename, pid, sessionid, substr(query,0,100) from pg_stat_activity where state != 'idle' and datname !='postgres' order by runtime desc limit 20;
如上图,该SQL执行时间为2min10s,SQL所在的数据库为db_test,用户为Ruby,从query字段获取查询SQL,将相关的表做一下统计收集:
analyze 表名;