VACUUM và ANALYZE là hai hoạt động bảo trì cơ sở dữ liệu PostgreSQL quan trọng nhất.
Chân không được sử dụng để khôi phục không gian bị chiếm bởi "bộ giá trị chết" trong bàn. Một tuple chết được tạo khi một bản ghi bị xóa hoặc được cập nhật (xóa theo sau là chèn). PostgreSQL không xóa hàng cũ khỏi bảng một cách vật lý nhưng đặt một "điểm đánh dấu" trên đó để các truy vấn không trả lại hàng đó. Khi một quá trình chân không chạy, không gian bị chiếm bởi các bộ giá trị chết này được đánh dấu là có thể tái sử dụng bởi các bộ nguyên khác.
Thao tác “phân tích” thực hiện đúng như tên gọi của nó - nó phân tích nội dung của các bảng trong cơ sở dữ liệu và thu thập số liệu thống kê về việc phân phối các giá trị trong mỗi cột của mỗi bảng. Công cụ truy vấn PostgreSQL sử dụng các số liệu thống kê này để tìm ra kế hoạch truy vấn tốt nhất. Khi các hàng được chèn, xóa và cập nhật trong cơ sở dữ liệu, thống kê cột cũng thay đổi. ANALYZE - chạy theo cách thủ công bởi DBA hoặc tự động bởi PostgreSQL sau khi autovacuum - đảm bảo số liệu thống kê được cập nhật.
Mặc dù chúng nghe có vẻ tương đối đơn giản, nhưng hậu trường, hút bụi và phân tích là hai quá trình phức tạp. May mắn thay, các DBA không phải lo lắng nhiều về nội bộ của họ. Tuy nhiên, họ thường nhầm lẫn về việc chạy các quy trình này theo cách thủ công hoặc đặt giá trị tối ưu cho các thông số cấu hình.
Trong bài viết này, chúng tôi sẽ chia sẻ một số phương pháp hay nhất về VACUUM và PHÂN TÍCH.
Mẹo 1:Không chạy VACUUM hoặc PHÂN TÍCH thủ công mà không có lý do
Hút chân không PostgreSQL (hút chân không tự động hoặc hút chân không thủ công) giảm thiểu sự phồng rộp của bảng và ngăn chặn việc bao bọc ID giao dịch. Autovacuum không khôi phục dung lượng ổ đĩa bị chiếm dụng bởi các bộ dữ liệu đã chết. Tuy nhiên, đang chạy VACUUM FULL lệnh sẽ làm như vậy. Tuy nhiên, VACUUM FULL có hàm ý về hiệu suất của nó. Bảng mục tiêu bị khóa độc quyền trong quá trình hoạt động, ngăn chặn việc đọc thậm chí trên bảng. Quá trình này cũng tạo một bản sao đầy đủ của bảng, điều này cần thêm dung lượng đĩa khi nó chạy. Chúng tôi khuyên bạn không nên chạy VACUUM FULL trừ khi có một tỷ lệ phần trăm cồng kềnh rất cao và các truy vấn đang bị ảnh hưởng nghiêm trọng. Chúng tôi cũng khuyên bạn nên sử dụng các khoảng thời gian có hoạt động cơ sở dữ liệu thấp nhất cho nó.
Cách tốt nhất là không chạy máy hút chân không thủ công quá thường xuyên trên toàn bộ cơ sở dữ liệu; cơ sở dữ liệu mục tiêu có thể đã được hút chân không tối ưu bằng quy trình autovacuum. Do đó, việc hút chân không bằng tay có thể không loại bỏ được bất kỳ bộ phận chết nào nhưng gây ra tải I / O không cần thiết hoặc tăng đột biến CPU. Nếu cần thiết, máy hút chân không thủ công chỉ nên chạy trên cơ sở từng bàn khi có nhu cầu, chẳng hạn như tỷ lệ thấp giữa các hàng sống và các hàng chết hoặc khoảng cách lớn giữa các máy hút bụi tự động. Ngoài ra, máy hút chân không thủ công nên được chạy khi hoạt động của người dùng là tối thiểu.
Autovacuum cũng cập nhật thống kê phân phối dữ liệu của bảng (không tạo lại chúng). Khi chạy theo cách thủ công, ANALYZE lệnh thực sự xây dựng lại các thống kê này thay vì cập nhật chúng. Một lần nữa, việc xây dựng lại số liệu thống kê khi chúng đã được cập nhật một cách tối ưu bởi autovacuum thường xuyên có thể gây ra áp lực không cần thiết đối với tài nguyên hệ thống.
Thời điểm bạn phải chạy ANALYZE theo cách thủ công là ngay sau khi tải dữ liệu hàng loạt vào bảng mục tiêu. Một số lượng lớn (thậm chí vài trăm) hàng mới trong bảng hiện có sẽ làm sai lệch đáng kể việc phân phối dữ liệu cột của nó. Các hàng mới sẽ làm cho mọi thống kê cột hiện có bị lỗi thời. Khi trình tối ưu hóa truy vấn sử dụng các thống kê như vậy, hiệu suất truy vấn có thể thực sự chậm. Trong những trường hợp này, chạy lệnh ANALYZE ngay sau khi tải dữ liệu để xây dựng lại hoàn toàn số liệu thống kê là một lựa chọn tốt hơn là đợi autovacuum khởi động.
Mẹo 2:Tinh chỉnh Ngưỡng hút chân không tự động
Điều cần thiết là phải kiểm tra hoặc điều chỉnh autovacuum và phân tích các thông số cấu hình trong postgresql.conf tệp hoặc trong các thuộc tính bảng riêng lẻ để đạt được sự cân bằng giữa autovacuum và tăng hiệu suất.
PostgreSQL sử dụng hai tham số cấu hình để quyết định thời điểm khởi động autovacuum:
- autovacuum_vacuum_threshold :giá trị này có giá trị mặc định là 50
- autovacuum_vacuum_scale_factor :giá trị này có giá trị mặc định là 0,2
Cùng với nhau, các tham số này cho PostgreSQL biết để bắt đầu autovacuum khi số lượng hàng chết trong bảng vượt quá số hàng trong bảng đó nhân với hệ số tỷ lệ, cộng với ngưỡng chân không. Nói cách khác, PostgreSQL sẽ bắt đầu autovacuum trên bảng khi:
pg_stat_user_tables.n_dead_tup > (pg_class.reltuples x autovacuum_vacuum_scale_factor) + autovacuum_vacuum_threshold
Đối với các bàn có kích thước vừa và nhỏ, điều này có thể đủ. Ví dụ:một bảng có 10.000 hàng, số hàng chết phải trên 2.050 ((10.000 x 0,2) + 50) trước khi bắt đầu tự động hút chân không.
Không phải mọi bảng trong cơ sở dữ liệu đều trải qua tốc độ sửa đổi dữ liệu như nhau. Thông thường, một số bảng lớn sẽ bị sửa đổi dữ liệu thường xuyên và kết quả là sẽ có số lượng hàng chết cao hơn. Các giá trị mặc định có thể không hoạt động cho các bảng như vậy. Ví dụ:với các giá trị mặc định, một bảng có 1 triệu hàng sẽ cần có hơn 200.050 hàng chết trước khi bắt đầu autovacuum ((1000.000 x 0,2) + 50). Điều này có thể có nghĩa là khoảng cách giữa các autovacuums dài hơn, thời gian autovacuum ngày càng dài và tệ hơn, autovacuum hoàn toàn không chạy nếu các giao dịch đang hoạt động trên bảng đang khóa nó.
Do đó, mục tiêu phải là đặt các ngưỡng này thành giá trị tối ưu để quá trình autovacuum có thể diễn ra đều đặn và không mất nhiều thời gian (và ảnh hưởng đến các phiên của người dùng) trong khi vẫn giữ cho số lượng hàng chết tương đối thấp.
Một cách tiếp cận là sử dụng một hoặc tham số khác. Vì vậy, nếu chúng tôi đặt autovacuum_vacuum_scale_factor thành 0 và thay vào đó đặt autovacuum_vacuum_threshold thành, chẳng hạn như 5.000, một bảng sẽ được tự động hút bụi khi số hàng chết của nó nhiều hơn 5.000.
Mẹo 3:Tinh chỉnh Ngưỡng tự động phân tích
Tương tự như autovacuum, autoanalyze cũng sử dụng hai tham số quyết định thời điểm autovacuum cũng sẽ kích hoạt autoanalyze:
- autovacuum_analyze_threshold :giá trị này có giá trị mặc định là 50
- autovacuum_analyze_scale_factor :giá trị này có giá trị mặc định là 0,1
Giống như autovacuum, tham số autovacuum_analyze_threshold có thể được đặt thành một giá trị quy định số lượng các bộ giá trị được chèn, xóa hoặc cập nhật trong bảng trước khi quá trình tự động phân tích bắt đầu. Chúng tôi khuyên bạn nên đặt thông số này một cách riêng biệt trên các bảng lớn và có lượng giao dịch cao. Cấu hình bảng sẽ ghi đè các giá trị postgresql.conf.
Đoạn mã bên dưới hiển thị cú pháp SQL để sửa đổi cài đặt autovacuum_analyze_threshold cho bảng.
ALTER TABLE <table_name> SET (autovacuum_analyze_threshold = <threshold rows>)
Mẹo 4:Tinh chỉnh Công nhân hút chân không
Một tham số khác thường bị DBA bỏ qua là autovacuum_max_workers , có giá trị mặc định là 3. Autovacuum không phải là một quá trình đơn lẻ, mà là một số luồng chân không riêng lẻ chạy song song. Lý do chỉ định nhiều nhân viên là để đảm bảo rằng việc hút bụi các bàn lớn không giữ các bàn nhỏ hơn và các phiên người dùng. Tham số autovacuum_max_workers cho PostgreSQL biết để tăng số lượng các chủ đề autovacuum worker để thực hiện dọn dẹp.
Một thực tế phổ biến của PostgreSQL DBAs là tăng số lượng luồng công nhân tối đa với hy vọng rằng nó sẽ tăng tốc autovacuum. Điều này không hoạt động vì tất cả các chuỗi chia sẻ cùng một autovacuum_vacuum_cost_limit , có giá trị mặc định là 200. Mỗi luồng autovacuum được chỉ định một giới hạn chi phí bằng cách sử dụng công thức hiển thị bên dưới:
individual thread’s cost_limit = autovacuum_vacuum_cost_limit / autovacuum_max_workers
Chi phí của công việc được thực hiện bởi một sợi hút chân không tự động được tính toán bằng cách sử dụng ba tham số:
- uum_cost_page_hit :giá trị này có giá trị mặc định là 1
- chân không_cost_trang_miss :giá trị này có giá trị mặc định là 10
- chân không_cost_page_dirty :giá trị này có giá trị mặc định là 20
Những thông số này có nghĩa là gì:
- Khi một luồng chân không tìm thấy trang dữ liệu mà nó phải làm sạch trong bộ đệm được chia sẻ, chi phí là 1.
- Nếu trang dữ liệu không nằm trong bộ đệm chia sẻ mà là bộ đệm hệ điều hành, chi phí sẽ là 10.
- Nếu trang phải được đánh dấu bẩn vì sợi chân không phải xóa các hàng chết, chi phí sẽ là 20.
Số lượng luồng công nhân tăng lên sẽ làm giảm giới hạn chi phí cho mỗi luồng. Khi mỗi luồng được chỉ định một giới hạn chi phí thấp hơn, nó sẽ đi vào chế độ ngủ thường xuyên hơn vì ngưỡng chi phí dễ dàng đạt đến, cuối cùng khiến toàn bộ quá trình chân không chạy chậm. Chúng tôi khuyên bạn nên tăng autovacuum_vacuum_cost_limit lên một giá trị cao hơn, chẳng hạn như 2000, sau đó điều chỉnh số luồng công nhân tối đa.
Một cách tốt hơn là chỉ điều chỉnh các thông số này cho các bảng riêng lẻ khi cần thiết. Ví dụ:nếu quá trình tự động hút chân không của một bảng giao dịch lớn diễn ra quá lâu, bảng có thể được định cấu hình tạm thời để sử dụng giới hạn chi phí chân không và độ trễ chi phí của riêng nó. Giới hạn chi phí và độ trễ sẽ ghi đè các giá trị trên toàn hệ thống được đặt trong postgresql.conf.
Đoạn mã bên dưới cho biết cách định cấu hình các bảng riêng lẻ.
ALTER TABLE <table_name> SET (autovacuum_vacuum_cost_limit = <large_value>) ALTER TABLE <table_name> SET (autovacuum_vacuum_cost_delay = <lower_cost_delay>)
Sử dụng tham số đầu tiên sẽ đảm bảo luồng autovacuum được gán cho bảng sẽ thực hiện nhiều công việc hơn trước khi đi ngủ. Giảm autovacuum_vacuum_cost_delay cũng có nghĩa là chuỗi đang ngủ ít thời gian hơn.
Lời kết
Như bạn có thể thấy, việc thay đổi các thông số cấu hình cho chân không và phân tích là đơn giản, nhưng nó cần quan sát cẩn thận trước. Mọi cơ sở dữ liệu đều khác nhau về kích thước, kiểu lưu lượng truy cập và tỷ lệ giao dịch. Chúng tôi khuyên các DBA nên bắt đầu bằng cách thu thập đủ thông tin về cơ sở dữ liệu của họ trước khi thay đổi các thông số hoặc triển khai chế độ phân tích / chân không thủ công. Thông tin đó có thể là:
- Số hàng trong mỗi bảng
- Số bộ giá trị đã chết trong mỗi bảng
- Thời điểm hút chân không cuối cùng cho mỗi bàn
- Thời điểm phân tích cuối cùng cho mỗi bảng
- Tỷ lệ chèn / cập nhật / xóa dữ liệu trong mỗi bảng
- Thời gian autovacuum thực hiện cho mỗi bảng
- Cảnh báo về việc bảng không được hút bụi
- Hiệu suất hiện tại của hầu hết các truy vấn quan trọng và các bảng mà chúng truy cập
- Hiệu suất của các truy vấn giống nhau sau khi hút chân không / phân tích thủ công
Từ đây, các DBA có thể chọn một vài bảng "thí điểm" để bắt đầu tối ưu hóa. Họ có thể bắt đầu thay đổi đặc tính chân không / phân tích cho các bảng và kiểm tra hiệu suất. PostgreSQL là một công cụ cơ sở dữ liệu thông minh - các DBA thường thấy rằng có lẽ tốt nhất là để PostgreSQL thực hiện việc hút bụi và phân tích thay vì làm những việc đó theo cách thủ công.