07 октября 2019

PostgreSQL для 1С 8.3 - резервное копирование

В этой статье разберем оптимизацию работы с моментальным снимком отдельной базы 1С в кластере PostgreSQL средствами pg_dump.exe, pg_restore.exe, psql.exe в среде Windows Server 2008,2012,2016. А также разберем проблемные ситуации и неожиданные ограничения при работе 1С в связке с PostgreSQL. Для Linux все аналогично.

 
Копирование-восстановление с помощью моментального снимка базы может потребоваться в разных случаях:
- копирование в другую базу в пределах кластера
- копирование в другую базу на другом сервере с более высокой версией PostgreSQL
- восстановление текущей базы
- восстановление некоторых таблиц текущей базы в случае падения 1С и т.д.

Задача 1. Копирование базы 1С на лету во время работы пользователей с сохранением целостности с помощью команд
pg_dump.exe, psql.exe

Для этого в общем случае алгоритм следующий:
Шаг 1. Выгружаем с помощью pg_dump.exe все таблицы из базы данных, кроме данных таблицы config (т.е. для config выгружаем только ее схему)
Шаг 2. Выгружаем с помощью psql.exe данные таблицы public.config с помощью COPY WITH BINARY

Итак,
- Шаг 1. Выгружаем с помощью pg_dump.exe все таблицы из базы данных, кроме данных таблицы config (т.е. для config  выгружаем только ее схему):
"<путь к pg_dump>\pg_dump.exe" и далее параметры с комментариями
--host <ip адрес или имя хоста сервера>
--port <порт>
--username "postgres" – имя пользователя
--role "postgres" - роль
--no-password – не спрашивать пароль в пакетном режиме
--format directory – создавать архив в виде каталога для использования параметра --jobs. При этом каждая таблица копируется в отдельный файл в каталоге, что позволяет распараллелить процесс создания архива
--jobs=<количество параллельных потоков процессора> - подбирается примерно как <количество ядер процессора>*2, можно пробовать увеличение или уменьшение параметра, чтобы максимально загрузить систему, не мешая работе пользователей. Практически на каждый процесс запускается копирование одной таблицы из базы данных. Сколько процессов задействовано, столько таблиц и обрабатывается одновременно. С помощью этого параметра можно достигнуть ускорения резервного копирования в 4 раза и более в зависимости от мощности оборудования сервера.
--blobs – позволяет выгружать поля большого размера
--encoding UTF8 - кодировка
--verbose – включить подробное комментирование
--exclude-table-data=config - исключить из выгрузки данные таблицы config, т.е. выгрузить только ее схему (config содержит записи: конфигурация, конфигурации поставщиков, отличия основной конфигурации от конфигураций поставщиков). Это требуется, когда база находится на поддержке у двух и более конфигураций поставщика и (или) очень много изменений внесено в конфигурацию. При этом размер изменений основной конфигурации относительно конфигурации одного из поставщиков приближается к 1Гб, что является пределом для поля большого размера в PostgreSQL. А 1С хранит изменения только в одной из записей таблицы config. При небольшом размере конфигурации можно не использовать этот параметр. Но при критическом (если размер хотя бы одной записи таблицы public.config (конфигурации) после чтения и распаковки в стандартный поток вывода stdout превысит 1 Гб) pg_dump.exe завершится с ошибкой:
pg_dump: Ошибка выгрузки таблицы "config": сбой в PQgetResult().
pg_dump:  Сообщение  об ошибке с сервера: invalid memory alloc request size 11173708065
pg_dump: Выполнялась команда: COPY public.config (filename, creation, modified, attributes, datasize, binarydata) TO stdout;
Если используется --format custom, то архив выгружается в виде одного файла, и ошибка создания архива на таблице public.config обнаружится при выполнении команды pg_restore, что и есть самое неприятное:
pg_restore: обрабатываются данные таблицы "public._usersworkhistory"
pg_restore: обрабатываются данные таблицы "public._yearoffset"
pg_restore: обрабатываются данные таблицы "public.config"
pg_restore: [внешний архиватор] не удалось прочитать входной файл: конец файла
(кроме того --format custom не позволит использовать --jobs - распараллеливание)
Наблюдается на больших конфигурациях KA 1.1-2.4, УПП 1.3, ERP 2.4.
--file "<имя каталога архива без таблицы config>"
"<имя базы данных>"
Шаг 2. Выгружаем с помощью psql.exe данные таблицы public.config с помощью COPY WITH BINARY:
md "<имя каталога архива только с таблицей config >" - создаем каталог для таблицы config
"<путь к psql>\psql.exe" – далее параметры
--host <ip адрес или имя хоста сервера>
--port <порт>
--username "postgres" – имя пользователя
--no-password – не спрашивать пароль в пакетном режиме
--command "COPY public.config TO '<имя каталога архива только с таблицей config с разделителями \\ для винды>' WITH BINARY;"
--dbname="<имя базы данных>"

Задача 2. Восстановление базы 1С в копию во время работы пользователей с сохранением целостности с помощью команд pg_restore.exe, psql.exe. Для этого в общем случае алгоритм следующий:
Шаг 0. Создаем пустую копию базы средствами pgAdmin.exe или с помощью psql.exe, dropdb, createdb.
Шаг 1. Загружаем с помощью pg_restore.exe все таблицы из архива базы данных, кроме данных таблицы config (т.е. для config  загружаем только ее схему)
Шаг 2. Загружаем с помощью psql.exe данные таблицы public.config с помощью COPY WITH BINARY

Шаг 0. Создаем пустую копию базы средствами pgAdmin.exe или с помощью psql.exe, dropdb, createdb.
Если база данных существует, мы должны сначала удалить ее из кластера с помощью команды DROP DATABASE "<имя базы данных>", а затем создать заново с помощью команды CREATE DATABASE "<имя базы данных>". Проще всего это сделать через pgAdmin, так как в нем есть запрос на удаление базы и образец запроса на создание базы. При удалении базы необходимо закрыть все соединения с базой, иначе база не будет удалена. Для Windows запрос на создание базы выглядит так:

CREATE DATABASE "<имя базы данных>"
WITH
OWNER = postgres
ENCODING = 'UTF8'
LC_COLLATE = 'Russian_Russia.1251'
LC_CTYPE = 'Russian_Russia.1251'
TABLESPACE = pg_default
CONNECTION LIMIT = -1;

Если мы время от времени хотим проверять, что база корректно достается из архива, то имеет cмысл автоматизировать шаг 0 в батнике командами psql, dropdb, createdb (добавлено по просьбам читателей):

0.1 Перед удалением закрываем все активные соединения с базой <имя базы данных>, кроме текущего:
"<путь к psql>\psql.exe" – далее параметры
--host <ip адрес или имя хоста сервера>
--port <порт>
--username "postgres" – имя пользователя
--dbname="<имя базы данных>"
--no-password – не спрашивать пароль в пакетном режиме
--command "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '<имя базы данных>' AND pid <> pg_backend_pid();"

0.2 Удаляем базу <имя базы данных>, если она существует без подтверждения об удалении.
"<путь к dropdb>\dropdb.exe"
--host <ip адрес или имя хоста сервера>
--port <порт>
--username "postgres" – имя пользователя
--no-password – не спрашивать пароль в пакетном режиме
--if-exists - проверка существования базы
--echo - вывод команд SQL, которые выполнит postgreSQL при вызове
"<имя базы данных>"

0.3 Создаем заново базу <имя базы данных> после удаления
"<путь к createdb>\createdb.exe"
--host <ip адрес или имя хоста сервера>
--port <порт>
--username "postgres" – имя пользователя
--no-password – не спрашивать пароль в пакетном режиме
--echo - вывод команд SQL, которые выполнит postgreSQL при вызове
--owner="postgres" - владелец базы
--encoding="UTF8" - кодировка
--locale="Russian_Russia.1251" - устанавливает одновременно параметры LC_COLLATE и LC_CTYPE для базы данных.
--tablespace="pg_default" - указывает табличное пространство, используемое по умолчанию.
"<имя базы данных>"
Теперь уже не нужно даже лезть в pgAdmin и там корячиться.
Шаг 1. Загружаем с помощью pg_restore.exe все таблицы из архива базы данных, кроме данных таблицы config (т.е. для config  загружаем только ее схему):
"<путь к pg_restore>\pg_restore.exe"
--host <ip адрес или имя хоста сервера>
--port <порт>
--username "postgres" – имя пользователя
--role "postgres" - роль
--no-password – не спрашивать пароль в пакетном режиме
--dbname "<имя базы данных в которую восстанавливаем>"
--jobs=<количество параллельных потоков процессора> - подбирается примерно как <количество ядер процессора>*2, можно пробовать увеличение или уменьшение параметра, чтобы максимально загрузить систему, не мешая работе пользователей. Практически на каждый процесс запускается восстановление одной таблицы базы данных. Сколько процессов задействовано, столько таблиц и индексов обрабатывается одновременно. С помощью этого параметра можно достигнуть ускорения восстановления базы в 2-3 раза и более в зависимости от мощности оборудования сервера.
--verbose – включить подробное комментирование
"<имя каталога архива без таблицы config>"

Шаг 2. Загружаем с помощью psql.exe данные таблицы public.config с помощью COPY WITH BINARY
"<путь к psql>\psql.exe" – далее параметры
--host <ip адрес или имя хоста сервера>
--port <порт>
--username "postgres" – имя пользователя
--dbname="<имя базы данных>"
--no-password – не спрашивать пароль в пакетном режиме
--command "\COPY public.config FROM '<имя каталога архива только с таблицей config с разделителями \\ для винды>' WITH BINARY;"

Обратите внимание на метакоманду \COPY вместо просто COPY.
\COPYоткрывает файл и передает содержимое на сервер, тогда как COPY сообщает серверу, что он сам открывает файл и читает его, что может быть проблематичным по разрешению или даже невозможно, если клиент и сервер работают на разных компьютерах без совместного доступа к файлам между ними.
Соответственно при использовании просто COPY может выскочить следующая ошибка:
Postgres ERROR: Permission denied (не удалось открыть файл для чтения)
Заметим, что архив базы может быть успешно восстановлен на последующих версиях  PostgreSQL. В моем случае, я переносил базу с сервера PostgreSQL 9.6 на PostgreSQL 10.3.
Все проходило гладко. Трудности теоретически могут возникнуть в команде  \COPY, т.к. она является платформо-зависимой.
На реальной базе размером 380 Гб за счет распараллеливания было достигнуто ускорение при работе pg_dump - в 4 раза, при работе pg_restore - в 2,5 раза, что весьма существенно, когда процесс занимает несколько часов.

Было: 2 часа на копирование, стало 0,5 часа на копирование; было 10 ч на восстановление, стало 4 ч на восстановление.
После перехода на более мощный сервер получили еще более существенные результаты:
Было: 2 часа на копирование, стало 0,5 часа на копирование; было 10 ч на восстановление, стало 1 ч  40 мин на восстановление. То есть количество ядер процессора и более быстрые диски при тех же параметрах дают значительное ускорение. Теперь чтобы скопировать и развернуть нашу огромную базу требуется всего 2 часа!

Ниже привожу примеры bat-файлов (качайте) для создания архивной копии базы данных DO_PROBA и восстановления в другую базу данных DO_PROBA_COPY. При этом в названии каталогов архива используется дата и время начала архивации и выводятся замеры времени на создание-восстановление. При восстановлении из вновь созданного архива необходимо каждый раз менять дату и время в bat-файле для восстановления (ее можно скопировать из имени каталога архива по образцу). Теперь будьте очень осторожны при восстановлении базы. По просьбам читателей и пользователей в bat-файлы добавлены команды автоматического удаления и создания восстанавливаемой базы в случае ее существования. Не ошибитесь в наименовании базы в команде SET ar_base_to=<Имя базы, куда восстанавливаем> !!! Иначе можно легко порушить существующие базы. 
СОВЕТ 1: периодически проверяйте (хотя бы раз в неделю) загрузку бэкапа в какую-нибудь тестовую базу и запускайте для проверки работоспособности режим конфигуратора 1С и рабочий режим. Тогда всегда будете уверены в своей архивной копии!
СОВЕТ 2: после отладки копирования и восстановления можно настроить Планировщик заданий (для Windows) на запуск нашего bat-файла по выбранному расписанию. Например, в 3:00 ночи ежедневно, пока никто из пользователей не работает.
***********
для поиска
pg_dump: Ошибка выгрузки таблицы «config»: сбой в PQgetResult().
pg_dump: Сообщение об ошибке с сервера: invalid memory alloc request size 11173708065
pg_dump: Выполнялась команда: COPY public.config (filename, creation, modified, attributes, datasize, binarydata) TO stdout;


СамСкрипт
#!/bin/sh
# Скрипт резервного копирования баз данных PostgreSQL
# Копирование базы 1С на лету во время работы пользователей с сохранением целостности с помощью команд pg_dump.exe, psql.exe
# Для этого в общем случае алгоритм следующий:
# Шаг 1. Выгружаем с помощью pg_dump все таблицы из базы данных, кроме данных таблицы config (т.е. для config выгружаем только ее схему)
# Шаг 2. Выгружаем с помощью psql данные таблицы public.config с помощью COPY WITH BINARY
# Шаг 3. Производим очистку и переиндексацю базы данных
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
#Логин и пароль пользователя, имеющего право выполнять резервные копии баз данных
dbUser=postgres
PGPASSWORD=
export PGPASSWORD
slog=/var/log/postgresql/service.log

#Путь резервных копий
pathB=/mnt/disk3/backup

#Резервирование базы данных
#Задаем имя резервируемой базы данных
database=UPP
#Задаем переменную date для того чтобы резервная копия базы данных и таблицы config имели одно и то же время
date=$(date "+%Y-%m-%d_%H-%M")

# Записываем информацию в лог с секундами
echo "`date +"%Y-%m-%d_%H-%M-%S"` Запуск резервного копирования базы — ${database}" >> ${slog}

#Выгружаем все таблицы из базы данных, кроме данных таблицы config (т.е. для config выгружаем только ее схему)
#pg_dump -U $dbUser —exclude-table-data=config $database | pigz > $pathB/${database}_${date}_without_public.config.sql.gz
#Выгружаем в несколько потоков (10 потоков)
pg_dump --format=d --jobs=10 --blobs -U $dbUser --exclude-table-data=config --file=$pathB/${database}_${date}_without_public.config $database
#Выгружаем данные таблицы public.config с помощью COPY WITH BINARY:
psql -U $dbUser —command="COPY public.config TO ‘$pathB/${database}_${date}_public.config.sql’ WITH BINARY;" $database

# Записываем информацию в лог с секундами
echo "`date +"%Y-%m-%d_%H-%M-%S"` Резервное копирование базы — ${database}" выполнено >> ${slog}

#Для выгрузки в сжатом состоянии. Как показала практика, не поддается сжатию
psql -U $dbUser —command="COPY public.config TO PROGRAM ‘pigz -0 > $pathB/${database}_${date}_public.config.sql.gz’ WITH BINARY;" $database

#Выполняем очистку и анализ базы данных 1С
echo "`date +"%Y-%m-%d_%H-%M-%S"` Запуск очистки базы — ${database}" >> ${slog}
vacuumdb -U $dbUser —full —analyze —dbname=${database}
echo "`date +"%Y-%m-%d_%H-%M-%S"` Очистка базы — ${database} выполнена" >> ${slog}

# Переиндексировать базу
echo "`date +"%Y-%m-%d_%H-%M-%S"` Запуск реиндексации базы — ${database}" >> ${slog}
reindexdb -U $dbUser —dbname=${database}
echo "`date +"%Y-%m-%d_%H-%M-%S"` Реиндексация базы — ${database} выполнена" >> ${slog}

# Удаляем в папке с бэкапами архивы старше 31-х дней
#find /${pathB} -type f -mtime +31 -exec rm -rf {} \;
#find /${pathB} -type d -mtime +31 -exec rm -rf {} \;

unset PGPASSWORD
 

via http://infostart.msk.ru/public/956734/ 
https://serveradmin.ru/bekap-i-vosstanovlenie-bazyi-1s-v-bd-postgresql/ 

1 комментарий:

  1. Ежедневник Админа: Postgresql Для 1С 8.3 - Резервное Копирование >>>>> Download Now

    >>>>> Download Full

    Ежедневник Админа: Postgresql Для 1С 8.3 - Резервное Копирование >>>>> Download LINK

    >>>>> Download Now

    Ежедневник Админа: Postgresql Для 1С 8.3 - Резервное Копирование >>>>> Download Full

    >>>>> Download LINK z2

    ОтветитьУдалить