這篇文章主要介紹“PostgreSQL在響應(yīng)客戶端發(fā)出備份命令pg_basebackup時(shí)做了什么”,在日常操作中,相信很多人在PostgreSQL在響應(yīng)客戶端發(fā)出備份命令pg_basebackup時(shí)做了什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”PostgreSQL在響應(yīng)客戶端發(fā)出備份命令pg_basebackup時(shí)做了什么”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
創(chuàng)新互聯(lián)專注于寧波網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供寧波營銷型網(wǎng)站建設(shè),寧波網(wǎng)站制作、寧波網(wǎng)頁設(shè)計(jì)、寧波網(wǎng)站官網(wǎng)定制、小程序設(shè)計(jì)服務(wù),打造寧波網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供寧波網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。
basebackup_options
pg_basebackup的選項(xiàng),在數(shù)據(jù)庫服務(wù)器解析為該數(shù)據(jù)結(jié)構(gòu).
typedef struct { //備份的標(biāo)簽 const char *label; //是否顯示進(jìn)度 bool progress; //是否執(zhí)行快速fast checkpoint? bool fastcheckpoint; //nowait? bool nowait; //是否包含wal data bool includewal; // uint32 maxrate; //是否包含表空間映射文件? bool sendtblspcmapfile; } basebackup_options;
數(shù)據(jù)庫服務(wù)器接收到請求,postmaster啟動新的postgres進(jìn)程響應(yīng)此請求,此進(jìn)程被視為walsender,標(biāo)記am_walsender設(shè)置為T,在PostgresMain函數(shù)中,將執(zhí)行以下邏輯:
... for (;;)//主循環(huán) { ... switch (firstchar) { case 'Q': /* simple query */ { if (am_walsender) { //如為WAL sender,執(zhí)行exec_replication_command if (!exec_replication_command(query_string)) exec_simple_query(query_string); ... ...
調(diào)用exec_replication_command函數(shù),執(zhí)行相關(guān)命令.該函數(shù)會調(diào)用SendBaseBackup函數(shù)執(zhí)行具體的實(shí)現(xiàn)邏輯,其中重點(diǎn)的實(shí)現(xiàn)函數(shù)是sendFileWithContent/sendDir.
1.sendFileWithContent函數(shù)用于發(fā)送backup_label等文件到客戶端
pq_putmessage發(fā)送消息,’d’的消息類型表示CopyData.
static void sendFileWithContent(const char *filename, const char *content) { struct stat statbuf; int pad, len; len = strlen(content); /* * Construct a stat struct for the backup_label file we're injecting in * the tar. */ /* Windows doesn't have the concept of uid and gid */ #ifdef WIN32 statbuf.st_uid = 0; statbuf.st_gid = 0; #else statbuf.st_uid = geteuid(); statbuf.st_gid = getegid(); #endif statbuf.st_mtime = time(NULL); statbuf.st_mode = pg_file_create_mode; statbuf.st_size = len; _tarWriteHeader(filename, NULL, &statbuf, false); /* Send the contents as a CopyData message */ pq_putmessage('d', content, len); /* Pad to 512 byte boundary, per tar format requirements */ pad = ((len + 511) & ~511) - len; if (pad > 0) { char buf[512]; MemSet(buf, 0, pad); pq_putmessage('d', buf, pad); } }
2.sendDir遍歷文件目錄,調(diào)用sendFile發(fā)送到客戶端
遞歸遍歷數(shù)據(jù)庫目錄,調(diào)用sendFile發(fā)送文件
... if (!sizeonly) sent = sendFile(pathbuf, pathbuf + basepathlen + 1, &statbuf, true, isDbDir ? pg_atoi(lastDir + 1, sizeof(Oid), 0) : InvalidOid); if (sent || sizeonly) { /* Add size, rounded up to 512byte block */ size += ((statbuf.st_size + 511) & ~511); size += 512; /* Size of the header of the file */ } ...
sendFile發(fā)送相應(yīng)的文件內(nèi)容到客戶端
... while ((cnt = fread(buf, 1, Min(sizeof(buf), statbuf->st_size - len), fp)) > 0) { ... /* Send the chunk as a CopyData message */ if (pq_putmessage('d', buf, cnt)) ereport(ERROR, (errmsg("base backup could not send data, aborting backup"))); ... }
客戶端啟動pg_basebackup
[xdb@localhost ~]$ pg_basebackup -h 192.168.26.25 -U replicator -p 5432 -D /data/backup -P -Xs -R Password:
跟蹤postmaster,設(shè)置跟蹤子進(jìn)程
(gdb) set follow-fork-mode child (gdb) b PostgresMain
客戶端輸入密碼后,進(jìn)入斷點(diǎn),在執(zhí)行BASE_BACKUP命令前,首先會執(zhí)行SHOW data_directory_mode/SHOW wal_segment_size/IDENTIFY_SYSTEM三個(gè)命令,然后再執(zhí)行BASE_BACKUP命令
... (gdb) p input_message $2 = {data = 0x20a1d78 "SHOW data_directory_mode", len = 25, maxlen = 1024, cursor = 0} ... (gdb) p input_message $4 = {data = 0x20a1d78 "SHOW wal_segment_size", len = 22, maxlen = 1024, cursor = 0} ... (gdb) p input_message $5 = {data = 0x20a1d78 "IDENTIFY_SYSTEM", len = 16, maxlen = 1024, cursor = 0} ... (gdb) p input_message $7 = {data = 0x20a1d78 "BASE_BACKUP LABEL 'pg_basebackup base backup' PROGRESS NOWAIT ", len = 67, maxlen = 1024, cursor = 0} ...
跟蹤SendBaseBackup
(gdb) b SendBaseBackup ... 4178 if (!exec_replication_command(query_string)) (gdb) step exec_replication_command (cmd_string=0x20a1d78 "BASE_BACKUP LABEL 'pg_basebackup base backup' PROGRESS NOWAIT ") at walsender.c:1438 1438 if (got_STOPPING) 1521 SendBaseBackup((BaseBackupCmd *) cmd_node); ...
進(jìn)入SendBaseBackup
(gdb) c Continuing. [New process 1811] [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". [Switching to Thread 0x7f46389b58c0 (LWP 1811)] Breakpoint 1, SendBaseBackup (cmd=0x2137da8) at basebackup.c:762 762 parse_basebackup_options(cmd->options, &opt); (gdb) n 764 WalSndSetState(WALSNDSTATE_BACKUP); (gdb) p opt $1 = {label = 0x2137760 "pg_basebackup base backup", progress = true, fastcheckpoint = false, nowait = true, includewal = false, maxrate = 0, sendtblspcmapfile = false}
實(shí)際執(zhí)行backup的是函數(shù)perform_base_backup
... (gdb) 775 perform_base_backup(&opt); (gdb) step perform_base_backup (opt=0x7ffc96573180) at basebackup.c:232
執(zhí)行sendXXX
320 if (ti->path == NULL) (gdb) 325 sendFileWithContent(BACKUP_LABEL_FILE, labelfile->data); (gdb) p *labelfile $4 = { data = 0x2138a50 "START WAL LOCATION: 0/66000028 (file 0000001", '0', "66)\nCHECKPOINT LOCATION: 0/66000060\nBACKUP METHOD: streamed\nBACKUP FROM: master\nSTART TIME: 2019-03-26 17:05:45 CST\nLABEL: pg_basebackup base"..., len = 227, maxlen = 1024, cursor = 0} (gdb) n 331 if (tblspc_map_file && opt->sendtblspcmapfile) (gdb) 337 sendDir(".", 1, false, tablespaces, true); (gdb) 340 if (lstat(XLOG_CONTROL_FILE, &statbuf) != 0) (gdb) 345 sendFile(XLOG_CONTROL_FILE, XLOG_CONTROL_FILE, &statbuf, false); (gdb) 356 if (opt->includewal && ti->path == NULL) (gdb) 361 pq_putemptymessage('c'); /* CopyDone */ (gdb) 309 foreach(lc, tablespaces) (gdb) 364 endptr = do_pg_stop_backup(labelfile->data, !opt->nowait, &endtli); (gdb) 366 PG_END_ENSURE_ERROR_CLEANUP(base_backup_cleanup, (Datum) 0); (gdb) 369 if (opt->includewal) (gdb) 605 SendXlogRecPtrResult(endptr, endtli); (gdb) 607 if (total_checksum_failures) (gdb) 623 } (gdb) SendBaseBackup (cmd=0x2137da8) at basebackup.c:776 776 } (gdb) exec_replication_command (cmd_string=0x20a1d78 "BASE_BACKUP LABEL 'pg_basebackup base backup' PROGRESS NOWAIT ") at walsender.c:1522 1522 break; (gdb) c Continuing. [Inferior 2 (process 1811) exited normally] (gdb)
到此,關(guān)于“PostgreSQL在響應(yīng)客戶端發(fā)出備份命令pg_basebackup時(shí)做了什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!