redis_db.sh 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #!/bin/bash
  2. export LANG=C
  3. export LC_ALL=C
  4. rdbver=1.1
  5. keyname=$2
  6. test -d $3 || mkdir -p $3
  7. log_file=$3/${0##*/}.log
  8. ## redis opts
  9. redis_cli_opts='--raw'
  10. redis_bgsave_timeout=300
  11. redis_bgsave_one_try_timeout=15
  12. redis_data_dir='/var/lib/redis'
  13. redis_rdp_location="$redis_data_dir/dump.rdb"
  14. test -f $redis_rdp_location || {
  15. redis_data_dir='/var/spool/redis'
  16. redis_rdp_location="$redis_data_dir/dump.rdb"
  17. }
  18. redis_backup_dir=$redis_data_dir
  19. current_date=`date '+%Y%m%d-%H%M%S'`
  20. ## choosing compress
  21. bzip=`which bzip2 2>/dev/null`; pbzip=`which pbzip2 2>/dev/null`; gzip=`which gzip 2>/dev/null`; bzcompress=${pbzip:-${bzip}}; compress_prog=${bzcompress:-${gzip}}
  22. test -x "$compress_prog" || { echo "[ERROR `date '+%Y/%m/%d-%H:%M:%S'`] No compress util or $compress_prog has no execute flag. Fix it first."; exit 1; }
  23. case "${compress_prog##*/}" in
  24. 'pbzip2' ) compress_ext='bz2'; tar --version | grep -oE '1.2[0-6]' > /dev/null || compress_prog+=' -l' ;;
  25. 'bzip2' ) compress_ext='bz2' ;;
  26. 'gzip' ) compress_ext='gz' ;;
  27. esac
  28. function show_error() {
  29. local message="$1"; local funcname="$2"; local log_date=`date '+%Y/%m/%d:%H:%M:%S'`
  30. echo -e "[ERROR.$funcname $log_date] $message" >> $log_file 2>&1
  31. }
  32. function show_notice() {
  33. local message="$1"; local funcname="$2"; local log_date=`date '+%Y/%m/%d:%H:%M:%S'`
  34. echo -e "[NOTICE.$funcname $log_date] $message" >> $log_file 2>&1
  35. }
  36. function show_usage() {
  37. echo "Usage: ${0##*/} --(get|remove) <domain name> <log path>"
  38. echo -e "\t Example: ${0##*/} --get example.ru /var/log"
  39. echo -e "\t Example: ${0##*/} --remove example.ru /var/log"
  40. }
  41. function backup_redis() {
  42. local err=0; local dir=$1; local seconds=0;
  43. which redis-cli > /dev/null || { show_error "Not found redis-cli." "$FUNCNAME"; return 1;}
  44. test $# -eq 1 || { show_error "Function wrong usage! Args=$@" "$FUNCNAME"; return 1; }
  45. test -d $dir || mkdir -p $dir
  46. local lastsave_before=`echo lastsave | redis-cli $redis_cli_opts`
  47. echo bgsave | redis-cli $redis_cli_opts
  48. while [ $seconds -lt $redis_bgsave_timeout ]; do
  49. sleep $redis_bgsave_one_try_timeout
  50. let seconds=seconds+$redis_bgsave_one_try_timeout
  51. local lastsave_after=`echo lastsave | redis-cli $redis_cli_opts`
  52. show_notice "Curent seconds: $seconds. Lastsave before: $lastsave_before, lastsave after: $lastsave_after." "$FUNCNAME"
  53. test "x$lastsave_before" != "x$lastsave_after" && {
  54. show_notice "Saving $redis_rdp_location to $dir/${current_date}-redis.rdb, and compress" "$FUNCNAME"
  55. cp $redis_rdp_location $dir/${current_date}-redis.rdb && \
  56. nice -n 19 ionice -c 3 $compress_prog -f $dir/${current_date}-redis.rdb || \
  57. { show_error "Error on copy and compress $redis_rdp_location" "$FUNCNAME"; local err=1; }
  58. return $err;
  59. }
  60. done
  61. show_error "Attempt to backup redis rdb has ended by timeout: $redis_bgsave_timeout seconds!" "$FUNCNAME"; return 1;
  62. }
  63. function remove_redis_db() {
  64. redis-cli $redis_cli_opts -n $dbnumber flushdb
  65. redis-cli $redis_cli_opts DEL $keyname
  66. show_notice "Database $keyname with dbnumber=$dbnumber removed." "get_redis_db_number"
  67. }
  68. function get_redis_db_number() {
  69. which redis-cli > /dev/null || { show_error "Not found redis-cli." "$FUNCNAME"; return 1;}
  70. dbnumber=`redis-cli $redis_cli_opts GET $keyname`
  71. show_notice "Curent dbnumber for key $keyname=$dbnumber" "$FUNCNAME"
  72. }
  73. function get_redis_db_list() {
  74. which redis-cli > /dev/null || { show_error "Not found redis-cli." "$FUNCNAME"; return 1;}
  75. dblist=`redis-cli $redis_cli_opts INFO keyspace |grep db |grep -v db0 |awk -F':' '{print $1}' | sed 's/db//' | sort | uniq |tr '\n' ' '`
  76. show_notice "Redis dblist: $dblist" "$FUNCNAME"
  77. }
  78. function get_redis_db_not_used_number() {
  79. local i=1;
  80. while true
  81. do
  82. echo $dblist | tr ' ' '\n' | grep -qE "^${i}$" || break
  83. i=$((i + 1));
  84. done
  85. dbnumber=$i
  86. show_notice "Uniq dbnumber: $dbnumber" "$FUNCNAME"
  87. }
  88. function create_redis_key_with_db_number() {
  89. redis-cli $redis_cli_opts SET $keyname "$dbnumber"
  90. show_notice "Created key: $keyname with value=$dbnumber" "$FUNCNAME"
  91. }
  92. test x"$1" = "x" -o x"$2" = "x" -o x"$3" = "x" && { echo "One or more arguments is missing!"; show_usage; exit 1; }
  93. test x"$1" == x"" && show_usage
  94. test x"$1" = x"--get" && {
  95. get_redis_db_number
  96. check=`echo $dbnumber | grep -E ^\-?[0-9]+$`
  97. test "$check" = '' && {
  98. show_notice "Database $keyname not exist, script generate new database number." "get_redis_db_number"
  99. backup_redis $redis_backup_dir && \
  100. get_redis_db_list && \
  101. get_redis_db_not_used_number && \
  102. create_redis_key_with_db_number
  103. } >> $log_file 2>&1
  104. echo $dbnumber
  105. exit 0
  106. }
  107. test x"$1" = x"--remove" && {
  108. get_redis_db_number
  109. check=`echo $dbnumber | grep -E ^\-?[0-9]+$`
  110. test "$check" = '' && {
  111. show_notice "Can't remove database $keyname, not exist." "get_redis_db_number"
  112. exit 1;
  113. } >> $log_file 2>&1
  114. backup_redis $redis_backup_dir && \
  115. remove_redis_db
  116. exit 0
  117. }