返回顶部
首页 > 资讯 > 数据库 >PostgreSQL的备份工具pg_basebackup源码中的主函数分析
  • 645
分享到

PostgreSQL的备份工具pg_basebackup源码中的主函数分析

2024-04-02 19:04:59 645人浏览 安东尼
摘要

本篇内容主要讲解“postgresql的备份工具pg_basebackup源码中的主函数分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Postgresql的

本篇内容主要讲解“postgresql的备份工具pg_basebackup源码中的主函数分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Postgresql的备份工具pg_basebackup源码中的主函数分析”吧!

一、数据结构

option
使用工具时存储选项的数据结构

#ifndef HAVE_STRUCT_OPTioN
//工具软件选项
struct option
{
    const char *name;//名称
    int         has_arg;//是否包含参数,no_argument/required_argument/optional_argument
    int        *flag;//标记
    int         val;//参数值
};
#define no_argument 0
#define required_argument 1
#define optional_argument 2
#endif

#ifndef HAVE_INT_OPTERR
int         opterr = 1,         
            optind = 1,         
            optopt;             
char       *optarg;             
#endif
#define BADCH   (int)'?'
#define BADARG  (int)':'
#define EMSG    ""

二、源码解读

pg_basebackup主函数,源码较为简单,获取选项,校验,调用BaseBackup()函数进行备份.

int
main(int arGC, char **argv)
{
    static struct option long_options[] = {
        {"help", no_argument, NULL, '?'},
        {"version", no_argument, NULL, 'V'},
        {"pgdata", required_argument, NULL, 'D'},
        {"fORMat", required_argument, NULL, 'F'},
        {"checkpoint", required_argument, NULL, 'c'},
        {"create-slot", no_argument, NULL, 'C'},
        {"max-rate", required_argument, NULL, 'r'},
        {"write-recovery-conf", no_argument, NULL, 'R'},
        {"slot", required_argument, NULL, 'S'},
        {"tablespace-mapping", required_argument, NULL, 'T'},
        {"wal-method", required_argument, NULL, 'X'},
        {"gzip", no_argument, NULL, 'z'},
        {"compress", required_argument, NULL, 'Z'},
        {"label", required_argument, NULL, 'l'},
        {"no-clean", no_argument, NULL, 'n'},
        {"no-sync", no_argument, NULL, 'N'},
        {"dbname", required_argument, NULL, 'd'},
        {"host", required_argument, NULL, 'h'},
        {"port", required_argument, NULL, 'p'},
        {"username", required_argument, NULL, 'U'},
        {"no-passWord", no_argument, NULL, 'w'},
        {"password", no_argument, NULL, 'W'},
        {"status-interval", required_argument, NULL, 's'},
        {"verbose", no_argument, NULL, 'v'},
        {"progress", no_argument, NULL, 'P'},
        {"waldir", required_argument, NULL, 1},
        {"no-slot", no_argument, NULL, 2},
        {"no-verify-checksums", no_argument, NULL, 3},
        {NULL, 0, NULL, 0}
    };//(完整)选项
    //选项的ASCII值
    int         c;
    //选项索引编号
    int         option_index;
    //程序名称
    progname = get_progname(argv[0]);
    set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup"));
    if (argc > 1)
    {
        //显示帮助信息
        if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
        {
            usage();
            exit(0);
        }
        else if (strcmp(argv[1], "-V") == 0
                 || strcmp(argv[1], "--version") == 0)
        {
            //显示版本信息
            puts("pg_basebackup (PostgreSQL) " PG_VERSION);
            exit(0);
        }
    }
    atexit(cleanup_directories_atexit);
    //getopt_long --> 获取选项
    while ((c = getopt_long(argc, argv, "CD:F:r:RS:T:X:l:nNzZ:d:c:h:p:U:s:wWkvP",
                            long_options, &option_index)) != -1)
    {
        switch (c)//根据选项设置参数
        {
            case 'C':
                create_slot = true;
                break;
            case 'D':
                basedir = pg_strdup(optarg);
                break;
            case 'F':
                if (strcmp(optarg, "p") == 0 || strcmp(optarg, "plain") == 0)
                    format = 'p';//不压缩
                else if (strcmp(optarg, "t") == 0 || strcmp(optarg, "tar") == 0)
                    format = 't';//tar包
                else
                {
                    fprintf(stderr,
                            _("%s: invalid output format \"%s\", must be \"plain\" or \"tar\"\n"),
                            progname, optarg);
                    exit(1);
                }
                break;
            case 'r':
                maxrate = parse_max_rate(optarg);
                break;
            case 'R':
                writerecoveryconf = true;
                break;
            case 'S':
                
                replication_slot = pg_strdup(optarg);
                temp_replication_slot = false;
                break;
            case 2:
                no_slot = true;
                break;
            case 'T':
                tablespace_list_append(optarg);
                break;
            case 'X':
                if (strcmp(optarg, "n") == 0 ||
                    strcmp(optarg, "none") == 0)
                {
                    includewal = NO_WAL;
                }
                else if (strcmp(optarg, "f") == 0 ||
                         strcmp(optarg, "fetch") == 0)
                {
                    includewal = FETCH_WAL;
                }
                else if (strcmp(optarg, "s") == 0 ||
                         strcmp(optarg, "stream") == 0)
                {
                    includewal = STREAM_WAL;
                }
                else
                {
                    fprintf(stderr,
                            _("%s: invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"\n"),
                            progname, optarg);
                    exit(1);
                }
                break;
            case 1:
                xlog_dir = pg_strdup(optarg);
                break;
            case 'l':
                label = pg_strdup(optarg);
                break;
            case 'n':
                noclean = true;
                break;
            case 'N':
                do_sync = false;
                break;
            case 'z':
#ifdef HAVE_LIBZ
                compresslevel = Z_DEFAULT_COMPRESSION;
#else
                compresslevel = 1;  
#endif
                break;
            case 'Z':
                compresslevel = atoi(optarg);
                if (compresslevel < 0 || compresslevel > 9)
                {
                    fprintf(stderr, _("%s: invalid compression level \"%s\"\n"),
                            progname, optarg);
                    exit(1);
                }
                break;
            case 'c':
                if (pg_strcasecmp(optarg, "fast") == 0)
                    fastcheckpoint = true;
                else if (pg_strcasecmp(optarg, "spread") == 0)
                    fastcheckpoint = false;
                else
                {
                    fprintf(stderr, _("%s: invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"\n"),
                            progname, optarg);
                    exit(1);
                }
                break;
            case 'd':
                connection_string = pg_strdup(optarg);
                break;
            case 'h':
                dbhost = pg_strdup(optarg);
                break;
            case 'p':
                dbport = pg_strdup(optarg);
                break;
            case 'U':
                dbuser = pg_strdup(optarg);
                break;
            case 'w':
                dbgetpassword = -1;
                break;
            case 'W':
                dbgetpassword = 1;
                break;
            case 's':
                standby_message_timeout = atoi(optarg) * 1000;
                if (standby_message_timeout < 0)
                {
                    fprintf(stderr, _("%s: invalid status interval \"%s\"\n"),
                            progname, optarg);
                    exit(1);
                }
                break;
            case 'v':
                verbose++;
                break;
            case 'P':
                showprogress = true;
                break;
            case 3:
                verify_checksums = false;
                break;
            default:
                
                fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
                        progname);
                exit(1);
        }
    }
    
    if (optind < argc)
    {
        fprintf(stderr,
                _("%s: too many command-line arguments (first is \"%s\")\n"),
                progname, argv[optind]);
        fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
                progname);
        exit(1);
    }
    
    if (basedir == NULL)
    {
        fprintf(stderr, _("%s: no target directory specified\n"), progname);
        fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
                progname);
        exit(1);
    }
    
    if (format == 'p' && compresslevel != 0)
    {
        fprintf(stderr,
                _("%s: only tar mode backups can be compressed\n"),
                progname);
        fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
                progname);
        exit(1);
    }
    if (format == 't' && includewal == STREAM_WAL && strcmp(basedir, "-") == 0)
    {
        fprintf(stderr,
                _("%s: cannot stream write-ahead logs in tar mode to stdout\n"),
                progname);
        fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
                progname);
        exit(1);
    }
    if (replication_slot && includewal != STREAM_WAL)
    {
        fprintf(stderr,
                _("%s: replication slots can only be used with WAL streaming\n"),
                progname);
        fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
                progname);
        exit(1);
    }
    if (no_slot)
    {
        if (replication_slot)
        {
            fprintf(stderr,
                    _("%s: --no-slot cannot be used with slot name\n"),
                    progname);
            fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
                    progname);
            exit(1);
        }
        temp_replication_slot = false;
    }
    if (create_slot)
    {
        if (!replication_slot)
        {
            fprintf(stderr,
                    _("%s: %s needs a slot to be specified using --slot\n"),
                    progname, "--create-slot");
            fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
                    progname);
            exit(1);
        }
        if (no_slot)
        {
            fprintf(stderr,
                    _("%s: --create-slot and --no-slot are incompatible options\n"),
                    progname);
            fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
                    progname);
            exit(1);
        }
    }
    if (xlog_dir)
    {
        if (format != 'p')
        {
            fprintf(stderr,
                    _("%s: WAL directory location can only be specified in plain mode\n"),
                    progname);
            fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
                    progname);
            exit(1);
        }
        
        canonicalize_path(xlog_dir);
        if (!is_absolute_path(xlog_dir))
        {
            fprintf(stderr, _("%s: WAL directory location must be "
                              "an absolute path\n"), progname);
            fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
                    progname);
            exit(1);
        }
    }
#ifndef HAVE_LIBZ
    if (compresslevel != 0)
    {
        fprintf(stderr,
                _("%s: this build does not support compression\n"),
                progname);
        exit(1);
    }
#endif
    
    //以复制模式连接到数据库
    conn = GetConnection();
    if (!conn)
    {
        
        //连接不成功
        exit(1);
    }
    atexit(disconnect_atexit);
    
    umask(pg_mode_mask);
    
    if (format == 'p' || strcmp(basedir, "-") != 0)
        verify_dir_is_empty_or_create(basedir, &made_new_pgdata, &found_existing_pgdata);
    
    //确定远程服务器的xlog segment大小
    if (!RetrieveWalSegSize(conn))
        exit(1);
    
    //如需要,创建pg_wal目录链接
    if (xlog_dir)
    {
        char       *linkloc;
        //
        verify_dir_is_empty_or_create(xlog_dir, &made_new_xlogdir, &found_existing_xlogdir);
        
        linkloc = psprintf("%s/%s", basedir,
                           PQserverVersion(conn) < MINIMUM_VERSION_FOR_PG_WAL ?
                           "pg_xlog" : "pg_wal");
#ifdef HAVE_SYMLINK
        if (symlink(xlog_dir, linkloc) != 0)
        {
            fprintf(stderr, _("%s: could not create symbolic link \"%s\": %s\n"),
                    progname, linkloc, strerror(errno));
            exit(1);
        }
#else
        fprintf(stderr, _("%s: symlinks are not supported on this platform\n"), progname);
        exit(1);
#endif
        free(linkloc);
    }
    //执行备份
    BaseBackup();
    //成功标记
    success = true;
    return 0;
}

void
set_pglocale_pgservice(const char *argv0, const char *app)
{
    char        path[MAXPGPATH];
    char        my_exec_path[MAXPGPATH];
    char        env_path[MAXPGPATH + sizeof("PGSYSCONFDIR=")];  
    char       *dup_path;
    
    //不要在后台进程中设置LC_ALL
    if (strcmp(app, PG_TEXTDOMAIN("postgres")) != 0)
    {
        setlocale(LC_ALL, "");
        
    }
    if (find_my_exec(argv0, my_exec_path) < 0)
        return;
#ifdef ENABLE_NLS
    get_locale_path(my_exec_path, path);
    bindtextdomain(app, path);
    textdomain(app);
    if (getenv("PGLOCALEDIR") == NULL)
    {
        //------ PGLOCALEDIR
        
        //设置libpq
        snprintf(env_path, sizeof(env_path), "PGLOCALEDIR=%s", path);
        canonicalize_path(env_path + 12);
        dup_path = strdup(env_path);
        if (dup_path)
            putenv(dup_path);
    }
#endif
    if (getenv("PGSYSCONFDIR") == NULL)
    {
        //---- PGSYSCONFDIR
        get_etc_path(my_exec_path, path);
        
        snprintf(env_path, sizeof(env_path), "PGSYSCONFDIR=%s", path);
        canonicalize_path(env_path + 13);
        dup_path = strdup(env_path);
        if (dup_path)
            putenv(dup_path);
    }
}

到此,相信大家对“PostgreSQL的备份工具pg_basebackup源码中的主函数分析”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

您可能感兴趣的文档:

--结束END--

本文标题: PostgreSQL的备份工具pg_basebackup源码中的主函数分析

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

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

猜你喜欢
  • PostgreSQL的备份工具pg_basebackup源码中的主函数分析
    本篇内容主要讲解“PostgreSQL的备份工具pg_basebackup源码中的主函数分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“PostgreSQL的...
    99+
    2024-04-02
  • PostgreSQL中的ProcessRepliesIfAny函数分析
    本篇内容主要讲解“PostgreSQL中的ProcessRepliesIfAny函数分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“PostgreSQL中的P...
    99+
    2024-04-02
  • 分析PostgreSQL CreateFunction中的interpret_function_parameter_list函数
    这篇文章主要介绍“分析PostgreSQL CreateFunction中的interpret_function_parameter_list函数”,在日常操作中,相信很多人在分析PostgreSQL Cr...
    99+
    2024-04-02
  • 分析PostgreSQL CreateFunction中的ProcedureCreate函数
    本篇内容介绍了“分析PostgreSQL CreateFunction中的ProcedureCreate函数”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何...
    99+
    2024-04-02
  • PostgreSQL的vacuum过程中heap_vacuum_rel函数分析
    这篇文章主要介绍“PostgreSQL的vacuum过程中heap_vacuum_rel函数分析”,在日常操作中,相信很多人在PostgreSQL的vacuum过程中heap_vacuum_rel函数分析问...
    99+
    2024-04-02
  • 35个JS中实用工具函数的代码分享
    目录1.Js天数相加获取新日期2.获取当前日期(yyyyMMdd格式)3.四舍五入4.Js将数字转成中文大写数字5.判断数据是否为空6.字符串日期比较7.验证邮件8.判断是否为日期数...
    99+
    2024-04-02
  • PHP 函数的性能分析工具有哪些?
    php 函数性能分析工具有助于识别瓶颈并改进代码。本文介绍了 xhprof(采样剖析)、tideways(商业平台)和 blackfire.io(saas 服务);实战案例展示了使用 x...
    99+
    2024-04-18
    php 性能分析工具
  • PostgreSQL中query_planner函数的处理逻辑分析
    这篇文章主要介绍“PostgreSQL中query_planner函数的处理逻辑分析”,在日常操作中,相信很多人在PostgreSQL中query_planner函数的处理逻辑分析问题上存在疑惑,小编查阅了...
    99+
    2024-04-02
  • Python的三大开源数据分析工具是什么
    本文小编为大家详细介绍“Python的三大开源数据分析工具是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“Python的三大开源数据分析工具是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。在大数据库领域...
    99+
    2023-06-02
  • NumPy库中的矩阵运算:优化Python数据分析的必备工具
    在Python数据分析领域,矩阵运算是非常重要的一环。NumPy库是Python中最常用的科学计算库之一,它提供了丰富的矩阵运算功能,可以极大地优化Python数据分析的效率。本文将介绍NumPy库中的矩阵运算功能,以及如何使用它们来优化...
    99+
    2023-11-09
    同步 numy 日志
  • 分析 C++ 函数性能的常用工具有哪些?
    c++++ 函数性能分析工具汇总:gprof:分析函数调用图、运行时间和调用频率。valgrind:检测内存错误和性能问题,分析函数调用、内存分配和缓存命中率。perf:收集和分析性能数...
    99+
    2024-04-18
    c++ 性能分析 linux
  • golang 函数调试和分析工具的适用范围
    go 函数调试和分析工具的适用范围包括:调试工具(delve、gdb)、分析工具(pprof、pprof.io、gocover)。这些工具可用于解决死锁问题(使用 delve 逐步执行并...
    99+
    2024-05-07
    分析 golang debug
  • 互联网中著名的开源分析工具有哪些
    这篇文章主要为大家展示了“互联网中著名的开源分析工具有哪些”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“互联网中著名的开源分析工具有哪些”这篇文章吧。著名的开源分析工具包括r语言、python、...
    99+
    2023-06-29
  • BlueHost Linux主机创建数据完全备份的示例分析
    这篇文章主要为大家展示了“BlueHost Linux主机创建数据完全备份的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“BlueHost Linux主机创建数据完全备份的示例分析”这篇...
    99+
    2023-06-05
  • PHP中封装性的静态代码分析工具
    引言:随着Web应用的不断发展,PHP已经成为了一种广泛使用的编程语言。然而,由于PHP语言的灵活性和简易性,很容易写出复杂、难以维护的代码。为了解决这个问题,开发人员经常需要使用静态代码分析工具来检测潜在的问题和提供最佳实践建议。本文将介...
    99+
    2023-10-21
    PHP 封装性 静态代码分析
  • PostgreSQL物理优化中的create_index_paths->generate_bitmap_or_paths函数分析
    这篇文章主要讲解了“PostgreSQL物理优化中的create_index_paths->generate_bitmap_or_paths函数分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大...
    99+
    2024-04-02
  • PostgreSQL物理优化中的create_index_paths->choose_bitmap_and函数分析
    这篇文章主要讲解了“PostgreSQL物理优化中的create_index_paths->choose_bitmap_and函数分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思...
    99+
    2024-04-02
  • 主键与外键:数据库设计中的必备工具
    ...
    99+
    2024-04-02
  • 微信小程序工具函数封装的示例分析
    这篇文章主要介绍微信小程序工具函数封装的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!具体内容如下const formatTime = date...
    99+
    2024-04-02
  • golang 函数调试与分析工具的陷阱与回避
    Go 函数调试与分析工具的陷阱与规避 在 Go 应用程序中进行调试和分析时,有许多有用的工具可供使用,例如:pprof、gotrace和go tool trace。然而,这些工具的使用...
    99+
    2024-05-06
    调试 golang
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作