Có đáng để chạy VACUUM trên một bảng chỉ nhận INSERT không?


19

Trong một cuộc tái ngộ năm 2015: AWS đã đề cập rằng chân không nên được chạy không chỉ sau khi cập nhật hoặc xóa mà còn sau khi chèn. Đây là phần có liên quan của buổi nói chuyện:

http://www.youtube.com/watch?v=tZXp19q8RFo&t=16m2s

Giả sử có một số dọn dẹp phải được thực hiện trên các khối ngay cả khi chúng chỉ nhận được chèn và việc dọn dẹp này có thể được thực hiện ngay lần đầu tiên một khối được chọn (làm chậm tốc độ đọc) hoặc trong khi hút bụi. Điều này có đúng không và nếu vậy, chính xác thì việc dọn dẹp phải được thực hiện?

Câu trả lời:


15

tl; dr: Quá trình đầu tiên đọc dữ liệu sau khi được cam kết sẽ đặt các bit gợi ý. Điều đó sẽ làm bẩn trang, tạo ra hoạt động viết. Điều khác VACUUM(nhưng không phải các lệnh khác) là đánh dấu trang là hiển thị tất cả, nếu phù hợp. VACUUMcuối cùng sẽ phải đập bàn để đóng băng các bộ dữ liệu.

Công việc cần được thực hiện sau khi chèn không thực sự dọn dẹp, ít nhất là không phải theo nghĩa của công việc khác VACUUMthông thường. Trước khi tôi đi vào chi tiết, lưu ý rằng câu trả lời này dựa trên mã 9.6 hiện tại (chưa được phát hành) và tôi bỏ qua các hiệu ứng của sao chép phát trực tuyến, mặc dù nó có thể ảnh hưởng đến khả năng hiển thị.

Do MVCC , mỗi khi Postgres đánh giá xem một bộ dữ liệu có thể hiển thị cho một truy vấn hay không, nó phải xem xét liệu giao dịch đã tạo bộ dữ liệu (được ghi trong trường ẩn xmin) được cam kết, cùng với một số tiêu chí khác. Kiểm tra đó rất tốn kém, vì vậy ngay khi biết rằng một giao dịch hiển thị cho tất cả các giao dịch hiện đang mở, một "bit gợi ý" được đặt trên tiêu đề tuple chỉ ra rằng. Cài đặt của bit đó làm mất hiệu lực trang, có nghĩa là nó sẽ phải được ghi vào đĩa. Điều này có thể rất khó hiểu nếu lệnh tiếp theo để đọc dữ liệu là một SELECTthứ đột nhiên tạo ra nhiều lưu lượng ghi. Chạy một VACUUMsau khi cam kết chèn sẽ tránh điều đó. Một điểm khác biệt quan trọng làVACUUMsẽ LUÔN gợi ý các bộ dữ liệu trên một trang (miễn là nó có khóa dọn dẹp trên trang), nhưng hầu hết các lệnh khác sẽ chỉ gợi ý nếu giao dịch chèn được cam kết trước khi lệnh bắt đầu.

Một điểm quan trọng về việc viết tất cả các bit gợi ý này là VACUUMcó thể được điều chỉnh (và autovacuum được điều chỉnh theo mặc định). Các lệnh khác không được điều chỉnh và sẽ tạo ra dữ liệu bẩn càng nhanh càng tốt.

VACUUMlà phương pháp duy nhất để đánh dấu các trang là hiển thị toàn bộ, đây là một xem xét hiệu suất quan trọng đối với một số hoạt động (đáng chú ý là chỉ quét chỉ mục). Nếu bạn thực hiện một thao tác chèn lớn, rất có thể có nhiều trang không có gì ngoài các bộ dữ liệu mới được chèn. VACUUMcó khả năng có thể đánh dấu các trang đó là hiển thị toàn bộ, nhưng chỉ khi giao dịch cũ nhất được chạy khi VACUUMbắt đầu mới hơn giao dịch đã chèn dữ liệu .

Do cách thức hoạt động của MVCC, các bộ dữ liệu được chèn hơn ~ 2 tỷ giao dịch trước đây phải được đánh dấu là " đóng băng ". Theo mặc định, autovacuum sẽ khởi động để thực hiện điều đó cứ sau 200 triệu giao dịch. Chạy chân không thủ công với chân không_freeze_min_age được đặt thành 0 sau khi chèn số lượng lớn có thể giúp giảm tác động của điều đó. Tích cực hơn, bạn có thể chạy VACUUM FREEZEtrên bàn sau khi chèn. Điều đó sẽ "đặt lại đồng hồ" khi lần quét đóng băng tiếp theo xảy ra.

Nếu bạn muốn biết chi tiết cụ thể, hãy xem HEAPTUPLE_LIVEtrường hợp sau khi gọi đến HeapTupleSatisfiesVacuum()bên trong lazy_scan_heap(). Cũng xem HeapTupleSatisfiesVacuum()chính nó, và so sánh nó với HeapTupleSatisfiesMVCC().

Có hai bài thuyết trình khác của tôi có thể thú vị. Video đầu tiên có sẵn từ http://www.pgcon.org/2015/schedule/events/829.en.html , trong khi video thứ hai (mà tôi nghĩ là tốt hơn một chút) tại https://www.youtube. com / đồng hồ? v = L8nErzxPJjQ


Điều này rất thú vị và cũng giải thích một số trang bị bẩn trong một số EXPLAIN (ANALYZE, BUFFERS) outputs. But, if I understand things correctly, some of the hint bits (at least * CAM KẾT 'và *INVALID) có thể (có thể) đã được đặt bởi COMMIThoặc ROLLBACK, phải không?
dezso

3
CAM KẾT và ROLLBACK không thực sự chạm vào các trang dữ liệu, vì vậy không, những lệnh đó đặc biệt không bao giờ có thể gợi ý. Lệnh DML vẫn có thể đặt cả hai trạng thái gợi ý xmin và xmax, cho các bộ dữ liệu được đánh dấu bởi các giao dịch khác hoặc có khả năng thậm chí các bộ dữ liệu được đánh dấu bởi giao dịch hiện tại.
Jim Nasby
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.