Làm cách nào để tìm hiểu khoảng cách dọc theo truy vấn PostgreSQL của tôi?


35

Tôi có một ý tưởng khá hay về việc có bao nhiêu hàng CHỌN ... truy vấn INTO của tôi sẽ thực sự xử lý (ví dụ: tôi biết có bao nhiêu hàng hóa sẽ thành hiện thực).

Tôi hiểu Postgres sẽ cho tôi biết tính đầy đủ về tỷ lệ phần trăm, có một cách (chôn sâu trong nhật ký, bảng hệ thống hoặc cách khác) để tôi có thể tìm hiểu có bao nhiêu hàng đã được bơm vào bảng đích hoặc đã được truy vấn CHỌN đọc ?

Câu trả lời:


33

Như Daniel Vérité đã đề cập, dường như không có một giải pháp chung chung nào. Khi tải dữ liệu vào một bảng từ một tệp, kỹ thuật sau đây có thể được sử dụng để có được tiến trình tải.

Thanh tiến trình điều khiển lệnh COPY

Tạo một bảng trống.

CREATE TABLE mytest (n int);

Tạo một tệp dữ liệu với 10 triệu dòng để tải vào bảng.

$ seq 10000000 > /tmp/data.txt

Tải dữ liệu từ tệp vào bảng và hiển thị thanh tiến trình.

$ pv /tmp/data.txt | psql -c "COPY mytest FROM STDIN;"

Bản giới thiệu

nhập mô tả hình ảnh ở đây

Làm thế nào điều này hoạt động

Bằng cách sử dụng các lệnh sao chép tùy chọn STDIN, chúng ta có thể cung cấp dữ liệu cho hoạt động sao chép từ một quy trình khác. Lệnh pv sẽ xuất ra một tệp và theo dõi tiến trình hiển thị thanh tiến trình, ETA, tổng thời gian đã trôi qua và tốc độ truyền dữ liệu.

COPY thanh tiến trình đồ họa

Sử dụng cùng một kỹ thuật chung, chúng tôi có thể hiển thị thanh tiến trình trong ứng dụng đồ họa hoặc ứng dụng dựa trên web. Ví dụ, sử dụng python mô-đun psycopg2 cho phép bạn gọi lệnh sao chép với một đối tượng tệp bạn chọn. Sau đó, bạn có thể theo dõi số lượng đối tượng tệp của mình đã được đọc và hiển thị thanh tiến trình.


2
Trước đây tôi không bắt gặp pvlệnh này và nó không được cài đặt trên máy chủ Debian của tôi, nhưng nó nằm trong repo. Mô tả cho biết "pv (Trình xem ống) có thể được chèn vào bất kỳ đường ống thông thường nào giữa hai quy trình để đưa ra một dấu hiệu trực quan về tốc độ truyền dữ liệu". Một lệnh rất hữu ích!
Richard Turner

27

Dường như không có một phương pháp chung, được hỗ trợ, nhưng có một số thủ thuật có thể được sử dụng trong bối cảnh giới hạn để đánh giá tiến trình của một truy vấn riêng lẻ. Dưới đây là một số trong số họ.

Trình tự

Khi truy vấn CHỌN hoặc CẬP NHẬT bao gồm bất kỳ nextval(sequence_name)hoặc INSERT có cột đích với nextvalmặc định, giá trị chuỗi hiện tại có thể được truy vấn nhiều lần trong một phiên khác với SELECT sequence_name.last_value. Nó hoạt động vì các chuỗi không bị ràng buộc bởi các giao dịch. Khi kế hoạch thực hiện sao cho chuỗi được tăng tuyến tính trong suốt truy vấn, nó có thể được sử dụng như một chỉ báo tiến trình.

pgstattuple

Các pgstattuple mô-đun contrib cung cấp chức năng mà có thể peek trực tiếp tại các trang dữ liệu. Có vẻ như khi các bộ dữ liệu được chèn vào một bảng trống và chưa được cam kết, chúng được tính trong dead_tuple_counttrường từ pgstattuplehàm.

Bản demo với 9.1: tạo một bảng trống

CREATE TABLE tt AS (n numeric);

Hãy chèn 10 triệu hàng vào đó:

INSERT INTO tt SELECT * FROM random() from generate_series(1,10000000);

Trong một phiên khác, hãy kiểm tra pgstattuple mỗi giây trong khi chèn:

$ while true;
   do psql -Atc "select dead_tuple_count from pgstattuple('tt')";
   sleep 1;
  done

Các kết quả:

0
69005
520035
1013430
1492210
1990415
2224625
2772040
3314460
3928660
4317345
4743770
5379430
6080950
6522915
7190395
7953705
8747725
9242045
0

Nó rơi trở về 0 khi chèn xong (tất cả các bộ dữ liệu trở nên hiển thị và sống).

Thủ thuật này cũng có thể được sử dụng khi bảng không được tạo mới, nhưng ban đầu dead_tuple_countcó thể có giá trị khác không và nó cũng có thể thay đổi đồng thời nếu hoạt động ghi khác như autovacuum đang diễn ra (có lẽ là không? đồng thời để mong đợi với autovacuum).

Tuy nhiên, nó không thể được sử dụng nếu bảng được tạo bởi chính câu lệnh ( CREATE TABLE ... AS SELECThoặc SELECT * INTO newtable), do việc tạo được giao dịch. Cách giải quyết sẽ là tạo bảng không có hàng (thêm LIMIT 0) và điền vào bảng trong giao dịch tiếp theo.

Lưu ý rằng pgstattuplekhông miễn phí: nó quét toàn bộ bảng trong mỗi cuộc gọi. Ngoài ra, nó giới hạn cho siêu nhân.

Bộ đếm tùy chỉnh

Trong blog của Pavel Stehule, anh ta cung cấp một hàm truy cập được triển khai trong C làm tăng các thông báo với số lần thực hiện được chỉ định. Bạn phải kết hợp chức năng với truy vấn bằng cách nào đó để cho người thi hành gọi nó. Các thông báo được gửi trong quá trình truy vấn và chúng không cần một phiên riêng biệt, chỉ có một máy khách SQL hiển thị chúng ( psqllà ứng cử viên rõ ràng).

Ví dụ về INSERT INTO được làm lại để đưa ra các thông báo:

/* transformation */
INSERT INTO destination_table
   SELECT (r).*
  FROM (SELECT counter(to_destination_table(_source), 1000, true) r
           FROM source _source) x

Câu hỏi liên quan về stackoverflow, cho các chức năng:
Cách báo cáo tiến trình từ chức năng PostgreQuery chạy dài đến máy khách

Lựa chọn tương lai?

Kể từ tháng 5 năm 2017, có một bản vá đầy hứa hẹn được gửi tới cộng đồng nhà phát triển: [PATCH v2] Lệnh tiến trình để theo dõi tiến trình của các truy vấn SQL chạy dài

mà có thể kết thúc như một giải pháp chung trong PostgreSQL 11 trở lên. Người dùng cảm thấy muốn tham gia vào các tính năng đang thực hiện có thể áp dụng phiên bản mới nhất của bản vá và thử PROGRESSlệnh được đề xuất .


3

Cho đến khi chức năng báo cáo tiến độ sẽ không được mở rộng, như @AmirAliAkbari đã đề cập trong câu trả lời của anh ấy, đây là một cách giải quyết ở cấp độ hệ điều hành.

Điều này chỉ hoạt động trên Linux, nhưng có lẽ có các giải pháp tương tự dễ dàng cho mọi hệ điều hành.

Ưu điểm lớn nhất và cũng bất lợi của PostgreSQL, rằng tất cả các phần phụ trợ của nó là quá trình đơn luồng đơn giản, sử dụng lseek(), read()write()để thao tác các file bảng của họ, trong khi họ đang tương tác trên mem chia sẻ và ổ khóa.

Kết quả này, tất cả các quy trình phụ trợ của nó luôn hoạt động trên một truy vấn duy nhất, có thể dễ dàng tìm thấy và dễ dàng straced.

Đầu tiên, bạn có thể thấy PID phụ trợ từ SELECT * FROM pg_stat_activity;:

29805270 | dbname  | 20019 |    16384 | username  |                  |             |                 |          -1 | 2018-09-19 21:31:57.68234+02  | 2018-09-19 21:31:59.435376+02 | 2018-09-\
20 00:34:30.892382+02 | 2018-09-20 00:34:30.892386+02 | Client          | ClientRead | active              |       92778 |        92778 |  INSERT INTO ...something...

Cột thứ ba là pid. Trong PostgreSQL, nó giống như quy trình Linux của phần phụ trợ.

Tiếp theo, bạn có thể strace nó, ví dụ bằng một strace -p 20019 -s 8192: ( -s 8192rất hữu ích vì postgresql hoạt động với các khối dài 8192 byte).

sendto(10, "C\0\0\0\17INSERT 0 1\0Z\0\0\0\5T", 22, 0, NULL, 0) = 22
recvfrom(10, "Q\0\0\1\267 INSERT <removed by @peterh>", 8192, 0, NULL, NULL) = 440
sendto(10, "C\0\0\0\17INSERT 0 1\0Z\0\0\0\5T", 22, 0, NULL, 0) = 22
lseek(298, 343634345)...
read(298, "<block data which was read in>"....
write(298, "<block data which was written out>"...

Ý nghĩa:

  • sendtoxảy ra nếu phụ trợ trả lời một cái gì đó cho khách hàng. Trong ví dụ này, nó trả lời kết quả của một INSERTtruy vấn.
  • recvfromxảy ra nếu phụ trợ nhận được một cái gì đó từ khách hàng. Nó thường là một truy vấn mới, trong ví dụ, một truy vấn khác INSERT.
  • lseek xảy ra nếu vị trí chuyển đổi phụ trợ trong tệp bảng.
  • read xảy ra nếu phụ trợ đọc một khối trong tệp bảng.
  • write xảy ra nếu phụ trợ ghi một khối ra vào một tệp bảng.

Trong trường hợp readwrite, bạn cũng có thể thấy nội dung của khối đó trong bảng. Nó có thể giúp rất nhiều để hiểu, nó đang làm gì và nó ở đâu.

Trong trường hợp recvfrom, bạn có thể xem truy vấn thực tế những gì phụ trợ đã có.


2

Như đã nói trong các câu trả lời khác, hiện tại không có cách trực tiếp để báo cáo tiến độ nói chung.

PostgreSQL có khả năng báo cáo tiến trình của một số lệnh nhất định trong quá trình thực thi lệnh. Hiện tại, lệnh duy nhất hỗ trợ báo cáo tiến độ là VACUUM. Điều này có thể được mở rộng trong tương lai.

Tuy nhiên, bắt đầu từ 9.6, bất cứ khi nào VACUUMđang chạy, pg_stat_progress_vacuumchế độ xem sẽ chứa một hàng cho mỗi phụ trợ (bao gồm các quy trình nhân viên tự động) hiện đang hút bụi. Thông tin chi tiết về pg_stat_progress_vacuumcó thể được tìm thấy trong tài liệu: 27.4 Báo cáo tiến độ .

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.