Điểm:2

Làm cách nào để gỡ lỗi lỗi phân đoạn PostgreSQL?

lá cờ ng

Tôi có một phiên bản PostgreSQL 13 liên tục gặp sự cố:

LOG: quá trình máy chủ (PID 10722) đã bị chấm dứt bởi tín hiệu 11: Lỗi phân đoạn
CHI TIẾT: Quá trình đang chạy không thành công: CAM KẾT
LOG: chấm dứt mọi quy trình máy chủ đang hoạt động khác
CẢNH BÁO: kết thúc kết nối do sự cố của quy trình máy chủ khác
CHI TIẾT: Người quản lý bưu điện đã ra lệnh cho quy trình máy chủ này khôi phục giao dịch hiện tại và thoát, vì một quy trình máy chủ khác đã thoát bất thường và có thể bị hỏng bộ nhớ dùng chung.

tôi đã cập nhật /etc/postgresql/13/main/pg_ctl.conf để bao gồm các bãi chứa lõi

pg_ctl_options = '--core-files'

và khởi động lại postgresql dịch vụ. Bây giờ nó dường như cho phép kết xuất lõi:

$ cho f trong `pgrep postgres`; làm cat /proc/$f/limits | lõi grep; xong
Kích thước tệp lõi tối đa không giới hạn byte không giới hạn 

gdb backtrace cho đầu ra sau

$ gdb /usr/lib/postgresql/13/bin/postgres 13/main/core.postgres.12264

Chương trình kết thúc với tín hiệu SIGSEGV, Lỗi phân đoạn.
#0 slot_deform_heap_tuple (natts=5, offp=0x557cc2e60720, tuple=<đã tối ưu hóa ngoài>, slot=0x557cc2e606d8) tại ./build/../src/backend/executor/execTuples.c:930
930 ./build/../src/backend/executor/execTuples.c: Không có tệp hoặc thư mục như vậy.
(gdb) bt
#0 slot_deform_heap_tuple (natts=5, offp=0x557cc2e60720, tuple=<đã tối ưu hóa ngoài>, slot=0x557cc2e606d8) tại ./build/../src/backend/executor/execTuples.c:930
#1 tts_buffer_heap_getsomeattrs (slot=0x557cc2e606d8, natts=5) tại ./build/../src/backend/executor/execTuples.c:695
#2 0x0000557cc1d3998c trong slot_getsomeattrs_int (slot=slot@entry=0x557cc2e606d8, attnum=5) tại ./build/../src/backend/executor/execTuples.c:1912
#3 0x0000557cc1d28fba trong slot_getsomeattrs (attnum=<đã tối ưu hóa ngoài>, slot=0x557cc2e606d8) tại ./build/../src/include/executor/tuptable.h:344
#4 ExecInterpExpr (state=0x557cc2e620a8, econtext=0x557cc2ea1768, isnull=<đã tối ưu hóa>) tại ./build/../src/backend/executor/execExprInterp.c:482
#5 0x0000557cc1d5548d trong ExecEvalExprSwitchContext (isNull=0x7ffdd2599507, econtext=0x557cc2ea1768, state=0x557cc2e620a8) tại ./build/../src/include/executor/executor.h:322
#6 ExecQual (econtext=0x557cc2ea1768, state=0x557cc2e620a8) tại ./build/../src/include/executor/executor.h:391
#7 MJFillInner (nút=0x557cc2ea1558) tại ./build/../src/backend/executor/nodeMergejoin.c:494
#8 0x0000557cc1d55ce8 trong ExecMergeJoin (pstate=0x557cc2ea1558) tại ./build/../src/backend/executor/nodeMergejoin.c:1353
#9 0x0000557cc1d2cc83 trong ExecProcNode (nút=0x557cc2ea1558) tại ./build/../src/include/executor/executor.h:248
#10 ExecutePlan (execute_once=<không được tối ưu hóa>, dest=0x557cc2e1a630, direction=<không được tối ưu hóa>, numberTuples=0, sendTuples=<không được tối ưu hóa>, operation=CMD_SELECT, use_parallel_mode=<không được tối ưu hóa>, planstate=0x557cc2ea1558, 
    bất động sản=0x557cc2ea12f8) tại ./build/../src/backend/executor/execMain.c:1632
#11 standard_ExecutorRun (queryDesc=0x557cc2e1a5a0, direction=<đã tối ưu hóa ngoài>, đếm=0, exec_once=<đã tối ưu hóa ngoài>) tại ./build/../src/backend/executor/execMain.c:350
#12 0x00007f0ec05ae09d trong pgss_ExecutorRun (queryDesc=0x557cc2e1a5a0, direction=ForwardScanDirection, count=0, exec_once=<đã tối ưu hóa>) tại ./build/../contrib/pg_stat_statements/pg_stat_statements.c:1045
#13 0x0000557cc1cdbcd4 trong PersistHoldablePortal (portal=portal@entry=0x557cc2d44b78) tại ./build/../src/backend/commands/portalcmds.c:407
#14 0x0000557cc1ff95f9 trong HoldPortal (portal=portal@entry=0x557cc2d44b78) tại ./build/../src/backend/utils/mmgr/portalmem.c:642
#15 0x0000557cc1ff9e7d trong PreCommit_Portals (isPrepare=isPrepare@entry=false) tại ./build/../src/backend/utils/mmgr/portalmem.c:738
#16 0x0000557cc1c001c4 trong CommTransaction () tại ./build/../src/backend/access/transam/xact.c:2087
#17 0x0000557cc1c015d5 trongCommitTransactionCommand() tại ./build/../src/backend/access/transam/xact.c:3085
#18 0x0000557cc1ea211d trong finish_xact_command () tại ./build/../src/backend/tcop/postgres.c:2662
#19 0x0000557cc1ea4703 trong exec_simple_query (query_string=0x557cc2c9cd28 "CAM KẾT") tại ./build/../src/backend/tcop/postgres.c:1264
#20 0x0000557cc1ea6143 trong PostgresMain (argc=<không được tối ưu hóa>, argv=argv@entry=0x557cc2cf6c68, dbname=<không được tối ưu hóa>, tên người dùng=<không được tối ưu hóa>) tại ./build/../src/backend/tcop/postgres .c:4339
#21 0x0000557cc1e25bcd trong BackendRun (cổng=0x557cc2ce94d0, cổng=0x557cc2ce94d0) tại ./build/../src/backend/postmaster/postmaster.c:4526
#22 Khởi động phụ trợ (cổng=0x557cc2ce94d0) tại ./build/../src/backend/postmaster/postmaster.c:4210
#23 Vòng lặp máy chủ () tại ./build/../src/backend/postmaster/postmaster.c:1739
#24 0x0000557cc1e26b41 trong PostmasterMain (argc=5, argv=<đã tối ưu hóa>) tại ./build/../src/backend/postmaster/postmaster.c:1412
#25 0x0000557cc1b70f4f trong chính (argc=5, argv=0x557cc2c96c30) tại ./build/../src/backend/main/main.c:210

Thêm log_statement = 'tất cả' đến /etc/postgresql/13/main/postgresql.conf không thực sự giúp đỡ, như trưởng bưu điện chấm dứt tất cả các quy trình ngay lập tức và truy vấn không được ghi vào nhật ký.

đây là bước đi đầu ra sau khi chạy LÀM

[pid 20006] pwrite64(29, "CAM KẾT", 6, 15936) = 6
[pid 20006] pwrite64(29, "\0", 1, 15942) = 1
[pid 20006] đóng(29) = 0
[pid 20006] --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x10} ---
[pid 20006] +++ bị giết bởi SIGSEGV (lõi bị đổ) +++
<... chọn đã tiếp tục> ) = ? ERESTARTNOHAND (Sẽ được khởi động lại nếu không có trình xử lý)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_DUMPED, si_pid=20006, si_uid=108, si_status=SIGSEGV, si_utime=0, si_stime=0} ---
wait4(-1, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGSEGV && WCOREDUMP(s)}], WNOHANG, NULL) = 20006
write(2, "2021-09-08 13:38:51.853 UTC [299"..., 198) = 198
write(2, "2021-09-08 13:38:51.853 UTC [299"..., 88) = 88
giết (19324, SIGQUIT) = 0
giết (-19324, SIGQUIT) = 0
giết (19331, SIGQUIT) = 0
giết (-19331, SIGQUIT) = 0
giết (19320, SIGQUIT) = 0
giết (-19320, SIGQUIT) = 0
giết (19319, SIGQUIT) = 0
giết (-19319, SIGQUIT) = 0
giết (19321, SIGQUIT) = 0
giết (-19321, SIGQUIT) = 0
giết (19322, SIGQUIT) = 0
giết (-19322, SIGQUIT) = 0
giết (19323, SIGQUIT) = 0
giết (-19323, SIGQUIT) = 0
wait4(-1, 0x7ffe90814374, WNOHANG, NULL) = 0
rt_sigreturn({mask=[]}) = -1 EINTR (Cuộc gọi hệ thống bị gián đoạn)
rt_sigprocmask(SIG_SETMASK, ~[ILL TRAP ABRT BUS FPE SEGV CONT SYS RTMIN RT_1], NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
select(7, [5 6], NULL, NULL, {tv_sec=5, tv_usec=0}) = ? ERESTARTNOHAND (Sẽ được khởi động lại nếu không có trình xử lý)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=19320, si_uid=108, si_status=2, si_utime=14, si_stime=3} ---

Có cách nào để theo dõi lại truy vấn SQL chính xác đã được thực thi không?

Michael Hampton avatar
lá cờ cz
Nếu nó tiếp tục xảy ra ở cùng một vị trí, rất có thể bạn đã gặp phải một số loại lỗi và nên gửi báo cáo lỗi.
lá cờ cn
Ngoài những điều trên, bạn đã xem nhật ký chưa?
lá cờ ng
@MichaelHampton Vâng, tôi sẽ cố gắng làm điều đó, trong thời gian chờ đợi, tôi cần tìm một số cách giải quyết khác để tránh làm hỏng toàn bộ postgres
lá cờ ng
@NasirRiley Không có gì thú vị trong nhật ký ngoại trừ các dòng đã được hiển thị.
Điểm:2
lá cờ ng

Trước tiên hãy cài đặt các biểu tượng gỡ lỗi cho bản phân phối của bạn, cho các bản phân phối Debian:

cài đặt apt gdb postgresql-13-dbgsym

Chuyển đến một khung có chứa một số truy vấnDesc biến, ví dụ 12:

(gdb) khung 12
#12 0x00007f0ec05ae09d trong pgss_ExecutorRun (queryDesc=0x557cc302b7d0, direction=ForwardScanDirection, count=0, exec_once=<đã tối ưu hóa>) tại ./build/../contrib/pg_stat_statements/pg_stat_statements.c:1045
1045 trong ./build/../contrib/pg_stat_statements/pg_stat_statements.c

in biến đó:

(gdb) p queryDesc
$1 = (QueryDesc *) 0x557cc302b7d0

bây giờ sao chép dòng trên sau dấu bằng và hủy đăng ký nó bằng cách sử dụng *

(gdb) p *(QueryDesc *) 0x557cc302b7d0
$6 = {hoạt động = CMD_SELECT, planstmt = 0x557cc300e218, 
  sourceText = 0x557cc302b370 "\n", ' ' <lặp lại 12 lần>, "KHAI BÁO \"categoryPagePhotoUrl_image_urls\" CON TRỎ BẰNG GIỮ CHO\n", ' ' <lặp lại 12 lần>, "CHỌN di.itemId, image_number, tên tệp TỪ ( SELECT *\n", ' ' <repeats 12 times>, "FROM downl"..., snapshot = 0x557cc2e9b188, crosscheck_snapshot = 0x0, dest = 0x557cc302b860, params = 0x0, queryEnv = 0x0, instrument_options = 0, tupDesc ​​= 0x557cc2f7bff8, 
  bất động sản = 0x557cc2cf8d08, planstate = 0x557cc2cf8f68, already_executed = true, tổng thời gian = 0x0}

Nó không cung cấp cho bạn toàn bộ truy vấn nhưng ít nhất là một ý tưởng về truy vấn được thực hiện trên bảng nào.

Dựa vào gdb đầu ra Tôi đã quản lý để cách ly các máy khách đang thực hiện truy vấn như vậy.

Tôi đã thử chạy CHÂN KHÔNG ĐẦY ĐỦ trên bảng bị ảnh hưởng, xây dựng lại bảng và chỉ mục, chuyển sang bản sao, sao chép toàn bộ cơ sở dữ liệu bằng cách sử dụng pg_dump. Tuy nhiên, vấn đề vẫn tồn tại trên các bản sao cơ sở dữ liệu.

Cuối cùng tôi đã quản lý để cô lập một mã SQL tối thiểu để sao chép vấn đề.

$ pg_createcluster 13 chính
$ đã tạob testdb
$ psql -d testdb -f postgresql-segfault.sql
TẠO LƯỢC ĐỒ
TẠO BẢNG
SAO CHÉP 1
THAY ĐỔI BẢNG
BẮT ĐẦU
TẠO BẢNG
KHAI BÁO CON TRỎ
 itemid  
---------
 1190300
(1 hàng)

psql:postgresql-segfault:34: máy chủ đóng kết nối bất ngờ
        Điều này có thể có nghĩa là máy chủ bị chấm dứt bất thường
        trước hoặc trong khi xử lý yêu cầu.
psql:postgresql-segfault:34: fatal: mất kết nối với máy chủ

Với một mã để sao chép điều này là đủ để báo lỗi đến lỗi pssql danh sách gửi thư (cũng có một biểu mẫu web). Hóa ra là một lỗi khi thực hiện lại một kế hoạch đã hoàn thành trên một con trỏ không ổn định đã được đưa vào PostgreSQL 13.4, 12.8 (và có thể là các phiên bản khác).

Miles avatar
lá cờ kr
Bạn đã cứu tôi rất nhiều rắc rối khi gỡ lỗi cái này, cảm ơn bạn.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.