Bypass recovery checks with older servers. This is required for Greenplum which is based on PG 8.3 at present.

pull/3/head
Atira Odhner 2017-01-30 17:02:55 +00:00 committed by Dave Page
parent 30e546208f
commit c6b67fc66a
11 changed files with 75 additions and 61 deletions

View File

@ -44,6 +44,19 @@ def has_any(data, keys):
return False return False
def recovery_state(connection, postgres_version):
recovery_check_sql = render_template("connect/sql/#{0}#/check_recovery.sql".format(postgres_version))
status, result = connection.execute_dict(recovery_check_sql)
if status:
in_recovery = result['rows'][0]['inrecovery']
wal_paused = result['rows'][0]['isreplaypaused']
else:
in_recovery = None
wal_paused = None
return in_recovery, wal_paused
class ServerModule(sg.ServerGroupPluginModule): class ServerModule(sg.ServerGroupPluginModule):
NODE_TYPE = "server" NODE_TYPE = "server"
LABEL = gettext("Servers") LABEL = gettext("Servers")
@ -74,21 +87,7 @@ class ServerModule(sg.ServerGroupPluginModule):
in_recovery = None in_recovery = None
wal_paused = None wal_paused = None
if connected: if connected:
status, result = conn.execute_dict(""" in_recovery, wal_paused = recovery_state(conn, manager.version)
SELECT CASE WHEN usesuper
THEN pg_is_in_recovery()
ELSE FALSE
END as inrecovery,
CASE WHEN usesuper AND pg_is_in_recovery()
THEN pg_is_xlog_replay_paused()
ELSE FALSE
END as isreplaypaused
FROM pg_user WHERE usename=current_user""")
if len(result['rows']):
in_recovery = result['rows'][0]['inrecovery']
wal_paused = result['rows'][0]['isreplaypaused']
yield self.generate_browser_node( yield self.generate_browser_node(
"%d" % (server.id), "%d" % (server.id),
gid, gid,
@ -231,19 +230,7 @@ class ServerNode(PGChildNodeView):
connected = conn.connected() connected = conn.connected()
if connected: if connected:
status, result = conn.execute_dict(""" in_recovery, wal_paused = recovery_state(conn, manager.version)
SELECT CASE WHEN usesuper
THEN pg_is_in_recovery()
ELSE FALSE
END as inrecovery,
CASE WHEN usesuper AND pg_is_in_recovery()
THEN pg_is_xlog_replay_paused()
ELSE FALSE
END as isreplaypaused
FROM pg_user WHERE usename=current_user""")
in_recovery = result['rows'][0]['inrecovery'];
wal_paused = result['rows'][0]['isreplaypaused']
else: else:
in_recovery = None in_recovery = None
wal_paused = None wal_paused = None
@ -274,6 +261,7 @@ class ServerNode(PGChildNodeView):
return make_json_response(result=res) return make_json_response(result=res)
def node(self, gid, sid): def node(self, gid, sid):
"""Return a JSON document listing the server groups for the user""" """Return a JSON document listing the server groups for the user"""
server = Server.query.filter_by(user_id=current_user.id, server = Server.query.filter_by(user_id=current_user.id,
@ -296,19 +284,7 @@ class ServerNode(PGChildNodeView):
connected = conn.connected() connected = conn.connected()
if connected: if connected:
status, result = conn.execute_dict(""" in_recovery, wal_paused = recovery_state(conn, manager.version)
SELECT CASE WHEN usesuper
THEN pg_is_in_recovery()
ELSE FALSE
END as inrecovery,
CASE WHEN usesuper AND pg_is_in_recovery()
THEN pg_is_xlog_replay_paused()
ELSE FALSE
END as isreplaypaused
FROM pg_user WHERE usename=current_user""")
in_recovery = result['rows'][0]['inrecovery'];
wal_paused = result['rows'][0]['isreplaypaused']
else: else:
in_recovery = None in_recovery = None
wal_paused = None wal_paused = None
@ -849,22 +825,7 @@ class ServerNode(PGChildNodeView):
current_app.logger.info('Connection Established for server: \ current_app.logger.info('Connection Established for server: \
%s - %s' % (server.id, server.name)) %s - %s' % (server.id, server.name))
# Update the recovery and wal pause option for the server if connected successfully # Update the recovery and wal pause option for the server if connected successfully
status, result = conn.execute_dict(""" in_recovery, wal_paused = recovery_state(conn, manager.version)
SELECT CASE WHEN usesuper
THEN pg_is_in_recovery()
ELSE FALSE
END as inrecovery,
CASE WHEN usesuper AND pg_is_in_recovery()
THEN pg_is_xlog_replay_paused()
ELSE FALSE
END as isreplaypaused
FROM pg_user WHERE usename=current_user""")
if status:
in_recovery = result['rows'][0]['inrecovery'];
wal_paused = result['rows'][0]['isreplaypaused']
else:
in_recovery = None
wal_paused = None
return make_json_response( return make_json_response(
success=1, success=1,

View File

@ -0,0 +1 @@
SELECT FALSE as inrecovery, FALSE as isreplaypaused;

View File

@ -0,0 +1,9 @@
SELECT CASE WHEN usesuper
THEN pg_is_in_recovery()
ELSE FALSE
END as inrecovery,
CASE WHEN usesuper AND pg_is_in_recovery()
THEN pg_is_xlog_replay_paused()
ELSE FALSE
END as isreplaypaused
FROM pg_user WHERE usename=current_user

View File

@ -0,0 +1,33 @@
import os
from pgadmin.utils.route import BaseTestGenerator
from regression import test_utils
class TestCheckRecovery(BaseTestGenerator):
versions_to_test = ["8.3_plus", "9.0_plus"]
def runTest(self):
cursor = test_utils.get_db_connection(self.server['db'],
self.server['username'],
self.server['db_password'],
self.server['host'],
self.server['port']).cursor()
for version in self.versions_to_test:
template_file = os.path.join(os.path.dirname(__file__), "..", version, "check_recovery.sql")
cursor.execute(open(template_file, 'r').read())
fetch_result = cursor.fetchall()
first_row = {}
for index, description in enumerate(cursor.description):
first_row[description.name] = fetch_result[0][index]
in_recovery = first_row['inrecovery']
wal_paused = first_row['isreplaypaused']
self.assertEqual(False, in_recovery)
self.assertEqual(False, wal_paused)

View File

@ -346,9 +346,7 @@ class PGChildNodeView(NodeView):
""" """
# Set the sql_path # Set the sql_path
sql_path = '' sql_path = 'depends/sql/#{0}#'.format(conn.manager.version)
if conn.manager.version >= 90100:
sql_path = 'depends/sql/9.1_plus'
if where is None: if where is None:
where_clause = "WHERE dep.objid={0}::oid".format(object_id) where_clause = "WHERE dep.objid={0}::oid".format(object_id)

View File

@ -2,6 +2,7 @@ import os
from flask import Flask from flask import Flask
from jinja2 import FileSystemLoader from jinja2 import FileSystemLoader
from jinja2 import TemplateNotFound
from pgadmin import VersionedTemplateLoader from pgadmin import VersionedTemplateLoader
from pgadmin.utils.route import BaseTestGenerator from pgadmin.utils.route import BaseTestGenerator
@ -35,11 +36,19 @@ class TestVersionedTemplateLoader(BaseTestGenerator):
self.assertIn("some_feature/sql/9.1_plus/some_action.sql", filename) self.assertIn("some_feature/sql/9.1_plus/some_action.sql", filename)
def test_get_source_when_the_version_is_9_3_and_there_are_templates_for_9_2_and_9_1_returns_9_2_template(self): def test_get_source_when_the_version_is_9_3_and_there_are_templates_for_9_2_and_9_1_returns_9_2_template(self):
content, filename, up_to_dateness = self.loader.get_source(None, "some_feature/sql/#90300#/some_action.sql") content, filename, up_to_dateness = self.loader.get_source(None, "some_feature/sql/#90300#/some_action.sql")
self.assertEqual("Some 9.2 SQL", content) self.assertEqual("Some 9.2 SQL", content)
self.assertIn("some_feature/sql/9.2_plus/some_action.sql", filename) self.assertIn("some_feature/sql/9.2_plus/some_action.sql", filename)
def test_raise_not_found_exception_when_postgres_version_less_than_all_available_sql_templates(self):
try:
self.loader.get_source(None, "some_feature/sql/#10100#/some_action.sql")
self.fail("No exception raised")
except TemplateNotFound, e:
return
class FakeApp(Flask): class FakeApp(Flask):
def __init__(self): def __init__(self):

View File

@ -12,7 +12,9 @@ class VersionedTemplateLoader(DispatchingJinjaLoader):
{'name': "9.4_plus", 'number': 90400}, {'name': "9.4_plus", 'number': 90400},
{'name': "9.3_plus", 'number': 90300}, {'name': "9.3_plus", 'number': 90300},
{'name': "9.2_plus", 'number': 90200}, {'name': "9.2_plus", 'number': 90200},
{'name': "9.1_plus", 'number': 90100} {'name': "9.1_plus", 'number': 90100},
{'name': "9.0_plus", 'number': 90000},
{'name': "8.3_plus", 'number': 80300}
) )
if len(template_path_parts) == 1: if len(template_path_parts) == 1:
@ -29,3 +31,4 @@ class VersionedTemplateLoader(DispatchingJinjaLoader):
return super(VersionedTemplateLoader, self).get_source(environment, template_path) return super(VersionedTemplateLoader, self).get_source(environment, template_path)
except TemplateNotFound: except TemplateNotFound:
continue continue
raise TemplateNotFound(template)