Пример #1
0
def listdbs(server, args_array, **kwargs):

    """Function:  listdbs

    Description:  List user or user/system databases in the database instance.

    Arguments:
        (input) server -> Server instance.
        (input) args_array -> Dictionary of command line options.
        (input) **kwargs:
            sys_dbs -> List of system databases.

    """

    args_array = dict(args_array)
    sys_dbs = list(kwargs.get("sys_dbs", []))
    db_list = gen_libs.dict_2_list(mysql_libs.fetch_db_dict(server),
                                   "Database")

    if "-k" in args_array:
        print("List of user and system databases:")

        for item in db_list:
            print("    %s" % (item))

    else:
        print("List of user databases:")

        for item in gen_libs.del_not_and_list(db_list, sys_dbs):
            print("    %s" % (item))
Пример #2
0
def set_db_list(server, args_array):
    """Function:  set_db_list

    Description:  Get the database list and check if all databases or a single
        database is being selected.

    Arguments:
        (input) server -> Database server instance.
        (input) args_array -> Array of command line options and values.
        (output) -> Database list.

    """

    args_array = dict(args_array)
    dump_list = []
    db_list = gen_libs.dict_2_list(mysql_libs.fetch_db_dict(server),
                                   "Database")

    # Specified databases.
    if "-B" in args_array:

        # Difference of -B databases to database list.
        for item in set(args_array["-B"]) - set(db_list):
            print("Warning: Database(%s) does not exist." % (item))

        # Intersect of -B databases to database list.
        dump_list = list(set(args_array["-B"]) & set(db_list))

    # All databases.
    elif "-A" in args_array:
        dump_list = list(db_list)

    return dump_list
Пример #3
0
def _proc_all_tbls(server, func_name, db_list, db_name, dict_key, **kwargs):

    """Function:  _proc_all_tbls

    Description:  Private function for process_requests().  Process all tables
        in listed databases.

    Arguments:
        (input) server -> Server instance.
        (input) func_name -> Name of a function.
        (input) db_list -> List of all databases.
        (input) db_name -> List of database names.
        (input) dict_key -> Dictionary key for fetch_tbl_dict call.
        (input) **kwargs:
            sys_dbs -> List of system databases.
            multi_val -> List of options that may have multiple values.

    """

    db_name = list(db_name)
    db_list = list(db_list)
    detect_dbs(db_name, db_list, **kwargs)

    for dbs in set(db_name) & set(db_list):
        for tbl in gen_libs.dict_2_list(mysql_libs.fetch_tbl_dict(server, dbs),
                                        dict_key):
            func_name(server, dbs, tbl, **kwargs)
Пример #4
0
def process_logs_list(server, args_array, **kwargs):
    """Function:  process_logs_list

    Description:  Get a list of binary log file names from the source database.
        Clean up the list if the -f and/or -g options are used.

    Arguments:
        (input) server -> Server instance.
        (input) args_array -> Array of command line options and values.
        (output) status -> Tuple on process status.
            status[0] - True|False - Process successful.
            status[1] - Error message if process failed.
        (output) binlog_list -> List of binary log file names.

    """

    args_array = dict(args_array)
    status = (True, None)
    binlog_list = []

    # Is -f and -g in the argument list and in the correct order.
    if ("-f" in args_array and "-g" in args_array) \
       and args_array["-g"] < args_array["-f"]:

        status = (False, "Error:  Option -g: '%s' is before -f '%s'." %
                  (args_array["-g"], args_array["-f"]))

        return status, binlog_list

    binlog_list = gen_libs.dict_2_list(mysql_libs.fetch_logs(server),
                                       "Log_name")

    if "-f" in args_array and args_array["-f"] in binlog_list:

        # Remove any logs before log file name.
        while binlog_list[0] < args_array["-f"]:
            binlog_list.pop(0)

    elif "-f" in args_array:

        status = (False,
                  "Error:  Option -f: '%s' not found in binary log list." %
                  (args_array["-f"]))

        return status, binlog_list

    if "-g" in args_array and args_array["-g"] in binlog_list:
        # Remove any logs after log file name.
        while binlog_list[-1] > args_array["-g"]:
            binlog_list.pop(-1)

    elif "-g" in args_array:

        status = (False,
                  "Error:  Option -g: '%s' not found in binary log list." %
                  (args_array["-g"]))

    return status, binlog_list
Пример #5
0
def process_request(server, func_name, db_name=None, tbl_name=None, **kwargs):

    """Function:  process_request

    Description:  Prepares for the type of check based on the arguments passed
        to the function and then calls the "func_name" function.
        NOTE:  If db_name and/or tbl_name is set to None, then assumes to
            process all databases/tables repsectively.

    Arguments:
        (input) server -> Server instance.
        (input) func_name -> Name of a function.
        (input) db_name -> Database name.
        (input) tbl_name -> Table name.
        (input) **kwargs:
            sys_dbs -> List of system databases.
            multi_val -> List of options that may have multiple values.

    """

    db_name = list() if db_name is None else list(db_name)
    tbl_name = list() if tbl_name is None else list(tbl_name)
    db_list = gen_libs.dict_2_list(mysql_libs.fetch_db_dict(server),
                                   "Database")
    dict_key = "table_name"

    # Determine the MySQL version for dictionary key name
    if mysql_class.fetch_sys_var(server, "version",
                                 level="session")["version"] >= "8.0":
        dict_key = "TABLE_NAME"

    # Process all databases
    if not db_name:
        _proc_all_dbs(server, func_name, db_list, dict_key, **kwargs)

    # Process all tables in some databases
    elif not tbl_name:
        _proc_all_tbls(server, func_name, db_list, db_name, dict_key, **kwargs)

    # Process specific tables.
    else:
        _proc_some_tbls(server, func_name, db_list, db_name, tbl_name,
                        dict_key, **kwargs)
Пример #6
0
def fetch_db_list(server, ign_db_list=None, db_name=None):
    """Function:  fetch_db_list

    Description:  Return list of database(s) minus any in the ignore database
        list or return the databases in the do list.

    Arguments:
        (input) server -> Server instance.
        (input) ign_db_list -> List of databases to be ignored.
        (input) db_name -> List of specify database names to be checked.
        (output) db_list | db_name -> List of databases.

    """

    if ign_db_list is None:
        ign_db_list = list()

    else:
        ign_db_list = list(ign_db_list)

    if db_name is None:
        db_name = list()

    else:
        db_name = list(db_name)

    if server.do_db:
        db_list = server.fetch_do_db()

    else:
        db_list = gen_libs.dict_2_list(mysql_libs.fetch_db_dict(server),
                                       "Database")

    if server.ign_db:
        ign_db_list = server.fetch_ign_db() + ign_db_list

    # Remove "ignore" databases from database list.
    db_list = gen_libs.del_not_and_list(db_list, ign_db_list)

    if db_name:
        return gen_libs.del_not_in_list(db_name, db_list)

    return db_list
Пример #7
0
def run_program(args_array, sys_ign_db, **kwargs):
    """Function:  run_program

    Description:  Creates class instance(s) and controls flow of the program.

    Arguments:
        (input) args_array -> Array of command line options and values.
        (input) sys_ign_db -> List of system databases to ignore.

    """

    global SUBJ_LINE

    args_array = dict(args_array)
    sys_ign_db = list(sys_ign_db)
    mail = None
    use_mailx = False
    no_std = args_array.get("-z", False)
    master = mysql_libs.create_instance(args_array["-c"], args_array["-d"],
                                        mysql_class.MasterRep)
    master.connect(silent=True)
    slave = mysql_libs.create_instance(args_array["-r"], args_array["-d"],
                                       mysql_class.SlaveRep)
    slave.connect(silent=True)

    if master.conn_msg or slave.conn_msg:
        print("run_program: Error encountered with connection of master/slave")
        print("\tMaster:  %s" % (master.conn_msg))
        print("\tSlave:  %s" % (slave.conn_msg))

    else:
        if args_array.get("-e", None):
            mail = gen_class.setup_mail(args_array.get("-e"),
                                        subj=args_array.get("-s", SUBJ_LINE))
            use_mailx = args_array.get("-u", False)

        # Determine datatype of server_id and convert appropriately.
        #   Required for mysql.connector v1.1.6 as this version assigns the
        #   id to a different datatype then later mysql.connector versions.
        slv_list = gen_libs.dict_2_list(master.show_slv_hosts(), "Server_id")
        slv_id = str(slave.server_id) \
            if isinstance(slv_list[0], str) else slave.server_id

        # Is slave in replication with master
        if slv_id in slv_list:

            # Check specified tables in database
            if "-t" in args_array:
                setup_cmp(master,
                          slave,
                          sys_ign_db,
                          args_array["-B"],
                          args_array["-t"],
                          mail=mail,
                          no_std=no_std,
                          use_mailx=use_mailx,
                          **kwargs)

            # Check single database
            elif "-B" in args_array:
                setup_cmp(master,
                          slave,
                          sys_ign_db,
                          args_array["-B"],
                          "",
                          mail=mail,
                          no_std=no_std,
                          use_mailx=use_mailx,
                          **kwargs)

            # Check all tables in all databases
            else:
                setup_cmp(master,
                          slave,
                          sys_ign_db,
                          "",
                          "",
                          mail=mail,
                          no_std=no_std,
                          use_mailx=use_mailx,
                          **kwargs)

            mysql_libs.disconnect(master, slave)

        else:
            mysql_libs.disconnect(master, slave)
            print("Error:  Replica is not in replication with Master.")
Пример #8
0
def setup_cmp(master,
              slave,
              sys_ign_db,
              db_name=None,
              tbl_name=None,
              **kwargs):
    """Function:  setup_cmp

    Description:  Setup the comparsion check getting list of databases and
        tables then calling the compare function.

    Arguments:
        (input) master -> Master instance.
        (input) slave -> Slave instance.
        (input) sys_ign_db -> List of system databases to ignore.
        (input) db_name -> List of database names.
        (input) tbl_name -> List of table names.
        (input) **kwargs:
            ign_db_tbl -> Dictionary-List of dbs & tables to be ignored.
            mail -> Mail class instance.
            no_std -> Suppress standard out.
            use_mailx -> Use the mailx command for sending emails.

    """

    db_name = list() if db_name is None else list(db_name)
    tbl_name = list() if tbl_name is None else list(tbl_name)
    sys_ign_db = list(sys_ign_db)
    ign_db_tbl = kwargs.get("ign_db_tbl", dict())
    mail = kwargs.get("mail", None)
    no_std = kwargs.get("no_std", False)
    mst_dbs = fetch_db_list(master)
    slv_dbs = fetch_db_list(slave, sys_ign_db, db_name)
    db_list = gen_libs.del_not_in_list(mst_dbs, slv_dbs)
    slv_do_dict = slave.fetch_do_tbl()
    slv_ign_dict = slave.fetch_ign_tbl()
    dict_key = "table_name"

    # Determine the MySQL version for dictionary key name
    if mysql_class.fetch_sys_var(master, "version",
                                 level="session")["version"] >= "8.0":
        dict_key = "TABLE_NAME"

    for dbs in db_list:
        # Get master list of tables.
        mst_tbl_list = gen_libs.dict_2_list(
            mysql_libs.fetch_tbl_dict(master, dbs), dict_key)

        # Database in "to do" list.
        if dbs in slv_do_dict:
            slv_tbl_list = slv_do_dict[dbs]

        else:
            # Get list of tables from slave.
            slv_tbl_list = gen_libs.dict_2_list(
                mysql_libs.fetch_tbl_dict(slave, dbs), dict_key)

        slv_ign_tbl = []

        # Database in slave "ignore" list
        if dbs in slv_ign_dict:
            slv_ign_tbl = slv_ign_dict[dbs]

        if dbs in ign_db_tbl:
            slv_ign_tbl = slv_ign_tbl + ign_db_tbl[dbs]

        # Drop "ignore" tables.
        slv_tbl_list = gen_libs.del_not_and_list(slv_tbl_list, slv_ign_tbl)

        tbl_list = gen_libs.del_not_in_list(mst_tbl_list, slv_tbl_list)

        if tbl_name:
            tbl_list = gen_libs.del_not_in_list(tbl_list, tbl_name)

        run_cmp(master, slave, dbs, tbl_list, mail=mail, no_std=no_std)

    if mail:
        mail.send_mail(use_mailx=kwargs.get("use_mailx", False))