लॉगिन उपलब्धता समूहों में समन्वयित नहीं कर रहे हैं


13

हमारे पास एक ऑल्टरऑन समूह में 2 सर्वर हैं।

जबकि प्रत्येक सिंक्रनाइज़ किए गए डेटाबेस में उपयोगकर्ता खाते दोनों सर्वरों पर मौजूद होते हैं, डेटाबेस आवृत्ति स्तर लॉगिन केवल एक सर्वर पर मौजूद होते हैं। यानी DBINSTANCE-> सुरक्षा-> एक सर्वर पर लॉगिन गायब हैं।

इसलिए जब कोई विफलता होती है, तो मुझे दूसरे सर्वर पर लॉगिन विफलता मिलती है (जिसमें संबंधित उदाहरण स्तर लॉगिन नहीं होता है)।

मैं इस मुद्दे को कैसे दूर करूं? क्या मैं उपयोगकर्ता खाते को एक विशेष तरीके से स्थापित करने वाला था?


मैं इस एक में हाल ही में भी तलाश शुरू कर दी, मैं अपने ही उपलब्ध कराई गई और वर्तमान में अपने ब्रांड के नए ब्लॉग में यह वर्णन कर रहा हूँ (ज्यादातर अपने ही लाभ के लिए के रूप में मैं आगे जाने के लिए और चीजों को भूल जाते हैं, लेकिन अगर दूसरों के लिए मदद की अपने सभी बेहतर) जीवन -और-dev.blogspot.co.uk/2015/04// यह और निम्नलिखित दंपति ऑल्वेज़ फ़ेलओवर ट्रैकिंग और जॉब / यूज़र सिंकिंग

आप sqlskills से SSMS प्लगइन का उपयोग कर सकते हैं उपलब्धता समूह लॉगिन और नौकरियां सिंक्रनाइज़ करें
Kin Shah

जवाबों:


15

मेरी समझ यह है कि यदि आप कन्‍टर्ड डेटाबेस का उपयोग नहीं कर रहे हैं , तो आपको यह सुनिश्चित करना होगा कि लॉग ऑन मैन्युअल रूप से अन्य इंस्टेंस पर बनाए जाएं।

SQLSoldier की इस स्क्रिप्ट की तरह कुछ , मूल रूप से एक डेटाबेस मिरर को ट्रांसफ़रिंग लॉगिन के रूप में पोस्ट किया गया है , को ट्रिक करना चाहिए।


एक बार हम अगले या दो सप्ताह में '12 पर स्विच करते हुए अपने कई प्रोडक्शन '05 डेटाबेस को नए निहित प्रारूप में बदलने की आशा कर रहे हैं। इस बीच, मैं द्वितीयक उदाहरण के लिए, लॉगिन, नौकरी आदि की प्रतिलिपि बनाने के लिए इडेरा के उपकरणों का उपयोग कर रहा हूं।
मैक्स वेरनॉन

निशान सही है, आपको या तो निहित डेटाबेस का उपयोग करने की आवश्यकता होगी या मैन्युअल रूप से सभी उदाहरणों पर एक ही SID का उपयोग करके क्लस्टर में सभी इंस्टेंस पर लॉगिन की प्रतिलिपि बनाने की आवश्यकता होगी।
मृन्नी

ध्यान रखें कि मैं ऑल्वो ऑन के बारे में पूछ रहा हूं, मिररिंग नहीं। मैंने स्क्रिप्ट की कोशिश की, हालांकि sys.servers तालिका में केवल स्थानीय सर्वर शामिल है, इसलिए मुझे संग्रहीत कार्यविधि चलाने पर निम्न त्रुटि मिलती है: Msg 7202, Level 11, State 2, Line 1 Could not find server 'otherserver' in sys.servers. Verify that the correct server name was specified. If necessary, execute the stored procedure sp_addlinkedserver to add the server to sys.servers.
John

मैंने इसे समझ लिया और ऑल्टरऑन के लिए उपयुक्त एक नया उत्तर पोस्ट किया।
जॉन

@ जॉनोह्यूज यह स्क्रिप्ट ऑल्वेज़ऑन के लिए उपयुक्त है। हालाँकि, आपको त्रुटि संदेश द्वारा इंगित किया गया है, उदाहरणों के बीच एक लिंक किए गए सर्वर को बनाने की आवश्यकता है।
मार्क स्टोरी-स्मिथ

7

आपको या तो एक नियंत्रित डेटाबेस का उपयोग करना चाहिए, या आपको उसी पासवर्ड हैश और SID के साथ अन्य सर्वर (ओं) पर उपयोगकर्ताओं को फिर से बनाना होगा।

ऐसा करने के लिए एक स्क्रिप्ट Microsoft द्वारा प्रदान की जाती है: SQL सर्वर के उदाहरणों के बीच लॉगिन और पासवर्ड कैसे स्थानांतरित करें

मार्क का समाधान आंशिक रूप से सही था लेकिन उसका अनुशंसित समाधान मिररड डेटाबेस के लिए था, ऑल्टरऑन के विपरीत, जो कि प्रश्न पूछता है।


2
उपलब्धता समूहों के लिए समाधान से किसी भी तरह से स्पष्ट डेटाबेस के लिए समाधान कैसे किया जाता है (नोट: ऑल्वोऑन तकनीक का एक गुच्छा के लिए एक विपणन लेबल है, एक विशेषता नहीं है)? एक ब्लॉग पोस्ट का शीर्षक इस तथ्य को नहीं बदलता है कि यह लापता लॉगिन को पुनर्स्थापित कर रहा है - जो, और स्वयं में, दर्पण, उपलब्धता समूहों, लॉग शिपिंग, मैनुअल बैकअप / पुनर्स्थापना, आदि का उपयोग करने से कोई लेना-देना नहीं है।
हारून बर्ट्रेंड

दुर्भाग्य से, मैं हमेशा AD खातों का उपयोग नहीं कर सकता। हम पासवर्ड की तुलना करने के तरीके के साथ संघर्ष कर रहे हैं। क्या हम यह मानने में सही नहीं हैं कि यदि पासवर्ड मेल नहीं खाते हैं, तो प्रतिकृति सर्वर के बीच विफलता विफल हो जाएगी?

1

मैं लंबे समय के बाद पोस्ट का जवाब दे रहा हूं, लेकिन यह इसी तरह के मुद्दे के साथ किसी और की मदद कर सकता है। PowerShell का उपयोग प्राथमिक प्रतिकृति से द्वितीयक प्रतिकृतियों में लॉगिन कॉपी करने के लिए किया जा सकता है। विवरण यहाँ पाया जा सकता है https://maq.guru/synchronizing-sql-server-logins-in-an-always-on-avavour-group/

पूर्ण प्रकटीकरण: मैं उपरोक्त साइट का मालिक हूं।

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
    }

2
धन्यवाद मुहम्मद, क्या आप लिंक की कुछ सामग्री शामिल कर सकते हैं? यदि लिंक मर जाता है, तो आपका प्रश्न बहुत कम उपयोगी हो जाएगा अन्यथा!
लोवलीबा आईबी

@ लवली डीबीए, मैंने स्क्रिप्ट को यहां रखने की कोशिश की है, लेकिन दुर्भाग्य से इसका बहुत लंबा :( लिंक इस वेबसाइट के मालिक के रूप में नहीं मरेगा।
मुहम्मद

स्क्रिप्ट बहुत लंबी नहीं है। मैं इसे तुम्हारे लिए जोड़ दूँगा। और उस स्थिति में, आपको अपने स्वयं के लिंक पोस्ट करते समय अपनी संबद्धता का खुलासा करना होगा
LowlyDBA

क्षमा याचना @LlyDBA, मुझे प्रकटीकरण के बारे में पता नहीं था। मैंने यहाँ स्क्रिप्ट को टिप्पणी अनुभाग में रखने की कोशिश की है लेकिन यह कुछ वर्णों तक सीमित है। मैंने पूरी स्क्रिप्ट जोड़ी है। धन्यवाद
मुहम्मद

यह बहुत शर्मनाक है कि सर्वर-स्तरीय सिंक एजी का हिस्सा नहीं है। आपके उत्तर को उस लेख के लिए अपवोट मिल जाता है, जो उस पर एमएस को बुलाता है।
youcantryreachingme

-1

आपको Windows डोमेन लॉगिन का उपयोग करना चाहिए और उन्हें हर उदाहरण में बनाना होगा, जैसा कि SID सक्रिय निर्देशिका द्वारा प्रबंधित किया जाता है, यदि आप प्राथमिक प्रतिकृति में लॉगिन मौजूद हैं, तो आप उपलब्धता समूह के सभी प्रतिकृतियों तक पहुंच सकेंगे। एक अन्य विकल्प आपको एक प्रमाण पत्र का उपयोग करना चाहिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.