Utiliser l’historique des sauvegardes des bases pour analyser les tendances de volumétrie des données

Une de mes tâches du moment est de pouvoir justifier ou non d’une éventuelle extension de disques  sur le SAN en fonction de l’évolution du volume des données des bases. Cela peut se faire de plusieurs façons mais une méthode simple est de se baser sur l’historique des sauvegardes complètes des bases qui sont vraiment représentatives des données réelles qu’elles hébergent.

Pour cela il suffit d’interroger les tables systèmes backupfile ( qui fournit des informations sur les fichiers ou journaux des bases de données) et backupset ( qui fournit des informations sur l’historique des jeux de sauvegardes) dans la base de données msdb.

Le script suivant se base sur ces tables systèmes et proposent un suivi par mois et par année de la volumétrie des sauvegardes qui permettra de dresser un bilan d’évolution des données et donc en déduire un prévisionnel d’extension de place disques si besoin.

DECLARE @database_name SYSNAME;
DECLARE @previousNbYear INT;

– @database_name
– Nom de la base ou NULL pour toutes les bases
SET @database_name = NULL;

– @previousNbYear
– Nombre d’années d’historiques à visualer (>=0)
SET @previousNbYear = 0;

WITH CTE_BACKUP_YEAR_MONTH_BACKUP_SET_ID
AS
(   
    SELECT
        bs.database_name,
        bs.backup_set_id,
        bs.type AS type_backup,
        MONTH(backup_start_date) AS backup_month,
        YEAR(backup_start_date) AS backup_year,
        bf.backup_size / 1024 / 1024 AS backup_size_Mo
    FROM msdb.dbo.backupfile bf
    INNER JOIN msdb.dbo.backupset bs
    ON bf.backup_set_id = bs.backup_set_id
    WHERE (database_name = @database_name OR @database_name IS NULL)
      AND YEAR(bs.backup_start_date) >= DATEADD(YY,-1 * @previousNbYear,YEAR(GETDATE()))
       AND bs.type = ‘D’
),
CTE_SUM_BACKUP_SIZE_AVG_DURATION
AS
(
    SELECT
        database_name,
        type_backup,
        backup_month,
        backup_year,
        SUM(backup_size_Mo) AS backup_size_Mo
    FROM CTE_BACKUP_YEAR_MONTH_BACKUP_SET_ID
    GROUP BY database_name,backup_set_id, type_backup, backup_year, backup_month
),
CTE_SUM_BACKUP_SIZE_AVG_DURATION_PER_MONTH
AS
(
    SELECT
        ROW_NUMBER() OVER(ORDER BY database_name, type_backup, backup_year DESC, backup_month DESC) AS num,
        database_name,
        type_backup,
        backup_year,
        backup_month,
        CAST(AVG(backup_size_Mo) AS DECIMAL(10,2)) AS avg_backup_size_Mo
    FROM CTE_SUM_BACKUP_SIZE_AVG_DURATION
    GROUP BY database_name, type_backup, backup_year, backup_month
),
CTE_SUMMARIZE_DIFFERENCE
AS
(
    SELECT
        c1.database_name,
        CASE c1.type_backup
            WHEN ‘D’ THEN ‘1 – FULL’
            WHEN ‘I’ THEN ‘2 – DIFFERENTIAL’
            WHEN ‘L’ THEN ‘3 – JOURNAL’
            WHEN ‘F’ THEN ‘4 – FILEGROUP FULL’
            WHEN ‘G’ THEN ‘5 – FILEGROUP DIFFERENTIAL’
            WHEN ‘P’ THEN ‘6 – PARTIAL’
            ELSE ‘7 – PARTIAL DIFFERENTIAL’
        END AS type_backup,
        c1.backup_year,
        c1.backup_month,
        c1.avg_backup_size_Mo,
        c2.backup_month AS backup_month_previous,
        c2.avg_backup_size_Mo AS avg_backup_size_previous_Mo,
        c1.avg_backup_size_Mo – c2.avg_backup_size_Mo AS size_difference_backup_Mo,
        CAST(CAST((c1.avg_backup_size_Mo – c2.avg_backup_size_Mo) / c2.avg_backup_size_Mo * 100.00 AS DECIMAL(10,2)) AS VARCHAR(10))
         + ‘%’ AS difference_size_ratio
    FROM CTE_SUM_BACKUP_SIZE_AVG_DURATION_PER_MONTH c1
    INNER JOIN CTE_SUM_BACKUP_SIZE_AVG_DURATION_PER_MONTH c2
    ON c1.num = c2.num – 1
     AND c1.database_name = c2.database_name
    WHERE c1.avg_backup_size_Mo – c2.avg_backup_size_Mo >= 0 — On supprime les backups qui n’ont pas évolués.
)
SELECT
    database_name,
    type_backup,   
    backup_year,
    backup_month,
    avg_backup_size_Mo,
    backup_month_previous,
    avg_backup_size_previous_Mo,
    size_difference_backup_Mo,
    difference_size_ratio
FROM CTE_SUMMARIZE_DIFFERENCE
UNION ALL
SELECT
    database_name,
    type_backup,   
    backup_year,   
    NULL,
    MAX(avg_backup_size_Mo),
    NULL,
    NULL,
    SUM(size_difference_backup_Mo),
    CAST(CAST(SUM(size_difference_backup_Mo) / MAX(avg_backup_size_Mo) * 100.00 AS DECIMAL(10,2)) AS VARCHAR(10))
     + ‘%’
FROM CTE_SUMMARIZE_DIFFERENCE
GROUP BY database_name, type_backup, backup_year
ORDER BY database_name, type_backup, backup_year DESC, backup_month DESC;

et un extrait de résultat :

result_audit_volumetrie

Bon audit de volumétrie !!

David BARBARIN (Mikedavem)
Elève ingénieur CNAM Lyon

Laisser un commentaire