В этой статье разберем оптимизацию работы с
моментальным снимком отдельной базы 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
Для этого в общем случае алгоритм следующий:
- копирование в другую базу в пределах кластера
- копирование в другую базу на другом сервере с более высокой версией 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;
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: [внешний архиватор] не удалось прочитать входной файл: конец файла
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 часа!
Было: 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;
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/
Ежедневник Админа: 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