{"id":542,"date":"2012-06-30T00:00:50","date_gmt":"2012-06-29T22:00:50","guid":{"rendered":"http:\/\/www.sqlserver.fr\/blog\/?p=542"},"modified":"2026-05-02T14:31:10","modified_gmt":"2026-05-02T12:31:10","slug":"log-complet-et-usage","status":"publish","type":"post","link":"https:\/\/www.sqlserver.fr\/blog\/log-complet-et-usage\/","title":{"rendered":"Log complet et usage"},"content":{"rendered":"<p>L&rsquo;expansion non contr\u00f4l\u00e9e du fichier de log d&rsquo;une base de donn\u00e9es SQL Server est un sujet r\u00e9curent dans les forums de discussion.<\/p>\n<p>Cet article a pour objectif d&rsquo;expliquer ce qu&rsquo;est le fichier de log inh\u00e9rent au fonctionnement de SQL Server, et les r\u00e8gles de base du param\u00e9trage dont il doit faire l&rsquo;objet.<!--more--><\/p>\n<p>Les \u00e9l\u00e9ments que je pr\u00e9sente ici sont pr\u00e9sent\u00e9s dans l&rsquo;aide en ligne (voir notamment la page <a title=\"Journal des transactions (SQL Server)\" href=\"https:\/\/docs.microsoft.com\/fr-fr\/sql\/relational-databases\/logs\/the-transaction-log-sql-server\" target=\"_blank\" rel=\"noopener noreferrer\">Journal des transactions<\/a>). Cet article n&rsquo;a pas vocation \u00e0 \u00eatre une redite de cette page, mais simplement une br\u00e8ve pr\u00e9sentation du journal, ax\u00e9e sur le contr\u00f4le de la taille des fichiers.<\/p>\n<p>Le premier \u00e9l\u00e9ment \u00e0 comprendre est le r\u00f4le central de ce fichier dans le fonctionnement de SQL Server. Toute op\u00e9ration de modification de donn\u00e9es (ajout \/ suppression \/ modification) est encadr\u00e9e par une transaction, et il en est de m\u00eame pour les modifications de structure. Si aucune transaction n&rsquo;est explicitement ouverte, une transaction implicite est cr\u00e9e. Cette transaction repr\u00e9sente une unit\u00e9 atomique (non s\u00e9cable) avant et apr\u00e8s laquelle les donn\u00e9es concern\u00e9es sont r\u00e9put\u00e9es dans un \u00e9tat coh\u00e9rent et durable.<\/p>\n<p>Tout au long de l&rsquo;op\u00e9ration, les donn\u00e9es sont modifi\u00e9es au fur et \u00e0 mesure du traitement. Mais ces modifications ne sont en fait pas r\u00e9alis\u00e9es directement sur les fichiers de donn\u00e9es. Elles sont en fait r\u00e9alis\u00e9es sur des pages (8Ko) de donn\u00e9es stock\u00e9es en m\u00e9moire, et elles sont stock\u00e9es au niveau du support fichier uniquement (dans un premier temps) dans le fichier de journal de transactions. Les informations stock\u00e9es dans le journal sont suffisantes pour faire et d\u00e9faire la modification.<\/p>\n<p>Suivant divers d\u00e9clencheurs (saturation m\u00e9moire ou fichier de log, op\u00e9ration de backup ou checkpoint manuel, &#8230;), les versions modifi\u00e9es des pages sont transf\u00e9r\u00e9es vers les fichiers de donn\u00e9es. Les donn\u00e9es du journal de transaction permettent notamment de faire et d\u00e9faire les modifications en cas d&rsquo;annulation de transaction (Rollback). Notamment, en cas d&rsquo;arr\u00eat inopin\u00e9 du syst\u00e8me, ces informations pr\u00e9sentes sur le disque dur (et donc r\u00e9put\u00e9es durables), les informations pr\u00e9sentes dans le journal de transaction sont utilis\u00e9es pour repositionner la base dans un \u00e9tat coh\u00e9rent.<\/p>\n<p><a href=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/06\/Redo_Undo.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-547\" title=\"Redo_Undo\" alt=\"\" src=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/06\/Redo_Undo-620x288.png\" width=\"620\" height=\"288\" srcset=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/06\/Redo_Undo-620x288.png 620w, https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/06\/Redo_Undo-300x139.png 300w, https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/06\/Redo_Undo.png 786w\" sizes=\"auto, (max-width: 620px) 100vw, 620px\" \/><\/a><\/p>\n<p>D\u00e8s lors que le Checkpoint a eu lieu, toute les informations contenues dans le journal de transaction et concernant des transactions termin\u00e9es deviennent inutiles pour cette fonctionnalit\u00e9 de r\u00e9cup\u00e9ration en cas de crash.<\/p>\n<p>Toutefois, elle peuvent rester utiles pour de nombreuses autre fonctionnalit\u00e9s :<\/p>\n<ul>\n<li>jeu des m\u00eames modifications sur une autre instance SQL Server, par exemple \u00e0 travers du Log Shipping ou du Database Mirroring<\/li>\n<li>restauration d&rsquo;une base en mode \u00ab\u00a0Point In Time\u00a0\u00bb, c&rsquo;est-\u00e0-dire en se repositionnant dans l&rsquo;\u00e9tat dans lequel se trouvaient les donn\u00e9es \u00e0 une date-heure donn\u00e9e.<\/li>\n<\/ul>\n<p>Pour cela, il peut \u00eatre n\u00e9cessaire de conserver les donn\u00e9es du journal de transactions y compris lorsque les transactions sont termin\u00e9es et qu&rsquo;un checkpoint a eu lieu ensuite. La base est dans ce cas configur\u00e9e en mode de r\u00e9cup\u00e9ration \u00ab\u00a0complet\u00a0\u00bb.<\/p>\n<p>A l&rsquo;oppos\u00e9, si l&rsquo;on d\u00e9cide de s&rsquo;affranchir des informations fournies pas une historisation des transactions, alors la base est \u00e0 configurer en mode \u00ab\u00a0simple\u00a0\u00bb, et l&rsquo;espace disque du journal des transactions est de nouveau disponible d\u00e8s lors que les transactions sont termin\u00e9es et que le checkpoint a eu lieu.<\/p>\n<p>Dans la pratique, on trouve tr\u00e8s souvent des bases de donn\u00e9es configur\u00e9es en mode complet soit de mani\u00e8re non justifi\u00e9e (pas de besoin de restauration \u00e0 une date-heure donn\u00e9e, pas de base miroir, &#8230;) ou non suivie (pas de sauvegarde du journal).<\/p>\n<p>Il est en effet important de noter qu&rsquo;\u00e0 partir du moment o\u00f9 une base est en mode complet, son journal de transaction m\u00e9morise l&rsquo;ensemble des modifications apport\u00e9es, et grossit au besoin (suivant les param\u00e8tres configur\u00e9s). L&rsquo;espace occup\u00e9 par des transactions r\u00e9volues n&rsquo;est lib\u00e9r\u00e9 que lorsque les informations qu&rsquo;il contient sont r\u00e9put\u00e9es stock\u00e9es en s\u00e9curit\u00e9 ailleurs, c&rsquo;est-\u00e0-dire dans une sauvegarde.<\/p>\n<p>Commen\u00e7ons par cr\u00e9er une base d\u00e9di\u00e9e, dans laquelle nous effectuerons quelques modifications&#8230;<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">-- Initialisation\r\nSET NOCOUNT ON\r\nGO\r\nCREATE DATABASE [Taille Log]\r\nGO\r\nBACKUP DATABASE [Taille Log] TO  DISK = N'C:\\Program Files\\Microsoft SQL Server\\MSSQL10_50.MSSQLSERVER\\MSSQL\\Backup\\Taille Log0.bak' WITH NOFORMAT, INIT,  NAME = N'Backup initial', SKIP, NOREWIND, NOUNLOAD,  STATS = 10\r\nGO\r\n\r\n-- Mise en place de la table, et remplissage\r\nuse [Taille Log]\r\nGO\r\nCREATE TABLE A(Id int IDENTITY, Chaine char(1000))\r\nGO\r\nINSERT INTO A(Chaine) values ('Test')\r\nGO 100000\r\n\r\n-- Suppression de la table\r\nDROP TABLE A\r\nGO<\/pre>\n<p>Accessoirement, on peut m\u00eame effectuer un petit Checkpoint histoire de s&rsquo;assurer que toutes les op\u00e9rations \u00ab\u00a0en standby\u00a0\u00bb en m\u00e9moire sont bien appliqu\u00e9es au fichier de donn\u00e9es.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">-- Checkpoint pour \"stabiliser\"\r\nCHECKPOINT\r\nGO<\/pre>\n<p>Dans l&rsquo;\u00e9tat actuel des choses, on n&rsquo;a plus aucune donn\u00e9e applicatives, la seule table cr\u00e9\u00e9e a m\u00eame \u00e9t\u00e9 supprim\u00e9e.<\/p>\n<p>Et pourtant, on a pas mal de place consomm\u00e9e par le fichier de log&#8230;<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">-- Taille du journal occup\u00e9e\r\nSELECT 'Taille du journal occup\u00e9e',s.name AS [Name],s.size * CONVERT(float,8) AS [Size],CAST(FILEPROPERTY(s.name, 'SpaceUsed') AS float)* CONVERT(float,8) AS [UsedSpace]\r\nFROM sys.master_files AS s\r\nWHERE (s.type = 0 and s.database_id = db_id())\r\nGO<\/pre>\n<p><a href=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/06\/TailleJournalOccupee.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-554\" title=\"TailleJournalOccupee\" alt=\"\" src=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/06\/TailleJournalOccupee.png\" width=\"366\" height=\"74\" srcset=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/06\/TailleJournalOccupee.png 366w, https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/06\/TailleJournalOccupee-300x60.png 300w\" sizes=\"auto, (max-width: 366px) 100vw, 366px\" \/><\/a><\/p>\n<p>Cette place ne sera lib\u00e9r\u00e9e que lors d&rsquo;un backup du journal de transaction.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">-- Sauvegarde du journal\r\nBACKUP LOG [Taille Log] TO  DISK = N'C:\\Program Files\\Microsoft SQL Server\\MSSQL10_50.MSSQLSERVER\\MSSQL\\Backup\\Taille Log.trn' WITH NOFORMAT, INIT,  NAME = N'Taille Log-Transaction Log  Backup', SKIP, NOREWIND, NOUNLOAD,  STATS = 10\r\nGO\r\n\r\n-- Taille du journal occup\u00e9e apr\u00e8s backup du journal\r\nSELECT 'apr\u00e8s backup du journal',s.name AS [Name],s.size * CONVERT(float,8) AS [Size],CAST(FILEPROPERTY(s.name, 'SpaceUsed') AS float)* CONVERT(float,8) AS [UsedSpace]\r\nFROM sys.master_files AS s\r\nWHERE (s.type = 0 and s.database_id = db_id())<\/pre>\n<p><a href=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/06\/ApresBackupJournal.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-555\" title=\"ApresBackupJournal\" alt=\"\" src=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/06\/ApresBackupJournal.png\" width=\"360\" height=\"70\" srcset=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/06\/ApresBackupJournal.png 360w, https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/06\/ApresBackupJournal-300x58.png 300w\" sizes=\"auto, (max-width: 360px) 100vw, 360px\" \/><\/a><\/p>\n<p>Maintenant, il est \u00e0 noter que le m\u00eame sc\u00e9nario r\u00e9alis\u00e9 avec un mode Recovery Simple n&rsquo;aurait pas vu le journal grossir \u00e0 ce point, bien loin de l\u00e0&#8230;<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">-- Initialisation\r\nSET NOCOUNT ON\r\nGO\r\nCREATE DATABASE [Taille Log2]\r\nGO\r\n-- Mise en place du mode Recovery Simple\r\nUSE [master]\r\nGO\r\nALTER DATABASE [Taille Log2] SET RECOVERY SIMPLE WITH NO_WAIT\r\nGO\r\n\r\n-- Mise en place de la table, et remplissage\r\nuse [Taille Log2]\r\nGO\r\nCREATE TABLE A(Id int IDENTITY, Chaine char(1000))\r\nGO\r\nINSERT INTO A(Chaine) values ('Test')\r\nGO 100000\r\n\r\n-- Suppression de la table\r\nDROP TABLE A\r\nGO\r\n\r\n-- Checkpoint pour \"stabiliser\"\r\nCHECKPOINT\r\nGO<\/pre>\n<p>Apr\u00e8s avoir laiss\u00e9 quelques secondes au syst\u00e8me pour se stabiliser, on constate que l&rsquo;espace occup\u00e9 dans le fichier de log est minime&#8230;<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\">-- Taille du journal occup\u00e9e\r\nSELECT 'Taille du journal occup\u00e9e',s.name AS [Name],s.size * CONVERT(float,8) AS [Size],CAST(FILEPROPERTY(s.name, 'SpaceUsed') AS float)* CONVERT(float,8) AS [UsedSpace]\r\nFROM sys.master_files AS s\r\nWHERE (s.type = 0 and s.database_id = db_id())\r\nGO<\/pre>\n<p><a href=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/06\/TailleJournalSimple.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-556\" title=\"TailleJournalSimple\" alt=\"\" src=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/06\/TailleJournalSimple.png\" width=\"369\" height=\"70\" srcset=\"https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/06\/TailleJournalSimple.png 369w, https:\/\/www.sqlserver.fr\/blog\/wp-content\/uploads\/2012\/06\/TailleJournalSimple-300x56.png 300w\" sizes=\"auto, (max-width: 369px) 100vw, 369px\" \/><\/a><\/p>\n<p>Au final, il est important de retenir que le mode Recovery complet ne doit \u00eatre utilis\u00e9 que s&rsquo;il y a un besoin particulier (et en g\u00e9n\u00e9ral pas dans le contexte d&rsquo;environnements de d\u00e9veloppement). De plus, si une base en mode complet subit de nombreuses modifications entre deux sauvegardes compl\u00e8tes, il convient d&rsquo;adjoindre une planification de sauvegardes de journaux de transactions entre deux sauvegardes compl\u00e8tes, afin de ne pas voir s&rsquo;envoler la taille du journal de transaction&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>L&rsquo;expansion non contr\u00f4l\u00e9e du fichier de log d&rsquo;une base de donn\u00e9es SQL Server est un sujet r\u00e9curent dans les forums de discussion. Cet article a pour objectif d&rsquo;expliquer ce qu&rsquo;est le fichier de log inh\u00e9rent au fonctionnement de SQL Server, &hellip; <a href=\"https:\/\/www.sqlserver.fr\/blog\/log-complet-et-usage\/\">Continuer la lecture <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-542","post","type-post","status-publish","format-standard","hentry","category-article_sql"],"_links":{"self":[{"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/posts\/542","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/comments?post=542"}],"version-history":[{"count":23,"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/posts\/542\/revisions"}],"predecessor-version":[{"id":1951,"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/posts\/542\/revisions\/1951"}],"wp:attachment":[{"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/media?parent=542"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/categories?post=542"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sqlserver.fr\/blog\/wp-json\/wp\/v2\/tags?post=542"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}