PostgreSQL là một trong những cơ sở dữ liệu nguồn mở phổ biến nhất trên thế giới và đã triển khai thành công trên một số môi trường quan trọng trên nhiều miền khác nhau, sử dụng các ứng dụng OLTP cao cấp trong thời gian thực thực hiện hàng triệu và hàng tỷ giao dịch mỗi ngày. PostgreSQL I / O khá đáng tin cậy, ổn định và hoạt động tốt trên hầu hết mọi phần cứng, kể cả đám mây.
Để đảm bảo rằng cơ sở dữ liệu hoạt động ở quy mô dự kiến với thời gian phản hồi dự kiến, cần có một số kỹ thuật hiệu suất. Chà, việc hoàn thành hiệu suất cơ sở dữ liệu tốt phụ thuộc vào nhiều yếu tố khác nhau. Hiệu suất cơ sở dữ liệu có thể xấu đi vì nhiều lý do khác nhau như đo kích thước cơ sở hạ tầng, chiến lược bảo trì cơ sở dữ liệu không hiệu quả, mã SQL kém hoặc các quy trình cơ sở dữ liệu được định cấu hình kém không sử dụng được tất cả các tài nguyên có sẵn - CPU, bộ nhớ, băng thông mạng và I / O đĩa.
Điều gì có thể khiến Hiệu suất cơ sở dữ liệu bị suy giảm?
- Các truy vấn được viết sai với các phép nối, logic, v.v. không hợp lệ, chiếm nhiều CPU và bộ nhớ
- Các truy vấn thực hiện quét toàn bảng trên các bảng lớn do lập chỉ mục không đúng
- Bảo trì cơ sở dữ liệu kém mà không có số liệu thống kê thích hợp
- Lập kế hoạch năng lực không hiệu quả dẫn đến cơ sở hạ tầng không đủ kích thước
- Thiết kế logic và vật lý không phù hợp
- Không có kết nối tổng hợp tại chỗ, điều này khiến các ứng dụng tạo ra một số lượng lớn kết nối theo cách không kiểm soát được
Vì vậy, đó là rất nhiều lĩnh vực tiềm ẩn có thể gây ra các vấn đề về hiệu suất. Một trong những lĩnh vực quan trọng mà tôi muốn tập trung vào trong blog này là cách điều chỉnh hiệu suất I / O (Đầu vào / Đầu ra) của PostgreSQL. Việc điều chỉnh các hoạt động Đầu vào / Đầu ra của PostgreSQL là điều cần thiết, đặc biệt là trong môi trường giao dịch cao như OLTP hoặc trong môi trường Kho dữ liệu với phân tích dữ liệu phức tạp trên các tập dữ liệu có kích thước lớn.
Hầu hết các vấn đề về hiệu suất cơ sở dữ liệu chủ yếu là do I / O cao. Điều này có nghĩa là, các quy trình cơ sở dữ liệu đang dành nhiều thời gian hơn để ghi hoặc đọc từ đĩa. Mọi thao tác dữ liệu thời gian thực đều bị ràng buộc I / O, điều bắt buộc là phải đảm bảo cơ sở dữ liệu được điều chỉnh I / O. Trong blog này, tôi sẽ tập trung vào các vấn đề I / O phổ biến mà cơ sở dữ liệu PostgreSQL có thể gặp phải trong môi trường sản xuất thời gian thực.
Điều chỉnh PostgreSQL I / O
Điều chỉnh PostgreSQL I / O là điều bắt buộc để xây dựng một kiến trúc cơ sở dữ liệu có hiệu suất cao và có thể mở rộng. Hãy cùng chúng tôi xem xét các yếu tố khác nhau ảnh hưởng đến hiệu suất I / O:
- Lập chỉ mục
- Phân vùng
- Điểm kiểm tra
- VACUUM, PHÂN TÍCH (với FILLFACTOR)
- Các vấn đề I / O khác
- PostgreSQL I / O trên đám mây
- Công cụ
Lập chỉ mục
Lập chỉ mục là một trong những kỹ thuật điều chỉnh cốt lõi đóng vai trò cấp thiết trong việc cải thiện hiệu suất I / O của cơ sở dữ liệu. Điều này thực sự áp dụng cho bất kỳ cơ sở dữ liệu nào. PostgreSQL hỗ trợ các loại chỉ mục khác nhau có thể tăng tốc hoạt động đọc ở mức độ lớn, mang lại khả năng mở rộng nâng cao cho các ứng dụng. Mặc dù việc tạo chỉ mục khá đơn giản và dễ hiểu, nhưng điều cần thiết là các DBA và nhà phát triển phải có kiến thức về loại chỉ mục để chọn và trên những cột nào. Thứ hai dựa trên các yếu tố khác nhau như độ phức tạp của truy vấn, kiểu dữ liệu, số lượng dữ liệu, khối lượng ghi, kích thước dữ liệu, kiến trúc đĩa, cơ sở hạ tầng (đám mây công cộng, đám mây riêng hoặc tại chỗ), v.v.
Trong khi lập chỉ mục có thể cải thiện đáng kể hiệu suất đọc truy vấn, nó cũng có thể làm chậm quá trình ghi vào các cột được lập chỉ mục. Hãy để chúng tôi xem xét một ví dụ:
Tác động của Chỉ mục đến hoạt động ĐỌC
Một bảng có tên là trống với khoảng 1 triệu hàng.
ĐỌC Hiệu suất mà không có Chỉ mục
postgres=# select * from emp where eid=10;
eid | ename | peid | did | doj
-----+---------------+--------+------+------------
10 | emp | | 1 | 2018-06-06
(1 row)
Time: 70.020 ms => took about 70+ milli-seconds to respond with on row
ĐỌC Hiệu suất với Chỉ mục
Hãy để chúng tôi đặt chỉ mục trên cột eid và xem sự khác biệt
postgres=# create index indx001 on emp ( eid );
CREATE INDEX
postgres=# select * from emp where eid=10;
eid | ename | peid | did | doj
------+-------------+-------+------+------------
10 | emp | | 1 | 2018-06-06
(1 row)
Time: 0.454 ms => 0.4+ milli-seconds!!! thats a huge difference - isn’t it?
Vì vậy, lập chỉ mục rất quan trọng.
Tác động của chỉ mục đến hoạt động WRITE
Các chỉ mục làm chậm hiệu suất ghi. Trong khi Chỉ mục có tác động đến tất cả các loại hoạt động ghi, chúng ta hãy xem xét một số phân tích về tác động của Chỉ mục đối với CHÈN
Chèn 1 triệu hàng vào Bảng không có chỉ mục
postgres=# do $$
postgres$# declare
postgres$# i integer;
postgres$# begin
postgres$# for i in 1..1000000 loop
postgres$# insert into emp values (i,'emp',null,1,current_date);
postgres$# end loop;
postgres$# end $$;
DO
Time: 4818.470 ms (00:04.818) => Takes about 4.8 seconds
Chèn 1 triệu hàng giống nhau với Chỉ mục
Trước tiên hãy để chúng tôi tạo Chỉ mục
postgres=# create index indx001 on emp ( eid );
CREATE INDEX
postgres=# do $$
postgres$# declare
postgres$# i integer;
postgres$# begin
postgres$# for i in 1..1000000 loop
postgres$# insert into emp values (i,'emp',null,1,current_date);
postgres$# end loop;
postgres$# end $$;
DO
Time: 7825.494 ms (00:07.825) => Takes about 7.8 seconds
Vì vậy, như chúng ta có thể quan sát, thời gian CHÈN tăng 80% chỉ với một chỉ mục và có thể mất nhiều thời gian hơn để kết thúc khi có nhiều chỉ mục. Nó có thể trở nên tồi tệ hơn khi có các chỉ mục dựa trên chức năng. Đó là những gì DBA phải sống chung! Các chỉ mục sẽ tăng hiệu suất ghi. Tuy nhiên, có nhiều cách để giải quyết vấn đề này, điều này phụ thuộc vào kiến trúc đĩa. Nếu máy chủ cơ sở dữ liệu đang sử dụng nhiều hệ thống tệp đĩa, thì các chỉ mục và bảng có thể được đặt trên nhiều không gian bảng nằm trên nhiều hệ thống tệp đĩa. Bằng cách này, có thể đạt được hiệu suất I / O tốt hơn.
MẸO quản lý chỉ mục
- Hiểu sự cần thiết của các chỉ mục. Lập chỉ mục thông minh là chìa khóa.
- Tránh tạo nhiều chỉ mục và chắc chắn không có chỉ mục không cần thiết, điều này thực sự có thể làm giảm hiệu suất ghi.
- Giám sát việc sử dụng các chỉ mục và loại bỏ mọi chỉ mục không sử dụng.
- Khi các cột được lập chỉ mục có thể bị thay đổi dữ liệu, các chỉ mục cũng bị phình ra. Vì vậy, hãy thường xuyên tổ chức lại các chỉ mục.
Phân vùng
Một chiến lược phân vùng hiệu quả có thể giảm thiểu các vấn đề về hiệu suất I / O đến một mức độ lớn. Các bảng lớn có thể được phân vùng dựa trên logic nghiệp vụ. PostgreSQL hỗ trợ phân vùng bảng. Mặc dù hiện tại nó không hỗ trợ đầy đủ tất cả các tính năng, nhưng nó chỉ có thể hỗ trợ một số trường hợp sử dụng trong thời gian thực. Trong PostgreSQL, các bảng con được phân vùng là hoàn toàn riêng lẻ đối với bảng chính, đây là một nút thắt cổ chai. Ví dụ:các ràng buộc được tạo trên bảng chính không thể được kế thừa tự động sang các bảng con.
Tuy nhiên, từ quan điểm cân bằng I / O, phân vùng thực sự có thể hữu ích. Tất cả các phân vùng con có thể được chia thành nhiều vùng bảng và hệ thống tệp đĩa. Các truy vấn có phạm vi ngày trong mệnh đề “where” chạm vào bảng, được phân vùng dựa trên phạm vi ngày, có thể hưởng lợi từ việc phân vùng bằng cách chỉ quét một hoặc hai phân vùng thay vì toàn bộ bảng.
Điểm kiểm tra
Các điểm kiểm tra xác định trạng thái nhất quán của cơ sở dữ liệu. Chúng rất quan trọng và điều quan trọng là các điểm kiểm tra phải diễn ra đủ thường xuyên để đảm bảo các thay đổi dữ liệu được lưu vĩnh viễn vào đĩa và cơ sở dữ liệu luôn ở trạng thái nhất quán. Điều đó đang được nói, cấu hình không đúng của các điểm kiểm tra có thể dẫn đến các vấn đề về hiệu suất I / O. Các DBA phải tỉ mỉ trong việc định cấu hình các điểm kiểm tra để đảm bảo không có I / O tăng đột biến và điều này cũng phụ thuộc vào mức độ tốt của đĩa và cách bố trí tệp dữ liệu được lưu trữ.
Trạm kiểm soát nào?
Nói một cách dễ hiểu, các điểm kiểm tra sẽ đảm bảo:
- Tất cả dữ liệu đã cam kết được ghi vào các tệp dữ liệu trên đĩa.
- tệp tắc nghẽn được cập nhật với trạng thái cam kết.
- Các tệp nhật ký giao dịch trong thư mục pg_xlog (bây giờ là pg_wal) được tái chế.
Điều đó giải thích cách các điểm kiểm tra chuyên sâu I / O. Có các tham số trong postgresql.conf có thể được định cấu hình / điều chỉnh để kiểm soát hành vi của trạm kiểm soát và các tham số đó là max_wal_size, min_wal_size, checkpoint_timeout và checkpoint_completion_target. Các tham số này sẽ quyết định tần suất các điểm kiểm tra sẽ xảy ra và trong khoảng thời gian các điểm kiểm tra phải hoàn thành.
Làm thế nào để hiểu cấu hình nào tốt hơn cho các trạm kiểm soát? Làm thế nào để điều chỉnh chúng?
Dưới đây là một số mẹo:
- Đánh giá TPS cơ sở dữ liệu. Đánh giá tổng khối lượng giao dịch xảy ra trong cơ sở dữ liệu trong một ngày làm việc và cũng xác định thời điểm số lượng giao dịch cao nhất truy cập vào cơ sở dữ liệu.
- Thường xuyên thảo luận với các nhà phát triển ứng dụng và các nhóm kỹ thuật khác để hiểu số liệu thống kê về tỷ lệ giao dịch trên cơ sở dữ liệu cũng như mức tăng trưởng giao dịch trong tương lai.
- Điều này cũng có thể được thực hiện từ phần cuối của cơ sở dữ liệu:
-
Theo dõi cơ sở dữ liệu và đánh giá số lượng giao dịch xảy ra trong ngày. Điều này có thể được thực hiện bằng cách truy vấn các bảng pgcatalog như pg_stat_user_tables.
-
Đánh giá số lượng tệp lưu trữ wal được tạo mỗi ngày
-
Theo dõi để hiểu cách các điểm kiểm tra đang hoạt động bằng cách bật tham số log_checkpoints
2018-06-06 15:03:16.446 IST [2111] LOG: checkpoint starting: xlog 2018-06-06 15:03:22.734 IST [2111] LOG: checkpoint complete: wrote 12112 buffers (73.9%); 0 WAL file(s) added, 0 removed, 25 recycled; write=6.058 s, sync=0.218 s, total=6.287 s; sync files=4, longest=0.178 s, average=0.054 s; distance=409706 kB, estimate=412479 kB
-
Hiểu xem cấu hình điểm kiểm tra hiện tại có đủ tốt cho cơ sở dữ liệu hay không. Định cấu hình tham số checkpoint_warning (theo mặc định được định cấu hình thành 30 giây) để xem các cảnh báo bên dưới trong tệp nhật ký postgres.
2018-06-06 15:02:42.295 IST [2111] LOG: checkpoints are occurring too frequently (11 seconds apart) 2018-06-06 15:02:42.295 IST [2111] HINT: Consider increasing the configuration parameter "max_wal_size".
-
Cảnh báo trên có nghĩa là gì?
Các điểm kiểm tra thường xảy ra bất cứ khi nào max_wal_size (1 GB theo mặc định có nghĩa là 64 tệp WAL) giá trị của các tệp nhật ký được lấp đầy hoặc khi đạt đến checkpoint_timeout (cứ 5 phút một lần theo mặc định). Cảnh báo trên có nghĩa là max_wal_size được định cấu hình không đủ và các điểm kiểm tra đang diễn ra sau mỗi 11 giây, điều đó có nghĩa là 64 tệp WAL trong thư mục PG_WAL sẽ được lấp đầy chỉ trong 11 giây, điều này quá thường xuyên. Nói cách khác, nếu có ít giao dịch thường xuyên hơn, thì các trạm kiểm soát sẽ diễn ra sau mỗi 5 phút. Vì vậy, như gợi ý cho thấy, hãy tăng thông số max_wal_size lên một giá trị cao hơn, thông số max_min_size có thể được tăng lên bằng hoặc nhỏ hơn giá trị cũ.
Một tham số quan trọng khác cần xem xét từ quan điểm hiệu suất I / O là checkpoint_completion_target, theo mặc định được định cấu hình thành 0,5.
checkpoint_completion_target =0,5 x checkpoint_timeout =2,5 phút
Điều đó có nghĩa là các trạm kiểm soát có 2,5 phút để đồng bộ các khối bẩn vào đĩa. 2,5 phút có đủ không? Điều đó cần được đánh giá. Nếu số lượng khối bẩn được ghi rất nhiều, thì 2,5 phút có vẻ rất hung hăng và đó là thời điểm có thể quan sát thấy mức tăng đột biến I / O. Việc định cấu hình tham số mục đích hoàn thành phải được thực hiện dựa trên các giá trị max_wal_size và checkpoint_timeout. Nếu các thông số này được nâng lên một giá trị cao hơn, hãy cân nhắc việc tăng checkpoint_completion_target cho phù hợp.
VACUUM, PHÂN TÍCH (với FILLFACTOR)
VACUUM là một trong những tính năng mạnh mẽ nhất của PostgreSQL. Nó có thể được sử dụng để loại bỏ các khối (không gian bị phân mảnh) trong các bảng và chỉ mục, và được tạo ra bởi các giao dịch. Cơ sở dữ liệu phải được sử dụng VACUUMing thường xuyên để đảm bảo duy trì lành mạnh và hoạt động tốt hơn. Một lần nữa, không sử dụng cơ sở dữ liệu thường xuyên có thể dẫn đến các vấn đề nghiêm trọng về hiệu suất. PHÂN TÍCH phải được thực hiện cùng với VACUUM (PHÂN TÍCH VACUUM) để đảm bảo thống kê cập nhật cho công cụ lập kế hoạch truy vấn.
PHÂN TÍCH KHÔNG KHÍ có thể được thực hiện theo hai cách:thủ công, tự động hoặc cả hai. Trong môi trường sản xuất thời gian thực, nó nói chung là cả hai. VACUUM tự động được kích hoạt bởi tham số “autovacuum” được định cấu hình theo mặc định thành “bật”. Với tính năng autovacuum được bật, PostgreSQL tự động bắt đầu VACUUMing các Bảng theo định kỳ. Các bảng ứng cử viên cần hút bụi được chọn bởi quy trình hút chân không tự động dựa trên các ngưỡng khác nhau được thiết lập bởi các thông số autovacuum * khác nhau, các thông số này có thể được tinh chỉnh / điều chỉnh để đảm bảo các khối của bảng được xóa định kỳ. Hãy để chúng tôi xem xét một số thông số và việc sử dụng chúng -
Các thông số tự động hút chân không
autovacuum =on | Tham số này được sử dụng để bật / tắt autovacuum. Mặc định là “bật”. |
log_autovacuum_min_duration =-1 | Ghi lại khoảng thời gian của quá trình autovacuum. Điều quan trọng là phải hiểu quá trình autovacuum đã chạy trong bao lâu. |
autovacuum_max_workers =3 | Số lượng quy trình hút chân không tự động cần thiết. Điều này phụ thuộc vào mức độ tích cực của các giao dịch cơ sở dữ liệu và số lượng CPU bạn có thể cung cấp cho các quy trình autovacuum. |
autovacuum_naptime =1 phút | Thời gian nghỉ của autovacuum giữa các lần chạy autovacuum. |
Các thông số xác định ngưỡng để bắt đầu quá trình Autovacuum
(Các) công việc Autovacuum bắt đầu khi đạt đến một ngưỡng nhất định. Dưới đây là các thông số có thể được sử dụng để đặt một ngưỡng nhất định, dựa vào đó, quá trình hút chân không tự động sẽ bắt đầu.
autovacuum_vacuum_threshold =50 | Bảng sẽ được hút chân không khi có tối thiểu 50 hàng được cập nhật / xóa trong Bảng. |
autovacuum_analyze_threshold =50 | Bảng sẽ được phân tích khi có tối thiểu 50 hàng được cập nhật / xóa trong Bảng. |
autovacuum_vacuum_scale_factor =0,2 | Bảng sẽ được hút chân không khi tối thiểu 20% số hàng được cập nhật / xóa trong Bảng. |
autovacuum_analyze_scale_factor =0,1 | Bảng sẽ được hút chân không khi tối thiểu 10% số hàng được cập nhật / xóa trong Bảng. |
Các thông số ngưỡng trên có thể được sửa đổi dựa trên hành vi của cơ sở dữ liệu. Các DBA sẽ cần phân tích và xác định các bảng nóng và đảm bảo các bảng đó được hút bụi thường xuyên nhất có thể để đảm bảo hoạt động tốt. Đạt được một giá trị nhất định cho các tham số này có thể là một thách thức trong môi trường giao dịch cao, trong đó các thay đổi dữ liệu xảy ra mỗi giây. Nhiều lần tôi nhận thấy rằng quá trình autovacuum mất khá nhiều thời gian để hoàn thành, dẫn đến tiêu tốn quá nhiều tài nguyên trong hệ thống sản xuất.
Tôi khuyên bạn không nên phụ thuộc hoàn toàn vào quy trình autovacuum, cách tốt nhất là lên lịch công việc PHÂN TÍCH VACUUM hàng đêm để giảm bớt gánh nặng cho autovacuum. Để bắt đầu, hãy cân nhắc việc TÍCH LŨY các bảng lớn theo cách thủ công với tỷ lệ giao dịch cao.
CHÂN KHÔNG ĐẦY ĐỦ
VACUUM FULL giúp lấy lại không gian bị phình ra trong các bảng và chỉ mục. Không thể sử dụng tiện ích này khi cơ sở dữ liệu trực tuyến vì nó khóa bảng. Các bảng chỉ được đặt ở trạng thái VACUUM FULL khi các ứng dụng đang tắt. Các chỉ mục cũng sẽ được sắp xếp lại cùng với các bảng trong khi VACUUM FULL.
Hãy cùng chúng tôi xem xét tác động của PHÂN TÍCH KHÔNG KHÍ
Bloats:Làm thế nào để xác định bloats? Các khối phồng được tạo ra khi nào?
Dưới đây là một số thử nghiệm:
Tôi có một bảng kích thước 1 GB với 10 triệu hàng.
postgres=# select pg_relation_size('pgbench_accounts')/1024/1024/1024;
?column?
----------------
1
postgres=# select count(*) From pgbench_accounts ;
count
-----------------
10000000
Hãy để chúng tôi xem xét tác động của khối phồng lên một truy vấn đơn giản:select * from pgbench_accounts;
Dưới đây là kế hoạch giải thích cho truy vấn:
postgres=# explain analyze select * from pgbench_accounts;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------
Seq Scan on pgbench_accounts (cost=0.00..263935.00 rows=10000000 width=97)
(actual time=0.033..1054.257 rows=10000000 loops=1)
Planning time: 0.255 ms
Execution time: 1494.448 ms
Bây giờ, chúng ta hãy cập nhật tất cả các hàng trong bảng và xem tác động của truy vấn SELECT ở trên.
postgres=# update pgbench_accounts set abalance=1;
UPDATE 10000000
postgres=# select count(*) From pgbench_accounts ;
count
-----------------
10000000
Dưới đây là KẾ HOẠCH GIẢI THÍCH về việc thực thi CẬP NHẬT bài đăng truy vấn.
postgres=# explain analyze select * from pgbench_accounts;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------
Seq Scan on pgbench_accounts (cost=0.00..527868.39 rows=19999939 width=97)
(actual time=404.474..1520.175 rows=10000000 loops=1)
Planning time: 0.051 ms
Execution time: 1958.532 ms
Kích thước của bảng đã tăng lên 2 GB sau khi CẬP NHẬT
postgres=# select pg_relation_size('pgbench_accounts')/1024/1024/1024;
?column?
-----------------
2
Nếu bạn có thể quan sát và so sánh các con số chi phí của KẾ HOẠCH GIẢI THÍCH trước đó, thì có một sự khác biệt rất lớn. Chi phí đã tăng lên một biên độ lớn. Quan trọng hơn nếu bạn quan sát kỹ, số lượng hàng (chỉ hơn 19 triệu) được quét sau khi CẬP NHẬT cao hơn, gần gấp hai lần số hàng hiện có thực tế (10 triệu). Điều đó có nghĩa là, số lượng hàng cồng kềnh là hơn 9 triệu và thời gian thực tế cũng tăng lên và thời gian thực hiện tăng từ 1,4 giây lên 1,9 giây.
Vì vậy, đó là tác động của việc không VACUUMING BẢNG sau khi CẬP NHẬT. Các con số KẾ HOẠCH GIẢI THÍCH ở trên có nghĩa chính xác là, bảng đã bị cồng kềnh.
Làm thế nào để nhận biết bàn ăn có bị phồng không? Sử dụng mô-đun đóng góp pgstattuple:
postgres=# select * from pgstattuple('pgbench_accounts');
table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent
------------+-------------+------------+---------------+------------------+----------------+--------------------+------------+--------------
2685902848 | 10000000 | 1210000000 | 45.05 | 9879891 | 1195466811 | 44.51 | 52096468 | 1.94
Con số trên chỉ ra rằng một nửa của bảng đã bị đầy hơi.
Hãy để chúng tôi PHÂN TÍCH CHÂN KHÔNG trong bảng và xem tác động ngay bây giờ:
postgres=# VACUUM ANALYZE pgbench_accounts ;
VACUUM
postgres=# explain analyze select * from pgbench_accounts;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------
Seq Scan on pgbench_accounts (cost=0.00..428189.05 rows=10032005 width=97)
(actual time=400.023..1472.118 rows=10000000 loops=1)
Planning time: 4.374 ms
Execution time: 1913.541 ms
Sau khi PHÂN TÍCH CHÂN KHÔNG, các con số chi phí đã giảm xuống. Bây giờ, số hàng được quét đang hiển thị gần 10 triệu, cũng là thời gian thực tế và thời gian thực hiện không thay đổi nhiều. Đó là bởi vì, mặc dù các tấm ngăn trên bàn đã biến mất, nhưng kích thước của bàn được quét vẫn giữ nguyên. Dưới đây là bài đăng đầu ra pgstattuple PHÂN TÍCH CHÂN KHÔNG.
postgres=# select * from pgstattuple('pgbench_accounts');
table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent
------------+-------------+------------+---------------+------------------+----------------+--------------------+------------+--------------
2685902848 | 10000000 | 1210000000 | 45.05 | 0 | 0 | 0 | 1316722516 | 49.02
Con số trên cho thấy rằng tất cả các khối phồng (bộ đồ chết) đã biến mất.
Hãy cùng chúng tôi xem xét tác động của PHÂN TÍCH ĐẦY ĐỦ CHÂN KHÔNG và xem điều gì sẽ xảy ra:
postgres=# vacuum full analyze pgbench_accounts ;
VACUUM
postgres=# explain analyze select * from pgbench_accounts;
QUERY PLAN
---------------------------------------------------------------------------
Seq Scan on pgbench_accounts (cost=0.00..263935.35 rows=10000035 width=97)
(actual time=0.015..1089.726 rows=10000000 loops=1)
Planning time: 0.148 ms
Execution time: 1532.596 ms
Nếu bạn quan sát, thời gian thực tế và con số thời gian thực hiện tương tự như con số trước khi CẬP NHẬT. Ngoài ra, kích thước của bảng hiện đã giảm từ 2 GB xuống 1 GB.
postgres=# select pg_relation_size('pgbench_accounts')/1024/1024/1024;
?column?
-----------------
1
Đó là tác động của VACUUM FULL.
CÔNG TY TNHH THƯƠNG MẠI
FILLFACTOR là một thuộc tính rất quan trọng có thể tạo ra sự khác biệt thực sự cho chiến lược bảo trì cơ sở dữ liệu ở cấp bảng và chỉ mục. Giá trị này cho biết lượng không gian được sử dụng bởi INSERT trong một khối dữ liệu. Giá trị FILLFACTOR mặc định là 100%, có nghĩa là INSERT có thể sử dụng tất cả không gian có sẵn trong một khối dữ liệu. Điều đó cũng có nghĩa là không còn chỗ trống cho các CẬP NHẬT. Giá trị này có thể được giảm xuống một giá trị nhất định đối với các bảng được cập nhật nhiều.
Tham số này có thể được cấu hình cho từng bảng và một chỉ mục. Nếu FILLFACTOR được định cấu hình thành giá trị tối ưu, bạn cũng có thể thấy sự khác biệt thực sự về hiệu suất VACUUM và hiệu suất truy vấn. Tóm lại, các giá trị FILLFACTOR tối ưu đảm bảo số lượng khối không cần thiết không được phân bổ.
Chúng ta hãy xem xét cùng một ví dụ ở trên -
Bảng có một triệu hàng
postgres=# select count(*) From pgbench_accounts ;
count
-----------------
10000000
Trước khi cập nhật, kích thước của bảng là 1 GB
postgres=# select pg_relation_size('pgbench_accounts')/1024/1024/1024;
?column?
--------
1
postgres=# update pgbench_accounts set abalance=1;
UPDATE 10000000
Sau khi cập nhật, kích thước của bảng đã tăng lên 2 GB sau CẬP NHẬT
postgres=# select pg_relation_size('pgbench_accounts')/1024/1024/1024;
?column?
---------
2
Điều đó có nghĩa là số khối được phân bổ cho bảng đã tăng 100%. Nếu FILLFACTOR đã được định cấu hình, kích thước của bảng có thể không tăng theo biên độ đó.
Làm cách nào để biết giá trị nào cần định cấu hình cho FILLFACTOR?
Tất cả phụ thuộc vào những cột nào đang được cập nhật và kích thước của các cột được cập nhật. Nói chung, sẽ rất tốt nếu đánh giá giá trị FILLFACTOR bằng cách thử nghiệm nó trong Cơ sở dữ liệu UAT. Nếu các cột đang được cập nhật chiếm 10% toàn bộ bảng, thì hãy xem xét định cấu hình hệ số lấp đầy thành 90% hoặc 80%.
Lưu ý quan trọng:
Nếu bạn thay đổi giá trị FILLFACTOR cho bảng hiện có bằng dữ liệu, bạn sẽ cần thực hiện ĐẦY ĐỦ hoặc tổ chức lại bảng để đảm bảo giá trị FILLFACTOR có hiệu lực cho dữ liệu hiện có.
MẸO HÚT CHÂN KHÔNG
- Như đã nói ở trên, hãy cân nhắc việc chạy thủ công công việc PHÂN TÍCH VACUUM hàng đêm trên các bảng được sử dụng nhiều ngay cả khi bật autovacuum.
- Xem xét chạy PHÂN TÍCH CHÂN KHÔNG trên các bảng sau khi CHÈN hàng loạt. Điều này rất quan trọng vì nhiều người tin rằng có thể không cần sử dụng CHÂN KHÔNG sau khi CHÈN.
- Giám sát để đảm bảo các bảng hoạt động cao đang nhận được VACUUM thường xuyên bằng cách truy vấn bảng pg_stat_user_tables.
- Sử dụng mô-đun đóng góp pg_stattuple để xác định kích thước của không gian cồng kềnh trong các phân đoạn bảng.
- Không thể sử dụng tiện ích VACUUM FULL trên hệ thống cơ sở dữ liệu sản xuất. Cân nhắc sử dụng các công cụ như pg_reorg hoặc pg_repack, những công cụ này sẽ giúp tổ chức lại các bảng và chỉ mục trực tuyến mà không bị khóa.
- Đảm bảo quy trình AUTOVACUUM chạy trong thời gian dài hơn trong giờ làm việc (lưu lượng truy cập cao).
- Bật tham số log_autovacuum_min_duration để ghi lại thời gian và thời lượng của các quy trình AUTOVACUUM.
- Quan trọng là đảm bảo FILLFACTOR được định cấu hình thành giá trị tối ưu trên các Bảng và Chỉ mục giao dịch cao.
Các vấn đề I / O khác
Sắp xếp đĩa
Các truy vấn thực hiện sắp xếp là một sự xuất hiện phổ biến khác trong cơ sở dữ liệu sản xuất thời gian thực và hầu hết những điều này không thể tránh khỏi. Các truy vấn sử dụng các mệnh đề như GROUP BY, ORDER BY, DISTINCT, CREATE INDEX, VACUUM FULL, v.v. thực hiện sắp xếp và việc sắp xếp có thể diễn ra trên đĩa. Việc sắp xếp diễn ra trong bộ nhớ nếu việc lựa chọn và sắp xếp được thực hiện dựa trên các cột được lập chỉ mục. Đây là nơi mà các chỉ mục tổng hợp đóng một vai trò quan trọng. Các chỉ mục được lưu trữ tích cực vào bộ nhớ. Nếu không, nếu có nhu cầu sắp xếp dữ liệu trên đĩa, hiệu suất sẽ chậm lại đáng kể.
Để đảm bảo việc sắp xếp diễn ra trong bộ nhớ, có thể sử dụng tham số work_mem. Tham số này có thể được cấu hình thành một giá trị để toàn bộ việc sắp xếp có thể được thực hiện trong bộ nhớ. Ưu điểm cốt lõi của tham số này là ngoài việc cấu hình nó trong postgresql.conf, nó cũng có thể được cấu hình ở cấp phiên, cấp người dùng hoặc cấp cơ sở dữ liệu. Giá trị work_mem phải là bao nhiêu? Làm thế nào để biết truy vấn nào đang thực hiện sắp xếp đĩa? Làm cách nào để giám sát các truy vấn thực hiện phân loại đĩa trên cơ sở dữ liệu sản xuất theo thời gian thực?
Câu trả lời là - cấu hình tham số log_temp_files thành một giá trị nhất định. Giá trị tính bằng byte, giá trị 0 ghi lại tất cả các tệp tạm thời (cùng với kích thước của chúng) được tạo trên đĩa do quá trình sắp xếp đĩa. Sau khi tham số được định cấu hình, bạn sẽ có thể thấy các thông báo sau trong tệp nhật ký
2018-06-07 22:48:02.358 IST [4219] LOG: temporary file: path "base/pgsql_tmp/pgsql_tmp4219.0", size 200425472
2018-06-07 22:48:02.358 IST [4219] STATEMENT: create index bid_idx on pgbench_accounts(bid);
2018-06-07 22:48:02.366 IST [4219] LOG: duration: 6421.705 ms statement: create index bid_idx on pgbench_accounts(bid);
Thông báo trên có nghĩa là truy vấn CREATE INDEX đang thực hiện sắp xếp đĩa và đã tạo tệp có kích thước 200425472 byte là 191+ MB. Điều đó chính xác có nghĩa là, tham số work_mem phải được định cấu hình thành 191+ MB trở lên cho truy vấn cụ thể này để thực hiện sắp xếp bộ nhớ.
Đối với các truy vấn ứng dụng, tham số work_mem chỉ có thể được định cấu hình ở cấp độ người dùng. Trước khi làm như vậy, hãy cẩn thận về số lượng kết nối mà người dùng đang thực hiện với cơ sở dữ liệu và số lượng truy vấn sắp xếp đang được thực thi bởi người dùng đó. Bởi vì PostgreSQL cố gắng phân bổ work_mem cho mỗi quy trình (thực hiện sắp xếp) trong mỗi kết nối, điều này có thể gây thiếu bộ nhớ trên máy chủ cơ sở dữ liệu.
Bố cục hệ thống tệp cơ sở dữ liệu
Thiết kế bố cục hệ thống tệp cơ sở dữ liệu hiệu quả và có lợi cho hiệu suất là điều quan trọng từ quan điểm hiệu suất và khả năng mở rộng. Quan trọng là, điều này không phụ thuộc vào kích thước cơ sở dữ liệu. Nói chung, nhận thức là cơ sở dữ liệu kích thước lớn sẽ cần kiến trúc đĩa hiệu suất cao, điều này KHÔNG đúng. Ngay cả khi kích thước cơ sở dữ liệu là 50 GB, bạn có thể cần một cấu trúc đĩa tốt. Và điều này có thể không thực hiện được nếu không phát sinh thêm chi phí.
Dưới đây là một số MẸO cho điều tương tự:
- Đảm bảo cơ sở dữ liệu có nhiều không gian bảng, với các bảng và chỉ mục được nhóm lại dựa trên tốc độ giao dịch.
- Không gian bảng phải được đặt trên nhiều hệ thống tệp đĩa để I / O cân bằng. Điều này cũng sẽ đảm bảo nhiều CPU hoạt động để thực hiện các giao dịch trên nhiều đĩa.
- Cân nhắc đặt thư mục pg_xlog hoặc pg_wal trên một đĩa riêng biệt trên cơ sở dữ liệu giao dịch cao.
- Đảm bảo các thông số * _cost được định cấu hình dựa trên cơ sở hạ tầng
- Sử dụng iostat, mpstat và các công cụ giám sát I / O khác để hiểu số liệu thống kê I / O trên tất cả các đĩa và kiến trúc / quản lý các đối tượng cơ sở dữ liệu cho phù hợp.
PostgreSQL trên đám mây
Cơ sở hạ tầng rất quan trọng để có hiệu suất cơ sở dữ liệu tốt. Các chiến lược kỹ thuật hiệu suất khác nhau dựa trên cơ sở hạ tầng và môi trường. Cần đặc biệt chú ý đến cơ sở dữ liệu PostgreSQL được lưu trữ trên đám mây. Điểm chuẩn hiệu suất cho cơ sở dữ liệu được lưu trữ trên máy chủ barebone vật lý trong trung tâm dữ liệu cục bộ có thể hoàn toàn khác với cơ sở dữ liệu được lưu trữ trong đám mây công cộng.
Nói chung, các phiên bản đám mây có thể chậm hơn một chút và các điểm chuẩn khác nhau theo biên độ đáng kể, đặc biệt là về I / O. Luôn thực hiện kiểm tra độ trễ I / O trước khi chọn / xây dựng phiên bản đám mây. Trước sự ngạc nhiên của tôi, tôi biết rằng hiệu suất của các phiên bản đám mây cũng có thể khác nhau tùy thuộc vào các khu vực, mặc dù chúng đến từ cùng một nhà cung cấp đám mây. Để giải thích thêm về điều này, một phiên bản đám mây có cùng thông số kỹ thuật được xây dựng ở hai khu vực khác nhau có thể cung cấp cho bạn kết quả hiệu suất khác nhau.
Tải dữ liệu hàng loạt
Các hoạt động tải dữ liệu hàng loạt ngoại tuyến khá phổ biến trong thế giới cơ sở dữ liệu. Chúng có thể tạo ra tải I / O đáng kể, do đó làm chậm hiệu suất tải dữ liệu. Tôi đã phải đối mặt với những thách thức như vậy trong kinh nghiệm của mình với tư cách là DBA. Thông thường, tải dữ liệu rất chậm và phải được điều chỉnh. Đây là một số lời khuyên. Xin lưu ý bạn, những điều này chỉ áp dụng cho các hoạt động tải dữ liệu ngoại tuyến và không thể được coi là tải dữ liệu trên cơ sở dữ liệu sản xuất trực tiếp.
- Vì hầu hết các hoạt động tải dữ liệu được thực hiện ngoài giờ làm việc, hãy đảm bảo các thông số sau được định cấu hình trong quá trình tải dữ liệu -
- Định cấu hình các giá trị liên quan đến điểm kiểm tra đủ lớn để các điểm kiểm tra không gây ra bất kỳ sự cố hiệu suất nào.
- Tắt full_page_write
- Tắt tính năng lưu trữ của wal
- Định cấu hình thông số sync_commit thành “tắt”
- Bỏ các ràng buộc và chỉ mục cho các bảng đó chịu tải dữ liệu (Các ràng buộc và chỉ mục có thể được tạo lại sau khi tải dữ liệu với giá trị work_mem lớn hơn)
- Nếu bạn đang thực hiện tải dữ liệu từ tệp CSV, thì Maint_work_mem lớn hơn có thể mang lại cho bạn kết quả tốt.
- Mặc dù sẽ có lợi ích đáng kể về hiệu suất, nhưng KHÔNG tắt thông số fsync vì điều đó có thể dẫn đến hỏng dữ liệu.
MẸO để phân tích hiệu suất đám mây
- Thực hiện kiểm tra độ trễ I / O kỹ lưỡng bằng pgbench. Theo kinh nghiệm của tôi, tôi đã có kết quả hiệu suất khá bình thường khi thực hiện kiểm tra độ trễ của đĩa như một phần của đánh giá TPS. Đã xảy ra sự cố với hiệu suất bộ nhớ cache trên một số phiên bản đám mây công cộng. Điều này sẽ giúp chọn các thông số kỹ thuật thích hợp cho phiên bản đám mây được chọn cho cơ sở dữ liệu.
- Các phiên bản đám mây có thể hoạt động khác nhau giữa các vùng. Phiên bản đám mây có thông số kỹ thuật chứng chỉ trong một khu vực có thể cho kết quả hiệu suất khác so với phiên bản đám mây có cùng thông số kỹ thuật ở khu vực khác. Các bài kiểm tra pgbench của tôi được thực hiện trên nhiều phiên bản đám mây (tất cả các thông số kỹ thuật giống nhau với cùng một nhà cung cấp đám mây) trên các khu vực khác nhau đã cho tôi kết quả khác nhau trên một số phiên bản. This is important especially when you are migrating to cloud.
- Query performance on the cloud might need a different tuning approach. DBAs will need to be using *_cost parameters to ensure healthy query execution plans are generated.
Tools to Monitor PostgreSQL Performance
There are various tools to monitor PostgreSQL performance. Let me highlight some of those.
- pg_top is a GREAT tool to monitor PostgreSQL database dynamically. I would highly recommend this tool for DBAs for various reasons. This tool has numerous advantages, let me list them out:
- pg_top tool uses textual interface and is similar to Unix “top” utility.
- Will clearly list out the processes and the hardware resources utilized. What excites me with this tool is that it will clearly tell you if a particular process is currently on DISK or CPU - in my view that’s excellent. DBAs can clearly pick the process running for longer time on the disk.
- You can check the EXPLAIN PLAN of the top SQLs dynamically or instantly
- You can also find out what Tables or Indexes are being scanned instantly
- Nagios is a popular monitoring tool for PostgreSQL which has both open-source and commercial versions. Open source version should suffice for monitoring. Custom Perl scripts can be built and plugged into Nagios module.
- Pgbadger is a popular tool which can be used to analyze PostgreSQL log files and generate performance reports. This report can be used to analyze the performance of checkpoints, disk sorting.
- Zabbix is another popular tool used for PostgreSQL monitoring.
ClusterControl is an up-and-coming management platform for PostgreSQL. Apart from monitoring, it also has functionality to deploy replication setups with load balancers, automatic failover, backup management, among others.