Пример #1
0
def get_mysqlops_connections():
    """ Get a connection to mysqlops for reporting

    Returns:
    A mysql connection
    """
    (reporting_host, port, _, _) = mysql_connect.get_mysql_connection('mysqlopsdb001')
    reporting = host_utils.HostAddr(''.join((reporting_host, ':', str(port))))
    return connect_mysql(reporting, 'scriptrw')
Пример #2
0
def get_master_from_instance(instance):
    """ Determine if an instance thinks it is a slave and if so from where

    Args:
    instance - A hostaddr object

    Returns:
    master - A hostaddr object or None
    """
    try:
        ss = get_slave_status(instance)
    except ReplicationError:
        return None

    return host_utils.HostAddr(''.join(
        (ss['Master_Host'], ':', str(ss['Master_Port']))))
Пример #3
0
def get_host_from_backup(full_path):
    """ Parse the filename of a backup to determine the source of a backup

    Note: there is a strong assumption that the port number matches 330[0-9]

    Args:
    full_path - Path to a backup file.
                Example: /backup/tmp/mysql-legaldb001c-3306-2014-06-06.xbstream
                Example: /backup/tmp/mysql-legaldb-1-1-3306-2014-06-06.xbstream

    Returns:
    host - A hostaddr object
    """
    filename = os.path.basename(full_path)
    pattern = 'mysql-([a-z0-9-]+)-(330[0-9])-.+'
    res = re.match(pattern, filename)
    return host_utils.HostAddr(''.join((res.group(1), ':', res.group(2))))
Пример #4
0
def get_metadata_from_backup_file(full_path):
    """ Parse the filename of a backup to determine the source of a backup

    Note: there is a strong assumption that the port number matches 330[0-9]

    Args:
    full_path - Path to a backup file.
                Example: xtrabackup/standard/testmodsharddb-1/testmodsharddb-1-79-3306-2016-05-18-22:34:39.xbstream

    Returns:
    host - A hostaddr object
    creation - a datetime object describing creation date
    """
    filename = os.path.basename(full_path)
    pattern = '([a-z0-9-]+)-(330[0-9])-(\d{4})-(\d{2})-(\d{2}).*'
    res = re.match(pattern, filename)
    host = host_utils.HostAddr(':'.join((res.group(1), res.group(2))))
    creation = datetime.date(int(res.group(3)), int(res.group(4)),
                             int(res.group(5)))
    return host, creation
Пример #5
0
def assert_replication_sanity(instance, checks=ALL_REPLICATION_CHECKS):
    """ Confirm that a replica has replication running and from the correct
        source if the replica is in zk. If not, throw an exception.

    args:
    instance - A hostAddr object
    """
    problems = set()
    slave_status = get_slave_status(instance)
    if (CHECK_IO_THREAD in checks
            and slave_status['Slave_IO_Running'] != 'Yes'):
        problems.add('Replica {r} has IO thread not running'
                     ''.format(r=instance))

    if (CHECK_SQL_THREAD in checks
            and slave_status['Slave_SQL_Running'] != 'Yes'):
        problems.add('Replcia {r} has SQL thread not running'
                     ''.format(r=instance))

    if CHECK_CORRECT_MASTER in checks:
        zk = host_utils.MysqlZookeeper()
        try:
            (replica_set,
             replica_type) = zk.get_replica_set_from_instance(instance)
        except:
            # must not be in zk, returning
            return
        expected_master = zk.get_mysql_instance_from_replica_set(replica_set)
        actual_master = host_utils.HostAddr(':'.join(
            (slave_status['Master_Host'], str(slave_status['Master_Port']))))
        if expected_master != actual_master:
            problems.add('Master is {actual} rather than expected {expected}'
                         'for replica {r}'.format(actual=actual_master,
                                                  expected=expected_master,
                                                  r=instance))

    if problems:
        raise Exception(', '.join(problems))
Пример #6
0
def get_metadata_from_backup_file(full_path):
    """ Parse the filename of a backup to determine the source of a backup

    Note: there is a strong assumption that the port number matches 330[0-9]

    Args:
    full_path - Path to a backup file.
                Example: /backup/tmp/mysql-legaldb001c-3306-2014-06-06.xbstream
                Example: /backup/tmp/mysql-legaldb-1-1-3306-2014-06-06.xbstream

    Returns:
    host - A hostaddr object
    creation - a datetime object describing creation date
    extension - file extension
    """
    filename = os.path.basename(full_path)
    pattern = 'mysql-([a-z0-9-]+)-(330[0-9])-(\d{4})-(\d{2})-(\d{2}).*\.(.+)'
    res = re.match(pattern, filename)
    host = host_utils.HostAddr(':'.join((res.group(1), res.group(2))))
    creation = datetime.date(int(res.group(3)), int(res.group(4)),
                             int(res.group(5)))
    extension = res.group(6)
    return host, creation, extension
Пример #7
0
def calc_slave_lag(slave_hostaddr, dead_master=False):
    """ Determine MySQL replication lag in bytes and binlogs

    Args:
    slave_hostaddr - A HostAddr object for a replica

    Returns:
    io_binlogs - Number of undownloaded binlogs. This is only slightly useful
                 as io_bytes spans binlogs. It mostly exists for dba amussement
    io_bytes - Bytes of undownloaded replication logs.
    sbm - Number of seconds of replication lag as determined by computing
          the difference between current time and what exists in a heartbeat
          table as populated by replication
    sql_binlogs - Number of unprocessed binlogs. This is only slightly useful
                  as sql_bytes spans binlogs. It mostly exists for dba
                  amussement
    sql_bytes - Bytes of unprocessed replication logs
    ss - None or the results of running "show slave status'
    """

    ret = {
        'sql_bytes': INVALID,
        'sql_binlogs': INVALID,
        'io_bytes': INVALID,
        'io_binlogs': INVALID,
        'sbm': INVALID,
        'ss': {
            'Slave_IO_Running': INVALID,
            'Slave_SQL_Running': INVALID,
            'Master_Host': INVALID,
            'Master_Port': INVALID
        }
    }
    try:
        ss = get_slave_status(slave_hostaddr)
    except ReplicationError:
        # Not a slave, so return dict of INVALID
        return ret
    except MySQLdb.OperationalError as detail:
        (error_code, msg) = detail.args
        if error_code == MYSQL_ERROR_CONN_HOST_ERROR:
            # Host down, but exists.
            return ret
        else:
            # Host does not exist or something else funky
            raise

    ret['ss'] = ss
    slave_sql_pos = ss['Exec_Master_Log_Pos']
    slave_sql_binlog = ss['Relay_Master_Log_File']
    _, slave_sql_binlog_num = re.split('\.', slave_sql_binlog)
    slave_io_pos = ss['Read_Master_Log_Pos']
    slave_io_binlog = ss['Master_Log_File']
    _, slave_io_binlog_num = re.split('\.', slave_io_binlog)

    master_hostaddr = host_utils.HostAddr(':'.join(
        (ss['Master_Host'], str(ss['Master_Port']))))
    if not dead_master:
        try:
            master_logs = get_master_logs(master_hostaddr)

            (ret['sql_bytes'],
             ret['sql_binlogs']) = calc_binlog_behind(slave_sql_binlog_num,
                                                      slave_sql_pos,
                                                      master_logs)
            (ret['io_bytes'],
             ret['io_binlogs']) = calc_binlog_behind(slave_io_binlog_num,
                                                     slave_io_pos, master_logs)
        except _mysql_exceptions.OperationalError as detail:
            (error_code, msg) = detail.args
            if error_code != MYSQL_ERROR_CONN_HOST_ERROR:
                raise
            # we can compute real lag because the master is dead

    try:
        ret['sbm'] = calc_alt_sbm(slave_hostaddr, ss['Master_Server_Id'])
    except MySQLdb.ProgrammingError as detail:
        (error_code, msg) = detail.args
        if error_code != MYSQL_ERROR_NO_SUCH_TABLE:
            raise
        # We can not compute a real sbm, so the caller will get
        # None default
        pass
    return ret