다음을 통해 공유


복구 충돌로 인한 문 취소

적용 대상: Azure Database for PostgreSQL - 유연한 서버

이 문서는 읽기 복제본에 대한 쿼리를 실행하는 동안 발생하는 문제를 해결하는 데 도움이 됩니다.

증상

  1. 읽기 복제본에서 쿼리를 실행하려고 하면 쿼리가 예기치 않게 종료됩니다.
  2. "복구와 충돌하여 문 취소"와 같은 오류 메시지가 로그 또는 쿼리 출력에 표시됩니다.
  3. 주 복제본에서 읽기 복제본으로의 복제에 상당한 지연 또는 지연이 있을 수 있습니다.

제공된 스크린샷의 왼쪽에는 기본 Azure Database for PostgreSQL 유연한 서버 인스턴스가 있고 오른쪽에는 읽기 복제본이 있습니다.

복구 오류와 충돌하여 취소 문을 트리거하는 것을 보여 주는 스크린샷

  • 읽기 복제본 콘솔(위의 스크린샷 오른쪽)
    • SELECT 문이 진행 중인 것을 확인할 수 있습니다. SQL에 대해 유의해야 할 중요한 관점은 데이터에 대한 일관된 보기입니다. SQL 문이 실행되면 기본적으로 데이터 보기를 "중지"합니다. 전체 실행 과정에서 SQL 문은 변경 내용이 다른 곳에서 동시에 발생하는 경우에도 항상 데이터의 일관된 스냅샷을 확인합니다.
  • 주 콘솔(위 스크린샷의 왼쪽)
    • UPDATE 작업이 실행되었습니다. UPDATE 자체에서 읽기 복제본의 동작을 늘 방해하는 것은 아니지만 후속 작업에서는 그렇습니다. 업데이트 후에는 VACUUM 작업(이 경우 데모용으로 수동으로 트리거되지만 autovacuum 프로세스를 자동으로 시작할 수도 있음)이 실행됩니다.
    • VACUUM의 역할은 이전 버전의 행을 제거하여 공간을 회수하는 것입니다. 읽기 복제본이 긴 SELECT 문을 실행하고 있는 경우, VACUUM의 제거 대상인 이러한 행 중 일부에 현재 액세스하고 있습니다.
    • 행 제거를 포함하는 VACUUM 작업에서 시작된 이러한 변경 내용은 WAL(Write-Ahead Log)에 로그인됩니다. Azure Database for PostgreSQL 유연한 서버 읽기 복제본은 원시 PostgreSQL 물리적 복제를 활용하므로 이러한 변경 내용은 나중에 읽기 복제본으로 전송됩니다.
    • 다음은 문제의 핵심입니다. VACUUM 작업이, 읽기 복제본에서 진행 중인 SELECT 문을 인지하지 못하여 읽기 복제본에 필요한 행을 제거합니다. 이 시나리오는 복제 충돌로 알려진 결과를 초래합니다.

이 시나리오의 여파로 VACUUM 작업에서 제거된 행으로 인해 읽기 복제본에 복제 충돌이 발생합니다. 기본적으로 읽기 복제본은 max_standby_streaming_delay 기본값인 30초로 설정되므로 30초 동안 이 충돌을 해결하려고 시도합니다. 이 기간이 지나면 충돌이 해결되지 않은 상태로 유지되면 읽기 복제본의 쿼리가 취소됩니다.

원인

이 문제의 근본 원인은 Azure Database for PostgreSQL 유연한 서버의 읽기 복제본이 지속적으로 복구되는 시스템이라는 것입니다. 이 상황은 복제본이 주 복제본을 따라잡는 동안 기본적으로 일정한 복구 상태에 있음을 의미합니다. 읽기 복제본의 쿼리가 복구 프로세스에 의해 동시에 업데이트되는 행을 읽으려고 하면(주 복제본이 변경되었기 때문에) Azure Database for PostgreSQL 유연한 서버가 쿼리를 취소하여 복구가 중단 없이 진행되도록 할 수 있습니다.

해결

  1. 조정max_standby_streaming_delay: 읽기 복제본에서 max_standby_streaming_delay 매개 변수 값을 높입니다. 설정 값을 높이면 복제본이 쿼리 취소를 결정하기 전에 충돌을 해결하는 데 더 많은 시간을 할애할 수 있습니다. 그러나 이로 인해 복제 지연 시간이 증가할 수 있으므로 상호 절충이 있습니다. 이 매개 변수는 동적이므로 서버를 다시 시작할 필요 없이 변경 내용이 적용됩니다.
  2. 모니터링 및 쿼리 최적화: 읽기 복제본에 대해 실행되는 쿼리의 형식 및 빈도를 검토합니다. 장기 실행 또는 복잡한 쿼리는 충돌에 더 취약할 수 있습니다. 최적화 또는 다르게 예약하는 것이 도움이 될 수 있습니다.
  3. 사용량이 낮은 쿼리 실행: 사용량이 많은 시간 동안 또는 장기 실행 쿼리를 실행하여 충돌 가능성을 줄이는 것이 좋습니다.
  4. 사용hot_standby_feedback: 읽기 복제본에서 hot_standby_feedbackon으로 설정하는 것이 좋습니다. 사용하도록 설정하면 복제본에서 현재 실행 중인 쿼리에 대해 주 서버에 알릴 수 있습니다. 이렇게 하면 주 데이터베이스가 복제본에 필요한 행을 제거하지 못하게 하여 복제 충돌이 발생할 가능성을 줄입니다. 이 매개 변수는 동적이므로 서버를 다시 시작할 필요 없이 변경 내용이 적용됩니다.

주의

hot_standby_feedback을 사용할 경우 다음과 같은 잠재적 문제가 발생할 수 있습니다.

  • 이 설정은 주 데이터베이스에서 필요한 정리 작업을 방지할 수 있으며, 이로 인해 테이블 블로트(오래된 행 버전으로 인해 디스크 공간 사용량이 증가함)가 발생할 수 있습니다.
  • 기본 디스크 공간 및 테이블 크기를 정기적으로 모니터링하는 것이 중요합니다. 여기에서 Azure Database for PostgreSQL 유연한 서버의 모니터링에 대해 자세히 알아보세요.
  • 문제가 있는 경우 잠재적인 테이블 블로트를 수동으로 관리할 수 있게 대비합니다. 이 문제를 완화하려면 Azure Database for PostgreSQL 유연한 서버에서 자동 진공 튜닝을 사용하도록 설정하는 것이 좋습니다.
  1. 조정 max_standby_archive_delay: max_standby_archive_delay 서버 매개 변수는 보관된 WAL 데이터를 읽을 때 서버에서 허용하는 최대 지연 시간을 지정합니다. Azure Database for PostgreSQL 유연한 서버 인스턴스의 복제본이 스트리밍 모드에서 파일 기반 로그 전달로 전환되는 경우(드물지만) 이 값을 조정하면 쿼리 취소 문제를 해결하는 데 도움이 될 수 있습니다.