关于sqlserver always on群集创建登录名和数据库用户名丢失关联

news/2024/7/24 11:42:07 标签: sqlserver

最近部署遇到一个问题,在always on 群集主节点用ssms工具创建登录名,然后故障故障转移到从节点创建登录名,用
sp_change_users_login 关联后,先前主节点登录名和数据库用户名就会丢失关联,这样集群就会有问题

经调查,sqlserver 的登录名和用户名是用sid关联的,调查如下
1.主节点1创建一个登录名,如图,查询登录名和用户的sid是相同的
在这里插入图片描述
2.然后故障转移到节点2,在节点2创建登录名,即使创建登录名称和数据库用户一致,但是sid却不一致,所以二者并不关联
exec sp_change_users_login ‘UPDATE_ONE’,‘用户名’,‘登录名’ 使得节点2登录名和数据库用户名一致,此时数据库用户名的sid 改成节点2的登录名的sid,节点1数据库用户名sid被覆盖 二者关联上
在这里插入图片描述
3这时查看节点1的信息,登录名sid 和数据库用户名sid 丢失关联,这就导致每次故障转移,就会丢失二者关联,导致sqlserver无法登录
在这里插入图片描述

解决:
1.在主节点执行以下sqlserver 存储过程

/*
--SQL 数据库导出迁移用户账户及权限
--EG. [sp_help_revlogin]
*/

--sp_hexadecimal
   USE master
GO
IF OBJECT_ID ('sp_hexadecimal') IS NOT NULL
  DROP PROCEDURE sp_hexadecimal
GO
CREATE PROCEDURE sp_hexadecimal
    @binvalue varbinary(256),
    @hexvalue varchar(256) OUTPUT
AS
DECLARE @charvalue varchar(256)
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
GO

----- sp_help_revlogin

IF OBJECT_ID ('sp_help_revlogin') IS NOT NULL
  DROP PROCEDURE sp_help_revlogin
GO
CREATE PROCEDURE [dbo].[sp_help_revlogin] @login_name sysname = NULL AS  
    DECLARE @name sysname  
    DECLARE @type varchar (1)  
    DECLARE @hasaccess int  
    DECLARE @denylogin int  
    DECLARE @is_disabled int  
    DECLARE @PWD_varbinary  varbinary (256)  
    DECLARE @PWD_string  varchar (514)  
    DECLARE @SID_varbinary varbinary (85)  
    DECLARE @SID_string varchar (514)  
    DECLARE @tmpstr  varchar (1024)  
    DECLARE @is_policy_checked varchar (3)  
    DECLARE @is_expiration_checked varchar (3)  
    DECLARE @defaultdb sysname  
    IF (@login_name IS NULL)  
    DECLARE login_curs CURSOR FOR  
    SELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM  
    sys.server_principals p LEFT JOIN sys.syslogins l  
    ON ( l.name = p.name ) WHERE p.type IN ( 'S', 'G', 'U' ) AND p.name <> 'sa'  
    ELSE  
    DECLARE login_curs CURSOR FOR  
    SELECT p.sid, p.name, p.type, p.is_disabled, p.default_database_name, l.hasaccess, l.denylogin FROM  
    sys.server_principals p LEFT JOIN sys.syslogins l  
    ON ( l.name = p.name ) WHERE p.type IN ( 'S', 'G', 'U' ) AND p.name = @login_name  
    OPEN login_curs  
    FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denylogin  
    IF (@@fetch_status = -1)  
    BEGIN  
    PRINT 'No login(s) found.'  
    CLOSE login_curs  
    DEALLOCATE login_curs  
    RETURN -1  
    END  
    SET @tmpstr = '/* sp_help_revlogin script '
    PRINT @tmpstr  
    SET @tmpstr = '** Generated ' + CONVERT (varchar, GETDATE()) + ' on ' + @@SERVERNAME + ' */'  
    PRINT @tmpstr  
    PRINT ''  
    WHILE (@@fetch_status <> -1)  
    BEGIN  
    IF (@@fetch_status <> -2)  
    BEGIN  
    PRINT ''  
    SET @tmpstr = '-- Login: ' + @name  
    PRINT @tmpstr  
    IF (@type IN ( 'G', 'U'))  
    BEGIN -- NT authenticated account/group  
    SET @tmpstr = 'CREATE LOGIN ' + QUOTENAME( @name ) + ' FROM WINDOWS WITH DEFAULT_DATABASE = [' + @defaultdb + ']'  
    END  
    ELSE BEGIN -- SQL Server authentication
    SET @PWD_varbinary = CAST( LOGINPROPERTY( @name, 'PasswordHash' ) AS varbinary (256) )  
    EXEC sp_hexadecimal @PWD_varbinary, @PWD_string OUT  
    EXEC sp_hexadecimal @SID_varbinary,@SID_string OUT
   SELECT @is_policy_checked = CASE is_policy_checked WHEN 1 THEN 'ON' WHEN
0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE name = @name  

    SELECT @is_expiration_checked = CASE is_expiration_checked WHEN 1 THEN 'ON' WHEN
0 THEN 'OFF' ELSE NULL END FROM sys.sql_logins WHERE name = @name  

    SET @tmpstr = 'CREATE LOGIN ' + QUOTENAME( @name ) + ' WITH PASSWORD = ' + @PWD_string + ' HASHED,
    SID = ' + @SID_string + ', DEFAULT_DATABASE = [' + @defaultdb + ']'  

    IF ( @is_policy_checked IS NOT NULL )  
    BEGIN  
    SET @tmpstr = @tmpstr + ', CHECK_POLICY = ' + @is_policy_checked  
    END  
    IF ( @is_expiration_checked IS NOT NULL )  
    BEGIN  
    SET @tmpstr = @tmpstr + ', CHECK_EXPIRATION = ' + @is_expiration_checked  
    END  
    END  
    IF (@denylogin = 1)  
    BEGIN -- login is denied access  
    SET @tmpstr = @tmpstr + '; DENY CONNECT SQL TO ' + QUOTENAME( @name )  
    END  
    ELSE IF (@hasaccess = 0)  
    BEGIN -- login exists but does not have access  
    SET @tmpstr = @tmpstr + '; REVOKE CONNECT SQL TO ' + QUOTENAME( @name )  
    END  
    IF (@is_disabled = 1)  
    BEGIN -- login is disabled  
    SET @tmpstr = @tmpstr + '; ALTER LOGIN ' + QUOTENAME( @name ) + ' DISABLE'  
    END  
    PRINT @tmpstr  
    END  
    FETCH NEXT FROM login_curs INTO @SID_varbinary, @name, @type, @is_disabled, @defaultdb, @hasaccess, @denylogin  
    END  
    CLOSE login_curs  
    DEALLOCATE login_curs  
    RETURN 0

2.在主节点执行存储过程,选择自己创建的用户
exec sp_help_revlogin
在这里插入图片描述

3.在从节点创建执行sql
在这里插入图片描述


http://www.niftyadmin.cn/n/1332315.html

相关文章

朋友入职中软一个月(外包华为)就离职了!

点击上方 果汁简历 &#xff0c;选择“置顶公众号”优质文章&#xff0c;第一时间送达我在年前从上一家公司离职&#xff0c;没想到过年期间疫情爆发&#xff0c;我也被困在家里&#xff0c;在家呆着的日子让人很焦躁&#xff0c;于是我疯狂的投简历&#xff0c;看面试题&#…

navicat 连接sqlsever报错:客户端不支持加密/encryption not supported on the client

最近navicat 连接sqlserver 突然连接不上了&#xff0c;telnet sqlserver端口能通 报错如下&#xff1a; 这种情况一般是navicat的sqlserver客户端损坏了&#xff0c;所以需要将客户端卸载&#xff0c;重装 打开windows 卸载程序 然后重新连接sqlserver &#xff0c;会让你重…

抖音创始人张一鸣:10 年面试 2000 人,我发现混的好的人,全都有同一个特质...

作者&#xff1a;张一鸣来源&#xff1a;字节范儿&#xff08;ID&#xff1a;Bytedancer&#xff09;01为何毕业多年后&#xff0c;原本水平差不多的同学都拉开了差距&#xff1f;大家好&#xff01;各位都非常年轻&#xff0c;我今天来的时候挺有压力。因为我毕业快11年了&…

windows 下日志切割,清理

基础软件和服务都会产生日志&#xff0c;当日志太多就会占用磁盘空间&#xff0c;因此需要定期清除&#xff0c;windows通常使用bat脚本处理 一&#xff1a;日志切割&#xff1a; 1.windows脚本&#xff0c;以nginx 为例 echo off c: set nginx%C:\Users\Lenovo\Desktop% set …

AI工程师面试宝典到手,开启有房有车有mm人生

在二十多岁的年纪里&#xff0c;在车水马龙的城市中&#xff0c;你是那个人生规划成功的人还是刷着“成功学”视频的迷茫者&#xff1f;无法实现财务自由&#xff0c;为了房租紧衣缩食&#xff0c;你在大城市里拼命打拼&#xff0c;你不敢生病&#xff0c;却喝着速溶的咖啡加着…

java服务的日志生成,切割

在配置文件中加入&#xff1a; logging.configclasspath:logback-spring.xml 在resources下创logback-spring.xml 可以实现控制台日志写入文件中&#xff0c;记录日志 <?xml version"1.0" encoding"UTF-8"?><!-- 日志级别从低到高分为TRACE &l…

永远不要在代码中使用「User」这个单词!

当你意识到你在项目开始时做的轻量、简单的设想竟然完全错了时&#xff0c;你已经用了六个月的时间投入到这个项目上。现在你需要解决这些问题&#xff0c;才能让这个系统继续运行下去&#xff0c;你发现你用在这个项目上的精力远远超出了你的预期&#xff0c;如果一开始就用正…

dkron定时任务系统:certificate signed by unknown authority X509

dkron 定时任务系统在请求https 时&#xff0c;日志报错&#xff1a;certificate signed by unknown authority 因为dkron默认开启证书认证&#xff0c;需要在配置文件executor_config中配置&#xff1a; tlsNoVerifyPeer&#xff1a;true 如果为true&#xff0c;则禁用对远程S…