PostgreSQL在响应客户端发出备份命令pg_basebackup时做了什么
这篇文章主要介绍“PostgreSQL在响应客户端发出备份命令pg_basebackup时做了什么”,在日常操作中,相信很多人在PostgreSQL在响应客户端发出备份命令pg_basebackup时做了什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”PostgreSQL在响应客户端发出备份命令pg_basebackup时做了什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
一、数据结构basebackup_options
pg_basebackup的选项,在数据库服务器解析为该数据结构.
typedefstruct{//备份的标签constchar*label;//是否显示进度boolprogress;//是否执行快速fastcheckpoint?boolfastcheckpoint;//nowait?boolnowait;//是否包含waldataboolincludewal;//uint32maxrate;//是否包含表空间映射文件?boolsendtblspcmapfile;}basebackup_options;二、源码解读
数据库服务器接收到请求,postmaster启动新的postgres进程响应此请求,此进程被视为walsender,标记am_walsender设置为T,在PostgresMain函数中,将执行以下逻辑:
...for(;;)//主循环{...switch(firstchar){case'Q':/*simplequery*/{if(am_walsender){//如为WALsender,执行exec_replication_commandif(!exec_replication_command(query_string))exec_simple_query(query_string);......
调用exec_replication_command函数,执行相关命令.该函数会调用SendBaseBackup函数执行具体的实现逻辑,其中重点的实现函数是sendFileWithContent/sendDir.
1.sendFileWithContent函数用于发送backup_label等文件到客户端
pq_putmessage发送消息,’d’的消息类型表示CopyData.
staticvoidsendFileWithContent(constchar*filename,constchar*content){structstatstatbuf;intpad,len;len=strlen(content);/**Constructastatstructforthebackup_labelfilewe'reinjectingin*thetar.*//*Windowsdoesn'thavetheconceptofuidandgid*/#ifdefWIN32statbuf.st_uid=0;statbuf.st_gid=0;#elsestatbuf.st_uid=geteuid();statbuf.st_gid=getegid();#endifstatbuf.st_mtime=time(NULL);statbuf.st_mode=pg_file_create_mode;statbuf.st_size=len;_tarWriteHeader(filename,NULL,&statbuf,false);/*SendthecontentsasaCopyDatamessage*/pq_putmessage('d',content,len);/*Padto512byteboundary,pertarformatrequirements*/pad=((len+511)&~511)-len;if(pad>0){charbuf[512];MemSet(buf,0,pad);pq_putmessage('d',buf,pad);}}
2.sendDir遍历文件目录,调用sendFile发送到客户端
递归遍历数据库目录,调用sendFile发送文件
...if(!sizeonly)sent=sendFile(pathbuf,pathbuf+basepathlen+1,&statbuf,true,isDbDir?pg_atoi(lastDir+1,sizeof(Oid),0):InvalidOid);if(sent||sizeonly){/*Addsize,roundedupto512byteblock*/size+=((statbuf.st_size+511)&~511);size+=512;/*Sizeoftheheaderofthefile*/}...
sendFile发送相应的文件内容到客户端
...while((cnt=fread(buf,1,Min(sizeof(buf),statbuf->st_size-len),fp))>0){.../*SendthechunkasaCopyDatamessage*/if(pq_putmessage('d',buf,cnt))ereport(ERROR,(errmsg("basebackupcouldnotsenddata,abortingbackup")));...}三、跟踪分析
客户端启动pg_basebackup
[xdb@localhost~]$pg_basebackup-h192.168.26.25-Ureplicator-p5432-D/data/backup-P-Xs-RPassword:
跟踪postmaster,设置跟踪子进程
(gdb)setfollow-fork-modechild(gdb)bPostgresMain
客户端输入密码后,进入断点,在执行BASE_BACKUP命令前,首先会执行SHOW data_directory_mode/SHOW wal_segment_size/IDENTIFY_SYSTEM三个命令,然后再执行BASE_BACKUP命令
...(gdb)pinput_message$2={data=0x20a1d78"SHOWdata_directory_mode",len=25,maxlen=1024,cursor=0}...(gdb)pinput_message$4={data=0x20a1d78"SHOWwal_segment_size",len=22,maxlen=1024,cursor=0}...(gdb)pinput_message$5={data=0x20a1d78"IDENTIFY_SYSTEM",len=16,maxlen=1024,cursor=0}...(gdb)pinput_message$7={data=0x20a1d78"BASE_BACKUPLABEL'pg_basebackupbasebackup'PROGRESSNOWAIT",len=67,maxlen=1024,cursor=0}...
跟踪SendBaseBackup
(gdb)bSendBaseBackup...4178if(!exec_replication_command(query_string))(gdb)stepexec_replication_command(cmd_string=0x20a1d78"BASE_BACKUPLABEL'pg_basebackupbasebackup'PROGRESSNOWAIT")atwalsender.c:14381438if(got_STOPPING)1521SendBaseBackup((BaseBackupCmd*)cmd_node);...
进入SendBaseBackup
(gdb)cContinuing.[Newprocess1811][Threaddebuggingusinglibthread_dbenabled]Usinghostlibthread_dblibrary"/lib64/libthread_db.so.1".[SwitchingtoThread0x7f46389b58c0(LWP1811)]Breakpoint1,SendBaseBackup(cmd=0x2137da8)atbasebackup.c:762762parse_basebackup_options(cmd->options,&opt);(gdb)n764WalSndSetState(WALSNDSTATE_BACKUP);(gdb)popt$1={label=0x2137760"pg_basebackupbasebackup",progress=true,fastcheckpoint=false,nowait=true,includewal=false,maxrate=0,sendtblspcmapfile=false}
实际执行backup的是函数perform_base_backup
...(gdb)775perform_base_backup(&opt);(gdb)stepperform_base_backup(opt=0x7ffc96573180)atbasebackup.c:232
执行sendXXX
320if(ti->path==NULL)(gdb)325sendFileWithContent(BACKUP_LABEL_FILE,labelfile->data);(gdb)p*labelfile$4={data=0x2138a50"STARTWALLOCATION:0/66000028(file0000001",'0'<repeats15times>,"66)\nCHECKPOINTLOCATION:0/66000060\nBACKUPMETHOD:streamed\nBACKUPFROM:master\nSTARTTIME:2019-03-2617:05:45CST\nLABEL:pg_basebackupbase"...,len=227,maxlen=1024,cursor=0}(gdb)n331if(tblspc_map_file&&opt->sendtblspcmapfile)(gdb)337sendDir(".",1,false,tablespaces,true);(gdb)340if(lstat(XLOG_CONTROL_FILE,&statbuf)!=0)(gdb)345sendFile(XLOG_CONTROL_FILE,XLOG_CONTROL_FILE,&statbuf,false);(gdb)356if(opt->includewal&&ti->path==NULL)(gdb)361pq_putemptymessage('c');/*CopyDone*/(gdb)309foreach(lc,tablespaces)(gdb)364endptr=do_pg_stop_backup(labelfile->data,!opt->nowait,&endtli);(gdb)366PG_END_ENSURE_ERROR_CLEANUP(base_backup_cleanup,(Datum)0);(gdb)369if(opt->includewal)(gdb)605SendXlogRecPtrResult(endptr,endtli);(gdb)607if(total_checksum_failures)(gdb)623}(gdb)SendBaseBackup(cmd=0x2137da8)atbasebackup.c:776776}(gdb)exec_replication_command(cmd_string=0x20a1d78"BASE_BACKUPLABEL'pg_basebackupbasebackup'PROGRESSNOWAIT")atwalsender.c:15221522break;(gdb)cContinuing.[Inferior2(process1811)exitednormally](gdb)
到此,关于“PostgreSQL在响应客户端发出备份命令pg_basebackup时做了什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。