首页 > 解决方案 > 在数据目录从 PostgreSQL 8.4.8 升级到 PostgreSQL 9.5.2 期间,日志(很少)出现两次

问题描述

我正在处理在 Windows 操作系统上升级 PostgreSQL 期间发生的cannot write to log...错误(在链接中描述)。这些答案都没有帮助我。在调试这个问题时,我注意到升级成功后,登录pg_upgrade_internal.log显示如下:

Running in verbose mode

-----------------------------------------------------------------
  pg_upgrade run on Mon Nov 27 10:03:23 2017
-----------------------------------------------------------------

Running in verbose mode

-----------------------------------------------------------------
  pg_upgrade run on Mon Nov 27 10:03:23 2017
-----------------------------------------------------------------

Performing Consistency Checks
-----------------------------

....

如果你注意到,Running in .. pg_upgrade run...出现两次。所以,我尝试查看PostgreSQL 9.5.2. 这些日志似乎是从void parseCommandLine(int argc, char *argv[])文件\src\bin\pg_upgrade\option.c链接)的功能写入的。以下是来自的源代码PostgreSQL 9.5.2

/*
 * parseCommandLine()
 *
 *  Parses the command line (argc, argv[]) and loads structures
 */
void
parseCommandLine(int argc, char *argv[])
{
    static struct option long_options[] = {
        {"old-datadir", required_argument, NULL, 'd'},
        {"new-datadir", required_argument, NULL, 'D'},
        {"old-bindir", required_argument, NULL, 'b'},
        {"new-bindir", required_argument, NULL, 'B'},
        {"old-options", required_argument, NULL, 'o'},
        {"new-options", required_argument, NULL, 'O'},
        {"old-port", required_argument, NULL, 'p'},
        {"new-port", required_argument, NULL, 'P'},

        {"username", required_argument, NULL, 'U'},
        {"check", no_argument, NULL, 'c'},
        {"link", no_argument, NULL, 'k'},
        {"retain", no_argument, NULL, 'r'},
        {"jobs", required_argument, NULL, 'j'},
        {"verbose", no_argument, NULL, 'v'},
        {NULL, 0, NULL, 0}
    };
    int         option;         /* Command line option */
    int         optindex = 0;   /* used by getopt_long */
    int         os_user_effective_id;
    FILE       *fp;
    char      **filename;
    time_t      run_time = time(NULL);

    user_opts.transfer_mode = TRANSFER_MODE_COPY;

    os_info.progname = get_progname(argv[0]);

    /* Process libpq env. variables; load values here for usage() output */
    old_cluster.port = getenv("PGPORTOLD") ? atoi(getenv("PGPORTOLD")) : DEF_PGUPORT;
    new_cluster.port = getenv("PGPORTNEW") ? atoi(getenv("PGPORTNEW")) : DEF_PGUPORT;

    os_user_effective_id = get_user_info(&os_info.user);
    /* we override just the database user name;  we got the OS id above */
    if (getenv("PGUSER"))
    {
        pg_free(os_info.user);
        /* must save value, getenv()'s pointer is not stable */
        os_info.user = pg_strdup(getenv("PGUSER"));
    }

    if (argc > 1)
    {
        if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
        {
            usage();
            exit(0);
        }
        if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
        {
            puts("pg_upgrade (PostgreSQL) " PG_VERSION);
            exit(0);
        }
    }

    /* Allow help and version to be run as root, so do the test here. */
    if (os_user_effective_id == 0)
        pg_fatal("%s: cannot be run as root\n", os_info.progname);

    if ((log_opts.internal = fopen_priv(INTERNAL_LOG_FILE, "a")) == NULL)
        pg_fatal("cannot write to log file %s\n", INTERNAL_LOG_FILE);

    while ((option = getopt_long(argc, argv, "d:D:b:B:cj:ko:O:p:P:rU:v",
                                 long_options, &optindex)) != -1)
    {
        switch (option)
        {
            case 'b':
                old_cluster.bindir = pg_strdup(optarg);
                break;

            case 'B':
                new_cluster.bindir = pg_strdup(optarg);
                break;

            case 'c':
                user_opts.check = true;
                break;

            case 'd':
                old_cluster.pgdata = pg_strdup(optarg);
                old_cluster.pgconfig = pg_strdup(optarg);
                break;

            case 'D':
                new_cluster.pgdata = pg_strdup(optarg);
                new_cluster.pgconfig = pg_strdup(optarg);
                break;

            case 'j':
                user_opts.jobs = atoi(optarg);
                break;

            case 'k':
                user_opts.transfer_mode = TRANSFER_MODE_LINK;
                break;

            case 'o':
                /* append option? */
                if (!old_cluster.pgopts)
                    old_cluster.pgopts = pg_strdup(optarg);
                else
                {
                    char       *old_pgopts = old_cluster.pgopts;

                    old_cluster.pgopts = psprintf("%s %s", old_pgopts, optarg);
                    free(old_pgopts);
                }
                break;

            case 'O':
                /* append option? */
                if (!new_cluster.pgopts)
                    new_cluster.pgopts = pg_strdup(optarg);
                else
                {
                    char       *new_pgopts = new_cluster.pgopts;

                    new_cluster.pgopts = psprintf("%s %s", new_pgopts, optarg);
                    free(new_pgopts);
                }
                break;

                /*
                 * Someday, the port number option could be removed and passed
                 * using -o/-O, but that requires postmaster -C to be
                 * supported on all old/new versions (added in PG 9.2).
                 */
            case 'p':
                if ((old_cluster.port = atoi(optarg)) <= 0)
                {
                    pg_fatal("invalid old port number\n");
                    exit(1);
                }
                break;

            case 'P':
                if ((new_cluster.port = atoi(optarg)) <= 0)
                {
                    pg_fatal("invalid new port number\n");
                    exit(1);
                }
                break;

            case 'r':
                log_opts.retain = true;
                break;

            case 'U':
                pg_free(os_info.user);
                os_info.user = pg_strdup(optarg);
                os_info.user_specified = true;

                /*
                 * Push the user name into the environment so pre-9.1
                 * pg_ctl/libpq uses it.
                 */
                pg_putenv("PGUSER", os_info.user);
                break;

            case 'v':
                pg_log(PG_REPORT, "Running in verbose mode\n");
                log_opts.verbose = true;
                break;

            default:
                pg_fatal("Try \"%s --help\" for more information.\n",
                         os_info.progname);
                break;
        }
    }

    /* label start of upgrade in logfiles */
    for (filename = output_files; *filename != NULL; filename++)
    {
        if ((fp = fopen_priv(*filename, "a")) == NULL)
            pg_fatal("cannot write to log file %s\n", *filename);

        /* Start with newline because we might be appending to a file. */
        fprintf(fp, "\n"
        "-----------------------------------------------------------------\n"
                "  pg_upgrade run on %s"
                "-----------------------------------------------------------------\n\n",
                ctime(&run_time));
        fclose(fp);
    }

    /* Turn off read-only mode;  add prefix to PGOPTIONS? */
    if (getenv("PGOPTIONS"))
    {
        char       *pgoptions = psprintf("%s %s", FIX_DEFAULT_READ_ONLY,
                                         getenv("PGOPTIONS"));

        pg_putenv("PGOPTIONS", pgoptions);
        pfree(pgoptions);
    }
    else
        pg_putenv("PGOPTIONS", FIX_DEFAULT_READ_ONLY);

    /* Get values from env if not already set */
    check_required_directory(&old_cluster.bindir, NULL, "PGBINOLD", "-b",
                             "old cluster binaries reside");
    check_required_directory(&new_cluster.bindir, NULL, "PGBINNEW", "-B",
                             "new cluster binaries reside");
    check_required_directory(&old_cluster.pgdata, &old_cluster.pgconfig,
                             "PGDATAOLD", "-d", "old cluster data resides");
    check_required_directory(&new_cluster.pgdata, &new_cluster.pgconfig,
                             "PGDATANEW", "-D", "new cluster data resides");

#ifdef WIN32

    /*
     * On Windows, initdb --sync-only will fail with a "Permission denied"
     * error on file pg_upgrade_utility.log if pg_upgrade is run inside the
     * new cluster directory, so we do a check here.
     */
    {
        char        cwd[MAXPGPATH],
                    new_cluster_pgdata[MAXPGPATH];

        strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
        canonicalize_path(new_cluster_pgdata);

        if (!getcwd(cwd, MAXPGPATH))
            pg_fatal("cannot find current directory\n");
        canonicalize_path(cwd);
        if (path_is_prefix_of_path(new_cluster_pgdata, cwd))
            pg_fatal("cannot run pg_upgrade from inside the new cluster data directory on Windows\n");
    }
#endif
}

该函数parseCommandLine只调用一次,如下代码所示:

int
main(int argc, char **argv)
{
    char       *analyze_script_file_name = NULL;
    char       *deletion_script_file_name = NULL;
    bool        live_check = false;

    parseCommandLine(argc, argv);

    get_restricted_token(os_info.progname);
    ...
    return 0;
}       

谁能解释一下,这是怎么回事?为什么日志出现两次?我可能遗漏了一些非常明显的东西。

更新:

其他文件pg_upgrade_server_start.logpg_upgrade_server.logpg_upgrade_utility.log也包含重复的日志,如下所述:

-----------------------------------------------------------------
  pg_upgrade run on Mon Nov 27 10:03:23 2017
-----------------------------------------------------------------


-----------------------------------------------------------------
  pg_upgrade run on Mon Nov 27 10:03:23 2017
-----------------------------------------------------------------

标签: postgresqlpostgresql-9.5

解决方案


推荐阅读