pgvacuum 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. #!/usr/bin/env bash
  2. (
  3. flock -n 9 || { logger -t PostgreSQL databases vacuum is already running!; exit 1; }
  4. print_elapsed_time() {
  5. time_elapsed=$(( $2-$1 ))
  6. milliseconds=$(( $time_elapsed%1000 ))
  7. seconds=$(( ($time_elapsed/1000)%60 ))
  8. minutes=$(( ($time_elapsed/1000/60)%60 ))
  9. hours=$(( ($time_elapsed/1000/60/60)%24 ))
  10. (( $hours > 0 )) && printf '%dh' $hours
  11. (( $minutes > 0 )) && printf '%dm' $minutes
  12. (( $seconds > 0 )) && printf '%ds' $seconds
  13. printf '%dms\n' $milliseconds
  14. }
  15. # ... commands executed under lock ...
  16. # Milliseconds from epoch
  17. vacuum_start_time=$(date +%s%3N)
  18. echo '###################################################################################################'
  19. echo '########################### PostgreSQL databases vacuum has started! ##########################'
  20. echo "########################### $(date '+%Y-%m-%d %H:%M:%S') #########################"
  21. echo '###################################################################################################'
  22. # Retrieve all databases from PostgreSQL
  23. excluded_db="db.datname NOT LIKE E'\'template%\''"
  24. excluded_schema="nspname NOT LIKE E'\'pg_toast%\'' AND nspname NOT LIKE E'\'pg_temp%\'' AND nspname NOT IN (E'\'pg_catalog\'', E'\'information_schema\'')"
  25. echo "$(date '+%Y-%m-%d %H:%M:%S') - retrieve all databases"
  26. databases=$(su - postgres -c "psql -Atc 'SELECT db.datname FROM pg_database db INNER JOIN pg_authid a ON a.oid = db.datdba WHERE $excluded_db ORDER BY db.datname'")
  27. for db in $databases; do
  28. start_time=$(date +%s%3N)
  29. echo "$(date '+%Y-%m-%d %H:%M:%S') - ==============================================================================="
  30. echo "$(date '+%Y-%m-%d %H:%M:%S') - vacuum for $db database has started!"
  31. echo "$(date '+%Y-%m-%d %H:%M:%S') - ==============================================================================="
  32. dbsize=$(su - postgres -c "psql -d $db -Atc 'SELECT pg_size_pretty(pg_database_size(pg_database.datname)) AS size FROM pg_database WHERE datname=E'\'$db\'''")
  33. echo "$(date '+%Y-%m-%d %H:%M:%S') - + $db size before vacuum: $dbsize"
  34. # Retrieve all shemas for current database
  35. schemas=$(su - postgres -c "psql -d $db -Atc 'SELECT nspname FROM pg_catalog.pg_namespace WHERE $excluded_schema ORDER BY nspname'")
  36. for schema in $schemas; do
  37. schema_start_time=$(date +%s%3N)
  38. echo "$(date '+%Y-%m-%d %H:%M:%S') - + => vacuum for $schema schema has started!"
  39. tables=$(su - postgres -c "psql -d $db -Atc 'SELECT tablename FROM pg_tables WHERE schemaname=E'\'$schema\'' ORDER BY tablename'")
  40. for table in $tables; do
  41. su - postgres -c "vacuumdb -q -f -z -d $db --t $schema.$table"
  42. done
  43. schema_end_time=$(date +%s%3N)
  44. echo "$(date '+%Y-%m-%d %H:%M:%S') - + .... vacuum for $schema schema has completed after" $(print_elapsed_time $schema_start_time $schema_end_time)
  45. done
  46. dbsize=$(su - postgres -c "psql -d $db -Atc 'SELECT pg_size_pretty(pg_database_size(pg_database.datname)) AS size FROM pg_database WHERE datname=E'\'$db\'''")
  47. echo "$(date '+%Y-%m-%d %H:%M:%S') - + $db size after vacuum: $dbsize"
  48. end_time=$(date +%s%3N)
  49. echo "$(date '+%Y-%m-%d %H:%M:%S') - + vacuum for $db database has completed after" $(print_elapsed_time $start_time $end_time)
  50. done
  51. vacuum_end_time=$(date +%s%3N)
  52. echo "$(date '+%Y-%m-%d %H:%M:%S') - PostgreSQL vacuum has completed after" $(print_elapsed_time $vacuum_start_time $vacuum_end_time)
  53. ) 9> /var/tmp/vacuum.lock
  54. exit $?