python统计MySQL表增长率并发送邮件

一、系统架构设计

[MySQL数据库] <--统计查询--> 
[Python统计程序] --> 
[SQLite统计库] --> 
[HTML邮件生成] --> 
[SMTP服务器]

二、配置文件设计(config.ini)

[mysql]
host = localhost
port = 3306
user = root
password = your_password
database = information_schema  # 默认统计所有数据库

[storage]
stats_db = statistics.db       # SQLite存储路径

[email]
smtp_server = smtp.example.com
smtp_port = 587
sender = monitor@example.com
password = email_password
receivers = admin1@ex.com,admin2@ex.com

三、核心代码实现(mysql_table_stats.py)

import configparser
import sqlite3
import smtplib
from email.mime.text import MIMEText
from datetime import datetime, timedelta
import mysql.connector

class TableMonitor:
    def __init__(self):
        self.config = configparser.ConfigParser()
        self.config.read('config.ini')
        
        # 初始化SQLite存储
        self.stats_conn = sqlite3.connect(self.config['storage']['stats_db'])
        self._init_sqlite()
        
    def _init_sqlite(self):
        """创建统计信息存储表"""
        cursor = self.stats_conn.cursor()
        cursor.execute('''CREATE TABLE IF NOT EXISTS table_stats
            (id INTEGER PRIMARY KEY AUTOINCREMENT,
             stat_date DATE NOT NULL,
             db_name TEXT NOT NULL,
             table_name TEXT NOT NULL,
             table_rows INTEGER,
             data_size REAL,
             index_size REAL)''')
        self.stats_conn.commit()

    def collect_stats(self):
        """采集MySQL表统计信息"""
        mysql_conf = self.config['mysql']
        conn = mysql.connector.connect(**mysql_conf)
        
        sql = f"""select
				table_schema as '数据库',
				table_name as '表名',
				table_rows as '记录数',
				truncate(data_length/1024/1024, 2) as '数据容量(MB)',
				truncate(index_length/1024/1024, 2) as '索引容量(MB)'
				from information_schema.tables
				where table_schema='mysql'
				order by data_length desc, index_length desc;
			"""
            
        cursor = conn.cursor(dictionary=True)
        cursor.execute(sql)
        
        today = datetime.now().strftime("%Y-%m-%d")
        for row in cursor:
            self._save_to_sqlite(today, row)
            
        cursor.close()
        conn.close()
        
    def _save_to_sqlite(self, date, data):
        """保存到SQLite数据库"""
        cursor = self.stats_conn.cursor()
        cursor.execute('''INSERT INTO table_stats 
            (stat_date, db_name, table_name, table_rows, data_size, index_size)
            VALUES (?,?,?,?,?,?)''',
            (date, data['TABLE_SCHEMA'], data['TABLE_NAME'], 
             data['TABLE_ROWS'], data['data_mb'], data['index_mb']))
        self.stats_conn.commit()

    def generate_report(self):
        """生成增速排名报告"""
        end_date = datetime.now()
        start_date = end_date - timedelta(days=7)
        
        cursor = self.stats_conn.cursor()
        cursor.execute('''
            SELECT 
                t1.db_name, t1.table_name,
                (t1.table_rows - COALESCE(t2.table_rows,0)) as row_growth,
                t1.data_size, t1.index_size
            FROM table_stats t1
            LEFT JOIN table_stats t2 
                ON t1.db_name = t2.db_name 
                AND t1.table_name = t2.table_name
                AND t2.stat_date = ?
            WHERE t1.stat_date = ?
            ORDER BY row_growth DESC
            LIMIT 50''', (start_date.strftime("%Y-%m-%d"), 
                         end_date.strftime("%Y-%m-%d")))
        
        return cursor.fetchall()

    def send_email(self, html_content):
        """发送HTML邮件"""
        msg = MIMEText(html_content, 'html')
        msg['Subject'] = f'MySQL表增长周报 {datetime.now().strftime("%Y-%m-%d")}'
        msg['From'] = self.config['email']['sender']
        msg['To'] = self.config['email']['receivers']

        with smtplib.SMTP(
            self.config['email']['smtp_server'],
            int(self.config['email']['smtp_port'])
        ) as server:
            server.starttls()
            server.login(
                self.config['email']['sender'],
                self.config['email']['password']
            )
            server.send_message(msg)

    def generate_html(self, data):
        """生成HTML表格"""
        html = '''<html><body>
            <h2>MySQL表增长周报 TOP50</h2>
            <table border="1" cellpadding="5">
            <tr>
                <th>数据库</th>
                <th>表名</th>
                <th>记录数</th>
                <th>数据容量(MB)</th>
                <th>索引容量(MB)</th>
            </tr>'''
        
        for row in data:
            html += f'''
            <tr>
                <td>{row[0]}</td>
                <td>{row[1]}</td>
                <td>{row[2]}</td>
                <td>{row[3]}</td>
                <td>{row[4]}</td>
            </tr>'''
            
        html += "</table></body></html>"
        return html

if __name__ == "__main__":
    monitor = TableMonitor()
    monitor.collect_stats()
    report_data = monitor.generate_report()
    html = monitor.generate_html(report_data)
    monitor.send_email(html)

四、关键实现说明

  1. 配置化管理

    • 使用configparser管理数据库连接、邮件服务等配置21
    • 不同环境只需修改配置文件,无需修改代码
  2. 统计逻辑

    • 通过information_schema获取表统计信息61
    • 计算周增长使用SQLite的时间窗口查询
  3. 存储设计

    • SQLite表记录每日统计快照34
    • 使用增量统计避免全量扫描16
  4. 邮件生成

    • 采用MIMEText生成HTML邮件51
    • 表格样式兼容主流邮件客户端
  5. 性能优化

    • 使用带缓存的MySQL连接池
    • SQLite采用批量提交事务

五、部署运行建议

  1. 配置定时任务(crontab):
# 每天凌晨执行统计
0 0 * * * /usr/bin/python3 /path/to/mysql_table_stats.py
  1. 初始化SQLite数据库:
sqlite3 statistics.db
> .schema  # 验证表结构
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学亮编程手记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值