1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Anuncie Aqui
    Anuncie aqui você Também: fdantas@4each.com.br

[Python] Vacuuming and analyzing redshift tables

Discussão em 'Python' iniciado por Stack, Setembro 16, 2024.

  1. Stack

    Stack Membro Participativo

    import logging
    import boto3
    import sys
    import argparse
    from urllib.parse import urlparse
    import os
    import signal
    import time

    try:
    sys.path.append(os.path.join(os.path.dirname(__file__), "lib"))
    except:
    pass

    import analyze_vacuum
    import config_constants

    # Cluster name should match the connection name created in Glue console
    JDBC_PREFIX = "jdbc:"
    logging.basicConfig(level=logging.INFO)
    LOGGER = logging.getLogger(__name__)

    __version__ = ".10"

    # Timeout function to limit total runtime
    def timeout_handler(signum, frame):
    raise TimeoutError("The process has exceeded the 8-hour time limit.")

    # Set the timeout signal (8 hours = 28,800 seconds)
    signal.signal(signal.SIGALRM, timeout_handler)
    signal.alarm(28800)`your text`

    def main(argv):
    """
    Triggers the vacuum analyze using a glue connection

    :param argv the arguments to parse
    """
    try:
    # setup cli args
    parser = argparse.ArgumentParser()
    parser.add_argument("--glue-connection", dest="glue_connection", required=True)
    parser.add_argument("--max-unsorted-pct", dest="max_unsorted_pct",
    help="Maximum unsorted percentage( to consider a table for vacuum : Default = 50")
    parser.add_argument("--min-unsorted-pct", dest="min_unsorted_pct",
    help="Minimum unsorted percentage( to consider a table for vacuum : Default = 5")
    parser.add_argument("--stats-off-pct", dest="stats_off_pct",
    help="Minimum stats off percentage( to consider a table for analyze : Default = 10")
    parser.add_argument("--vacuum-parameter", dest="vacuum_parameter",
    help="Vacuum parameters [ FULL | SORT ONLY | DELETE ONLY | REINDEX ] Default = FULL")
    parser.add_argument("--blacklisted-tables", dest="blacklisted_tables", help="The tables we do not want to Vacuum")
    parser.add_argument("--debug", dest="debug", default=False, help="Generate Debug Output including SQL Statements being run")
    parser.add_argument("--ignore-errors", dest="ignore_errors", default=True,
    help="Ignore errors raised when running and continue processing")
    parser.add_argument("--max-table-size-mb", dest="max_table_size_mb", type=int, help="Maximum table size in MB : Default = 700*1024 MB")
    parser.add_argument("--query-group", dest="query_group", help="Set the query_group for all queries")
    parser.add_argument("--schema-name", dest="schema_name", help="The Schema to be Analyzed or Vacuumed (REGEX: Default = public")
    parser.add_argument("--slot-count", dest="slot_count", help="Modify the wlm_query_slot_count : Default = 1")
    parser.add_argument("--suppress-cloudwatch", dest="suppress_cw",
    help="Don't emit CloudWatch metrics for analyze or vacuum when set to True")
    parser.add_argument("--skip-materialized-views", dest="skip_materialized_views", default=True,
    help="Skip materialized views (added to blacklisted tables)")

    full_args, extra = parser.parse_known_args(argv)
    LOGGER.info(f"Parsed args : {full_args}, extra args : {extra}")

    args = {}
    # remove args that end up as None
    for k, v in vars(full_args).items():
    if v is not None:
    args[k] = v

    # getting boto3 custom session object to access metadata
    my_session = boto3.session.Session()
    region_id = my_session.region_name
    glue_client = my_session.client('glue', region_name=region_id)

    # get the connection through glue client
    catalog_config = glue_client.get_connection(Name=args['glue_connection'])
    connection_props = catalog_config['Connection']['ConnectionProperties']
    # Parse the jdbc url
    connection_dsn = urlparse(connection_props['JDBC_CONNECTION_URL'].removeprefix(JDBC_PREFIX))

    LOGGER.debug("Creating redshift connection : {}, User : {}".format(connection_props['JDBC_CONNECTION_URL'], connection_dsn.username))
    args[config_constants.DB_NAME] = connection_dsn.path[1:]
    args[config_constants.DB_USER] = connection_props['USERNAME']
    args[config_constants.DB_PASSWORD] = connection_props['PASSWORD']
    args[config_constants.DB_HOST] = connection_dsn.hostname
    args[config_constants.DB_PORT] = int(connection_dsn.port)

    # Flags for analyze and vacuum
    args['analyze_flag'] = 'True'
    args['vacuum_flag'] = 'True'

    # Step 1: Vacuum first
    LOGGER.info("Starting table vacuuming...")
    args['analyze_flag'] = 'False' # Turn off analyze temporarily
    result = analyze_vacuum.run_analyze_vacuum(**args)
    if result is not None:
    LOGGER.error("Vacuum failed with result: %s", result)
    sys.exit(result)

    # Step 2: Analyze second
    LOGGER.info("Starting table analysis...")
    args['vacuum_flag'] = 'False' # Turn off vacuum
    args['analyze_flag'] = 'True' # Turn on analyze
    result = analyze_vacuum.run_analyze_vacuum(**args)
    if result is not None:
    LOGGER.error("Analysis failed with result: %s", result)
    sys.exit(result)

    LOGGER.info("Process complete.")
    sys.exit(0)
    except TimeoutError as te:
    LOGGER.error("Process timed out: %s", str(te))
    sys.exit(1)
    except Exception as e:
    LOGGER.error("Process failed: %s", str(e))
    sys.exit(1)

    if __name__ == "__main__":
    main(sys.argv)


    need to run first all vacuum for all tables and then analyze current code is taking one table at a time and running vacuum and analyze for each table i want to execute all the tables vacuum ad then analyze instead of one by one

    above program run the vacuum process for each table overnight and sometime it take more than 8 hour we want to kill the process if it goes more then 8 hour

    Continue reading...

Compartilhe esta Página