#!/bin/bash
#当表的数据小于20万则对表做 reindex table xxx操作
#否则先删除索引(唯一约束索引,及主键除则 reindx index xxx),然后再创建该索引
#zhaowenzhong 2019-04-02
date=`date +"%Y%m%d%H%M"`
v_constant=200000
v_hour=0
v_param=$#
if [ $v_param -ge 3 ];then
echo "Invalid argument!! E.g sh pg-reindex-all.sh vlnx191001.xxx.cn OR sh pg-reindex-all.sh vlnx191001.xxx.cn \" db1,db2,db3,...\""
exit 1
fi
pghosts=$1
if [ -n "$pghosts" ];then
hostname=${pghosts%%.*}
filename=$hostname'-reindex-'$date
for pghostname in $pghosts
do
if [ $v_param -eq 1 ];then
dblist=$(psql -h $pghostname -U zhaowz -d postgres -c "select datname from pg_database where datname not in ('postgres','template0','template1','repmgr')" -A -t)
elif [ $v_param -eq 2 ];then
dblist=$(psql -h $pghostname -U zhaowz -d postgres -c "select datname from pg_database where datname=any('{$2}')" -A -t)
fi
if [ -z "$dblist" ];then
echo "Invalid dbname OR Invalid hostname !!!" >> /home/zhaowz/logs/$filename.log
exit 1
fi
for db in $dblist
do
v_hour=$(date "+%k")
if [[ ${v_hour} -ge 1 && ${v_hour} -lt 7 ]]; then
echo "$db : `date +"%Y%m%d%H%M%S"` Begin ">>/home/zhaowz/logs/$filename.log
tables=$(psql -h $pghostname -U zhaowz -d $db -c "select tablename from pg_tables where schemaname='public'" -A -t)
for table in $tables
do
v_count=0
v_count=$(psql -h $pghostname -U zhaowz -d $db -c "select reltuples from v_get_eachtable_size where relname='$table'" -A -t)
v_hour=$(date "+%k")
if [[ ${v_hour} -ge 1 && ${v_hour} -lt 7 ]]; then
if [ $v_count -gt $v_constant ]; then
#过滤出非 主键索引和唯一索引
indexes=$(psql -h $pghostname -U zhaowz -d $db -c "select indexname from v_get_indexes_stats where relname='$table' and ((\"Unique\" !='Y' and \"Primary\" !='Y') or (\"Unique\" !='Y' and \"Primary\" ='N'))" -A -t)
for idx_line in $indexes
do
v_create_index=''
v_create_index=$(psql -h $pghostname -U zhaowz -d $db -c "select 'create index if not exists '|| indexname || ' on '|| relname || ' USING '|| pg_get_indexdef || ';' from v_get_indexes_stats where relname='$table' and indexname='$idx_line'" -A -t)
#由于程序使用的是长连接模式,长连接模式会产生很多 idle in trans 状态,该状态会导致 reindex index 阻塞。故在reindex时 将该状态的连接 pg_terminate_backend
v_idel_in_tran=''
v_idel_in_tran=$(psql -h $pghostname -U zhaowz -d $db -c "select 'pg_terminate_backend('||pid||');' from pg_stat_activity where state='idle in transaction'" -A -t)
if [ -n "$v_idel_in_tran" ]; then
for v_tran in $v_idel_in_tran
do
psql -h $pghostname -U zhaowz -d postgres -c "select $v_tran"
done
fi
echo "$db.$table.$idx_line :`date +"%Y%m%d%H%M%S"` Begin drop ">>/home/zhaowz/logs/$filename.log
psql -h $pghostname -U zhaowz -d $db -c "drop index $idx_line ;"
echo "$db.$table.$idx_line :`date +"%Y%m%d%H%M%S"` has finished drop ">>/home/zhaowz/logs/$filename.log
echo "$db.$table.$idx_line :`date +"%Y%m%d%H%M%S"` Begin create ">>/home/zhaowz/logs/$filename.log
psql -h $pghostname -U zhaowz -d $db -c " $v_create_index">>/home/zhaowz/logs/$filename.log
echo "$db.$table.$idx_line :`date +"%Y%m%d%H%M%S"` has finished create ">>/home/zhaowz/logs/$filename.log
echo $v_create_index >> /home/zhaowz/logs/$filename.log
done
#过滤出 主键索引和唯一索引
indexes_pkey_uq=$(psql -h $pghostname -U zhaowz -d $db -c "select indexname from v_get_indexes_stats where relname='$table' and ((\"Unique\" ='Y' and \"Primary\" ='Y') or (\"Unique\" ='Y' and \"Primary\" ='N'))" -A -t)
for idx_pkey_uq in $indexes_pkey_uq
do
#由于程序使用的是长连接模式,长连接模式会产生很多 idle in trans 状态,该状态会导致 reindex index 阻塞。故在reindex时 将该状态的连接 pg_terminate_backend
v_idel_in_tran=''
v_idel_in_tran=$(psql -h $pghostname -U zhaowz -d $db -c "select 'pg_terminate_backend('||pid||');' from pg_stat_activity where state='idle in transaction'" -A -t)
if [ -n "$v_idel_in_tran" ]; then
for v_tran in $v_idel_in_tran
do
psql -h $pghostname -U zhaowz -d postgres -c "select $v_tran"
done
fi
echo "$db.$table.$indexes_pkey_uq :`date +"%Y%m%d%H%M%S"` Begin reindex " >> /home/zhaowz/logs/$filename.log
psql -h $pghostname -U zhaowz -d $db -c "reindex index $indexes_pkey_uq ;"
echo "$db.$table.$indexes_pkey_uq :`date +"%Y%m%d%H%M%S"` has finished reindex " >> /home/zhaowz/logs/$filename.log
done
elif [[ $v_count -gt 0 && $v_count -lt $v_constant ]]; then
v_hour=$(date "+%k")
if [[ ${v_hour} -ge 1 && ${v_hour} -lt 7 ]]; then
#由于程序使用的是长连接模式,长连接模式会产生很多 idle in trans 状态,该状态会导致 reindex index 阻塞。故在reindex时 将该状态的连接 pg_terminate_backend
v_idel_in_tran=''
v_idel_in_tran=$(psql -h $pghostname -U zhaowz -d $db -c "select 'pg_terminate_backend('||pid||');' from pg_stat_activity where state='idle in transaction'" -A -t)
if [ -n "$v_idel_in_tran" ]; then
for v_tran in $v_idel_in_tran
do
psql -h $pghostname -U zhaowz -d postgres -c "select $v_tran"
done
fi
echo "$db.$table :`date +"%Y%m%d%H%M%S"` Begin reindex ">>/home/zhaowz/logs/$filename.log
psql -h $pghostname -U zhaowz -d $db -c "reindex table $table"
echo "$db.$table :`date +"%Y%m%d%H%M%S"` has finished reindex ">>/home/zhaowz/logs/$filename.log
fi
fi
echo "$db.$table :`date +"%Y%m%d%H%M%S"` has Begin vacuum analyze ">>/home/zhaowz/logs/$filename.log
psql -h $pghostname -U zhaowz -d $db -c "vacuum analyze $table"
echo "$db.$table :`date +"%Y%m%d%H%M%S"` has finished vacuum analyze ">>/home/zhaowz/logs/$filename.log
fi
done
fi
done
done
fi