国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SQL Server實(shí)例間同步登錄用戶

這篇具有很好參考價(jià)值的文章主要介紹了SQL Server實(shí)例間同步登錄用戶。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

SQL Server實(shí)例間同步登錄用戶

問題痛點(diǎn):由于AlwaysOn和數(shù)據(jù)庫鏡像無法同步數(shù)據(jù)庫外實(shí)例對象,例如 登錄用戶、作業(yè)、鏈接服務(wù)器等,導(dǎo)致主庫切換之后,應(yīng)用連接不上數(shù)據(jù)庫或者作業(yè)不存在導(dǎo)致每晚跑批任務(wù)漏跑等

目前來看,作業(yè)等其他實(shí)例對象的同步還比較難實(shí)現(xiàn),比如作業(yè)分為很多步驟,而且作業(yè)包含的命令也比較復(fù)雜,作業(yè)也支持調(diào)用其他子系統(tǒng),比如 PowerShell ,ActiveX,CmdExec等數(shù)據(jù)庫外部程序和命令,用動(dòng)態(tài)SQL方式很難處理

目前只有升級到SQL Server 2022并使用包含可用性組(支持同步登錄用戶、SQL代理作業(yè)、鏈接服務(wù)器)才能最絲滑的解決這個(gè)問題

本文主要介紹的是登錄用戶的同步,畢竟登錄用戶的重要性還是比較高的,應(yīng)用需要先通過登錄用戶登錄DB實(shí)例才能執(zhí)行后續(xù)的操作

?

要在SQLServer實(shí)例間同步登錄用戶,主要有幾種方法

1、創(chuàng)建操作系統(tǒng)域用戶,然后創(chuàng)建基于這個(gè)域用戶的登錄用戶,因?yàn)橛蛴脩粼谟蚶锩媸峭降?,但是這種方法前提是需要有域環(huán)境,而且普通開發(fā)人員一般也沒有域控機(jī)器權(quán)限創(chuàng)建域用戶

2、使用外部第三方工具,比如 sqlcmd,PowerShell,SQLServer自帶的SSIS服務(wù)

3、使用鏈接服務(wù)器 和 動(dòng)態(tài)拼接SQL方法

?

本文主要使用第三種方法,因?yàn)榈谌N方法本人認(rèn)為有下面幾種優(yōu)勢

1、保證最低維護(hù)成本,純SQL實(shí)現(xiàn),不需要借助第三方工具

2、通用性,幾乎所有SQL Server版本都能用,也不需要像第三方工具例如 PowerShell那樣有時(shí)候需要升級版本

3、兼容性,跨操作系統(tǒng)平臺Linux、Windows

4、高可靠性,使用SQLServer自帶原生工具,足夠簡單高效

?

?

這個(gè)工具腳本的主要流程如下

?SQL Server實(shí)例間同步登錄用戶

?

具體使用步驟

假設(shè)有三個(gè)AlwaysOn節(jié)點(diǎn),分別是

node1 ip:192.168.10.10

node2 ip:192.168.10.11

node3 ip:192.168.10.12

step1: 創(chuàng)建鏈接服務(wù)器,在所有AlwaysOn節(jié)點(diǎn)上創(chuàng)建其他節(jié)點(diǎn)的鏈接服務(wù)器,比如在192.168.10.10上創(chuàng)建其他節(jié)點(diǎn)鏈接服務(wù)器,下面腳本在192.168.10.10服務(wù)器上執(zhí)行,其他節(jié)點(diǎn)以此類推

--create  linkedserver
USE [master]
GO

DECLARE @IP NVARCHAR(MAX)
DECLARE @Login NVARCHAR(MAX)
DECLARE @PWD NVARCHAR(MAX)

SET @Login = N'sa' --★Do
SET @PWD = N'xxxxxx'  --★Do
SET  @IP ='192.168.10.11,1433'    --★Do


EXEC master.dbo.sp_addlinkedserver @server = @IP,@srvproduct = N'SQL Server'

EXEC master.dbo.sp_serveroption @server = @IP,@optname = N'collation compatible', @optvalue = N'false'
EXEC master.dbo.sp_serveroption @server = @IP,@optname = N'data access', @optvalue = N'true'
EXEC master.dbo.sp_serveroption @server = @IP, @optname = N'dist',@optvalue = N'false'
EXEC master.dbo.sp_serveroption @server = @IP, @optname = N'pub',@optvalue = N'false'
EXEC master.dbo.sp_serveroption @server = @IP, @optname = N'rpc',@optvalue = N'true'
EXEC master.dbo.sp_serveroption @server = @IP, @optname = N'rpc out',@optvalue = N'true'
EXEC master.dbo.sp_serveroption @server = @IP, @optname = N'sub',@optvalue = N'false'
EXEC master.dbo.sp_serveroption @server = @IP,@optname = N'connect timeout', @optvalue = N'0'
EXEC master.dbo.sp_serveroption @server = @IP,@optname = N'collation name', @optvalue = NULL
EXEC master.dbo.sp_serveroption @server = @IP,@optname = N'lazy schema validation', @optvalue = N'false'
EXEC master.dbo.sp_serveroption @server = @IP,@optname = N'query timeout', @optvalue = N'0'
EXEC master.dbo.sp_serveroption @server = @IP,@optname = N'use remote collation', @optvalue = N'true'
EXEC master.dbo.sp_serveroption @server = @IP,@optname = N'connect timeout', @optvalue = N'120'
EXEC master.dbo.sp_serveroption @server = @IP,@optname = N'query timeout', @optvalue = N'120'
EXEC master.dbo.sp_serveroption @server = @IP,@optname = N'remote proc transaction promotion',@optvalue = N'true'

USE [master]
EXEC master.dbo.sp_addlinkedsrvlogin 
@rmtsrvname = @IP,
@locallogin = NULL, 
@useself = N'False', 
@rmtuser = @Login,
@rmtpassword = @PWD



---------------------------------------------------------------------------------------------------------------------------

--create  linkedserver
USE [master]
GO

DECLARE @IP NVARCHAR(MAX)
DECLARE @Login NVARCHAR(MAX)
DECLARE @PWD NVARCHAR(MAX)

SET @Login = N'sa' --★Do
SET @PWD = N'xxxxxx'  --★Do
SET  @IP ='192.168.10.12,1433'    --★Do


EXEC master.dbo.sp_addlinkedserver @server = @IP,@srvproduct = N'SQL Server'

EXEC master.dbo.sp_serveroption @server = @IP,@optname = N'collation compatible', @optvalue = N'false'
EXEC master.dbo.sp_serveroption @server = @IP,@optname = N'data access', @optvalue = N'true'
EXEC master.dbo.sp_serveroption @server = @IP, @optname = N'dist',@optvalue = N'false'
EXEC master.dbo.sp_serveroption @server = @IP, @optname = N'pub',@optvalue = N'false'
EXEC master.dbo.sp_serveroption @server = @IP, @optname = N'rpc',@optvalue = N'true'
EXEC master.dbo.sp_serveroption @server = @IP, @optname = N'rpc out',@optvalue = N'true'
EXEC master.dbo.sp_serveroption @server = @IP, @optname = N'sub',@optvalue = N'false'
EXEC master.dbo.sp_serveroption @server = @IP,@optname = N'connect timeout', @optvalue = N'0'
EXEC master.dbo.sp_serveroption @server = @IP,@optname = N'collation name', @optvalue = NULL
EXEC master.dbo.sp_serveroption @server = @IP,@optname = N'lazy schema validation', @optvalue = N'false'
EXEC master.dbo.sp_serveroption @server = @IP,@optname = N'query timeout', @optvalue = N'0'
EXEC master.dbo.sp_serveroption @server = @IP,@optname = N'use remote collation', @optvalue = N'true'
EXEC master.dbo.sp_serveroption @server = @IP,@optname = N'connect timeout', @optvalue = N'120'
EXEC master.dbo.sp_serveroption @server = @IP,@optname = N'query timeout', @optvalue = N'120'
EXEC master.dbo.sp_serveroption @server = @IP,@optname = N'remote proc transaction promotion',@optvalue = N'true'

USE [master]
EXEC master.dbo.sp_addlinkedsrvlogin 
@rmtsrvname = @IP,
@locallogin = NULL, 
@useself = N'False', 
@rmtuser = @Login,
@rmtpassword = @PWD

?

step2: 創(chuàng)建存儲過程,在所有AlwaysOn節(jié)點(diǎn)上創(chuàng)建存儲過程,記住是所有AlwaysOn節(jié)點(diǎn)都要執(zhí)行

USE [master]
GO
-- =================================================================
-- Author:        <steven>
-- Create date: <2021-12-26>
-- Description:    <Synchronize login users between multiple SQLServer Instances>
-- =================================================================
create  PROCEDURE [dbo].[usp_SyncLoginUserRegularBetweenInstances]
AS
BEGIN

      IF EXISTS(SELECT  1   FROM    sys.dm_hadr_availability_replica_states hars 
              INNER JOIN sys.availability_groups ag ON ag.group_id = hars.group_id
              INNER JOIN sys.availability_replicas ar ON ar.replica_id = hars.replica_id
      WHERE   [hars].[is_local] = 1 AND [hars].[role_desc] = 'PRIMARY'AND [hars].[operational_state_desc] = 'ONLINE'
              AND [hars].[synchronization_health_desc] = 'HEALTHY')
      BEGIN
               ----Check for prerequisite, if not present deploy it.
               IF NOT EXISTS (SELECT  id  FROM  [master].[dbo].[sysobjects] where name='sp_hexadecimal' and xtype='P')  
               BEGIN
                     DECLARE @sp_hexadecimalcreatescript NVARCHAR(3000)
                     --The sp_hexadecimal stored procedure is used to generate the user's password hash value and the user's SID
                     SET @sp_hexadecimalcreatescript =  N'
                  CREATE PROCEDURE [dbo].[sp_hexadecimal]
                      @binvalue VARBINARY(256) ,
                      @hexvalue VARCHAR(514) OUTPUT
                  AS
                      DECLARE @charvalue VARCHAR(514);
                      DECLARE @i INT;
                      DECLARE @length INT;
                      DECLARE @hexstring CHAR(16);
                      SELECT @charvalue = ''0x'';
                      SELECT @i = 1;
                      SELECT @length = DATALENGTH(@binvalue);
                      SELECT @hexstring = ''0123456789ABCDEF'';
                      WHILE ( @i <= @length )
                          BEGIN
                              DECLARE @tempint INT;
                              DECLARE @firstint INT;
                              DECLARE @secondint INT;
                              SELECT @tempint = CONVERT(INT, SUBSTRING(@binvalue, @i, 1));
                              SELECT @firstint = FLOOR(@tempint / 16);
                              SELECT @secondint = @tempint - ( @firstint * 16 );
                              SELECT @charvalue = @charvalue
                                                  + SUBSTRING(@hexstring, @firstint + 1, 1)
                                                  + SUBSTRING(@hexstring, @secondint + 1, 1);
                              SELECT @i = @i + 1;
                          END;
                  
                      SELECT @hexvalue = @charvalue;'
                           
                           EXEC [master].[dbo].sp_executesql @sp_hexadecimalcreatescript
               END
               
                              
               
               --The temporary table below is used to save the generated login user script , user by user, line by line
               DECLARE @TempTable TABLE
               (id INT IDENTITY ,Script NVARCHAR(MAX))
               DECLARE @Login NVARCHAR(MAX)
               DECLARE CURLOGIN CURSOR FOR
               SELECT name 
               FROM sys.server_principals
               WHERE [type] = 'S' AND  [is_disabled] =0   AND  [name] <> 'sa'
               --WHERE CONVERT(VARCHAR(24), create_date, 103) = CONVERT(VARCHAR(24), GETDATE(), 103)
               --    OR CONVERT(VARCHAR(24), modify_date, 103) = CONVERT(VARCHAR(24), GETDATE(), 103)
               
               OPEN CURLOGIN
               FETCH NEXT FROM CURLOGIN INTO @Login
               
               WHILE @@FETCH_STATUS = 0
               BEGIN
                   SET NOCOUNT ON
                   DECLARE @Script NVARCHAR(MAX)
                   DECLARE @LoginName VARCHAR(1500) = @Login
                   DECLARE @LoginSID VARBINARY(400)
                   DECLARE @SID_String VARCHAR(1514)
                   DECLARE @LoginPWD VARBINARY(1256)
                   DECLARE @PWD_String VARCHAR(1514)
                   DECLARE @LoginType CHAR(1)
                   DECLARE @is_disabled BIT
                   DECLARE @default_database_name SYSNAME
                   DECLARE @default_language_name SYSNAME
                   DECLARE @is_policy_checked BIT
                   DECLARE @is_expiration_checked BIT
                   DECLARE @createdDateTime DATETIME
               
                   SELECT @LoginSID = P.[sid]
                       , @LoginType = P.[type]
                       , @is_disabled = P.is_disabled 
                       , @default_database_name = P.default_database_name 
                       , @default_language_name = P.default_language_name 
                       , @createdDateTime = P.create_date 
                   FROM sys.server_principals P
                   WHERE P.name = @LoginName
               
                   SET @Script = ''
               
                   --If the login is a SQL Login, then do a lot of stuff...
                   IF @LoginType = 'S'
                   BEGIN
                       SET @LoginPWD = CAST(LOGINPROPERTY(@LoginName, 'PasswordHash') AS VARBINARY(256))
                       EXEC [master].[dbo].[sp_hexadecimal] @LoginPWD, @PWD_String OUT    
                       EXEC [master].[dbo].[sp_hexadecimal] @LoginSID, @SID_String OUT
                       SELECT @is_policy_checked = S.is_policy_checked
                           , @is_expiration_checked = S.is_expiration_checked
                       FROM sys.sql_logins S  
                       WHERE S.[type] = 'S' AND  S.[is_disabled] =0  
               
                       -- Create  diff Script
                       SET @Script = @Script + CHAR(13) 
                           + CHAR(13) + '''' 
                           + CHAR(13) + 'USE  [master];'  + CHAR(13) 
                           + 'IF EXISTS (SELECT name FROM sys.server_principals WHERE name= ''''' + @LoginName + ''''') ' 
                           + CHAR(13) + 'BEGIN '
                           + CHAR(13) + CHAR(9) + ' DECLARE @CurrentLoginPWD VARBINARY(512)'
                           + CHAR(13) + CHAR(9) + ' DECLARE @CurrentPWD_String VARCHAR(1514)'
                           + CHAR(13) + CHAR(9) + ' DECLARE @CurrentLoginSID VARBINARY(400)'
                           + CHAR(13) + CHAR(9) + ' DECLARE @CurrentSID_String VARCHAR(1514)'
                           + CHAR(13) + CHAR(9) + ' SELECT @CurrentLoginSID = [sid]  FROM sys.server_principals WHERE name = '''''+ @LoginName +''''''
                           + CHAR(13) + CHAR(9) + ' SET  @CurrentLoginPWD =CAST(LOGINPROPERTY(''''' + @LoginName + ''''', ' + '''''PasswordHash''''' +') AS VARBINARY(512))'
                           + CHAR(13) + CHAR(9) + ' EXEC [master].[dbo].[sp_hexadecimal] @CurrentLoginPWD , @CurrentPWD_String OUT    '
                           + CHAR(13) + CHAR(9) + ' EXEC [master].[dbo].[sp_hexadecimal] @CurrentLoginSID, @CurrentSID_String OUT '
                           + CHAR(13) + CHAR(9) + ' --Compare two SID if the same  '
                           + CHAR(13) + CHAR(9) + ' IF  ''''' + @SID_String + ''''' =  @CurrentSID_String      '
                           + CHAR(13) + CHAR(9) + ' BEGIN'
                           + CHAR(13) + CHAR(9) +  CHAR(9) +  CHAR(9) + ' --Compare two password  if the same '
                           + CHAR(13) + CHAR(9) +  CHAR(9) +  CHAR(9) + ' IF  ''''' + @PWD_String + ''''' <>  @CurrentPWD_String      '
                           + CHAR(13) + CHAR(9) +  CHAR(9) +  CHAR(9) + ' BEGIN'
                           + CHAR(13) + CHAR(9) +  CHAR(9) +  CHAR(9) +  CHAR(9) +  '--Just update login user password'
                           + CHAR(13) + CHAR(9) +  CHAR(9) +  CHAR(9) +  CHAR(9) +  ' ALTER LOGIN ' + QUOTENAME(@LoginName)
                           + CHAR(13) + CHAR(9) +  CHAR(9) +  CHAR(9) +  CHAR(9) +  ' WITH PASSWORD = ' + @PWD_String + ' HASHED'
                           + CHAR(13) + CHAR(9) +  CHAR(9) +  CHAR(9) +  CHAR(9) +  ', DEFAULT_DATABASE = [' + @default_database_name + ']'
                           + CHAR(13) + CHAR(9) +  CHAR(9) +  CHAR(9) +  CHAR(9) +  ', DEFAULT_LANGUAGE = [' + @default_language_name + ']'
                           + CHAR(13) + CHAR(9) +  CHAR(9) +  CHAR(9) +  CHAR(9) +  ', CHECK_POLICY ' + CASE WHEN @is_policy_checked = 0 THEN '=OFF' ELSE '=ON' END
                           + CHAR(13) + CHAR(9) +  CHAR(9) +  CHAR(9) +  CHAR(9) +  ', CHECK_EXPIRATION ' + CASE WHEN @is_expiration_checked = 0 THEN '=OFF' ELSE '=ON' END
                           + CHAR(13) + CHAR(9) +  CHAR(9) +  CHAR(9) + ' END'
                           + CHAR(13) + CHAR(9) + ' END'
                           + CHAR(13) + 'END '
                           + CHAR(13) + 'ELSE'
                           + CHAR(13) + 'BEGIN '
                           + CHAR(13) + CHAR(9) + ' --Create new login user ' 
                           + CHAR(13) + CHAR(9) + ' CREATE LOGIN ' + QUOTENAME(@LoginName)
                           + CHAR(13) + CHAR(9) + ' WITH PASSWORD = ' + @PWD_String + ' HASHED'
                           + CHAR(13) + CHAR(9) + ', SID = ' + @SID_String
                           + CHAR(13) + CHAR(9) + ', DEFAULT_DATABASE = [' + @default_database_name + ']'
                           + CHAR(13) + CHAR(9) + ', DEFAULT_LANGUAGE = [' + @default_language_name + ']'
                           + CHAR(13) + CHAR(9) + ', CHECK_POLICY ' + CASE WHEN @is_policy_checked = 0 THEN '=OFF' ELSE '=ON' END
                           + CHAR(13) + CHAR(9) + ', CHECK_EXPIRATION ' + CASE WHEN @is_expiration_checked = 0 THEN '=OFF' ELSE '=ON' END
                           + CHAR(13) + 'END '
                       
                       --SET @Script = @Script + CHAR(13) + CHAR(13)
                       --    + ' ALTER LOGIN [' + @LoginName + ']'
                       --    + CHAR(13) + CHAR(9) + 'WITH DEFAULT_DATABASE = [' + @default_database_name + ']'
                       --    + CHAR(13) + CHAR(9) + ', DEFAULT_LANGUAGE = [' + @default_language_name + ']'
                   END
                   --ELSE
                   --BEGIN
                   --    --The login is a NT login (or group).
                   --    SET @Script = @Script + CHAR(13) + CHAR(13)
                   --        + 'IF NOT EXISTS (SELECT name FROM sys.server_principals WHERE name= ''' + @LoginName + ''') ' 
                   --        + CHAR(13) + ' BEGIN '
                   --        + CHAR(13) + CHAR(9) + ' CREATE LOGIN ' + QUOTENAME(@LoginName) + ' FROM WINDOWS'
                   --        + CHAR(13) + CHAR(9) + 'WITH DEFAULT_DATABASE = [' + @default_database_name + ']'
                   --        + CHAR(13) + ' END '
                   --END
               
               
                   --This section deals with the Server Roles that belong to that login...
                   DECLARE @ServerRoles TABLE
                       (
                       ServerRole SYSNAME
                       , MemberName SYSNAME
                       , MemberSID VARBINARY(185)
                       )
               
                   ----Prevent multiple records from being inserted into the @ServerRoles table
                   IF NOT EXISTS (SELECT 1 FROM @ServerRoles )
                   BEGIN
                       INSERT INTO @ServerRoles EXEC sp_helpsrvrolemember
                   END
                   
               
                   ----Remove all Roles
                   --SET @Script = @Script + CHAR(13)
                   --SET @Script = @Script 
                   --    + CHAR(13) + 'EXEC sp_dropsrvrolemember ' + QUOTENAME(@LoginName) + ', ''sysadmin'''
                   --    + CHAR(13) + 'EXEC sp_dropsrvrolemember ' + QUOTENAME(@LoginName) + ', ''securityadmin'''
                   --    + CHAR(13) + 'EXEC sp_dropsrvrolemember ' + QUOTENAME(@LoginName) + ', ''serveradmin''' 
                   --    + CHAR(13) + 'EXEC sp_dropsrvrolemember ' + QUOTENAME(@LoginName) + ', ''setupadmin''' 
                   --    + CHAR(13) + 'EXEC sp_dropsrvrolemember ' + QUOTENAME(@LoginName) + ', ''processadmin'''
                   --    + CHAR(13) + 'EXEC sp_dropsrvrolemember ' + QUOTENAME(@LoginName) + ', ''diskadmin''' 
                   --    + CHAR(13) + 'EXEC sp_dropsrvrolemember ' + QUOTENAME(@LoginName) + ', ''dbcreator''' 
                   --    + CHAR(13) + 'EXEC sp_dropsrvrolemember ' + QUOTENAME(@LoginName) + ', ''bulkadmin''' 
               
                   /** Output to script... **/
                   --SET @Script = @Script + CHAR(13) + CHAR(13)
               
                        --Test if there are any server roles for this login...
                        IF EXISTS(SELECT 1 FROM @ServerRoles WHERE MemberName = @LoginName)
                        BEGIN
                        
                            SET @Script = @Script + CHAR(13)
                        
                            DECLARE @ServerRole SYSNAME
                            DECLARE curRoles CURSOR LOCAL STATIC FORWARD_ONLY
                        
                            FOR SELECT  ServerRole 
                                FROM @ServerRoles
                                WHERE MemberName = @LoginName
                            
                            OPEN curRoles
                        
                            FETCH NEXT FROM curRoles
                            INTO @ServerRole
                        
                            WHILE @@FETCH_STATUS = 0
                            BEGIN
                                 /** Output to Script **/
                                 SET @Script = @Script 
                                              + CHAR(13) + 'EXEC sp_addsrvrolemember ' + QUOTENAME(@LoginName) + ', ' + '''''' + @ServerRole + ''''''
                                     
                                 FETCH NEXT FROM curRoles
                                 INTO @ServerRole
                            END
                        
                            --Cleanup.
                            CLOSE curRoles
                            DEALLOCATE curRoles
                        END
                        SET @Script = @Script + CHAR(13)  + '''' 
                        INSERT INTO @TempTable
                        VALUES(@Script)
                        
                        FETCH NEXT FROM CURLOGIN INTO @Login
               END
               CLOSE CURLOGIN;
               DEALLOCATE CURLOGIN;
               SELECT id, Script FROM @TempTable ORDER BY id
              
            
               ------------------------------------------------------------------------------------
               --Use  linked servers  to send scripts to remote machines for execution
               --------------------------------------------------------------------------------
               DECLARE @LinkedServerName NVARCHAR(512);
               DECLARE @DynamicSQL NVARCHAR(MAX);
               DECLARE @EXISTSSQL NVARCHAR(2000);
               
               
               DECLARE cursor_linked_servers CURSOR FOR
               SELECT name
               FROM sys.servers
               WHERE is_linked = 1 
               AND [product]='SQL Server' 
               AND [provider]='SQLNCLI' 
               AND [connect_timeout]>0 AND [query_timeout] >0;
               
               
               OPEN cursor_linked_servers;
               FETCH NEXT FROM cursor_linked_servers INTO @LinkedServerName;
               WHILE @@FETCH_STATUS = 0
               BEGIN  
                       --Determine whether the remote machine has the stored procedure call "sp_hexadecimal"
                       --if not have  do not execute the cursor traversal loop
                       CREATE TABLE #EXISTSTB(id BIGINT)
                       SET @EXISTSSQL='SELECT * FROM OPENQUERY('+ QUOTENAME(@LinkedServerName) + ', ''SELECT  id  FROM  [master].[dbo].[sysobjects] WHERE name = ''''sp_hexadecimal'''' AND xtype=''''P'''' '')'
                       INSERT INTO #EXISTSTB EXEC(@EXISTSSQL) 
                       IF EXISTS(SELECT * FROM #EXISTSTB)
                       BEGIN
                               DECLARE @RunSQL NVARCHAR(MAX)
                               DECLARE CURSYNC CURSOR FOR
                               SELECT Script FROM @TempTable ORDER BY id
                               
                               OPEN CURSYNC
                               FETCH NEXT FROM CURSYNC INTO @RunSQL
                               
                               WHILE @@FETCH_STATUS = 0
                               BEGIN 
                                        SET @DynamicSQL = 'EXEC('+ @RunSQL + ') AT ['+ @LinkedServerName +']'
                                        EXEC sp_executesql @DynamicSQL;
                               
                                   FETCH NEXT FROM CURSYNC INTO @RunSQL
                               END;
                               
                               CLOSE CURSYNC
                               DEALLOCATE CURSYNC
                       END
                       DROP TABLE #EXISTSTB
               
                   FETCH NEXT FROM cursor_linked_servers INTO @LinkedServerName;
               END;
               
               -- close cursor
               CLOSE cursor_linked_servers;
               DEALLOCATE cursor_linked_servers;
      
      END
        
END

?

?step3: 創(chuàng)建作業(yè)定時(shí)執(zhí)行上面的存儲過程,在所有AlwaysOn節(jié)點(diǎn)上創(chuàng)建作業(yè),記住是所有AlwaysOn節(jié)點(diǎn)都要執(zhí)行,下面腳本默認(rèn)是60分鐘執(zhí)行一次

USE [msdb]
GO

/****** Object:  Job [synchronize_loginusers]    Script Date: 2023/9/6 15:46:26 ******/
BEGIN TRANSACTION
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
/****** Object:  JobCategory [Database Maintenance]    Script Date: 2023/9/6 15:46:26 ******/
IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'Database Maintenance' AND category_class=1)
BEGIN
EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'Database Maintenance'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback

END

DECLARE @jobId BINARY(16)
EXEC @ReturnCode =  msdb.dbo.sp_add_job @job_name=N'synchronize_loginusers', 
        @enabled=1, 
        @notify_level_eventlog=0, 
        @notify_level_email=0, 
        @notify_level_netsend=0, 
        @notify_level_page=0, 
        @delete_level=0, 
        @description=N'Synchronize login users between SQL Server Instances', 
        @category_name=N'Database Maintenance', 
        @owner_login_name=N'sa', @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/****** Object:  Step [execute SyncLoginUsers script]    Script Date: 2023/9/6 15:46:26 ******/
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'execute SyncLoginUsers script', 
        @step_id=1, 
        @cmdexec_success_code=0, 
        @on_success_action=1, 
        @on_success_step_id=0, 
        @on_fail_action=2, 
        @on_fail_step_id=0, 
        @retry_attempts=0, 
        @retry_interval=0, 
        @os_run_priority=0, @subsystem=N'TSQL', 
        @command=N'exec [master].[dbo].[usp_SyncLoginUserRegularBetweenInstances] ', 
        @database_name=N'master', 
        @flags=0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'Schedule SyncLoginUsers', 
        @enabled=1, 
        @freq_type=4, 
        @freq_interval=1, 
        @freq_subday_type=4, 
        @freq_subday_interval=60, 
        @freq_relative_interval=0, 
        @freq_recurrence_factor=0, 
        @active_start_date=20110224, 
        @active_end_date=99991231, 
        @active_start_time=200, 
        @active_end_time=235959, 
        @schedule_uid=N'563258f6-0b3f-47bf-b9b3-2f597038cc38'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
    IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:

GO
 

所有步驟完畢

?

?

對于這個(gè)自動(dòng)定時(shí)同步登錄用戶腳本有以下說明

本工具腳本遵循的思想是,不做減法,只做加法,盡可能減少對線上生產(chǎn)環(huán)境影響,主要有下面幾點(diǎn):

(1)新增用戶:如果從庫不存在同步過來的用戶,就新建用戶

(2)更新用戶:如果從庫存在同步過來的用戶,就會判斷用戶SID和用戶密碼是否一樣,如果用戶SID一樣,密碼不一樣,就更新用戶密碼

(3)刪除用戶:如果從庫存在同名用戶,就不新建用戶,否則新建用戶,為了盡可能減少對線上生產(chǎn)環(huán)境影響,不做刪除用戶操作,所以如果從庫存在同名用戶并且用戶SID不同,建議手動(dòng)刪除用戶由腳本自動(dòng)同步主庫用戶過來

?無論是新增用戶還是更新用戶,都會執(zhí)行添加服務(wù)器角色權(quán)限的步驟,如果同名用戶已經(jīng)存在當(dāng)前服務(wù)器角色權(quán)限,那么再次執(zhí)行添加服務(wù)器角色權(quán)限并不會有任何影響,而且本工具腳本并不會刪除同名用戶的服務(wù)器角色權(quán)限

最終目的:不做減法,只做加法,盡可能減少對線上生產(chǎn)環(huán)境影響

?

?

對于這個(gè)自動(dòng)定時(shí)同步登錄用戶腳本有下面幾個(gè)注意點(diǎn)

1、本工具腳本使用sa用戶來創(chuàng)建鏈接服務(wù)器,所以不會同步sa用戶,注意如果更改了sa用戶密碼,也要同步更改鏈接服務(wù)器密碼,當(dāng)然您也可以使用其他有足夠權(quán)限的用戶來創(chuàng)建鏈接服務(wù)器

2、新建登錄用戶的時(shí)候,一定要確保在主庫上新建登錄用戶,否則可能會無法實(shí)施數(shù)據(jù)庫角色權(quán)限或者無法同步該登錄用戶

3、新建登錄用戶時(shí)候,登錄用戶名不要帶有特殊字符,例如單引號,否則差異腳本有可能不work

4、這個(gè)腳本是針對AlwaysOn集群,當(dāng)然如果你是數(shù)據(jù)庫鏡像環(huán)境,你可以改一下代碼,把判斷AlwaysOn主庫的部分改為判斷鏡像主庫就可以了

5、如果對登錄用戶同步延遲有要求,那么可以修改作業(yè)執(zhí)行頻率,默認(rèn)是60分鐘執(zhí)行一次


?

?

參考文章
https://maq.guru/synchronizing-sql-server-logins-in-an-always-on-availability-group/

https://www.jb51.net/article/282734.htm

?

本文版權(quán)歸作者所有,未經(jīng)作者同意不得轉(zhuǎn)載。文章來源地址http://www.zghlxwxcb.cn/news/detail-706339.html

到了這里,關(guān)于SQL Server實(shí)例間同步登錄用戶的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • SQL Server2019安裝后使用SQL Server身份驗(yàn)證登錄失敗

    SQL Server2019安裝后使用SQL Server身份驗(yàn)證登錄失敗

    今天在電腦安裝SQL Server2019和SMMS,安裝過程一切順利,但是在使用SMMS連接數(shù)據(jù)庫時(shí)出現(xiàn)了異常。使用\\\"Window 身份驗(yàn)證\\\"登錄時(shí)正常,但是如果改為使用\\\"SQL Server 身份驗(yàn)證\\\"登錄時(shí)卻連接失??! 1.先使用\\\"Window 身份驗(yàn)證\\\"連接數(shù)據(jù)庫 2.右鍵點(diǎn)擊連接,選擇\\\"屬性\\\" 3.選擇\\\"安全性\\\",將

    2024年02月12日
    瀏覽(95)
  • 超細(xì),設(shè)計(jì)一個(gè)“完美“的測試用例,用戶登錄模塊實(shí)例...

    好的測試用例一定是一個(gè)完備的集合,它能夠覆蓋所有等價(jià)類以及各種邊界值,而跟能否發(fā)現(xiàn)缺陷無關(guān) 好的測試用例必須具備哪些特征 整體完備性:一定是一個(gè)完備的整體,是有效測試用例組成的集合,能夠完全覆蓋測試需求 等價(jià)類劃分的準(zhǔn)確性:對于每個(gè)等價(jià)類都能保證

    2024年02月17日
    瀏覽(17)
  • MongoDB 6.0 單實(shí)例基于用戶角色實(shí)現(xiàn)授權(quán)登錄

    現(xiàn)代數(shù)據(jù)庫系統(tǒng)能夠存儲和處理大量數(shù)據(jù)。因此,由任何一個(gè)用戶單獨(dú)負(fù)責(zé)處理與管理數(shù)據(jù)庫相關(guān)的所有活動(dòng)的情況相對較少。通常,不同的數(shù)據(jù)庫用戶需要對數(shù)據(jù)庫的某些部分具有不同級別的訪問權(quán)限:某些用戶可能只需要讀取特定數(shù)據(jù)庫中的數(shù)據(jù),而其他用戶則必須能夠

    2024年02月05日
    瀏覽(17)
  • SQL Server創(chuàng)建用戶并且為用戶授權(quán)

    SQL Server創(chuàng)建用戶并且為用戶授權(quán)

    右鍵點(diǎn)擊登錄名→新建登錄名 進(jìn)入【服務(wù)器角色】在右側(cè)的服務(wù)器角色面板中,勾選public 服務(wù)器角色 說明 sysadmin 執(zhí)行SQL Server中的任何操作 serveradmin 配置服務(wù)器設(shè)置 setupadmin 安裝復(fù)制和管理擴(kuò)展過程 securityadmin 管理登錄和CREATE DATABASE的權(quán)限以及閱讀審計(jì) processadmin 管理SQL Se

    2024年02月10日
    瀏覽(33)
  • SQL Server 創(chuàng)建用戶,用戶授權(quán),實(shí)驗(yàn)報(bào)告

    SQL Server 創(chuàng)建用戶,用戶授權(quán),實(shí)驗(yàn)報(bào)告

    首先我們得有一個(gè)數(shù)據(jù)庫,數(shù)據(jù)庫里有表 職工表: ?部門表: 接下來的操作都是針對以上的表 其次我們來建立登錄用戶 登錄名 為王明, 密碼 為123456. 創(chuàng)建登錄名之后,登錄用戶還不能對數(shù)據(jù)庫進(jìn)行操作,還要對登錄用戶創(chuàng)建數(shù)據(jù)庫用戶 這時(shí)候登錄王明的賬戶,數(shù)據(jù)庫會自

    2024年02月04日
    瀏覽(32)
  • Sql Server 登錄錯(cuò)誤:18456

    Sql Server 登錄錯(cuò)誤:18456

    Sql Server 安裝后使用Sql Server身份驗(yàn)證登錄。出現(xiàn)錯(cuò)誤:18456。如下圖所示: 1,使用Windows驗(yàn)證登錄,進(jìn)入登錄名,右鍵點(diǎn)擊sa,點(diǎn)擊屬性。 2,設(shè)置登錄名是否啟用,和是否允許鏈接到數(shù)據(jù)引擎。 3,右鍵數(shù)據(jù)庫連接選擇屬性,設(shè)置安全性中的服務(wù)器什么驗(yàn)證。 4,點(diǎn)擊左下角的

    2024年02月13日
    瀏覽(18)
  • Windows Server 程序設(shè)置自啟動(dòng)(用戶不登錄)

    Windows Server 程序設(shè)置自啟動(dòng)(用戶不登錄) 在Windows Server中,想要在系統(tǒng)啟動(dòng)時(shí)自動(dòng)啟動(dòng)一個(gè)程序,但不依賴用戶登錄,可以使用以下幾種方法: 將程序添加為服務(wù) 這是Windows Server中最標(biāo)準(zhǔn)的方法??梢允褂胹c.exe命令行工具或者Win+R運(yùn)行→services.msc服務(wù)管理控制臺來設(shè)置一個(gè)程序作

    2023年04月25日
    瀏覽(12)
  • SQL server 數(shù)據(jù)庫同步(發(fā)布與訂閱)【解決辦法】

    SQL server 數(shù)據(jù)庫同步(發(fā)布與訂閱)【解決辦法】

    注意:所有連接數(shù)據(jù)庫操作時(shí)注意連接的數(shù)據(jù)庫是否在所選服務(wù)器上 ![在這里插入圖片描述](https://img-blog.csdnimg.cn/38812acbb640420b89ba666dd016adb8.png) 在 發(fā)布服務(wù)器 和 訂閱服務(wù)器 本地防火墻放通1433端口 參考 【操作方法】windows防火墻添加出入站規(guī)則方法 此處選擇影響代理管理位

    2024年02月16日
    瀏覽(21)
  • 【遠(yuǎn)程連接 多個(gè)SQL SERVER數(shù)據(jù)庫實(shí)例】

    【遠(yuǎn)程連接 多個(gè)SQL SERVER數(shù)據(jù)庫實(shí)例】

    在公司電腦上同時(shí)安裝了SQL SERVER2012和SQL SERVER2019,分別設(shè)置了不同的實(shí)例,現(xiàn)用VPN連接公司電腦上的兩個(gè)數(shù)據(jù)庫實(shí)例,做一些記錄。 如圖所示,分別有MSSQLSERVER2012與MSSQLSERVER2019兩個(gè)不同的實(shí)例,分別查看實(shí)例對應(yīng)的TCP/IP 為數(shù)據(jù)庫引擎訪問配置 Windows 防火墻 - SQL Server | Micro

    2024年02月07日
    瀏覽(27)
  • “目前沒有可用的登錄服務(wù)器處理登錄請求”停用的Windows Server 2008 R2服務(wù)器改域用戶登錄為本地用戶登錄

    “目前沒有可用的登錄服務(wù)器處理登錄請求”停用的Windows Server 2008 R2服務(wù)器改域用戶登錄為本地用戶登錄

    這兩天公司要那臺下線有段時(shí)間的老服務(wù)器里的數(shù)據(jù),WinServer08搭建的,頭一次接觸域控制器(安裝了活動(dòng)目錄的主機(jī)稱為域控制器,域控制器控制每個(gè)域)這個(gè)東西,打開之前備份的虛擬機(jī),通過域用戶登錄的時(shí)候報(bào)錯(cuò)如下,有點(diǎn)懵逼。 聯(lián)系資源池的老師打開虛擬機(jī)遠(yuǎn)程連

    2024年02月05日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包