Điều gì xảy ra trong điểm kiểm tra PostgreSQL?


22

Đây là một phần của nhật ký điểm kiểm tra của tôi:

2014-03-26 11:51:29.341 CDT,,,18682,,532854fc.48fa,4985,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 15047 buffers (1.4%); 0 transaction log file(s) added, 0 removed, 30 recycled; write=68.980 s, sync=1.542 s, total=70.548 s; sync files=925, longest=0.216 s, average=0.001 s",,,,,,,,,""
2014-03-26 11:56:05.430 CDT,,,18682,,532854fc.48fa,4987,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 16774 buffers (1.6%); 0 transaction log file(s) added, 0 removed, 31 recycled; write=72.542 s, sync=17.164 s, total=89.733 s; sync files=885, longest=3.812 s, average=0.019 s",,,,,,,,,""
2014-03-26 12:01:21.650 CDT,,,18682,,532854fc.48fa,4989,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 14436 buffers (1.4%); 0 transaction log file(s) added, 0 removed, 33 recycled; write=122.350 s, sync=5.212 s, total=127.676 s; sync files=924, longest=3.740 s, average=0.005 s",,,,,,,,,""
2014-03-26 12:06:25.028 CDT,,,18682,,532854fc.48fa,4991,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 13277 buffers (1.3%); 0 transaction log file(s) added, 0 removed, 29 recycled; write=126.217 s, sync=5.733 s, total=131.991 s; sync files=894, longest=1.859 s, average=0.006 s",,,,,,,,,""
2014-03-26 12:10:41.958 CDT,,,18682,,532854fc.48fa,4993,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 20765 buffers (2.0%); 0 transaction log file(s) added, 0 removed, 28 recycled; write=88.015 s, sync=10.818 s, total=98.872 s; sync files=881, longest=2.690 s, average=0.012 s",,,,,,,,,""

Tôi nhận thấy rằng đôi khi cơ sở dữ liệu của chúng tôi rất chậm - bạn có thể thấy một số lượng rất lớn các truy vấn ngắn thông thường bị mắc kẹt lâu hơn nhiều so với bây giờ. Nó xảy ra thường xuyên mà không có thủ phạm rõ ràng.

Câu hỏi: Điểm kiểm tra có thể gây ra điều này? Điều gì xảy ra trong giai đoạn "đồng bộ hóa" của trạm kiểm soát?

Câu trả lời:


32

Trong quá trình hoạt động, PostgreSQL ghi lại các thay đổi đối với các tệp nhật ký giao dịch, nhưng nó không ngay lập tức xóa chúng vào các bảng cơ sở dữ liệu thực tế. Nó thường chỉ giữ các thay đổi trong bộ nhớ và trả lại chúng từ bộ nhớ khi chúng được yêu cầu, trừ khi RAM bắt đầu đầy và nó phải ghi chúng ra.

Điều này có nghĩa là nếu nó gặp sự cố, các bảng trên đĩa sẽ không được cập nhật. Nó phải phát lại nhật ký giao dịch, áp dụng các thay đổi cho các bảng trên đĩa, trước khi có thể bắt đầu sao lưu. Điều đó có thể mất một thời gian cho một cơ sở dữ liệu lớn, bận rộn.

Vì lý do đó và để nhật ký giao dịch không tiếp tục phát triển, PostgreQuery định kỳ thực hiện một điểm kiểm tra để đảm bảo DB ở trạng thái sạch. Nó xóa tất cả các thay đổi đang chờ xử lý vào đĩa và tái chế các bản ghi giao dịch đang được sử dụng để giữ một bản ghi phục hồi sự cố của các thay đổi.

Sự tuôn ra này xảy ra theo hai giai đoạn:

  • Đệm write()s bẩn shared_buffersđến bàn; và
  • fsync() các tệp bị ảnh hưởng để đảm bảo các thay đổi thực sự xảy ra với đĩa

Cả hai đều có thể tăng tải I / O đĩa. Sự tham gia gây ra bởi những lần ghi này có thể làm chậm việc đọc và cũng có thể làm chậm việc xóa các phân đoạn WAL được yêu cầu để thực hiện giao dịch.

Đó là một thách thức lâu dài, nhưng nó trở nên tồi tệ hơn khi chúng ta thấy các hệ thống có càng nhiều RAM để chúng có thể đệm nhiều dữ liệu hơn và mất nhiều thời gian hơn để ghi ra. Có cuộc thảo luận giữa cộng đồng Linux và PostgreQuery về cách giải quyết vấn đề này vào lúc này, như đã thảo luận trong bài viết này của LWN.net . (LWN.net sẽ không thể tiếp tục viết loại công việc tuyệt vời này nếu mọi người không đăng ký. Tôi là người đăng ký và chia sẻ liên kết này vì nó hữu ích và nhiều thông tin. Vui lòng xem xét đăng ký nếu bạn muốn xem thêm về điều này đại loại

Điều chính bạn có thể làm để giảm tác động của các trạm kiểm soát tại thời điểm này là phân tán hoạt động của điểm kiểm tra bằng cách tăng checkpoint_completion_targetđể nhiều dữ liệu được ghi vào thời điểm trạm kiểm soát cuối cùng xuất hiện. Tuy nhiên, điều này có chi phí - nếu bạn cập nhật một trang (giả sử) mười lần, nó có thể được ghi vào đĩa nhiều lần trước điểm kiểm tra với mục tiêu hoàn thành cao, mặc dù nó chỉ phải được viết ra một lần để đảm bảo an toàn. Mục tiêu hoàn thành cao hơn giúp cho các mẫu I / O mượt mà hơn nhưng tổng chi phí I / O tổng thể cao hơn.

Một điều khác bạn có thể làm để giúp là yêu cầu hệ điều hành của bạn bắt đầu ngay lập tức ghi dữ liệu khi nó được ghi vào bộ đệm. Điều này giống như phía hạt nhân của cài đặt checkpoint_completion_targetvà có sự đánh đổi tương tự. Xem tài liệu vm linux , đặc biệt là dirty_background_bytes, dirty_background_ratio, dirty_expire_centisecs.


Bài viết được lan truyền trong một thời gian dài và tôi không nghĩ nó gây ra vấn đề. Còn về sự đồng bộ, liệu có phải là một loại hoạt động dừng lại trên thế giới?
Konrad Garus

@KonradGarus Đồng bộ hóa không phải là một loại hoạt động thế giới, nhưng nó thường là dù sao đi nữa. Đọc bài viết tôi liên kết ở trên, đây là một bản tóm tắt rất kịp thời và hữu ích về các vấn đề, mặc dù từ quan điểm khá kỹ thuật. Phiên bản ngắn là "fsync () trên Linux có xu hướng hoàn toàn rác hiệu năng của bất kỳ I / O nào đồng thời với fsync ()". Bạn có thể giảm thiểu điều đó bằng các tùy chọn điều chỉnh được liệt kê ở trên, để giảm số lượng phải được xóa bởi fsync.
Craig Ringer

1

Xóa bộ đệm hệ thống tệp hệ điều hành bẩn do vượt quá dirty_byteshoặc dirty_ratio một hoạt động chặn tiền cảnh!

Các tunables hạt nhân dirty_bytes, dirty_background_bytes, dirty_ratio, dirty_background_ratiodirty_centisecskiểm soát đỏ bừng bộ đệm hệ thống tập tin hệ điều hành bẩn vào đĩa. dirty_byteslà ngưỡng tính theo byte, dirty_ratiolà ngưỡng dưới dạng tỷ lệ của tổng bộ nhớ. dirty_background_bytesdirty_background_ratiolà các ngưỡng tương tự, nhưng việc xóa xảy ra trong nền và không chặn các hoạt động đọc / ghi khác cho đến khi hoàn thành. dirty_centisecslà bao nhiêu phần trăm giây có thể trôi qua trước khi bắt đầu tuôn ra.

Gần đây, mặc định cho các điều chỉnh này đã được hạ xuống trong Linux, vì kích thước bộ nhớ cho các máy hiện đại đã tăng lên đáng kể. Ngay cả các tỷ lệ 5 và 10% cho dirty_background_ratiodirty_ratiotrên máy 256 GB có thể làm ngập hệ thống I / O.

Điều chỉnh dirty_background_byteshoặc dirty_background_ratiođể bắt đầu xả bộ đệm bẩn trong nền là khó khăn. May mắn thay, bạn có thể điều chỉnh các cài đặt này mà không phải dừng PostgreSQL hoặc máy chủ lưu trữ bằng cách lặp lại các giá trị mới cho các tệp thích hợp:

$ sudo echo [int value of bytes] > /proc/sys/vm/dirty_background_bytes

ví dụ để đặt số byte bị bẩn để kích hoạt xóa nền. Nếu bạn đang sử dụng một tụ hậu thuẫn, hoặc bộ nhớ flash card RAID pin-backed (bạn làm muốn giữ lại dữ liệu của bạn trong trường hợp của một vụ tai nạn, không bạn?) Bắt đầu bằng cách điều chỉnh dirty_background_bytesđể 1/2 các ghi nhớ cache kích thước bộ đệm và dirty_bytesđến 3/4 kích thước đó. Theo dõi hồ sơ I / O của bạn bằng iostats và nếu bạn vẫn thấy các vấn đề về độ trễ có nghĩa là tải ghi cơ sở dữ liệu của bạn vẫn áp đảo các bộ đệm bộ đệm bộ đệm. Tắt các giá trị cho đến khi độ trễ được cải thiện hoặc xem xét nâng cấp hệ thống con I / O của bạn. Thẻ FusionIO và SSD là hai khả năng cho thông lượng I / O cực cao.

Chúc may mắn!


Nhận xét của bạn về dữ liệu "bẩn" là một điểm có liên quan cho sự chậm chạp. Về cơ bản: tỷ lệ bẩn càng lớn, bộ đệm được phân bổ càng nhiều cho dữ liệu bẩn trước khi xả nước. Do đó, giảm thiểu độ trễ xả có nghĩa là tăng bộ đệm bẩn hoặc tăng thời gian dữ liệu bẩn có thể lưu lại trong bộ nhớ.
Peter Teoh
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.