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 :
Bon audit de volumétrie !!
David BARBARIN (Mikedavem)
Elève ingénieur CNAM Lyon