On Sat, Jan 19, 2013 at 09:56:48PM -0500, Bruce Momjian wrote:
> > (But, at least with the type of packaging I'm using in Fedora, he would
> > first have to go through a package downgrade/reinstallation process,
> > because the packaging provides no simple scripted way of manually
> > starting the old postgres executable, only the new one. Moreover, what
> > pg_upgrade is printing provides no help in figuring out whether that's
> > the next step.)
> >
> > I do sympathize with taking a paranoid attitude here, but I'm failing
> > to see what advantage there is in not attempting to start the old
> > postmaster. In the *only* case that pg_upgrade is successfully
> > protecting against with this logic, namely there's-an-active-postmaster-
> > already, the postmaster is equally able to protect itself. In other
> > cases it would be more helpful not less to let the postmaster analyze
> > the situation.
> >
> > > The other problem is that if the server start fails, how do we know if
> > > the failure was due to a running postmaster?
> >
> > Because we read the postmaster's log file, or at least tell the user to
> > do so. That report would be unambiguous, unlike pg_upgrade's.
>
> Attached is a WIP patch to give you an idea of how I am going to solve
> this problem. This comment says it all:
Attached is a ready-to-apply version of the patch. I continued to use
postmaster.pid to determine if I need to try the start/stop test ---
that allows me to know which servers _might_ be running, because a
server start failure might be for many reasons and I would prefer not to
suggest the server is running if I can avoid it, and the pid file gives
me that.
The patch is longer than I expected because the code needed to be
reordered. The starting banner indicates if it a live check, but to
check for a live server we need to start/stop the servers and we needed
to know where the binaries are, and we didn't do that until after the
start banner. I removed the 'check' line for binary checks, and moved
that before the banner printing. postmaster_start also now needs an
option to supress an error.
--
Bruce Momjian <[email protected]> http://momjian.us
EnterpriseDB http://enterprisedb.com
+ It's impossible for everything to be true. +
diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c
new file mode 100644
index 1780788..8188643
*** a/contrib/pg_upgrade/check.c
--- b/contrib/pg_upgrade/check.c
*************** fix_path_separator(char *path)
*** 56,66 ****
}
void
! output_check_banner(bool *live_check)
{
! if (user_opts.check && is_server_running(old_cluster.pgdata))
{
- *live_check = true;
pg_log(PG_REPORT, "Performing Consistency Checks on Old Live Server\n");
pg_log(PG_REPORT, "------------------------------------------------\n");
}
--- 56,65 ----
}
void
! output_check_banner(bool live_check)
{
! if (user_opts.check && live_check)
{
pg_log(PG_REPORT, "Performing Consistency Checks on Old Live Server\n");
pg_log(PG_REPORT, "------------------------------------------------\n");
}
*************** check_and_dump_old_cluster(bool live_che
*** 78,84 ****
/* -- OLD -- */
if (!live_check)
! start_postmaster(&old_cluster);
set_locale_and_encoding(&old_cluster);
--- 77,83 ----
/* -- OLD -- */
if (!live_check)
! start_postmaster(&old_cluster, true);
set_locale_and_encoding(&old_cluster);
*************** issue_warnings(char *sequence_script_fil
*** 201,207 ****
/* old = PG 8.3 warnings? */
if (GET_MAJOR_VERSION(old_cluster.major_version) <= 803)
{
! start_postmaster(&new_cluster);
/* restore proper sequence values using file created from old server */
if (sequence_script_file_name)
--- 200,206 ----
/* old = PG 8.3 warnings? */
if (GET_MAJOR_VERSION(old_cluster.major_version) <= 803)
{
! start_postmaster(&new_cluster, true);
/* restore proper sequence values using file created from old server */
if (sequence_script_file_name)
*************** issue_warnings(char *sequence_script_fil
*** 224,230 ****
/* Create dummy large object permissions for old < PG 9.0? */
if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
{
! start_postmaster(&new_cluster);
new_9_0_populate_pg_largeobject_metadata(&new_cluster, false);
stop_postmaster(false);
}
--- 223,229 ----
/* Create dummy large object permissions for old < PG 9.0? */
if (GET_MAJOR_VERSION(old_cluster.major_version) <= 804)
{
! start_postmaster(&new_cluster, true);
new_9_0_populate_pg_largeobject_metadata(&new_cluster, false);
stop_postmaster(false);
}
diff --git a/contrib/pg_upgrade/exec.c b/contrib/pg_upgrade/exec.c
new file mode 100644
index e326a10..44dafc3
*** a/contrib/pg_upgrade/exec.c
--- b/contrib/pg_upgrade/exec.c
*************** exec_prog(const char *log_file, const ch
*** 140,152 ****
/*
! * is_server_running()
*
! * checks whether postmaster on the given data directory is running or not.
! * The check is performed by looking for the existence of postmaster.pid file.
*/
bool
! is_server_running(const char *datadir)
{
char path[MAXPGPATH];
int fd;
--- 140,151 ----
/*
! * pid_lock_file_exists()
*
! * Checks whether the postmaster.pid file exists.
*/
bool
! pid_lock_file_exists(const char *datadir)
{
char path[MAXPGPATH];
int fd;
*************** void
*** 180,187 ****
verify_directories(void)
{
- prep_status("Checking current, bin, and data directories");
-
#ifndef WIN32
if (access(".", R_OK | W_OK | X_OK) != 0)
#else
--- 179,184 ----
*************** verify_directories(void)
*** 194,200 ****
check_data_dir(old_cluster.pgdata);
check_bin_dir(&new_cluster);
check_data_dir(new_cluster.pgdata);
- check_ok();
}
--- 191,196 ----
diff --git a/contrib/pg_upgrade/pg_upgrade.c b/contrib/pg_upgrade/pg_upgrade.c
new file mode 100644
index a752fe8..55155d2
*** a/contrib/pg_upgrade/pg_upgrade.c
--- b/contrib/pg_upgrade/pg_upgrade.c
*************** static void prepare_new_databases(void);
*** 48,54 ****
static void create_new_objects(void);
static void copy_clog_xlog_xid(void);
static void set_frozenxids(void);
! static void setup(char *argv0, bool live_check);
static void cleanup(void);
ClusterInfo old_cluster,
--- 48,54 ----
static void create_new_objects(void);
static void copy_clog_xlog_xid(void);
static void set_frozenxids(void);
! static void setup(char *argv0, bool *live_check);
static void cleanup(void);
ClusterInfo old_cluster,
*************** main(int argc, char **argv)
*** 80,88 ****
adjust_data_dir(&old_cluster);
adjust_data_dir(&new_cluster);
! output_check_banner(&live_check);
! setup(argv[0], live_check);
check_cluster_versions();
--- 80,88 ----
adjust_data_dir(&old_cluster);
adjust_data_dir(&new_cluster);
! setup(argv[0], &live_check);
! output_check_banner(live_check);
check_cluster_versions();
*************** main(int argc, char **argv)
*** 95,101 ****
/* -- NEW -- */
! start_postmaster(&new_cluster);
check_new_cluster();
report_clusters_compatible();
--- 95,101 ----
/* -- NEW -- */
! start_postmaster(&new_cluster, true);
check_new_cluster();
report_clusters_compatible();
*************** main(int argc, char **argv)
*** 116,122 ****
/* New now using xids of the old system */
/* -- NEW -- */
! start_postmaster(&new_cluster);
prepare_new_databases();
--- 116,122 ----
/* New now using xids of the old system */
/* -- NEW -- */
! start_postmaster(&new_cluster, true);
prepare_new_databases();
*************** main(int argc, char **argv)
*** 177,183 ****
static void
! setup(char *argv0, bool live_check)
{
char exec_path[MAXPGPATH]; /* full path to my executable */
--- 177,183 ----
static void
! setup(char *argv0, bool *live_check)
{
char exec_path[MAXPGPATH]; /* full path to my executable */
*************** setup(char *argv0, bool live_check)
*** 189,203 ****
verify_directories();
! /* no postmasters should be running */
! if (!live_check && is_server_running(old_cluster.pgdata))
! pg_log(PG_FATAL, "There seems to be a postmaster servicing the old cluster.\n"
! "Please shutdown that postmaster and try again.\n");
/* same goes for the new postmaster */
! if (is_server_running(new_cluster.pgdata))
! pg_log(PG_FATAL, "There seems to be a postmaster servicing the new cluster.\n"
"Please shutdown that postmaster and try again.\n");
/* get path to pg_upgrade executable */
if (find_my_exec(argv0, exec_path) < 0)
--- 189,227 ----
verify_directories();
! /* no postmasters should be running, except for a live check */
! if (pid_lock_file_exists(old_cluster.pgdata))
! {
! /*
! * If we have a postmaster.pid file, try to start the server. If
! * it starts, the pid file was stale, so stop the server. If it
! * doesn't start, assume the server is running. If the pid file
! * is left over from a server crash, this also allows any committed
! * transactions stored in the WAL to be replayed so they are not
! * lost, because WAL files are not transfered from old to new
! * servers.
! */
! if (start_postmaster(&old_cluster, false))
! stop_postmaster(false);
! else
! {
! if (!user_opts.check)
! pg_log(PG_FATAL, "There seems to be a postmaster servicing the old cluster.\n"
! "Please shutdown that postmaster and try again.\n");
! else
! *live_check = true;
! }
! }
/* same goes for the new postmaster */
! if (pid_lock_file_exists(new_cluster.pgdata))
! {
! if (start_postmaster(&new_cluster, false))
! stop_postmaster(false);
! else
! pg_log(PG_FATAL, "There seems to be a postmaster servicing the new cluster.\n"
"Please shutdown that postmaster and try again.\n");
+ }
/* get path to pg_upgrade executable */
if (find_my_exec(argv0, exec_path) < 0)
diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h
new file mode 100644
index 70b9381..69b9c60
*** a/contrib/pg_upgrade/pg_upgrade.h
--- b/contrib/pg_upgrade/pg_upgrade.h
*************** extern OSInfo os_info;
*** 307,313 ****
/* check.c */
! void output_check_banner(bool *live_check);
void check_and_dump_old_cluster(bool live_check,
char **sequence_script_file_name);
void check_new_cluster(void);
--- 307,313 ----
/* check.c */
! void output_check_banner(bool live_check);
void check_and_dump_old_cluster(bool live_check,
char **sequence_script_file_name);
void check_new_cluster(void);
*************** exec_prog(const char *log_file, const ch
*** 341,347 ****
bool throw_error, const char *fmt,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 4, 5)));
void verify_directories(void);
! bool is_server_running(const char *datadir);
/* file.c */
--- 341,347 ----
bool throw_error, const char *fmt,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 4, 5)));
void verify_directories(void);
! bool pid_lock_file_exists(const char *datadir);
/* file.c */
*************** __attribute__((format(PG_PRINTF_ATTRIBUT
*** 429,435 ****
char *cluster_conn_opts(ClusterInfo *cluster);
! void start_postmaster(ClusterInfo *cluster);
void stop_postmaster(bool fast);
uint32 get_major_server_version(ClusterInfo *cluster);
void check_pghost_envvar(void);
--- 429,435 ----
char *cluster_conn_opts(ClusterInfo *cluster);
! bool start_postmaster(ClusterInfo *cluster, bool throw_error);
void stop_postmaster(bool fast);
uint32 get_major_server_version(ClusterInfo *cluster);
void check_pghost_envvar(void);
diff --git a/contrib/pg_upgrade/server.c b/contrib/pg_upgrade/server.c
new file mode 100644
index 0b48251..d1a3f76
*** a/contrib/pg_upgrade/server.c
--- b/contrib/pg_upgrade/server.c
*************** stop_postmaster_atexit(void)
*** 170,177 ****
}
! void
! start_postmaster(ClusterInfo *cluster)
{
char cmd[MAXPGPATH * 4 + 1000];
PGconn *conn;
--- 170,177 ----
}
! bool
! start_postmaster(ClusterInfo *cluster, bool throw_error)
{
char cmd[MAXPGPATH * 4 + 1000];
PGconn *conn;
*************** start_postmaster(ClusterInfo *cluster)
*** 236,241 ****
--- 236,244 ----
false,
"%s", cmd);
+ if (!pg_ctl_return && !throw_error)
+ return false;
+
/* Check to see if we can connect to the server; if not, report it. */
if ((conn = get_db_conn(cluster, "template1")) == NULL ||
PQstatus(conn) != CONNECTION_OK)
*************** start_postmaster(ClusterInfo *cluster)
*** 256,261 ****
--- 259,266 ----
CLUSTER_NAME(cluster));
os_info.running_cluster = cluster;
+
+ return true;
}
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers