Theo tôi hiểu, thực tế là truy vấn của chúng tôi đang chờ khóa có nghĩa là nó luôn chờ khóa và nó không bao giờ thay đổi bất cứ điều gì.
Phải - nếu bạn thấy pg_stat_activity.waiting là "đúng" đối với ALTER TABLE, điều đó gần như chắc chắn có nghĩa là nó kiên nhẫn chờ khóa ACCESS EXCLUSIVE trên bảng mục tiêu và công việc thực sự của nó (viết lại bảng nếu cần, thay đổi danh mục , xây dựng lại các chỉ mục, v.v.) chưa bắt đầu.
Có an toàn cho chúng tôi để hủy bỏ hoàn toàn truy vấn ALTER TABLE của chúng tôi không? Hoặc có thể là truy vấn đã sửa đổi một cái gì đó và hủy bỏ nó sẽ khiến cơ sở dữ liệu của chúng ta ở trạng thái nửa chừng?
Hủy bỏ các truy vấn (hoặc, tương tự, khôi phục giao dịch) trong PostgreQuery không có bất kỳ nguy cơ tham nhũng cơ sở dữ liệu nào mà bạn có thể đã bị phát hiện trong một số cơ sở dữ liệu khác (ví dụ: cảnh báo đáng sợ ở cuối trang này). Đó là lý do tại sao những người không phải siêu nhân, trong các phiên bản gần đây, được sử dụng miễn phí pg_cancel_backend()
và pg_terminate_backend()
giết các truy vấn của riêng họ đang chạy trong các phụ trợ khác - họ an toàn để sử dụng mà không phải lo lắng về tham nhũng cơ sở dữ liệu. Rốt cuộc, PostgreSQL phải sẵn sàng đối phó với mọi quá trình bị tiêu diệt, ví dụ SIGKILL từ kẻ giết người OOM, tắt máy chủ, v.v. Đó là những gì nhật ký WAL dành cho.
Bạn cũng có thể đã thấy rằng trong PostgreSQL, có thể thực hiện hầu hết các lệnh DDL được lồng trong một giao dịch (đa câu lệnh), ví dụ:
BEGIN;
ALTER TABLE foo ...;
ALTER TABLE bar ...;
-- more stuff
COMMIT; -- or ROLLBACK; if you've changed your mind
(tuyệt vời để đảm bảo rằng việc di chuyển lược đồ đi cùng nhau hoặc không hoàn toàn.) Bạn đã nói, mặc dù:
Chúng tôi không gói gọn ALTER TABLE
trong một giao dịch.
Điều đó tốt cho một lệnh duy nhất - từ các tài liệu ,
PostgreSQL thực sự coi mọi câu lệnh SQL là được thực thi trong một giao dịch. Nếu bạn không ban hành lệnh BEGIN, thì mỗi câu lệnh riêng lẻ có BEGIN ẩn và CAM KẾT (nếu thành công) được bao quanh nó. Một nhóm các báo cáo được bao quanh bởi BEGIN và CAMIT đôi khi được gọi là khối giao dịch.
Vì vậy, việc hủy bỏ điều đó ALTER TABLE
, thông qua pg_cancel_backend()
hoặc Ctrl-C được phát ra từ dấu nhắc psql kiểm soát, sẽ có tác động tương tự như bạn đã làm
BEGIN;
ALTER TABLE ... ;
ROLLBACK;
(mặc dù như bạn hy vọng đã thấy, việc hủy bỏ sự đắt đỏ đó ALTER TABLE
có thể lưu cơ sở dữ liệu khỏi nhiều công việc không cần thiết nếu bạn vẫn tiếp tục ROLLBACK
.)