1c: различия между версиями

Материал из wiki.nntc.nnov.ru
Перейти к навигации Перейти к поиску
(Базовый скрипт)
(Базовый скрипт)
 
(не показаны 4 промежуточные версии этого же участника)
Строка 48: Строка 48:
 
BACKUP_TIMEOUT_SEC="${7}"
 
BACKUP_TIMEOUT_SEC="${7}"
 
TIMEOUT_COUNTER=0
 
TIMEOUT_COUNTER=0
 +
LOCK_FILE_PATH="/home/usr1cv8/.1cv8/1C/1cv8/reg_1541/snccntx8e79a393-c2af-4fd7-b25a-af6b5ed19bfa/snccntx.dat"
 
#-----------------------------
 
#-----------------------------
 
export DISPLAY="${DISPLAY}"
 
export DISPLAY="${DISPLAY}"
Строка 53: Строка 54:
 
PASSWORD=`cat ${PASSWORD_FILE} | head -1`
 
PASSWORD=`cat ${PASSWORD_FILE} | head -1`
 
infobase_suffix="$(date +%Y-%m-%d-%H-%M-%S).dt"
 
infobase_suffix="$(date +%Y-%m-%d-%H-%M-%S).dt"
 +
TMP_STORAGE="/opt/1c_backup_scripts/tmp_storage"
 +
ib_tmp_filepath="${TMP_STORAGE}/${REF}__${infobase_suffix}"
 +
ib_tmp_log="${ib_tmp_filepath}.log"
 
ib_filepath="${STORAGE}/${REF}__${infobase_suffix}"
 
ib_filepath="${STORAGE}/${REF}__${infobase_suffix}"
 
ib_log="${ib_filepath}.log"
 
ib_log="${ib_filepath}.log"
Строка 62: Строка 66:
  
 
for f in $(/bin/ls $filenames_cmd); do
 
for f in $(/bin/ls $filenames_cmd); do
 +
#echo "f=$f"
 
datetime_from_file=`echo ${f} | awk -F '__' {'print $2'} | awk -F '.' {'print $1'}`
 
datetime_from_file=`echo ${f} | awk -F '__' {'print $2'} | awk -F '.' {'print $1'}`
 +
#echo "datetime_from_file=${datetime_from_file}"
 +
 +
#2023-12-24-22-01-02
 
Y=`echo ${datetime_from_file} | awk -F '-' {'print $1'}`
 
Y=`echo ${datetime_from_file} | awk -F '-' {'print $1'}`
 
M=`echo ${datetime_from_file} | awk -F '-' {'print $2'}`
 
M=`echo ${datetime_from_file} | awk -F '-' {'print $2'}`
Строка 89: Строка 97:
 
   if [ ! -d /proc/${1}/ ]; then
 
   if [ ! -d /proc/${1}/ ]; then
 
     nice_text="Выгрузка информационной базы успешно завершена"
 
     nice_text="Выгрузка информационной базы успешно завершена"
     res_text=$(grep -o -i "${nice_text}" ${ib_log})
+
     res_text=$(grep -o -i "${nice_text}" ${ib_tmp_log})
  
 
     # start apache2
 
     # start apache2
Строка 95: Строка 103:
  
 
     if [ "${res_text}" = "${nice_text}" ]; then
 
     if [ "${res_text}" = "${nice_text}" ]; then
 +
      /bin/cp ${ib_tmp_filepath} ${ib_filepath} && /bin/rm ${ib_tmp_filepath}
 +
      /bin/cp ${ib_tmp_log} ${ib_log} && /bin/rm ${ib_tmp_log}
 +
      #echo "TEST: ${ib_filepath} AND ${ib_log}"
 
       rotate_backups
 
       rotate_backups
 
       exit 0
 
       exit 0
Строка 101: Строка 112:
 
     exit 1
 
     exit 1
 
   fi
 
   fi
 +
  #echo "pid alive: ${1}"
 
   sleep 1
 
   sleep 1
 
   TIMEOUT_COUNTER=$(($TIMEOUT_COUNTER+1))
 
   TIMEOUT_COUNTER=$(($TIMEOUT_COUNTER+1))
 
   wait ${1}
 
   wait ${1}
 
}
 
}
 +
 +
# prepare tmp storage
 +
[ ! -d ${TMP_STORAGE} ] && sudo mkdir "${TMP_STORAGE}" && sudo chown administrator: "${TMP_STORAGE}" -R
  
 
# stop apache2
 
# stop apache2
Строка 110: Строка 125:
 
sleep 2
 
sleep 2
  
DISPLAY=:0 XAUTHORITY=/home/administrator/.Xauthority ${bin1c} CONFIG /N "${LOGIN}" /P "${PASSWORD}" /S "${SRV}/${REF}" /DumpIB "${ib_filepath}" /OUT "${ib_log}" &
+
# reset srv1cv8 sessions
 +
sudo systemctl stop srv1cv8
 +
sleep 2
 +
sudo /bin/rm -f "${LOCK_FILE_PATH}"
 +
sudo systemctl start srv1cv8
 +
sleep 2
 +
 
 +
DISPLAY=:0 XAUTHORITY=/home/administrator/.Xauthority ${bin1c} CONFIG /N "${LOGIN}" /P "${PASSWORD}" /S "${SRV}/${REF}" /DumpIB "${ib_tmp_filepath}" /OUT "${ib_tmp_log}" &
 
main_process_pid=$!
 
main_process_pid=$!
  
 
wait ${main_process_pid}
 
wait ${main_process_pid}
EOF
 
 
</pre>
 
</pre>
  
Строка 122: Строка 143:
  
 
===Скрипт для резервирования конкретной базы данных===
 
===Скрипт для резервирования конкретной базы данных===
 +
Данный скрипт представляет из себя обёртку над выше приведённым скриптом, с заданием конкретных параметров резервирования
 +
 +
<pre>
 +
cat << 'EOF' > /opt/1c_backup_scripts/backup__my_super_infobase.sh
 +
#!/bin/bash
 +
 +
### PARAMETERS ###
 +
STORAGE="/mnt/storage/my-1c-host-backups" # каталог для сохранения резервных копий
 +
SRV="my-1c-host"                          # хост, на котором работает платформа "1С: Предприятие"
 +
REF="my_super_infobase"                  # имя базы данных, которую резервируем
 +
LOGIN="backupuser"                        # 1с-пользователь, которому разрешено резервировать базу данных
 +
PASSWORD_FILE="/home/administrator/.1c-cluster-infobases-backup.pass" # в этом файле должен находиться только пароль от 1с-пользоателя
 +
KEEP_BACKUPS_FOR_LAST_DAYS="2"            # сохранить резервные копии только за эти несколько последных дней (в текущем примере - за 2 последних дня)
 +
BACKUP_TIMEOUT_SEC="300"                  # таймаут, в течение которого разрешено работать процессу резервирования (процессу платформы "1С: Предприятие". Если за этот таймаут процесс не успел сделать резервную копию, то он снимается с выполнения)
 +
 +
# ------------------------------------------------------------------------------------------------
 +
 +
### BOT PARAMETERS
 +
TELEGRAM_BOT_TOKEN=""            # сюда нужно вписать токен телеграм-бота, который будет отсылать уведомления
 +
TELEGRAM_DESTINATION_GROUP_ID=""  # сюда нужно вписать идентификатор телеграм-пользователя или телеграм-группы (не забывайте про минус в начале, если это идентификатор группы), в которого (или в которую, если это группа) бот будет писать сообщения
 +
 +
function send_message_telegram(){
 +
#exit 0  # раскомментируйте эту строчку, если отсылка сообщений телеграм-ботом не нужна (следовательно, и параметры дя бота при этом можно не задавать)
 +
message=${1}
 +
curl -s -X POST \
 +
    -H 'Content-Type: application/json' \
 +
    -d "{\"chat_id\": \"${TELEGRAM_DESTINATION_GROUP_ID}\", \"text\": \"${message}\", \"disable_notification\": true}" \
 +
    https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage > /dev/null
 +
}
 +
# ------------------------------------------------------------------------------------------------
 +
 +
### START ###
 +
BASE=`dirname ${0}`
 +
${BASE}/backup_infobase_1c_generic.sh "${STORAGE}" "${SRV}" "${REF}" "${LOGIN}" "${PASSWORD_FILE}" "${KEEP_BACKUPS_FOR_LAST_DAYS}" "${BACKUP_TIMEOUT_SEC}"
 +
res=$?
 +
 +
if [ ${res} -eq 0 ]; then
 +
send_message_telegram "[Успешно]\nРезервное копирование информационной базы '${REF}' выполнено успешно"
 +
else
 +
send_message_telegram "[Ошибка]\nРезервное копирование информационной базы '${REF}' не выполнено"
 +
fi
 +
EOF
 +
</pre>
 +
 +
Делаем файл исполняемым
 +
 +
chmod +x /opt/1c_backup_scripts/backup__my_super_infobase.sh
 +
 +
===Ставим задачу для планировщика cron===
 +
 +
Под пользователем
 +
 +
administrator
 +
 +
в терминале открываем временный файл для настройки crontab
 +
 +
EDITOR=nano crontab -e
 +
 +
в результате редактором
 +
 +
nano
 +
 +
будет открыт временный файл для установки параметров планировщика для текущего пользователя. Отредактировав и сохранив (Ctrl+O - Enter) изменения в этом файле и закрыв редактор (Ctrl+X) будет сконфигурирован планировщик для текущего пользователя.
 +
 +
Проверить корректность заданных параметров планировщика можно выполнением команды
 +
 +
crontab -l
 +
 +
В случае, если планировщик был сконфигурирован на запуск скрипта резервного копирования каждые сутки с 23:01, вывод команды проверки должен быть примерно такой:
 +
<pre>
 +
#minute (0-59),
 +
#| hour (0-23),
 +
#| | day of the month (1-31),
 +
#| | | month of the year (1-12),
 +
#| | | | day of the week (0-6 with 0=Sunday).
 +
#| | | | | commands
 +
1      23 * * * /opt/1c_backup_scripts/backup__my_super_infobase.sh
 +
</pre>

Текущая версия на 23:48, 1 января 2024

В GNU/Linux

Автоматизация резервного копирования информационных баз

Предполагается, что платформа "1С Предприятие" работает на GNU/Linux системе и скрипт резервного копирования выполняется от пользователя

administrator

, графическое окружение которого автоматически запускается после загрузки компьютера.

Дело в том, что по каким-то причинам, разработчики платформы "1С Предприятие" не заложили в систему запуск резервного копирования в headless-режиме, поэтому платформе необходим дисплей X-сервера.

Также предполагается, что файл с паролем от пользователя платформы "1С Предприятие", которому разрешено выполнять резервное копирование, хранится в файле

/home/administrator/.1c-cluster-infobases-backup.pass

и рекомендуемые права на этот файл

0400


Подготовка каталога для скриптов

mkdir /opt/1c_backup_scripts

Базовый скрипт

При необходимости, в тексте скрипта, отредактируйте строчку

bin1c="/opt/1cv8/x86_64/8.3.23.1912/1cv8"

, указав путь до конкретной версии платформы "1С Предприятие".

Ниже предоставлен текст, который можно выделить, скопировать в текстовый редактор, при необходимости поправить, затем весь этот текст можно бросить в консоль для создания файла посредством heredoc-синтаксиса:

cat << 'EOF' > /opt/1c_backup_scripts/backup_infobase_1c_generic.sh 
#!/bin/bash
export LANG=ru_RU.UTF-8

NON_ROOT_USER="administrator"
DISPLAY=":0"
STORAGE="${1}"
SRV="${2}"
REF="${3}"
LOGIN="${4}"
PASSWORD_FILE="${5}"
KEEP_BACKUPS_FOR_LAST_DAYS="${6}"
BACKUP_TIMEOUT_SEC="${7}"
TIMEOUT_COUNTER=0
LOCK_FILE_PATH="/home/usr1cv8/.1cv8/1C/1cv8/reg_1541/snccntx8e79a393-c2af-4fd7-b25a-af6b5ed19bfa/snccntx.dat"
#-----------------------------
export DISPLAY="${DISPLAY}"
bin1c="/opt/1cv8/x86_64/8.3.23.1912/1cv8"
PASSWORD=`cat ${PASSWORD_FILE} | head -1`
infobase_suffix="$(date +%Y-%m-%d-%H-%M-%S).dt"
TMP_STORAGE="/opt/1c_backup_scripts/tmp_storage"
ib_tmp_filepath="${TMP_STORAGE}/${REF}__${infobase_suffix}"
ib_tmp_log="${ib_tmp_filepath}.log"
ib_filepath="${STORAGE}/${REF}__${infobase_suffix}"
ib_log="${ib_filepath}.log"

function rotate_backups(){
filenames_cmd="${STORAGE}/${REF}*"
current_unixtime=`date +%s --date="$(date +%Y-%m-%d) 00:00:00"`
test_unixtime=$(($current_unixtime-$KEEP_BACKUPS_FOR_LAST_DAYS*60*60*24))

for f in $(/bin/ls $filenames_cmd); do
#echo "f=$f"
datetime_from_file=`echo ${f} | awk -F '__' {'print $2'} | awk -F '.' {'print $1'}`
#echo "datetime_from_file=${datetime_from_file}"

#2023-12-24-22-01-02
Y=`echo ${datetime_from_file} | awk -F '-' {'print $1'}`
M=`echo ${datetime_from_file} | awk -F '-' {'print $2'}`
D=`echo ${datetime_from_file} | awk -F '-' {'print $3'}`
h=`echo ${datetime_from_file} | awk -F '-' {'print $4'}`
m=`echo ${datetime_from_file} | awk -F '-' {'print $5'}`
s=`echo ${datetime_from_file} | awk -F '-' {'print $6'}`

unixtime_from_file=`date +%s --date="${Y}-${M}-${D} ${h}:${m}:${s}"`

if [[ $unixtime_from_file -lt $test_unixtime ]]; then
  echo "delete file: ${f}"
  /bin/rm ${f}
else
  echo "keep file: ${f}"
fi
done
}

function wait(){

  if [[ $TIMEOUT_COUNTER -ge $BACKUP_TIMEOUT_SEC ]]; then
    kill -9 ${1}
  fi

  if [ ! -d /proc/${1}/ ]; then
    nice_text="Выгрузка информационной базы успешно завершена"
    res_text=$(grep -o -i "${nice_text}" ${ib_tmp_log})

    # start apache2
    sudo systemctl start httpd2

    if [ "${res_text}" = "${nice_text}" ]; then
      /bin/cp ${ib_tmp_filepath} ${ib_filepath} && /bin/rm ${ib_tmp_filepath}
      /bin/cp ${ib_tmp_log} ${ib_log} && /bin/rm ${ib_tmp_log}
      #echo "TEST: ${ib_filepath} AND ${ib_log}"
      rotate_backups
      exit 0
    fi

    exit 1
  fi
  #echo "pid alive: ${1}"
  sleep 1
  TIMEOUT_COUNTER=$(($TIMEOUT_COUNTER+1))
  wait ${1}
}

# prepare tmp storage
[ ! -d ${TMP_STORAGE} ] && sudo mkdir "${TMP_STORAGE}" && sudo chown administrator: "${TMP_STORAGE}" -R

# stop apache2
sudo systemctl stop httpd2
sleep 2

# reset srv1cv8 sessions
sudo systemctl stop srv1cv8
sleep 2
sudo /bin/rm -f "${LOCK_FILE_PATH}"
sudo systemctl start srv1cv8
sleep 2

DISPLAY=:0 XAUTHORITY=/home/administrator/.Xauthority ${bin1c} CONFIG /N "${LOGIN}" /P "${PASSWORD}" /S "${SRV}/${REF}" /DumpIB "${ib_tmp_filepath}" /OUT "${ib_tmp_log}" &
main_process_pid=$!

wait ${main_process_pid}

Делаем файл исполняемым

chmod +x /opt/1c_backup_scripts/backup_infobase_1c_generic.sh

Скрипт для резервирования конкретной базы данных

Данный скрипт представляет из себя обёртку над выше приведённым скриптом, с заданием конкретных параметров резервирования

cat << 'EOF' > /opt/1c_backup_scripts/backup__my_super_infobase.sh 
#!/bin/bash

### PARAMETERS ###
STORAGE="/mnt/storage/my-1c-host-backups" # каталог для сохранения резервных копий
SRV="my-1c-host"                          # хост, на котором работает платформа "1С: Предприятие"
REF="my_super_infobase"                   # имя базы данных, которую резервируем
LOGIN="backupuser"                        # 1с-пользователь, которому разрешено резервировать базу данных
PASSWORD_FILE="/home/administrator/.1c-cluster-infobases-backup.pass" # в этом файле должен находиться только пароль от 1с-пользоателя 
KEEP_BACKUPS_FOR_LAST_DAYS="2"            # сохранить резервные копии только за эти несколько последных дней (в текущем примере - за 2 последних дня)
BACKUP_TIMEOUT_SEC="300"                  # таймаут, в течение которого разрешено работать процессу резервирования (процессу платформы "1С: Предприятие". Если за этот таймаут процесс не успел сделать резервную копию, то он снимается с выполнения)

# ------------------------------------------------------------------------------------------------

### BOT PARAMETERS
TELEGRAM_BOT_TOKEN=""             # сюда нужно вписать токен телеграм-бота, который будет отсылать уведомления
TELEGRAM_DESTINATION_GROUP_ID=""  # сюда нужно вписать идентификатор телеграм-пользователя или телеграм-группы (не забывайте про минус в начале, если это идентификатор группы), в которого (или в которую, если это группа) бот будет писать сообщения

function send_message_telegram(){
#exit 0  # раскомментируйте эту строчку, если отсылка сообщений телеграм-ботом не нужна (следовательно, и параметры дя бота при этом можно не задавать)
message=${1}
curl -s -X POST \
     -H 'Content-Type: application/json' \
     -d "{\"chat_id\": \"${TELEGRAM_DESTINATION_GROUP_ID}\", \"text\": \"${message}\", \"disable_notification\": true}" \
     https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage > /dev/null
}
# ------------------------------------------------------------------------------------------------

### START ###
BASE=`dirname ${0}`
${BASE}/backup_infobase_1c_generic.sh "${STORAGE}" "${SRV}" "${REF}" "${LOGIN}" "${PASSWORD_FILE}" "${KEEP_BACKUPS_FOR_LAST_DAYS}" "${BACKUP_TIMEOUT_SEC}"
res=$?

if [ ${res} -eq 0 ]; then
send_message_telegram "[Успешно]\nРезервное копирование информационной базы '${REF}' выполнено успешно"
else
send_message_telegram "[Ошибка]\nРезервное копирование информационной базы '${REF}' не выполнено"
fi
EOF

Делаем файл исполняемым

chmod +x /opt/1c_backup_scripts/backup__my_super_infobase.sh

Ставим задачу для планировщика cron

Под пользователем

administrator

в терминале открываем временный файл для настройки crontab

EDITOR=nano crontab -e

в результате редактором

nano

будет открыт временный файл для установки параметров планировщика для текущего пользователя. Отредактировав и сохранив (Ctrl+O - Enter) изменения в этом файле и закрыв редактор (Ctrl+X) будет сконфигурирован планировщик для текущего пользователя.

Проверить корректность заданных параметров планировщика можно выполнением команды

crontab -l

В случае, если планировщик был сконфигурирован на запуск скрипта резервного копирования каждые сутки с 23:01, вывод команды проверки должен быть примерно такой:

#minute (0-59),
#|	hour (0-23),
#|	|	day of the month (1-31),
#|	|	|	month of the year (1-12),
#|	|	|	|	day of the week (0-6 with 0=Sunday).
#|	|	|	|	|	commands
1       23	*	*	*	/opt/1c_backup_scripts/backup__my_super_infobase.sh