{"id":464,"date":"2021-11-07T17:17:52","date_gmt":"2021-11-07T16:17:52","guid":{"rendered":"https:\/\/blog.sguazz.it\/?p=464"},"modified":"2021-11-11T16:10:28","modified_gmt":"2021-11-11T15:10:28","slug":"sql-server-2005-e-file-sparse-su-ntfs","status":"publish","type":"post","link":"https:\/\/blog.sguazz.it\/index.php\/archives\/464","title":{"rendered":"SQL Server 2005 e file \u00absparse\u00bb su NTFS"},"content":{"rendered":"\n<p>Di recente mi hanno chiesto di sistemare un vecchio sistema che da qualche giorno non funzionava pi\u00f9: un database di SQL Server era in stato \u00absuspect\u00bb e non si riusciva pi\u00f9 ad accedervi.<\/p>\n\n\n\n<p>La macchina era piuttosto vecchia: Windows Server 2003 a 64 bit, SQL Server 2005 a 64 bit; il tutto su ESXi. Era un sistema di produzione, con un applicativo \u2014 baan IV \u2014 in via di migrazione alla nuova versione (dopo oltre 10 anni di onorata carriera su IBM AIX e Informix e gli ultimi anni su questo Windows Server con SQL Server).<\/p>\n\n\n\n<p>Il sistemista locale faceva il <em>backup<\/em> con Veeam, sia della intera macchina virtuale, sia dei database, ma da qualche mese il <em>backup<\/em> di SQL Server falliva, sicch\u00e9 quest&#8217;ultimo era stato disabilitato. Invece il <em>backup<\/em> della macchina virtuale completa girava regolarmente. Per non si sa quale motivo, il sistema si \u00e8 automaticamente riavviato e SQL Server ha smesso di funzionare.<\/p>\n\n\n\n<p>Mi soffermer\u00f2 qui su alcuni brevi passaggi che hanno portato alla soluzione del problema.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>Il database era in stato <em>suspect<\/em>, vale a dire che SQL Server 2005 non era riuscito a farne il <em>recovery<\/em> all&#8217;accensione dell&#8217;istanza. Se si cerca su Internet come risolvere questa cosa, la risposta \u00e8 abbastanza costante e consiste nel mettere il database in stato EMERGENCY, poi fare un controllo di consistenza dei file e dei dati (con eventuale accettazione di perdita dei dati), infine mettere il database nuovamente in stato <em>online<\/em>. Ad esempio, si pu\u00f2 fare tutto con questi comandi SQL:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">EXEC sp_resetstatus 'b4c4db';<br \/>ALTER DATABASE b4c4db SET EMERGENCY;<br \/>ALTER DATABASE b4c4db SET SINGLE_USER WITH ROLLBACK IMMEDIATE;<br \/>DBCC CheckDB ('b4c4db', REPAIR_ALLOW_DATA_LOSS)<br \/>ALTER DATABASE b4c4db SET MULTI_USER;<\/pre>\n\n\n\n<p>Durante queste operazioni si possono leggere i messaggi di stato e quelli d&#8217;errore nel normale file di log di SQL Server. Durante il DBCC viene riportato il messaggio:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">2021-11-05 11:28:07.81 spid2s SQL Server has encountered 1 occurrence(s) of <span class=\"has-inline-color has-blue-color\"><strong>I\/O requests taking longer than 15 seconds to complete<\/strong><\/span> on file [G:\\MSSQL\\B4C4\\b4c4db.mdf] in database <a href=\"5\">b4c4db<\/a>. The OS file handle is 0x00000000000004E8. The offset of the latest long I\/O is: 0x00002076d00000<\/pre>\n\n\n\n<p>\u00c8 l&#8217;ultimo messaggio che si legge, mentre normalmente ci sarebbero messaggi sulla percentuale di avanzamento del <em>recovery<\/em>.<\/p>\n\n\n\n<p>Dal controllo dell&#8217;istanza \u00e8 venuto fuori che il database era di una versione senza quasi nessuna <em>patch<\/em>, cio\u00e8 la 9.0.1406. Ho quindi deciso di installare il <em>service pack<\/em> 4 di SQL Server 2005 (kb2463332-x64-enu) per vedere se questo risolvesse il problema. L&#8217;installazione non \u00e8 andata a buon fine perch\u00e9, dopo aver copiato sul <em>file system<\/em> il programma aggiornato, veniva avviato il nuovo SQL Server per eseguire alcuni <em>script<\/em> SQL che avrebbero dovuto aggiornare i database di sistema, ma all&#8217;avvio partiva anche il <em>recovery<\/em>, che trovava il database utente che non va e si bloccava. Fortunatamente questa nuova versione (SP4) inserisce una informazione in pi\u00f9 nel log, che viene ripetuta ogni pochi secondi:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">2021-11-05 11:28:07.81 spid2s SQL Server has encountered 1 occurrence(s) of <span class=\"has-inline-color has-blue-color\"><strong>I\/O requests taking longer than 15 seconds to complete<\/strong><\/span> on file [G:\\MSSQL\\B4C4\\b4c4db.mdf] in database <a href=\"5\">b4c4db<\/a>. The OS file handle is 0x00000000000004E8. The offset of the latest long I\/O is: 0x00002076d00000\n2021-11-05 11:29:28.42 spid51 <span class=\"has-inline-color has-blue-color\"><strong>The operating system returned error 1450(error not found) to SQL Server<\/strong><\/span> during a write at offset 0x00002076d00000 in file with handle 0x00000000000004E8. This is usually a temporary condition and the SQL Server will keep retrying the operation. If the condition persists then immediate action must be taken to correct it.<\/pre>\n\n\n\n<p>L&#8217;errore 1450 di Windows Server 2003 \u00e8 \u00ab<em>Insufficient system resources exist to complete the requested service<\/em>\u00bb e, nel nostro caso, sta a indicare che SQL Server ha chiesto qualcosa al <em>file system<\/em>, ma questo non riesce a farlo. Scavando nella documentazione si scopre che durante le operazioni di <em>backup<\/em> (il famoso <em>backup<\/em> di Veeam che falliva da mesi) e di <em>recovery<\/em> (quello fatto all&#8217;avvio) SQL Server sfrutta gli <em>snapshot<\/em> per completare l&#8217;operazione. Lo <em>snapshot<\/em> va a sua volta a usare una caratteristica dei file <em>sparse<\/em>, che non esistono solo su Unix e Linux ma anche su NTFS, solo che qui viene usata una tabellina a dimensione fissa per segnare l&#8217;elenco delle zone di blocchi contigui del disco usate per lo <em>snapshot<\/em>. Se queste zone di blocchi contigui sono piccole allora, a parit\u00e0 di dati, il loro numero aumenta, e ou\u00f2 finire per riempire la tabellina. Al che il <em>file system<\/em> genera l&#8217;errore 1450, SQL Server non riesce a terminare il <em>backup<\/em> o il <em>recovery<\/em> e tutto si blocca. La soluzione indicata da Microsoft \u00e8 di usare ReFS (disponibile da Windows Server 2012) al posto di NTFS, il quale non ha questa limitazione sulla gestione dei file <em>sparse<\/em>, cio\u00e8 permette di avere <em>snapshot<\/em> con un numero qualsiasi di zone di blocchi contigui.<\/p>\n\n\n\n<p>Non avendo ReFS su Windows Server 2003, ho aggiunto un ulteriore disco alla VM, l&#8217;ho formattato con <em>file system<\/em> NTFS e <em>cluster<\/em> da 64kb, vi ho copiato i file del database di SQL Server (questa operazione ha prodotto una copia deframmentata dei file, riducendo al minimo i blocchi di settori contigui che formano i file). Ho poi cambiato le lettere del nome dei dischi in modo che il nuovo prendesse il posto del vecchio, ho riacceso SQL Server che ha fatto il <em>recovery<\/em> senza errori.<\/p>\n\n\n\n<p>Voil\u00e0.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Di recente mi hanno chiesto di sistemare un vecchio sistema che da qualche giorno non funzionava pi\u00f9: un database di SQL Server era in stato \u00absuspect\u00bb e non si riusciva pi\u00f9 ad accedervi. La macchina era piuttosto vecchia: Windows Server 2003 a 64 bit, SQL Server 2005 a 64 bit; il tutto su ESXi. Era [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,3],"tags":[32,31,30,33],"class_list":["post-464","post","type-post","status-publish","format-standard","hentry","category-sysadmin","category-computer","tag-32","tag-ntfs","tag-sql-server-2005","tag-suspect"],"_links":{"self":[{"href":"https:\/\/blog.sguazz.it\/index.php\/wp-json\/wp\/v2\/posts\/464","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.sguazz.it\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.sguazz.it\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.sguazz.it\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.sguazz.it\/index.php\/wp-json\/wp\/v2\/comments?post=464"}],"version-history":[{"count":6,"href":"https:\/\/blog.sguazz.it\/index.php\/wp-json\/wp\/v2\/posts\/464\/revisions"}],"predecessor-version":[{"id":474,"href":"https:\/\/blog.sguazz.it\/index.php\/wp-json\/wp\/v2\/posts\/464\/revisions\/474"}],"wp:attachment":[{"href":"https:\/\/blog.sguazz.it\/index.php\/wp-json\/wp\/v2\/media?parent=464"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.sguazz.it\/index.php\/wp-json\/wp\/v2\/categories?post=464"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.sguazz.it\/index.php\/wp-json\/wp\/v2\/tags?post=464"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}