掛起的PostgreSQL查詢?nèi)∠椒?/h1>
更新時間:2026年05月07日 08:49:28 作者:北重樓01
本文介紹了在PostgreSQL中取消卡住查詢的方法,當常規(guī)取消方法無效時,可通過gdb調(diào)試器直接向卡住的后臺進程發(fā)送ProcessInterrupts()信號,使其安全退出,此操作需謹慎評估風險,需要的朋友可以參考下
有時,PostgreSQL 中的某個查詢會運行異常緩慢,甚至陷入“掛起”狀態(tài)。通常情況下,我們可以輕松地將其中斷(取消)。但有時這會變成一個棘手的問題:查詢無法被取消。本文將探討可能導致這一問題的原因,并介紹一個解決方案的技巧(該操作風險較高,請謹慎評估!)
如何取消正在運行的查詢
PostgreSQL 協(xié)議中規(guī)定了中斷正在執(zhí)行的語句的方法:建立一個新的連接,并發(fā)送一個包含秘鑰的 CancelRequest 消息。該秘鑰在原始連接建立時由服務器發(fā)送。沒有這個秘鑰,任何人都可以取消您的查詢,這將帶來嚴重的安全隱患。
C 語言庫 libpq 提供了 PQgetCancel() 和 PQcancel() 函數(shù)來取消查詢,其他數(shù)據(jù)庫 API 通常也有類似的功能。在交互式 psql 會話中,您只需按下 Ctrl+C 即可發(fā)送取消請求,圖形化客戶端也通常會提供一個用于此目的的按鈕。
此外,也可以通過調(diào)用數(shù)據(jù)庫函數(shù) pg_cancel_backend() 來取消他人的查詢。另一個選項是 pg_terminate_backend(),其作用更進一步——直接終止他人的數(shù)據(jù)庫會話。要使用這些函數(shù),您必須是超級用戶,或者是默認角色 pg_signal_backend 的成員(原因?qū)⒃谙乱还?jié)解釋),或者您必須使用與目標會話相同的數(shù)據(jù)庫用戶登錄(即您有權(quán)取消自己的語句)。
服務器如何處理取消請求
PostgreSQL 中的進程間通信高度依賴信號機制。
當 postmaster 進程收到 CancelRequest 消息時,它會向?qū)獢?shù)據(jù)庫會話的后臺進程發(fā)送 SIGINT 信號。pg_cancel_backend() 函數(shù)執(zhí)行的也是此操作。而 pg_terminate_backend() 發(fā)送的是 SIGTERM 信號。
每個 PostgreSQL 進程都設(shè)有一個信號處理器,用于處理接收到的信號。該處理器不會立即中斷后臺進程,而是為進程設(shè)置全局標志位:SIGINT 設(shè)置 QueryCancelPending,SIGTERM 設(shè)置 ProcDiePending。后臺進程有責任在合適的時機檢查這些標志位并做出響應。這種設(shè)計確保了進程不會在不安全的狀態(tài)(例如,正在修改共享內(nèi)存時)被意外中斷。
在 PostgreSQL 代碼中的安全位置,遍布著 CHECK_FOR_INTERRUPTS() 宏(該宏會調(diào)用 ProcessInterrupts() 函數(shù))。該函數(shù)會根據(jù)設(shè)置的標志,拋出錯誤以取消當前語句,或終止后臺進程。
取消查詢可能失敗的原因
查詢?nèi)∠】赡苡幸韵聨追N原因:
- 執(zhí)行卡在了一個不包含
CHECK_FOR_INTERRUPTS() 的循環(huán)中:這屬于 PostgreSQL 自身的缺陷,修復方法是增加對該宏的調(diào)用。 - 執(zhí)行卡在了一個通過 SQL 語句調(diào)用的第三方 C 函數(shù)里:請將此問題報告給該函數(shù)的作者。
- 執(zhí)行卡在了一個無法中斷的系統(tǒng)調(diào)用中:這通常表明操作系統(tǒng)或硬件層面存在問題。需要注意的是,當進程處于內(nèi)核空間時,信號的傳遞會被延遲。
謹慎使用kill -9
直接使用普通的 kill 命令處理 PostgreSQL 后臺進程是可行的。這會發(fā)送 SIGTERM 信號,效果等同于為后臺進程調(diào)用 pg_terminate_backend()。如果此操作無效,有人可能會嘗試使用 kill -9,它會發(fā)送 SIGKILL 信號。該信號無法被捕獲,會立即終止進程。問題在于,postmaster 會檢測其子進程是否正常退出。一旦檢測到異常終止,它會殺死所有其他 PostgreSQL 進程并執(zhí)行崩潰恢復,這將導致整個數(shù)據(jù)庫短暫停服,持續(xù)時間從數(shù)秒到數(shù)分鐘不等。
請注意,對后臺進程使用 kill -9 僅會造成短暫停機,但對 postmaster 進程本身使用 kill -9 則會產(chǎn)生更嚴重的后果,應堅決避免。這會打開一個時間窗口,在此期間新的 postmaster 可能被啟動,而舊 postmaster 的某些子進程仍然存活,極有可能導致磁盤上的數(shù)據(jù)損壞。永遠不要使用 kill -9 殺死 postmaster 進程!
有時,即使是 kill -9 也無法殺死一個 PostgreSQL 后臺進程。這意味著該進程卡在了一個不可中斷的系統(tǒng)調(diào)用中,例如,在對已不可用的網(wǎng)絡附加存儲執(zhí)行 I/O 操作。如果這種狀況持續(xù)存在,唯一的方法就是重啟操作系統(tǒng)。
高級技巧:在不重啟服務器的情況下取消卡住的查詢
有時,您可以按照以下步驟操作,以避免數(shù)據(jù)庫崩潰恢復和停服。以下示例基于 Linux 環(huán)境下的 GNU 調(diào)試器 gdb;其他環(huán)境請自行適配。
1. 創(chuàng)建一個會掛起的函數(shù)示例
我們編寫一個簡單的 C 函數(shù)(源文件 loop.c):
#include "postgres.h"
#include "fmgr.h"
#include <unistd.h>
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(loop);
Datum
loop(PG_FUNCTION_ARGS)
{
/* 一個無限循環(huán) */
while(1)
sleep(2);
}
按如下方式構(gòu)建共享庫(請根據(jù)實際環(huán)境調(diào)整包含路徑):
gcc -I /usr/pgsql-14/include/server -fPIC -shared -o loop.so loop.c
將生成的 loop.so 文件復制到 PostgreSQL 的共享庫目錄(可通過 pg_config --libdir 獲?。?。
2. 定義并調(diào)用函數(shù)
以超級用戶身份在 SQL 中定義函數(shù):
CREATE FUNCTION loop() RETURNS void
LANGUAGE c AS 'loop';
然后,以普通用戶身份調(diào)用該函數(shù):
SELECT loop();
執(zhí)行將陷入掛起。您可以嘗試取消查詢,但它會持續(xù)運行。
3. 定位掛起的后臺進程并發(fā)送終止信號
使用相同的數(shù)據(jù)庫用戶打開另一個數(shù)據(jù)庫連接,通過以下查詢找出該會話的后臺進程 ID:
SELECT pid, query
FROM pg_stat_activity
WHERE query LIKE '%loop%';
獲取進程 ID 后,向其發(fā)送 SIGTERM 信號:
SELECT pg_terminate_backend(12345);
(請將 12345 替換為實際進程 ID)。該函數(shù)返回 TRUE,表示信號已發(fā)送,但查詢?nèi)栽趫?zhí)行。
4. 用調(diào)試器附加到進程
確保已安裝 gdb 調(diào)試器。為獲得可讀的堆棧跟蹤,建議安裝 PostgreSQL 服務器的調(diào)試符號(但這并非本技巧的必需步驟)。以 PostgreSQL 用戶(通常名為 postgres)身份登錄到數(shù)據(jù)庫服務器,按如下方式調(diào)用 gdb(請使用正確的 postgres 可執(zhí)行文件路徑和進程 ID):
gdb /usr/pgsql-14/bin/postgres 12345
在 (gdb) 提示符下,輸入 bt 命令生成堆棧跟蹤,輸出類似如下:
#0 __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0,
req=req@entry=0x7ffdaf61cde0, rem=rem@entry=0x7ffdaf61cde0)
at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:71
#1 0x00007f113d864897 in __GI___nanosleep (req=req@entry=0x7ffdaf61cde0,
rem=rem@entry=0x7ffdaf61cde0) at ../sysdeps/unix/sysv/linux/nanosleep.c:25
#2 0x00007f113d8647ce in __sleep (seconds=0) at ../sysdeps/posix/sleep.c:55
#3 0x00007f113e623139 in loop () from /usr/pgsql-14/lib/loop.so
#4 0x00000000006d71fb in ExecInterpExpr (state=0x13837b8, econtext=0x13834e0,
isnull=<optimized out>) at executor/execExprInterp.c:1260
#5 0x000000000070e391 in ExecEvalExprSwitchContext (isNull=0x7ffdaf61ced7,
econtext=0x13834e0, state=0x13837b8)
at executor/../../../src/include/executor/executor.h:339
#6 ExecProject (projInfo=0x13837b0)
at executor/../../../src/include/executor/executor.h:373
#7 ExecResult (pstate=<optimized out>) at executor/nodeResult.c:136
#8 0x00000000006da8b2 in ExecProcNode (node=0x13833d0)
at executor/../../../src/include/executor/executor.h:257
#9 ExecutePlan (execute_once=<optimized out>, dest=0x137f4c0, direction=<optimized out>,
numberTuples=0, sendTuples=<optimized out>, operation=CMD_SELECT,
use_parallel_mode=<optimized out>, planstate=0x13833d0, estate=0x13831a8)
at executor/execMain.c:1551
[...]
堆棧跟蹤有助于定位問題根源。如果您需要向 PostgreSQL 報告此問題,請附上此信息。
如果您不想繼續(xù)下一步,可以在 (gdb) 提示符下輸入 detach 分離調(diào)試器,讓進程繼續(xù)運行。
5. 通過讓卡住的后臺進程干凈退出以取消執(zhí)行
觀察上面的堆棧跟蹤,可以看到當前執(zhí)行點位于一個自定義函數(shù)中(loop () from /usr/pgsql-14/lib/loop.so),而不是 PostgreSQL 內(nèi)部代碼。這種情況下,讓進程退出是相對安全的。如果執(zhí)行點位于 PostgreSQL 服務器內(nèi)部,則可能存在一定的風險(例如,進程可能正持有自旋鎖或處于修改共享狀態(tài))。若您熟悉 PostgreSQL 源碼,可以通過調(diào)用棧評估風險。
現(xiàn)在,如果決定繼續(xù),請在 (gdb) 提示符下調(diào)用 ProcessInterrupts() 函數(shù)。由于此前已設(shè)置了 ProcDiePending 標志,該調(diào)用將導致進程退出:
(gdb) print ProcessInterrupts()
[Inferior 1 (process 12345) exited with code 01]
The program being debugged exited while in a function called from GDB.
Evaluation of the expression containing the function
(ProcessInterrupts) will be abandoned.
(gdb) quit
6. 改進函數(shù)以支持取消
為了避免此類問題,函數(shù)代碼應修改為定期檢查中斷標志:
#include "postgres.h"
#include "fmgr.h"
#include "miscadmin.h"
#include <unistd.h>
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(loop);
Datum
loop(PG_FUNCTION_ARGS)
{
/* 一個無限循環(huán),但允許中斷 */
while(1)
{
CHECK_FOR_INTERRUPTS();
sleep(2);
}
}
修改后,函數(shù)將每兩秒檢查一次中斷標志,從而能夠被安全地取消。
結(jié)論
取消 PostgreSQL 查詢的本質(zhì)是向后臺進程發(fā)送 SIGINT 信號。如果 SIGINT 和 SIGTERM 均無法中斷進程,您可以使用 gdb 附加到該進程,并直接調(diào)用 ProcessInterrupts() 函數(shù),使其干凈退出。
以上就是掛起的PostgreSQL查詢?nèi)∠椒ǖ脑敿殐?nèi)容,更多關(guān)于取消掛起PostgreSQL查詢的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
-
PostgreSQL創(chuàng)建觸發(fā)器的實現(xiàn)示例
PostgreSQL的觸發(fā)器Trigger是一類特殊的數(shù)據(jù)庫對象,本文主要介紹了PostgreSQL創(chuàng)建觸發(fā)器的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧 2025-06-06
-
Windows版?PostgreSQL?利用?pg_upgrade?進行大版升級操作方法
最近?PostgreSQL?15?版本正式發(fā)布了,新版本的各種特性和好處本文就不展開介紹了,主要介紹一下?Windows?環(huán)境下?PostgreSQL?大版本升級的方法,我們現(xiàn)在的幾個數(shù)據(jù)庫都是運行在?Windows服務器的?PostgreSQL?14,需要的朋友可以參考下 2022-10-10
-
使用PostgreSQL創(chuàng)建高級搜索引擎的代碼示例
本文我們將探索PostgreSQL中的全文搜索功能,并研究我們能夠復制多少典型搜索引擎功能,文中有詳細的代碼示例供大家參考,需要的朋友可以參考下 2023-07-07
-
PostgreSQL高級特性與性能優(yōu)化的實戰(zhàn)指南
本文將深入探討PostgreSQL的高級特性與性能優(yōu)化技術(shù),結(jié)合Python實踐,幫助開發(fā)者充分發(fā)揮PostgreSQL的潛力,文中的示例代碼講解詳細,需要的小伙伴可以了解下 2026-02-02
-
PostgreSQL實現(xiàn)一個通用標簽系統(tǒng)
這篇文章主要給大家介紹了關(guān)于利用PostgreSQL實現(xiàn)一個通用標簽系統(tǒng)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧 2019-01-01
有時,PostgreSQL 中的某個查詢會運行異常緩慢,甚至陷入“掛起”狀態(tài)。通常情況下,我們可以輕松地將其中斷(取消)。但有時這會變成一個棘手的問題:查詢無法被取消。本文將探討可能導致這一問題的原因,并介紹一個解決方案的技巧(該操作風險較高,請謹慎評估!)
如何取消正在運行的查詢
PostgreSQL 協(xié)議中規(guī)定了中斷正在執(zhí)行的語句的方法:建立一個新的連接,并發(fā)送一個包含秘鑰的 CancelRequest 消息。該秘鑰在原始連接建立時由服務器發(fā)送。沒有這個秘鑰,任何人都可以取消您的查詢,這將帶來嚴重的安全隱患。
C 語言庫 libpq 提供了 PQgetCancel() 和 PQcancel() 函數(shù)來取消查詢,其他數(shù)據(jù)庫 API 通常也有類似的功能。在交互式 psql 會話中,您只需按下 Ctrl+C 即可發(fā)送取消請求,圖形化客戶端也通常會提供一個用于此目的的按鈕。
此外,也可以通過調(diào)用數(shù)據(jù)庫函數(shù) pg_cancel_backend() 來取消他人的查詢。另一個選項是 pg_terminate_backend(),其作用更進一步——直接終止他人的數(shù)據(jù)庫會話。要使用這些函數(shù),您必須是超級用戶,或者是默認角色 pg_signal_backend 的成員(原因?qū)⒃谙乱还?jié)解釋),或者您必須使用與目標會話相同的數(shù)據(jù)庫用戶登錄(即您有權(quán)取消自己的語句)。
服務器如何處理取消請求
PostgreSQL 中的進程間通信高度依賴信號機制。
當 postmaster 進程收到 CancelRequest 消息時,它會向?qū)獢?shù)據(jù)庫會話的后臺進程發(fā)送 SIGINT 信號。pg_cancel_backend() 函數(shù)執(zhí)行的也是此操作。而 pg_terminate_backend() 發(fā)送的是 SIGTERM 信號。
每個 PostgreSQL 進程都設(shè)有一個信號處理器,用于處理接收到的信號。該處理器不會立即中斷后臺進程,而是為進程設(shè)置全局標志位:SIGINT 設(shè)置 QueryCancelPending,SIGTERM 設(shè)置 ProcDiePending。后臺進程有責任在合適的時機檢查這些標志位并做出響應。這種設(shè)計確保了進程不會在不安全的狀態(tài)(例如,正在修改共享內(nèi)存時)被意外中斷。
在 PostgreSQL 代碼中的安全位置,遍布著 CHECK_FOR_INTERRUPTS() 宏(該宏會調(diào)用 ProcessInterrupts() 函數(shù))。該函數(shù)會根據(jù)設(shè)置的標志,拋出錯誤以取消當前語句,或終止后臺進程。
取消查詢可能失敗的原因
查詢?nèi)∠】赡苡幸韵聨追N原因:
- 執(zhí)行卡在了一個不包含
CHECK_FOR_INTERRUPTS()的循環(huán)中:這屬于 PostgreSQL 自身的缺陷,修復方法是增加對該宏的調(diào)用。 - 執(zhí)行卡在了一個通過 SQL 語句調(diào)用的第三方 C 函數(shù)里:請將此問題報告給該函數(shù)的作者。
- 執(zhí)行卡在了一個無法中斷的系統(tǒng)調(diào)用中:這通常表明操作系統(tǒng)或硬件層面存在問題。需要注意的是,當進程處于內(nèi)核空間時,信號的傳遞會被延遲。
謹慎使用kill -9
直接使用普通的 kill 命令處理 PostgreSQL 后臺進程是可行的。這會發(fā)送 SIGTERM 信號,效果等同于為后臺進程調(diào)用 pg_terminate_backend()。如果此操作無效,有人可能會嘗試使用 kill -9,它會發(fā)送 SIGKILL 信號。該信號無法被捕獲,會立即終止進程。問題在于,postmaster 會檢測其子進程是否正常退出。一旦檢測到異常終止,它會殺死所有其他 PostgreSQL 進程并執(zhí)行崩潰恢復,這將導致整個數(shù)據(jù)庫短暫停服,持續(xù)時間從數(shù)秒到數(shù)分鐘不等。
請注意,對后臺進程使用 kill -9 僅會造成短暫停機,但對 postmaster 進程本身使用 kill -9 則會產(chǎn)生更嚴重的后果,應堅決避免。這會打開一個時間窗口,在此期間新的 postmaster 可能被啟動,而舊 postmaster 的某些子進程仍然存活,極有可能導致磁盤上的數(shù)據(jù)損壞。永遠不要使用 kill -9 殺死 postmaster 進程!
有時,即使是 kill -9 也無法殺死一個 PostgreSQL 后臺進程。這意味著該進程卡在了一個不可中斷的系統(tǒng)調(diào)用中,例如,在對已不可用的網(wǎng)絡附加存儲執(zhí)行 I/O 操作。如果這種狀況持續(xù)存在,唯一的方法就是重啟操作系統(tǒng)。
高級技巧:在不重啟服務器的情況下取消卡住的查詢
有時,您可以按照以下步驟操作,以避免數(shù)據(jù)庫崩潰恢復和停服。以下示例基于 Linux 環(huán)境下的 GNU 調(diào)試器 gdb;其他環(huán)境請自行適配。
1. 創(chuàng)建一個會掛起的函數(shù)示例
我們編寫一個簡單的 C 函數(shù)(源文件 loop.c):
#include "postgres.h"
#include "fmgr.h"
#include <unistd.h>
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(loop);
Datum
loop(PG_FUNCTION_ARGS)
{
/* 一個無限循環(huán) */
while(1)
sleep(2);
}按如下方式構(gòu)建共享庫(請根據(jù)實際環(huán)境調(diào)整包含路徑):
gcc -I /usr/pgsql-14/include/server -fPIC -shared -o loop.so loop.c
將生成的 loop.so 文件復制到 PostgreSQL 的共享庫目錄(可通過 pg_config --libdir 獲?。?。
2. 定義并調(diào)用函數(shù)
以超級用戶身份在 SQL 中定義函數(shù):
CREATE FUNCTION loop() RETURNS void LANGUAGE c AS 'loop';
然后,以普通用戶身份調(diào)用該函數(shù):
SELECT loop();
執(zhí)行將陷入掛起。您可以嘗試取消查詢,但它會持續(xù)運行。
3. 定位掛起的后臺進程并發(fā)送終止信號
使用相同的數(shù)據(jù)庫用戶打開另一個數(shù)據(jù)庫連接,通過以下查詢找出該會話的后臺進程 ID:
SELECT pid, query FROM pg_stat_activity WHERE query LIKE '%loop%';
獲取進程 ID 后,向其發(fā)送 SIGTERM 信號:
SELECT pg_terminate_backend(12345);
(請將 12345 替換為實際進程 ID)。該函數(shù)返回 TRUE,表示信號已發(fā)送,但查詢?nèi)栽趫?zhí)行。
4. 用調(diào)試器附加到進程
確保已安裝 gdb 調(diào)試器。為獲得可讀的堆棧跟蹤,建議安裝 PostgreSQL 服務器的調(diào)試符號(但這并非本技巧的必需步驟)。以 PostgreSQL 用戶(通常名為 postgres)身份登錄到數(shù)據(jù)庫服務器,按如下方式調(diào)用 gdb(請使用正確的 postgres 可執(zhí)行文件路徑和進程 ID):
gdb /usr/pgsql-14/bin/postgres 12345
在 (gdb) 提示符下,輸入 bt 命令生成堆棧跟蹤,輸出類似如下:
#0 __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0,
req=req@entry=0x7ffdaf61cde0, rem=rem@entry=0x7ffdaf61cde0)
at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:71
#1 0x00007f113d864897 in __GI___nanosleep (req=req@entry=0x7ffdaf61cde0,
rem=rem@entry=0x7ffdaf61cde0) at ../sysdeps/unix/sysv/linux/nanosleep.c:25
#2 0x00007f113d8647ce in __sleep (seconds=0) at ../sysdeps/posix/sleep.c:55
#3 0x00007f113e623139 in loop () from /usr/pgsql-14/lib/loop.so
#4 0x00000000006d71fb in ExecInterpExpr (state=0x13837b8, econtext=0x13834e0,
isnull=<optimized out>) at executor/execExprInterp.c:1260
#5 0x000000000070e391 in ExecEvalExprSwitchContext (isNull=0x7ffdaf61ced7,
econtext=0x13834e0, state=0x13837b8)
at executor/../../../src/include/executor/executor.h:339
#6 ExecProject (projInfo=0x13837b0)
at executor/../../../src/include/executor/executor.h:373
#7 ExecResult (pstate=<optimized out>) at executor/nodeResult.c:136
#8 0x00000000006da8b2 in ExecProcNode (node=0x13833d0)
at executor/../../../src/include/executor/executor.h:257
#9 ExecutePlan (execute_once=<optimized out>, dest=0x137f4c0, direction=<optimized out>,
numberTuples=0, sendTuples=<optimized out>, operation=CMD_SELECT,
use_parallel_mode=<optimized out>, planstate=0x13833d0, estate=0x13831a8)
at executor/execMain.c:1551
[...]堆棧跟蹤有助于定位問題根源。如果您需要向 PostgreSQL 報告此問題,請附上此信息。
如果您不想繼續(xù)下一步,可以在 (gdb) 提示符下輸入 detach 分離調(diào)試器,讓進程繼續(xù)運行。
5. 通過讓卡住的后臺進程干凈退出以取消執(zhí)行
觀察上面的堆棧跟蹤,可以看到當前執(zhí)行點位于一個自定義函數(shù)中(loop () from /usr/pgsql-14/lib/loop.so),而不是 PostgreSQL 內(nèi)部代碼。這種情況下,讓進程退出是相對安全的。如果執(zhí)行點位于 PostgreSQL 服務器內(nèi)部,則可能存在一定的風險(例如,進程可能正持有自旋鎖或處于修改共享狀態(tài))。若您熟悉 PostgreSQL 源碼,可以通過調(diào)用棧評估風險。
現(xiàn)在,如果決定繼續(xù),請在 (gdb) 提示符下調(diào)用 ProcessInterrupts() 函數(shù)。由于此前已設(shè)置了 ProcDiePending 標志,該調(diào)用將導致進程退出:
(gdb) print ProcessInterrupts() [Inferior 1 (process 12345) exited with code 01] The program being debugged exited while in a function called from GDB. Evaluation of the expression containing the function (ProcessInterrupts) will be abandoned. (gdb) quit
6. 改進函數(shù)以支持取消
為了避免此類問題,函數(shù)代碼應修改為定期檢查中斷標志:
#include "postgres.h"
#include "fmgr.h"
#include "miscadmin.h"
#include <unistd.h>
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(loop);
Datum
loop(PG_FUNCTION_ARGS)
{
/* 一個無限循環(huán),但允許中斷 */
while(1)
{
CHECK_FOR_INTERRUPTS();
sleep(2);
}
}修改后,函數(shù)將每兩秒檢查一次中斷標志,從而能夠被安全地取消。
結(jié)論
取消 PostgreSQL 查詢的本質(zhì)是向后臺進程發(fā)送 SIGINT 信號。如果 SIGINT 和 SIGTERM 均無法中斷進程,您可以使用 gdb 附加到該進程,并直接調(diào)用 ProcessInterrupts() 函數(shù),使其干凈退出。
以上就是掛起的PostgreSQL查詢?nèi)∠椒ǖ脑敿殐?nèi)容,更多關(guān)于取消掛起PostgreSQL查詢的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
PostgreSQL創(chuàng)建觸發(fā)器的實現(xiàn)示例
PostgreSQL的觸發(fā)器Trigger是一類特殊的數(shù)據(jù)庫對象,本文主要介紹了PostgreSQL創(chuàng)建觸發(fā)器的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2025-06-06
Windows版?PostgreSQL?利用?pg_upgrade?進行大版升級操作方法
最近?PostgreSQL?15?版本正式發(fā)布了,新版本的各種特性和好處本文就不展開介紹了,主要介紹一下?Windows?環(huán)境下?PostgreSQL?大版本升級的方法,我們現(xiàn)在的幾個數(shù)據(jù)庫都是運行在?Windows服務器的?PostgreSQL?14,需要的朋友可以參考下2022-10-10
使用PostgreSQL創(chuàng)建高級搜索引擎的代碼示例
本文我們將探索PostgreSQL中的全文搜索功能,并研究我們能夠復制多少典型搜索引擎功能,文中有詳細的代碼示例供大家參考,需要的朋友可以參考下2023-07-07
PostgreSQL高級特性與性能優(yōu)化的實戰(zhàn)指南
本文將深入探討PostgreSQL的高級特性與性能優(yōu)化技術(shù),結(jié)合Python實踐,幫助開發(fā)者充分發(fā)揮PostgreSQL的潛力,文中的示例代碼講解詳細,需要的小伙伴可以了解下2026-02-02
PostgreSQL實現(xiàn)一個通用標簽系統(tǒng)
這篇文章主要給大家介紹了關(guān)于利用PostgreSQL實現(xiàn)一個通用標簽系統(tǒng)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-01-01
CVE-2019-9193之PostgreSQL?任意命令執(zhí)行漏洞的問題

