태그 보관물: postgresql

postgresql

“트랜잭션 ID 랩 어라운드”정보 달려 있습니다. 현재 트랜잭션의 XID보다 큰 삽입

이제 “트랜잭션 ID 랩 어라운드”에 대한 문서를 읽었지만 실제로 이해하지 못하는 것이 있습니다. 문서는 다음 URL입니다.
http://www.postgresql.org/docs/9.0/static/routine-vacuuming .html # VACUUM-FOR-WRAPAROUND

23.1.4. 트랜잭션 ID 랩 어라운드 실패 방지

PostgreSQL의 MVCC 트랜잭션 시맨틱은 트랜잭션 ID (XID) 번호를 비교할 수 있는지에 달려 있습니다. 현재 트랜잭션의 XID보다 큰 삽입 XID를 가진 행 버전은 “미래에 있으며”현재 트랜잭션에 표시되지 않아야합니다. 그러나 트랜잭션 ID의 크기 (32 비트)가 제한되어 있기 때문에 (40 억 건 이상의 트랜잭션) 오랫동안 실행되는 클러스터는 트랜잭션 ID 랩 어라운드를 겪을 수 있습니다. XID 카운터는 0으로 줄어 듭니다. 과거는 미래에있는 것으로 보입니다. 즉, 결과가 보이지 않습니다. 요컨대, 치명적인 데이터 손실. (실제로 데이터는 여전히 존재하지만 데이터를 얻을 수 없으면 냉정한 편입니다.)이를 피하려면 적어도 20 억 건의 트랜잭션마다 모든 데이터베이스의 모든 테이블을 진공 청소기로 청소해야합니다.

“트랜잭션 ID 랩 어라운드가 발생할 수 있습니다. XID 카운터가 0으로 줄어 듭니다. 과거에 발생한 모든 갑작스런 트랜잭션은 미래에있는 것으로 보입니다. 즉, 결과가 보이지 않습니다.”

누군가 이것을 설명 할 수 있습니까? 데이터베이스가 트랜잭션 ID를 겪은 후에 왜 과거에 있던 트랜잭션이 미래에 나타나는 것처럼 보입니까? 요컨대, postgreSQL이 autovacuum에 의한 트랜잭션 ID 랩핑 후 “데이터 손실”상황에 있는지 알고 싶습니다.

개인적인 견해로는 출력이 64 비트이고 순환되지 않는 txid_current () 함수를 사용하여 현재 트랜잭션 ID를 얻을 수 있습니다. 따라서 xmin으로 알려진 튜플의 삽입 트랜잭션 ID는 얻는 xid보다 신경이 더 큽니다. txid_current () 함수에 의해. PostgreSQL 서버를 종료 한 후 pg_resetxlog 재설정 재설정 트랜잭션 ID를 사용한다는 점을 제외하고. 내가 맞아? 감사



답변

데이터베이스가 트랜잭션 ID를 겪은 후에 왜 과거에 있던 트랜잭션이 미래에 나타나는 것처럼 보입니까?

그들은하지 않습니다. 인용 된 텍스트는 postgres가 modulo 2 31 산술 을 사용해야하는 이유를 설명합니다 (오래된 거래가 충분히 일찍 얼어 붙으면 거래가 끝날 수 있음을 의미합니다).

일반 XID는 모듈로 -2 ^ 31 산술을 사용하여 비교됩니다. 이는 모든 일반 XID에 대해 “더 오래된”20 억 개의 XID와 “더 새로운”20 억 개의 XID가 있음을 의미합니다.

구체적으로 말하면 :

이전 행 버전에 XID FrozenXID가 20 억 건의 이전 마크에 도달하기 전에 언젠가 다시 할당해야합니다.

XID를 감싸면 문제가 발생합니다. 이를 방지하기 위해 postgres는 경고를 시작하고 필요한 경우 종료하고 새 트랜잭션을 시작하지 않습니다.

어떤 이유로 autovacuum이 테이블에서 오래된 XID를 지우지 못하는 경우 데이터베이스의 가장 오래된 XID가 랩 어라운드 지점에서 천만 건의 트랜잭션에 도달하면 시스템은 다음과 같은 경고 메시지를 표시합니다.

WARNING:  database "mydb" must be vacuumed within 177009986 transactions
HINT:  To avoid a database shutdown, execute a database-wide VACUUM in "mydb". 

(수동 VACUUM은 힌트에서 제안한대로 문제를 해결해야하지만 VACUUM은 수퍼 유저가 수행해야합니다. 그렇지 않으면 시스템 카탈로그를 처리하지 못하므로 데이터베이스의 datfrozenxid를 진행시킬 수 없습니다.) 무시 될 때까지 시스템이 종료되고 1 백만 건 미만의 트랜잭션이 남아 있으면 새 트랜잭션 시작을 거부합니다.

다시 말해, “과거에 있었던 거래는 미래에있는 것으로 보인다”및 “데이터 손실”은 전적으로 이론적 인 것이며 실제로 트랜잭션 ID 랩 어라운드에 의해 야기되지는 않습니다.


답변

붙여 넣은 블록이 질문에 대답하는 것 같습니다. 그것은 모두 ‘미래’거래를 숨기는 데 사용되는 논리에 달려 있습니다.

트랜잭션 ID (XID) 카운터는 32 비트로 제한되며 이전 최대 트랜잭션을 바꾸지 않고 다음 숫자에 도달하면 0에서 새로 시작됩니다.

글쎄, 지금은 0이므로 PostgreSQL은 0보다 큰 모든 트랜잭션을 숨기고 있습니다. 따라서 트랜잭션 # 2,147,483,633은 20 초 전에 발생했지만 PostgreSQL은 다른 2,147,483,633 트랜잭션에서는 발생하지 않을 것이라고 생각합니다.


답변