Kích thước cơ sở dữ liệu ban đầu của PostgreSQL


12

Có 2 phần cho câu hỏi của tôi.

  1. Có cách nào để chỉ định kích thước ban đầu của cơ sở dữ liệu trong PostgreSQL không?
  2. Nếu không có, làm thế nào để bạn đối phó với sự phân mảnh khi cơ sở dữ liệu phát triển theo thời gian?

Gần đây tôi đã di chuyển từ MSSQL sang Postgres và một trong những điều chúng tôi đã làm trong thế giới MSSQL khi tạo cơ sở dữ liệu là chỉ định kích thước ban đầu của cơ sở dữ liệu và nhật ký giao dịch. Điều này làm giảm sự phân mảnh và tăng hiệu suất, đặc biệt là nếu biết trước kích thước "bình thường" của cơ sở dữ liệu.

Hiệu suất của cơ sở dữ liệu của tôi giảm khi kích thước tăng lên. Ví dụ, khối lượng công việc tôi đặt nó thông thường mất 10 phút. Khi cơ sở dữ liệu phát triển, thời gian này tăng lên. Làm một VACUUM, VACUUM FULL và VACUUM FULL ANALYZE không xuất hiện để giải quyết vấn đề. Điều gì giải quyết vấn đề hiệu năng là dừng cơ sở dữ liệu, phân mảnh ổ đĩa và sau đó thực hiện VACUUM FULL ANALYZE đưa hiệu năng kiểm tra của tôi trở lại 10 phút ban đầu. Điều này khiến tôi nghi ngờ rằng sự phân mảnh là điều khiến tôi đau đớn.

Tôi không thể tìm thấy bất kỳ tham chiếu nào để đặt trước không gian bảng / không gian cơ sở dữ liệu trong Postgres. Hoặc là tôi đang sử dụng thuật ngữ sai và do đó không tìm thấy gì, hoặc có một cách khác để giảm thiểu sự phân mảnh hệ thống tệp trong Postgres.

Bất kỳ con trỏ?

Giải pháp

Các câu trả lời được cung cấp đã giúp xác nhận những gì tôi bắt đầu nghi ngờ. PostgreSQL lưu trữ cơ sở dữ liệu trên nhiều tệp và đây là những gì cho phép cơ sở dữ liệu phát triển mà không lo bị phân mảnh. Hành vi mặc định là đóng gói các tệp này vào vành với dữ liệu bảng, điều này tốt cho các bảng hiếm khi thay đổi nhưng lại không tốt cho các bảng được cập nhật thường xuyên.

PostgreSQL sử dụng MVCC để cung cấp quyền truy cập đồng thời vào dữ liệu bảng. Theo sơ đồ này, mỗi bản cập nhật tạo ra một phiên bản mới của hàng đã được cập nhật (điều này có thể thông qua dấu thời gian hoặc số phiên bản, ai biết?). Dữ liệu cũ không bị xóa ngay lập tức, nhưng được đánh dấu để xóa. Việc xóa thực tế xảy ra khi một thao tác VACUUM được thực hiện.

Làm thế nào điều này liên quan đến các yếu tố điền? Hệ số điền mặc định của bảng là 100 gói đầy đủ các trang bảng, điều này có nghĩa là không có khoảng trống trong trang bảng để giữ các hàng được cập nhật, tức là các hàng được cập nhật sẽ được đặt trong một trang bảng khác với hàng ban đầu. Điều này là xấu cho hiệu suất, như kinh nghiệm của tôi cho thấy. Vì các bảng tóm tắt của tôi được cập nhật rất thường xuyên (tối đa 1500 hàng / giây), tôi đã chọn đặt hệ số lấp đầy là 20, tức là 20% bảng sẽ dành cho dữ liệu hàng được chèn và 80% cho dữ liệu cập nhật. Mặc dù điều này có vẻ quá mức, nhưng không gian lớn dành cho các hàng được cập nhật có nghĩa là các hàng được cập nhật vẫn ở trong cùng một trang với bản gốc và có một trang bảng không đầy đủ vào thời điểm trình nền tự động chạy để xóa các hàng lỗi thời.

Để "sửa" cơ sở dữ liệu của tôi, tôi đã làm như sau.

  1. Đặt hệ số lấp đầy của các bảng tóm tắt của tôi thành 20. Bạn có thể thực hiện việc này tại thời điểm tạo bằng cách chuyển một tham số cho CREATE TABLE hoặc sau thực tế thông qua ALTER TABLE. Tôi đã ban hành lệnh plpgsql sau đây:ALTER TABLE "my_summary_table" SET (fillfactor = 20);
  2. Đã phát hành VACUUM FULL, vì điều này viết một phiên bản hoàn toàn mới của tệp bảng và do đó bằng cách ghi một tệp bảng mới với hệ số điền mới .

Chạy lại các thử nghiệm của tôi, tôi thấy không có sự suy giảm hiệu năng ngay cả khi cơ sở dữ liệu lớn như tôi cần với hàng triệu hàng.

TL; DR - Phân mảnh tệp không phải là nguyên nhân, đó là phân mảnh không gian bảng. Điều này được giảm nhẹ bằng cách điều chỉnh hệ số lấp đầy của bảng cho phù hợp với trường hợp sử dụng cụ thể của bạn.


Tôi nghi ngờ rằng đó là hoạt động thay đổi kích thước tập tin. Tôi đoán là việc duy trì các chỉ mục là những gì làm chậm các phần chèn. Có một cuộc thảo luận hiện tại trên danh sách PG gửi thư về vấn đề này (mặc dù không có một giải pháp): postgresql.1045698.n5.nabble.com/...
a_horse_with_no_name

Câu trả lời:


4
  1. Không có gì duy nhất gần như là khi bạn biên dịch máy chủ với khóa chuyển đổi --with-segsize, điều này có thể hữu ích nếu bảng của bạn chiếm nhiều dung lượng hơn một gig và hệ thống tệp của bạn có thể xử lý một tệp duy nhất trong một gig. Nếu bạn chèn 20 hợp đồng biểu diễn, nó sẽ phải tạo 20 tệp nếu bạn không sử dụng công tắc này. Nếu hệ thống tệp của bạn có thể xử lý một tệp trong một hợp đồng biểu diễn, bạn chỉ có thể đặt nó thành một giá trị lớn rất có thể sẽ thấy một số lợi ích, trong trường hợp xấu nhất là một lợi ích nhỏ.

  2. Hãy xem CLUSTER http://www.postgresql.org/docs/9.1/static/sql-cluster.html và FILLFACTOR http://www.postgresql.org/docs/9.1/static/sql-createtable.html , http://www.postgresql.org/docs/9.1/static/sql-createindex.html

Lưu ý rằng FILLFACTOR có thể được áp dụng cho cả bảng và chỉ mục.


5

Có một điều nữa trong trò chơi chưa được đưa vào phương trình của bạn: Cập nhật NÓNG . Câu trả lời liên quan:

Cài đặt FILLFACTORở mức thấp như 20 vẻ quá mức. Nó làm phồng cái bàn lên tới năm lần kích thước của nó. Nếu các cập nhật HOT hoạt động, bạn không cần phải đi quá thấp - thông thường .

Có các trường hợp ngoại lệ: Các bản cập nhật HOT chỉ có thể sử dụng lại các bộ dữ liệu đã chết từ các giao dịch trước đó , không phải từ các giao dịch tương tự hoặc đồng thời . Do đó, tải đồng thời nặng hoặc giao dịch dài liên tục cập nhật cùng một hàng có thể đảm bảo cài đặt thấp (hoặc thậm chí thấp hơn).

Nếu bạn có các cập nhật lớn, thay đổi các phần lớn của bảng cùng một lúc, bạn có thể muốn chia chúng thành một số khối, lý tưởng là chỉ thay đổi nhiều hàng cùng một lúc phù hợp cục bộ trên trang dữ liệu. Nhưng điều đó thật khó để ước tính và điều tiết.

Lưu ý rằng các cập nhật HOT chỉ hoạt động khi các cột đã thay đổi không liên quan đến các chỉ mục theo bất kỳ cách nào (không phải là dữ liệu cũng như điều kiện trong một chỉ mục một phần). Bạn có thể đang chặn các bản cập nhật HOT với các chỉ mục trên các cột được cập nhật. Nếu đó là những chi phí có thể, bạn có thể có hiệu suất tổng thể tốt hơn mà không có chúng.

Cuối cùng, bạn có thể đặt tham số autovacuum cho mỗi bảng . Bạn có thể nhắm mục tiêu các bảng được cập nhật nhiều với các cài đặt tích cực cho phép đóng gói các hàng chặt chẽ hơn chỉ FILLFACTOR 20.


1
Những điều thú vị, tôi sẽ đọc nó và cố gắng hiểu rõ hơn về những cập nhật HOT có ý nghĩa gì với hệ thống của tôi.
CadentOrange

4

Nếu vấn đề của bạn là phân mảnh tập tin thì không, không có. Trong Postgres, mỗi bảng sẽ có tệp riêng hoặc tập hợp tệp nếu sử dụng TOAST, trong hệ thống tệp. Điều này khác với, ví dụ, Oracle (hoặc rõ ràng là MS-SQL) nơi bạn tạo các tệp không gian bảng có kích thước trước để thả các bảng vào - mặc dù ở đó bạn có thể gặp sự cố phân mảnh hệ thống tệp nếu tệp không gian bảng được mở rộng hoặc hệ thống tệp phân mảnh xấu để bắt đầu với.

Đối với câu hỏi thứ hai của bạn ... Tôi không biết làm thế nào để xử lý sạch phân mảnh hệ thống tệp vì MS-Windows là hệ điều hành duy nhất mà tôi gặp phải sự cố phân mảnh và tôi không chạy MS-Windows nữa cần là những ngày này. Có lẽ việc đặt các tệp cơ sở dữ liệu trên (các) đĩa riêng của họ có thể giảm thiểu điều đó đến một mức độ nào đó.


Hãy nhớ rằng bạn có phân mảnh cơ sở dữ liệu PostgreSQL nội bộ và bạn có phân mảnh hệ thống tệp bên ngoài. Nội bộ Tôi tin rằng có thể được giảm nhẹ bằng VACUUM và sử dụng CLUSTERS và FILLFACTOR. Hệ thống tệp có thể được xử lý bằng cách chạy phân mảnh cho hệ thống tệp đã cho. Và các hệ thống tệp Linux / Unix có thể bị phân mảnh một số lần tùy thuộc vào tải công việc và loại hệ thống tệp.
Kuberchaun

Phân mảnh hệ thống tệp không thực sự là một vấn đề lớn với NTFS hiện nay.
a_horse_with_no_name

1
Tôi nghĩ rằng NTFS là nổi tiếng với nó? Máy trạm của tôi bị phân mảnh khá tốt, điều duy nhất giữ nó trong tầm kiểm soát là phân mảnh theo lịch trình mà Windows7 chạy hàng ngày.
Kuberchaun
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.