Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added possibility to execute after_commands on master nodes #9

Open
wants to merge 1 commit into
base: REL1_0_STABLE
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pg_keeper 1.0
pg_keeper 1.1
===========

pg_keeper is a simplified clustering module for PostgreSQL, to promote a standby server to master in a 2 servers cluster.
Expand Down Expand Up @@ -51,10 +51,15 @@ Note that the parameters with (*) are mandatory options.

- Specifies how many times pg_keeper try polling to master server in order to promote standby server. 4 times by default.

- pg_keeper.after_command
- pg_keeper.master_after_command

- Specifies shell command that will be called after connection to standby is lost.

- pg_keeper.standby_after_command

- Specifies shell command that will be called after promoted. Setting stonith command to this parameter is useful for preventing the split-brain syndrome.


## Tested platforms
pg_keeper has been built and tested on following platforms:

Expand Down
3 changes: 3 additions & 0 deletions master.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,9 @@ KeeperMainMaster(void)
*/
updateStatus(KEEPER_MASTER_ASYNC);
standby_connected = false;
/* If after command is given, execute it */
if (pgkeeper_master_after_command)
doAfterCommand(pgkeeper_master_after_command);
}
}
/* nothing to do if in async mode */
Expand Down
43 changes: 40 additions & 3 deletions pg_keeper.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ int pgkeeper_keepalives_time;
int pgkeeper_keepalives_count;
char *pgkeeper_partner_conninfo;
char *pgkeeper_my_conninfo;
char *pgkeeper_master_after_command;
char *pgkeeper_standby_after_command;

KeeperShmem *keeperShmem;

Expand Down Expand Up @@ -122,10 +124,21 @@ _PG_init(void)
NULL,
NULL);

DefineCustomStringVariable("pg_keeper.after_command",
"Shell command that will be called after promoted",
DefineCustomStringVariable("pg_keeper.master_after_command",
"Shell command that will be called after master loses standby connection",
NULL,
&pgkeeper_after_command,
&pgkeeper_master_after_command,
NULL,
PGC_SIGHUP,
GUC_NOT_IN_SAMPLE,
NULL,
NULL,
NULL);

DefineCustomStringVariable("pg_keeper.standby_after_command",
"Shell command that will be called after standby is promoted",
NULL,
&pgkeeper_standby_after_command,
NULL,
PGC_SIGHUP,
GUC_NOT_IN_SAMPLE,
Expand Down Expand Up @@ -396,3 +409,27 @@ updateStatus(KeeperStatus status)
/* Then, update process title */
set_ps_display(getStatusPsString(status), false);
}

/*
* Attempt to execute an external shell command after promotion.
*/
void
doAfterCommand(const char *command)
{
int rc;

Assert(command);

ereport(LOG,
(errmsg("executing after command \"%s\"",
command)));

rc = system(command);

if (rc != 0)
{
ereport(LOG,
(errmsg("failed to execute after command \"%s\"",
command)));
}
}
4 changes: 3 additions & 1 deletion pg_keeper.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ sig_atomic_t got_sighup;
sig_atomic_t got_sigterm;

extern void updateStatus(KeeperStatus status);
extern void doAfterCommand(const char *command);

/* master.c */
extern bool KeeperMainMaster(void);
Expand All @@ -72,4 +73,5 @@ extern int pgkeeper_keepalives_time;
extern int pgkeeper_keepalives_count;
extern char *pgkeeper_partner_conninfo;
extern char *pgkeeper_my_conninfo;
extern char *pgkeeper_after_command;
extern char *pgkeeper_standby_after_command;
extern char *pgkeeper_master_after_command;
33 changes: 2 additions & 31 deletions standby.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,6 @@ bool KeeperMainStandby(void);
void setupKeeperStandby(void);

static void doPromote(void);
static void doAfterCommand(void);

/* GUC variables */
char *pgkeeper_after_command;

/* Variables for heartbeat */
static int retry_count;
Expand Down Expand Up @@ -130,8 +126,8 @@ KeeperMainStandby(void)
doPromote();

/* If after command is given, execute it */
if (pgkeeper_after_command)
doAfterCommand();
if (pgkeeper_standby_after_command)
doAfterCommand(pgkeeper_standby_after_command);

return true;
}
Expand Down Expand Up @@ -169,28 +165,3 @@ doPromote(void)
ereport(LOG,
(errmsg("pg_keeper promoted standby server to primary server")));
}

/*
* Attempt to execute an external shell command after promotion.
*/
static void
doAfterCommand(void)
{
int rc;

Assert(pgkeeper_after_command);

ereport(LOG,
(errmsg("executing after promoting command \"%s\"",
pgkeeper_after_command)));

rc = system(pgkeeper_after_command);

if (rc != 0)
{
ereport(LOG,
(errmsg("failed to execute after promoting command \"%s\"",
pgkeeper_after_command)));
}
}