Voici mon scénario: nous avons une base de données, appelons-la Logging, avec une table qui contient des enregistrements de Log4Net (via MSMQ). Le mode de récupération de la base de données est défini sur Simple: les journaux de transactions ne nous intéressent pas: ils peuvent être reconduits.Sql Server: les suppressions de segment remplissent toujours le journal des transactions; en cas d'échec, toutes les suppressions sont annulées - pourquoi?
Nous avons un travail qui utilise des données de sp_spaceused pour déterminer si nous avons atteint un certain seuil de taille. Si le seuil est dépassé, nous déterminons combien de lignes doivent être supprimées pour ramener la taille à x% de ce seuil. (En aparté, j'utilise exec sp_spaceused MyLogTable
, TRUE
pour obtenir le nombre de lignes et une approximation grossière de leur taille moyenne, même si je ne suis pas convaincu que ce soit la meilleure façon d'y arriver, mais c'est un problème différent.)
J'essaie ensuite de morceau supprime (disons, 5000 à la fois) en bouclant un appel à une procédure stockée qui fait essentiellement ceci:
DELETE TOP (@RowsToDelete) FROM [dbo].[MyLogTable]
jusqu'à ce que j'ai supprimé ce qui doit être supprimé.
Voici le problème: Si j'ai beaucoup de lignes à supprimer, le fichier du journal des transactions se remplit. Je peux le regarder grandir en exécutant
dbcc sqlperf (logspace)
Ce qui me déconcerte est que, lorsque le travail échoue, toutes les lignes supprimées se révulsés. En d'autres termes, il semble que tous les morceaux soient enveloppés (en quelque sorte) dans une transaction implicite.
J'ai essayé explicitement de désactiver les transactions implicites, en encapsulant chaque instruction DELETE dans un BEGIN et un COMMIT TRAN, mais en vain: tous les blocs supprimés réussissent, ou pas du tout.
Je sais que la réponse est simple, faites en sorte que votre fichier journal soit assez grand pour gérer le plus grand nombre possible d'enregistrements que vous ayez jamais supprimés, mais pourquoi est-ce traité comme une seule transaction?
Désolé si j'ai manqué quelque chose de facile, mais j'ai regardé beaucoup de messages concernant la croissance du fichier journal, les modes de récupération, etc., et je ne peux pas comprendre cela.
Une autre chose: une fois que le travail a échoué, le fichier journal reste à environ 95 - 100% plein pendant un certain temps avant de retomber. Cependant, si j'exécute
checkpoint
dbcc dropcleanbuffers
il redescend à environ 5% d'utilisation.
TIA.
Piotr, merci pour votre suggestion s. En fait, j'ai exécuté un sproc "pilote" à partir de Query Analyzer. Votre question à propos d'une transaction externe me fait me demander, Est-ce que Query Analyzer a activé implicit_transactions par défaut? J'ai vérifié Profilier et je n'ai pas vu ça. Cependant, je vais réessayer avec SET IMPLICIT_TRANSACTIONS OFF dans ma session Query Analyzer et voir si cela fait une différence (que tout ou partie soit annulé en cas d'échec). Je vais republier quand j'ai effectué ce test. Merci, Paul –