def get_pg_stat_replication(self): '''Returns the pg_stat_replication result as a list''' if self.stdby.wait_for_walsender() == 0: raise WalReplException('Standby Replication has not started') with DbConn(utility=True, dbname='template1') as conn: return conn.execute(""" SELECT procpid, usesysid, usename, application_name, client_addr, client_port, backend_start, state, sent_location, write_location, flush_location, replay_location, sync_priority, sync_state FROM pg_stat_replication """)
def enable_replication(self, rolname=None): """ Add 'replication' lines to pg_hba. """ if rolname is None: with DbConn(utility=True) as conn: # oid = 10 is the bootstrap user. sql = 'select rolname from pg_authid where oid = 10' rolname = conn.execute(sql)[0].rolname def callback(lines): values = ['local', 'replication', rolname, 'ident'] newline = '\t'.join(values) + '\n' if newline not in lines: lines.append(newline) values = ['host', 'replication', rolname, '0.0.0.0/0', 'trust'] newline = '\t'.join(values) + '\n' if newline not in lines: lines.append(newline) return lines self.modify_pg_hba(callback) self.reload_master()
def tearDown(self): datadir = os.environ['MASTER_DATA_DIRECTORY'] pg_hba = os.path.join(datadir, 'pg_hba.conf') if os.path.exists(pg_hba + '.orig'): os.rename(pg_hba + '.orig', pg_hba) self.reload_master() with DbConn() as conn: conn.execute('drop role if exists waluser')
def createdb(self, dbname): need = False with DbConn() as conn: res = conn.execute("SELECT * FROM pg_database " "WHERE datname = '{0}'".format(dbname)) if len(res) == 0: need = True # Do it outside of the block above, as it's accessing template1. if need: PSQL.run_sql_command('CREATE DATABASE "{0}"'.format(dbname))
def test_nonsuper(self): """ Replication connection for non-super user shuold be disallowed even if pg_hba says ok. @tags sanity """ with DbConn() as conn: conn.execute('create role waluser login') self.enable_replication(rolname='waluser') with WalClient('replication=true user=waluser') as client: self.assertEqual(client.status(), pqwrap.CONNECTION_BAD)
def check_standby_processes(self): '''Check if all the standby processes are present ''' # Get hostname and data directory of standby, if any. # We could use gparray, but for now let's stay away from gppylib with DbConn(dbname='postgres') as conn: results = conn.execute(""" SELECT hostname, fselocation FROM gp_segment_configuration INNER JOIN pg_filespace_entry ON dbid = fsedbid WHERE fsefsoid = 3052 AND content = -1 AND role = 'm' """) # If standby is not configured, there must not be any standby processes. if len(results) == 0: return False host = results[0].hostname datadir = results[0].fselocation # We look for these processes that are spawned from standby postmaster. # They should have postmaster pid as ppid. We minimize remote operation # cost by getting ps output once, and search for these strings from the # output lines using regexp. process_list = [ 'master logger process', 'startup process', 'wal receiver process' ] target_process = '(' + '|'.join(process_list) + ')' postmaster_pid = walrepl.get_postmaster_pid(datadir, host) # If postmaster does not exit, child processes are not present. if postmaster_pid == -1: return False # Make it string for the later comparison postmaster_pid = str(postmaster_pid) cmd = SmartCmd('ps -e -o ppid,command | grep [p]ostgres', host=host) cmd.run() standby_processes = [] for line in cmd.get_results().stdout.splitlines(True): line = line.strip() (ppid, command) = re.split(r'\s+', line, 1) if ppid == postmaster_pid and re.search(target_process, command): standby_processes.append(line) # If we found more or less than expected, we don't know. if len(standby_processes) != len(process_list): return False tinctest.logger.info( 'All the standby processes are present at standby host' '') return True