AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 29903
Accepted
John
John
Asked: 2012-12-06 15:41:42 +0800 CST2012-12-06 15:41:42 +0800 CST 2012-12-06 15:41:42 +0800 CST

Os logins não estão sendo sincronizados entre os grupos de disponibilidade

  • 772

Temos 2 servidores em um grupo AlwaysOn.

Embora as contas de usuário em cada banco de dados sincronizado existam em ambos os servidores, os logons no nível da instância do banco de dados só existem em um dos servidores. Ou seja, DBINSTANCE->Security->Logins estão faltando em um servidor.

Portanto, quando há um failover, recebo falhas de login no segundo servidor (que não possui os logins de nível de instância correspondentes).

Como faço para superar este problema? Eu deveria configurar a conta de usuário de uma maneira especial?

sql-server sql-server-2012
  • 4 4 respostas
  • 27171 Views

4 respostas

  • Voted
  1. Mark Storey-Smith
    2012-12-06T16:01:21+08:002012-12-06T16:01:21+08:00

    Meu entendimento é que, se você não estiver usando Bancos de Dados Contidos , precisará garantir que os logins sejam criados manualmente em outras instâncias.

    Algo como o script do SQLSoldier , publicado originalmente no artigo Transferindo logins para um espelho de banco de dados , deve funcionar.

    • 15
  2. Best Answer
    John
    2012-12-07T07:46:14+08:002012-12-07T07:46:14+08:00

    Você deve usar um Banco de Dados Contido ou deve recriar os usuários no(s) outro(s) servidor(es) com o mesmo hash de senha e SID.

    Um script para fazer isso é fornecido pela Microsoft: Como transferir logins e senhas entre instâncias do SQL Server

    A solução de Mark estava parcialmente correta, mas sua solução recomendada era para bancos de dados espelhados, em oposição ao AlwaysOn, que é o que as perguntas pedem.

    • 7
  3. Muhammad
    2018-04-20T09:43:37+08:002018-04-20T09:43:37+08:00

    Estou respondendo ao post depois de muito tempo, mas pode ajudar alguém com o problema semelhante. O PowerShell pode ser usado para copiar logons da réplica primária para réplicas secundárias. Os detalhes podem ser encontrados aqui https://maq.guru/synchronizing-sql-server-logins-in-an-always-on-availability-group/ .

    Divulgação completa: Eu possuo o site acima.

    O script do PowerShell:

    $Conn=New-Object System.Data.SqlClient.SQLConnection
    $QueryTimeout = 120
    $ConnectionTimeout = 30
    
    ###########################################################
    # Execute Query function 
    ###########################################################
    Function executequery($Query, $QueryTimeout, $ServerName)
    {
        $Datatable = New-Object System.Data.DataTable
        $ConnectionString = "Server={0};Database={1};Integrated Security=True;Connect Timeout={2}" -f $ServerName,$Database,$ConnectionTimeout
        $Conn.ConnectionString=$ConnectionString
        $Cmd=New-Object system.Data.SqlClient.SqlCommand($Query,$Conn)
        $Cmd.CommandTimeout=$QueryTimeout
    
                do
                    {   
                        $Conn.Open()
                        Start-Sleep -Seconds 2
                    }while ($Conn.State -ne 'Open')
    
                $Reader = $cmd.ExecuteReader()
                $Datatable.Load($Reader)
                $Conn.Close()
                return $Datatable    
    }
    
    
    ###########################################################
    # Create spHexaDecimal Stored Procedure
    ###########################################################
    
    Function CreatespHexaDecimal ($ServerName)
        {
        $Query='USE [master];
                    GO
                    SET ANSI_NULLS ON;
                    GO
                    SET QUOTED_IDENTIFIER ON;
                    GO
                    CREATE PROCEDURE [dbo].[spHexaDecimal]
                    (
                        @BinValue VARBINARY(256)
                        , @HexValue VARCHAR(514) OUTPUT
                    )
                    AS
    
                    DECLARE @CharValue VARCHAR(514)
                    DECLARE @i INT
                    DECLARE @Length INT
                    DECLARE @HexString CHAR(16)
    
                    SET @CharValue = ''0x''
                    SET @i = 1
                    SET @Length = DATALENGTH(@BinValue)
                    SET @HexString = ''0123456789ABCDEF''
    
                    WHILE (@i <= @Length)
                    BEGIN
    
                        DECLARE @TempInt INT
                        DECLARE @FirstInt INT
                        DECLARE @SecondInt INT
    
                        SET @TempInt = CONVERT(INT, SUBSTRING(@BinValue, @i, 1))
                        SET @FirstInt = FLOOR(@TempInt/16)
                        SET @SecondInt = @TempInt - (@FirstInt * 16)
                        SET @CharValue = @CharValue 
                                            + SUBSTRING(@HexString, @FirstInt + 1, 1)
                                            + SUBSTRING(@HexString, @SecondInt + 1, 1)
    
                        SET @i = @i + 1
    
                    END --WHILE (@i <= @Length)
    
                    SET @HexValue = @CharValue'
    
                    Invoke-Sqlcmd -Query $Query -ServerInstance $ServerName
        }
    
    
    ###########################################################
    # CheckStroedProc 
    ###########################################################
    
    Function CheckStoredProc ($Server)
    {
        $Query= 'SELECT 1 AS ExistCheck
                 FROM   sysobjects 
                 WHERE  id = object_id(N''[dbo].[spHexaDecimal]'') 
                     AND OBJECTPROPERTY(id, N''IsProcedure'') = 1 '
    
        $Result=executequery $Query $QueryTimeout $Server
        $Exist=$Result | SELECT -ExpandProperty ExistCheck
        IF ($Exist -ne 1)
            {
                CreatespHexaDecimal -ServerName $Server
            }
    }
    
    ###########################################################
    # Get Login Script
    ###########################################################
    
    Function Get-Script ($Server)
    {
    
    $Query='DECLARE @TempTable TABLE
    (Script NVARCHAR(MAX))
    DECLARE @Login NVARCHAR (MAX)
    DECLARE CURLOGIN CURSOR FOR
    SELECT name 
    FROM sys.server_principals
    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(500)= @Login
        DECLARE @LoginSID VARBINARY(85)
        DECLARE @SID_String VARCHAR(514)
        DECLARE @LoginPWD VARBINARY(256)
        DECLARE @PWD_String VARCHAR(514)
        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
    
        /** Some Output **/
        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 spHexaDecimal @LoginPWD, @PWD_String OUT   
            EXEC spHexaDecimal @LoginSID, @SID_String OUT
    
            SELECT @is_policy_checked = S.is_policy_checked
                , @is_expiration_checked = S.is_expiration_checked
            FROM sys.sql_logins S
    
            /** Create Script **/
            SET @Script = @Script + CHAR(13) + CHAR(13)
                            + ''IF EXISTS (SELECT name FROM sys.server_principals WHERE name= ''''''+ @LoginName + '''''') '' 
                            + CHAR(13) + '' BEGIN ''
                            + CHAR(13) + CHAR(9) + '' ALTER LOGIN '' + QUOTENAME(@LoginName)
                            + CHAR(13) + CHAR(9) + ''WITH PASSWORD = '' + @PWD_String + '' HASHED''
                            + 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 ''
                            + CHAR(13) + ''ELSE''
                            + CHAR(13) + '' BEGIN ''
                            + 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(85)
            )
    
        INSERT INTO @ServerRoles EXEC sp_helpsrvrolemember
    
        --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, '''''''') + '', '' + QUOTENAME(@ServerRole, '''''''')
    
                FETCH NEXT FROM curRoles
                INTO @ServerRole
    
            END
    
            --Cleanup.
            CLOSE curRoles
            DEALLOCATE curRoles
    
        END
        INSERT INTO @TempTable
        VALUES(@Script)
    
        FETCH NEXT FROM CURLOGIN INTO @Login
    END
    CLOSE CURLOGIN;
    DEALLOCATE CURLOGIN;
    SELECT Script FROM @TempTable'
    
    $Result=executequery $Query $QueryTimeout $Server
    
    If($Result -eq $null)
        {
            break
        }
    Else
        {
            [Void][System.IO.Directory]::CreateDirectory("C:\temp")
            $Path = "C:\temp"
            $Acl = (Get-Item $Path).GetAccessControl('Access')
            $Username = Get-WmiObject win32_service | Where name -EQ 'SQLSERVERAGENT' | Select -ExpandProperty StartName
            $Ar = New-Object System.Security.AccessControl.FileSystemAccessRule($Username, 'Full', 'ContainerInherit,ObjectInherit', 'None', 'Allow')
            $Acl.SetAccessRule($Ar)
            Set-Acl -path $Path -AclObject $Acl
            $Result | select -ExpandProperty Script | Out-File C:\temp\Script.txt
        }
    }
    
    
    ###########################################################
    # SCRIPT BODY 
    ###########################################################
    
    $Query= "SELECT ISNULL(SERVERPROPERTY ('InstanceName'), 'DEFAULT') InstanceName 
                , name AGName
                , replica_server_name Replica
                , role_desc 
                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 role_desc = 'PRIMARY'
                ORDER BY role_desc asc"
    Write-Host "Is this Primary Replica?"
    $Result=executequery $Query $QueryTimeout $PrimaryReplica
    If ($Result -eq $null)
        {
            Write-Host "No, it's not."
            break
        }
    Else
        {
            Write-Host "Yes, it is."
            $PrimaryReplica= $Result | select -ExpandProperty Replica
            Write-Host "Check for prerequisite, if not present deploy it."
            CheckStoredProc -Server $PrimaryReplica
            Write-Host "Get script for new/modifies login(s)."
            Get-Script -Server $PrimaryReplica
    
            $Query= "SELECT ISNULL(SERVERPROPERTY ('InstanceName'), 'DEFAULT') InstanceName 
                        , name AGName
                        , replica_server_name Replica
                        , role_desc 
                        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 role_desc = 'SECONDARY'
                        ORDER BY role_desc asc"
    
            $Result=executequery $Query $QueryTimeout $PrimaryReplica
            $SecondaryReplicas= $Result | select -ExpandProperty Replica
            $Query= Get-Content -Path 'C:\temp\Script.txt' | Out-String
            ForEach($SecondaryReplica in $SecondaryReplicas)
                {
                    Invoke-Sqlcmd -Query $Query -ServerInstance $SecondaryReplica
                    Write-Host "Successfully copied login(s) to $SecondaryReplica"
                }
            Remove-Item C:\temp\Script.txt
        }
    
    • 1
  4. user70509
    2015-07-14T10:52:48+08:002015-07-14T10:52:48+08:00

    Você deve usar os logins de domínio do Windows e criá-los em todas as instâncias, como o SID é gerenciado pelo Active Directory você poderá acessar em todas as réplicas membros do grupo de disponibilidade caso o login exista na réplica primária. outra opção, você deve usar um certificado.

    • -1

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como ver a lista de bancos de dados no Oracle?

    • 8 respostas
  • Marko Smith

    Quão grande deve ser o mysql innodb_buffer_pool_size?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    restaurar a tabela do arquivo .frm e .ibd?

    • 10 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Como selecionar a primeira linha de cada grupo?

    • 6 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve