Tengo el siguiente script:
#!/bin/bash -e
set -e
DATA_DIR=/home/admin/backup_avl_historico/data
DB_HOST=myHost
DB_USER=myPass
#extract table list
logger 'Extracting Table List'
psql -h $DB_HOST -U $DB_USER -c "select table_name from information_schema.tables where table_name like 'avl_historico_%';" -t -o $DATA_DIR/tables.list
array=($(wc -l $DATA_DIR/tables.list))
logger ''$array
total_tables=${array[0]}
logger 'Total tables: '$total_tables
#Get max date
max_date=$(psql -h $DB_HOST -U $DB_USER -t -c "select now() - interval '12 months'")
logger 'Max date: '$max_date
array=($max_date)
date=${array[0]}
logger 'Only date: '$date
#Dump each table
while read table_name
do
logger 'looping...'
if [ ! -z "$table_name" ]; then
logger 'Processing table '$table_name
output=${table_name}_pre_${date}.csv
psql -h $DB_HOST -U $DB_USER -t -F , -c "COPY (select * from reports.$table_name where fecha < '$max_date') TO STDOUT WITH CSV" -o ${DATA_DIR}/$output
if [ -f ${DATA_DIR}/$output ];then
if test -s ${DATA_DIR}/$output
then
logger 'Deleting records'
psql -h $DB_HOST -U $DB_USER -c "delete from reports.$table_name where fecha < '$max_date'"
logger 'Gzipping '$output
pigz ${DATA_DIR}/$output
logger 'Moving to S3'
aws s3 mv ${DATA_DIR}/$output.gz s3://my-bucket/avl_historico/
logger 'Vacuuming table'
psql -h $DB_HOST -U $DB_USER -c "vacuum full analyze reports.$table_name"
else
rm ${DATA_DIR}/$output
fi
fi
fi
done < $DATA_DIR/tables.list
El problema que tengo es que cuando PostgreSQL sale de una declaración con el siguiente error:
ERROR: canceling statement due to lock timeout
Todo el script se cancela y no continúa con la siguiente iteración del do
bucle.
Se agradecería cualquier idea sobre cómo evitar esa condición de salida, por lo que el script podría omitir simplemente una iteración, pero continuar con el resto.
Respuesta1
Si desea que su secuencia de comandos ejecute todos los comandos sin tener en cuenta cualquier falla, elimine ambas -e
banderas. Por otro lado, si aún desea finalizar el script en caso de error, pero desea detectar uno específico (PostgreSQL en su caso), deje solo una de las -e
banderas, no importa cuál, sino una preferencia personal. en el script, no en el shebang, y la forma de detectar el error es agregar un ||
(OR lógico) al final del comando que sale con un valor distinto de 0. Lo que esto ||
hace es que si el código de salida del comando anterior no es 0, ejecute lo siguiente uno:
psql -h $DB_HOST -U $DB_USER -c "delete from reports.$table_name where fecha < '$max_date'" || true
El ejemplo anterior detectará silenciosamente psql
códigos de salida distintos de 0 y continuará. Puede reemplazar el true
comando por lo que desee (registrar el error, esperar un tiempo, etc.) solo asegúrese de que salga con 0 o terminará en el mismo situación. El true
comando no hace absolutamente nada, simplemente sale con el código 0.