Перейти к основному содержимому Перейти к дополнительному содержимому

Работа с группами доступности AlwaysOn в Microsoft SQL Server

Функция «Группы доступности AlwaysOn» в Microsoft SQL Server представляет собой решение для обеспечения высокой доступности и аварийного восстановления, которое обеспечивает альтернативу зеркалирования баз данных на корпоративном уровне.

Предварительные требования

  • Для подключения к отдельным репликам необходимо использовать те же учетные данные, что и для подключения к прослушивателю AlwaysOn Listener.
  • Настройки реплик должны разрешать подключения.

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

    ALTER AVAILABILITY GROUP [{ag_name}]
    MODIFY REPLICA ON '{replica_name}'
    WITH (SECONDARY_ROLE (ALLOW_CONNECTIONS = ALL, READ_ONLY_ROUTING_URL = 
    'TCP://{replica_name}:{Port}'))

Настройка Data Movement Gateway для доступа к прослушивателю AlwaysOn

При работе с группами доступности AlwaysOn необходимо указать IP-адрес или имя сервера и учетные данные для доступа к прослушивателю группы доступности AlwaysOn. в свойствах подключения.

Ограничения

DAG (распределенные группы доступности) не поддерживаются.

Доступ к архивным журналам в группах доступности AlwaysOn

В противоположность активным журналам транзакций, которые синхронизируются с группой доступности AlwaysOn, для каждой реплики имеются отдельные архивные журналы транзакций. Следовательно, когда Data Movement Gateway требуется доступ к архивным журналам транзакций, необходимые журналы по очереди запрашиваются у каждой реплики, пока не будут найдены нужные архивные журналы транзакций. Обратите внимание, что если одна из реплик, к которой Data Movement Gateway пытается обратиться, работает в автономном режиме, Data Movement Gateway ждет, пока эта реплика снова подключится к сети, а затем запрашивает ее архивные журналы транзакций.

Data Movement Gateway требуется доступ к архивным журналам транзакций каждой реплики (пока не будут найдены необходимые журналы) в следующих сценариях:

  • Работа в режиме использования только резервных копий.

    Для получения дополнительной информации об этом режиме см. раздел Локальный сервер Microsoft SQL Server (на основе журнала).

  • Из-за задержки, то есть в случае большого процента событий (изменений), которые Data Movement Gateway не может обработать с использованием только активного журнала.
Примечание к информации

Для чтения архивных журналов из групп доступности AlwaysOn требуется открыть подключение ко всем репликам. Если открывать подключения нежелательно, задайте для параметра Режим обработки изменений на вкладке «Дополнительно» () в свойствах подключения значение Только онлайн-журналы.

Настройка пользователя, не являющегося системным администратором, при работе с группами доступности AlwaysOn

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

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

  1. Настройте Microsoft SQL Server для репликации, как описано в разделе Настройка Microsoft SQL Server для репликации.
  2. Включите MS-REPLICATION в исходной базе данных. Это можно сделать вручную, либо однократно выполнить задачу от имени системного администратора.

    Примечание к информации

    Распространитель MS-REPLICATION следует настроить как локальный или таким образом, чтобы пользователи, не являющиеся системными администраторами, могли получать доступ через ассоциированный связанный сервер.

  1. Для каждой реплики выполните следующие действия (a-l):
    1. Создайте схему [attrep] в основной базе данных.
    2. Создайте функцию с табличным значением [attrep].[split_partition_list] в основной базе данных следующим образом:

      USE [master]
      GO
      
      set ansi_nulls on
      go
      
      set quoted_identifier on
      go
      
      if (object_id('[attrep].[split_partition_list]','TF')) is not null
      drop  function [attrep].[split_partition_list];
      go
      
      create function [attrep].[split_partition_list] 
      ( 
      @plist varchar(8000),	--A delimited list of partitions	
      @dlm nvarchar(1)	--Delimiting character
      ) 
      returns @partitionsTable table --Table holding the BIGINT values of the string fragments
      (
      pid bigint primary key
      ) 
      as 
      begin
      declare @partition_id bigint;
      declare @dlm_pos integer;
      declare @dlm_len integer;
      
      set @dlm_len = len(@dlm);
      
      while (charindex(@dlm,@plist)>0)
      begin 
      set @dlm_pos = charindex(@dlm,@plist);
      set @partition_id = cast( ltrim(rtrim(substring(@plist,1,@dlm_pos-1))) as bigint);
      insert into @partitionsTable (pid) values (@partition_id)
      set @plist = substring(@plist,@dlm_pos+@dlm_len,len(@plist));
      end 
      set @partition_id = cast (ltrim(rtrim(@plist)) as bigint);
      insert into @partitionsTable (pid) values (  @partition_id  );
      return
      end
      GO
      
    3. Создайте процедуру [attrep].[rtm_dump_dblog] в основной базе данных следующим образом:

      USE [master]
      GO
      
      use [MASTER] 
      go 
      
      if (object_id('[attrep].[rtm_dump_dblog]','P')) is not null
      drop procedure [attrep].[rtm_dump_dblog]; 
      go
      
      set ansi_nulls on
      go 
      
      set quoted_identifier on 
      go
      							
      create procedure [attrep].[rtm_dump_dblog]
      (
      @start_lsn        varchar(32),
      @seqno            integer,
      @filename         varchar(260),
      @partition_list        varchar(8000), -- A comma delimited list: P1,P2,... Pn
      @programmed_filtering integer,
      @minPartition     bigint,
      @maxPartition     bigint
      ) 
      as begin
      
              declare @start_lsn_cmp varchar(32); -- Stands against the GT comparator
      
              SET NOCOUNT ON  -- Disable "rows affected display"
      
              set @start_lsn_cmp = @start_lsn;
              if (@start_lsn_cmp) is null
                      set @start_lsn_cmp = '00000000:00000000:0000';
      
              if (@partition_list is null)
              begin
                      RAISERROR ('Null partition list waspassed',16,1);
                      return
                      --set @partition_list = '0,';    -- A dummy which is never matched
              end
      
              if (@start_lsn) is not null
                      set @start_lsn = '0x'+@start_lsn;
      
      if (@programmed_filtering=0)
              SELECT
                      [Current LSN],
                      [operation],
                      [Context],
                      [Transaction ID],
                      [Transaction Name],
                      [Begin Time],
                      [End Time],
                      [Flag Bits],
                      [PartitionID],
                      [Page ID],
                      [Slot ID],
                      [RowLog Contents 0],
                      [Log Record],
                      [RowLog Contents 1] -- After Image
              FROM
                      fn_dump_dblog (
                              @start_lsn, NULL, N'DISK', @seqno, @filename,
                              default, default, default, default, default, default, default,
                              default, default, default, default, default, default, default,
                              default, default, default, default, default, default, default,
                              default, default, default, default, default, default, default,
                              default, default, default, default, default, default, default,
                              default, default, default, default, default, default, default,
                              default, default, default, default, default, default, default,
                              default, default, default, default, default, default, default,
                              default, default, default, default, default, default, default)
              where [Current LSN] collate SQL_Latin1_General_CP1_CI_AS > @start_lsn_cmp collate SQL_Latin1_General_CP1_CI_AS -- This aims for implementing FN_DBLOG based on GT comparator.
              and
              (
                (  [operation] in ('LOP_BEGIN_XACT','LOP_COMMIT_XACT','LOP_ABORT_XACT') )
                or
                (  [operation] in ('LOP_INSERT_ROWS','LOP_DELETE_ROWS','LOP_MODIFY_ROW')
                      and
                      ( ( [context]   in ('LCX_HEAP','LCX_CLUSTERED','LCX_MARK_AS_GHOST') ) or ([context] = 'LCX_TEXT_MIX') )
                      and       [PartitionID] in ( select * from master.attrep.split_partition_list (@partition_list,','))
                )
                or
                ([operation] = 'LOP_HOBT_DDL')
              )
      else
              SELECT
                      [Current LSN],
                      [operation],
                      [Context],
                      [Transaction ID],
                      [Transaction Name],
                      [Begin Time],
                      [End Time],
                      [Flag Bits],
                      [PartitionID],
                      [Page ID],
                      [Slot ID],
                      [RowLog Contents 0],
                      [Log Record],
                      [RowLog Contents 1] -- After Image
              FROM
                      fn_dump_dblog (
                              @start_lsn, NULL, N'DISK', @seqno, @filename,
                              default, default, default, default, default, default, default,
                              default, default, default, default, default, default, default,
                              default, default, default, default, default, default, default,
                              default, default, default, default, default, default, default,
                              default, default, default, default, default, default, default,
                              default, default, default, default, default, default, default,
                              default, default, default, default, default, default, default,
                              default, default, default, default, default, default, default,
                              default, default, default, default, default, default, default)
              where [Current LSN] collate SQL_Latin1_General_CP1_CI_AS > @start_lsn_cmp collate SQL_Latin1_General_CP1_CI_AS -- This aims for implementing FN_DBLOG based on GT comparator.
              and
              (
                (  [operation] in ('LOP_BEGIN_XACT','LOP_COMMIT_XACT','LOP_ABORT_XACT') )
                or
                (  [operation] in ('LOP_INSERT_ROWS','LOP_DELETE_ROWS','LOP_MODIFY_ROW')
                      and
                      ( ( [context]   in ('LCX_HEAP','LCX_CLUSTERED','LCX_MARK_AS_GHOST') ) or ([context] = 'LCX_TEXT_MIX') )
                      and           ([PartitionID] is not null) and ([PartitionID] >= @minPartition and [PartitionID]<=@maxPartition)
                )
                or
                ([operation] = 'LOP_HOBT_DDL')
              )
              SET NOCOUNT OFF -- Re-enable "rows affected display"
      
      end
      GO
      
    4. Создайте сертификат в основной базе данных:

      Use [master]
      Go
      CREATE CERTIFICATE [attrep_rtm_dump_dblog_cert]
      ENCRYPTION BY PASSWORD = N'choose_your_own_pwd'
      WITH SUBJECT = N'Certificate for FN_DUMP_DBLOG Permissions';
    5. Создайте учетные данные на основе сертификата следующим образом:

      Use [master]
      Go
      CREATE LOGIN attrep_rtm_dump_dblog_login FROM CERTIFICATE
      [attrep_rtm_dump_dblog_cert];
    6. Добавьте учетные данные в роль системного администратора на сервере следующим образом:

      ALTER SERVER ROLE [sysadmin] ADD MEMBER [attrep_rtm_dump_dblog_login];
    7. Добавьте подпись сертификата в [master].[attrep].[rtm_dump_dblog] следующим образом:

      Use [master]
      GO
      ADD SIGNATURE
      TO [master].[attrep].[rtm_dump_dblog]
      BY CERTIFICATE [attrep_rtm_dump_dblog_cert]
      					WITH PASSWORD = 'choose_your_own_pwd';
      Примечание к информации

      Если повторно создается сохраненная процедура, необходимо добавить подпись еще раз.

    8. Создайте процедуру [attrep].[rtm_position_1st_timestamp] в основной базе данных следующим образом:

      use [master]
      if object_id('[attrep].[rtm_position_1st_timestamp]','P') is not null
      DROP PROCEDURE [attrep].[rtm_position_1st_timestamp];
      go
      create procedure [attrep].[rtm_position_1st_timestamp]
      (
      @dbname                sysname,      -- Database name
      @seqno                 integer,      -- Backup set sequence/position number within file
      @filename              varchar(260), -- The backup filename
      @1stTimeStamp          varchar(40)   -- The timestamp to position by
      ) 
      as begin
      
      SET NOCOUNT ON       -- Disable "rows affected display"
      
      declare @firstMatching table
      (
      cLsn varchar(32),
      bTim datetime
      )
      
      declare @sql nvarchar(4000)
      declare @nl                       char(2)
      declare @tb                       char(2)
      declare @fnameVar                 nvarchar(254) = 'NULL'
      
      set @nl  = char(10); -- New line
      set @tb  = char(9)   -- Tab separator
      
      if (@filename is not null)
      set @fnameVar = ''''+@filename +''''
      
      set @sql='use ['+@dbname+'];'+@nl+
      'select top 1 [Current LSN],[Begin Time]'+@nl+
      'FROM fn_dump_dblog (NULL, NULL, NULL, '+ cast(@seqno as varchar(10))+','+ @fnameVar+','+@nl+
      @tb+'default, default, default, default, default, default, default,'+@nl+
      @tb+'default, default, default, default, default, default, default,'+@nl+
      @tb+'default, default, default, default, default, default, default,'+@nl+
      @tb+'default, default, default, default, default, default, default,'+@nl+
      @tb+'default, default, default, default, default, default, default,'+@nl+
      @tb+'default, default, default, default, default, default, default,'+@nl+
      @tb+'default, default, default, default, default, default, default,'+@nl+
      @tb+'default, default, default, default, default, default, default,'+@nl+
      @tb+'default, default, default, default, default, default, default)'+@nl+
      'where operation=''LOP_BEGIN_XACT''' +@nl+
      'and [Begin Time]>= cast('+''''+@1stTimeStamp+''''+' as datetime)'+@nl
      
      --print @sql
      delete from  @firstMatching 
      insert into @firstMatching  exec sp_executesql @sql    -- Get them all
      
      select top 1 cLsn as [matching LSN],convert(varchar,bTim,121) as [matching Timestamp] from @firstMatching;
      
      SET NOCOUNT OFF      -- Re-enable "rows affected display"
      
      end
      GO
      
    9. Создайте сертификат в основной базе данных:

      Use [master]
      Go
      CREATE CERTIFICATE [attrep_rtm_position_1st_timestamp_cert]
      ENCRYPTION BY PASSWORD = N'choose_your_own_pwd'
      WITH SUBJECT = N'Certificate for FN_POSITION_1st_TIMESTAMP Permissions';
    10. Создайте учетные данные на основе сертификата следующим образом:

      Use [master]
      Go
      CREATE LOGIN attrep_rtm_position_1st_timestamp_login FROM CERTIFICATE
      [attrep_rtm_position_1st_timestamp_cert];
    11. Добавьте учетные данные в роль системного администратора на сервере следующим образом:

      ALTER SERVER ROLE [sysadmin] ADD MEMBER [attrep_rtm_position_1st_timestamp_login];
    12. Добавьте подпись сертификата в [master].[attrep].[rtm_position_1st_timestamp] следующим образом:

      Use [master]
      GO
      ADD SIGNATURE
      TO [master].[attrep].[rtm_position_1st_timestamp]
      BY CERTIFICATE [attrep_rtm_position_1st_timestamp_cert]
      WITH PASSWORD = 'choose_your_own_pwd';
      Примечание к информации

      Если повторно создается сохраненная процедура, необходимо добавить подпись еще раз.

  2. Создайте пользователя со следующими разрешениями/ролями (в каждой из следующих баз данных):

    Примечание к информации

    Необходимо создать учетные данные с одним и тем же идентификатором SID в каждой реплике.

    • Основная база данных (в каждой реплике):
      • select on sys.fn_dblog
      • view any definition
      • view server state (следует предоставить для учетных данных).
      • execute on sp_repldone
      • execute on sp_replincrementlsn
      • execute on sp_addpublication
      • execute on sp_addarticle
      • execute on sp_articlefilter
      • select on [attrep].[split_partition_list]
      • execute on [attrep].[rtm_dump_dblog]
      • execute on [attrep].[rtm_position_1st_timestamp]
    • База данных MSDB (в каждой реплике):
      • select on msdb.dbo.backupset
      • select on msdb.dbo.backupmediafamily
      • select on msdb.dbo.backupfile
    • Исходная база данных (так как база данных синхронизируется, это достаточно сделать только в первичной реплике):
      • db_owner ROLE

Помогла ли вам эта страница?

Если вы обнаружили какую-либо проблему на этой странице и с ее содержанием — будь то опечатка, пропущенный шаг или техническая ошибка, сообщите нам об этом, чтобы мы смогли ее исправить!