Контейнерная группа доступности (Contained Availability Group, CAG) предназначена для упрощения высокодоступности и аварийного восстановления путём инкапсуляции системных баз данных (master, msdb) непосредственно внутри самой группы доступности. Это означает, что учётные записи (логины), задания агента SQL Server, учётные данные и прочие метаданные автоматически реплицируются между репликами, устраняя необходимость ручной синхронизации и снижая эксплуатационную сложность.
Начиная с SQL Server 2025 CU1, вы можете создавать или восстанавливать базы данных напрямую через прослушиватель CAG — без подключения к физическому экземпляру — включая специальный ключ контекста сеанса.
Почему изолированные группы доступности важны
- Автономный модуль высокой доступности (self-contained HA unit): Каждая изолированная группа доступности имеет собственную копию
masterиmsdb, что делает её независимой от физического экземпляра SQL Server. - Упрощённое переключение (failover): При переключении группы доступности все связанные метаданные перемещаются вместе с ней, обеспечивая бесперебойную работу приложений без ручного вмешательства.
- Улучшенная автоматизация: Поддерживает сценарии, в которых прямой доступ к экземпляру SQL Server ограничен, позволяя выполнять операции через прослушиватель группы доступности.
- Повышенная безопасность: Снижает уязвимости за счёт ограничения доступа на уровне экземпляра; операции могут быть ограничены контекстом изолированной группы доступности.
- Упрощённое управление: Устраняет в сценариях необходимость репликации учётных записей и заданий между репликами.
Шаг 1. Подготовка базы данных для группы доступности
В этом примере используется SQL Server на Linux; однако шаги идентичны для SQL Server на Windows.
В данном руководстве существующая база данных с именем CAGDB добавляется в CAG. Прежде чем добавить базу данных в контейнерную группу доступности, убедитесь, что она настроена в модели восстановления FULL, и выполните полную резервную копию базы данных.
ALTER DATABASE CAGDB SET RECOVERY FULL;
GO
BACKUP DATABASE CAGDB TO DISK = N'/var/opt/mssql/backups/CAGDB.bak' WITH INIT, COMPRESSION;
GO
Примечание: В Linux убедитесь, что целевой каталог для резервных копий существует и принадлежит пользователю mssql.
sudo mkdir -p /var/opt/mssql/backups
sudo chown mssql:mssql /var/opt/mssql/backups
Шаг 2. Создание контейнерной группы доступности
На ваших узлах Linux с SQL Server выполните:
CREATE AVAILABILITY GROUP [CAGDemo] WITH ( CLUSTER_TYPE = EXTERNAL, CONTAINED ) FOR DATABASE [CAGDB] REPLICA ON N'node1' WITH ( ENDPOINT_URL = N'tcp://node1:5022', AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, FAILOVER_MODE = EXTERNAL, SEEDING_MODE = AUTOMATIC ), N'node2' WITH ( ENDPOINT_URL = N'tcp://node2:5022', AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, FAILOVER_MODE = EXTERNAL, SEEDING_MODE = AUTOMATIC );
GO
-- Подключитесь к дополнительным репликам и присоедините их к группе доступности:
ALTER AVAILABILITY GROUP [CAGDemo] JOIN WITH (CLUSTER_TYPE = EXTERNAL);
ALTER AVAILABILITY GROUP [CAGDemo] GRANT CREATE ANY DATABASE;
Шаг 3. Настройка прослушивателя и подключение к нему
Создайте прослушиватель и подключитесь с помощью SQL Server Management Studio (SSMS) или sqlcmd:
ALTER AVAILABILITY GROUP [CAGDemo] ADD LISTENER N'CAGDemoListener' ( WITH IP ( (N'*.*.*.*', N'255.255.255.0') ), PORT = 1453 );
GO
Шаг 4. Подключение к прослушивателю изолированной группы доступности и попытка создания базы данных (неудача)
При подключении через прослушиватель:
CREATE DATABASE TestCAGDB;
Результат:
Msg 262, Level 14, State 1: CREATE DATABASE is not allowed in this context.Это происходит потому, что создание базы данных по умолчанию заблокировано в сеансе CAG.
Шаг 5. Включение создания базы данных в сеансе изолированной группы доступности
EXEC sp_set_session_context
@key = N'allow_cag_create_db',
@value = 1;
Это включает создание базы данных для вашего текущего сеанса.
Шаг 6. Повторная попытка создания базы данных (успех)
CREATE DATABASE TestCAGDB;
Результат: База данных успешно создана в контексте изолированной группы доступности.
Это действие в контексте CAG могут выполнять пользователи с ролью dbcreator.
Шаг 7. Создание резервной копии базы данных
ALTER DATABASE TestCAGDB SET RECOVERY FULL;
BACKUP DATABASE TestCAGDB TO DISK = N'/var/opt/mssql/data/backups/TestCAGDB.bak';
Шаг 8. Добавление базы данных в изолированную группу доступности
ALTER AVAILABILITY GROUP [CAGDemo] ADD DATABASE [TestCAGDB];
Автоматизация процесса с помощью хранимой процедуры
Чтобы автоматизировать шаги 4–8, вы можете создать хранимую процедуру (например, [dbo].[sp_cag_create_db]) и выполнять её, подключившись через контекст прослушивателя изолированной группы доступности (CAG).
CREATE OR ALTER PROCEDURE [dbo].[sp_cag_create_db]
@database_name sysname,
@createdb_sql NVARCHAR(MAX) = NULL
AS
BEGIN
SET NOCOUNT ON
DECLARE @fIsContainedAGSession int
EXECUTE @fIsContainedAGSession = sys.sp_MSIsContainedAGSession
if (@fIsContainedAGSession = 1)
BEGIN
DECLARE @SQL NVARCHAR(MAX);
DECLARE @AG_Name sysname;
EXEC sp_set_session_context @key = N'allow_cag_create_db', @value = 1;
IF @createdb_sql IS NULL
SET @SQL = 'CREATE DATABASE ' + QUOTENAME(@database_name);
ELSE
SET @SQL = @createdb_sql;
PRINT @SQL
EXEC sp_executesql @SQL;
SET @SQL = 'ALTER DATABASE ' + QUOTENAME(@database_name) + ' SET RECOVERY FULL';
PRINT @SQL
EXEC sp_executesql @SQL;
SET @SQL = 'BACKUP DATABASE ' + QUOTENAME(@database_name) + ' TO DISK = N''NUL''';
PRINT @SQL
EXEC sp_executesql @SQL;
SELECT @AG_Name = name FROM sys.availability_groups ags
INNER JOIN sys.dm_exec_sessions des ON ags.group_id = des.contained_availability_group_id
WHERE @@SPID = des.session_id;
SET @SQL = 'ALTER AVAILABILITY GROUP ' + QUOTENAME(@AG_Name) + ' ADD DATABASE ' + QUOTENAME(@database_name);
PRINT @SQL
EXEC sp_executesql @SQL;
EXEC sp_set_session_context @key = N'allow_cag_create_db', @value = 0;
END
ELSE
BEGIN
RAISERROR('Эту процедуру можно использовать только при подключении через изолированную группу доступности.', 16, 1);
END
END
GO
Эта процедура упрощает добавление базы данных в контейнерную группу доступности, объединяя следующие действия в единый рабочий процесс:
- Создание (или восстановление) базы данных
- Установка модели восстановления FULL (полное восстановление)
- Выполнение начальной резервной копии, необходимой для начального заполнения (seeding) в группе доступности
- Добавление базы данных в целевую CAG
Пример: создание базы данных
Выполните следующую команду, чтобы создать NewTestDB и добавить её в целевую изолированную группу доступности.
EXEC [dbo].sp_cag_create_db @database_name = N'NewTestDB';
Пример: восстановление базы данных
Хранимая процедура также поддерживает необязательный параметр @createdb_sql, который позволяет передать пользовательскую инструкцию SQL для создания или восстановления базы данных (например, восстановление из резервной копии). После того как файл резервной копии базы данных существует и доступен SQL Server, вы можете использовать этот параметр при выполнении своих операции.
Важно: При использовании @createdb_sql процедура выполняет эту инструкцию SQL напрямую. Убедитесь, что инструкция SQL получена из безопасного и надёжного источника.
DECLARE @restoreSql NVARCHAR(MAX);
SET @restoreSql = N'
RESTORE DATABASE AdventureWorks2022
FROM DISK = ''/var/opt/mssql/backups/AdventureWorks2022.bak''
WITH
MOVE ''AdventureWorks2022''
TO ''/var/opt/mssql/data/AdventureWorks2022.mdf'',
MOVE ''AdventureWorks2022_log''
TO ''/var/opt/mssql/data/AdventureWorks2022_log.ldf'',
RECOVERY;
';
EXEC dbo.sp_cag_create_db
@database_name = N'AdventureWorks2022',
@createdb_sql = @restoreSql;
Заключение
Контейнерный группы доступности представляют собой значительный шаг вперёд в упрощении высокой доступности для SQL Server. Инкапсулируя системные базы данных в контекст группы доступности, они устраняют сложность синхронизации учётных записей, заданий и учётных данных между репликами.
Благодаря новой возможности в SQL Server 2025 CU1 создавать или восстанавливать базы данных напрямую через прослушиватель группы доступности с помощью sp_set_session_context, организации могут оптимизировать автоматизацию и снизить эксплуатационные накладные расходы.

Комментариев нет:
Отправить комментарий