Thursday, June 14, 2007

Репликация MS SQL Server 2005 для баз 1С:Предприятия v7.7

Репликация MS SQL Server 2005 для баз 1С:Предприятия v7.7

Материал для статьи предоставлен Midnight Ghost


В данной статье речь пойдёт о том, как настроить репликацию в MS SQL Server 2005 для больших по размеру баз данных 1С:Предприятия v7.7. Подобная репликация преследует цель создать копию базы данных 1С:Предприятия v7.7 на другом сервере, предназначенную только для чтения. В данной копии можно будет формировать отчёты и просматривать данные, при этом используя "основную" базу в основном только для ввода документов, что в некоторых случаях позволит неплохо решить проблемы производительности системы. О том, как в принципе заставить работать 1С:Предприятие v7.7 вместе с MS SQL Server 2005, вы можете прочитать здесь.

Итак, мы имеем массивную распределённую базу данных 1С:Предприятия v7.7 на MS SQL Server 2005 и желаем создать копию центральной базы "только для чтения" на другом сервере.

Примечание: на момент написания статьи имеется опыт успешной промышленной (не тестовой) эксплуатации 1С:Предприятия v7.7 с MS SQL 2005. При этом размер mdf-файла рабочей базы данных составляет порядка 20 Гб, имеется копия базы данных "только для чтения", настроенная именно так, как описано в этой статье.

Создадим новую периферийную базу в Конфигураторе с признаком "только получатель". Данная периферийная база будет довольно формальной (мы не будем даже инициализировать её) и послужит "опорой" для проверок некоторых условий в конфигурации. Необходимо средствами конфигурирования и встроенного языка 1С:Предприятия создать в конфигурации механизм, который обеспечивал бы запреты на ввод информации в копии базы, а с другой стороны - обеспечивал бы запреты на запуск формирования отчетов в "основной" базе. При этом желательно сделать такие запреты опциональными (отключаемыми) с тем, чтобы можно было в любой момент разрешить формирование отчётов в "основной" базе в случае недоступности по каким-либо причинам копии и т.п. Следовательно, в коде форм журналов документов, отчётов и т.д. перед запуском определённых действий прежде всего нужно определить, в какой базе мы "находимся" - в копии или в "основной" базе. Здесь и пригодится признак "только получатель": если мы в копии, метод "ТекущаяИБТолькоПолучатель()" вернёт единицу. Конечно, данный метод определения "копия - не копия" является не единственно возможным. Кроме того, если вы желаете реплицировать нераспределённую базу, вам придётся самостоятельно внести некоторые коррективы в дальнейшее изложение, и при этом ваша задача несколько упростится.

Примечания: запуск SQL Server Management Studio, которая потребуется для дальнейшей работы, осуществляется через меню "Пуск" – "Программы" – "Microsoft SQL Server 2005" - "SQL Server Management Studio". В SQL Server Management Studio нам потребуются окна "Object Explorer" и "Registered Servers". Если этих окон нет на экране, их можно отобразить через меню "View".

Обычно настройка репликации сводится к определению публикатора, дистрибьютора и подписчика с автоматической инициализацией подписки, в результате чего и получается копия базы данных. К сожалению, практика показала, что данная процедура не всегда гладко проходит с большими базами данных 1С:Предприятия v7.7. На этапе инициализации подписки вы можете получить сообщение об ошибке с прекращением всего процесса. Поэтому в данном описании мы пойдём более сложным путём, искусственно "инициализируя" базу подписчика путём копирования файлов. Примечание: не исключено, что ваша база данных может быть удачно реплицирована и "стандартным" способом, если немного поэксперементировать с параметрами настройки репликации.

Примем следующие обозначения:
MyMainServer - имя SQL-сервера, на котором расположена наша "основная" база данных.
MyMainDatabase - имя нашей "основной" базы данных.
MySecondServer - имя SQL-сервера, на котором (будет) расположена наша база данных "только для чтения", являющаяся копией "основной" базы данных.
MySecondDatabase - имя нашей базы данных "только для чтения", являющейся копией "основной" базы данных.

Настройка репликации по шагам:
Настройка репликации на SQL-сервере. В окне "Object Explorer" в ветке "Replication" на сервере-источнике (где находится "основная" база данных) необходимо вызвать команду контекстного меню "Configure Distribution...". Если команда контекстного меню "Configure Distribution..." изначально отсутствует, а вместо неё присутствует команда "Disable Publishing and Distribution...", репликация на этом сервере уже настроена, и весь этот пункт можно пропустить. Откроется окно мастера. Далее по шагам:
Шаг "Distributor". Выбрать имя текущего сервера (по умолчанию). Таким образом, сервер назначается дистрибьютором самому себе.
Шаг "Snapshot Folder". Выбрать папку, в которой будут созданы файлы подписки (папка может быть сетевой).
Шаг "Distribution Database". Создание системной базы данных для репликации. Имя базы данных можно оставить по умолчанию – "distribution". Папки для хранения файлов .mdf (файл базы данных) и .ldf (файл лога базы данных) могут совпадать (т.е. может быть указана одна и та же папка). Примечание: файлов distribution.MDF и distribution.LDF в этой папке на данный момент быть не должно (если они есть, их необходимо предварительно удалить, иначе на последнем шаге работы мастера произойдёт ошибка).
Шаг "Publishers". Добавление публикаторов. Здесь ничего добавлять не надо, т.к. текущий сервер уже добавлен по умолчанию.
Шаг "Wizard Actions". Должен стоять флажок "Configure distribution" (по умолчанию).
В результате будет создана системная база данных "distribution", а ветке "Replication" появятся пункты контекстного меню "Publisher Properties...", "Distributor Properties..." и "Disable Publishing and Distribution...", а пункта "Configure Distribution" уже не будет. Примечание: если настройка репликации не получилась или сделана неверно, для повторной настройки следует вначале отменить настройку репликации через пункт контекстного меню "Disable Publishing and Distribution...", на втором шаге открывшегося мастера выбрав "Yes, disable publishing on this server".
Сжатие "основной" базы данных перед копированием. Чтобы в момент сжатия были удалены все записи лог-файла .ldf, которые ещё не попали в резервную копию (а по умолчанию этого не произойдёт), необходимо выполнить запрос, который "скажет" системе, что все записи лог-файла уже якобы попали в резервную копию. Для этого необходимо выполнить следующий запрос:
backup log MyMainDatabase with no_log
Здесь "MyMainDatabase" - имя нашей "основной" базы данных. Далее необходимо собственно сжать нашу "основную" базу данных: в окне "Object Explorer" в ветке "Databases" - "MyMainDatabase" вызвать команду контекстного меню "Tasks" - "Shrink" - "Database". Установить флажок "Reorganize files before releasing...", и нажать "ОК". Сжатие может занять некоторое время (десятки минут).
Устранение проблемы с полями типа IDENTITY. Если в некоторых таблицах автоинкрементные поля с признаком IDENTITY не содержат признака "NOT FOR REPLICATION", при вставке нового элемента в таблицу в базе данных подписчика (например, при добавлении элемента справочника) репликация остановится. 1С:Предприятие автоматически никогда не ставит подобный признак. Чтобы у полей IDENTITY появилось свойство "NOT FOR REPLICATION", необходимо искусственно создать и удалить публикацию.
В окне "Object Explorer" в ветке "Replication" - "Local Publications" текущего сервера необходимо вызвать команду контекстного меню "New Publication...". Откроется окно мастера. Далее по шагам:
Шаг "Publication Database". Выбрать нашу "основную" базу данных.
Шаг "Publication Type". Выбрать тип публикации "Transactional Publication" (второй сверху).
Шаг "Articles". Выбор, что публиковать. Поставьте флажок "Tables", чтобы выбрались все таблицы. Затем раскройте ветку "Tables" и уберите флажки с двух таблиц:
_1SDBSET (список распределённых баз). Эта таблица убирается для того, чтобы копия стала периферийной базой.
_1SDNLOCK (номера новых несохранённых справочников и документов).
Кроме того, автоматически будут не отмечены флажками те таблицы, которые не имеют первичного ключа (их реплицировать нельзя в принципе).
Шаг "Filter Table Rows". Фильтры задавать не надо.
Шаг "Snapshot Agent". Все флажки должны быть сняты, т.к. инициализация этой публикации нам не потребуется.
Шаг "Agent Security". Указываем параметры безопасности (первая кнопка "Security Settings"), под какими учётными записями будет идти репликация. Выбрать "Run under the SQL Server Agent..." и "By impersonating the process account".
"Snapshot Agent" и "Log Reader Agent" настраиваются одинаково, т.е. флажок "Use the security settings from the Snapshot Agent" должен стоять.
Шаг "Wizard Actions". Флажок "Create the publication" должен стоять.
Шаг "Complete the Wizard". Задайте имя публикации, совпадающее с именем нашей "основной" базы данных.
Удалите только что созданную публикацию в дереве Object Explorer командой контекстного меню "Delete".
Отключение баз данных. Необходимо перевести базы в состояние off-line. В окне "Object Explorer" в ветке "MyMainServer" - "Databases" - "MyMainDatabase" необходимо вызвать команду контекстного меню "Tasks" - "Take offline".
Если вы настраиваете репликацию не в первый раз, и копия базы данных уже существует, в окне "Object Explorer" в ветке "MySecondServer" - "Databases" - "MySecondDatabase" также необходимо вызвать команду контекстного меню "Tasks" - "Take offline".
Примечание: если процесс перевода базы в состояние off-line идёт слишком долго (несколько минут), возможно, кто-то "сидит" в базе данных. В этом случае надо найти и удалить нужное подключение через Activity Monitor в ветке Management на нужном сервере, иначе процесс перевода базы в состояние off-line может никогда не завершиться.
Копирование файлов. Необходимо скопировать файлы базы данных с одного сервера на другой. Если файлы большие, копирование может занять продолжительное время.
Удалите MySecondDatabase.mdf и MySecondDatabase_log.ldf в папке назначения, если они существуют.
Скопируйте MyMainDatabase.mdf и MyMainDatabase_log.ldf (в процессе копирования можно выполнять п.6 настоящей инструкции).
Переименуйте скопированные файлы в MySecondDatabase.mdf и MySecondDatabase_log.ldf.
Получение необходимых хранимых процедур для подписчика. Для базы данных подписчика необходимо наличие определённых хранимых процедур, которые были бы созданы автоматически, если бы репликация настраивалась стандартным способом, а не "в обход" (копированием файлов баз данных). Поскольку в данном случае репликация настраивается "в обход", необходимые хранимые процедуры придётся получить искусственно, создав пустые базы публикатора и подписчика с той же конфигурацией (md). Порядок действий:
Необходимо создать две базы данных на sql-сервере MyMainServer: "Pub" и "Sub".
В окне "Object Explorer" в ветке "MyMainServer" - "Databases" необходимо вызвать команду контекстного меню "New Database".
В разделе "General" задаётся "Database name" (задайте "Pub").
В разделе "Options" следует задать свойство "Compatibility Level" как "SQL server 2000 (80)".
Ту же операцию (создание базы данных на sql-сервере) проделайте и для базы "Sub".
Разверните файловую часть базы "Pub":
Создайте произвольный каталог на жестком диске, например C:\Temp\Pub\. Зарегистрируйте его как базу в диалоге "Запуск 1С:Предприятия" и откройте в режиме Конфигуратора (тип базы при запуске укажите как SQL-Server). Создайте пользователя с административными правами.
Задайте параметры соединения с сервером (меню "Администрирование" - "Параметры базы данных SQL..."), сервер - MyMainServer, база данных – Pub, пользователь – sa.
Загрузите конфигурацию (меню "Конфигурация" - "Загрузить измененную конфигурацию..."), выбрав MD-файл вашей конфигурации "основной" базы данных. Сохраните конфигурацию (меню "Файл" - "Сохранить").
Создайте распределённую базу. Меню "Администрирование" - "Распределенная ИБ" - "Управление", кнопка "Центральная ИБ". Задайте произвольный код и сохраните.
Удалите файловую часть базы "Pub" (папку C:\Temp\Pub\).
Настройте публикацию Pub -> Sub, почти как в п.3 "Устранение проблемы с полями типа IDENTITY", но для базы Pub, и в конце не удаляйте созданную публикацию. На шаге "Snapshot Agent" установите флажок "Create a snapshot immediately...".
В окне "Object Explorer" в ветке "MyMainServer" - "Replication" - "Local Publications" - "Pub" вызовите команду контекстного меню "View Snapshot Agent Status" и дождитесь окончания публикации (100%).
Создайте подписку. В окне "Object Explorer" в ветке "MyMainServer" - "Replication" - "Local Subscriptions" вызовите команду контекстного меню "New Subscriptions...". Откроется окно мастера. Далее по шагам:
Шаг "Publication". Выберите сервер MyMainServer и базу-публикатора "Pub".
Шаг "Distribution Agent Location". Выберите вид публикации "pull". Примечание: в варианте "push" (заталкивать) работает сервер дистрибьютера, в варианте "pull" (вытягивать) работает сервер подписчика.
Шаг "Subscribers". Выберите сервер MyMainServer (поставьте галку) и базу-подписчика "Sub".
Шаг "Distribution Agent Security". Задайте параметры безопасности: выберите "Run under the SQL Server Agent...", в группе "Connect to the Distributor" выберите "Using the following SQL Server login", задайте пользователя sa и его пароль.
Шаг "Synchronization Shedule". Оставьте по умолчанию "Run continuously", т.е. выполнять задачу по синхронизации постоянно.
Шаг "Initialize Subscriptions". Инициализацию подписчиков поставьте "Immediately" (с галкой), т.е. немедленно.
Шаг "Wizard Actions". Флажок "Create the subscription(s)" должен стоять.
Количество созданных в результате в базе Sub хранимых процедур должно быть ровно втрое больше, чем таблиц (процедуры для INSERT, UPDATE и DELETE). Дождитесь, пока количество хранимых процедур достигнет нужной величины (это может произойти не мгновенно). Необходимо заскриптовать все хранимые процедуры базы Sub. В окне "Object Explorer" в ветке "MyMainServer" - "Databases" - "Sub" необходимо вызвать команду контекстного меню "Tasks" - "Generate Scripts", откроется окно мастера. Далее по шагам:
Шаг "Select Database". Выберите Sub.
Шаг "Choose Script Options". Всё оставьте по умолчанию.
Шаг "Choose Object Types". Выберите Stored Procedures.
Шаг "Choose Stored Procedures". Выберите все кнопкой "Select All".
Шаг "Output Option". Выберите "Script to file". Выберите файл для сохранения.
В окне "Object Explorer" в ветке "MyMainServer" - "Replication" - "Local Subscriptions" удалите подписку базы Sub. В ветке "Replication" - "Local Publications" удалите публикацию базы Pub. В ветке "Databases" удалите и сами базы Pub и Sub на SQL-сервере MyMainServer.
Подключение баз данных. Необходимо перевести базы в состояние on-line.
В окне "Object Explorer" в ветке "MyMainServer" - "Databases" - "MyMainDatabase" необходимо вызвать команду контекстного меню "Tasks" - "Bring online". В окне "Object Explorer" в ветке "MySecondServer" - "Databases" - "MySecondDatabase" также необходимо вызвать команду контекстного меню "Tasks" - "Bring online".
Необходимо запустить два скрипта на базе MySecondDatabase.
Скрипт, который провешивает хранимые процедуры, нужные для репликации. Это тот скрипт, в который мы заскриптовали все хранимые процедуры базы Sub в конце шага 6.
Скрипт, который сделает базу периферийной:
UPDATE
_1SSYSTEM
SET
DBSIGN = 'MSD'

DELETE FROM
_1SDBSET
WHERE
(DBSIGN <> 'MMD')
AND (DBSIGN <> 'MSD')

UPDATE
_1SDBSET
SET
DBSTATUS = 'P'
WHERE
DBSIGN = 'MMD'

UPDATE
_1SDBSET
SET
DBSTATUS = 'M'
WHERE
DBSIGN = 'MSD'
Важное примечание: "MMD" и "MSD" в вышеприведённом скрипте необходимо заменить на трёхбуквенные коды (заданные в Конфигураторе 1С) ваших центральной и периферийной ИБ соответственно.
Следует создать Job на сервере MySecondServer для установки точки актуальности в базе MySecondDatabase. В окне "Object Explorer" - ветка "MySecondServer" - "SQL Server Agent" - "Jobs". Пусть такой Job раз в час устанавливает точку актуальности в базе MySecondDatabase, равной концу дня текущей даты (для успешного формирования отчетов в базе в любой момент). Job может выполнять примерно такой скрипт:
UPDATE
_1SSYSTEM
SET
CURDATE = CONVERT(DATETIME, RIGHT('0000'+LTRIM(STR(DATEPART(yy, GETDATE()))),4)+
RIGHT('00'+LTRIM(STR(DATEPART(mm, GETDATE()))),2)+
RIGHT('00'+LTRIM(STR(DATEPART(dd, GETDATE()))),2)),
CURTIME = 863999999,
EVENTIDTA = 'ZZZZZZZZZ'
Создание публикации для MyMainDatabase. Необходимо создать публикацию на сервере MyMainServer для базы данных MyMainDatabase, как в п.3 "Устранение проблемы с полями типа IDENTITY".
Создание подписки для MySecondDatabase. Необходимо создать подписку на сервере MySecondServer для базы данных MySecondDatabase, почти так же, как в п.6 ("Получение необходимых хранимых процедур для подписчика"), подпункте "Создайте подписку", но со следующими отличиями:
Шаг "Publication". Выберите сервер MyMainServer и базу-публикатора MyMainDatabase.
Шаг "Subscribers". Выберите сервер MySecondServer (поставьте галку) и базу-подписчика MySecondDatabase.
Шаг "Initialize Subscriptions". Уберите галку инициализации подписчиков, т.к. подписчик уже инициализирован.
Исправление владельца MySecondDatabase. Чтобы ликвидировать последствия ручного переноса файлов базы данных, возможно, придётся откорректировать владельца базы данных MySecondDatabase. Для этого выполните на этой базе запрос, подобный следующему:
sp_changedbowner 'ИмяВладельца'
Запустите базы MyMainDatabase и MySecondDatabase в 1С:Предприятии, убедитесь, что они работают.

***


В случае произведения операций с базами MyMainDatabase или MySecondDatabase, требующих монопольного доступа (например, обновление конфигурации без изменения структуры таблиц, открытие периода или восстановление последовательности в MyMainDatabase), необходимо временно остановить репликацию, произвести нужные действия, а затем вновь запустить репликацию.

В окне "Object Explorer" в ветке "MyMainServer" - "Replication" - "Local Publications" - "MyMainDatabase" команда контекстного меню "View Log Reader Agent Status" открывает окно, в котором можно остановить или запустить репликацию кнопками Stop и Start.

В случае переноса баз данных MyMainDatabase и/или MySecondDatabase между серверами, всю настройку репликации придётся повторить, за исключением п.3 ("Устранение проблемы с полями типа IDENTITY") и п.6 ("Получение необходимых хранимых процедур для подписчика").

В случае обновления конфигурации с изменением структуры таблиц всю настройку репликации придётся повторить полностью.

Использование MS SQL Server 2005 с 1С:Предприятием v7.7

Использование MS SQL Server 2005 с 1С:Предприятием v7.7

Материал для статьи предоставлен Midnight Ghost


Данная статья является изложением опыта запуска 1С:Предприятия v7.7 на MS SQL Server 2005. К сожалению, "штатно" 1С:Предприятие v7.7 работу с MS SQL Server 2005 не поддерживает, поэтому понадобятся некоторые ухищрения, которые и будут здесь описаны. Примечание: на данный момент имеется опыт успешной промышленной (не тестовой) эксплуатации 1С:Предприятия v7.7 с MS SQL 2005. При этом размер mdf-файла рабочей базы данных составляет порядка 10 Гб, количество одновременных подключений - порядка 60, конфигурация полностью самописная, активно используется технология 1С++ в части "прямых" запросов к базе данных.

При установке SQL сервера необходимо выставить режим авторизации "MixedMode" (т.е. Windows+SQL), и указать пароль для учетной записи "SA". Параметр "Server Collation" следует установить как "Cyrillic_General_CI_AS".

Если SQL сервер "не виден" с других компьютеров (1С выдаёт сообщение "SQL-сервер не существует, или отсутствует доступ."), следует разрешить удаленные соединения в SQL Server Surface Area Configuration. Меню "Пуск" - "Программы" - "Microsoft SQL Server 2005" - "Configuration Tools" - "SQL Server Surface Area Configuration". Выбрать ссылку "Surface Area Configuration for Services and Connections", в дереве выбрать элемент "Remote Connections".

Если у вас MS SQL Server 2005 Express Edition, в 1С в "Параметрах базы данных SQL" нужно указывать не просто имя сервера, а Имя_Сервера\SQLEXPRESS.

В свойствах базы данных на SQL Server необходимо поставить Compatibility Level "SQL Server 2000(80)". Это можно сделать в Microsoft SQL Server Management Studio Express (меню "Пуск" - "Программы" - "Microsoft SQL Server 2005" - "SQL Server Management Studio Express CTP"). Примечание: база данных может быть создана на Microsoft SQL Server 2000, и перенесена на Microsoft SQL Server 2005 через простой Detach - Attach, можно также через Backup - Restore. Однако простого пути для возврата базы назад (на MS SQL 2000) уже не будет.

Если возникают проблемы с подключением к базе MS SQL 2005, просмотрите настройки протоколов в "SQL Server Configuration Manager". Меню "Пуск" - "Программы" - "Microsoft SQL Server 2005" - "Configuration Tools" - "SQL Server Configuration Manager".

Поскольку 1С v7.7 штатно не поддерживает MS SQL 2005, вы получите сообщение "Требуется MS SQL Server 6.5 + Service Pack 5a или более старшая версия!". Чтобы устранить это, необходимо изменить BkEnd.dll следующим образом (для 21-го релиза 1С):
000D9B7A: 83 EB
000D9B7B: E8 15
000DAFE0: 83 EB
000DAFE1: E8 10

Для 25-го релиза 1С:
000D9C4A: 83 EB
000D9C4B: E8 15
000DB0B0: 83 EB
000DB0B1: E8 10

Для 26-го и 27-го релизов 1С:
000D9CCA: 83 EB
000D9CCB: E8 15
000DB130: 83 EB
000DB131: E8 10

Для возможности коллективной работы в базе данных (одновременной работы нескольких пользователей) необходим режим Multiple для базы данных ("Properties - Options - State - Restrict access" - "Multiple").

Возможно, для коллективной работы в базе данных (одновременной работы нескольких пользователей) могут потребоваться дополнительные изменения в BkEnd.dll, которые можно произвести с помощью Unofficial Service Pack v2.13.24 для 24 релиза 1С (он работает и на 25 релизе), установив флажок "Разрешать другим пользователям входить в базу (SQL)" на вкладке "Защита". Эти изменения можно произвести и вручную (для 25-го релиза 1С):
000DA023: 85 40
000DA024: C0 90

Примечание: после вышеупомянутых изменений 1С будет производить верификацию структуры таблиц и процедур всегда, а не только при входе первого пользователя в базу (при коллективной работе), что немного замедлит запуск 1С.

При работе на базе MS SQL 2005 может возникнуть проблема с автонумерацией документов (при интерактивном создании нового документа номер присваивается некорректно), причём проблема эта воспроизводится не всегда. Чтобы обойти эту проблему, можно поместить в процедуру "ПриЗаписи" всех документов код, подобный следующему:
докДок=СоздатьОбъект("Документ."+Вид());
Если докДок.НайтиПоНомеру(НомерДок,ДатаДок)<>0 Тогда
Если докДок.ТекущийДокумент()<>ТекущийДокумент() Тогда
УстановитьНовыйНомер();
КонецЕсли;
КонецЕсли;

Ссылки для скачивания бесплатных дистрибутивов Microsoft: