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