I den här artikeln lär du dig hur du övervakar och felsöker problem med en länk mellan SQL Server och Azure SQL Managed Instance.
Du kan kontrollera tillståndet för länken med Transact-SQL (T-SQL), Azure PowerShell eller Azure CLI. Om du får problem kan du använda felkoderna för att felsöka problemet.
Om du stöter på problem med en länk kan du använda Transact-SQL (T-SQL), Azure PowerShell eller Azure CLI för att få information om länkens aktuella tillstånd.
Använd T-SQL för en snabb statusinformation om länktillståndet och använd sedan Azure PowerShell eller Azure CLI för en omfattande information om länkens aktuella tillstånd.
Använd T-SQL för att fastställa länkens tillstånd under seedningsfasen eller efter att datasynkroniseringen har påbörjats.
Använd följande T-SQL-fråga för att fastställa statusen för länken under seedningsfasen på SQL Server eller SQL Managed Instance som är värd för databasen som är seedad via länken:
SELECT
ag.local_database_name AS 'Local database name',
ar.current_state AS 'Current state',
ar.is_source AS 'Is source',
ag.internal_state_desc AS 'Internal state desc',
ag.database_size_bytes / 1024 / 1024 AS 'Database size MB',
ag.transferred_size_bytes / 1024 / 1024 AS 'Transferred MB',
ag.transfer_rate_bytes_per_second / 1024 / 1024 AS 'Transfer rate MB/s',
ag.total_disk_io_wait_time_ms / 1000 AS 'Total Disk IO wait (sec)',
ag.total_network_wait_time_ms / 1000 AS 'Total Network wait (sec)',
ag.is_compression_enabled AS 'Compression',
ag.start_time_utc AS 'Start time UTC',
ag.estimate_time_complete_utc as 'Estimated time complete UTC',
ar.completion_time AS 'Completion time',
ar.number_of_attempts AS 'Attempt No'
FROM sys.dm_hadr_physical_seeding_stats AS ag
INNER JOIN sys.dm_hadr_automatic_seeding AS ar
ON local_physical_seeding_id = operation_id
-- Estimated seeding completion time
SELECT DISTINCT CONVERT(VARCHAR(8), DATEADD(SECOND, DATEDIFF(SECOND, start_time_utc, estimate_time_complete_utc) ,0), 108) as 'Estimated complete time'
FROM sys.dm_hadr_physical_seeding_stats
Om frågan inte returnerar några resultat har seeding-processen inte startats eller har redan slutförts.
Använd följande T-SQL-fråga på den primära-instansen för att kontrollera länkens hälsotillstånd när datasynkroniseringen börjar:
DECLARE @link_name varchar(max) = '<DAGname>'
SELECT
rs.synchronization_health_desc [Link sync health]
FROM
sys.availability_groups ag
join sys.dm_hadr_availability_replica_states rs
on ag.group_id = rs.group_id
WHERE
rs.is_local = 0 AND rs.role = 2 AND ag.is_distributed = 1 AND ag.name = @link_name
GO
Frågan returnerar följande möjliga värden:
inget resultat: Frågan kördes på den sekundära instansen.
HEALTHY: Länken är felfri och data synkroniseras mellan replikerna.
NOT_HEALTHY: Länken är inte felfri och data synkroniseras inte mellan replikerna.
Använd Get-AzSqlInstanceLink för att hämta länktillståndsinformation med PowerShell.
Kör följande exempelkod i Azure Cloud Shell eller installera Az.SQL-modulen lokalt.
$ManagedInstanceName = "<ManagedInstanceName>" # The name of your linked SQL Managed Instance
$DAGName = "<DAGName>" # distributed availability group name
# Find out the resource group name
$ResourceGroupName = (Get-AzSqlInstance -InstanceName $ManagedInstanceName).ResourceGroupName
# Show link state details
(Get-AzSqlInstanceLink -ResourceGroupName $ResourceGroupName -InstanceName $ManagedInstanceName -Name $DAGName).Databases
Använd az sql mi link show för att hämta länktillståndsinformation med Azure CLI.
# type "az" to use Azure CLI
managedInstanceName = "<ManagedInstanceName>" # The name of your linked SQL Managed Instance
dagName = "<DAGName>" # distributed availability group name
rgName = "<RGName>" # the resource group for the linked SQL Managed Instance
# Print link state details
az sql mi link show –-resource-group $rgName –-instance-name $managedInstanceName –-name $dagName
Värdet replicaState beskriver den aktuella länken. Om tillståndet även innehåller Fel uppstod ett fel under åtgärden som anges i tillståndet. Till exempel anger LinkCreationError att ett fel uppstod när länken skapades.
Det finns två olika kategorier av fel som du kan stöta på när du använder länken – fel när du försöker initiera länken och fel när du försöker skapa länken.
Fel vid initiering av en länk
Följande fel kan inträffa när en länk initieras (länktillstånd: LinkInitError):
Fel 41962: Åtgärden avbröts eftersom länken inte initierades inom 5 minuter. Kontrollera nätverksanslutning och försök igen.
Fel 41976: Tillgänglighetsgruppen svarar inte. Kontrollera namn och konfigurationsparametrar och försök igen.
Fel 41986: Det går inte att upprätta länken eftersom anslutningen misslyckades eller att den sekundära repliken inte svarar. Kontrollera namn, konfigurationsparametrar och nätverksanslutning och försök sedan igen.
Fel 47521: Det går inte att upprätta länken eftersom den sekundära servern inte tog emot begäran. Kontrollera att tillgänglighetsgruppen och databaserna är felfria på den primära servern och försök igen.
Fel vid skapande av en länk
Följande fel kan inträffa när du skapar en länk (länktillstånd: LinkCreationError):
Fel 41977: Måldatabasen svarar inte. Kontrollera länkparametrarna och försök igen.
Inkonsekvent systemtillstånd efter tvingad överlämning
Efter en tvingad redundansväxlingkan du stöta på ett split-brain-scenario där båda replikerna har den primära rollen, vilket lämnar länken i ett inkonsekvent tillstånd. Detta kan inträffa om du redundansväxlar till den sekundära repliken under ett haveri och den primära repliken är online igen.
Bekräfta först att du är i ett scenario med delad hjärna. Du kan göra det med hjälp av SQL Server Management Studio (SSMS) eller Transact-SQL (T-SQL).
Anslut till både SQL Server och SQL-hanterad instans i SSMS och i Object Explorer, expandera Tillgänglighetsrepliker under noden Tillgänglighetsgruppen i Always On High Availability. Om två olika repliker visas som (primär)är du i ett scenario med delad hjärna.
Du kan också köra följande T-SQL-skript på både SQL Server och SQL Managed Instance för att kontrollera replikernas roll:
-- Execute on SQL Server and SQL Managed Instance
USE master
DECLARE @link_name varchar(max) = '<DAGName>'
SELECT
ag.name [Link name],
rs.role_desc [Link role]
FROM
sys.availability_groups ag
JOIN sys.dm_hadr_availability_replica_states rs
ON ag.group_id = rs.group_id
WHERE
rs.is_local = 1 AND ag.is_distributed = 1 AND ag.name = @link_name
GO
Om båda instanserna listar PRIMÄR i kolumnen för Länkroll, är du i ett delad-hjärna-scenario.
Lös det delade hjärntillståndet genom att först göra en säkerhetskopia på den replik som var den ursprungliga primära. Om den ursprungliga primära var SQL Server tar du en säkerhetskopia av tail log. Om den ursprungliga primära instansen var SQL Managed Instance ska du ta en kopi-endast fullständig säkerhetskopiering. När säkerhetskopieringen är klar anger du den distribuerade tillgänglighetsgruppen till den sekundära rollen för repliken som tidigare var den ursprungliga primära men som nu kommer att vara den nya sekundära.
I händelse av ett verkligt haveri förutsätter du till exempel att du har tvingat fram en redundansväxling av SQL Server-arbetsbelastningen till Azure SQL Managed Instance och tänker fortsätta köra arbetsbelastningen på SQL Managed Instance, göra en säkerhetskopiering av en slutlogg på SQL Server och sedan ange den distribuerade tillgänglighetsgruppen till den sekundära rollen på SQL Server, till exempel följande exempel:
--Execute on SQL Server
USE master
ALTER AVAILABILITY GROUP [<DAGName>]
SET (ROLE = SECONDARY)
GO
Kör sedan en planerad manuell redundansväxling från SQL Managed Instance till SQL Server med hjälp av länken, till exempel följande exempel:
--Execute on SQL Managed Instance
USE master
ALTER AVAILABILITY GROUP [<DAGName>] FAILOVER
GO
Testa nätverksanslutning
Dubbelriktad nätverksanslutning mellan SQL Server och SQL Managed Instance krävs för att länken ska fungera. När du har öppnat portar på SQL Server-sidan och konfigurerat en NSG-regel på SQL Managed Instance-sidan testar du anslutningen med antingen SQL Server Management Studio (SSMS) eller Transact-SQL.
Testa nätverket genom att skapa ett tillfälligt SQL Agent-jobb på både SQL Server och SQL Managed Instance för att kontrollera anslutningen mellan de två instanserna. När du använder Network Checker i SSMS skapas jobbet automatiskt åt dig och tas bort när testet har slutförts. Du måste ta bort SQL Agent-jobbet manuellt om du testar nätverket med hjälp av T-SQL.
Not
Det finns för närvarande inte stöd för att köra PowerShell-skript av SQL Server-agenten på SQL Server i Linux, så det går för närvarande inte att köra Test-NetConnection från SQL Server Agent-jobbet på SQL Server i Linux.
Om du vill använda SQL-agenten för att testa nätverksanslutningen behöver du följande krav:
Användaren som utför testet måste ha behörighet att skapa ett jobb (antingen som en sysadmin eller tillhör SQLAgentOperator-rollen för msdb) för både SQL Server och SQL Managed Instance.
SQL Server Agent-tjänsten måste köra på SQL Server. Eftersom agenten är aktiverad som standard på SQL Managed Instance krävs ingen ytterligare åtgärd.
Följ dessa steg för att testa nätverksanslutningen mellan SQL Server och SQL Managed Instance i SSMS:
Anslut till den instans som ska vara den primära repliken i SSMS.
I Object Explorerexpanderar du databaser och högerklickar på den databas som du vill länka till den sekundära. Välj Uppgifter>länken Azure SQL Managed Instance>Test Connection för att öppna guiden Nätverkskontroll:
Välj Nästa på sidan Introduktion i verktyget Network Checker.
Om alla krav uppfylls på sidan Förutsättningar väljer du Nästa. Lös annars eventuella ouppfyllda krav och välj sedan Kör validering igen.
På sidan Inloggning väljer du Inloggning för att ansluta till en annan instans som kommer att fungera som den sekundära repliken. Välj Nästa.
Kontrollera informationen på sidan Ange nätverksalternativ och ange en IP-adress om det behövs. Välj Nästa.
På sidan Sammanfattning granskar du de åtgärder som guiden vidtar och väljer sedan Slutför för att testa anslutningen mellan de två replikerna.
Granska sidan Resultat för att verifiera att anslutningen finns mellan de två replikerna, och välj sedan Stäng för att avsluta.
Om du vill använda T-SQL för att testa anslutningen måste du kontrollera anslutningen i båda riktningarna. Testa först anslutningen från SQL Server till SQL Managed Instance och testa sedan anslutningen från SQL Managed Instance till SQL Server.
Testa anslutningen från SQL Server till SQL Managed Instance
Använd SQL Server Agent på SQL Server för att köra anslutningstester från SQL Server till SQL Managed Instance.
Anslut till SQL Managed Instance och kör följande skript för att generera parametrar som du behöver senare:
SELECT 'DECLARE @serverName NVARCHAR(512) = N''' + value + ''''
FROM sys.dm_hadr_fabric_config_parameters
WHERE parameter_name = 'DnsRecordName'
UNION
SELECT 'DECLARE @node NVARCHAR(512) = N''' + NodeName + '.' + Cluster + ''''
FROM (
SELECT SUBSTRING(replica_address, 0, CHARINDEX('\', replica_address)) AS NodeName,
RIGHT(service_name, CHARINDEX('/', REVERSE(service_name)) - 1) AppName,
JoinCol = 1
FROM sys.dm_hadr_fabric_partitions fp
INNER JOIN sys.dm_hadr_fabric_replicas fr
ON fp.partition_id = fr.partition_id
INNER JOIN sys.dm_hadr_fabric_nodes fn
ON fr.node_name = fn.node_name
WHERE service_name LIKE '%ManagedServer%'
AND replica_role = 2
) t1
LEFT JOIN (
SELECT value AS Cluster,
JoinCol = 1
FROM sys.dm_hadr_fabric_config_parameters
WHERE parameter_name = 'ClusterName'
) t2
ON (t1.JoinCol = t2.JoinCol)
INNER JOIN (
SELECT [value] AS AppName
FROM sys.dm_hadr_fabric_config_parameters
WHERE section_name = 'SQL'
AND parameter_name = 'InstanceName'
) t3
ON (t1.AppName = t3.AppName)
UNION
SELECT 'DECLARE @port NVARCHAR(512) = N''' + value + ''''
FROM sys.dm_hadr_fabric_config_parameters
WHERE parameter_name = 'HadrPort';
Spara resultatet om du vill använda nästa steg. Eftersom dessa parametrar kan ändras efter en failover bör du generera dem på nytt vid behov.
Anslut till SQL Server-instansen.
Öppna ett nytt frågefönster och klistra in följande skript:
--START
-- Parameters section
DECLARE @node NVARCHAR(512) = N''
DECLARE @port NVARCHAR(512) = N''
DECLARE @serverName NVARCHAR(512) = N''
--Script section
IF EXISTS (
SELECT job_id
FROM msdb.dbo.sysjobs_view
WHERE name = N'TestMILinkConnection'
)
EXEC msdb.dbo.sp_delete_job @job_name = N'TestMILinkConnection',
@delete_unused_schedule = 1
DECLARE @jobId BINARY (16),
@cmd NVARCHAR(MAX)
EXEC msdb.dbo.sp_add_job @job_name = N'TestMILinkConnection',
@enabled = 1,
@job_id = @jobId OUTPUT
SET @cmd = (N'tnc ' + @serverName + N' -port 5022 | select ComputerName, RemoteAddress, TcpTestSucceeded | Format-List')
EXEC msdb.dbo.sp_add_jobstep @job_id = @jobId,
@step_name = N'Test Port 5022',
@step_id = 1,
@cmdexec_success_code = 0,
@on_success_action = 3,
@on_fail_action = 3,
@subsystem = N'PowerShell',
@command = @cmd,
@database_name = N'master'
SET @cmd = (N'tnc ' + @node + N' -port ' + @port + ' | select ComputerName, RemoteAddress, TcpTestSucceeded | Format-List')
EXEC msdb.dbo.sp_add_jobstep @job_id = @jobId,
@step_name = N'Test HADR Port',
@step_id = 2,
@cmdexec_success_code = 0,
@subsystem = N'PowerShell',
@command = @cmd,
@database_name = N'master'
EXEC msdb.dbo.sp_add_jobserver @job_id = @jobId,
@server_name = N'(local)'
GO
EXEC msdb.dbo.sp_start_job @job_name = N'TestMILinkConnection'
GO
--Check status every 5 seconds
DECLARE @RunStatus INT
SET @RunStatus = 10
WHILE (@RunStatus >= 4)
BEGIN
SELECT DISTINCT @RunStatus = run_status
FROM [msdb].[dbo].[sysjobhistory] JH
INNER JOIN [msdb].[dbo].[sysjobs] J
ON JH.job_id = J.job_id
WHERE J.name = N'TestMILinkConnection'
AND step_id = 0
WAITFOR DELAY '00:00:05';
END
--Get logs once job completes
SELECT [step_name],
SUBSTRING([message], CHARINDEX('TcpTestSucceeded', [message]), CHARINDEX('Process Exit', [message]) - CHARINDEX('TcpTestSucceeded', [message])) AS TcpTestResult,
SUBSTRING([message], CHARINDEX('RemoteAddress', [message]), CHARINDEX('TcpTestSucceeded', [message]) - CHARINDEX('RemoteAddress', [message])) AS RemoteAddressResult,
[run_status],
[run_duration],
[message]
FROM [msdb].[dbo].[sysjobhistory] JH
INNER JOIN [msdb].[dbo].[sysjobs] J
ON JH.job_id = J.job_id
WHERE J.name = N'TestMILinkConnection'
AND step_id <> 0
--END
Ersätt parametrarna @node, @portoch @serverName med de värden som du fick från det första steget.
Kör skriptet och kontrollera resultatet. Du bör se resultat, till exempel följande exempel:
Kontrollera resultatet:
Resultatet av varje test vid TcpTestSucceeded bör vara TcpTestSucceeded : True.
RemoteAddresses ska tillhöra IP-intervallet för undernätet SQL Managed Instance.
Om svaret misslyckas kontrollerar du följande nätverksinställningar:
Det finns regler i både nätverksbrandväggen och brandväggen för SQL Server-värdoperativsystemet (Windows/Linux) som tillåter trafik till hela undernäts-IP-intervall för SQL Managed Instance.
Det finns en NSG-regel som tillåter kommunikation på port 5022 för det virtuella nätverk som är värd för SQL Managed Instance.
Testa anslutningen från SQL Managed Instance till SQL Server
Om du vill kontrollera att SQL Managed Instance kan nå SQL Server skapar du först en testslutpunkt. Sedan använder du SQL Server-agenten för att köra ett PowerShell-skript med kommandot tnc pinga SQL Server på port 5022 från sql-hanterad instans.
Om du vill skapa en testslutpunkt ansluter du till SQL Server och kör följande T-SQL-skript:
-- Run on SQL Server
-- Create the certificate needed for the test endpoint
USE MASTER
CREATE CERTIFICATE TEST_CERT
WITH SUBJECT = N'Certificate for SQL Server',
EXPIRY_DATE = N'3/30/2051'
GO
-- Create the test endpoint on SQL Server
USE MASTER
CREATE ENDPOINT TEST_ENDPOINT
STATE=STARTED
AS TCP (LISTENER_PORT=5022, LISTENER_IP = ALL)
FOR DATABASE_MIRRORING (
ROLE=ALL,
AUTHENTICATION = CERTIFICATE TEST_CERT,
ENCRYPTION = REQUIRED ALGORITHM AES
)
Kontrollera att SQL Server-slutpunkten tar emot anslutningar på port 5022 genom att köra följande PowerShell-kommando på värdoperativsystemet för SQL Server-instansen:
tnc localhost -port 5022
Ett lyckat test visar TcpTestSucceeded : True. Du kan sedan fortsätta att skapa ett SQL Server Agent-jobb på den SQL-hanterade instansen för att testa SQL Server-testslutpunkten på port 5022 från den SQL-hanterade instansen.
Skapa sedan ett SQL Server Agent-jobb på den SQL-hanterade instansen med namnet NetHelper genom att köra följande T-SQL-skript på den SQL-hanterade instansen. Ersätta:
<SQL_SERVER_IP_ADDRESS> med IP-adressen för SQL Server som är tillgänglig från en SQL-hanterad instans.
-- Run on SQL managed instance
-- SQL_SERVER_IP_ADDRESS should be an IP address that could be accessed from the SQL Managed Instance host machine.
DECLARE @SQLServerIpAddress NVARCHAR(MAX) = '<SQL_SERVER_IP_ADDRESS>'; -- insert your SQL Server IP address in here
DECLARE @tncCommand NVARCHAR(MAX) = 'tnc ' + @SQLServerIpAddress + ' -port 5022 -InformationLevel Quiet';
DECLARE @jobId BINARY(16);
IF EXISTS (
SELECT *
FROM msdb.dbo.sysjobs
WHERE name = 'NetHelper'
) THROW 70000,
'Agent job NetHelper already exists. Please rename the job, or drop the existing job before creating it again.',
1
-- To delete NetHelper job run: EXEC msdb.dbo.sp_delete_job @job_name=N'NetHelper'
EXEC msdb.dbo.sp_add_job @job_name = N'NetHelper',
@enabled = 1,
@description = N'Test SQL Managed Instance to SQL Server network connectivity on port 5022.',
@category_name = N'[Uncategorized (Local)]',
@owner_login_name = N'sa',
@job_id = @jobId OUTPUT;
EXEC msdb.dbo.sp_add_jobstep @job_id = @jobId,
@step_name = N'TNC network probe from SQL MI to SQL Server',
@step_id = 1,
@os_run_priority = 0,
@subsystem = N'PowerShell',
@command = @tncCommand,
@database_name = N'master',
@flags = 40;
EXEC msdb.dbo.sp_update_job @job_id = @jobId,
@start_step_id = 1;
EXEC msdb.dbo.sp_add_jobserver @job_id = @jobId,
@server_name = N'(local)';
Tips
Om du behöver ändra IP-adressen för din SQL Server för anslutningsavsökningen från sql-hanterad instans tar du bort NetHelper-jobbet genom att köra EXEC msdb.dbo.sp_delete_job @job_name=N'NetHelper'och återskapa NetHelper-jobbet med hjälp av föregående skript.
Skapa sedan en lagrad procedur ExecuteNetHelper som hjälper dig att köra jobbet och hämta resultat från nätverksavsökningen. Kör följande T-SQL-skript på SQL-hanterad instans:
-- Run on managed instance
IF EXISTS(SELECT * FROM sys.objects WHERE name = 'ExecuteNetHelper')
THROW 70001, 'Stored procedure ExecuteNetHelper already exists. Rename or drop the existing procedure before creating it again.', 1
GO
CREATE PROCEDURE ExecuteNetHelper AS
-- To delete the procedure run: DROP PROCEDURE ExecuteNetHelper
BEGIN
-- Start the job.
DECLARE @NetHelperstartTimeUtc DATETIME = GETUTCDATE();
DECLARE @stop_exec_date DATETIME = NULL;
EXEC msdb.dbo.sp_start_job @job_name = N'NetHelper';
-- Wait for job to complete and then see the outcome.
WHILE (@stop_exec_date IS NULL)
BEGIN
-- Wait and see if the job has completed.
WAITFOR DELAY '00:00:01'
SELECT @stop_exec_date = sja.stop_execution_date
FROM msdb.dbo.sysjobs sj
INNER JOIN msdb.dbo.sysjobactivity sja
ON sj.job_id = sja.job_id
WHERE sj.name = 'NetHelper'
-- If job has completed, get the outcome of the network test.
IF (@stop_exec_date IS NOT NULL)
BEGIN
SELECT sj.name JobName,
sjsl.date_modified AS 'Date executed',
sjs.step_name AS 'Step executed',
sjsl.log AS 'Connectivity status'
FROM msdb.dbo.sysjobs sj
LEFT JOIN msdb.dbo.sysjobsteps sjs
ON sj.job_id = sjs.job_id
LEFT JOIN msdb.dbo.sysjobstepslogs sjsl
ON sjs.step_uid = sjsl.step_uid
WHERE sj.name = 'NetHelper'
END
-- In case of operation timeout (90 seconds), print timeout message.
IF (datediff(second, @NetHelperstartTimeUtc, getutcdate()) > 90)
BEGIN
SELECT 'NetHelper timed out during the network check. Please investigate SQL Agent logs for more information.'
BREAK;
END
END
END;
Kör följande fråga på sql-hanterad instans för att köra den lagrade proceduren som ska köra NetHelper-agentjobbet och visa den resulterande loggen:
-- Run on managed instance
EXEC ExecuteNetHelper;
Om anslutningen lyckades visar loggen True. Om anslutningen misslyckades visar loggen False.
Om anslutningen misslyckades kontrollerar du följande:
Brandväggen på SQL Server-värdinstansen tillåter inkommande och utgående kommunikation på port 5022.
En NSG-regel för det virtuella nätverket som är värd för SQL Managed Instance tillåter kommunikation på port 5022.
Om SQL Server-instansen finns på en virtuell Azure-dator tillåter en NSG-regel kommunikation på port 5022 i det virtuella nätverk som är värd för den virtuella datorn.
SQL Server körs.
Det finns en testslutpunkt på SQL Server.
När du har löst problem kör du NetHelper-nätverksavsökningen igen genom att köra EXEC ExecuteNetHelper på en hanterad instans.
När nätverkstestet har slutförts släpper du slutligen testslutpunkten och certifikatet på SQL Server med hjälp av följande T-SQL-kommandon:
-- Run on SQL Server
DROP ENDPOINT TEST_ENDPOINT;
GO
DROP CERTIFICATE TEST_CERT;
GO
Försiktighet
Fortsätt endast med nästa steg om du har verifierat nätverksanslutningen mellan käll- och målmiljöerna. Annars kan du felsöka problem med nätverksanslutningen innan du fortsätter.
Relaterat innehåll
Mer information om länkfunktionen finns i följande resurser: