Esempio n. 1
0
    def do_PLPERL_initialize(self):
        """ Language PL/PERL upgrade to 9.1: initialize test data  """

        gpuserRole = GpUserRole(HOST, USER, DBNAME)
        gpuserRole.createUser('pltestuser', 'NOSUPERUSER')
        gpuserRole.createUser('plsuperuser', 'SUPERUSER')
        pg_hba_path = os.path.join(os.environ.get('MASTER_DATA_DIRECTORY'),
                                   'pg_hba.conf')
        print 'pg_hba_path', pg_hba_path
        pghba_file = PgHba.PgHba(pg_hba_path)
        new_ent = PgHba.Entry(entry_type='local',
                              database=DBNAME,
                              user='******',
                              authmethod='trust')
        pghba_file.add_entry(new_ent)
        new_ent = PgHba.Entry(entry_type='local',
                              database=DBNAME,
                              user='******',
                              authmethod='trust')
        pghba_file.add_entry(new_ent)
        pghba_file.write()
        grantcmd = 'CREATE SCHEMA pltest; GRANT ALL ON SCHEMA pltest TO pltestuser;'
        cmd = PSQL(sql_cmd=grantcmd, dbname=DBNAME)
        tinctest.logger.info("Running command - %s" % cmd)
        cmd.run(validateAfter=False)
        result = cmd.get_results()
        ok = result.rc
        out = result.stdout
        if ok:
            raise Exception(
                'Grant all on schema pltest to pltestuser failed: %s' % out)
Esempio n. 2
0
 def test_sql_cmd_with_out_file_disabled(self):
     sql_cmd = "select 1"
     out_file = os.path.join(
         os.path.dirname(inspect.getfile(self.__class__)), 'test.out')
     psql = PSQL(sql_cmd=sql_cmd, out_file=out_file, output_to_file=False)
     expected_cmdstr = 'psql -a -c \"%s\"' % (sql_cmd)
     self.assertEquals(re.sub(' +', ' ', psql.cmdStr.strip()),
                       expected_cmdstr)
Esempio n. 3
0
 def test_sql_file_with_out_file_none(self):
     sql_file = os.path.join(
         os.path.dirname(inspect.getfile(self.__class__)), 'test.sql')
     out_file = sql_file.replace('.sql', '.out')
     psql = PSQL(sql_file=sql_file)
     expected_cmdstr = "psql -a -f %s &> %s 2>&1" % (sql_file, out_file)
     self.assertEquals(re.sub(' +', ' ', psql.cmdStr.strip()),
                       expected_cmdstr)
Esempio n. 4
0
 def test_sql_file_with_out_file_disabled(self):
     sql_file = os.path.join(
         os.path.dirname(inspect.getfile(self.__class__)), 'test.sql')
     out_file = os.path.join(
         os.path.dirname(inspect.getfile(self.__class__)), 'test.out')
     psql = PSQL(sql_file=sql_file, out_file=out_file, output_to_file=False)
     expected_cmdstr = "psql -a -f %s" % (sql_file)
     self.assertEquals(re.sub(' +', ' ', psql.cmdStr.strip()),
                       expected_cmdstr)
Esempio n. 5
0
 def test_psql_with_username(self):
     sql_file = os.path.join(
         os.path.dirname(inspect.getfile(self.__class__)), 'test.sql')
     psql = PSQL(sql_file=sql_file,
                 username='******',
                 output_to_file=False)
     expected_cmdstr = 'psql -U gpadmin -a -f %s' % (sql_file)
     self.assertEquals(re.sub(' +', ' ', psql.cmdStr.strip()),
                       expected_cmdstr)
Esempio n. 6
0
 def test_psql_with_pgoptions(self):
     sql_file = os.path.join(
         os.path.dirname(inspect.getfile(self.__class__)), 'test.sql')
     psql = PSQL(sql_file=sql_file,
                 PGOPTIONS="-c gp_optimizer=off",
                 output_to_file=False)
     expected_cmdstr = "PGOPTIONS=\'-c gp_optimizer=off\' psql -a -f %s" % (
         sql_file)
     self.assertEquals(re.sub(' +', ' ', psql.cmdStr.strip()),
                       expected_cmdstr)
Esempio n. 7
0
 def test_psql_with_password(self):
     sql_file = os.path.join(
         os.path.dirname(inspect.getfile(self.__class__)), 'test.sql')
     psql = PSQL(sql_file=sql_file,
                 password='******',
                 output_to_file=False)
     expected_cmdstr = 'psql -a -f %s' % (sql_file)
     self.assertEquals(re.sub(' +', ' ', psql.cmdStr.strip()),
                       expected_cmdstr)
     self.assertEquals(psql.propagate_env_map.get('PGPASSWORD'), 'changeme')
Esempio n. 8
0
 def do_PLPERL_initialize(self):
     """ Language PL/PERL upgrade to 9.1: initialize test data  """
     self.doTest(None, "plperl91/test000_initialize", default='-e')
     """ Initialize: generate data tbctest.lineitem.tbl, and add users to pg_hba.conf """
     fname = os.environ.get(
         'TINCREPOHOME') + '/mpp/lib/datagen/datasets/lineitem.csv'
     copycmd = 'copy pltest.lineitem from \'' + fname + '\' DELIMITER \'|\';'
     cmd = PSQL(sql_cmd=copycmd, dbname=DBNAME)
     tinctest.logger.info("Running command - %s" % cmd)
     cmd.run(validateAfter=False)
     result = cmd.get_results()
     ok = result.rc
     out = result.stdout
     if ok:
         raise Exception('Copy statement failed: %s' % out)
     gpuserRole = GpUserRole(HOST, USER, DBNAME)
     gpuserRole.createUser('pltestuser', 'NOSUPERUSER')
     gpuserRole.createUser('plsuperuser', 'SUPERUSER')
     pg_hba_path = os.path.join(os.environ.get('MASTER_DATA_DIRECTORY'),
                                'pg_hba.conf')
     print 'pg_hba_path', pg_hba_path
     pghba_file = PgHba.PgHba(pg_hba_path)
     new_ent = PgHba.Entry(entry_type='local',
                           database=DBNAME,
                           user='******',
                           authmethod='trust')
     pghba_file.add_entry(new_ent)
     new_ent = PgHba.Entry(entry_type='local',
                           database=DBNAME,
                           user='******',
                           authmethod='trust')
     pghba_file.add_entry(new_ent)
     pghba_file.write()
     grantcmd = 'GRANT ALL ON SCHEMA pltest TO pltestuser;'
     cmd = PSQL(sql_cmd=grantcmd, dbname=DBNAME)
     tinctest.logger.info("Running command - %s" % cmd)
     cmd.run(validateAfter=False)
     result = cmd.get_results()
     ok = result.rc
     out = result.stdout
     if ok:
         raise Exception(
             'Grant all on schema pltest to pltestuser failed: %s' % out)
Esempio n. 9
0
    def GetGpdbVersion(self):
        """
        
        @summary: Returns the version and build number of the Greenplum Database
        @return: (version, build)
        """

        sql_cmd = 'select version();'
        cmd = PSQL(sql_cmd=sql_cmd,
                   flags='-q -t',
                   dbname=os.environ.get('PGDATABASE'))
        tinctest.logger.info("Running command - %s" % cmd)
        cmd.run(validateAfter=False)
        result = cmd.get_results()
        ok = not result.rc
        out = result.stdout.strip()

        assert ok, 'Running select version(); returned non-zero code.'
        assert len(out) > 0, 'select version() did not return any rows'

        # Assumption is that version is enclosed in parenthesis: (Greenplum Database 4.2.1.0 build 1)
        version_st = out.find('(') + 1
        version_end = out.find(')')
        version_str = out[version_st:version_end]

        gpdb_version_prefix = 'Greenplum Database '
        build_prefix = 'build '

        assert version_str.find(
            gpdb_version_prefix
        ) == 0, "'%s' not found in output of select version();" % gpdb_version_prefix
        assert version_str.find(build_prefix) > (
            version_str.find(gpdb_version_prefix) + len(gpdb_version_prefix)
        ), "'%s' not found after '%s' in output of select version();" % (
            build_prefix, gpdb_version_prefix)

        build_st = version_str.find('build')
        build_end = build_st + len(build_prefix)

        # version is in between 'Greenplum Database ' and 'build ': Greenplum Database 4.2.1.0 build 1
        version = version_str[len(gpdb_version_prefix):build_st].strip()
        # build number is after 'build ': Greenplum Database 4.2.1.0 build 1
        build = version_str[build_end:].strip()

        # If "(with assert checking)" is presented, then it is a debug build
        # Added by Hai Huang
        if (hasExpectedStr(out, '(with assert checking)')):
            version += "_debug"
            self.is_debug = True

        # Strips the STRING portion from the version string
        if re.match(".*_.+$", version) and version.find("_debug") == -1:
            version = re.sub(r'_.+$', r'', version)

        return (version, build)
Esempio n. 10
0
 def check_lock_corruption(self):
     """
     Check if pg_locks has records with transaction = 0, which is corrupted.
     """
     sql = "SELECT count(*) FROM pg_locks WHERE transaction = 0"
     # Use -A and -t, suppress -a, to get only the number.
     psql = PSQL(sql_cmd=sql, flags='-A -t')
     psql.run()
     results = psql.get_results()
     # Should be zero.
     self.assertEqual(results.stdout.strip(), '0')
Esempio n. 11
0
    def test_mpp20964(self):
        """

        @description Test MPP-20964, uncleaned lock table by pg_terminate_backend
        @created 2013-08-21 00:00:00
        @modified 2013-08-21 00:00:00
        @tags mpp-20964
        @product_version gpdb: [4.2.6.3- main]
        """

        # setup
        PSQL.run_sql_command("""
          DROP TABLE IF EXISTS foo;
          CREATE TABLE foo AS SELECT i a, i b FROM generate_series(1, 100)i;
          """)

        # Let the backend run executor in QE and hang for a while.
        sql = ("""
          SELECT * FROM (
            SELECT count(CASE WHEN pg_sleep(1) IS NULL THEN 1 END)
            FROM foo
          )s;
        """)
        # Run it backend.  We'll kill him while he's running.
        PSQL(sql_cmd=sql, background=True).run(validateAfter=False)
        # Let him reach to QE, just in case.
        time.sleep(1)

        # Now I'm killing him.  Note we kill both QE and QD.  QD runs
        # proc_exit and tries to get result from running QE.  Since
        # QE also died due to the termination, QD tries to issue an ERROR,
        # turning it to FATAL, calling proc_exit again.  He loses a chance
        # to release locks.
        sql = """
          SELECT pg_terminate_backend(procpid)
          FROM(
            SELECT (pg_stat_get_activity(NULL)).*
            FROM gp_dist_random('gp_id')
            WHERE gp_segment_id = 0
          )s
          WHERE sess_id <> current_setting('gp_session_id')::int
          UNION
          SELECT pg_terminate_backend(procpid)
          FROM pg_stat_activity
          WHERE sess_id <> current_setting('gp_session_id')::int
        """
        PSQL.run_sql_command(sql)

        # Finally check the pg_locks view to check if corrupted records
        # are seen.  If proclock was left without valid PGPROC, it would show
        # transaction = 0.  For some reason, one time might pass the test.
        # Check five times.
        for i in range(5):
            self.check_lock_corruption()
Esempio n. 12
0
 def template0_warn_limit_on_segment(self, primary):
     """
     Same as template0_warn_limit, but on a segment.
     """
     logger.info("template0_warn_limit_on_segment: dbid(%d) %s:%d'" %
                 (primary.dbid, primary.hostname, primary.port))
     # Bump up age of template0 to cause warn limit violation.
     self._raise_template0_age(self.WARN_LIMIT, primary)
     # All is well until we create a new db off template0.
     self._basic_sanity_check("clean")
     # Create database newdb off template0.
     PSQL(sql_cmd="CREATE DATABASE newdb TEMPLATE template0").run(
         validateAfter=True)
     logger.info("newdb created off template0")
     # newdb is now the oldest database, older than warn limit.
     self._basic_sanity_check("warn_segment")
     # Ensure that vacuum freeze on newdb stops the warnings.
     PSQL(sql_cmd="VACUUM FREEZE", dbname="newdb",
          out_file="vacuum_newdb_warn_seg.out").run(validateAfter=True)
     self._basic_sanity_check("clean")
     PSQL.drop_database(dbname="newdb")
Esempio n. 13
0
 def check_lock_corruption(self):
     """
     Check if pg_locks has records with NULL pid or mppsessionid = 0.
     These must be corrupted lock entries.
     """
     sql = "SELECT count(*) FROM pg_locks WHERE pid IS NULL OR mppsessionid = 0"
     # Use -A and -t, suppress -a, to get only the number.
     psql = PSQL(sql_cmd=sql, flags='-A -t')
     psql.run()
     results = psql.get_results()
     # Should be zero.
     self.assertEqual(results.stdout.strip(), '0')
Esempio n. 14
0
    def template0_warn_limit(self):
        """
        Raise next xid so that age(template0) grows beyond warn limit.
        Create a new database from template0, which will inherit age
        of template0.  Ensure that warnings stop when vacuum freeze is
        run on the new database.

        """
        # Bump up age of template0 to cause warn limit violation.
        self._raise_template0_age(self.WARN_LIMIT, self.gparray.master)
        # All is well until we create a new db off template0.
        self._basic_sanity_check("clean")
        # Create database newdb off template0.
        PSQL(sql_cmd="CREATE DATABASE newdb TEMPLATE template0").run(
            validateAfter=True)
        # newdb is now the oldest database, older than warn limit.
        self._basic_sanity_check("warn")
        # Ensure that vacuum freeze on newdb stops the warnings.
        PSQL(sql_cmd="VACUUM FREEZE", dbname="newdb",
             out_file="vacuum_newdb_wl_master.out").run(validateAfter=True)
        self._basic_sanity_check("clean")
        PSQL.drop_database(dbname="newdb")
Esempio n. 15
0
    def test_insert_commit_before_truncate(self):
        '''
        @description We suspend the vacuum on master after the first
                     transaction, and connect to segment.  Modify the
                     relation in vacuum and commit the segment local
                     transaction before the truncate transaction starts.
        '''
        fault_name = 'vacuum_relation_end_of_first_round'

        gpdbconfig = GPDBConfig()
        seghost, segport = gpdbconfig.get_hostandport_of_segment(0, 'p')
        filereputil = Filerepe2e_Util()
        filereputil.inject_fault(f=fault_name, y='suspend', seg_id='1')

        # run vacuum in background, it'll be blocked.
        sql_file1, ans_file1, out_file1 = self.get_file_names('conn1')
        psql1 = PSQL(sql_file=sql_file1, out_file=out_file1)
        thread1 = threading.Thread(target=self.run_psql, args=(psql1, ))
        thread1.start()

        self.check_fault_triggered(fault_name)

        sql_file2, ans_file2, out_file2 = self.get_file_names('conn2')
        # utility to seg0
        psql2 = PSQL(sql_file=sql_file2,
                     out_file=out_file2,
                     host=seghost,
                     port=segport,
                     PGOPTIONS='-c gp_session_role=utility')
        self.run_psql(psql2)

        # resume vacuum
        filereputil.inject_fault(f=fault_name, y='reset', seg_id='1')
        thread1.join()
        self.assertTrue(Gpdiff.are_files_equal(out_file1, ans_file1))
        self.assertTrue(Gpdiff.are_files_equal(out_file2, ans_file2))
Esempio n. 16
0
    def run_sequence(self, sql, fault, fault_type, segid):
        (ok, out) = self.util.inject_fault(f=fault, y=fault_type, seg_id=segid)
        if not ok:
            raise Exception(
                "Fault dtm_broadcast_commit_prepared injection failed")
        psql = PSQL(sql_cmd=sql)
        tinctest.logger.debug("Executing:" + sql)
        psql.run()
        results = psql.get_results()
        tinctest.logger.debug(results.stderr)

        self.check_no_dangling_prepared_transaction()

        if "PANIC" not in results.stderr:
            raise Exception(
                "Fault %s type %s (on segid: %d) did not cause the master reset"
                % (fault, fault_type, segid))
Esempio n. 17
0
    def run(self):
        """Run psql and see if stderr contains "ERROR" string.
        If it was an error, re-try with given interval (1 sec by default)
        and repeat as many as retry parameter (5 by default).  If retry
        count exceeds, return False.  Otherwise, True.
        """

        retry = self.retry
        for i in range(self.retry):
            cmd = PSQL(**self.psql_args)
            logger.debug("Running command: %s" % cmd)
            cmd.run(validateAfter=False)
            result = cmd.get_results()
            if "ERROR" not in result.stderr:
                return True
            time.sleep(self.interval)
        return False
Esempio n. 18
0
    def isInstalled(self, plname=None):
        """
        check if a given procedural language is installed on gpdb
        @param plname: the name of the procedural language to be checked
        @return: True if the given procedural language is installed on gpdb, False if it is not installed
        """
        if plname is None:
            plname = ""
        else:
            plname = plname.lower()

        if self.isSupported(plname):
            sql = "SELECT COUNT(*) FROM pg_language WHERE lanname='%s';" % (
                plname)

            cmd = PSQL(sql_cmd=sql,
                       flags='-q -t',
                       dbname=os.environ.get('PGDATABASE'))
            tinctest.logger.info("Running command - %s" % cmd)
            cmd.run(validateAfter=False)
            result = cmd.get_results()
            ok = result.rc
            out = result.stdout.strip()

            print 'ok is', ok
            if not ok:
                print 'out is', out
                ans = int(out[0].rstrip().lstrip())
                print 'ans is', ans
                if ans == 0:
                    return False
                elif ans == 1:
                    return True
                else:
                    raise Exception(
                        "Error when retrieving information about procedural languages from catalog"
                    )
            else:
                raise Exception(
                    "Error when retrieving information about procedural languages from catalog"
                )
        else:
            raise Exception("Unsupported procedural language %s" % (plname))
Esempio n. 19
0
    def run_sequence(self, sql, fault, fault_type, segid, should_panic=True):
        (ok,out) = self.util.inject_fault(f=fault, y=fault_type, seg_id=segid);
        if not ok:
           raise Exception("Fault dtm_broadcast_commit_prepared injection failed")
        psql = PSQL(sql_cmd=sql);
        tinctest.logger.debug("Executing:" + sql)
        psql.run()
        results = psql.get_results()
        tinctest.logger.debug(results.stderr)

        self.check_no_dangling_prepared_transaction()

	if "PANIC" not in results.stderr and should_panic:
            raise Exception("Fault %s type %s (on segid: %d) did not cause the master reset" % (fault, fault_type, segid))

	if "PANIC" in results.stderr and not should_panic:
            raise Exception("Fault %s type %s (on segid: %d) caused a PANIC. dtx two phase retry failed" % (fault, fault_type, segid))

        PSQL.wait_for_database_up()
Esempio n. 20
0
    def check_no_dangling_prepared_transaction(self):
        """
        Check if pg_prepared_xacts reports any records.
        """
        while True:
            sql = "SELECT count(*) FROM pg_prepared_xacts"
            # Use -A and -t, suppress -a, to get only the number.
            psql = PSQL(sql_cmd=sql, flags='-A -t')
            psql.run()
            results = psql.get_results()
            if psql.get_results().rc == 0:
                break

        if (results.stdout.strip() != '0'):
            PSQL.run_sql_command("""
          SELECT * FROM gp_dist_random('pg_prepared_xacts');
          """)

        # Should be zero.
        self.assertEqual(results.stdout.strip(), '0')
Esempio n. 21
0
    def _reset_age(self, dbname, segdb=None):
        """
        Resets datfrozenxid and relfrozenxid's in pg_class of the
        specified dbname to a value close to the current xid.  This is
        a recommended way of resetting age of dbname or a database
        that is created off template0.

        @param segdb: identifies the segment on which to operate.  It is an
        instance of GpDB class.

        Note that the database dbname must have all tuples frozen (xmin=2).
        This holds true of template0 and of a database created off template0,
        only if there are no modifications done to the database.

        """
        if segdb is None:
            segdb = self.gparray.master
        dburl = dbconn.DbURL(hostname=segdb.hostname, port=segdb.port)
        dburl_dbname = dbconn.DbURL(hostname=segdb.hostname,
                                    port=segdb.port,
                                    dbname=dbname)
        with dbconn.connect(dburl, utility=True,
                            allowSystemTableMods="dml") as conn:
            sql = "SELECT get_next_xid()"
            next_xid = int(dbconn.execSQLForSingleton(conn, sql))
            sql = "UPDATE pg_database SET datfrozenxid='%d'::xid WHERE datname='%s'"
            dbconn.execSQL(conn, sql % (next_xid, dbname))
            conn.commit()
        if dbname == "template0":
            self._set_allowconn_template0(True)
        with dbconn.connect(dburl_dbname,
                            utility=True,
                            allowSystemTableMods="dml") as conn:
            sql = ("UPDATE pg_class SET relfrozenxid='%d'::xid WHERE "
                   "int8in(xidout(relfrozenxid)) > 0")
            dbconn.execSQL(conn, sql % next_xid)
            conn.commit()
        PSQL(sql_cmd="VACUUM FREEZE pg_class",
             dbname=dbname,
             PGOPTIONS="-c 'gp_session_role=utility'",
             host=segdb.hostname,
             port=segdb.port,
             out_file="vacuum_%s.out" % dbname).run(validateAfter=True)
        with dbconn.connect(dburl_dbname,
                            utility=True,
                            allowSystemTableMods="dml") as conn:
            dbconn.execSQL(conn, "DELETE FROM pg_stat_last_operation")
            conn.commit()
        PSQL(sql_cmd="VACUUM FREEZE pg_stat_last_operation",
             dbname=dbname,
             PGOPTIONS="-c 'gp_session_role=utility'",
             host=segdb.hostname,
             port=segdb.port,
             out_file="vacuum_%s.out" % dbname).run(validateAfter=True)
        if dbname == "template0":
            self._set_allowconn_template0(False)
        with dbconn.connect(dburl, utility=True) as conn:
            sql = "SELECT age(datfrozenxid) FROM pg_database WHERE datname='%s'"
            age_dbname = dbconn.execSQLForSingleton(conn, sql % dbname)
            age_dbname = int(age_dbname)
        logger.info("Age of %s reset to %d" % (dbname, age_dbname))
        # We are OK as long as dbname age is less than xid_warn_limit.  The
        # 10000 is just a number assumed to be less than xid_warn_limit.
        self.assertTrue(
            age_dbname > 0 and age_dbname < 10000,
            "age(%s) = %d, next xid = %d" % (dbname, age_dbname, next_xid))
Esempio n. 22
0
    def _raise_template0_age(self, limit, segdb):
        """
        Increase age of template0 beyond the specified limit on the specified
        segment.  When a new database is created off template0, the limit will
        be exceeded.  Assumption: template0 age =~ 0 or at least not already
        crossing any of the xid limits.  Because this function can only raise
        the age, cannot decrease it.

        @param limit: one of WARN_LIMIT, STOP_LIMIT and WRAP_LIMIT.

        @param segdb: an instance of GpDB class representing the segment on
        which the limit will be exceeded.
        """
        dburl = dbconn.DbURL(hostname=segdb.hostname, port=segdb.port)
        databases = []
        with dbconn.connect(dburl, utility=True) as conn:
            sql = "SELECT datname FROM pg_database WHERE datallowconn='t'"
            for row in dbconn.execSQL(conn, sql):
                databases.append(row[0])
            sql = "SHOW xid_stop_limit"
            stop_limit_guc = int(dbconn.execSQLForSingleton(conn, sql))
            sql = "SHOW xid_warn_limit"
            warn_limit_guc = int(dbconn.execSQLForSingleton(conn, sql))
            sql = ("SELECT datfrozenxid, age(datfrozenxid) FROM pg_database "
                   "WHERE datname='template0'")
            row = dbconn.execSQL(conn, sql).fetchone()
            datfxid, age = int(row[0]), int(row[1])
            sql = "SELECT get_next_xid()"
            current_xid = int(dbconn.execSQLForSingleton(conn, sql))
        # Estimate of XIDs consumed by vacuum freeze operaiton on all databases.
        vacuum_xids = len(databases) * 500
        logger.info("Estimated xids for vacuume freeze: %d" % vacuum_xids)
        if limit == self.WARN_LIMIT:
            target_age = (2**31) - stop_limit_guc - warn_limit_guc
            target_xid = xid_sum(datfxid, target_age)
            keep_raising = lambda x: x < target_age
        elif limit == self.STOP_LIMIT:
            target_age = (2**31) - stop_limit_guc
            target_xid = xid_sum(datfxid, target_age)
            keep_raising = lambda x: x < target_age
        elif limit == self.WRAP_LIMIT:
            target_xid = xid_sum(datfxid, 2**31)
            keep_raising = lambda x: x > 0
        logger.info("Target xid = %d, limit = %d" % (target_xid, limit))
        self.assertEqual(
            preceding_xid(target_xid, current_xid), current_xid,
            "Target xid (%d) precedes current xid (%d)" %
            (target_xid, current_xid))
        while keep_raising(age):
            with dbconn.connect(dburl, utility=True) as conn:
                sql = "SELECT get_stop_limit()"
                stop_limit = int(dbconn.execSQLForSingleton(conn, sql))
                # GPDB may stop accepting connections if we spoof nextXid beyond
                # max_xid.
                max_xid = xid_sum(stop_limit, -vacuum_xids)
                new_xid = preceding_xid(target_xid, max_xid)
                logger.info(
                    "Spoofing next xid to %d, current stop limit = %d" %
                    (new_xid, stop_limit))
                sql = "SELECT spoof_next_xid('%d'::xid)"
                dbconn.execSQL(conn, sql % new_xid)
                conn.commit()
                sql = ("SELECT age(datfrozenxid) FROM pg_database "
                       "WHERE datname='template0'")
                age = int(dbconn.execSQLForSingleton(conn, sql))
            logger.info("template0 age raised to %d" % age)
            # The vacuum freeze of all databases advances stop_limit further,
            # necessary for iterating the while loop.  And template0 becomes the
            # oldest database aka the only culprit to violate the specified
            # limit.
            PSQL(sql_cmd='VACUUM FREEZE',
                 dbname='postgres',
                 out_file='vacuum_postgres.out').run(validateAfter=True)
            for datname in databases:
                logger.info('vacuum freeze %s' % datname)
                PSQL(sql_cmd='VACUUM FREEZE',
                     dbname=datname,
                     out_file='vacuum_%s.out' %
                     datname).run(validateAfter=True)
Esempio n. 23
0
    def test_syncrep(self):

        # 1. Initiate the Standby
        # 2. Once the WAL receiver starts, signal it to suspend post xlog flush
        #    but before sending the ack.
        # 3. Now execute a transaction and commit it. The backend is expected
        #    be blocked.
        # 4. Resume the WALReceiver and see the transaction passed and its
        #    results are visible.

        # cleanup
        PSQL.run_sql_command('DROP table if exists foo')

        # 1. create standby and start
        res = self.standby.create()
        self.assertEqual(res, 0)
        res = self.standby.start()
        self.assertTrue(res.wasSuccessful())

        # wait for the walreceiver to start
        num_walsender = self.wait_for_walsender()
        self.assertEqual(num_walsender, 1)

        # 2. Once the WAL receiver starts, signal it to suspend post xlog flush
        #    but before sending the ack.
        proc = subprocess.Popen(['ps', '-ef'], stdout=subprocess.PIPE)
        stdout = proc.communicate()[0]
        search = "wal receiver process"
        for line in stdout.split('\n'):
            if (line.find(search) > 0):
                split_line = re.split(r'\s+', line.strip())
                break

        self.assertTrue(len(split_line) > 0)

        wal_rcv_pid = int(split_line[1])
        logger.info('Suspending WAL Receiver(' + str(wal_rcv_pid) + ')...')
        self.generate_trigger_file('wait_before_send_ack')
        os.kill(wal_rcv_pid, signal.SIGUSR2)

        # 3. Now execute a transaction and commit it. The backend is expected
        #    be blocked.
        logger.info('Create table foo...')

        # we use subprocess since we expect it'll be blocked.
        proc = subprocess.Popen(['psql', '-c', 'create table foo (a int)'],
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        readable = self.wait_stdout(proc, 5.0)
        self.assertFalse(readable, 'psql did not block')

        # 4. Resume the WALReceiver and see the transaction passed and its
        #    results are visible.
        logger.info('Resume the WAL Receiver...')
        self.generate_trigger_file('resume')
        os.kill(wal_rcv_pid, signal.SIGUSR2)

        readable = self.wait_stdout(proc, 5.0)
        self.assertTrue(readable, 'psql still blocks')
        proc.communicate()

        logger.info('No blocked backend found!')

        logger.info('Verifying if table exists ? ...')
        PSQL(sql_cmd='select * from foo').run(validateAfter=True)

        logger.info('Pass')
Esempio n. 24
0
 def test_default_sql_file_construction(self):
     sql_file = os.path.join(os.path.dirname(inspect.getfile(self.__class__)),'test.sql')
     psql = PSQL(sql_file = sql_file, output_to_file = False)
     expected_cmdstr = 'psql -a -f %s' %sql_file
     self.assertEquals(re.sub(' +', ' ', psql.cmdStr.strip()), expected_cmdstr)
Esempio n. 25
0
 def test_psql_with_invalid_sql_file(self):
     sql_file = os.path.join(
         os.path.dirname(inspect.getfile(self.__class__)), 'test_not.sql')
     with self.assertRaises(PSQLException) as cm:
         psql = PSQL(sql_file=sql_file, output_to_file=False)
Esempio n. 26
0
 def test_default_sql_cmd_construction(self):
     sql_cmd = "select 1"
     psql = PSQL(sql_cmd=sql_cmd, output_to_file=False)
     expected_cmdstr = 'psql -a -c \"%s\"' % sql_cmd
     self.assertEquals(re.sub(' +', ' ', psql.cmdStr.strip()),
                       expected_cmdstr)
Esempio n. 27
0
 def test_psql_with_background(self):
     sql_file = os.path.join(os.path.dirname(inspect.getfile(self.__class__)),'test.sql')
     psql = PSQL(sql_file = sql_file, background = True, output_to_file = False)
     expected_cmdstr = 'psql -a -f %s &' %(sql_file)
     self.assertEquals(re.sub(' +', ' ', psql.cmdStr.strip()), expected_cmdstr)
Esempio n. 28
0
 def run_SQLCommand(self, sql_cmd = None, dbname = None, username = None, password = None,
                     PGOPTIONS = None, host = None, port = None):
     cmd = PSQL(None, sql_cmd = sql_cmd, dbname = dbname, username = username, password = password, PGOPTIONS = PGOPTIONS, host = host, port = port)
     cmd.run(validateAfter = False)
     result = cmd.get_results()
     return result.rc, result.stdout