Использование динамических фильтров совместно с динамическими снимками

ПУБЛИКАЦИИ  

Автор: Александр Гладченко

0. Введение
1. Подготовительные действия
2. Создаём публикацию filtertest для репликации слиянием таблицы _test
3. Во-первых, нужно указать, что мы будем использовать динамические фильтры
4. В этом примере мы используем только горизонтальный фильтр
5. Наш фильтр будет динамическим
6. Выбираем фильтруемую таблицу и указываем условие в предложении WHERE
7. Указываем функцию для выверки реплицируемых данных
8. Указываем, необходимо ли минимизировать трафик реплицируемых данных
9. После создания публикации, изменить фильтр можно в её свойствах
10. В свойствах публикации можно изменить и другие параметры фильтрации
11. Признак динамического фильтра и определяющих его функций хранится в системной таблице sysmergepublications
12. Условие фильтрации хранится в системной таблице sysmergearticles
13. Добавляем динамический снапшот
14. Указываем значение для фильтра динамического снапшота
15. Указываем расположение динамического снапшота для нашего условия фильтрации
16. Создаём подписку и указываем для неё место расположения динамического снапшота
17. Редактируем свойства подписки
18. Изменяем логин для подключения подписчика к издателю
19. Расположение динамического снапшота подписки можно изменить
20. Изменяем владельца задания, запускающего агента репликации на подписчике
21. Запускаем сеанс создания динамического снимка, а потом сеанс репликации
22. Внесём записи под пользователем u1 на подписчике
23. Особенности формирования динамического снимка

Введение

Динамические фильтры в репликации позволяют использовать возвращаемые системными функциями SUSER_SNAME() и HOST_NAME() значения для выделения своих разделов данных каждому подписчику. Кроме этих функций, динамическую фильтрацию можно построить на определяемых пользователем функциях - UDF.
Динамическая фильтрация данных позволяет существенно снизить трафик сеансов репликации и предоставить подписчику доступ только к своей информации. Каждый фильтр является свойством входящей в публикацию статьи и может быть применён как для одной статьи публикации, так и для любого числа входящих в публикацию статей.
Поскольку динамический фильтр подразумевает наличие разных наборов данных, которые передаются подписчикам, создаваемый для первоначальной синхронизации моментальный снимок отличается от стандартного снимка. В таком снимке отсутствует файл BCP, который содержит данные. Данные передаются после применения схемы и указанного в свойствах статей публикации набора реплицируемых объектов. Стандартный моментальный снимок в компрессованном виде доставляется подписчику, распаковывается, после чего данные из BCP файла с помощью BULK INSERT загружаются в таблицы подписчика. Создаваемый же для содержащей динамический фильтр публикации снимок будет очень маленьким, т.к. не содержит данных, но применяться будет существенно дольше стандартного снимка. Данные будут загружаться таким же образом, как реплицируется вставка, и вставляться будут все значения из таблиц издателя, на основании которых построена публикация. Для больших и даже для средних баз данных такая первоначальная синхронизация или реинициализация подписчика может занять очень много времени.
Именно для решения проблемы очень долгой инициализации используются динамические моментальные снимки, которые можно создавать для использующих динамические фильтры публикаций.
В этой статье мы рассмотрим пример, на основании которого будет не сложно разобраться во всех нюансах использования динамических фильтров совместно с динамическими снимками. Ниже представлена последовательность шагов, которая позволит нам создать необходимые объекты, заполнить таблицы тестовыми данными, развернуть репликацию и посмотреть, как работает динамическая фильтрация и что представляет из себя динамический моментальный снимок.

1. Подготовительные действия

Для демонстрации совместного использования динамических фильтров и снимков создадим две базы данных: filtertest и subscriber1, которые содержат таблицу _test, а также двух пользователей, для которых мы будем фильтровать данные в публикации. Кроме того, таблицу на издателе заполним тестовыми данными.


/***** Начало скрипта *****/
-- Для правильного исполнения, запустите с правами sysadmin
use master
GO
CREATE DATABASE [filtertest]-- База для издателя
GO
CREATE DATABASE [subscriber1]-- База для первого подписчика
GO
-- Создание пользователей и таблиц
USE subscriber1
GO
EXEC sp_addlogin @loginame = 'u1' 
GO
EXEC sp_adduser 'u1'
GO
EXEC sp_change_users_login 'Update_One', 'u1', 'u1'
GO
EXEC sp_addsrvrolemember 'u1', 'sysadmin'
GO
USE filtertest
GO
EXEC sp_addlogin @loginame = 'u0' 
GO
EXEC sp_adduser 'u0'
GO
EXEC sp_adduser 'u1'
GO
EXEC sp_change_users_login 'Update_One', 'u0', 'u0'
GO
EXEC sp_change_users_login 'Update_One', 'u1', 'u1'
GO
EXEC sp_addsrvrolemember 'u0', 'sysadmin'
GO
CREATE TABLE _test 
	(row_id int IDENTITY (1, 1) NOT FOR REPLICATION,
	name_bd char (21),
	name_host char (21),
	name_user char (21) 
	)
GO
ALTER TABLE _test ADD 
	CONSTRAINT DF_name_host DEFAULT (host_name()) FOR name_host,
	CONSTRAINT DF_name_user DEFAULT (suser_sname()) FOR name_user
GO
CREATE  UNIQUE  INDEX IX_test ON _test(row_id, name_host, name_user)
GO
SETUSER 'u0'
declare @count_insert int
SET @count_insert = 0
WHILE @count_insert < 5
BEGIN
	 SET @count_insert = (@count_insert + 1)
	 PRINT 'Вставляется ' + CONVERT(varchar(4), @count_insert) + '-я строка'
	 insert _test (name_bd) VALUES (db_name())
END
GO
SETUSER
SETUSER 'u1'
declare @count_insert int
SET @count_insert = 0
WHILE @count_insert < 5
BEGIN
	 SET @count_insert = (@count_insert + 1)
	 PRINT 'Вставляется ' + CONVERT(varchar(4), @count_insert) + '-я строка'
	 insert _test (name_bd) VALUES (db_name())
END
GO
SETUSER
-------
USE subscriber1
GO
CREATE TABLE _test 
	(row_id int IDENTITY (1, 1) NOT FOR REPLICATION,
	name_bd char (21),
	name_host char (21),
	name_user char (21) 
	)
GO
ALTER TABLE _test ADD 
	CONSTRAINT DF_name_host DEFAULT (host_name()) FOR name_host,
	CONSTRAINT DF_name_user DEFAULT (suser_sname()) FOR name_user
GO
CREATE  UNIQUE  INDEX IX_test ON _test(row_id, name_host, name_user)
GO
/***** Конец скрипта *****/

2. Создаём публикацию filtertest для репликации слиянием таблицы _test

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

3. Во-первых, нужно указать, что мы будем использовать динамические фильтры.

4. В этом примере мы используем только горизонтальный фильтр.

5. Наш фильтр будет динамическим.

6. Выбираем фильтруемую таблицу и указываем условие в предложении WHERE.

7. Указываем функцию для выверки реплицируемых данных.

8. Указываем, необходимо ли минимизировать трафик реплицируемых данных.

9. После создания публикации, изменить фильтр можно в её свойствах.

10. В свойствах публикации можно изменить и другие параметры фильтрации.

11. Признак динамического фильтра и определяющих его функций хранится в системной таблице sysmergepublications.

Тот факт, что информация о наличии в публикации динамических фильтров хранится в системных таблицах, позволяет не сложным образом преобразовывать существующие публикации в публикации с использованием динамических фильтров.

12. Условие фильтрации хранится в системной таблице sysmergearticles.

13. Добавляем динамический снапшот.

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

14. Указываем значение для фильтра динамического снапшота.

Для каждого подписчика должен быть создан свой динамический моментальный снимок. Для этого, каждому подписчику необходимо оказать то значение используемых в фильтре системных функций, на основании которого будут фильтроваться данные. Поскольку в нашем примере данные фильтруются функцией SUSER_SNAME(), которая возвращает имя оперирующего реплицируемыми данными пользователя на подписчике, нам необходимо указать в качестве значения для фильтра динамического снапшота имя пользователя u1. От имени этого пользователя будут осуществляться операции с данными и запускаться агент репликации слиянием. Целью нашей динамической фильтрации является выделение подписчику такого горизонтального раздела данных, который содержал бы записи таблицы _test со значением поля name_user равным u1.
Напомню, что для этого поля нами было введено значение по умолчанию, которое мы определили как:

CONSTRAINT DF_name_user DEFAULT (suser_sname()) FOR name_user

Поэтому, в визарде создания динамического снимка для значения функции SUSER_SNAME() мы указываем имя пользователя, который будет вставлять данные на подписчике.

15. Указываем расположение динамического снапшота для нашего условия фильтрации.

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

16. Создаём подписку и указываем для неё место расположения динамического снапшота.

Именно эту папку, которую мы определили в предыдущем шаге в качестве динамического снимка подписчиков, у которых значение поля name_user равно u1, мы укажем и в визарде создания подписки, а также пометим эту папку, как содержащую динамический моментальный снимок.
Обращаю Ваше внимание на то, что все предшествующие окна мастера создания подписки были пропущены, т.к. не представляют интереса в рамках этой статьи и используют предлагаемые визардом по умолчанию значения.

17. Редактируем свойства подписки.

После создания публикации или подписки, у Вас есть возможность внести изменения в их свойства.

18. Изменяем логин для подключения подписчика к издателю.

В нашем примере мы изменим имя и пароль пользователя, от имени которого подписчик будет подключаться к издателю и дистрибутору. Это необходимо сделать, т.к. мастер по умолчанию использует для такого подключения логин, под которым выполнялись операции по созданию подписки.

19. Расположение динамического снапшота подписки можно изменить.

Если Вы забыли указать папку расположения динамического моментального снимка или необходимо изменить её расположение, всё это можно сделать в соответствующей закладке окна свойств подписки.

20. Изменяем владельца задания, запускающего агента репликации на подписчике.

Для каждой подписки мастером автоматически создаётся своё задание по расписанию, основная цель которого - запуск с необходимыми параметрами соответствующего агента репликации.
В нашем примере нам потребуется, также как и в свойствах подписки, изменить владельца задания, которым визард сделал того пользователя, который создавал подписку.

21. Запускаем сеанс создания динамического снимка, а потом сеанс репликации.

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

22. Внесём записи под пользователем u1 на подписчике:


USE subscriber1
GO
SETUSER 'u1'
declare @count_insert int
SET @count_insert = 0
WHILE @count_insert < 5
BEGIN
	 SET @count_insert = (@count_insert + 1)
	 PRINT 'Вставляется ' + CONVERT(varchar(4), @count_insert) + '-я строка'
	 insert _test (name_bd) VALUES (db_name())
END
GO
SETUSER

После исполнения представленного выше скрипта и повторного, ручного запуска задания агента репликации слиянием, мы увидим, что данные на подписчике содержат только те строки, которые мы отфильтровали, а на издателе присутствует весь объём введённых нами данных.

23. Особенности формирования динамического снимка.

Если открыть находящийся в указанной нами для моментального снимка папке BCP файл, мы увидим, что в нём также присутствуют только отфильтрованные данные.

Файлы динамических снимков могут быть также сжаты, как и файлы стандартного снимка. Чтобы сжать стандартный снимок, а заодно и динамические снимки, откройте свойства публикации, и на закладке Snapshot Location, укажите в текстовом поле Generate snapshots in the following location местоположение дополнительного снимка, и затем включите чек-бокс Compress snapshot files in this location.

[В начало]


Перевод: Александра Гладченко  2003г.

ПУБЛИКАЦИИ

Скачать электронную карту Ангарска бесплатно
Сайт управляется системой uCoz