awips2/deltaScripts/17.3.1/DR6122/6122_fix_freespacemap.sh
2022-05-05 12:34:50 -05:00

76 lines
2.3 KiB
Bash
Executable file

#!/bin/bash
# #6122 - Repair any possible free-space map errors in PostgreSQL databases
# by deleting corrupt files, as described in 9.5.5 release notes:
# https://www.postgresql.org/docs/9.5/static/release-9-5-5.html
#
# If there are no errors to correct then this script does nothing except
# restart PostgreSQL.
#
# Run as root on all Postgres servers. Postgres must be running for this to
# work.
#
# Author: tgurney
psql=/awips2/psql/bin/psql
pg_ctl=/awips2/postgresql/bin/pg_ctl
data_dir=/awips2/data
su - awips -c "${pg_ctl} -D ${data_dir} -s status"
if [[ "$?" -ne 0 ]]; then
echo "ERROR: Postgres is not running. Cannot continue."
exit 1
fi
echo "INFO: Checking all databases for free-space map corruption"
filecount=0
for db in $(${psql} --user=awipsadmin --db=metadata -Aqt -c 'select datname from pg_database;'); do
file_list=$(mktemp || exit 1)
old_filecount=${filecount}
echo -n " ${db}..."
# https://wiki.postgresql.org/wiki/Free_Space_Map_Problems
${psql} --user=awipsadmin --db=${db} -Aqt -c "
create extension if not exists pg_freespacemap;
select oid::regclass as relname,
pg_relation_filepath(oid) || '_fsm' AS fsm
from pg_class,
cast(current_setting('block_size') as bigint) as bs
where relkind in ('r', 'i', 't', 'm') and exists
(select 1 from
generate_series(pg_relation_size(oid) / bs,
(pg_relation_size(oid, 'fsm') - 2*bs) / 2) as blk
where pg_freespace(oid, blk) > 0);
" >> ${file_list} 2>/dev/null
filecount=$(wc -l "${file_list}" | awk '{print $1}')
if [[ "${filecount}" -gt "${old_filecount}" ]]; then
echo "errors found"
else
echo "ok"
fi
done
if [[ "${filecount}" -ne 0 ]]; then
echo INFO: Need to delete ${filecount} corrupt files
echo INFO: Stopping PostgreSQL
su - awips -c "${pg_ctl} -D ${data_dir} -s stop"
if [[ "$?" -ne 0 ]]; then
echo ERROR: Failed to stop Postgres. Cannot continue
rm -f ${file_list}
exit 1
fi
while IFS= read -r line; do
if [[ -f "${line}" ]]; then
rm -fv ${line}
fi
done < ${file_list}
echo INFO: Starting PostgreSQL
su - awips -c "${pg_ctl} -D ${data_dir} -s start"
else
echo "INFO: Found no free-space map errors"
fi
rm -f ${file_list}
echo INFO: Done.