You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写Bash脚本清理MySQL备份文件并保留指定版本

MySQL备份文件夹清理脚本分享与优化请求

需求说明

  • 备份文件夹分为daily、weekly、monthly三类
  • 备份文件格式:<db_table_name>_bkup_yyyy_mm_dd.sql.gz
  • 核心功能:指定目标文件夹和保留的备份版本数,当文件数量超过保留数时,自动删除最旧的文件

我已自行完成脚本编写,但认为仍有优化空间,现分享该脚本供大家使用,也希望有人能在保证可读性的前提下对其进行优化。

已完成的脚本代码

#!/bin/bash -l
# CEM2 - 2023.01.18 new
# db_backup_cleanup.sh (/home/link/intra/system/db/) 
#
# Purpose:  Deletes extra database table backup files.
#           In order to keep only x number of table backup files
#
# Backup files must be:
#   - in /backup/db/<database_name>/
#   - subfolders of daily / weekly / monthly
#   - file format <table_name>_bkup_yyyy_mm_dd.sql.gz
#
#------------------------------------------------------------------------  

do_cleanup()
{
  #--------------------------------------------------------------------
  # Reads each file from the path
  # Grabs the file prefix which contains the table name
  # Compares each incoming file until a change in table is found
  # Processes the table:
  #   - Collects all file_date_suffixes in an array
  #   - Calls routine to check how many files there are for this table
  #   - Delete early ones if we have too many.
  #--------------------------------------------------------------------

  myPath="/backup/db/$myDb/$myFreq"
  echo "=========================================="
  echo "== Ready to clean extra bckup files in:"
  echo "  Folder =  $myPath"
  echo "  Keeping $keep number of versions"
  echo " " 
  echo "------------------------------------------"

  #-- Looking for needle _bkup_ in filename.  
  #-- This separates the path/table_name from date_suffix
  #-- ex. /path/mytable_bkup_2023_12_31.sql.gz
  prev_file=""
  files=("$myPath"/*)

  #-- counts files deleted
  cleaned_cntr=0;
  #-- counts files read in 
  cntr=0

  #=== Loop Through the files...
  for file in "${files[@]}"; do

    #--- Increment file counter
    cntr=$(($cntr+1))
    echo "------------------- "
    echo "File Number   : $cntr"
    echo "Backup File   : $file"

    #--- get the file prefix (path and file name)
    #-- backup= path/db_tblname_bkup_yyyy_mm_dd.sql.gz
    #-- prefix= path/db_tblname
    prefix=${file%%$needle*}
    echo "Path and File : $prefix"

    #-- If prefix = whole file name then we didn't find _bkup_
    #--   this is not a backup file so skip it.
    if [ "$prefix" == "$file" ]
    then
      echo "  NOT a backup file.  Not processing."
      continue
    fi


    #-- First time in, prev_file will be empty.
    #-- Set it to first file prefix before comparison is made.
    if [ "$prev_file" == "" ]
    then
      prev_file="$prefix"
    fi

    #-- in what position is the needle.
    mypos=${#prefix}
    #--- Debug only
    # echo "found $needle at $mypos"

    #-- get file date suffix
    #-- Last position of "_bkup_"
    x=$(($mypos+6))
    file_date="${file:$x:10}"
#    echo "the suffix is $file_date"

    #-- Debug Only  
    #    echo "prefix: $prefix and prev_file: $prev_file" 
    if [ "$prefix" != "$prev_file" ] 
    then
      #-- Filename change - check file...
      echo "That's all the files for PREVIOUS table."
      echo "Going to see if we should delete some..."
      do_remove_extras
      #-- prepare for the next filename
  #-- Clear the Main Array for new files
      aryFiles=()
      prev_file="${prefix}"
      aryFiles+=($file_date)
    else
      aryFiles+=($file_date)
    fi
    echo " "

  done

  #-- Process last file which will not be triggered by a
  #--    change in file name.
  echo "Process Final File... "
  do_remove_extras

  echo " "
  echo "======================================================"
  echo "Summary for $myPath"
  echo "======================================================"
  echo "Deleted ${cleaned_cntr} files."
  echo "-----------------------------------"
  echo " "


}

#---------------------------------------
do_remove_extras()
{
  #-- Empty ary that will hold the sorted file date suffixes
  arySorted=()

  #-- How many file date suffixes do we have
  nbrSuffixes=${#aryFiles[@]}
  echo "  There are $nbrSuffixes suffixes for this file  (keeping $keep)."
  #--  echo "Printing Original array"
  #-- for (( i=0; i<$nbrSuffixes; i++ )); do echo "${aryFiles[$i]}" ; done

  #-- Sort the suffixes by date yyyy-mm-dd - earliest first
  arySorted=($(echo "${aryFiles[@]}" | sed 's/ /\n/g' | sort))    
  echo "  Printing Sorted array..."
  echo "    ${arySorted[@]}"

  #-- Delete Extra files
  nbr_to_rm=$(($nbrSuffixes-$keep))
  #   echo "  How many files to remove? $nbr_to_rm"
  if (( $nbr_to_rm > 0 ))
  then
    #-- need to delete some
    echo "  We will delete $nbr_to_rm files..."
    del_cntr=0;
    for (( i=0; i<$nbrSuffixes; i++ )); do 
      suff="${arySorted[$i]}";
      del_fname="${prev_file}$needle${suff}" ;
      if [ $del_cntr -lt $nbr_to_rm ]
      then
        #-- debug  echo "   del_cntr = ${del_cntr} and nbr_to_rm = ${nbr_to_rm}"
        echo "    DELETING filename = ${del_fname}.sql.gz"
        rm -f "${del_fname}.sql.gz"
        (( cleaned_cntr++ ))
        (( del_cntr++ ))
      else
        echo "    Keeping ${del_fname}..."
      fi
    done
  
  fi

  
  
}

#=======================================================================
#  MAIN SCRIPT
#=======================================================================

echo "======================================================"
echo "Starting $(basename $BASH_SOURCE) at `date`"
echo " "

#get general variables
echo "  Getting System variables..."
source "./cemsoft.conf"

#---  Was DB provided
if [ -z "$1" ]; then
    echo "No Database Was provided"
    exit;
    #-- set Default?
#  COMP="cscs"
else
    myDb=$1
fi

echo "  Managing DB Backup files at path=<LOG_PATH>"
echo " "

cleaned_cntr=0;
aryFiles=()
needle="_bkup_"


#---------------------------------------------------
# Call as many times as needed
#---------------------------------------------------

myFreq="daily"
keep=2     
do_cleanup

myFreq="weekly"
do_cleanup

myFreq="monthly"
do_cleanup

echo " "
echo " " 
echo "======================================================"
echo "Finished with Backup Cleanup."
echo "======================================================"
echo " "

优化方向

希望能在保证脚本可读性的前提下,从以下方面优化:

  • 简化循环与数组处理逻辑
  • 提升脚本执行效率
  • 增强错误处理与健壮性
  • 优化参数传递方式,让脚本更灵活

内容的提问来源于stack exchange,提问作者user2103442

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 14:05:18