Hi,

This patch adds support for pause/resume functions on a hotstandby
server via two new service factory for servers. Quite simple actually.
Patch attached.

Comments?


-- 
Guillaume
 http://www.postgresql.fr
 http://dalibo.com
>From 966088d0821c2b97d83a8fa23aa0ecff8f5f145f Mon Sep 17 00:00:00 2001
From: Guillaume Lelarge <guilla...@lelarge.info>
Date: Sun, 13 Mar 2011 01:36:05 +0100
Subject: [PATCH] Add support for basic recovery control functions

A "in recovery" server has two new commands: pause recovery and resume
recovery.
---
 pgadmin/frm/frmMain.cpp           |    2 +
 pgadmin/include/schema/pgServer.h |   29 +++++++++++++-
 pgadmin/schema/pgServer.cpp       |   81 +++++++++++++++++++++++++++++++++++++
 3 files changed, 111 insertions(+), 1 deletions(-)

diff --git a/pgadmin/frm/frmMain.cpp b/pgadmin/frm/frmMain.cpp
index 3883043..5edc48d 100644
--- a/pgadmin/frm/frmMain.cpp
+++ b/pgadmin/frm/frmMain.cpp
@@ -345,6 +345,8 @@ void frmMain::CreateMenus()
 	new startServiceFactory(menuFactories, toolsMenu, 0);
 	new stopServiceFactory(menuFactories, toolsMenu, 0);
 	new reloadconfServiceFactory(menuFactories, toolsMenu, 0);
+	new pausereplayServiceFactory(menuFactories, toolsMenu, 0);
+	new resumereplayServiceFactory(menuFactories, toolsMenu, 0);
 
 	new createFactory(menuFactories, editMenu, toolBar);
 	new dropFactory(menuFactories, editMenu, toolBar);
diff --git a/pgadmin/include/schema/pgServer.h b/pgadmin/include/schema/pgServer.h
index c32163e..441c412 100644
--- a/pgadmin/include/schema/pgServer.h
+++ b/pgadmin/include/schema/pgServer.h
@@ -64,6 +64,9 @@ public:
 	bool GetServerRunning();
 	bool GetServerControllable();
 	bool ReloadConfiguration();
+	bool IsReplayPaused();
+	bool PauseReplay();
+	bool ResumeReplay();
 
 	pgServer *GetServer() const;
 
@@ -152,6 +155,14 @@ public:
 	{
 		inRecovery = b;
 	}
+	bool GetReplayPaused() const
+	{
+		return replayPaused;
+	}
+	void SetReplayPaused(const bool b)
+	{
+		replayPaused = b;
+	}
 	wxDateTime GetConfLoadedSince()
 	{
 		return confLoadedSince;
@@ -418,7 +429,7 @@ private:
 	wxString group;
 	wxString sslcert, sslkey, sslrootcert, sslcrl;
 
-	bool inRecovery;
+	bool inRecovery, replayPaused;
 	wxString receiveLoc, replayLoc, replayTimestamp;
 	wxDateTime confLoadedSince;
 
@@ -540,4 +551,20 @@ public:
 	bool CheckEnable(pgObject *obj);
 };
 
+class pausereplayServiceFactory : public contextActionFactory
+{
+public:
+	pausereplayServiceFactory (menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar);
+	wxWindow *StartDialog(frmMain *form, pgObject *obj);
+	bool CheckEnable(pgObject *obj);
+};
+
+class resumereplayServiceFactory : public contextActionFactory
+{
+public:
+	resumereplayServiceFactory (menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar);
+	wxWindow *StartDialog(frmMain *form, pgObject *obj);
+	bool CheckEnable(pgObject *obj);
+};
+
 #endif
diff --git a/pgadmin/schema/pgServer.cpp b/pgadmin/schema/pgServer.cpp
index 4facef8..a0fb835 100644
--- a/pgadmin/schema/pgServer.cpp
+++ b/pgadmin/schema/pgServer.cpp
@@ -729,6 +729,7 @@ int pgServer::Connect(frmMain *form, bool askPassword, const wxString &pwd, bool
 		if (conn->BackendMinimumVersion(9, 1))
 		{
 			sql += wxT(", CASE WHEN usesuper THEN pg_last_xact_replay_timestamp() ELSE NULL END as replay_timestamp");
+			sql += wxT(", CASE WHEN usesuper AND pg_is_in_recovery() THEN pg_is_xlog_replay_paused() ELSE NULL END as isreplaypaused");
 		}
 
 		pgSet *set = ExecuteSet(sql + wxT("\n  FROM pg_user WHERE usename=current_user"));
@@ -749,6 +750,7 @@ int pgServer::Connect(frmMain *form, bool askPassword, const wxString &pwd, bool
 			if (conn->BackendMinimumVersion(9, 1))
 			{
 				iSetReplayTimestamp(set->GetVal(wxT("replay_timestamp")));
+				SetReplayPaused(set->GetBool(wxT("isreplaypaused")));
 			}
 			delete set;
 		}
@@ -1058,6 +1060,10 @@ void pgServer::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *prop
 			if (conn->BackendMinimumVersion(9, 1))
 			{
 				properties->AppendItem(_("Last XACT replay timestamp"), GetReplayTimestamp());
+				if (GetInRecovery())
+					properties->AppendItem(_("Replay paused"), (GetReplayPaused() ? _("paused") : _("running")));
+				else
+					properties->AppendItem(_("Replay paused"), wxEmptyString);
 			}
 		}
 		if (GetServerControllable())
@@ -1151,6 +1157,7 @@ void pgServer::ShowDependents(frmMain *form, ctlListView *referencedBy, const wx
 	referencedBy->AddColumn(_("Restriction"), 50);
 }
 
+
 bool pgServer::ReloadConfiguration()
 {
 	wxString sql = wxT("select pg_reload_conf()");
@@ -1158,6 +1165,22 @@ bool pgServer::ReloadConfiguration()
 }
 
 
+bool pgServer::PauseReplay()
+{
+	SetReplayPaused(true);
+	wxString sql = wxT("SELECT pg_xlog_replay_pause()");
+	return conn->ExecuteVoid(sql);
+}
+
+
+bool pgServer::ResumeReplay()
+{
+	SetReplayPaused(false);
+	wxString sql = wxT("SELECT pg_xlog_replay_resume()");
+	return conn->ExecuteVoid(sql);
+}
+
+
 pgServerCollection::pgServerCollection(pgaFactory *factory)
 	: pgCollection(factory)
 {
@@ -1830,3 +1853,61 @@ bool reloadconfServiceFactory::CheckEnable(pgObject *obj)
 	return false;
 }
 
+pausereplayServiceFactory::pausereplayServiceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list)
+{
+	mnu->Append(id, _("Pause replay of WAL"), _("Pause replay of WAL"));
+}
+
+
+wxWindow *pausereplayServiceFactory::StartDialog(frmMain *form, pgObject *obj)
+{
+	pgServer *server = (pgServer *)obj;
+	form->StartMsg(_("Pausing replay of WAL"));
+	bool rc = server->PauseReplay();
+	form->EndMsg(rc);
+	return 0;
+}
+
+
+bool pausereplayServiceFactory::CheckEnable(pgObject *obj)
+{
+	if (obj && obj->IsCreatedBy(serverFactory))
+	{
+		pgServer *server = (pgServer *)obj;
+		return server->GetConnected() &&
+               server->connection()->BackendMinimumVersion(9, 1) &&
+               server->GetInRecovery() &&
+			   !server->GetReplayPaused();
+	}
+	return false;
+}
+
+resumereplayServiceFactory::resumereplayServiceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list)
+{
+	mnu->Append(id, _("Resume replay of WAL"), _("Resume replay of WAL"));
+}
+
+
+wxWindow *resumereplayServiceFactory::StartDialog(frmMain *form, pgObject *obj)
+{
+	pgServer *server = (pgServer *)obj;
+	form->StartMsg(_("Resuming replay of WAL"));
+	bool rc = server->ResumeReplay();
+	form->EndMsg(rc);
+	return 0;
+}
+
+
+bool resumereplayServiceFactory::CheckEnable(pgObject *obj)
+{
+	if (obj && obj->IsCreatedBy(serverFactory))
+	{
+		pgServer *server = (pgServer *)obj;
+		return server->GetConnected() &&
+               server->connection()->BackendMinimumVersion(9, 1) &&
+               server->GetInRecovery() &&
+			   server->GetReplayPaused();
+	}
+	return false;
+}
+
-- 
1.7.1

-- 
Sent via pgadmin-hackers mailing list (pgadmin-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers

Reply via email to