web-dev-qa-db-fra.com

Espace journal TempDB et ACTIVE_TRANSACTION

Notre solution de surveillance (SCOM) signale actuellement que le journal tempdb manque d'espace. Cependant, nous avons une croissance automatique définie sur des morceaux de 1 Go pour le journal et il nous reste 25 Go d'espace sur le lecteur.

J'ai regardé ce que le log_reuse_wait_desc était et l'a trouvé ACTIVE_TRANSACTION

J'ai commencé à me demander si, pour une raison quelconque, le fichier journal se remplissait et que la croissance automatique ne se déclenche pas, et après quelques recherches, j'ai constaté que le fichier journal devrait continuer de croître même pendant un ACTIVE_TRANSACTION.

J'ai trouvé un article sur un problème similaire où le journal tempdb manquait d'espace:

http://sqltimes.wordpress.com/2014/07/05/sql-server-error-messages-the-transaction-log-for-database-tempdb-is-full-due-to-active_transaction/

Ici, ils ont émis un CHECKPOINT pour résoudre le problème sur tempdb. Je sais qu'un CHECKPOINT vide les pages sales sur le disque, mais je ne comprends pas comment cela résoudrait le ACTIVE_TRANSACTION problème?

De plus, je ne sais pas non plus pourquoi nous recevons cette alerte alors qu'il y a beaucoup d'espace. Existe-t-il une situation dans laquelle un tempdb peut se remplir et la croissance automatique ne fonctionne pas pour une raison quelconque?

7
Tom

Comme Max l'a mentionné, l'alerte a probablement été déclenchée juste avant que le journal ne croisse/ait besoin de croître. SCOM collecte% d'espace libre dans le journal des transactions, bien que je ne sois pas sûr à quel seuil l'alerte se déclenchera.

voici un exemple rapide pour vous montrer dans quel état tempdb se trouve probablement lorsque vous recevez ces alertes mais pas de croissance du fichier journal.

créez d'abord une base de données, définissez la récupération sur complète et sauvegardez-la

    create database tlogspace
    on(name=tlogspace_dat,
        filename='c:\temp\tlogspace.mdf',
        size=4MB)
    log on (name=tlogspace_log,
        filename='c:\temp\tlogspace.ldf',
        size=1MB);
    go

    alter database tlogspace set recovery full;
    go
    backup database tlogspace to disk='nul';
    go

basculez maintenant vers cette base de données, créez une table et exécutez DBCC sqlperf (logspace) pour vérifier la taille et l'espace libre dans votre fichier journal.

use tlogspace
go

create table data(id int identity(1,1), col varchar(8000))
dbcc sqlperf(logspace)

Sur mon système, j'ai une taille de fichier journal de 0,9921875 et un espace journal utilisé (%) de 48,4245. Insérez maintenant des données dans la table et exécutez à nouveau DBCC sqlperf (logspace). Sur mon système, 45 lignes insérées ont donné les résultats souhaités (le nombre de lignes insérées peut devoir être ajusté).

insert into data(col)
select replicate('a',8000)
go 45 --may need to adjust number
dbcc sqlperf(logspace)

Cette fois, la sortie DBCC sqlperf doit montrer que la taille du journal est la même mais que l'espace utilisé est un peu moins de 100%. Dans ce cas, SCOM déclencherait probablement une alerte indiquant que l'espace de journalisation est faible. Il n'y a plus d'activité en cours pour provoquer la croissance du fichier journal et (dans cet exemple) aucune sauvegarde de journal pour libérer de l'espace utilisé. tempdb est en récupération simple, donc votre transaction active a probablement utilisé la plupart de l'espace disponible et ne l'a pas libéré mais il n'y avait pas assez d'activité dans tempdb pour déclencher la croissance du fichier journal provoquant ainsi le déclenchement de l'alerte.

nettoyer la base de données une fois terminé

use master
drop database tlogspace
3
Bob Klimes

Cela ne répond pas à votre question, mais j'ai pensé que vous pourriez trouver utile de voir s'il y a eu des augmentations de journaux récentes:

/*
    Description:    display growth events for all databases on the instance
    by:             Max Vernon
    date:           2014-10-01
*/
DECLARE @Version NVARCHAR(255);
DECLARE @VersionINT INT;
SET @Version = CONVERT(NVARCHAR(255),SERVERPROPERTY('ProductVersion'));
SET @VersionINT = CONVERT(INT, SUBSTRING(@Version,1 ,CHARINDEX('.',@Version)-1));
DECLARE @cmd NVARCHAR(2000);
SET @cmd = '';
IF @VersionINT >= 9
BEGIN
    SET @cmd = 
'
DECLARE @trcfilename VARCHAR(1000);

SELECT @trcfilename = path 
FROM sys.traces 
WHERE is_default = 1;

IF COALESCE(@trcfilename,'''') <> ''''
BEGIN
SELECT
    '''''''' + @@SERVERNAME + '''''','''''' +
     DB_NAME(mf.database_id) + '''''','''''' +
     mf.name + '''''','' +
     CONVERT(VARCHAR(255), a.NumberOfGrowths) + '','' +
     CONVERT(VARCHAR(255), CAST(a.DurationOfGrowthsInSeconds AS decimal(38, 20)))
    FROM
    (
        SELECT
            tt.DatabaseID AS database_id,
            tt.FileName AS LogicalFileName,
            COUNT(*) AS NumberOfGrowths,
            SUM(tt.Duration / (1000 * 1000.0)) AS DurationOfGrowthsInSeconds
            FROM sys.fn_trace_gettable(@trcfilename, default) tt
            WHERE (EventClass IN (92, 93))
            GROUP BY
                tt.DatabaseID,
                tt.FileName
    ) a
    INNER JOIN sys.master_files mf ON
        (mf.database_id = a.database_id) AND
        (mf.name = a.LogicalFileName);
END
ELSE
BEGIN
    SELECT @@SERVERNAME, ''NO TRACE FILE'';
END
';
EXEC sp_executesql @cmd;
END
ELSE
BEGIN
    SELECT @@SERVERNAME, SERVERPROPERTY('ProductVersion');
END
0
Max Vernon