다음을 통해 공유


연결 문제 및 기타 오류 해결

적용 대상: Fabric의 Azure SQL Database Azure SQL Managed Instance SQL 데이터베이스

Azure SQL Database, Fabric SQL Database 또는 Azure SQL Managed Instance에 대한 연결이 실패하면 오류 메시지가 표시됩니다.

언제나처럼 애플리케이션 디자인 프로세스 중에 모범 사례 및 디자인 지침을 적용합니다.

참고 항목

Azure SQL 연결 검사기를 사용하여 다양한 연결 오류를 감지하고 수정할 수 있습니다.

일반적인 연결 문제 해결 단계

  1. 애플리케이션 서버에서 TCP/IP가 클라이언트 프로토콜로 사용되는지 확인합니다. SQL 도구가 설치되어 있지 않은 애플리케이션 서버에서 TCP/IP를 사용하도록 설정했는지 확인하려면 cliconfg.exe(SQL Server 클라이언트 네트워크 유틸리티)를 실행합니다.

  2. 애플리케이션의 연결 문자열이 올바르게 구성되었는지 확인합니다. 예를 들어 연결 문자열이 올바른 포트(1433) 및 정규화된 서버 이름을 지정하는지 확인해야 합니다. SQL Server Management Studio를 사용하여 연결 정보 가져오기를 참조하세요.

  3. 연결 제한 시간을 늘려 보세요. 30 초 이상의 연결 제한 시간을 사용하는 것이 좋습니다.

  4. 빠른 시작: SSMS(SQL Server Management Studio)를 사용하여 Azure SQL Database 또는 Azure SQL Managed Instance 쿼리, UDL 파일, ping 또는 텔넷을 사용하여 애플리케이션 서버와 Azure SQL Database 간의 연결을 테스트합니다. 자세한 내용은 연결 문제 해결연결 문제 진단을 참조하세요.

    참고

    문제 해결 단계 중 하나로 다른 클라이언트 컴퓨터에서 연결을 테스트할 수도 있습니다.

  5. 클라우드 연결 애플리케이션은 재시도 논리를 사용해야 하는 모범 사례입니다.

이러한 단계를 수행해도 문제가 해결되지 않으면 더 많은 데이터를 수집한 다음 고객 지원팀에 문의하세요. 애플리케이션이 클라우드 서비스인 경우 로깅을 사용하도록 설정합니다. 이 단계에서는 실패의 UTC 타임스탬프를 반환합니다. 로깅 사용에 대한 자세한 내용은 Azure App Service에서 앱에 대한 진단 로깅 설정을 참조하세요. 또한 SQL Database는 추적 ID를 반환합니다. Microsoft 고객 지원팀 서비스에서 이 정보를 사용할 수 있습니다.

다시 시도 논리 구현

자체 해결을 위한 일시적 오류 시간이 지난 후 연결을 다시 시도할 수 있도록 클라이언트 응용 프로그램이 재시도 논리를 사용하는 것이 좋습니다. 첫 번째 재시도 전에 5초간 지연하는 것이 좋습니다. 5초보다 짧은 지연 후 재시도는 클라우드 서비스에 많은 위험이 있습니다. 각 후속 재시도에 대해 지연 시간은 최대 60초까지 기하급수적으로 증가해야 합니다.

재시도 논리의 코드 예제는 다음을 참조하십시오.

응용 프로그램에서 일시적인 오류를 처리하는 방법에 대한 더 자세한 내용은 SQL 데이터베이스 및 SQL Managed Instance의 일시적 연결 오류 문제 해결을 참조하세요.

ADO.NET을 사용하는 클라이언트에 대한 차단 기간의 설명은 연결 풀링(ADO.NET)에서 사용 가능합니다.

일시적인 장애 오류 메시지(40197, 40613 및 기타)

Azure 인프라에 는 SQL Database 서비스에 과도한 워크로드 부하가 발생하는 경우 서버를 동적으로 다시 구성 하는 기능이 있습니다. 이러한 동적인 동작으로 인해 데이터베이스 또는 인스턴스에 대한 클라이언트 프로그램의 연결이 손실될 수 있습니다. 이러한 종류의 오류 상황을 일시적 장애라고 합니다. 데이터베이스 재구성 이벤트는 계획된 이벤트(예: 소프트웨어 업그레이드) 또는 계획되지 않은 이벤트(예: 프로세스 충돌 또는 부하 분산) 때문에 발생합니다. 대부분의 재구성 이벤트는 일시적으로 발생하며 최대 60초 이내에 완료됩니다. 그러나 큰 트랜잭션으로 인해 복구가 오래 실행되는 등 이러한 이벤트가 완료되는 데 시간이 더 오래 걸리는 경우도 있습니다. 다음 표에는 Azure SQL Database에 연결할 때 애플리케이션에서 받을 수 있는 다양한 일시적인 오류가 나열되어 있습니다.

일시적인 오류 코드 목록

오류 코드 심각도 설명
926 14 Database 'replicatedmaster' cannot be opened. It has been marked SUSPECT by recovery. See the SQL Server error log for more information.

이 오류는 재구성의 마지막 단계에서 짧은 기간 동안 SQL Managed Instance 오류 로그에 로그될 수 있으며 이전 주요가 해당 로그를 종료할 수 있습니다.
이 오류 메시지와 관련된 기타 일시적이지 않은 시나리오는 MSSQL 오류 문서에 설명되어 있습니다.
4060 16 Cannot open database "%.*ls" requested by the login. The login failed.

자세한 내용은 오류 4000~4999를 참조하세요.
40197 17 The service has encountered an error processing your request. Please try again. Error code %d.

소프트웨어 또는 하드웨어 업그레이드, 하드웨어 오류 또는 기타 장애 조치 문제로 인해 서비스가 종료되는 경우 이 오류가 발생합니다. 오류 40197 메시지 내에 포함된 오류 코드(%d)는 발생한 오류 또는 장애 조치의 종류에 대한 추가 정보를 제공합니다. 오류 40197 메시지 내에 포함된 오류 코드의 일부 예제는 40020, 40143, 40166 및 40540입니다.
재연결은 데이터베이스의 정상 복사본으로 자동 연결됩니다. 애플리케이션은 오류 40197을 포착하고 문제 해결을 위해 메시지 내에 포함된 오류 코드(%d)를 로그하고 리소스가 사용 가능하고 연결이 다시 설정될 때까지 SQL Database에 다시 접속을 시도해야 합니다. 자세한 내용은 일시적인 오류를 참조하세요.
40501 20 The service is currently busy. Retry the request after 10 seconds. Incident ID: %ls. Code: %d.

자세한 내용은 다음을 참조하세요.
리소스 관리.
DTU 구매 모델을 사용한 Elastic Pool의 리소스 한도.
단일 데이터베이스에 대한 vCore 기반 한도.
탄력적 풀에 대한 vCore 기반 한도.
Azure SQL Managed Instance 리소스 한도
40613 17 Database '%.*ls' on server '%.*ls' is not currently available. Please retry the connection later. If the problem persists, contact customer support, and provide them with the session tracing ID of '%.*ls'.

이 오류는 데이터베이스에 기존 DAC(관리자 전용 연결)가 이미 설정된 경우에 발생할 수 있습니다. 자세한 내용은 일시적인 오류를 참조하세요.
49918 16 Cannot process request. Not enough resources to process request. The service is currently busy. Please retry the request later.

자세한 내용은 다음을 참조하세요.
리소스 관리.
DTU 구매 모델을 사용한 Elastic Pool의 리소스 한도.
단일 데이터베이스에 대한 vCore 기반 한도.
탄력적 풀에 대한 vCore 기반 한도.
Azure SQL Managed Instance 리소스 한도
49919 16 Cannot process create or update request. Too many create or update operations in progress for subscription "%ld".

서비스가 구독 또는 서버에 대한 여러 요청을 만들거나 업데이트하는 처리로 사용 중입니다. 요청은 현재 리소스 최적화에 대해 차단됩니다. 보류 중인 작업에 대해 sys.dm_operation_status를 쿼리합니다. 만들기 또는 업데이트를 보류 중인 요청이 완료되거나 보류 중인 요청 중 하나를 삭제할 때까지 대기하고 나중에 요청을 다시 시도합니다. 작업이 중단된 것 같으면 진행 중인 다른 작업이 완료될 때까지 기다리거나 가능한 경우 취소합니다. 예를 들어 생성 중인 데이터베이스 또는 복제본을 삭제하여 데이터베이스 복사본 또는 지역 복제본 생성을 취소할 수 있습니다. 중단된 것으로 보이는 작업을 취소할 수 없는 경우 Microsoft에서 지원 티켓을 엽니다.
49920 16 Cannot process request. Too many operations in progress for subscription "%ld".

서비스가 구독에 대한 여러 요청을 처리하는 데 사용 중입니다. 요청은 현재 리소스 최적화에 대해 차단됩니다. 작업 상태에 대해 sys.dm_operation_status를 쿼리합니다. 보류 중인 요청이 완료되거나 보류 중인 요청 중 하나를 삭제할 때까지 대기하고 나중에 요청을 다시 시도합니다. 작업이 중단된 것 같으면 진행 중인 다른 작업이 완료될 때까지 기다리거나 가능한 경우 취소합니다. 예를 들어 생성 중인 데이터베이스 또는 복제본을 삭제하여 데이터베이스 복사본 또는 지역 복제본 생성을 취소할 수 있습니다. 중단된 것으로 보이는 작업을 취소할 수 없는 경우 Microsoft에서 지원 티켓을 엽니다.
4221 16 Login to read-secondary failed due to long wait on 'HADR_DATABASE_WAIT_FOR_TRANSITION_TO_VERSIONING'.

행 버전이 복제본이 재활용될 때 처리 중이었던 트랜잭션에 대해 누락되었기 때문에 로그인에 복제본을 사용할 수 없습니다. 주 복제본에서 활성 트랜잭션을 롤백하거나 커밋하여 문제를 해결할 수 있습니다. 주 복제본에서 긴 쓰기 트랜잭션을 방지하여 이 조건의 발생을 최소화할 수 있습니다.
615 21 Could not find database ID %d, name '%.*ls'

메모리 내 캐시가 SQL 서버 인스턴스와 동기화되지 않았으며 조회에서 부실 데이터베이스 ID를 검색하고 있습니다.

SQL 로그인에서 메모리 내 캐시를 사용하여 데이터베이스 이름을 ID 매핑으로 가져옵니다. SQL 서버 인스턴스에 데이터베이스를 연결하고 분리할 때마다 캐시가 백 엔드 데이터베이스와 동기화되고 업데이트되어야 합니다.
분리 워크플로가 메모리 내 캐시를 적시에 정리하지 못하면 이 오류가 수신되고 후속 데이터베이스 조회가 부실 데이터베이스 ID를 가리킵니다.
리소스가 사용 가능하고 연결이 다시 설정될 때까지 SQL Database에 다시 연결을 시도해야 합니다. 자세한 내용은 일시적인 오류를 참조하세요.

일시적인 연결 문제를 해결하는 단계

  1. Microsoft Azure 서비스 대시보드에서 응용프로그램이 보고한 시간 동안 발생한 알려진 중단을 모두 확인합니다.
  2. Azure SQL Database와 같이 클라우드 서비스에 연결하는 애플리케이션에서는 주기적으로 다시 구성 이벤트가 발생하므로, 이러한 이벤트를 사용자에게 애플리케이션 오류로 표시하는 대신 해당 오류를 처리하는 재시도 논리를 구현해야 합니다.
  3. 데이터베이스가 리소스 한계에 도달하면 일시적인 연결 문제가 발생한 것처럼 보일 수 있습니다. 리소스 한도를 참조하세요.
  4. 연결 문제가 계속 발생하거나 애플리케이션에서 오류가 발생하는 기간이 60초를 초과하는 경우 또는 특정일에 오류가 여러 번 발생하는 경우에는 Azure 지원 사이트에서 지원 받기를 선택하여 Azure 지원 요청을 접수합니다.

애플리케이션에서 서버에 연결할 수 없는 경우 문제가 발생합니다.

이 문제를 해결하려면 일반적인 연결 문제 해결 단계 섹션에서 제시된 순서대로 단계를 시도합니다.

서버/인스턴스를 찾을 수 없거나 액세스할 수 없습니다(오류 26, 40, 10053)

오류 26: 지정된 서버를 찾는 동안 오류 발생

System.Data.SqlClient.SqlException: A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections.(provider: SQL Network Interfaces, error: 26 – Error Locating Server/Instance Specified)

오류 40: 서버에 대한 연결을 열 수 없음

A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)

오류 10053: 서버에서 결과를 받을 때 전송 수준 오류 발생

10053: A transport-level error has occurred when receiving results from the server. (Provider: TCP Provider, error: 0 - An established connection was aborted by the software in your host machine)

애플리케이션에서 서버에 연결할 수 없는 경우 이러한 문제가 발생합니다.

이러한 문제를 해결하려면 일반적인 연결 문제 해결 단계 섹션에서 제시된 순서대로 단계를 시도합니다.

방화벽 문제로 인해 서버에 연결할 수 없음

오류 40615: <서버 이름>에 연결할 수 없음

이 문제를 해결하려면 SQL Database에서 Azure portal을 통해 방화벽 설정을 구성합니다.

오류 5: <서버 이름>에 연결할 수 없음

이 문제를 해결하려면 클라이언트와 인터넷 간의 모든 방화벽에서 아웃바운드 연결을 위해 1433 포트가 열려 있는지 확인합니다.

서버에 로그인할 수 없음(오류 18456, 40531)

‘<사용자 이름>’ 사용자에 대한 로그인 실패

Login failed for user '<User name>'.This session has been assigned a tracing ID of '<Tracing ID>'. Provide this tracing ID to customer support when you need assistance. (Microsoft SQL Server, Error: 18456)

이 문제를 해결하려면 서비스 관리자에게 문의하여 유효한 사용자 이름과 암호를 확인합니다.

일반적으로 서비스 관리자는 다음 단계를 사용하여 로그인을 자격 증명을 추가할 수 있습니다.

  1. SSMS(SQL Server Management Studio)를 사용하여 서버에 로그인합니다.

  2. 로그인 이름이 사용하지 않도록 설정되었는지 여부를 확인하려면 master 데이터베이스에서 다음 SQL 쿼리를 실행합니다.

    SELECT name, is_disabled FROM sys.sql_logins;
    
  3. 해당 이름이 비활성화된 경우 다음 문을 사용하여 활성화해야 할 수 있습니다.

    ALTER LOGIN <User name> ENABLE;
    
  4. SQL 로그인 사용자 이름이 없으면 다음 SQL 쿼리를 편집하고 실행하여 새 SQL 로그인을 만듭니다.

    CREATE LOGIN <SQL_login_name, sysname, login_name>
    WITH PASSWORD = '<password, sysname, Change_Password>';
    GO
    
  5. SSMS 개체 탐색기에서 데이터베이스를 확장합니다.

  6. 사용자에게 권한을 부여하려는 데이터베이스를 선택합니다.

  7. 보안을 마우스 오른쪽 단추로 클릭한 다음, 사용자를 선택합니다.

  8. 개체 틀이 있는 생성된 스크립트에서 단계를 따라 SSMS 템플릿 매개 변수를 바꾸고 실행하며, 예제는 다음과 같습니다.

    CREATE USER [<user_name, sysname, user_name>]
    FOR LOGIN [<login_name, sysname, login_name>]
    WITH DEFAULT_SCHEMA = [<default_schema, sysname, dbo>];
    GO
    
    -- Add user to the database owner role
    EXEC sp_addrolemember N'db_owner', N'<user_name, sysname, user_name>';
    GO
    

    sp_addrolemember을(를) 사용하여 특정 사용자를 특정 데이터베이스 역할에 매핑할 수도 있습니다.

    참고

    Azure SQL Database에서는 데이터베이스 역할 멤버 자격을 관리하기 위한 새로운 ALTER ROLE 구문을 고려합니다.

자세한 내용은 데이터베이스 액세스 권한 부여를 참조하세요.

연결 제한 시간 만료 오류

System.Data.SqlClient.SqlException (0x80131904): 연결 제한 시간이 만료됨

System.Data.SqlClient.SqlException (0x80131904): Connection Timeout Expired. The timeout period elapsed while attempting to consume the pre-login handshake acknowledgement. This could be because the pre-login handshake failed or the server was unable to respond back in time. The duration spent while attempting to connect to this server was - [Pre-Login] initialization=3; handshake=29995;

System.Data.SqlClient.SqlException (0x80131904): 제한 시간이 만료됨

System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

System.Data.Entity.Core.EntityException: 열 때 기본 공급자가 실패

System.Data.Entity.Core.EntityException: The underlying provider failed on Open. -> System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. -> System.ComponentModel.Win32Exception: The wait operation timed out

<서버 이름>에 연결할 수 없음

Cannot connect to <server name>.ADDITIONAL INFORMATION:Connection Timeout Expired. The timeout period elapsed during the post-login phase. The connection could have timed out while waiting for server to complete the login process and respond; Or it could have timed out while attempting to create multiple active connections. The duration spent while attempting to connect to this server was - [Pre-Login] initialization=231; handshake=983; [Login] initialization=0; authentication=0; [Post-Login] complete=13000; (Microsoft SQL Server, Error: -2) For help, click: http://go.microsoft.com/fwlink?ProdName=Microsoft%20SQL%20Server&EvtSrc=MSSQLServer&EvtID=-2&LinkId=20476 The wait operation timed out

이러한 예외는 연결 또는 쿼리 문제로 인해 발생할 수 있습니다. 연결 문제가 이 오류를 발생시켰는지 확인하려면 연결 문제로 인해 오류가 발생했는지 확인을 참조하세요.

애플리케이션에서 서버에 연결할 수 없기 때문에 연결 제한 시간 문제가 발생합니다. 이 문제를 해결하려면 일반적인 연결 문제 해결 단계 섹션에서 제시된 순서대로 단계를 시도합니다.

네트워크 연결 종료 오류

SQL 클라이언트 라이브러리는 TCP 네트워크 프로토콜을 사용하여 Azure SQL Database 및 Azure SQL Managed Instance에 연결합니다. 클라이언트 라이브러리는 TCP 공급자라는 하위 수준 구성 요소를 사용하여 TCP 연결을 관리합니다. TCP 공급자가 원격 호스트가 기존 TCP 연결을 예기치 않게 종료하는 것을 검색하면 클라이언트 라이브러리에서 오류가 발생합니다. 오류는 SQL Server 오류가 아닌 클라이언트 오류이므로 SQL 오류 번호가 포함되지 않습니다. 대신 오류 번호는 0이고 TCP 공급자의 오류 메시지가 사용됩니다.

네트워크 연결 종료 오류의 예제는 다음과 같습니다.

A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.) An existing connection was forcibly closed by the remote host

A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.)

The client was unable to establish a connection because of an error during connection initialization process before login. Possible causes include the following: the client tried to connect to an unsupported version of SQL Server; the server was too busy to accept new connections; or there was a resource limitation (insufficient memory or maximum allowed connections) on the server. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.)

A connection was successfully established with the server, but then an error occurred during the login process. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.)

데이터베이스 또는 탄력적 풀을 일시적으로 사용할 수 없으므로 연결 종료 오류가 발생할 수 있습니다. 이 오류는 방화벽, 네트워크 어플라이언스 등을 포함하여 데이터베이스 서버와 클라이언트 애플리케이션 간의 네트워크 인프라에서 다양한 문제로 인해 발생합니다. 이러한 문제는 일시적이거나 영구적일 수 있습니다. 일반적인 참고 자료로 애플리케이션은 영구 실패로 간주하기 전에 이 오류에 대해 고정된 횟수의 재시도를 사용해야 합니다.

리소스 관리 오류

Azure SQL Database는 리소스 관리자를 기준으로 리소스 거버넌스 구현을 사용하여 리소스 제한을 적용합니다. Azure SQL Database의 리소스 관리에 대해 자세히 알아보세요.

가장 일반적인 리소스 거버넌스 오류가 세부 정보와 함께 먼저 나열된 다음, 리소스 거버넌스 오류 메시지 표가 표시됩니다.

오류 10928 및 10936: 리소스 ID: 1. [데이터베이스 또는 탄력적 풀]에 대한 요청 제한은 %d 이며 이 제한에 도달했습니다.

데이터베이스 수준 제한에 도달한 경우 자세한 오류 메시지 Resource ID : 1. The request limit for the database is %d and has been reached. See 'http://go.microsoft.com/fwlink/?LinkId=267637' for assistance.가 표시됩니다.

탄력적 풀 한도에 도달한 경우 다음과 같은 자세한 오류 메시지가 표시됩니다. Resource ID : 1. The request limit for the elastic pool is %d and has been reached. See 'http://go.microsoft.com/fwlink/?LinkId=267637' for assistance. 탄력적 풀 한도는 데이터베이스 제한보다 높습니다. 자세한 내용은 리소스 한도를 참조하세요. 제한은 풀의 여러 데이터베이스에서 리소스(예: 작업자)를 동시에 사용할 때 발생할 수 있습니다.

이 오류 메시지는 데이터베이스 또는 탄력적 풀에 대한 작업자 제한에 도달했음을 나타냅니다. 자리 표시자 %d 대신 데이터베이스 또는 탄력적 풀의 서비스 목표에 대한 최대 동시 작업자 값이 있게 됩니다.

참고

Azure SQL Database의 초기 제품은 단일 스레드 쿼리만 지원했습니다. 당시 요청 수는 항상 작업자 수와 동일했습니다. Azure SQL Database의 오류 메시지 10928 및 10936에는 이전 버전과의 호환성을 위해 “요청 제한[...]이 N이며 이 제한에 도달했습니다.”라는 문구가 포함되어 있습니다. 도달한 제한은 실제로 작업자 수입니다. 최대 병렬 처리 수준(MAXDOP) 설정이 0과 같거나 1보다 큰 경우 작업자 수가 요청 수보다 훨씬 많을 수 있으며 MAXDOP가 1과 같을 때보다 훨씬 더 빨리 제한에 도달할 수 있습니다.

세션, 작업자 및 요청에 대해 자세히 알아보세요.

필요한 경우 DAC(관리자 전용 연결)를 사용하여 연결

작업자 제한에 도달하기 직전이거나 도달한 경우 라이브 인시던트가 계속 진행 중이면 SSMS(SQL Server Management Studio) 또는 Azure Data Studio를 사용하여 연결할 때 오류 10928이 발생할 수 있습니다. 최대 작업자 임계값에 도달한 경우에도 DAC(데이터베이스 관리자를 위한 진단 연결)를 사용하여 하나의 세션에 연결할 수 있습니다.

SSMS에서 DAC와 연결을 설정하려면 다음을 수행합니다.

  • 메뉴에서 파일 > 새로 만들기 > 데이터베이스 엔진 쿼리를 선택합니다.
  • 서버 이름 필드의 연결 대화 상자에서 admin:<fully_qualified_server_name>(예: admin:servername.database.windows.net)의 내용을 입력합니다.
  • 옵션 >>을 선택합니다.
  • 연결 속성 탭을 선택합니다.
  • 데이터베이스에 연결: 상자에 데이터베이스 이름을 입력합니다.
  • 연결을 선택합니다.

오류 40613(Database '%.&#x2a;ls' on server '%.&#x2a;ls' is not currently available. Please retry the connection later. If the problem persists, contact customer support, and provide them the session tracing ID of '%.&#x2a;ls')이 발생한다면 다른 세션이 DAC에 이미 연결되어 있는 것을 나타낼 수 있습니다. 한 번에 하나의 세션만 단일 데이터베이스 또는 탄력적 풀의 DAC에 연결할 수 있습니다.

연결을 선택한 후 '서버에 연결하지 못했습니다' 오류가 발생하는 경우, 18.9 이전의 SSMS 버전을 사용한다면 DAC 세션이 여전히 성공적으로 설정되어 있을 수 있습니다. 초기 버전의 SSMS는 DAC에 연결하기 위해 Intellisense를 제공하려고 시도했습니다. DAC는 단일 작업자만 지원하고 Intellisense에는 별도의 작업자가 필요하므로 이는 실패했습니다.

SSMS에서 개체 탐색기와의 DAC 연결은 사용할 수 없습니다.

max_worker_percent usage 검토

데이터베이스의 14일간 리소스 사용량 통계를 찾으려면 sys.resource_stats 시스템 카탈로그 보기를 쿼리합니다. max_worker_percent 열은 데이터베이스의 작업자 제한 대비 사용된 작업자의 백분율을 보여줍니다. 논리 서버master 데이터베이스에 연결하여 sys.resource_stats를 쿼리합니다.

SELECT start_time, end_time, database_name, sku, avg_cpu_percent, max_worker_percent, max_session_percent 
FROM sys.resource_stats;

sys.dm_db_resource_stats 동적 관리 뷰를 사용하면 지난 1시간의 쿼리 리소스 소비량 통계도 볼 수 있습니다. 데이터베이스에 직접 연결하여 sys.dm_db_resource_stats를 쿼리합니다.

SELECT end_time, avg_cpu_percent, max_worker_percent, max_session_percent
FROM sys.dm_db_resource_stats;

가능한 경우 더 적은 작업자 사용

체인을 차단하면 데이터베이스의 작업자 수가 급증할 수 있습니다. 대량의 동시 병렬 쿼리로 인해 많은 수의 작업자가 발생할 수 있습니다. MAXDOP(최대 병렬 처리 수준)를 늘리거나 MAXDOP를 0으로 설정하면 활성 작업자 수가 증가할 수 있습니다.

다음 단계에 따라 부족한 작업자와 관련한 인시던트를 심사합니다.

  1. 차단이 발생하는지 또는 대량의 동시 작업자를 식별할 수 있는지 조사합니다. 다음 쿼리를 실행하여 현재 요청을 검사하고 데이터베이스에서 오류 10928을 반환하는 경우 차단을 검사합니다. 쿼리를 실행하기 위해 DAC(관리자 전용 연결)에 연결해야 할 수 있습니다.

    SELECT
        r.session_id, r.request_id, r.blocking_session_id, r.start_time, 
        r.status, r.command, DB_NAME(r.database_id) AS database_name,
        (SELECT COUNT(*) 
            FROM sys.dm_os_tasks AS t 
            WHERE t.session_id=r.session_id and t.request_id=r.request_id) AS worker_count,
        i.parameters, i.event_info AS input_buffer,
        r.last_wait_type, r.open_transaction_count, r.total_elapsed_time, r.cpu_time,
        r.logical_reads, r.writes, s.login_time, s.login_name, s.program_name, s.host_name
    FROM sys.dm_exec_requests as r
    JOIN sys.dm_exec_sessions as s on r.session_id=s.session_id
    OUTER APPLY sys.dm_exec_input_buffer (r.session_id,r.request_id) AS i
    WHERE s.is_user_process=1;
    GO
    
    1. 차단된 세션을 식별하는 blocking_session_id가 있는 행을 찾습니다. 목록에서 각 blocking_session_id를 찾아 해당 세션도 차단되었는지 여부를 확인합니다. blocking_session_idsession_id 값을 따르면 결국 차단되지는 않지만 차단 중인 세션인 헤드 블로커로 연결됩니다. 헤드 블로커 쿼리를 조정합니다.

      장기 실행 또는 차단 쿼리의 문제 해결에 대한 자세한 내용은 Azure SQL Database 차단 문제 이해 및 해결을 참조하세요.

    2. 대량의 동시 작업자를 식별하기 위해 전체 요청 수와 각 요청의 worker_count 열을 검토합니다. Worker_count는 샘플링된 시간의 작업자 수로, 추후 요청이 실행됨에 따라 변경될 수 있습니다. 최적의 병렬 처리 수준으로 실행되는 동시 쿼리 때문에 작업자가 증가하는 경우, 리소스 사용률을 줄이기 위해 쿼리를 조정합니다. 자세한 내용은 쿼리 튜닝/힌트를 참조하세요.

  2. 데이터베이스의 MAXDOP(최대 병렬 처리 수준) 설정을 평가합니다.

작업자 제한 늘리기

데이터베이스 또는 탄력적 풀이 차단 해결, 쿼리 최적화 및 MAXDOP 설정의 유효성 검사에도 불구하고 지속적으로 작업자 제한에 도달하는 경우, 데이터베이스 또는 탄력적 풀을 스케일 업하여 작업자 제한을 늘리는 것이 좋습니다.

Azure SQL Database의 서비스 계층 및 컴퓨팅 크기별 리소스 제한을 확인하세요.

Azure SQL Database 작업자 리소스 거버넌스에 대해 자세히 알아보세요.

오류 10929: 리소스 ID: 1

10929: Resource ID: 1. The %s minimum guarantee is %d, maximum limit is %d and the current usage for the database is %d. However, the server is currently too busy to support requests greater than %d for this database. See http://go.microsoft.com/fwlink/?LinkId=267637 for assistance. Otherwise, please try again later.

오류 40501: 현재 서비스 사용량이 너무 많습니다.

40501: The service is currently busy. Retry the request after 10 seconds. Incident ID: %ls. Code: %d.

40501 오류는 리소스 한도를 초과했음을 나타내는 엔진 제한 오류입니다.

리소스 한도에 대한 자세한 내용은 Azure SQL Database의 리소스 한도를 참조하세요.

오류 40544: 데이터베이스가 크기 할당량에 도달했습니다.

40544: The database has reached its size quota. Partition or delete data, drop indexes, or consult the documentation for possible resolutions. Incident ID: <ID>. Code: <code>.

이 오류는 데이터베이스가 크기 할당량에 도달했을 때 발생합니다.

다음 단계를 통해 문제를 해결하거나 추가 옵션을 얻을 수 있습니다.

  1. Azure Portal에서 대시보드를 사용하여 데이터베이스의 현재 크기를 확인합니다.

    참고

    가장 많은 공간을 사용하는 테이블을 식별하여 결과적으로 정리가 필요한 잠재적 후보를 찾아내므로 다음 SQL 쿼리를 실행합니다.

    SELECT o.name,
     SUM(p.row_count) AS 'Row Count',
     SUM(p.reserved_page_count) * 8.0 / 1024 AS 'Table Size (MB)'
    FROM sys.objects o
    JOIN sys.dm_db_partition_stats p on p.object_id = o.object_id
    GROUP BY o.name
    ORDER BY [Table Size (MB)] DESC;
    GO
    
  2. 현재 크기가 현재 버전에서 지원하는 최대 크기를 초과하지 않는 경우 ALTER DATABASE를 사용하여 MAXSIZE 설정을 늘릴 수 있습니다.

  3. 데이터베이스가 버전에서 지원하는 최대 크기를 이미 초과하는 경우 다음 단계 중 하나 이상을 시도합니다.

    • 일반 데이터베이스 정리 작업을 수행합니다. 예를 들어 잘라내기/삭제를 사용하여 원치 않는 데이터를 정리하거나 SSIS(SQL Server Integration Services) 또는 bcp(대량 복사 프로그램) 유틸리티를 사용하여 데이터를 이동합니다.
    • 데이터를 분할 또는 삭제하거나 인덱스를 삭제하거나 가능한 해결 방법에 대한 설명서를 참조하십시오.
    • 데이터베이스 크기 조정은 단일 데이터베이스 리소스 확장탄력적 풀 리소스 확장을 참조하세요.

오류 40549: 트랜잭션을 오래 실행하여 세션이 종료됩니다.

40549: Session is terminated because you have a long-running transaction. Try shortening your transaction.

이 오류가 반복적으로 발생하는 경우 다음 단계를 수행하여 문제를 해결해 보세요.

  1. 다음 쿼리를 실행하여 duration_ms 열에 높은 값이 있는 열린 세션을 확인하세요.

    SELECT
        r.start_time, DATEDIFF(ms,start_time, SYSDATETIME()) as duration_ms, 
        r.session_id, r.request_id, r.blocking_session_id,  
        r.status, r.command, DB_NAME(r.database_id) AS database_name,
        i.parameters, i.event_info AS input_buffer,
        r.last_wait_type, r.open_transaction_count, r.total_elapsed_time, r.cpu_time,
        r.logical_reads, r.writes, s.login_time, s.login_name, s.program_name, s.host_name
    FROM sys.dm_exec_requests as r
    JOIN sys.dm_exec_sessions as s on r.session_id=s.session_id
    OUTER APPLY sys.dm_exec_input_buffer (r.session_id,r.request_id) AS i
    WHERE s.is_user_process=1
    ORDER BY start_time ASC;
    GO
    

    input_buffer 열에 sys.fn_MSxe_read_event_stream이라는 쿼리가 표시되는 행을 무시할 수 있습니다. 이러한 요청은 확장 이벤트 세션과 관련이 있습니다.

  2. blocking_session_id 열을 검토하여 차단이 장기 실행 트랜잭션에 기여하는지 검토합니다.

    참고

    Azure SQL Database 차단 문제 해결에 대한 자세한 내용은 Azure SQL Database 차단 문제 이해 및 해결을 참조하세요.

  3. 쿼리는 일괄 처리하는 것이 좋습니다. 일괄 처리에 대한 자세한 내용은 일괄 처리를 사용하여 Azure SQL Database 및 Azure SQL Managed Instance 애플리케이션 성능을 개선하는 방법을 참조하세요.

오류 40551: tempdb 사용량이 너무 많아 세션이 종료됨

40551: The session has been terminated because of excessive TEMPDB usage. Try modifying your query to reduce the temporary table space usage.

이 문제를 해결하려면 아래 단계를 수행합니다.

  1. 임시 테이블 공간 사용량을 줄이기 위해 쿼리를 변경합니다.
  2. 임시 개체가 더 이상 필요하지 않은 경우 삭제합니다.
  3. 테이블을 자르거나 사용하지 않는 테이블을 제거합니다.

오류 40552: 트랜잭션 로그 공간 사용량이 너무 많아 세션이 종료됨

40552: The session has been terminated because of excessive transaction log space usage. Try modifying fewer rows in a single transaction.

이 문제를 해결하려면 다음 방법을 사용해 보세요.

  • 이 문제는 삽입, 업데이트 또는 삭제 작업으로 인해 발생할 수 있습니다. 일괄 처리를 구현하거나 여러 개의 작은 트랜잭션으로 분할하여 즉시 실행되는 행 수를 줄여 보세요.
  • 인덱스 다시 빌드 작업으로 인해 이 문제가 발생할 수 있습니다. 이 문제를 해결하려면 테이블의 영향을 받는 행 수 * (업데이트된 필드의 평균 크기(바이트) + 80)가 2GB 미만(< 2)인지 확인합니다.
  • 인덱스를 다시 빌드하는 경우 업데이트되는 필드의 평균 크기를 평균 인덱스 크기로 대체해야 합니다.
  • 자세한 내용은 Azure SQL Database에서 전체 트랜잭션 로그 문제 해결Azure SQL Managed Instance에서 트랜잭션 로그 오류 문제 해결을 참조하세요.

오류 40553: 메모리 사용량이 너무 많아 세션이 종료됨

40553: The session has been terminated because of excessive memory usage. Try modifying your query to process fewer rows.

이 문제를 해결하려면 쿼리를 최적화해 보세요.

심층 문제 해결 절차는 내 쿼리가 클라우드에서 제대로 실행되나요?를 참조하세요

다른 메모리 부족 오류와 샘플 쿼리에 관한 자세한 내용은 Azure SQL Database를 사용하여 메모리 부족 오류 문제 해결을 참조하세요.

리소스 거버넌스 오류 메시지 표

오류 코드 심각도 설명
10928 20 Resource ID: %d. The %s limit for the database is %d and has been reached. See 'http://go.microsoft.com/fwlink/?LinkId=267637' for assistance.

리소스 ID는 제한에 도달한 리소스를 나타냅니다. 리소스 ID = 1이면 작업자 제한에 도달한 것입니다. 오류 10928: 리소스 ID: 1. 데이터베이스에 대한 요청 제한이 %d이며, 이 제한에 도달했습니다. 리소스 ID = 2인 경우 세션 제한에 도달한 것입니다.
리소스 제한에 대한 자세한 정보:
Azure SQL Database의 리소스 관리.
DTU 구매 모델에 대한 리소스 한도.
단일 데이터베이스에 대한 vCore 기반 한도.
Azure SQL Managed Instance 리소스 한도
10936 20 Resource ID: %d. The %s limit for the elastic pool is %d and has been reached. See 'http://go.microsoft.com/fwlink/?LinkId=267637' for assistance.

리소스 ID는 제한에 도달한 리소스를 나타냅니다. 리소스 ID = 1이면 작업자 제한에 도달한 것입니다. 오류 10936: 리소스 ID: 1. 탄력적 풀의 요청 한도는 %d이며 이 한도에 도달했습니다.에서 자세히 알아보세요. 리소스 ID = 2이면 세션 한도에 도달한 것입니다.
리소스 제한에 대한 자세한 정보:
Azure SQL Database의 리소스 관리.
DTU 구매 모델을 사용한 Elastic Pool의 리소스 한도.
탄력적 풀에 대한 vCore 기반 한도.
Azure SQL Managed Instance 리소스 한도
10929 20 Resource ID: %d. The %s minimum guarantee is %d, maximum limit is %d, and the current usage for the database is %d. However, the server is currently too busy to support requests greater than %d for this database.

리소스 ID는 제한에 도달한 리소스를 나타냅니다. 작업자 스레드의 경우 리소스 ID = 1입니다. 세션의 경우 리소스 ID = 2입니다. 자세한 내용은 다음을 참조하세요.
Azure SQL Database의 리소스 관리.
DTU 구매 모델을 사용한 Elastic Pool의 리소스 한도.
단일 데이터베이스에 대한 vCore 기반 한도.
탄력적 풀에 대한 vCore 기반 한도.
Azure SQL Managed Instance 리소스 한도
나중에 다시 시도하세요.
40544 20 The database has reached its size quota. Partition or delete data, drop indexes, or consult the documentation for possible resolutions.

데이터베이스 크기 조정은 단일 데이터베이스 리소스 확장탄력적 풀 리소스 확장을 참조하세요.
40549 16 Session is terminated because you have a long-running transaction. Try shortening your transaction.

일괄 처리에 대한 자세한 내용은 일괄 처리를 사용하여 Azure SQL Database 및 Azure SQL Managed Instance 애플리케이션 성능을 개선하는 방법을 참조하세요.
40550 16 The session has been terminated because it has acquired too many locks. Try reading or modifying fewer rows in a single transaction.

일괄 처리에 대한 자세한 내용은 일괄 처리를 사용하여 Azure SQL Database 및 Azure SQL Managed Instance 애플리케이션 성능을 개선하는 방법을 참조하세요.
40551 16 The session has been terminated because of excessive tempdb usage. Try modifying your query to reduce the temporary table space usage.

임시 개체를 사용하는 경우 세션에서 더 이상 필요하지 않을 때 임시 개체를 삭제하여 tempdb 데이터베이스의 공간을 절약하세요. SQL Database의 tempdb 제한에 대한 자세한 내용은 SQL Database의 tempdb 데이터베이스를 참조하세요.
40552 16 The session has been terminated because of excessive transaction log space usage. Try modifying fewer rows in a single transaction.

일괄 처리에 대한 자세한 내용은 일괄 처리를 사용하여 Azure SQL Database 및 Azure SQL Managed Instance 애플리케이션 성능을 개선하는 방법을 참조하세요.
bcp.exe 유틸리티 또는 System.Data.SqlClient.SqlBulkCopy 클래스를 사용하여 대량 삽입을 수행하는 경우 -b batchsize 또는 BatchSize 옵션을 사용하여 각 트랜잭션에서 서버로 복사된 행의 수를 제한하세요. ALTER INDEX 문을 사용하여 인덱스를 다시 작성하는 경우 REBUILD WITH ONLINE = ON 옵션을 사용하여 시도하십시오. VCore 구매 모델의 트랜잭션 로그 크기에 대한 자세한 내용은 다음을 참조하세요.
단일 데이터베이스에 대한 vCore 기반 한도.
탄력적 풀에 대한 vCore 기반 한도.
Azure SQL Managed Instance 리소스 한도
40553 16 The session has been terminated because of excessive memory usage. Try modifying your query to process fewer rows.

Transact-SQL 코드에서 ORDER BYGROUP BY 작업의 수를 줄이면 쿼리의 메모리 요구 사항이 줄어듭니다. 데이터베이스 크기 조정은 단일 데이터베이스 리소스 확장탄력적 풀 리소스 확장을 참조하세요. 메모리 부족 오류와 샘플 쿼리에 관한 자세한 내용은 Azure SQL Database를 사용하여 메모리 부족 오류 문제 해결을 참조하세요.

탄력적 풀 오류

다음 오류는 탄력적 풀 만들기 및 사용하기와 관련이 있습니다.

오류 코드 심각도 설명 정정 작업
1132 17 The elastic pool has reached its storage limit. The storage usage for the elastic pool cannot exceed (%d) MBs.

탄력적 풀이 스토리지 용량 한도에 도달했을 때 데이터베이스에 데이터를 기록하려고 했습니다. 리소스 제한에 대한 정보는 다음을 참조하세요.
DTU 구매 모델을 사용한 Elastic Pool의 리소스 한도.
탄력적 풀에 대한 vCore 기반 한도.
가능하다면 탄력적 풀의 DTU를 늘리거나, 늘리고 탄력적 풀에 스토리지를 추가하여 스토리지 용량 한도를 늘리거나, 탄력적 풀에 있는 개별 데이터베이스에서 사용하는 스토리지를 줄이거나, 탄력적 풀에서 데이터베이스를 제거하는 것을 고려하세요. 탄력적 풀 크기 조정에 대한 정보는 탄력적 풀 리소스 크기 조정을 참조하세요. 데이터베이스에서 사용하지 않는 공간을 제거하는 방법에 대한 자세한 내용은 Azure SQL Database에서 데이터베이스용 파일 공간 관리를 참조하세요.
10929 16 The %s minimum guarantee is %d, maximum limit is %d, and the current usage for the database is %d. However, the server is currently too busy to support requests greater than %d for this database.

리소스 제한에 대한 정보는 다음을 참조하세요.
Elastic Pool의 DTU 리소스 한도
탄력적 풀에 대한 vCore 기반 한도.
나중에 다시 시도하세요. 데이터베이스당 DTU/vCore 최솟값, 데이터베이스당 DTU/vCore 최댓값. 탄력적 풀에 있는 전체 데이터베이스의 동시 작업자 수 합계가 풀 한도를 초과하려고 했습니다.
가능하다면 탄력적 풀의 DTU 또는 vCore를 늘려 작업자 한도를 늘리거나 탄력적 풀에서 데이터베이스를 제거하는 것을 고려하세요.
40844 16 Database '%ls' on Server '%ls' is a '%ls' edition database in an elastic pool and cannot have a continuous copy relationship. 해당 없음
40857 16 Elastic pool not found for server: '%ls', elastic pool name: '%ls'. Specified elastic pool does not exist in the specified server. 유효한 탄력적 풀 이름을 입력하세요.
40858 16 Elastic pool '%ls' already exists in server: '%ls'. Specified elastic pool already exists in the specified server. 새 탄력적 풀 이름을 입력하세요.
40859 16 Elastic pool does not support service tier '%ls'. Specified service tier is not supported for elastic pool provisioning. 기본 서비스 계층을 사용하려면 올바른 버전을 제시하거나 서비스 계층을 빈 상태로 두세요.
40860 16 Elastic pool '%ls' and service objective '%ls' combination is invalid. Elastic pool and service tier can be specified together only if resource type is specified as 'ElasticPool'. 탄력적 풀과 서비스 계층의 올바른 조합을 지정하세요.
40861 16 The database edition '%.*ls' cannot be different than the elastic pool service tier which is '%.*ls'. The database edition is different than the elastic pool service tier. 탄력적 풀 서비스 계층과 다른 데이터베이스 버전을 지정하지 마세요. 데이터베이스 버전은 지정할 필요가 없습니다.
40862 16 Elastic pool name must be specified if the elastic pool service objective is specified. Elastic pool service objective does not uniquely identify an elastic pool. 탄력적 풀 서비스 목표를 사용하는 경우 탄력적 풀 이름을 지정하세요.
40864 16 The DTUs for the elastic pool must be at least (%d) DTUs for service tier '%.*ls'. Attempting to set the DTUs for the elastic pool below the minimum limit. 탄력적 풀의 DTU를 최소 한도 이상으로 다시 설정하세요.
40865 16 The DTUs for the elastic pool cannot exceed (%d) DTUs for service tier '%.*ls'. Attempting to set the DTUs for the elastic pool above the maximum limit. 탄력적 풀의 DTU를 최대 한도 미만으로 다시 설정하세요.
40867 16 The DTU max per database must be at least (%d) for service tier '%.*ls'. Attempting to set the DTU max per database below the supported limit. 원하는 설정을 지원하는 탄력적 풀 서비스 계층을 사용하는 것을 고려하세요.
40868 16 The DTU max per database cannot exceed (%d) for service tier '%.*ls'. Attempting to set the DTU max per database beyond the supported limit. 원하는 설정을 지원하는 탄력적 풀 서비스 계층을 사용하는 것을 고려하세요.
40870 16 The DTU min per database cannot exceed (%d) for service tier '%.*ls'. Attempting to set the DTU min per database beyond the supported limit. 원하는 설정을 지원하는 탄력적 풀 서비스 계층을 사용하는 것을 고려하세요.
40873 16 The number of databases (%d) and DTU min per database (%d) cannot exceed the DTUs of the elastic pool (%d). Attempting to specify DTU min for databases in the elastic pool that exceeds the DTUs of the elastic pool. 탄력적 풀의 DTU를 늘리거나, 데이터베이스당 DTU 최소값을 줄이거나, 탄력적 풀에 포함된 데이터베이스 수를 줄이는 것을 고려하세요.
40877 16 An elastic pool cannot be deleted unless it does not contain any databases. The elastic pool contains one or more databases and therefore cannot be deleted. 탄력적 풀을 삭제하려면 탄력적 풀에서 데이터베이스를 제거하세요.
40881 16 The elastic pool '%.*ls' has reached its database count limit. The database count limit for the elastic pool cannot exceed (%d) for an elastic pool with (%d) DTUs. Attempting to create or add database to elastic pool when the database count limit of the elastic pool has been reached. 가능하다면 탄력적 풀의 DTU를 늘려 데이터베이스 한도를 확대하거나 탄력적 풀에서 데이터베이스를 제거하는 것을 고려하세요.
40889 16 The DTUs or storage limit for the elastic pool '%.*ls' cannot be decreased since that would not provide sufficient storage space for its databases. Attempting to decrease the storage limit of the elastic pool below its storage usage. 탄력적 풀에 있는 개별 데이터베이스의 스토리지 사용량을 줄이거나 풀에서 데이터베이스를 제거하여 DTU 또는 스토리지 한도를 줄이는 것을 고려하세요.
40891 16 The DTU min per database (%d) cannot exceed the DTU max per database (%d). Attempting to set the DTU min per database higher than the DTU max per database. 데이터베이스당 DTU 최소값이 데이터베이스당 DTU 최대값을 초과하지 않도록 하세요.
TBD 16 The storage size for an individual database in an elastic pool cannot exceed the max size allowed by '%.*ls' service tier elastic pool. The max size for the database exceeds the max size allowed by the elastic pool service tier. 데이터베이스의 최대 크기를 탄력적 풀 서비스 계층에서 허용하는 최대 크기 한도 내로 설정하세요.

로그인에서 요청한 데이터베이스 "master"를 열 수 없습니다. 로그인에 실패했습니다.

이 문제는 계정에 master 데이터베이스에 대한 액세스 권한이 없기 때문에 발생합니다. 그러나 SSMS(SQL Server Management Studio)는 기본값으로 master 데이터베이스에 연결을 시도합니다.

이 문제를 해결하려면 다음 단계를 따릅니다.

  1. SSMS의 로그인 화면에서 옵션을 선택한 다음 연결 속성을 선택합니다.

  2. 데이터베이스에 연결 필드에서 사용자의 기본 데이터베이스 이름을 기본 로그인 데이터베이스로 입력하고 연결을 선택합니다.

    연결 속성 탭을 보여 주는 SSMS의 커넥트 대화 상자 스크린샷입니다.

읽기 전용 오류

읽기 전용 데이터베이스에 쓰려고 하면 오류가 발생합니다. 일부 시나리오에서는 데이터베이스의 읽기 전용 상태의 원인이 즉시 명확하지 않을 수 있습니다.

오류 3906: 데이터베이스가 읽기 전용이기 때문에 'databaseName' 데이터베이스를 업데이트하지 못했습니다.

읽기 전용 데이터베이스를 수정하려고 하면 다음 오류가 발생합니다.

Msg 3906, Level 16, State 2, Line 1
Failed to update database "%d" because the database is read-only.

데이터베이스가 읽기 전용인 이유에 대한 여러 가지 가능한 설명이 있습니다.

수동 장애 조치(failover) 이후 애플리케이션은 여전히 이전 복제본(replica)에 연결합니다.

Azure SQL Database에서 다른 복제본(replica) 장애 조치(failover) 이후 애플리케이션이 DNS로 인해 이전 주 복제본에 연결될 수 있습니다. 장애 조치(failover) 그룹 연결 라우팅은 DNS를 사용하여 구현됩니다.

가능한 근본 원인:

  1. 장애 조치(failover) 중에는 적절한 DNS 항목의 대상을 변경하여 적절한 새 주 및 새 보조 서버를 가리키도록 장애 조치(failover) 그룹 엔드포인트가 업데이트됩니다. 기본적으로 DNS 항목은 30초의 TTL로 만들어집니다. 즉, DNS 클라이언트는 이러한 항목을 30초 동안 캐시합니다. 따라서 DNS 레코드에 대한 업데이트가 즉시 전파되지는 않으며, 항목은 모든 클라이언트 및 중간 노드가 캐시를 새로 고치기 전까지는 부실합니다. 따라서 장애 조치(failover) 후 로그인이 장애 조치(failover) 그룹 엔드포인트를 새 대상으로 라우팅하는 데 0분에서 약 10분(네트워크 토폴로지에 따라 다름)이 걸릴 수 있습니다. DNS 캐시를 플러시하면 DNS 요청에 응답하는 중간 네트워크 노드도 DNS 결과를 한 시간 동안 캐시하므로 문제가 발생할 수도 있고 그렇지 않을 수도 있습니다.

    이 문제에 대한 권장 해결 방법은 단순히 클라이언트에서 DNS 항목을 새로 고칠 때까지 기다리는 것입니다. 현재 이 해결 방법으로 문제를 10분 내에 자체적으로 해결됨 수 있습니다.

  2. 일부 SQL 클라이언트 라이브러리는 새 데이터베이스 연결이 필요할 때마다 연결을 닫고 다시 열지 않고 동일한 데이터 원본에 대한 연결을 다시 사용하는 "연결 풀링"이라는 기능을 사용합니다. 특히 ADO.NET에서 연결 풀링은 기본적으로 활성화되어 있습니다. 1에 설명된 문제를 결합하면 연결 풀링으로 인해 새로 열린 연결에서 이전 데이터베이스에 대한 연결을 다시 사용할 수 있으므로 애플리케이션이 새 주 데이터베이스에 무기한 연결되지 않도록 할 수 있습니다.

솔루션:

장애 조치(failover) 그룹 장애 조치(failover) 이후 이 DNS 문제에 대한 세 가지 잠재적 해결 방법이 있습니다.

  1. "읽기 전용" 오류가 발생할 때마다 SQLConnection.ClearAllPools 또는 SQLConnection.ClearPool(conn)의 호출을 위해 애플리케이션을 수정합니다.
  2. 애플리케이션 연결 문자열 연결 풀링을 사용하지 않도록 Pooling=False의 지정이 필요합니다. 애플리케이션이 연결을 자주 열고 닫는 경우 성능에 큰 영향을 미칠 수 있으므로 테스트해야 합니다.
  3. DNS 복제본(replica)/캐싱 지연을 방지하는 또 다른 옵션은 3906이 발생한 후 일정 기간 동안 Azure SQL Database 논리 서버 이름(원래 보조 서버의 새 주 서버)을 사용하여 직접 연결하는 것입니다.

읽기 전용 복제본에 연결되어 있을 수 있습니다.

Azure SQL Database 및 Azure SQL Managed Instance 모두 읽기 전용 복제본의 데이터베이스에 연결할 수 있습니다. 이 경우 DATABASEPROPERTYEX() 함수를 사용하는 다음 쿼리는 READ_ONLY를 반환합니다.

SELECT DATABASEPROPERTYEX(DB_NAME(), 'Updateability');
GO

SQL Server Management Studio를 사용하여 연결하는 경우 연결 옵션추가 연결 매개 변수 탭에서 ApplicationIntent=ReadOnly를 지정했는지 확인합니다.

연결 문자열을 사용하는 애플리케이션 또는 클라이언트에서 연결하는 경우 연결 문자열에 ApplicationIntent=ReadOnly가 지정되었는지 유효성 검사합니다. 읽기 전용 복제본에 연결에서 자세히 알아봅니다.

데이터베이스를 읽기 전용으로 설정할 수 있습니다.

Azure SQL Database를 사용하는 경우 데이터베이스 자체가 읽기 전용으로 설정되었을 수 있습니다. 다음 쿼리를 사용하여 데이터베이스 상태를 확인할 수 있습니다.

SELECT name, is_read_only
FROM sys.databases
WHERE database_id = DB_ID();

ALTER DATABASE Transact-SQL을 사용하여 Azure SQL Database에서 데이터베이스의 읽기 전용 상태를 수정할 수 있습니다. 현재 관리되는 인스턴스의 데이터베이스를 읽기 전용으로 설정할 수 없습니다.

연결 문제로 인해 오류가 발생했는지 확인

연결 문제로 인해 오류가 발생했는지 확인하려면 호출을 표시하는 프레임에 대한 스택 추적을 검토하여 다음과 같은 연결을 엽니다(SqlConnection 클래스에 대한 참조 확인).

System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
 at System.Data.SqlClient.SqlConnection.Open()
 at AzureConnectionTest.Program.Main(String[] args)
ClientConnectionId:<Client connection ID>

예외가 쿼리 문제로 인해 트리거되는 경우 다음과 유사한 호출 스택이 표시됩니다(SqlCommand 클래스에 대한 참조 확인). 이 경우 쿼리를 조정합니다.

  at System.Data.SqlClient.SqlCommand.ExecuteReader()
  at AzureConnectionTest.Program.Main(String[] args)
  ClientConnectionId:<Client ID>

미세 조정 성능에 대한 더 많은 정보는 다음 리소스를 참조하세요.