Với tư cách là Quản trị viên cơ sở dữ liệu PostgreSQL, có những kỳ vọng hàng ngày là kiểm tra các bản sao lưu, áp dụng các thay đổi DDL, đảm bảo nhật ký không có bất kỳ lỗi nào của trò chơi vi phạm LỖI và trả lời các cuộc gọi hoảng loạn từ các nhà phát triển, những người báo cáo đang chạy lâu gấp đôi bình thường và họ có cuộc họp sau 10 phút.
Ngay cả khi hiểu rõ về tình trạng của cơ sở dữ liệu được quản lý, sẽ luôn có những trường hợp mới và vấn đề mới xuất hiện liên quan đến hiệu suất và cảm giác của cơ sở dữ liệu. Cho dù đó là một email hoảng loạn hay một vé mở cho "cơ sở dữ liệu cảm thấy chậm", nhiệm vụ phổ biến này thường có thể được thực hiện với một vài bước để kiểm tra xem có sự cố với PostgreSQL hay không và vấn đề đó có thể là gì.
Đây hoàn toàn không phải là một hướng dẫn đầy đủ, cũng như không cần thực hiện các bước theo thứ tự cụ thể nào. Nhưng đó là một tập hợp các bước ban đầu có thể được thực hiện để giúp nhanh chóng tìm ra những kẻ vi phạm phổ biến, cũng như có được cái nhìn sâu sắc mới về vấn đề có thể là gì. Nhà phát triển có thể biết cách ứng dụng hoạt động và phản hồi, nhưng Quản trị viên cơ sở dữ liệu biết cách cơ sở dữ liệu hoạt động và phản hồi với ứng dụng, đồng thời, vấn đề có thể được tìm ra.
LƯU Ý: Các truy vấn được thực thi phải được thực hiện dưới dạng superuser, chẳng hạn như ‘postgres’ hoặc bất kỳ người dùng cơ sở dữ liệu nào được cấp quyền superuser. Người dùng hạn chế sẽ bị từ chối hoặc bị bỏ qua dữ liệu.
Bước 0 - Thu thập thông tin
Nhận càng nhiều thông tin càng tốt từ bất kỳ ai nói rằng cơ sở dữ liệu có vẻ chậm; các truy vấn cụ thể, các ứng dụng được kết nối, khung thời gian về độ chậm của hiệu suất, v.v. Chúng càng cung cấp nhiều thông tin thì càng dễ tìm ra vấn đề.
Bước 1 - Kiểm tra pg_stat_activity
Yêu cầu có thể có nhiều dạng khác nhau, nhưng nếu "sự chậm chạp" là vấn đề chung, thì việc kiểm tra pg_stat_activity là bước đầu tiên để hiểu điều gì đang xảy ra. Chế độ xem pg_stat_activity (có thể tìm thấy tài liệu cho mọi cột trong chế độ xem này ở đây) chứa một hàng cho mọi quy trình / kết nối máy chủ với cơ sở dữ liệu từ máy khách. Có một số thông tin hữu ích trong chế độ xem này có thể giúp ích.
LƯU Ý: pg_stat_activity đã được biết là thay đổi cấu trúc theo thời gian, tinh chỉnh dữ liệu mà nó trình bày. Sự hiểu biết về bản thân các cột sẽ giúp xây dựng các truy vấn động nếu cần trong tương lai.
Các cột đáng chú ý trong pg_stat_activity là:
- truy vấn:cột văn bản hiển thị truy vấn hiện đang được thực thi, đang chờ được thực thi hoặc được thực hiện lần cuối (tùy thuộc vào trạng thái). Điều này có thể giúp xác định truy vấn / truy vấn nào mà nhà phát triển có thể đang báo cáo đang chạy chậm.
- client_addr:Địa chỉ IP mà kết nối và truy vấn này bắt nguồn từ đó. Nếu trống (hoặc Null), nó bắt nguồn từ localhost.
- backend_start, xact_start, query_start:Ba thứ này cung cấp dấu thời gian về thời điểm bắt đầu tương ứng. Backend_start biểu thị thời điểm kết nối với cơ sở dữ liệu được thiết lập, xact_start là khi giao dịch hiện tại bắt đầu và query_start là khi truy vấn hiện tại (hoặc cuối cùng) bắt đầu.
- trạng thái:Trạng thái của kết nối với cơ sở dữ liệu. Đang hoạt động có nghĩa là nó hiện đang thực hiện một truy vấn, "nhàn rỗi" có nghĩa là nó đang đợi thêm thông tin nhập từ khách hàng, "không hoạt động trong giao dịch" có nghĩa là nó đang chờ thêm thông tin đầu vào từ khách hàng trong khi giữ một giao dịch đang mở. (Có những người khác, tuy nhiên khả năng xảy ra là rất hiếm, hãy tham khảo tài liệu để biết thêm thông tin).
- datname:Tên của cơ sở dữ liệu mà kết nối hiện đang được kết nối. Trong nhiều cụm cơ sở dữ liệu, điều này có thể giúp cô lập các kết nối có vấn đề.
- wait_event_type và wait_event:Các cột này sẽ rỗng khi truy vấn không đợi, nhưng nếu đang đợi, chúng sẽ chứa thông tin về lý do tại sao truy vấn đang chờ và việc khám phá pg_locks có thể xác định xem nó đang đợi gì. (PostgreSQL 9.5 trở về trước chỉ có một cột boolean được gọi là "wait", true nếu đang chờ, false nếu không.
1.1. Truy vấn có đang chờ / bị chặn không?
Nếu có một truy vấn cụ thể hoặc các truy vấn “chậm” hoặc “treo”, hãy kiểm tra xem chúng có đang chờ một truy vấn khác hoàn thành hay không. Do khóa quan hệ, các truy vấn khác có thể khóa bảng và không cho phép bất kỳ truy vấn nào khác truy cập hoặc thay đổi dữ liệu cho đến khi truy vấn hoặc giao dịch đó được thực hiện.
PostgreSQL 9.5 trở về trước:
SELECT * FROM pg_stat_activity WHERE waiting = TRUE;
PostgreSQL 9.6:
SELECT * FROM pg_stat_activity WHERE wait_event IS NOT NULL;
PostgreSQL 10 trở lên (?):
SELECT * FROM pg_stat_activity WHERE wait_event IS NOT NULL AND backend_type = 'client backend';
Kết quả của truy vấn này sẽ hiển thị bất kỳ kết nối nào hiện đang chờ trên một kết nối khác để giải phóng khóa trên một mối quan hệ cần thiết.
Nếu truy vấn bị chặn bởi một kết nối khác, có một số cách để tìm hiểu xem chúng là gì. Trong PostgreSQL 9.6 trở lên, hàm pg_blocking_pids () cho phép nhập ID quy trình đang bị chặn và nó sẽ trả về một mảng ID quy trình chịu trách nhiệm chặn nó.
PostgreSQL 9.6 trở lên:
SELECT * FROM pg_stat_activity
WHERE pid IN (SELECT pg_blocking_pids(<pid of blocked query>));
PostgreSQL 9.5 trở về trước:
SELECT blocked_locks.pid AS blocked_pid,
blocked_activity.usename AS blocked_user,
blocking_locks.pid AS blocking_pid,
blocking_activity.usename AS blocking_user,
blocked_activity.query AS blocked_statement,
blocking_activity.query AS current_statement_in_blocking_process
FROM pg_catalog.pg_locks blocked_locks
JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
JOIN pg_catalog.pg_locks blocking_locks
ON blocking_locks.locktype = blocked_locks.locktype
AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE
AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
AND blocking_locks.pid != blocked_locks.pid
JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
WHERE NOT blocked_locks.GRANTED;
(Có sẵn từ Wiki PostgreSQL).
Các truy vấn này sẽ trỏ đến bất kỳ thứ gì đang chặn một PID cụ thể được cung cấp. Do đó, bạn có thể đưa ra quyết định loại bỏ truy vấn hoặc kết nối chặn hoặc để nó chạy.
Bước 2 - Nếu các truy vấn đang chạy, tại sao chúng lại mất nhiều thời gian như vậy?
2.1. Người lập kế hoạch có đang chạy các truy vấn một cách hiệu quả không?
Nếu một truy vấn (hoặc một tập hợp các truy vấn) được đề cập có trạng thái là 'hoạt động', thì nó thực sự đang chạy. Nếu toàn bộ truy vấn không có sẵn trong pg_stat_activity, hãy tìm nạp nó từ các nhà phát triển hoặc nhật ký postgresql và bắt đầu khám phá công cụ lập kế hoạch truy vấn.
EXPLAIN SELECT * FROM postgres_stats.table_stats t JOIN hosts h ON (t.host_id = h.host_id) WHERE logged_date >= '2018-02-01' AND logged_date < '2018-02-04' AND t.india_romeo = 569;
Nested Loop (cost=0.280..1328182.030 rows=2127135 width=335)
-> Index Scan using six on victor_oscar echo (cost=0.280..8.290 rows=1 width=71)
Index Cond: (india_romeo = 569)
-> Append (cost=0.000..1306902.390 rows=2127135 width=264)
-> Seq Scan on india_echo romeo (cost=0.000..0.000 rows=1 width=264)
Filter: ((logged_date >= '2018-02-01'::timestamp with time zone) AND (logged_date < '2018-02-04'::timestamp with time zone) AND (india_romeo = 569))
-> Seq Scan on juliet victor_echo (cost=0.000..437153.700 rows=711789 width=264)
Filter: ((logged_date >= '2018-02-01'::timestamp with time zone) AND (logged_date < '2018-02-04'::timestamp with time zone) AND (india_romeo = 569))
-> Seq Scan on india_papa quebec_bravo (cost=0.000..434936.960 rows=700197 width=264)
Filter: ((logged_date >= '2018-02-01'::timestamp with time zone) AND (logged_date < '2018-02-04'::timestamp with time zone) AND (india_romeo = 569))
-> Seq Scan on two oscar (cost=0.000..434811.720 rows=715148 width=264)
Filter: ((logged_date >= '2018-02-01'::timestamp with time zone) AND (logged_date < '2018-02-04'::timestamp with time zone) AND (india_romeo = 569))
Ví dụ này cho thấy một kế hoạch truy vấn cho một phép nối hai bảng cũng truy cập vào một bảng được phân vùng. Chúng tôi đang tìm kiếm bất kỳ thứ gì có thể khiến truy vấn bị chậm và trong trường hợp này, người lập kế hoạch đang thực hiện một số Lần quét tuần tự trên các phân vùng, cho thấy rằng chúng đang thiếu chỉ mục. Thêm chỉ mục vào các bảng này cho cột ‘india_romeo’ sẽ cải thiện ngay lập tức truy vấn này.
Những thứ cần tìm là quét tuần tự, vòng lặp lồng nhau, sắp xếp đắt tiền, v.v. Hiểu được công cụ lập kế hoạch truy vấn là rất quan trọng để đảm bảo các truy vấn đang hoạt động theo cách tốt nhất có thể, có thể đọc tài liệu chính thức để biết thêm thông tin tại đây.
2.2. Các bảng liên quan có bị cồng kềnh không?
Nếu các truy vấn vẫn còn chậm mà người lập kế hoạch truy vấn chỉ ra bất kỳ điều gì rõ ràng, thì đã đến lúc kiểm tra tình trạng của các bảng có liên quan. Chúng có quá lớn không? Họ có bị đầy hơi không?
SELECT n_live_tup, n_dead_tup from pg_stat_user_tables where relname = ‘mytable’;
n_live_tup | n_dead_tup
------------+------------
15677 | 8275431
(1 row)
Ở đây, chúng ta thấy rằng số hàng chết nhiều hơn gấp nhiều lần so với hàng trực tiếp, có nghĩa là để tìm đúng hàng, công cụ phải sàng lọc dữ liệu thậm chí không liên quan để tìm dữ liệu thực. Chân không / chân không đầy trên bàn này sẽ tăng hiệu suất đáng kể.
Bước 3 - Kiểm tra Nhật ký
Nếu vấn đề vẫn không được tìm thấy, hãy kiểm tra nhật ký để tìm bất kỳ manh mối nào.
Thông báo FATAL / ERROR:
Tìm kiếm các thông báo có thể gây ra sự cố, chẳng hạn như bế tắc hoặc thời gian chờ đợi lâu để nhận được khóa.
Trạm kiểm soát
Hy vọng rằng log_checkpoints được đặt thành bật, sẽ ghi thông tin điểm kiểm tra vào nhật ký. Có hai loại trạm kiểm soát, hẹn giờ và yêu cầu (bắt buộc). Nếu các trạm kiểm soát đang bị ép buộc, thì các bộ đệm bẩn trong bộ nhớ phải được ghi vào đĩa trước khi xử lý thêm các truy vấn, điều này có thể tạo cho hệ thống cơ sở dữ liệu tổng thể cảm giác “chậm chạp”. Việc tăng checkpoint_searies hoặc max_wal_size (tùy thuộc vào phiên bản cơ sở dữ liệu) sẽ cung cấp cho người kiểm tra nhiều không gian hơn để làm việc, cũng như giúp người viết nền đỡ một phần công việc viết.
Bước 4 - Tình trạng của Hệ thống Máy chủ lưu trữ là gì?
Nếu không có manh mối nào trong chính cơ sở dữ liệu, có lẽ bản thân máy chủ đã quá tải hoặc đang gặp sự cố. Bất cứ điều gì từ chanel IO quá tải đến đĩa, bộ nhớ tràn để hoán đổi, hoặc thậm chí ổ đĩa bị lỗi, không có vấn đề nào trong số này rõ ràng với bất kỳ điều gì chúng ta đã xem xét trước đây. Giả sử cơ sở dữ liệu đang chạy trên hệ điều hành dựa trên * nix, đây là một số điều có thể giúp ích.
4.1. Tải hệ thống
Sử dụng "top", hãy xem mức trung bình tải cho máy chủ. Nếu số lượng đang đạt đến hoặc vượt quá số lõi trên hệ thống, thì đó có thể đơn giản là quá nhiều kết nối đồng thời tấn công cơ sở dữ liệu khiến nó phải thu thập thông tin để bắt kịp.
load average: 3.43, 5.25, 4.85
4.2. Bộ nhớ hệ thống và SWAP
Sử dụng 'miễn phí', hãy kiểm tra xem SWAP đã được sử dụng chưa. Bộ nhớ tràn sang SWAP trong môi trường cơ sở dữ liệu PostgreSQL là cực kỳ xấu cho hiệu suất và nhiều DBA thậm chí sẽ loại bỏ SWAP khỏi máy chủ cơ sở dữ liệu, vì lỗi 'hết bộ nhớ' thích hợp hơn là một hệ thống chậm chạp.
Nếu SWAP đang được sử dụng, khởi động lại hệ thống sẽ xóa nó và tăng tổng bộ nhớ hệ thống hoặc định cấu hình lại việc sử dụng bộ nhớ cho PostgreSQL (chẳng hạn như giảm shared_buffers hoặc work_mem).
[[email protected] ~]$ free -m
total used free shared buff/cache available
Mem: 7986 225 1297 12 6462 7473
Swap: 7987 2048 5939
4.3. Quyền truy cập đĩa
PostgreSQL cố gắng thực hiện rất nhiều công việc của nó trong bộ nhớ và trải rộng quá trình ghi vào đĩa để giảm thiểu tắc nghẽn, nhưng trên một hệ thống quá tải với việc ghi nhiều, có thể dễ dàng thấy các lần đọc và ghi nặng khiến toàn bộ hệ thống chậm lại khi bắt kịp. theo yêu cầu. Đĩa nhanh hơn, nhiều đĩa hơn và kênh IO là một số cách để tăng khối lượng công việc có thể được thực hiện.
Các công cụ như ‘iostat’ hoặc ‘iotop’ có thể giúp xác định xem có tắc nghẽn ổ đĩa hay không và nó có thể đến từ đâu.
4.4. Kiểm tra các Đăng nhập
Nếu vẫn không thành công hoặc thậm chí nếu không, bạn phải luôn kiểm tra nhật ký để xem hệ thống có đang báo cáo bất kỳ điều gì không ổn hay không. Chúng ta đã thảo luận về việc kiểm tra postgresql.logs, nhưng nhật ký hệ thống có thể cung cấp thông tin về các vấn đề như hỏng đĩa, hỏng bộ nhớ, sự cố mạng, v.v. Bất kỳ một trong những vấn đề này đều có thể khiến cơ sở dữ liệu hoạt động chậm và không thể đoán trước được, vì vậy hãy hiểu rõ sức khỏe hoàn hảo có thể giúp tìm ra những vấn đề này.
Tải xuống Báo cáo chính thức hôm nay Quản lý &Tự động hóa PostgreSQL với ClusterControlTìm hiểu về những điều bạn cần biết để triển khai, giám sát, quản lý và mở rộng PostgreSQLTải xuống Báo cáo chính thứcBước 5 - Vẫn có điều gì đó không hiệu quả?
Ngay cả những quản trị viên dày dạn kinh nghiệm nhất cũng sẽ gặp phải điều gì đó mới không có ý nghĩa. Đó là nơi cộng đồng PostgreSQL toàn cầu có thể tham gia để trợ giúp. Giống như bước # 0, thông tin cung cấp cho cộng đồng càng rõ ràng thì họ càng dễ dàng trợ giúp.
5.1. Danh sách gửi thư PostgreSQL
Vì PostgreSQL được phát triển và quản lý bởi cộng đồng mã nguồn mở, nên có hàng nghìn người nói chuyện qua danh sách gửi thư để thảo luận về vô số chủ đề bao gồm các tính năng, lỗi và các vấn đề về hiệu suất. Bạn có thể tìm thấy danh sách gửi thư tại đây, với pgsql-admin và pgsql-performance là những thứ quan trọng nhất để tìm kiếm trợ giúp về các vấn đề hiệu suất.
5.2. IRC
Freenode tổ chức một số kênh PostgreSQL với các nhà phát triển và quản trị viên trên toàn thế giới và không khó để tìm một người hữu ích để theo dõi các vấn đề có thể đến từ đâu. Bạn có thể tìm thêm thông tin trên trang PostgreSQL IRC.