I did set up always on between 2 servers 1 active 1 passive(readable not writable)
i had a table with identity, when failover happens and i try to insert the data , the identity went from current row to 1000, i was surprised and the with little bit of research i found a way to solve the issue...
WHEN EVER SQL restart happens or Failover happens which means a Role is changed , so when a role is changed we need to have a mechanism to notify
1. Configure role with error number =1480
and then in response execute a sql job ,and notify Operator
SQL JOB Code below: on both servers..
USE MASTER
GO
DECLARE @ServerName NVARCHAR(256) = @@SERVERNAME
DECLARE @RoleDesc NVARCHAR(60)
SELECT @RoleDesc = a.role_desc
FROM sys.dm_hadr_availability_replica_states AS a
JOIN sys.availability_replicas AS b
ON b.replica_id = a.replica_id
WHERE b.replica_server_name = @ServerName
IF @RoleDesc = 'PRIMARY'
BEGIN
USE MASTER
EXEC [dbo].[sp_FixIdentityReSeeds]
END
ELSE
BEGIN
RETURN
END
------------The sp is below
USE [master]
GO
/****** Object: StoredProcedure [dbo].[sp_FixIdentityReSeeds] Script Date: 10/8/2015 2:24:08 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_FixIdentityReSeeds]
AS
BEGIN
--foreach database
DECLARE @DatabaseName varchar(255)
DECLARE DatabasesCursor CURSOR READ_ONLY
FOR
SELECT name
FROM sys.databases
where name not in ('master','tempdb','model','msdb') and
sys.databases.state_desc = 'online'
OPEN DatabasesCursor
FETCH NEXT FROM DatabasesCursor
INTO @DatabaseName
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC ('USE '+@DatabaseName + '
--foreach identity column
DECLARE @tableName varchar(255)
DECLARE @columnName varchar(255)
DECLARE @schemaName varchar(255)
DECLARE IdentityColumnCursor CURSOR READ_ONLY
FOR
select TABLE_NAME , COLUMN_NAME, TABLE_SCHEMA
from INFORMATION_SCHEMA.COLUMNS
where COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME,
''IsIdentity'') = 1 and TABLE_NAME not like ''%syncobj_0x%''
OPEN IdentityColumnCursor
FETCH NEXT FROM IdentityColumnCursor
INTO @tableName, @columnName, @schemaName
WHILE @@FETCH_STATUS = 0
BEGIN
print ''['+@DatabaseName+'].[''+@tableName+''].[''+
@schemaName+''].[''+@columnName+'']''
EXEC (''declare @MAX int = 0
select @MAX = max(''+@columnName+'')
from ['+@DatabaseName+'].[''+@schemaName+''].[''+@tableName+'']
if (@MAX IS NULL)
BEGIN
SET @MAX = 0
END
DBCC CHECKIDENT(['+@DatabaseName+'.''+
@schemaName+''.''+@tableName+''],RESEED,@MAX)'')
FETCH NEXT FROM IdentityColumnCursor
INTO @tableName, @columnName, @schemaName
END
CLOSE IdentityColumnCursor
DEALLOCATE IdentityColumnCursor')
FETCH NEXT FROM DatabasesCursor
INTO @DatabaseName
END
CLOSE DatabasesCursor
DEALLOCATE DatabasesCursor
END
EXEC sp_configure 'show advanced options', 1 ;
i had a table with identity, when failover happens and i try to insert the data , the identity went from current row to 1000, i was surprised and the with little bit of research i found a way to solve the issue...
WHEN EVER SQL restart happens or Failover happens which means a Role is changed , so when a role is changed we need to have a mechanism to notify
1. Configure role with error number =1480
and then in response execute a sql job ,and notify Operator
SQL JOB Code below: on both servers..
USE MASTER
GO
DECLARE @ServerName NVARCHAR(256) = @@SERVERNAME
DECLARE @RoleDesc NVARCHAR(60)
SELECT @RoleDesc = a.role_desc
FROM sys.dm_hadr_availability_replica_states AS a
JOIN sys.availability_replicas AS b
ON b.replica_id = a.replica_id
WHERE b.replica_server_name = @ServerName
IF @RoleDesc = 'PRIMARY'
BEGIN
USE MASTER
EXEC [dbo].[sp_FixIdentityReSeeds]
END
ELSE
BEGIN
RETURN
END
------------The sp is below
USE [master]
GO
/****** Object: StoredProcedure [dbo].[sp_FixIdentityReSeeds] Script Date: 10/8/2015 2:24:08 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sp_FixIdentityReSeeds]
AS
BEGIN
--foreach database
DECLARE @DatabaseName varchar(255)
DECLARE DatabasesCursor CURSOR READ_ONLY
FOR
SELECT name
FROM sys.databases
where name not in ('master','tempdb','model','msdb') and
sys.databases.state_desc = 'online'
OPEN DatabasesCursor
FETCH NEXT FROM DatabasesCursor
INTO @DatabaseName
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC ('USE '+@DatabaseName + '
--foreach identity column
DECLARE @tableName varchar(255)
DECLARE @columnName varchar(255)
DECLARE @schemaName varchar(255)
DECLARE IdentityColumnCursor CURSOR READ_ONLY
FOR
select TABLE_NAME , COLUMN_NAME, TABLE_SCHEMA
from INFORMATION_SCHEMA.COLUMNS
where COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME,
''IsIdentity'') = 1 and TABLE_NAME not like ''%syncobj_0x%''
OPEN IdentityColumnCursor
FETCH NEXT FROM IdentityColumnCursor
INTO @tableName, @columnName, @schemaName
WHILE @@FETCH_STATUS = 0
BEGIN
print ''['+@DatabaseName+'].[''+@tableName+''].[''+
@schemaName+''].[''+@columnName+'']''
EXEC (''declare @MAX int = 0
select @MAX = max(''+@columnName+'')
from ['+@DatabaseName+'].[''+@schemaName+''].[''+@tableName+'']
if (@MAX IS NULL)
BEGIN
SET @MAX = 0
END
DBCC CHECKIDENT(['+@DatabaseName+'.''+
@schemaName+''.''+@tableName+''],RESEED,@MAX)'')
FETCH NEXT FROM IdentityColumnCursor
INTO @tableName, @columnName, @schemaName
END
CLOSE IdentityColumnCursor
DEALLOCATE IdentityColumnCursor')
FETCH NEXT FROM DatabasesCursor
INTO @DatabaseName
END
CLOSE DatabasesCursor
DEALLOCATE DatabasesCursor
END
EXEC sp_configure 'show advanced options', 1 ;
No comments:
Post a Comment