Перейти к основному содержанию

Seafile — резервное копирование и обслуживание

Seafile

Обновил скрипты для резервного копирования Seafile.

Seafile — это личное хранилище для хранения данных в стиле Dropbox. Seafile — замечательный инструмент для создания личного, семейного или корпоративного файлового хранилища. Не очень сложен в установке и настройке.

Речь не только по резервное копирование, а про обслуживание Community версии вашего (и нашего) личного файлового хранилища. Периодически нужно не просто бэкапить данные, но и чистить мусор, проверять целостность, восстанавливать повреждённые библиотеки.

Функции

Наш набор скриптов будет выполнять еженедельную операцию и осуществлять:

  • резервное копирование БД
  • резервное копирование файлов Seafile
  • запускать сборщик мусора
  • проверять целостность данных
  • восстанавливать повреждённые библиотеки

Способ резервного копирования

В официальной документации по Seafile рекомендуется бэкапить две вещи:

  • Базы данных
  • Файлы данных

Исходя из этих требованию была написана первая версия скриптов для обслуживания:

Seafile — резервное копирование

Однако, файловая структура данных Seafile имеет свой блочный формат, использовать резервную копию этих данных можно только для восстановления той же версии Seafile. Использовать резервную копию просто для поиска в ней файла достаточно сложно, придётся развернуть Seafile отдельно из резервной копии. Для переноса данных в какую-то другую систему данная резервная копия не подойдёт.

Естественно, у такого способа резервного копирования есть свои плюсы, например, бэкапится вся хранимая версионность файлов.

Но я использую Seafile только как файловое хранилище, поэтому версии мне не интересны, а интересны только файлы. Поэтому я решил сделать скрипт, который бэкапит не структуру данных Seafile, а именно содержимое. В случае сбоя просто разворачивается с нуля чистый Seafile и вручную загружаются в него данные. При этом даже БД не нужно бэкапить, но мы будем, на всякий случай.

Для этого используется  расширение FUSE. Необходимо его предварительно настройть.

Seafile — расширение FUSE

Seaf-fuse является реализацией виртуальной файловой системы FUSE. Этот скрипт монтирует всё содержимое Seafile в папку (которая называется "mount point"), так что мы получаем доступ ко всем файлам Seafile так же, как к обычной папке на сервере.

Примечание: доступ к зашифрованным папкам с помощью seaf-fuse не предоставляется. Соответственно, бэкапиться шифрованные библиотеки данным скриптом не будут.

Код

Основной скрипт bck.weekly.sh. Он запускается раз в неделю через cron по понедельникам:

0 4 * * Mon /opt/cron/bck.weekly.sh > /opt/cron/bck.weekly.log

Результаты выполнения скрипта логируются в /opt/cron/bck.weekly.log.

Содержимое bck.weekly.sh:

#!/bin/bash
#####
# Uncomment the following line if you rather want to run the script manually.
# Display usage if the script is not run as root user
#        if [[ $USER != "root" ]]; then
#                echo "This script must be run as root user!"
#                exit 1
#        fi
#
# echo "Super User detected!!"
# read -p "Press [ENTER] to start the procedure, this will stop the seafile server!!"
#####

log(){
  message="$(date +"%y-%m-%d %T") $@"
  echo $message
}

log "------------------------------------------"
log "Weekly backup started"

# backup seafile
log "Starting Seafile maintenance"
/bin/bash /opt/cron/bck.seafile.sh

# maintenance seafile
log "Starting Seafile maintenance"
/bin/bash /opt/cron/mnt.seafile.sh

log "Weekly backup complete!"

Это вспомогательный скрипт, который последовательно запускает два скрипта:

  • bck.seafile.sh — резервное копирование
  • mnt.seafile.sh — обслуживание

Резервное копирование осуществляется без остановки сервисов!

Содержимое bck.seafile.sh:

#!/bin/bash
#####
# Uncomment the following line if you rather want to run the script manually.
# Display usage if the script is not run as root user
#        if [[ $USER != "root" ]]; then
#                echo "This script must be run as root user!"
#                exit 1
#        fi
#
# echo "Super User detected!!"
# read -p "Press [ENTER] to start the procedure, this will stop the seafile server!!"
#####

DBUSER="seafile"
DBPASSWORD="пароль"
DBHOST="127.0.0.1"
DBPORT="3306"
DBPROT="tcp"
DBBACKUPDIR="/backup/seafile/databases/"
DBARCHDIR="/backup/seafile/databases/archive/"
DBCCNET="seafile-ccnet"
DBSEAFILE="seafile-db"
DBSEAHUB="seafile-seahub"
DATASEAFILEBACKUPDIR="/backup/seafile/data/"
DATASEAFILEDIR="/opt/seafile-fuse/"
DATACONFBACKUPDIR="/backup/seafile/conf/"
DATACONFDIR="/opt/conf/"
TEMPDIR="/tmp/sf/"
BACKUPMOUNT="//192.168.1.10/backup"
FUSEMOUNT="/opt/seafile-fuse"

log(){
  message="$(date +"%y-%m-%d %T") $@"
  echo $message
}

log "------------------------------------------"
log "Starting backup procedure for seafile"

# check backup mount
if ! mount | grep -q "${BACKUPMOUNT}"; then
   log "Error: ${BACKUPMOUNT} not mounted"
   exit 0
fi
echo "${BACKUPMOUNT} mounted, continue..."

# check fuse mount
if ! mount | grep -q "${FUSEMOUNT}"; then
   log "Error: ${FUSEMOUNT} not mounted"
   exit 0
fi
echo "${FUSEMOUNT} mounted, continue..."

# create temp dir
rm -rf ${TEMPDIR}
mkdir ${TEMPDIR}

# backup databases
log "Starting databases backup"
rm ${DBARCHDIR}*.bz2
mv ${DBBACKUPDIR}*.bz2 ${DBARCHDIR}

# backup DB
log "DB $DBCCNET"
DBDATE=`date +"%Y-%m-%d-%H-%M-%S"`
mysqldump --single-transaction -h ${DBHOST} -u${DBUSER} -p${DBPASSWORD} --protocol=${DBPROT} --port=${DBPORT} --opt ${DBCCNET} > ${TEMPDIR}${DBCCNET}.sql.${DBDATE}
bzip2 ${TEMPDIR}${DBCCNET}.sql.${DBDATE}
mv ${TEMPDIR}${DBCCNET}.sql.${DBDATE}.bz2 ${DBBACKUPDIR}

log "DB $DBSEAFILE"
DBDATE=`date +"%Y-%m-%d-%H-%M-%S"`
mysqldump --single-transaction -h ${DBHOST} -u${DBUSER} -p${DBPASSWORD} --protocol=${DBPROT} --port=${DBPORT} --opt ${DBSEAFILE} > ${TEMPDIR}${DBSEAFILE}.sql.${DBDATE}
bzip2 ${TEMPDIR}${DBSEAFILE}.sql.${DBDATE}
mv ${TEMPDIR}${DBSEAFILE}.sql.${DBDATE}.bz2 ${DBBACKUPDIR}

log "DB $DBSEAHUB"
DBDATE=`date +"%Y-%m-%d-%H-%M-%S"`
mysqldump --single-transaction -h ${DBHOST} -u${DBUSER} -p${DBPASSWORD} --protocol=${DBPROT} --port=${DBPORT} --opt ${DBSEAHUB} > ${TEMPDIR}${DBSEAHUB}.sql.${DBDATE}
bzip2 ${TEMPDIR}${DBSEAHUB}.sql.${DBDATE}
mv ${TEMPDIR}${DBSEAHUB}.sql.${DBDATE}.bz2 ${DBBACKUPDIR}

# backup data
log "Starting data backup"
rsync -az --delete ${DATASEAFILEDIR} ${DATASEAFILEBACKUPDIR}
rsync -az --delete ${DATACONFDIR} ${DATACONFBACKUPDIR}

# remove temp dir
rm -rf ${TEMPDIR}

log "Seafile backup procedure complete!"

Здесь:

  • DBUSER — пользователь БД
  • DBPASSWORD — пароль пользователя БД
  • DBHOST — сервер БД, у меня localhost
  • DBPORT — порт БД
  • DBPROT — протокол БД
  • DBBACKUPDIR — путь куда бэкапить БД, у меня смонтированная шара
  • DBARCHDIR — путь куда сохранять предыдущий бэкап БД (на всякий случай)
  • DBCCNET — имя базы cnet
  • DBSEAFILE — имя базы seafile
  • DBSEAHUB — имя базы seahub
  • DATASEAFILEBACKUPDIR — путь куда бэкапить файлы
  • DATASEAFILEDIR — путь откуда бэкапить файлы, директория FUSE
  • DATACONFBACKUPDIR — путь куда бэкапить конфиги
  • DATACONFDIR — путь откуда бэкапить конфиги
  • TEMPDIR — путь к временным файлам
  • BACKUPMOUNT — смонтированная шара для бэкапа, проверяем её существование
  • FUSEMOUNT — смонтированная директория FUSE, проверяем её существование

Для резервирования БД используем mysqldump. Бэкап сжимаем с помощью bzip. Файлы бэкапим с помощью rsync. Я удаляю из архивной копии более несуществующие файлы.

Если нет смонтированных папок BACKUPMOUNT и FUSEMOUNT, резервное копирование данных не осуществляется, некуда и/или неоткуда бэкапить.

Обслуживание осуществляется с остановкой сервисов!

Содержимое mnt.seafile.sh:

#!/bin/bash

#####
# Uncomment the following line if you rather want to run the script manually.
# Display usage if the script is not run as root user
#        if [[ $USER != "root" ]]; then
#                echo "This script must be run as root user!"
#                exit 1
#        fi
#
# echo "Super User detected!!"
# read -p "Press [ENTER] to start the procedure, this will stop the seafile server!!"
#####

FUSEMOUNT="/opt/seafile-fuse"
SEAFILEDIR="/opt/seafile-server-latest/"

log(){
  message="$(date +"%y-%m-%d %T") $@"
  echo $message
}

# stop the services
log "------------------------------------------"
log "Starting maintenance procedure for seafile"
log "Stopping the services"
systemctl stop nginx.service
systemctl stop minidlna.service
systemctl stop seafile-fuse.service
sleep 20
umount ${FUSEMOUNT}
sleep 10
systemctl stop seafile.service
systemctl stop seahub.service
log "Giving the server some time to stop services properly"
sleep 20

# run the cleanup
log "Seafile cleanup started"
sudo -u sf ${SEAFILEDIR}seaf-gc.sh -r
sudo -u sf ${SEAFILEDIR}seaf-gc.sh
log "Seafile cleanup done!"
log "Giving the server some time"
sleep 20

# run repair
log "Seafile repair started"
sudo -u sf ${SEAFILEDIR}seaf-fsck.sh --repair
log "Seafile repair done!"
log "Giving the server some time"
sleep 20

# start the services
log "Starting the services"
systemctl start seafile.service
systemctl start seahub.service
sleep 20
systemctl start seafile-fuse.service
systemctl start jellyfin.service
sleep 20
systemctl start nginx.service

log "Seafile maintenance procedure complete!"

Здесь:

  • FUSEMOUNT — смонтированная директория FUSE, иногда стандартный скрипт остановки сервиса не демонтирует папку, приходится делать это вручную
  • SEAFILEDIR — путь к директории со скриптами обслуживания
  1. останавливаются службы, в том числе зависимые, для примера здесь зависимые nginx и minidlna
  2. запускается сборщик мусора
  3. запускается восстановление библиотек
  4. запускаются остановленные службы

Скрипты накидал на коленке, натуральный продукт, без GPT.

Теги

 

Похожие материалы

Zabbix — оповещение по телефону через Asterisk

Как-то раз мы проспали проблему. Zabbix прислал пару SMS, но никто ночью не проснулся. А если бы Zabbix позвонил, да ещё бы и рассказал о проблеме, то было бы проще всё упавшее поднимать. Учим Zabbix звонить на телефон.

Теги