\x89PNG\r\n\x1a\n\x00\x00\x00\x0DIHDR\x00\x00\x00\x01\x00 \x00\x00\x01\x08\x06\x00\x00\x00\x1F\x15\xC4\x89\x00\x00\x00 \x0AIDATx\x9Ccb\x00\x00\x00\x06\x00\x03\x1A\x05\x9D\x00\x00 \x00\x00IEND\xAE\x42\x60\x82
| Path : /var/www/html/yedekledb24/DatabaseBackupMasterv8/ |
|
B-Con CMD Config cPanel C-Rdp D-Log Info Jump Mass Ransom Symlink vHost Zone-H |
| Current File : /var/www/html/yedekledb24/DatabaseBackupMasterv8/mysql_performance_charts.py |
"""
MySQL/MariaDB performans verilerini görselleştirmek için script.
Bu script, MySQL/MariaDB'den alınan sorgu performans verilerini Pandas DataFrame'e dönüştürür
ve Matplotlib kullanarak statik grafikler oluşturur.
"""
import os
import sys
import json
import logging
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
from datetime import datetime
import pymysql
# Türkçe karakterleri düzgün gösterme
plt.rcParams['font.family'] = 'DejaVu Sans'
# Log yapılandırması
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# Grafik dizini
CHART_DIR = os.path.join('static', 'charts')
os.makedirs(CHART_DIR, exist_ok=True)
def get_top_queries(connection_info, limit=10, order_by='total_time'):
"""
MySQL/MariaDB veritabanından en çok kaynak tüketen sorguları alır ve DataFrame olarak döndürür.
"""
try:
# Bağlantı kur
connection = pymysql.connect(
host=connection_info['host'],
port=connection_info['port'],
user=connection_info['username'],
password=connection_info['password'],
database=connection_info['database']
)
cursor = connection.cursor()
# Performance Schema etkin mi kontrol et
cursor.execute("SHOW VARIABLES LIKE 'performance_schema'")
performance_schema_enabled = cursor.fetchone()
if not performance_schema_enabled or performance_schema_enabled[1].lower() != 'on':
logger.error("Performance Schema etkin değil.")
return pd.DataFrame(), {'total_calls': 0, 'total_time': 0, 'query_count': 0}
# Sıralama sütununu belirle
order_column = "SUM_TIMER_WAIT DESC"
if order_by == "calls":
order_column = "COUNT_STAR DESC"
elif order_by == "rows":
order_column = "SUM_ROWS_AFFECTED DESC"
# Sorguyu çalıştır
query = """
SELECT
DIGEST_TEXT as query,
COUNT_STAR as calls,
SUM_ROWS_AFFECTED as affected_rows,
SUM_TIMER_WAIT/1000000000 as total_time,
AVG_TIMER_WAIT/1000000000 as avg_time,
ROUND(100 * SUM_TIMER_WAIT / (SELECT SUM(SUM_TIMER_WAIT)
FROM performance_schema.events_statements_summary_by_digest), 2) as percentage_cpu
FROM performance_schema.events_statements_summary_by_digest
WHERE SCHEMA_NAME = %s
ORDER BY {}
LIMIT %s
""".format(order_column)
cursor.execute(query, (connection_info['database'], limit))
# Sonuçları DataFrame'e dönüştür
columns = [desc[0] for desc in cursor.description]
rows = cursor.fetchall()
if not rows:
logger.warning("Sorgu sonucu boş.")
return pd.DataFrame(), {'total_calls': 0, 'total_time': 0, 'query_count': 0}
df = pd.DataFrame(rows, columns=columns)
# Özet bilgileri al
summary_query = """
SELECT
COALESCE(SUM(COUNT_STAR), 0) as total_calls,
COALESCE(SUM(SUM_TIMER_WAIT)/1000000000, 0) as total_time,
COUNT(*) as query_count
FROM performance_schema.events_statements_summary_by_digest
WHERE SCHEMA_NAME = %s
"""
cursor.execute(summary_query, (connection_info['database'],))
summary_row = cursor.fetchone()
summary = {
'total_calls': int(summary_row[0]),
'total_time': float(summary_row[1]),
'query_count': int(summary_row[2])
}
# Bağlantıyı kapat
cursor.close()
connection.close()
# DataFrame'i biraz düzenle
# Kısa sorgu etiketleri oluştur
df['short_query'] = df['query'].apply(lambda x: (str(x)[:20] + '...') if x and len(str(x)) > 20 else x)
# affected_rows sütun adını rows olarak değiştir (geriye dönük uyumluluk için)
if 'affected_rows' in df.columns and 'rows' not in df.columns:
df['rows'] = df['affected_rows']
return df, summary
except Exception as e:
logger.error(f"MySQL sorgu verisi alınırken hata: {str(e)}")
# Boş DataFrame ve özet bilgi döndür
return pd.DataFrame(), {'total_calls': 0, 'total_time': 0, 'query_count': 0}
def create_charts(df, db_id, timestamp=None):
"""
DataFrame'deki verilerden dört farklı grafik oluşturur ve kaydeder.
Returns:
dict: Grafik dosyalarının yollarını içeren bir sözlük
"""
if df.empty:
logger.warning("Boş DataFrame, grafikler oluşturulamadı.")
return {}
# Zaman damgası
ts = timestamp or datetime.now().strftime("%Y%m%d%H%M%S")
# Grafik dosya adları
chart_files = {
'execution_time': f"{CHART_DIR}/mysql_exec_time_{db_id}_{ts}.png",
'cpu_percentage': f"{CHART_DIR}/mysql_cpu_pct_{db_id}_{ts}.png",
'calls': f"{CHART_DIR}/mysql_calls_{db_id}_{ts}.png",
'scatter': f"{CHART_DIR}/mysql_scatter_{db_id}_{ts}.png"
}
# Görsel stil ayarları
plt.style.use('dark_background')
mpl.rcParams['axes.edgecolor'] = '#666'
mpl.rcParams['axes.facecolor'] = '#222'
mpl.rcParams['figure.facecolor'] = '#222'
mpl.rcParams['grid.color'] = '#444'
mpl.rcParams['text.color'] = '#DDD'
mpl.rcParams['axes.labelcolor'] = '#DDD'
mpl.rcParams['xtick.color'] = '#DDD'
mpl.rcParams['ytick.color'] = '#DDD'
# Renkler
colors = ['#3498db', '#e74c3c', '#2ecc71', '#f39c12', '#9b59b6',
'#1abc9c', '#d35400', '#34495e', '#7f8c8d', '#27ae60']
try:
# 1. Çalışma Süresi Grafiği
plt.figure(figsize=(10, 6))
bars = plt.bar(range(len(df)), df['total_time'], color=colors[:len(df)])
plt.xticks(range(len(df)), df['short_query'], rotation=45, ha='right')
plt.xlabel('Sorgular')
plt.ylabel('Çalışma Süresi (ns)')
plt.title('Sorgu Çalışma Süresi Dağılımı (MySQL/MariaDB)')
plt.tight_layout()
plt.savefig(chart_files['execution_time'], dpi=100)
plt.close()
# 2. CPU Yüzdesi Grafiği (Pasta)
plt.figure(figsize=(10, 6))
plt.pie(df['percentage_cpu'], labels=df['short_query'], autopct='%1.1f%%', startangle=90, colors=colors[:len(df)])
plt.axis('equal')
plt.title('CPU Kullanım Yüzdesi (MySQL/MariaDB)')
plt.tight_layout()
plt.savefig(chart_files['cpu_percentage'], dpi=100)
plt.close()
# 3. Çağrı Sayısı Grafiği
plt.figure(figsize=(10, 6))
plt.bar(range(len(df)), df['calls'], color='#2ecc71')
plt.xticks(range(len(df)), df['short_query'], rotation=45, ha='right')
plt.xlabel('Sorgular')
plt.ylabel('Çağrı Sayısı')
plt.title('Sorgu Çağrı Sayısı (MySQL/MariaDB)')
plt.tight_layout()
plt.savefig(chart_files['calls'], dpi=100)
plt.close()
# 4. Scatter Plot (Çalışma Süresi vs CPU Yüzdesi)
plt.figure(figsize=(10, 6))
scatter = plt.scatter(df['total_time'], df['percentage_cpu'], s=df['calls'],
alpha=0.6, c=range(len(df)), cmap='viridis')
# Nokta etiketleri
for i, txt in enumerate(df['short_query']):
plt.annotate(txt, (df['total_time'].iloc[i], df['percentage_cpu'].iloc[i]),
xytext=(5, 5), textcoords='offset points', fontsize=8)
plt.xlabel('Çalışma Süresi (ns)')
plt.ylabel('CPU Kullanımı (%)')
plt.title('Süre ve CPU Kullanımı İlişkisi (MySQL/MariaDB)')
plt.tight_layout()
plt.savefig(chart_files['scatter'], dpi=100)
plt.close()
logger.info(f"MySQL grafikleri başarıyla oluşturuldu ve {CHART_DIR} dizinine kaydedildi.")
return chart_files
except Exception as e:
logger.error(f"MySQL grafikleri oluşturulurken hata: {str(e)}")
return {}
def main(db_id=None, limit=10, order_by='total_time'):
"""
Ana fonksiyon - veritabanı ID'si için grafikleri oluşturur.
"""
from models import DatabaseConnection
from sqlalchemy.orm import scoped_session, sessionmaker
from app import db
try:
# Oturum oluştur
Session = scoped_session(sessionmaker(bind=db.engine))
session = Session()
# Veritabanı bağlantısını al
db_conn = session.query(DatabaseConnection).filter_by(id=db_id).first()
if not db_conn:
logger.error(f"ID={db_id} olan veritabanı bulunamadı.")
return None
# Bağlantı bilgilerini hazırla
connection_info = {
'host': db_conn.host,
'port': db_conn.port,
'username': db_conn.username,
'password': db_conn.password,
'database': db_conn.database
}
# Sadece MySQL/MariaDB için çalışır
if db_conn.db_type not in ['mysql', 'mariadb']:
logger.error("Bu script sadece MySQL ve MariaDB için çalışır.")
return None
# Verileri al ve grafikleri oluştur
df, summary = get_top_queries(connection_info, limit, order_by)
charts = create_charts(df, db_id)
Session.remove()
return {
'charts': charts,
'summary': summary,
'query_count': len(df)
}
except Exception as e:
logger.error(f"Hata: {str(e)}")
return None
if __name__ == "__main__":
# Komut satırından çalıştırıldığında
if len(sys.argv) > 1:
db_id = int(sys.argv[1])
limit = int(sys.argv[2]) if len(sys.argv) > 2 else 10
order_by = sys.argv[3] if len(sys.argv) > 3 else 'total_time'
result = main(db_id, limit, order_by)
print(json.dumps(result, indent=2))
else:
print("Kullanım: python mysql_performance_charts.py <db_id> [limit] [order_by]")