잠금 대기중인 PostgreSQL ALTER TABLE 쿼리를 취소하는 것이 안전합니까?


10

우리는 ALTER TABLE몇 시간 전에 쿼리를 시작했으며 최근에야 pg_stat_activity잠금을 기다리고 있음을 깨달았습니다 . 우리는 변경하려는 테이블에 잠금을 유지하고 놓지 않는 다른 쿼리를 발견했습니다.

쿼리는 "단순한"쿼리 (열 데이터 유형 변경)이지만 대규모 테이블에서 실행 중입니다.

잠금을 유지하고있는 프로세스를 종료하는 대신에을 종료하기로 결정했습니다 ALTER TABLE.

우리는 거래를 포장 하지 않았습니다ALTER TABLE .

내가 이해하는 한, 쿼리가 잠금을 기다리고 있다는 것은 항상 잠금을 기다리고 있었고 아무것도 변경하지 않았다는 것을 의미합니다.

이것이 사실입니까? ALTER TABLE검색어 를 완전히 취소해도 안전 합니까? 아니면 쿼리가 이미 무언가를 수정하고 취소하면 데이터베이스가 중간 정도의 상태가 될 수 있습니까?

추신 : 계획은을 (를) 사용하여 취소하는 것 SELECT pg_cancel_backend(pid);입니다. 이것이 나쁜 생각이라면 알려주십시오.


1
ALTER TABLE을 취소해야합니다. PostgreSQL에는 트랜잭션 DDL이 있으므로 ALTER TABLE을 전혀 실행하지 않은 것과 같은 상태로 남아 있어야합니다.
Josh Kupershmidt

따라서 PostgreSQL에 트랜잭션 DDL이 있다고 말하면 스키마 변경 쿼리가 본질적으로 트랜잭션 내에서 실행된다는 의미입니까?
JMTyler

1
"ALTER TABLE을 트랜잭션에 래핑하지 않았습니다."라고 말했기 때문에 ALTER TABLE은 "트랜잭션 내부에서 본질적으로 실행"되었습니다. 그래도 원한다면 BEGIN을 쓸 수 있습니다. ALTER TABLE foo ...; ALTER TABLE 바 ...; 등; 범하다; 이것이 트랜잭션 DDL을 갖는 PostgreSQL의 진정한 킬러 ​​기능입니다. 그러나 당장의 상황에서, ALTER TABLE 자체는 안전하게 취소 할 수 있으며 마치 발생한 적이없는 것처럼 롤백됩니다.
Josh Kupershmidt

빠른 답변 감사합니다! 이것은 매우 좋은 정보입니다. 답변으로 게시하여 수락 된 것으로 표시 할 수 있습니까?
JMTyler

답변:


13

내가 이해하는 한, 쿼리가 잠금을 기다리고 있다는 것은 항상 잠금을 기다리고 있었고 아무것도 변경하지 않았다는 것을 의미합니다.

오른쪽-ALTER TABLE에 대해 pg_stat_activity.waiting이 "true"인 경우 대상 테이블에서 ACCESS EXCLUSIVE 잠금 및 실제 작업 (필요한 경우 테이블 다시 작성, 카탈로그 변경)을 참을성있게 기다리는 것을 의미합니다 , 색인 다시 작성 등)이 아직 시작되지 않았습니다.

ALTER TABLE 쿼리를 완전히 취소해도 안전합니까? 아니면 쿼리가 이미 무언가를 수정하고 취소하면 데이터베이스가 중간 정도의 상태가 될 수 있습니까?

PostgreSQL에서 쿼리를 취소하거나 트랜잭션을 롤백하면 특정 데이터베이스에서 발생할 수있는 데이터베이스 손상 위험이 없습니다 (예 : 이 페이지 하단의 끔찍한 경고 ). 그렇기 때문에 최근 수퍼 유저가 아닌 사용자는 다른 백엔드에서 실행되는 자체 쿼리를 자유롭게 사용 pg_cancel_backend()하고 종료 pg_terminate_backend()할 수 있습니다. 데이터베이스 손상에 대한 걱정없이 안전하게 사용할 수 있습니다. 결국 PostgreSQL은 OOM 킬러에서 SIGKILL, 서버 종료 등과 같은 프로세스 종료를 처리 할 준비가되어 있어야합니다. 이것이 바로 WAL 로그 입니다.

PostgreSQL에서 (다중 문) 트랜잭션 내에 중첩 된 대부분의 DDL 명령을 수행 할 수 있음을 알 수 있습니다.

BEGIN;
ALTER TABLE foo ...;
ALTER TABLE bar ...;
-- more stuff
COMMIT; -- or ROLLBACK; if you've changed your mind

(스키마 마이그레이션이 함께 또는 전혀 이루어지지 않도록하는 것이 좋습니다.) 그러나 다음과 같이 말했습니다.

우리는 거래를 포장 하지 않았습니다ALTER TABLE .

문서 에서 단일 명령으로도 충분합니다 .

PostgreSQL은 실제로 모든 SQL 문을 트랜잭션 내에서 실행되는 것으로 취급합니다. BEGIN 명령을 발행하지 않으면, 각 개별 명령문에는 내재 된 BEGIN이 있고 (성공한 경우) COMMIT가 랩핑되어 있습니다. BEGIN 및 COMMIT로 둘러싸인 명령문 그룹을 트랜잭션 블록이라고도합니다.

제어 psql 프롬프트에서 발행 된 Ctrl-C를 ALTER TABLE통해 pg_cancel_backend()또는을 취소 하면 마치 마치 마치 마치

BEGIN;
ALTER TABLE ... ;
ROLLBACK;

(바람직하게 볼 수는 있지만, 고가를 취소 ALTER TABLE하면 ROLLBACK어쨌든 갈 때 데이터베이스를 불필요한 불필요하게 분쇄 할 수 있습니다 .)


5

Josh의 정확하고 훌륭한 답변을 자세히 설명하려면 다음을 수행하십시오.

ALTER TABLE 쿼리를 완전히 취소해도 안전합니까?

예.

테이블을 다시 쓰는 동안에도 안전 합니다 .

원하는 경우 전체 PostgreSQL 서버를 종료하거나 실제로 실행되는 시스템을 재시작하면 다시 시작하면 모든 것이 정상입니다. PostgreSQL의 DDL은 트랜잭션 방식이며 충돌에 안전합니다.

DDL 작업은 WAL을 통해 기록되며 충돌이나 중단 후 복구시 롤백되거나 완료 될 수 있습니다.


3
"전체 PostgreSQL 서버를 종료하거나 실제로 실행중인 시스템을 재시작하고 다시 시작하면 모든 것이 정상입니다"라는 것에 대한 참고 사항입니다. , wiki.postgresql.org/wiki/Reliable_Writes
Josh Kupershmidt

2
@JoshKupershmidt 물론이지만 DDL에만 국한된 것은 아닙니다. 동기화 문제가있는 경우 모든 것에 대해 안전하지 않은 상태입니다 .
Craig Ringer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.