久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

PostgreSQL同步復制主庫掛起分析

249次閱讀
沒有評論

共計 7186 個字符,預計需要花費 18 分鐘才能閱讀完成。

這篇文章主要講解了“PostgreSQL 同步復制主庫掛起分析”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著丸趣 TV 小編的思路慢慢深入,一起來研究和學習“PostgreSQL 同步復制主庫掛起分析”吧!

在 Streaming Replication 環境中 PostgreSQL 主節點設置為同步復制, 如 standby 節點沒有啟動或者網絡出現問題沒法連接到主節點時, 主節點如執行 DML 則進程會掛起, 下面分析這個掛起的問題.

一、數據結構

Latch
Latch 結構體應被視為 opaque”不透明的”, 并且只能通過公共的函數訪問. 在這里定義是運行把 Latchs 作為更大的結構體的一部分.

// 通常情況下,int 類型的變量通常是原子訪問的,也可以認為  sig_atomic_t 就是 int 類型的數據,// 因為對這些變量要求一條指令完成,所以 sig_atomic_t 不可能是結構體,只會是數字類型。typedef int __sig_atomic_t;
 * Latch structure should be treated as opaque and only accessed through
 * the public functions. It is defined here to allow embedding Latches as
 * part of bigger structs.
 * Latch 結構體應被視為 不透明的 opaque, 并且只能通過公共的函數訪問.
 *  在這里定義是運行把 Latchs 作為更大的結構體的一部分.
 */
typedef struct Latch
 sig_atomic_t is_set;
 bool is_shared;
 int owner_pid;
#ifdef WIN32
 HANDLE event;
#endif
} Latch;

二、源碼解讀

N/A

二、跟蹤分析

啟動 master 節點, 不啟動 standby 節點, 使用 psql 連接數據庫, 執行 SQL,Session 掛起:

testdb=# drop table t1;

使用 gdb 跟蹤掛起的進程

[xdb@localhost ~]$ ps -ef|grep postgres
xdb 1318 1 0 12:14 pts/0 00:00:00 /appdb/xdb/pg11.2/bin/postgres
xdb 1319 1318 0 12:14 ? 00:00:00 postgres: logger 
xdb 1321 1318 0 12:14 ? 00:00:00 postgres: checkpointer 
xdb 1322 1318 0 12:14 ? 00:00:00 postgres: background writer 
xdb 1323 1318 0 12:14 ? 00:00:00 postgres: walwriter 
xdb 1324 1318 0 12:14 ? 00:00:00 postgres: autovacuum launcher 
xdb 1325 1318 0 12:14 ? 00:00:00 postgres: archiver 
xdb 1326 1318 0 12:14 ? 00:00:00 postgres: stats collector 
xdb 1327 1318 0 12:14 ? 00:00:00 postgres: logical replication launcher 
xdb 1331 1318 0 12:15 ? 00:00:00 postgres: xdb testdb [local] DROP TABLE waiting for 0/5D07B668
[xdb@localhost ~]$ gdb -p 1331
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-100.el7
...

查看調用棧

(gdb) bt
#0 0x00007f4636d48903 in __epoll_wait_nocancel () from /lib64/libc.so.6
#1 0x000000000088e668 in WaitEventSetWaitBlock (set=0x21640e8, cur_timeout=-1, occurred_events=0x7ffc96572f40, nevents=1)
 at latch.c:1048
#2 0x000000000088e543 in WaitEventSetWait (set=0x21640e8, timeout=-1, occurred_events=0x7ffc96572f40, nevents=1, 
 wait_event_info=134217761) at latch.c:1000
#3 0x000000000088dcec in WaitLatchOrSocket (latch=0x7f462d5b44d4, wakeEvents=17, sock=-1, timeout=-1, 
 wait_event_info=134217761) at latch.c:385
#4 0x000000000088dbcd in WaitLatch (latch=0x7f462d5b44d4, wakeEvents=17, timeout=-1, wait_event_info=134217761)
 at latch.c:339
#5 0x0000000000863e2d in SyncRepWaitForLSN (lsn=1560786536, commit=true) at syncrep.c:286
#6 0x0000000000546279 in RecordTransactionCommit () at xact.c:1359
#7 0x0000000000546da3 in CommitTransaction () at xact.c:2074
#8 0x0000000000547a3f in CommitTransactionCommand () at xact.c:2817
#9 0x00000000008be250 in finish_xact_command () at postgres.c:2523
#10 0x00000000008bbf45 in exec_simple_query (query_string=0x20a1d78  drop table t1;) at postgres.c:1170
#11 0x00000000008c0191 in PostgresMain (argc=1, argv=0x20cdcd8, dbname=0x20cdb40  testdb , username=0x209ea98  xdb)
 at postgres.c:4182
#12 0x000000000081e06c in BackendRun (port=0x20c3b10) at postmaster.c:4361
#13 0x000000000081d7df in BackendStartup (port=0x20c3b10) at postmaster.c:4033
#14 0x0000000000819bd9 in ServerLoop () at postmaster.c:1706
#15 0x000000000081948f in PostmasterMain (argc=1, argv=0x209ca50) at postmaster.c:1379
#16 0x0000000000742931 in main (argc=1, argv=0x209ca50) at main.c:228
(gdb)

kill 進程, 重新進入在 WaitLatch 上設置斷點進行跟蹤

#########
[xdb@localhost ~]$ kill -9 1331
#########
testdb=# select pg_backend_pid();
 pg_backend_pid 
----------------
 1377
(1 row)
#########
[xdb@localhost ~]$ gdb -p 1377
(gdb) b WaitLatch
Breakpoint 1 at 0x88dbac: file latch.c, line 339.
(gdb) 
#########
testdb=# drop table t1;
ERROR: table  t1  does not exist
testdb=# create table t1(id int);

進入斷點

(gdb) b WaitLatch
Breakpoint 1 at 0x88dbac: file latch.c, line 339.
(gdb) c
Continuing.
Breakpoint 1, WaitLatch (latch=0x7f462d5b44d4, wakeEvents=17, timeout=-1, wait_event_info=134217761) at latch.c:339
339 return WaitLatchOrSocket(latch, wakeEvents, PGINVALID_SOCKET, timeout,
(gdb)

進入 WaitLatchOrSocket

(gdb) step
WaitLatchOrSocket (latch=0x7f462d5b44d4, wakeEvents=17, sock=-1, timeout=-1, wait_event_info=134217761) at latch.c:359
359 int ret = 0;
(gdb) 
(gdb) p *latch
$1 = {is_set = 0, is_shared = true, owner_pid = 1377}

構建等待事件集

(gdb) n
362 WaitEventSet *set = CreateWaitEventSet(CurrentMemoryContext, 3);
(gdb) n
364 if (wakeEvents   WL_TIMEOUT)
(gdb) 
367 timeout = -1;
(gdb) 
369 if (wakeEvents   WL_LATCH_SET)
(gdb) p *set
$2 = {nevents = 0, nevents_space = 3, events = 0x2181eb8, latch = 0x0, latch_pos = 0, epoll_fd = 37, 
 epoll_ret_events = 0x2181f00}
(gdb) p *set- events
$3 = {pos = 0, events = 0, fd = 0, user_data = 0x0}
(gdb) p *set- epoll_ret_events
$4 = {events = 0, data = {ptr = 0x0, fd = 0, u32 = 0, u64 = 0}}
(gdb) 
$5 = {events = 0, data = {ptr = 0x0, fd = 0, u32 = 0, u64 = 0}}
(gdb) n
370 AddWaitEventToSet(set, WL_LATCH_SET, PGINVALID_SOCKET,
(gdb) 
373 if (wakeEvents   WL_POSTMASTER_DEATH   IsUnderPostmaster)
(gdb) 
374 AddWaitEventToSet(set, WL_POSTMASTER_DEATH, PGINVALID_SOCKET,
(gdb) 
377 if (wakeEvents   WL_SOCKET_MASK)
(gdb) 
385 rc = WaitEventSetWait(set, timeout,  event, 1, wait_event_info);
(gdb) p *set
$6 = {nevents = 2, nevents_space = 3, events = 0x2181eb8, latch = 0x7f462d5b44d4, latch_pos = 0, epoll_fd = 37, 
 epoll_ret_events = 0x2181f00}
(gdb) p *set- events
$7 = {pos = 0, events = 1, fd = 11, user_data = 0x0}
(gdb) p *set- epoll_ret_events
$8 = {events = 0, data = {ptr = 0x0, fd = 0, u32 = 0, u64 = 0}}
(gdb)

進入 WaitEventSetWait

(gdb) step
WaitEventSetWait (set=0x2181e90, timeout=-1, occurred_events=0x7ffc96572f40, nevents=1, wait_event_info=134217761)
 at latch.c:925
925 int returned_events = 0;
(gdb)

輸入參數

(gdb) n
928 long cur_timeout = -1;
(gdb) p *set
$9 = {nevents = 2, nevents_space = 3, events = 0x2181eb8, latch = 0x7f462d5b44d4, latch_pos = 0, epoll_fd = 37, 
 epoll_ret_events = 0x2181f00}
(gdb) p *occurred_events
$10 = {pos = 35135068, events = 0, fd = -1772664741, user_data = 0x7ffc96572fa0}
(gdb)

執行相關判斷和設置參數

(gdb) n
930 Assert(nevents   0);
(gdb) 
936 if (timeout  = 0)
(gdb) 
943 pgstat_report_wait_start(wait_event_info);
(gdb) 
946 waiting = true;
(gdb)

未有事件出現, 則循環

951 while (returned_events == 0)
(gdb)

不符合 set- latch- is_set 為 T 的條件, 繼續循環

982 if (set- latch   set- latch- is_set)
(gdb) p *set- latch
$11 = {is_set = 0, is_shared = true, owner_pid = 1377}
(gdb)

進入 WaitEventSetWaitBlock

(gdb) n
1000 rc = WaitEventSetWaitBlock(set, cur_timeout,
(gdb) step
WaitEventSetWaitBlock (set=0x2181e90, cur_timeout=-1, occurred_events=0x7ffc96572f40, nevents=1) at latch.c:1042
1042 int returned_events = 0;
(gdb)

調用 epoll_wait, 掛起

(gdb) n
1048 rc = epoll_wait(set- epoll_fd, set- epoll_ret_events,
(gdb) p *set
$12 = {nevents = 2, nevents_space = 3, events = 0x2181eb8, latch = 0x7f462d5b44d4, latch_pos = 0, epoll_fd = 37, 
 epoll_ret_events = 0x2181f00}
(gdb) 
(gdb) n

啟動 standby 節點

####
[xdb@localhost ~]$ pg_ctl start
pg_ctl: another server might be running; trying to start server anyway
...

接收到信號

Program received signal SIGUSR1, User defined signal 1.
0x00007f4636d48903 in __epoll_wait_nocancel () from /lib64/libc.so.6
(gdb) 
(gdb) n
Single stepping until exit from function __epoll_wait_nocancel,
which has no line number information.
procsignal_sigusr1_handler (postgres_signal_arg=-1) at procsignal.c:262
262 {(gdb)

感謝各位的閱讀,以上就是“PostgreSQL 同步復制主庫掛起分析”的內容了,經過本文的學習后,相信大家對 PostgreSQL 同步復制主庫掛起分析這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是丸趣 TV,丸趣 TV 小編將為大家推送更多相關知識點的文章,歡迎關注!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-24發表,共計7186字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 开封县| 城步| 仪陇县| 奇台县| 红安县| 永嘉县| 嘉禾县| 甘谷县| 柳林县| 阿尔山市| 政和县| 平定县| 济南市| 邳州市| 平武县| 永顺县| 土默特右旗| 南木林县| 晴隆县| 乳山市| 凤城市| 北海市| 北安市| 万宁市| 含山县| 马山县| 拉孜县| 齐河县| 昭通市| 台安县| 樟树市| 宜春市| 郎溪县| 阜南县| 安图县| 铜鼓县| 淮安市| 扎兰屯市| 会宁县| 靖西县| 永嘉县|