系统:Centos7
pg版本:14.11
自建pgsql14中有很多个库,一个库对应一个租户,偶尔会出现单个租户执行慢sql影响全局的问题,目前官方也没有比较合适的处理方案或者插件
解决方案:
因为pgsql是多进程应用,所以正好可以使用linux自带的cgroup功能进行资源限制。定时将进程中出现的数据库pid,加入对应cgroup限制组,这样就可以限制单个数据库能使用的cpu最大占比。不会因为单个库的问题,造成整体宕机。
#!/bin/bash
# 计算需要分配的资源,如每个db分配总核心的20%,cpu_percent就设置为20
cpu_percent=20
# 计算单个核心
single_cpu_quota=$(( 100000 * $cpu_percent / 100 ))
# 计算总核心
cpu_num=$(nproc)
total_cpu_quota=$(( $single_cpu_quota * $cpu_num ))
if [[ ! -d "/sys/fs/cgroup/cpu/postgres/" ]]; then
cgcreate -g cpu:/postgres
fi
pg_all_pid=$(ps -ef|grep 'postgres: postgres'|grep -v 'grep'|awk '{print $2}')
for pg_ppid in $pg_all_pid; do
pg_dbname=$(ps -f -p $pg_ppid|grep 'postgres: postgres'|grep -v 'grep'|awk '{print $10}')
echo '进程号:' $pg_ppid '数据库:' $pg_dbname
cgroup_path="/postgres/$pg_dbname"
if [[ ! -d "/sys/fs/cgroup/cpu$cgroup_path" ]]; then
echo '创建cgroup cpu:'$cgroup_path
cgcreate -g cpu:$cgroup_path
cgset -r cpu.cfs_quota_us=$total_cpu_quota "$cgroup_path"
cgclassify -g "cpu:$cgroup_path" $pg_ppid
else
if ! grep -q "$pg_ppid" /sys/fs/cgroup/cpu$cgroup_path/tasks ; then
cgclassify -g "cpu:$cgroup_path" $pg_ppid
fi
fi
done