이 페이지에서는 Spanner 오류 코드와 이러한 오류를 처리하기 위한 권장 조치를 설명합니다. Spanner를 포함한 Google API는 google.rpc.Code를 통해 정의된 표준 오류 코드를 사용합니다.
Spanner 요청이 성공하면 API는 응답 본문에서 요청된 데이터와 함께 HTTP 200 OK 상태 코드를 반환합니다.
요청이 실패하면 Spanner API는 실패를 일반적으로 식별하는 HTTP 4xx 또는 5xx 상태 코드와 함께 실패를 초래한 오류에 대한 구체적인 정보를 제공하는 응답을 반환합니다.
응답 객체에는 단일 error 필드가 포함되고 값에는 다음 요소가 포함되어 있습니다.
| 요소 | 설명 |
|---|---|
code |
요청 실패를 전반적으로 식별하는 HTTP 상태 코드 |
message |
요청 실패에 대한 자세한 정보 |
status |
Google API의 표준 오류 코드(google.rpc.Code)입니다. Spanner API에서 반환할 수 있는 코드는 오류 코드에 나열되어 있습니다. |
application/x-protobuf 콘텐츠 유형으로 생성된 요청으로 인해 오류가 발생한 경우에는 페이로드로 직렬화된 google.rpc.Status 메시지가 반환됩니다.
오류 코드
오류를 분류하는 좋은 방법은 표준 오류 코드(google.rpc.Code) 값을 검사하는 것입니다. JSON 오류에서 이 코드는 status 필드에 표시됩니다. application/x-protobuf 오류에서는 code 필드에 표시됩니다.
| 오류 코드 | 설명 | 권장 조치 |
|---|---|---|
ABORTED |
작업이 취소되었습니다. 대개 시퀀서 확인 실패, 트랜잭션 취소 등의 동시 실행 문제가 원인입니다. 요청이 다른 요청과 충돌했음을 나타냅니다. | 비트랜잭션 커밋의 경우: 요청을 다시 시도하거나 항목을 구조화하여 경합을 줄입니다. 트랜잭션 커밋의 일부인 요청의 경우: 전체 트랜잭션을 다시 시도하거나 항목을 구조화하여 경합을 줄입니다. |
ALREADY_EXISTS |
클라이언트에서 만들려고 시도한 항목이 이미 존재합니다(예: 기존 기본 키가 있는 행 삽입). | 문제를 해결하지 않은 상태로 다시 시도하지 마세요. |
CANCELLED |
작업이 취소되었습니다. 대개 호출자에 의해 취소됩니다. | 작업을 재시도합니다. |
DEADLINE_EXCEEDED |
작업을 완료하기 전에 기한이 지났습니다. | 기한이 충분한지 조사합니다. 응답이 유용한 실제 시간에 해당하는 기한을 사용하세요. 시스템의 상태를 변경하는 작업의 경우 작업이 정상적으로 완료되어도 오류가 반환될 수 있습니다. 도움말은 기한 초과 오류 문제 해결을 참조하세요. |
FAILED_PRECONDITION |
요청의 전제 조건이 충족되지 않아 작업이 거부되었습니다. 오류 응답의 메시지 필드는 충족하지 못한 전제조건에 대한 정보를 제공합니다. 예를 들어 최대 타임스탬프 비활성을 초과한 타임스탬프에서 읽거나 쿼리하는 경우입니다. | 문제를 해결하지 않은 상태로 다시 시도하지 마세요. |
INTERNAL |
서버에서 오류를 반환했습니다. 기본 시스템에서 예상하는 불변성이 손상되었습니다. | 오류의 구체적인 상황과 원인을 이해하지 않는 한 다시 시도하지 마세요. |
INVALID_ARGUMENT |
클라이언트가 잘못된 값을 지정했습니다. 오류 응답의 메시지 필드에서 어떤 값이 잘못되었는지에 대한 정보를 제공합니다. | 문제를 해결하지 않은 상태로 다시 시도하지 마세요. |
NOT_FOUND |
항목 업데이트, 테이블 또는 열 쿼리와 같은 요청된 항목이 존재하지 않음을 나타냅니다. | 문제를 해결하지 않은 상태로 다시 시도하지 마세요. |
OUT_OF_RANGE |
유효한 범위를 벗어나는 작업을 시도했습니다. | 문제를 해결하지 않은 상태로 다시 시도하지 마세요. |
PERMISSION_DENIED |
사용자가 요청을 보낼 권한이 없습니다. | 문제를 해결하지 않은 상태로 다시 시도하지 마세요. |
RESOURCE_EXHAUSTED |
일부 리소스가 소진되었습니다. 관리자 영역의 경우, 프로젝트의 할당량을 초과하거나 전체 파일 시스템의 저장 공간이 모두 사용되었을 수 있습니다. 데이터 영역의 경우, Spanner 노드에 과부하가 발생한 경우 이러한 문제가 발생할 수 있습니다. 자세한 내용은 세션 관련 오류 코드를 참고하세요. |
관리자 영역의 경우 Spanner 또는 프로젝트 할당량을 초과하지 않았는지 확인합니다. 할당량을 초과한 경우 할당량 상향을 요청하거나 할당량이 재설정될 때까지 기다린 후 다시 시도하세요. 지수 백오프를 사용하도록 재시도를 구성합니다. 데이터 영역의 경우 Spanner 노드가 용량을 초과하지 않았는지 확인합니다. Spanner는 클라이언트 라이브러리에서 이러한 오류를 재시도합니다. 모든 재시도가 실패하면 흐름 제어 메커니즘 오류를 참조하세요. 일반적으로 애플리케이션에 RESOURCE_EXHAUSTED 오류가 발생하면 이 상황을 UNAVAILABLE 오류처럼 처리하고 지수 백오프를 사용해 다시 시도합니다. |
UNAUTHENTICATED |
요청에 작업과 관련된 올바른 사용자 인증 정보가 없습니다. | 문제를 해결하지 않은 상태로 다시 시도하지 마세요. |
UNAVAILABLE |
서버를 사용할 수 없습니다. | 지수 백오프를 사용하여 다시 시도하세요. 멱등성이 없는 작업을 재시도하는 것이 항상 안전한 것은 아닙니다. |
UNIMPLEMENTED |
작업이 구현되지 않았거나 이 서비스에서 지원되지 않거나 사용 설정되지 않았습니다. | 문제를 해결하지 않은 상태로 다시 시도하지 마세요. |
UNKNOWN |
서버에서 알 수 없는 오류를 반환했습니다. 오류 정보를 충분히 반환하지 않는 API에서 발생한 오류가 이 오류로 변환될 수 있습니다. | 요청이 안전한지 확인합니다. 그런 다음 지수 백오프로 다시 시도합니다. |
세션 오류
Spanner는 세션을 사용하여 애플리케이션과 데이터베이스 간의 상호작용을 관리합니다. 세션은 데이터베이스에 대한 연결을 나타내며 읽기 및 쓰기와 같은 작업을 용이하게 합니다.
애플리케이션에서 발생할 수 있는 일반적인 세션 관련 오류는 다음과 같습니다.
세션을 찾을 수 없음
Session not found 오류는 애플리케이션이 더 이상 존재하지 않는 세션을 사용하려고 할 때 발생합니다. 여러 이유로 이 문제가 발생할 수 있습니다.
클라이언트 애플리케이션이 세션을 명시적으로 삭제할 수 있습니다. 예를 들어 코드에서 데이터베이스 클라이언트를 닫거나
deleteSessionsAPI를 직접 호출하면 세션이 삭제됩니다. Spanner 클라이언트 라이브러리 중 하나를 사용하지 않는 경우 이 오류가 발생하면 새 세션을 만드세요. 세션 풀에 새 세션을 추가하고 풀에서 삭제된 세션을 삭제합니다.또한 Spanner는 특정 조건에서 세션을 자동으로 삭제합니다.
1시간 이상 유휴 상태로 유지되면 세션을 삭제합니다. 다운스트림 처리가 세션 유휴 시간 제한보다 오래 걸리는 데이터 스트림 작업에서 발생할 수 있습니다. Dataflow 작업을 사용하는 경우 Dataflow 파이프라인에서 Spanner 읽기 후에
Reshuffle변환 작업을 추가합니다. 이렇게 하면 Spanner 읽기 작업이 후속 장기 실행 처리 단계에서 분리될 수 있습니다.또한 Spanner는 28일이 지난 세션을 삭제합니다. 클라이언트 라이브러리를 사용하는 경우 이러한 사례는 자동으로 처리됩니다. Spanner 클라이언트 라이브러리 중 하나를 사용하지 않는 경우 이 오류가 발생하면 새 세션을 만드세요. 세션 풀에 새 세션을 추가하고 풀에서 삭제된 세션을 삭제합니다.
Spanner 클라이언트 라이브러리 중 하나를 사용하는 경우 라이브러리에서 세션을 자동으로 관리합니다. 이 오류가 발생하면 데이터베이스 클라이언트를 닫는 등 코드가 세션을 명시적으로 삭제하지 않는지 확인하세요. 클라이언트 라이브러리의 세션 관리 문제로 인해 발생할 수도 있습니다.
리소스가 소진됨
RESOURCE_EXHAUSTED: No session available in the pool 또는 RESOURCE_EXHAUSTED: Timed out after waiting X ms for acquiring session 오류는 애플리케이션이 세션 풀에서 세션을 획득할 수 없음을 나타냅니다. 이는 새 읽기 또는 쓰기 요청을 처리할 수 있는 세션이 없는 경우 발생합니다.
다음 표에서는 이러한 오류를 일으킬 수 있는 몇 가지 이유와 해당 권장 조치를 설명합니다.
| 이유 | 권장 조치 |
|---|---|
| 풀의 모든 세션이 사용 중입니다. 애플리케이션이 구성된 최대 세션 수보다 많은 동시 요청을 수신할 수 있습니다. 풀의 모든 세션이 사용 중이며 새 요청에 사용할 수 있는 세션이 없습니다. |
다중화 세션 사용 설정
다중화 세션을 사용하면 여러 트랜잭션과 읽기가 단일 세션을 공유할 수 있으므로 애플리케이션에 필요한 총 세션 수를 줄일 수 있습니다. 세션 풀 설정에서 maxSession 또는 minSession 구성을 늘릴 수도 있습니다. |
| 요청을 완료하는 데 시간이 오래 걸립니다. 장기 실행 읽기 또는 쓰기 요청은 사용 가능한 모든 세션을 장기간 점유할 수 있습니다. 이러한 요청이 세션 획득 시간 제한 설정보다 오래 걸리면 새 요청이 세션 풀에서 세션을 획득할 수 없습니다. | 요청을 완료하는 데 시간이 오래 걸리는 이유를 조사합니다. 쿼리 또는 애플리케이션 로직을 최적화하여 실행 시간을 줄입니다. 세션 획득 시간 제한 설정을 늘릴 수 있습니다. 적격한 클라이언트 라이브러리에 대해 다중화 세션을 사용 설정하여 세션 활용률을 높일 수도 있습니다. |
| 세션이 유출됩니다. 세션 유출은 애플리케이션이 풀에서 세션을 체크아웃했지만 요청을 완료한 후 반환하지 않는 경우에 발생합니다. 이 문제는 일반적으로 코드에서 반복자나 결과 집합이 제대로 닫히지 않을 때 발생합니다. 모든 세션이 누수되면 새 요청에 사용할 수 있는 세션이 없습니다. | 애플리케이션 코드를 디버그하여 세션 누수를 식별하고 수정합니다. 코드가 모든 반복자와 결과 집합을 올바르게 닫는지 확인합니다. 자세한 내용은 세션 누수 감지 솔루션을 참고하세요. 세션 유출 자동 정리 기능을 사용하여 비활성 트랜잭션을 자동으로 해결하도록 세션 풀을 설정할 수도 있습니다. |
세션 생성이 느립니다. 세션 생성은 계산 비용이 많이 드는 작업입니다. 클라이언트 라이브러리는 BatchCreateSessions API를 전송하여 초기 세션을 만들고 (minSession 구성 기반) CreateSessions API를 전송하여 추가 세션을 만듭니다 (maxSession까지). 세션 생성 시간이 세션 획득 제한 시간 설정보다 길어지면 세션을 기다리는 동안 새 요청의 시간이 초과될 수 있습니다. |
BatchCreateSessions 및 CreateSessions API 호출의 지연 시간을 확인합니다. 세션 생성이 느린 것은 Spanner 측의 리소스 문제 또는 다수의 동시 세션 생성 작업 때문일 수 있습니다. |
흐름 제어 메커니즘 오류
Spanner는 다음 조건에서 과부하를 방지하기 위해 흐름 제어 메커니즘을 활성화할 수 있습니다.
- Spanner 노드에서 CPU 사용량이 많습니다. 요청으로 인해 CPU 사용량이 높은 것으로 의심되는 경우 CPU 사용률 측정항목을 사용하여 문제를 조사할 수 있습니다.
- 요청 처리 시간이 늘어나는 부하 집중이 있을 수 있습니다. 요청으로 인해 부하 집중이 발생하는 것으로 의심되면 데이터베이스에서 부하 집중 찾기를 참조하여 문제를 조사하세요. 자세한 내용은 키 시각화 도구를 참조하세요.
흐름 제어 메커니즘은 다음 클라이언트 라이브러리에서 지원됩니다.
흐름 제어 메커니즘을 사용해도 요청이 완료되는 데 걸리는 전체 시간은 늘어나지 않습니다. 이 메커니즘이 없으면 Spanner는 요청을 처리하기 전에 대기하고 결국 DEADLINE_EXCEEDED 오류를 반환합니다.
흐름 제어 메커니즘이 활성 상태이면 Spanner는 재시도하도록 요청을 클라이언트에 다시 푸시합니다. 재시도로 사용자가 제공한 기한 전체가 소진되면 클라이언트에 RESOURCE_EXHAUSTED 오류가 수신됩니다.
이 오류는 Spanner에서 요청의 처리 시간이 너무 길다고 추정하는 경우 반환됩니다. 오류는 흐름 제어를 전파하고 Spanner는 내부적으로 재시도를 누적하는 대신 클라이언트에 요청을 재시도합니다. 이렇게 하면 Spanner가 추가 리소스 소비를 누적하지 않습니다.