Mini Shell

Direktori : /opt/maint/bin/
Upload File :
Current File : //opt/maint/bin/log_tablespace_conflicts.py

#!/opt/imh-python/bin/python3
"""locate any innodb tablespace conflicts and log them to
/home/nagios/tablespace_conflicts.json"""
import os
import json
from pathlib import Path
from collections import defaultdict
from construct import Struct, Int16ub, Int32ub, Int64ub

IBD_STRUCT = Struct(
    'checksum' / Int32ub,
    'page_number' / Int32ub,
    'previous_page' / Int32ub,
    'next_page' / Int32ub,
    'last_mod_lsn' / Int64ub,
    'page_type' / Int16ub,
    'flush_lsn' / Int64ub,
    'tbl_space' / Int32ub,
)

CONFLICTS_LOG = '/home/nagios/tablespace_conflicts.json'


def main():
    """Main: if file per table, log conflicts to `CONFLICTS_LOG`"""
    data = map_innodb_tablespace_ids()
    conflicts = {}
    for space_id, ibd_files in data.items():
        if space_id == 0:
            continue
        if space_id == 'missing' or len(ibd_files) > 1:
            conflicts[space_id] = ibd_files
    print(conflicts)
    with open(f"{CONFLICTS_LOG}.tmp", 'w', encoding='utf-8') as file:
        json.dump(conflicts, file, indent=4)
    os.rename(f"{CONFLICTS_LOG}.tmp", CONFLICTS_LOG)


def map_innodb_tablespace_ids():
    """Build a mapping what tablespace IDs go to what ibd file"""
    tablespace_ids = defaultdict(list)
    for path in Path('/var/lib/mysql').glob('*/*.ibd'):
        if not path.is_file():
            continue
        try:
            with path.open('rb') as file:
                ibd_head = file.read(38)
            tbl_id = IBD_STRUCT.parse(ibd_head)['tbl_space']
        except Exception:
            tbl_id = 'missing'
        tablespace_ids[tbl_id].append(str(path))
    return tablespace_ids


if __name__ == '__main__':
    main()

Zerion Mini Shell 1.0