Quantcast
Channel: SQL.ru: Microsoft SQL Server
Viewing all articles
Browse latest Browse all 7251

Переход AlwaysOn на новые сервера.

$
0
0
Добрый день.
Возникла задача. Добавить в кластер Windows 2012R2 Stadard (x64) + SQL 2014 Enterprise (x64) новый узел/ноду без простоя и с возможностью, в случае "что то пошло не так, откатиться назад на старую указанную ноду" новый узел с Windows 2016 Standard (x64) и желательно SQL 2016 Enterprise.
Недельку пожив с 2мя разными версиями узлов, обновить 2ю ноду кластера windows 2016 или переустановить заново.

1. Изначально есть знания, что Microsoft рекомендует собирать кластер из одинакового железа и одинакового софта. Честно говоря для меня было удивительным, что можно собрать кластер из разных версий Windows.
2. Но, о чудо! Админ (не ДБА) пропустил все тесты при сборке кластера на тесте - и кластер собран (пока без SQL).
3. Установил на собранный кластер на тесте SQL 2014 Enterprise x64 (evaluation) пытаюсь хотя бы с одинаковой версией SQL запустить AlwaysOn. Мастером не запускается, начал по скриптам прогонять. Endpoint Avail.Group поднялись БД тестовая забэкапилась отресторилась и фул и журнал транзакций. Последний шаг - цикл который ждет вывода БД в онлайн - не проходит.
+ полный скрипт
--- YOU MUST EXECUTE THE FOLLOWING SCRIPT IN SQLCMD MODE.
:Connect NODE2012r2

IF (SELECT state FROM sys.endpoints WHERE name = N'Hadr_endpoint') <> 0
BEGIN
	ALTER ENDPOINT [Hadr_endpoint] STATE = STARTED
END


GO

use [master]

GO

GRANT CONNECT ON ENDPOINT::[Hadr_endpoint] TO [NT Service\MSSQLSERVER]

GO

:Connect NODE2016

IF (SELECT state FROM sys.endpoints WHERE name = N'Hadr_endpoint') <> 0
BEGIN
	ALTER ENDPOINT [Hadr_endpoint] STATE = STARTED
END


GO

use [master]

GO

GRANT CONNECT ON ENDPOINT::[Hadr_endpoint] TO [NT Service\MSSQLSERVER]

GO

:Connect NODE2012r2

IF EXISTS(SELECT * FROM sys.server_event_sessions WHERE name='AlwaysOn_health')
BEGIN
  ALTER EVENT SESSION [AlwaysOn_health] ON SERVER WITH (STARTUP_STATE=ON);
END
IF NOT EXISTS(SELECT * FROM sys.dm_xe_sessions WHERE name='AlwaysOn_health')
BEGIN
  ALTER EVENT SESSION [AlwaysOn_health] ON SERVER STATE=START;
END

GO

:Connect NODE2016

IF EXISTS(SELECT * FROM sys.server_event_sessions WHERE name='AlwaysOn_health')
BEGIN
  ALTER EVENT SESSION [AlwaysOn_health] ON SERVER WITH (STARTUP_STATE=ON);
END
IF NOT EXISTS(SELECT * FROM sys.dm_xe_sessions WHERE name='AlwaysOn_health')
BEGIN
  ALTER EVENT SESSION [AlwaysOn_health] ON SERVER STATE=START;
END

GO

:Connect NODE2012r2

USE [master]

GO

CREATE AVAILABILITY GROUP [grp1]
WITH (AUTOMATED_BACKUP_PREFERENCE = SECONDARY)
FOR DATABASE [db1]
REPLICA ON N'NODE2012R2' WITH (ENDPOINT_URL = N'TCP://node2012r2.kurenkov.test:5022', FAILOVER_MODE = AUTOMATIC, AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50, SECONDARY_ROLE(ALLOW_CONNECTIONS = ALL)),
	N'NODE2016' WITH (ENDPOINT_URL = N'TCP://node2016.kurenkov.test:5022', FAILOVER_MODE = AUTOMATIC, AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50, SECONDARY_ROLE(ALLOW_CONNECTIONS = ALL));

GO

:Connect NODE2016

ALTER AVAILABILITY GROUP [grp1] JOIN;

GO

:Connect NODE2012r2

BACKUP DATABASE [db1] TO  DISK = N'\\adtest\Share\db1.bak' WITH  COPY_ONLY, FORMAT, INIT, SKIP, REWIND, NOUNLOAD, COMPRESSION,  STATS = 5

GO

:Connect NODE2016

RESTORE DATABASE [db1] FROM  DISK = N'\\adtest\Share\db1.bak' WITH  NORECOVERY,  NOUNLOAD,  STATS = 5

GO

:Connect NODE2012r2

BACKUP LOG [db1] TO  DISK = N'\\adtest\Share\db1_20161215115747.trn' WITH NOFORMAT, NOINIT, NOSKIP, REWIND, NOUNLOAD, COMPRESSION,  STATS = 5

GO

:Connect NODE2016

RESTORE LOG [db1] FROM  DISK = N'\\adtest\Share\db1_20161215115747.trn' WITH  NORECOVERY,  NOUNLOAD,  STATS = 5

GO

:Connect NODE2016


-- Wait for the replica to start communicating
begin try
declare @conn bit
declare @count int
declare @replica_id uniqueidentifier 
declare @group_id uniqueidentifier
set @conn = 0
set @count = 30 -- wait for 5 minutes 

if (serverproperty('IsHadrEnabled') = 1)
	and (isnull((select member_state from master.sys.dm_hadr_cluster_members where upper(member_name COLLATE Latin1_General_CI_AS) = upper(cast(serverproperty('ComputerNamePhysicalNetBIOS') as nvarchar(256)) COLLATE Latin1_General_CI_AS)), 0) <> 0)
	and (isnull((select state from master.sys.database_mirroring_endpoints), 1) = 0)
begin
    select @group_id = ags.group_id from master.sys.availability_groups as ags where name = N'grp1'
	select @replica_id = replicas.replica_id from master.sys.availability_replicas as replicas where upper(replicas.replica_server_name COLLATE Latin1_General_CI_AS) = upper(@@SERVERNAME COLLATE Latin1_General_CI_AS) and group_id = @group_id
	while @conn <> 1 and @count > 0
	begin
		set @conn = isnull((select connected_state from master.sys.dm_hadr_availability_replica_states as states where states.replica_id = @replica_id), 1)
		if @conn = 1
		begin
			-- exit loop when the replica is connected, or if the query cannot find the replica status
			break
		end
		waitfor delay '00:00:10'
		set @count = @count - 1
	end
end
end try
begin catch
	-- If the wait loop fails, do not stop execution of the alter database statement
end catch
ALTER DATABASE [db1] SET HADR AVAILABILITY GROUP = [grp1];

GO

В общем последний шаг - цикл @conn <> 1 который 30 раз проверяет с задержкой вышла реплика connect_state в 1, ничего не делая, тупо ожидание в 10 секунд и так 30 раз показывает что заканчивается через 30 итераций и 5 минут ожидания и вылетает с ожибкой на команте - ALTER DATABASE [db1] SET HADR AVAILABILITY GROUP = [grp1];.
+ сам шаг скрипта сгенерированного мастером
-- Wait for the replica to start communicating
begin try
declare @conn bit
declare @count int
declare @replica_id uniqueidentifier 
declare @group_id uniqueidentifier
set @conn = 0
set @count = 30 -- wait for 5 minutes 

if (serverproperty('IsHadrEnabled') = 1)
	and (isnull((select member_state from master.sys.dm_hadr_cluster_members where upper(member_name COLLATE Latin1_General_CI_AS) = upper(cast(serverproperty('ComputerNamePhysicalNetBIOS') as nvarchar(256)) COLLATE Latin1_General_CI_AS)), 0) <> 0)
	and (isnull((select state from master.sys.database_mirroring_endpoints), 1) = 0)
begin
    select @group_id = ags.group_id from master.sys.availability_groups as ags where name = N'grp1'
	select @replica_id = replicas.replica_id from master.sys.availability_replicas as replicas where upper(replicas.replica_server_name COLLATE Latin1_General_CI_AS) = upper(@@SERVERNAME COLLATE Latin1_General_CI_AS) and group_id = @group_id
	while @conn <> 1 and @count > 0
	begin
		set @conn = isnull((select connected_state from master.sys.dm_hadr_availability_replica_states as states where states.replica_id = @replica_id), 1)
		if @conn = 1
		begin
			-- exit loop when the replica is connected, or if the query cannot find the replica status
			break
		end
		waitfor delay '00:00:10'
		set @count = @count - 1
	end
end
end try
begin catch
	-- If the wait loop fails, do not stop execution of the alter database statement
end catch
ALTER DATABASE [db1] SET HADR AVAILABILITY GROUP = [grp1];


Тынца доказывающего что нельзя собрать AlwaysOn на разных версиях Windows я не нашел. Мануалов много типа поднять олвизон 2012. поднять кластер 2008, 2012 и т.п.
А вот как аргументированно показать руководству что идея поднять на продакшн ноду с другой версий Windows Server я не знаю. На слово - не верят, нужен тынц. Ну или если все таки возможно поднять олвизон на разных вин сервер - подскажите как.

Viewing all articles
Browse latest Browse all 7251

Trending Articles