Mini Shell

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

#!/opt/imh-python/bin/python3
"""Locate any innodb tables that no longer exist in engine"""

import os
import json
import pymysql
from pymysql.cursors import DictCursor

MISSING_IBD_LOG = "/home/nagios/missing_ibd.json"

# specify the socket file for pymysql
if os.path.exists("/etc/redhat-release"):
    SOCK = "/var/lib/mysql/mysql.sock"
else:
    # ubuntu support
    SOCK = "/run/mysqld/mysqld.sock"


def check_dbs(dbcur: DictCursor, dbs: list[str]):
    """Checks table status of each database & returns results"""
    results = {}
    for dbname in dbs:
        # deals with how mysql escapes identifiers
        escaped = dbname.replace("`", "``")
        dbcur.execute(f"SHOW TABLE STATUS FROM `{escaped}`")
        tblstats = dbcur.fetchall()
        # adds entry if any affected tables were found
        if out := parse_status(tblstats):
            results[dbname] = out
    return results


def parse_status(rows):
    """Parses table status query & returns list of affected tables"""
    tables = []
    for row in rows:
        # indicates an innodb table cannot be accessed
        if "doesn't exist in engine" in row["Comment"]:
            tables.append(row["Name"])
    return tables


def main():
    """Main: Logs which dbs and tables have missing ibd files"""
    with pymysql.connect(
        read_default_file="/root/.my.cnf",
        unix_socket=SOCK,
    ) as conn:
        with conn.cursor() as cur:
            cur.execute("SHOW DATABASES")
            db_list = [x[0] for x in cur.fetchall()]
        with conn.cursor(DictCursor) as cur:
            missing_ibd = check_dbs(cur, db_list)

        with open(MISSING_IBD_LOG, "w", encoding="utf-8") as logfile:
            json.dump(missing_ibd, logfile, indent=4)


if __name__ == "__main__":
    main()

Zerion Mini Shell 1.0