Использование помеченных транзакций (модель полного восстановления)

 Этот раздел относится только к базам данных SQL Server, использующим полные модели восстановления или модели восстановления с неполным протоколированием.

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

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

ПримечаниеПримечание

Резервные копии журнала в различных базах данных могут быть созданы независимо друга от друга и могут не быть совместными.

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

  • Один или несколько журналов транзакций разрушены. Необходимо восстановить набор баз данных до согласованного состояния во время резервного копирования последнего журнала.

  • Необходимо восстановить весь набор баз данных до взаимно стабильного состояния на более раннем этапе.

Важное примечаниеВажно!

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

Дополнительные сведения о создании помеченных транзакций см. в теме «Создание помеченных транзакций» далее в разделе.

Типичные сценарии для использования помеченных транзакций

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

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

  2. Пометка блока транзакций во всех базах данных.

  3. Резервное копирование журнала транзакции во всех базах данных.

  4. Восстановление резервных копий базы данных с ключевым словом WITH NORECOVERY.

  5. Восстановление журналов с ключевым словом WITH STOPATMARK.

Сведения об использовании помеченных транзакций

Перед вставкой именованных меток в журнал транзакций следует учесть следующее:

  • метки транзакций занимают место в журнале, поэтому их следует использовать только для транзакций, играющих важную роль в стратегии восстановления базы данных;

  • после фиксации помеченной транзакции в таблицу logmarkhistory базы данных msdb вставляется строка;

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

Создайте помеченные транзакции

Чтобы создать помеченные транзакции, используйте инструкцию BEGIN TRANSACTION и предложение WITH MARK [описание]. Необязательное описание представляет собой текстовое описание метки. Имя метки для транзакции указывается обязательно. Имя метки может быть использовано повторно. В журнале транзакций записывается имя метки, описание, база данных, пользователь, данные datetime и порядковый номер транзакции в журнале (LSN). Данные datetime используются наряду с именем метки, чтобы уникально идентифицировать метку.

Создание помеченных транзакций в наборе баз данных

  1. Дайте имя транзакции в инструкции BEGIN TRAN и используйте предложение WITH MARK.

    Можно вложить инструкцию BEGIN TRAN new_mark_name WITH MARK в существующую транзакцию. Значение параметра new_mark_name является помеченным именем для транзакции, даже если транзакция владеет им.

    ПримечаниеПримечание

    Если вызывается вторая вложенная инструкция BEGIN TRAN...WITH MARK, предыдущая инструкция пропускается, но в результате появляется предупреждающее сообщение.

  2. Выполните обновление всех баз данных в наборе.

    Метка указанной транзакции добавлена в журналы транзакций только на экземпляре сервера, где выполнена инструкция BEGIN TRAN...WITH MARK. Метка транзакции размещается только в журнале транзакции каждой базы данных, обновленной помеченной транзакцией на данном экземпляре сервера. Если базы данных постоянно находятся на различных экземплярах сервера, идентичные метки должны быть созданы на каждом из них.

Примеры

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

USE AdventureWorks
GO
BEGIN TRANSACTION ListPriceUpdate
   WITH MARK 'UPDATE Product list prices';
GO

UPDATE Production.Product
   SET ListPrice = ListPrice * 1.10
   WHERE ProductNumber LIKE 'BK-%';
GO

COMMIT TRANSACTION ListPriceUpdate;
GO

-- Time passes. Regular database 
-- and log backups are taken.
-- An error occurs in the database.
USE master
GO

RESTORE DATABASE AdventureWorks
FROM AdventureWorksBackups
WITH FILE = 3, NORECOVERY;
GO

RESTORE LOG AdventureWorks
   FROM AdventureWorksBackups 
   WITH FILE = 4,
   RECOVERY, 
   STOPATMARK = 'ListPriceUpdate';

Форсирование отметки к распространению на другие сервера

В процессе распространения транзакции имя отметки транзакции не передается автоматически на другой сервер. Чтобы заставить отметку распространиться на другие сервера, хранимая процедура должна содержать инструкцию BEGIN TRAN имя WITH MARK. Эта хранимая процедура затем должна быть выполнена на удаленном сервере в области транзакции на исходном сервере.

Например, рассмотрим секционированную базу данных, существующую в нескольких экземплярах SQL Server. В каждом экземпляре находится база данных под названием coyote. Во-первых, необходимо создать хранимую процедуру, например sp_SetMark, в каждой базе данных.

CREATE PROCEDURE sp_SetMark
@name nvarchar (128)
AS
BEGIN TRANSACTION @name WITH MARK
UPDATE coyote.dbo.Marks SET one = 1
COMMIT TRANSACTION;
GO

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

CREATE PROCEDURE sp_MarkAll
@name nvarchar (128)
AS
BEGIN TRANSACTION
EXEC instance0.coyote.dbo.sp_SetMark @name
EXEC instance1.coyote.dbo.sp_SetMark @name
EXEC instance2.coyote.dbo.sp_SetMark @name
COMMIT TRANSACTION;
GO

Двухфазная фиксация

Фиксация распределенной транзакции делится на две фазы: подготовка и фиксация. При фиксации помеченной транзакции запись журнала фиксации для каждой базы данных в помеченной транзакции размещается в журнале в том месте, где нет проблемных транзакций. На данном этапе гарантируется, что не появятся транзакции, зафиксированные в одном журнале, но не зафиксированные в другом.

Следующие шаги выполняются во время фиксации помеченной транзакции.

  1. Фаза подготовки помеченной транзакции останавливает все новые подготовки и фиксации.

  2. Может продолжаться только фиксация уже подготовленных транзакций.

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

  4. Помеченная транзакция готова и зафиксирована.

  5. Остановка новых подготовок и фиксаций удалена.

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

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

Восстановление до помеченной транзакции

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