잘못된 데이터베이스를 사용한 autovacuum 동작 이해 - Amazon Relational Database Service

잘못된 데이터베이스를 사용한 autovacuum 동작 이해

DROP DATABASE 작업 도중에 중단된 데이터베이스를 유효하지 않은 것으로 나타내는 새 -2 값이 pg_database 카탈로그의 datconnlimit 열에 도입되었습니다.

이 새 값은 다음과 같은 RDS for PostgreSQL 버전에서 사용할 수 있습니다.

  • 15.4 이상의 모든 버전

  • 14.9 이상 버전

  • 13.12 이상 버전

  • 12.16 이상 버전

  • 11.21 이상 버전

잘못된 데이터베이스는 유효한 데이터베이스의 기능을 중지하는 autovacuum 기능에 영향을 주지 않습니다. autovacuum은 잘못된 데이터베이스를 무시합니다. 따라서 PostgreSQL 환경의 모든 유효한 데이터베이스에 대해 정기적인 vacuum 작업이 계속해서 적절하고 효율적으로 작동합니다.

트랜잭션 ID 모니터링

age(datfrozenxid) 함수는 일반적으로 데이터베이스의 트랜잭션 ID(XID) 수명을 모니터링하여 트랜잭션 ID 랩어라운드를 방지하는 데 사용됩니다.

유효하지 않은 데이터베이스는 autovacuum에서 제외되므로, 트랜잭션 ID(XID) 횟수가 최대값인 2 billion에 도달하여 - 2 billion로 순환하며 이 주기를 무한정 계속할 수 있습니다. 트랜잭션 ID 랩어라운드를 모니터링하는 일반적인 쿼리는 다음과 같습니다.

SELECT max(age(datfrozenxid)) FROM pg_database;

그러나 datconnlimit에 대한 -2 값이 도입되면 잘못된 데이터베이스가 이 쿼리의 결과를 왜곡할 수 있습니다. 이러한 데이터베이스는 유효하지 않으며 정기적인 유지 관리 검사에 포함되어서는 안 되므로, 오탐을 유발할 수 있어 실제보다 age(datfrozenxid)가 높다고 믿게 됩니다.

모니터링 쿼리 조정

정확한 모니터링을 위해서는 잘못된 데이터베이스를 제외하도록 모니터링 쿼리를 조정해야 합니다. 다음 권장 쿼리를 따르세요.

SELECT max(age(datfrozenxid)) FROM pg_database WHERE datconnlimit <> -2;

이 쿼리를 사용하면 PostgreSQL 환경 전체의 트랜잭션 ID 사용 기간을 정확하게 반영하여 유효한 데이터베이스만 age(datfrozenxid) 계산에 고려합니다.

잘못된 데이터베이스 문제 해결

잘못된 데이터베이스에 연결하려고 하면 다음과 같은 오류 메시지가 표시될 수 있습니다.

postgres=> \c db1 connection to server at "mydb.xxxxxxxxxx.us-west-2.rds.amazonaws.com" (xx.xx.xx.xxx), port xxxx failed: FATAL: cannot connect to invalid database "db1" HINT: Use DROP DATABASE to drop invalid databases. Previous connection kept

또한, log_min_messages 파라미터가 DEBUG2 이상으로 설정된 경우 autovacuum 프로세스가 잘못된 데이터베이스를 건너뛰고 있음을 나타내는 다음과 같은 로그 항목을 확인할 수 있습니다.

2024-07-30 05:59:00 UTC::@:[32000]:DEBUG: autovacuum: skipping invalid database "db6" 2024-07-30 05:59:00 UTC::@:[32000]:DEBUG: autovacuum: skipping invalid database "db1"

이 문제를 해결하려면 연결 시도 중에 제공된 HINT를 따르세요. RDS 마스터 계정 또는 rds_superuser 역할이 있는 데이터베이스 계정을 사용하여 유효한 데이터베이스에 연결하고 잘못된 데이터베이스를 삭제합니다.

SELECT 'DROP DATABASE ' || quote_ident(datname) || ';' FROM pg_database WHERE datconnlimit = -2 \gexec