iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >PostgreSQL在响应客户端发出备份命令pg_basebackup时做了什么
  • 877
分享到

PostgreSQL在响应客户端发出备份命令pg_basebackup时做了什么

2024-04-02 19:04:59 877人浏览 八月长安
摘要

这篇文章主要介绍“postgresql在响应客户端发出备份命令pg_basebackup时做了什么”,在日常操作中,相信很多人在Postgresql在响应客户端发出备份命令pg_basebackup时做了什

这篇文章主要介绍“postgresql在响应客户端发出备份命令pg_basebackup时做了什么”,在日常操作中,相信很多人在Postgresql在响应客户端发出备份命令pg_basebackup时做了什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”PostgreSQL在响应客户端发出备份命令pg_basebackup时做了什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

一、数据结构

basebackup_options
pg_basebackup的选项,在数据库服务器解析为该数据结构.

typedef struct
{
  //备份的标签
    const char *label;
    //是否显示进度
    bool        progress;
    //是否执行快速fast checkpoint?
    bool        fastcheckpoint;
    //nowait?
    bool        nowait;
    //是否包含wal data
    bool        includewal;
    //
    uint32      maxrate;
    //是否包含表空间映射文件?
    bool        sendtblspcmapfile;
} basebackup_options;

二、源码解读

数据库服务器接收到请求,postmaster启动新的postgres进程响应此请求,此进程被视为walsender,标记am_walsender设置为T,在PostgresMain函数中,将执行以下逻辑:

...
  for (;;)//主循环
  {
    ...
    switch (firstchar)
    {
      case 'Q':     
        {
          if (am_walsender)
          {
            //如为WAL sender,执行exec_replication_command
            if (!exec_replication_command(query_string))
              exec_simple_query(query_string);
            ...
...

调用exec_replication_command函数,执行相关命令.该函数会调用SendBaseBackup函数执行具体的实现逻辑,其中重点的实现函数是sendFileWithContent/sendDir.
1.sendFileWithContent函数用于发送backup_label等文件到客户端
pq_putmessage发送消息,’d’的消息类型表示CopyData.

static void
sendFileWithContent(const char *filename, const char *content)
{
    struct stat statbuf;
    int         pad,
                len;
    len = strlen(content);
    
    
#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);
    
    pq_putmessage('d', content, len);
    
    pad = ((len + 511) & ~511) - len;
    if (pad > 0)
    {
        char        buf[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)
            {
                
                size += ((statbuf.st_size + 511) & ~511);
                size += 512;    
            }
...

sendFile发送相应的文件内容到客户端

...
    while ((cnt = fread(buf, 1, Min(sizeof(buf), statbuf->st_size - len), fp)) > 0)
    {
      ...
       
        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,设置跟踪子进程

(gdb) set follow-fork-mode child
(gdb) b PostgresMain

客户端输入密码后,进入断点,在执行BASE_BACKUP命令前,首先会执行SHOW data_directory_mode/SHOW wal_segment_size/IDENTIFY_SYSTEM三个命令,然后再执行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);
...

进入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}

实际执行backup的是函数perfORM_base_backup

...
(gdb) 
775   perform_base_backup(&opt);
(gdb) step
perform_base_backup (opt=0x7ffc96573180) at basebackup.c:232

执行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' <repeats 15 times>, "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');  
(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)

到此,关于“PostgreSQL在响应客户端发出备份命令pg_basebackup时做了什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

您可能感兴趣的文档:

--结束END--

本文标题: PostgreSQL在响应客户端发出备份命令pg_basebackup时做了什么

本文链接: https://www.lsjlt.com/news/64165.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • oracle怎么查询当前用户所有的表
    要查询当前用户拥有的所有表,可以使用以下 sql 命令:select * from user_tables; 如何查询当前用户拥有的所有表 要查询当前用户拥有的所有表,可以使...
    99+
    2024-05-14
    oracle
  • oracle怎么备份表中数据
    oracle 表数据备份的方法包括:导出数据 (exp):将表数据导出到外部文件。导入数据 (imp):将导出文件中的数据导入表中。用户管理的备份 (umr):允许用户控制备份和恢复过程...
    99+
    2024-05-14
    oracle
  • oracle怎么做到数据实时备份
    oracle 实时备份通过持续保持数据库和事务日志的副本来实现数据保护,提供快速恢复。实现机制主要包括归档重做日志和 asm 卷管理系统。它最小化数据丢失、加快恢复时间、消除手动备份任务...
    99+
    2024-05-14
    oracle 数据丢失
  • oracle怎么查询所有的表空间
    要查询 oracle 中的所有表空间,可以使用 sql 语句 "select tablespace_name from dba_tablespaces",其中 dba_tabl...
    99+
    2024-05-14
    oracle
  • oracle怎么创建新用户并赋予权限设置
    答案:要创建 oracle 新用户,请执行以下步骤:以具有 create user 权限的用户身份登录;在 sql*plus 窗口中输入 create user identified ...
    99+
    2024-05-14
    oracle
  • oracle怎么建立新用户
    在 oracle 数据库中创建用户的方法:使用 sql*plus 连接数据库;使用 create user 语法创建新用户;根据用户需要授予权限;注销并重新登录以使更改生效。 如何在 ...
    99+
    2024-05-14
    oracle
  • oracle怎么创建新用户并赋予权限密码
    本教程详细介绍了如何使用 oracle 创建一个新用户并授予其权限:创建新用户并设置密码。授予对特定表的读写权限。授予创建序列的权限。根据需要授予其他权限。 如何使用 Oracle 创...
    99+
    2024-05-14
    oracle
  • oracle怎么查询时间段内的数据记录表
    在 oracle 数据库中查询指定时间段内的数据记录表,可以使用 between 操作符,用于比较日期或时间的范围。语法:select * from table_name wh...
    99+
    2024-05-14
    oracle
  • oracle怎么查看表的分区
    问题:如何查看 oracle 表的分区?步骤:查询数据字典视图 all_tab_partitions,指定表名。结果显示分区名称、上边界值和下边界值。 如何查看 Oracle 表的分区...
    99+
    2024-05-14
    oracle
  • oracle怎么导入dump文件
    要导入 dump 文件,请先停止 oracle 服务,然后使用 impdp 命令。步骤包括:停止 oracle 数据库服务。导航到 oracle 数据泵工具目录。使用 impdp 命令导...
    99+
    2024-05-14
    oracle
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作