\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/DatabaseBackupMasterv5/
(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/DatabaseBackupMasterv5/database_performance.py


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
PostgreSQL veritabanı performans metrikleri için yardımcı fonksiyonlar.
Bu modül, pg_stat_statements kullanarak sunucularda çalışan sorguların performans verilerini alır.
"""

import os
import logging
from datetime import datetime, timedelta
import psycopg2
from psycopg2 import sql

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

def pg_stat_statements_enabled(connection):
    """
    PostgreSQL sunucusunda pg_stat_statements'ın etkin olup olmadığını kontrol eder.
    
    Args:
        connection: PostgreSQL bağlantı nesnesi
        
    Returns:
        bool: Modül yüklüyse True, değilse False
    """
    try:
        cursor = connection.cursor()
        cursor.execute("SELECT 1 FROM pg_extension WHERE extname = 'pg_stat_statements'")
        extension_exists = cursor.fetchone() is not None
        
        # Eğer modül yüklüyse, shared_preload_libraries içinde olup olmadığını da kontrol et
        if extension_exists:
            cursor.execute("SHOW shared_preload_libraries")
            libraries = cursor.fetchone()[0]
            if libraries and 'pg_stat_statements' in libraries:
                return True
        
        return False
    except Exception as e:
        logger.error(f"pg_stat_statements kontrol edilirken hata: {str(e)}")
        return False

def enable_pg_stat_statements(connection):
    """
    PostgreSQL sunucusunda pg_stat_statements'ı etkinleştirir.
    
    Args:
        connection: PostgreSQL bağlantı nesnesi
        
    Returns:
        dict: İşlem sonucu (success, message)
    """
    try:
        cursor = connection.cursor()
        
        # Önce extension'ın zaten var olup olmadığını kontrol et
        cursor.execute("SELECT 1 FROM pg_extension WHERE extname = 'pg_stat_statements'")
        if cursor.fetchone() is None:
            # Extension'ı kur
            cursor.execute("CREATE EXTENSION IF NOT EXISTS pg_stat_statements")
            connection.commit()
            return {"success": True, "message": "pg_stat_statements eklentisi kuruldu. Sunucuyu yeniden başlatmanız gerekebilir."}
        
        return {"success": True, "message": "pg_stat_statements eklentisi zaten kurulu."}
    except Exception as e:
        logger.error(f"pg_stat_statements etkinleştirilirken hata: {str(e)}")
        return {"success": False, "message": f"Hata: {str(e)}"}

def get_top_queries(db_conn, limit=20, order_by='total_time', interval=None):
    """
    PostgreSQL sunucusunda en çok kaynak tüketen sorguları alır.
    
    Args:
        db_conn: PostgreSQL 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:
        list: Sorgu istatistikleri listesi
    """
    try:
        # Bağlantı yap
        conn_str = f"host={db_conn['host']} port={db_conn['port']} user={db_conn['username']} password={db_conn['password']} dbname={db_conn['database']}"
        connection = psycopg2.connect(conn_str)
        
        # pg_stat_statements'ın etkin olup olmadığını kontrol et
        if not pg_stat_statements_enabled(connection):
            return {"success": False, "message": "pg_stat_statements modülü etkin değil.", "data": []}
        
        cursor = connection.cursor()
        
        # PostgreSQL 13 ve üzeri için query
        pg_version_query = "SHOW server_version"
        cursor.execute(pg_version_query)
        pg_version = cursor.fetchone()[0]
        pg_version_major = int(pg_version.split('.')[0])
        
        # PG13 ve üzeri için total_time yerine total_exec_time kullanılır
        time_column = "total_exec_time" if pg_version_major >= 13 else "total_time"
        
        # Sıralama kriteri
        if order_by == 'total_time':
            order_column = time_column + " DESC"
        elif order_by == 'calls':
            order_column = "calls DESC"
        elif order_by == 'rows':
            order_column = "rows DESC" 
        else:
            order_column = time_column + " DESC"
        
        # Reset isteği varsa, istatistikleri sıfırla
        if interval and interval == 'reset':
            cursor.execute("SELECT pg_stat_statements_reset()")
            connection.commit()
            return {"success": True, "message": "Sorgu istatistikleri sıfırlandı.", "data": []}

        # PG13 ve üzeri farklı bir query yapısına sahip
        if pg_version_major >= 13:
            query = f"""
            SELECT 
                query,
                calls,
                rows,
                {time_column} as total_time,
                {time_column}/calls as avg_time,
                min_exec_time as min_time,
                max_exec_time as max_time,
                mean_exec_time as mean_time,
                stddev_exec_time as stddev_time,
                100.0 * {time_column} / sum({time_column}) OVER() AS percentage_cpu
            FROM pg_stat_statements
            ORDER BY {order_column}
            LIMIT %s
            """
        else:
            # PG12 ve altı için
            query = f"""
            SELECT 
                query,
                calls,
                rows,
                {time_column} as total_time,
                {time_column}/calls as avg_time,
                min_time,
                max_time,
                mean_time,
                stddev_time,
                100.0 * {time_column} / sum({time_column}) OVER() AS percentage_cpu
            FROM pg_stat_statements
            ORDER BY {order_column}
            LIMIT %s
            """
        
        cursor.execute(query, (limit,))
        results = cursor.fetchall()
        
        # Sonuçları işle ve formatla
        columns = [desc[0] for desc in cursor.description]
        data = []
        for row in results:
            data_row = {}
            for i, value in enumerate(row):
                if columns[i] == 'query':
                    # Sorguyu kısalt ve SQL formatı ekle
                    if value and len(value) > 500:
                        value = value[:500] + '...'
                    data_row[columns[i]] = value
                elif columns[i] in ['total_time', 'avg_time', 'min_time', 'max_time', 'mean_time', 'stddev_time']:
                    # Zamanları ms cinsinden formatla
                    if value:
                        data_row[columns[i]] = f"{value:.2f} ms"
                    else:
                        data_row[columns[i]] = "N/A"
                elif columns[i] == 'percentage_cpu':
                    # Yüzdeyi formatla
                    if value:
                        data_row[columns[i]] = f"{value:.2f}%"
                    else:
                        data_row[columns[i]] = "N/A"
                else:
                    data_row[columns[i]] = value
            data.append(data_row)
            
        # Veri özetini getir
        summary_query = """
        SELECT 
            sum(calls) as total_calls,
            sum(rows) as total_rows,
            sum(total_exec_time) as total_exec_time,
            count(*) as query_count
        FROM pg_stat_statements
        """
        cursor.execute(summary_query)
        summary = cursor.fetchone()
        summary_data = {
            "total_calls": summary[0],
            "total_rows": summary[1],
            "total_exec_time": f"{summary[2]:.2f} ms",
            "query_count": summary[3],
            "pg_version": pg_version
        }
        
        connection.close()
        return {"success": True, "message": "Veriler başarıyla alındı", "data": data, "summary": summary_data, "pg_version": pg_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):
    """
    PostgreSQL veritabanı hakkında genel istatistikleri getirir.
    
    Args:
        db_conn: PostgreSQL bağlantı bilgileri (dict)
        
    Returns:
        dict: Veritabanı istatistikleri
    """
    try:
        # Bağlantı yap
        conn_str = f"host={db_conn['host']} port={db_conn['port']} user={db_conn['username']} password={db_conn['password']} dbname={db_conn['database']}"
        connection = psycopg2.connect(conn_str)
        cursor = connection.cursor()
        
        # Veritabanı boyutu
        cursor.execute("SELECT pg_size_pretty(pg_database_size(current_database()))")
        db_size = cursor.fetchone()[0]
        
        # Tablo sayısı
        cursor.execute("SELECT count(*) FROM information_schema.tables WHERE table_schema NOT IN ('pg_catalog', 'information_schema')")
        table_count = cursor.fetchone()[0]
        
        # İndeks sayısı
        cursor.execute("SELECT count(*) FROM pg_indexes WHERE schemaname NOT IN ('pg_catalog', 'information_schema')")
        index_count = cursor.fetchone()[0]
        
        # Aktif bağlantı sayısı
        cursor.execute("SELECT count(*) FROM pg_stat_activity WHERE state = 'active'")
        active_connections = cursor.fetchone()[0]
        
        # En büyük tablolar
        cursor.execute("""
        SELECT 
            relname as table_name, 
            pg_size_pretty(pg_total_relation_size(relid)) as total_size
        FROM pg_catalog.pg_statio_user_tables
        ORDER BY pg_total_relation_size(relid) DESC
        LIMIT 5
        """)
        largest_tables = []
        for row in cursor.fetchall():
            largest_tables.append({"table_name": row[0], "size": row[1]})
            
        # En sık kullanılan tablolar
        cursor.execute("""
        SELECT 
            relname as table_name, 
            seq_scan + idx_scan as total_scans
        FROM pg_stat_user_tables
        ORDER BY total_scans DESC
        LIMIT 5
        """)
        most_accessed_tables = []
        for row in cursor.fetchall():
            most_accessed_tables.append({"table_name": row[0], "scans": row[1]})
            
        # En az verimli indeksler
        cursor.execute("""
        SELECT
            indexrelname as index_name,
            relname as table_name,
            idx_scan as scans
        FROM pg_stat_user_indexes
        ORDER BY idx_scan ASC
        LIMIT 5
        """)
        least_used_indexes = []
        for row in cursor.fetchall():
            least_used_indexes.append({"index_name": row[0], "table_name": row[1], "scans": row[2]})
            
        connection.close()
        
        return {
            "success": True,
            "message": "Veritabanı istatistikleri başarıyla alındı",
            "data": {
                "db_size": db_size,
                "table_count": table_count,
                "index_count": index_count,
                "active_connections": active_connections,
                "largest_tables": largest_tables,
                "most_accessed_tables": most_accessed_tables,
                "least_used_indexes": least_used_indexes
            }
        }
    
    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: PostgreSQL bağlantı bilgileri (dict)
        table_name (str): Tablo adı
        
    Returns:
        dict: Tablo istatistikleri
    """
    try:
        # Bağlantı yap
        conn_str = f"host={db_conn['host']} port={db_conn['port']} user={db_conn['username']} password={db_conn['password']} dbname={db_conn['database']}"
        connection = psycopg2.connect(conn_str)
        cursor = connection.cursor()
        
        # Güvenli SQL oluştur
        table_query = sql.SQL("SELECT * FROM pg_stat_user_tables WHERE relname = %s")
        cursor.execute(table_query, (table_name,))
        stats = cursor.fetchone()
        
        if not stats:
            return {"success": False, "message": f"Tablo bulunamadı: {table_name}", "data": {}}
        
        # Tablo boyutu
        size_query = sql.SQL("SELECT pg_size_pretty(pg_total_relation_size(%s))")
        cursor.execute(size_query, (table_name,))
        table_size = cursor.fetchone()[0]
        
        # İndeks bilgileri
        index_query = sql.SQL("""
        SELECT
            indexrelname as index_name,
            idx_scan as scans,
            pg_size_pretty(pg_relation_size(indexrelid)) as index_size
        FROM pg_stat_user_indexes
        WHERE relname = %s
        ORDER BY idx_scan DESC
        """)
        cursor.execute(index_query, (table_name,))
        indexes = []
        for row in cursor.fetchall():
            indexes.append({
                "index_name": row[0],
                "scans": row[1],
                "index_size": row[2]
            })
            
        # Sütun bilgileri
        column_query = sql.SQL("""
        SELECT
            column_name,
            data_type,
            character_maximum_length
        FROM information_schema.columns
        WHERE table_name = %s
        ORDER BY ordinal_position
        """)
        cursor.execute(column_query, (table_name,))
        columns = []
        for row in cursor.fetchall():
            columns.append({
                "column_name": row[0],
                "data_type": row[1],
                "max_length": row[2]
            })
            
        # Satır sayısı (yaklaşık)
        count_query = sql.SQL("SELECT reltuples::bigint FROM pg_class WHERE relname = %s")
        cursor.execute(count_query, (table_name,))
        row_count = cursor.fetchone()[0]
        
        connection.close()
        
        return {
            "success": True,
            "message": f"{table_name} tablosu istatistikleri başarıyla alındı",
            "data": {
                "table_name": table_name,
                "table_size": table_size,
                "row_count": row_count,
                "seq_scan": stats[4],
                "seq_tup_read": stats[5],
                "idx_scan": stats[6],
                "idx_tup_fetch": stats[7],
                "n_tup_ins": stats[8],
                "n_tup_upd": stats[9],
                "n_tup_del": stats[10],
                "n_live_tup": stats[12],
                "n_dead_tup": stats[13],
                "last_vacuum": stats[14],
                "last_autovacuum": stats[15],
                "last_analyze": stats[16],
                "last_autoanalyze": stats[17],
                "indexes": indexes,
                "columns": columns
            }
        }
    
    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