<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SQL in the Wild &#187; Admin</title>
	<atom:link href="http://sqlinthewild.co.za/index.php/category/sql-server/admin/feed/" rel="self" type="application/rss+xml" />
	<link>http://sqlinthewild.co.za</link>
	<description>A discussion on SQL Server</description>
	<lastBuildDate>Sun, 01 Jan 2012 14:30:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>T-SQL Tuesday: Disasters don&#8217;t just come in huge</title>
		<link>http://sqlinthewild.co.za/index.php/2011/06/14/t-sql-tuesday-disasters-dont-just-come-in-huge/</link>
		<comments>http://sqlinthewild.co.za/index.php/2011/06/14/t-sql-tuesday-disasters-dont-just-come-in-huge/#comments</comments>
		<pubDate>Tue, 14 Jun 2011 14:30:00 +0000</pubDate>
		<dc:creator>Gail</dc:creator>
				<category><![CDATA[Admin]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Syndication]]></category>

		<guid isPermaLink="false">http://sqlinthewild.co.za/?p=1086</guid>
		<description><![CDATA[So we&#8217;re supposed to talk about disasters we&#8217;ve had or discuss disaster recovery technologies. I&#8217;m going to take a slightly different approach… &#60;soapbox&#62; I&#8217;m in the fortunate position of living in a region of the world that&#8217;s relatively free of natural disasters. We&#8217;re reasonably geologically stable, the nearest fault lines are the Great Rift Valley [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.allenkinsel.com/archive/2011/06/invitation-for-t-sql-tuesday-19-disasters-recovery/"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; float: right; padding-top: 0px; border-width: 0px;" title="image" src="http://sqlinthewild.co.za/wp-content/uploads/2011/06/image_thumb.png" border="0" alt="image" width="154" height="154" align="right" /></a>So we&#8217;re supposed to talk about disasters we&#8217;ve had or discuss disaster recovery technologies. I&#8217;m going to take a slightly different approach…</p>
<p>&lt;soapbox&gt;</p>
<p>I&#8217;m in the fortunate position of living in a region of the world that&#8217;s relatively free of natural disasters. We&#8217;re reasonably geologically stable, the nearest fault lines are the Great Rift Valley and somewhere in the Antarctic ocean. We don&#8217;t get tornadoes, we&#8217;re a long way from the ocean (and Madagascar partially protects the coast from typhoons and tsunamis)</p>
<p>Given that, and looking at the recent events in Japan and Southern USA, local IT managers might be grateful that their critical infrastructure is here, not there. But that is no reason for complacency, no reason to ignore putting a disaster recovery plan in place.</p>
<p>Major huge national disasters, while they attract a whole lot of attention (and rightly so) are probably not the main cause of IT disasters. IT disasters, for the most part, are likely to be caused more by smaller events like these<sup>1</sup></p>
<ul>
<li>A drive in the RAID 5 array fails, and the SAN admin switches out the wrong drive.</li>
<li>A SAN controller fails and overwrites a LUN or 2 with binary garbage.</li>
<li>The server room floor collapses dumping the SAN 2 floors down into a garage, with the server on top of it.</li>
<li>A water leak a floor above the server room results in the UPS getting a shower, and the resultant power surge fries the servers&#8217; main boards</li>
<li>A developer with far too many permissions truncates an important table on the production server, thinking he was working on the development environment.</li>
<li>The mains power fails but the generators don&#8217;t come online because their fuel was drained a day earlier in preparation for maintenance.</li>
</ul>
<p>Events like those (or probably even more mundane events) are the ones that we need to plan for. Relatively minor disaster that can leave business without critical infrastructure or critical data for hours or days.</p>
<p>You need to plan for the small disasters as well as the large ones. Plan for the dropped table. Plan for two drives failing in the RAID 5 array. Plan for the server&#8217;s power supply failing. Plan for the big disasters too, just don&#8217;t think that they&#8217;re the only thing that endangers your data and your business.</p>
<p>(1) I&#8217;ve personally seen 3 of those events happen, I&#8217;ve heard from people who have seen two more and I know of a company that&#8217;s at risk of one. They&#8217;re not just made-up improbably occurrences.</p>
]]></content:encoded>
			<wfw:commentRss>http://sqlinthewild.co.za/index.php/2011/06/14/t-sql-tuesday-disasters-dont-just-come-in-huge/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Full backups, the log chain and the COPY_ONLY option.</title>
		<link>http://sqlinthewild.co.za/index.php/2011/03/08/full-backups-the-log-chain-and-the-copy_only-option/</link>
		<comments>http://sqlinthewild.co.za/index.php/2011/03/08/full-backups-the-log-chain-and-the-copy_only-option/#comments</comments>
		<pubDate>Tue, 08 Mar 2011 14:30:44 +0000</pubDate>
		<dc:creator>Gail</dc:creator>
				<category><![CDATA[Admin]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Syndication]]></category>

		<guid isPermaLink="false">http://sqlinthewild.co.za/?p=903</guid>
		<description><![CDATA[There have been a large number of posts made regarding the interaction between full database backups and the log chain (like this one). However there still seems to be a lot of confusion around regarding how they interact. I doubt I can clear up the confusion with yet another blog post, but I&#8217;ll try. One [...]]]></description>
			<content:encoded><![CDATA[<p>There have been a large number of posts made regarding the interaction between full database backups and the log chain (<a href="http://sqlskills.com/BLOGS/PAUL/post/Misconceptions-around-the-log-and-log-backups-how-to-convince-yourself.aspx">like this one</a>). However there still seems to be a lot of confusion around regarding how they interact. I doubt I can clear up the confusion with yet another blog post, but I&#8217;ll try.</p>
<p>One that seems to come up now and again is the COPY_ONLY Option on backups. Typically the comment is something like &#8216;Use the COPY_ONLY option when taking ad-hoc full backups so that you don&#8217;t impact the log backups.&#8217; Now we know from the blog posts linked above that full backups don&#8217;t ever break the log chain (and I&#8217;m not going to run yet more tests to prove it) so what is the copy only option there for?</p>
<p>Books Online states the following regarding the COPY_ONLY option for backups &#8211; &#8220;Specifies that the backup is a copy-only backup, which does not affect the normal sequence of backups. A copy-only backup is created independently of your regularly scheduled, conventional backups. A copy-only backup does not affect your overall backup and restore procedures for the database.&#8221;</p>
<p>Well, that doesn&#8217;t clear things up much. It does however go on to say this: &#8220;When used with BACKUP DATABASE, the COPY_ONLY option creates a full backup that cannot serve as a differential base. The differential bitmap is not updated, and differential backups behave as if the copy-only backup does not exist. Subsequent differential backups use the most recent conventional full backup as their base.&#8221;</p>
<p>So it&#8217;s not the log chain that copy only is there to not affect, it&#8217;s the differential base. Let&#8217;s test and see how it works.</p>
<p><span id="more-903"></span></p>
<pre class="brush: sql; title: ; notranslate">CREATE DATABASE TestingBackups
GO

USE TestingBackups
GO

CREATE TABLE Testing (
ID INT IDENTITY PRIMARY KEY,
SomeValue CHAR(4)
);
GO

BACKUP DATABASE TestingBackups TO DISK = 'C:\Databases\Backup\TestingBackups_Full1.bak'
GO

INSERT INTO Testing (SomeValue)
VALUES ('abc')

BACKUP DATABASE TestingBackups TO DISK = 'C:\Databases\Backup\TestingBackups_Diff1.bak' WITH DIFFERENTIAL
GO

INSERT INTO Testing (SomeValue)
VALUES ('def')

BACKUP DATABASE TestingBackups TO DISK = 'C:\Databases\Backup\TestingBackups_Full2.bak'
GO

INSERT INTO Testing (SomeValue)
VALUES ('ghi')

BACKUP DATABASE TestingBackups TO DISK = 'C:\Databases\Backup\TestingBackups_Diff2.bak' WITH DIFFERENTIAL
GO</pre>
<p>Right, so that&#8217;s a database with two full backups and two differential backups and a couple data changes in between. Let&#8217;s drop the database and test some restore strategies. The goal is to restore the database to the point that it was at the time the second differential backup was taken.</p>
<p>First the obvious route. Full backup 2 and differential backup 2.</p>
<pre class="brush: sql; title: ; notranslate">RESTORE DATABASE TestingBackups FROM DISK = 'C:\Databases\Backup\TestingBackups_Full2.bak' WITH NORECOVERY
GO
RESTORE DATABASE TestingBackups FROM DISK = 'C:\Databases\Backup\TestingBackups_Diff2.bak' WITH NORECOVERY
GO
RESTORE DATABASE TestingBackups WITH RECOVERY</pre>
<p>That works. That&#8217;s the most obvious and likely the one that will be used the most. What happens though if we don&#8217;t have full backup 2? What if it was a full backup that an evil developer took without asking, used to restore a development/test database somewhere and then deleted the backup file?</p>
<p>There are two options there that might work:</p>
<ul>
<li>Full backup 1 and differential backup 2 (differential backups are cumulative aren&#8217;t they?)</li>
<li>Full backup 1, differential backup 1 and then differential backup 2.</li>
</ul>
<p>Option 1</p>
<pre class="brush: sql; title: ; notranslate">RESTORE DATABASE TestingBackups FROM DISK = 'C:\Databases\Backup\TestingBackups_Full1.bak' WITH NORECOVERY
GO
RESTORE DATABASE TestingBackups FROM DISK = 'C:\Databases\Backup\TestingBackups_Diff2.bak' WITH NORECOVERY
GO
RESTORE DATABASE TestingBackups WITH RECOVERY</pre>
<p>Well that didn&#8217;t work…</p>
<blockquote><p>Msg 3136, Level 16, State 1, Line 1<br />
This differential backup cannot be restored because the database has not been restored to the correct earlier state.<br />
Msg 3013, Level 16, State 1, Line 1<br />
RESTORE DATABASE is terminating abnormally.</p></blockquote>
<p>Option 2</p>
<pre class="brush: sql; title: ; notranslate">RESTORE DATABASE TestingBackups FROM DISK = 'C:\Databases\Backup\TestingBackups_Full1.bak' WITH NORECOVERY
GO
RESTORE DATABASE TestingBackups FROM DISK = 'C:\Databases\Backup\TestingBackups_Diff1.bak' WITH NORECOVERY
GO
RESTORE DATABASE TestingBackups FROM DISK = 'C:\Databases\Backup\TestingBackups_Diff2.bak' WITH NORECOVERY
GO
RESTORE DATABASE TestingBackups WITH RECOVERY</pre>
<p>That didn&#8217;t work either.</p>
<blockquote><p>Msg 3136, Level 16, State 1, Line 1<br />
This differential backup cannot be restored because the database has not been restored to the correct earlier state.<br />
Msg 3013, Level 16, State 1, Line 1<br />
RESTORE DATABASE is terminating abnormally.</p></blockquote>
<p>Differential backup 1 restored fine, differential backup 2 didn&#8217;t. The reason is that, unlike log backups, differential backups are affected by full backups. Specifically, a differential backup is based on the last full backup that ran before it. If an ad-hoc full backup is taken, any differential run after that is based on the ad-hoc full backup and not the one run as part of the standard backup plan. Not fun if a developer runs one then deletes the backup file when it&#8217;s no longer needed.</p>
<p>This is what copy-only affects when specified on a full backup. A full backup run with copy-only does not change the differential base and does not reset the list of extents changed since the last full backup. Hence an ad-hoc full database backup, if specified with the COPY_ONLY option, won&#8217;t cause administrators unpleasant surprises when test restores are done or a disaster occurs and a full restore is necessary.</p>
<p>Let&#8217;s drop that test database and recreate it using COPY_ONLY on the second full backup.</p>
<pre class="brush: sql; title: ; notranslate">CREATE DATABASE TestingBackups
GO

USE TestingBackups
GO

CREATE TABLE Testing (
ID INT IDENTITY PRIMARY KEY,
SomeValue CHAR(4)
);
GO

BACKUP DATABASE TestingBackups TO DISK = 'C:\Databases\Backup\TestingBackups_Full1.bak'
GO

INSERT INTO Testing (SomeValue)
VALUES ('abc')

BACKUP DATABASE TestingBackups TO DISK = 'C:\Databases\Backup\TestingBackups_Diff1.bak' WITH DIFFERENTIAL
GO

INSERT INTO Testing (SomeValue)
VALUES ('def')

BACKUP DATABASE TestingBackups TO DISK = 'C:\Databases\Backup\TestingBackups_Full2.bak' WITH COPY_ONLY
GO

INSERT INTO Testing (SomeValue)
VALUES ('ghi')

BACKUP DATABASE TestingBackups TO DISK = 'C:\Databases\Backup\TestingBackups_Diff2.bak' WITH DIFFERENTIAL
GO</pre>
<p>Now the restore path using full backup 1 and differential backup 2 does work.</p>
<pre class="brush: sql; title: ; notranslate">RESTORE DATABASE TestingBackups FROM DISK = 'C:\Databases\Backup\TestingBackups_Full1.bak' WITH NORECOVERY
GO
RESTORE DATABASE TestingBackups FROM DISK = 'C:\Databases\Backup\TestingBackups_Diff2.bak' WITH NORECOVERY
GO
RESTORE DATABASE TestingBackups WITH RECOVERY</pre>
<blockquote><p>Processed 168 pages for database &#8216;TestingBackups&#8217;, file &#8216;TestingBackups&#8217; on file 1.<br />
Processed 5 pages for database &#8216;TestingBackups&#8217;, file &#8216;TestingBackups_log&#8217; on file 1.<br />
RESTORE DATABASE successfully processed 173 pages in 0.215 seconds (6.286 MB/sec).<br />
Processed 64 pages for database &#8216;TestingBackups&#8217;, file &#8216;TestingBackups&#8217; on file 1.<br />
Processed 1 pages for database &#8216;TestingBackups&#8217;, file &#8216;TestingBackups_log&#8217; on file 1.<br />
RESTORE DATABASE successfully processed 65 pages in 0.103 seconds (4.873 MB/sec).<br />
RESTORE DATABASE successfully processed 0 pages in 0.371 seconds (0.000 MB/sec).</p></blockquote>
<p>With that out of the way, the question still remains as to whether COPY_ONLY has anything to do with log backups or the log chain. Books online also says this about them: &#8220;When used with BACKUP LOG, the COPY_ONLY option creates a copy-only log backup, which does not truncate the transaction log. The copy-only log backup has no effect on the log chain, and other log backups behave as if the copy-only backup does not exist.&#8221;</p>
<p>So COPY_ONLY changes the effect a backup has on the log chain only when specified on a transaction log backup, not on full databases backups. Useful if you need an ad-hoc log backup for something.</p>
]]></content:encoded>
			<wfw:commentRss>http://sqlinthewild.co.za/index.php/2011/03/08/full-backups-the-log-chain-and-the-copy_only-option/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Why is CheckDB rolling back transactions?</title>
		<link>http://sqlinthewild.co.za/index.php/2009/09/24/why-is-checkdb-rolling-back-transactions/</link>
		<comments>http://sqlinthewild.co.za/index.php/2009/09/24/why-is-checkdb-rolling-back-transactions/#comments</comments>
		<pubDate>Thu, 24 Sep 2009 08:00:43 +0000</pubDate>
		<dc:creator>Gail</dc:creator>
				<category><![CDATA[Admin]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Syndication]]></category>

		<guid isPermaLink="false">http://sqlinthewild.co.za/?p=348</guid>
		<description><![CDATA[I saw this one on a forum recently and it&#8217;s a fun question to look into. When running CheckDB on an in-use database, sometimes messages like the following will appear in the SQL error log 1 transactions rolled back in database &#8216;Testing&#8217; (8). This is an informational message only. No user action is required. DBCC [...]]]></description>
			<content:encoded><![CDATA[<p>I saw this one on a forum recently and it&#8217;s a fun question to look into.</p>
<p>When running CheckDB on an in-use database, sometimes messages like the following will appear in the SQL error log</p>
<p>1 transactions rolled back in database &#8216;Testing&#8217; (8). This is an informational message only. No user action is required.<br />
DBCC CHECKDB (Testing) WITH no_infomsgs executed by theAdmin found 0 errors and repaired 0 errors. Elapsed time: 0 hours 0 minutes 31 seconds.</p>
<p>What&#8217;s going on here? Why is checkDB rolling transactions back?</p>
<p>Well, the truth is, it&#8217;s not rolling anything back.</p>
<p>When CheckDB runs it has to be able to get a consistent view of the database, one without half-done transactions, without data modifications in progress. On SQL 2000 (and earlier), CheckDB used the transaction log to get that consistent view. It would read through the transaction log to see what had been done to the various structures in the database. In SQL 2005 this was changed and CheckDB now uses the database snapshot feature to get its consistent, point-in-time view of the database.</p>
<h4>Database Snapshots</h4>
<p>A database snapshot is a read-only, point-in-time copy of a database. It uses a combination of sparse file and copy-on-write technology to reduce space usage and, as a result, it&#8217;s usually much smaller than the database it was based on.</p>
<p>When a snapshot is created, any open transactions are rolled back within the context of the database snapshot to generate the consistent, point-in-time copy. This generates messages in the SQL error log stating how many transactions were rolled back</p>
<h4>CheckDB</h4>
<p>The first thing that CheckDB has to do is to create an internal, hidden database snapshot to get the consistent view of the DB that it needs. It will do this unless it&#8217;s run with the TABLOCK option. When the snapshot is created, any open transactions will be rolled back but only in the context of the snapshot, not in the context of the actual database. CheckDB will then run against the snapshot and will drop it once complete.</p>
<p>So the answer to the question of why checkDB is rolling back transactions is a simple one. It isn&#8217;t.</p>
]]></content:encoded>
			<wfw:commentRss>http://sqlinthewild.co.za/index.php/2009/09/24/why-is-checkdb-rolling-back-transactions/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Backing up to NUL vs Backup with Truncate only</title>
		<link>http://sqlinthewild.co.za/index.php/2009/08/31/backing-up-to-nul-vs-backup-with-truncate-only/</link>
		<comments>http://sqlinthewild.co.za/index.php/2009/08/31/backing-up-to-nul-vs-backup-with-truncate-only/#comments</comments>
		<pubDate>Mon, 31 Aug 2009 20:25:16 +0000</pubDate>
		<dc:creator>Gail</dc:creator>
				<category><![CDATA[Admin]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Syndication]]></category>

		<guid isPermaLink="false">http://sqlinthewild.co.za/?p=299</guid>
		<description><![CDATA[Or &#8220;It&#8217;s 10pm, do you know where your log records are?&#8221; Something that I&#8217;ve started to see recently is the idea that Backup Log &#8230; With Truncate Only, which was deprecated in SQL 2005 and gone in SQL 2008 can be simulated by backing the log up to the NUL device (backup log &#8230; to [...]]]></description>
			<content:encoded><![CDATA[<p>Or &#8220;<em>It&#8217;s 10pm, do you know where your log records are?</em>&#8221;</p>
<p>Something that I&#8217;ve started to see recently is the idea that Backup Log &#8230; With Truncate Only, which was deprecated in SQL 2005 and gone in SQL 2008 can be simulated by backing the log up to the NUL device (backup log &#8230; to disk = &#8216;Nul&#8217;). Is that true? If so, is that a good idea?</p>
<p>To answer those questions, first we need to explore what the two statements do.</p>
<h3>Backup Log With Truncate_Only</h3>
<p>When this statement is run against a database in full or bulk-logged recovery, SQL discards the inactive log records for that database. From that point until a full database backup is done, the database is in pseudo-simple recovery, the inactive log records get discarded when a checkpoint runs and any attempt to back the log up results in an error message.</p>
<p>Msg 4214, Level 16, State 1, Line 1<br />
BACKUP LOG cannot be performed because there is no current database backup.</p>
<p>So once the log has been truncated it&#8217;s exceedingly clear that the log chain is broken.</p>
<h3><span id="more-299"></span>Backup Log to disk = &#8216;Nul&#8217;</h3>
<p>To understand what this is doing, first we need to understand what Nul is, in the context of a file. It is not just a misspelling of NULL.</p>
<p>DOS, since the earliest days, has had a number of devices that can be treated like files, eg LPT1, COM1 and CON. NUL is another of those devices (virtual files, if you like) and is equivalent to the unix \dev\nul, a &#8216;file&#8217; that deletes any data that&#8217;s written to it. The bitbucket, if you will.</p>
<p>So anything that&#8217;s written to NUL is discarded. So when a transaction log backup is made with &#8216;nul&#8217; as the file destination, SQL dutifully reads over the inactive log records, formats them as for a transaction log backup and hands them off to the operating system which promptly discards the data and sends back an acknowledgement that the data has been written.</p>
<p>So SQL thinks that the log chain is intact. It discards the log records that were sent to Nul as it would after a normal log backup, because it thinks that they were backed up to disk. It does not switch the DB into a pseudo-simple recovery model. Inactive log records are not discarded at a checkpoint and future log backups will succeed.</p>
<p>That&#8217;s the main difference. Log records will still be retained after a backup to NUL. Log backups will succeed after a backup to NUL. They&#8217;re useless for restoring the DB because there&#8217;s a log backup missing, but they&#8217;ll succeed.</p>
<h3>Replacement?</h3>
<p>So, is backup to nul a replacement for backup with truncate_only? No, it&#8217;s not. The replacement for Backup Log with Truncate_Only is well documented. It&#8217;s switching the database to simple recovery. If the inactive log records in the log file do not need to be retained for recoverability, this is the way to tell SQL to discard them. If log backups need to be made after this, the DB can be switched back to full and a full DB backup taken.</p>
<p>Backup Log to Disk = &#8216;Nul&#8217; is the same as backing up the log to a file and then deleting the backup file. Nothing more.</p>
]]></content:encoded>
			<wfw:commentRss>http://sqlinthewild.co.za/index.php/2009/08/31/backing-up-to-nul-vs-backup-with-truncate-only/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Why the DMVs are not a replacement for SQL Trace</title>
		<link>http://sqlinthewild.co.za/index.php/2009/07/10/why-the-dmvs-are-not-a-replacement-for-sql-trace/</link>
		<comments>http://sqlinthewild.co.za/index.php/2009/07/10/why-the-dmvs-are-not-a-replacement-for-sql-trace/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 10:39:20 +0000</pubDate>
		<dc:creator>Gail</dc:creator>
				<category><![CDATA[Admin]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Syndication]]></category>

		<guid isPermaLink="false">http://sqlinthewild.co.za/?p=222</guid>
		<description><![CDATA[With the introduction of the DMVs in SQL 2005, there&#8217;s now a wealth of information available on every aspect of SQL&#8217;s behaviour. It&#8217;s possible now to interrogate the SQL procedure cache to find out what queries have been running and how well or badly they are performing. So does all this mean that SQL Trace [...]]]></description>
			<content:encoded><![CDATA[<p>With the introduction of the DMVs in SQL 2005, there&#8217;s now a wealth of information available on every aspect of SQL&#8217;s behaviour. It&#8217;s possible now to interrogate the SQL procedure cache to find out what queries have been running and how well or badly they are performing. So does all this mean that SQL Trace is now obsolete?</p>
<p>It does not. The execution stats available through sys.dm_exec_query_stats are only retained while the plan for the query is in cache. As soon as the plan is removed from cache (for whatever reason), the query stats for that query will be discarded. There are also a couple of reasons for a query&#8217;s plan not going into the cache at all.</p>
<p>Let&#8217;s try a quick example. I&#8217;m going to use the AdventureWorks database (SQL 2008), because it&#8217;s convenient. I&#8217;m going to create 4 procedures, run them several times, along with a couple other commands and then compare what a trace shows and what a query of the plan cache shows.</p>
<p><span id="more-222"></span></p>
<pre class="brush: sql; title: ; notranslate">Create Procedure GetLatestPriorWeeksTransactions (@WeekEnds DATETIME)
AS

SELECT p.Name, TransactionDate, TransactionType, Quantity, ActualCost
FROM Production.TransactionHistory th inner join Production.Product p on th.ProductID = p.ProductID
WHERE TransactionDate BETWEEN @WeekEnds AND DATEADD(ww,-1,@WeekEnds)

GO

CREATE Procedure ArchiveTransactionHistory (@ArchiveEndDate DATETIME)
AS
Insert Into Production.TransactionHistoryArchive (TransactionID, ProductID, ReferenceOrderID, ReferenceOrderLineID, TransactionDate, TransactionType, Quantity, ActualCost, ModifiedDate)
SELECT TransactionID, ProductID, ReferenceOrderID, ReferenceOrderLineID, TransactionDate, TransactionType, Quantity, ActualCost, ModifiedDate
  FROM Production.TransactionHistory
  WHERE TransactionDate &lt; @ArchiveEndDate

DELETE FROM Production.TransactionHistory WHERE TransactionDate &lt; @ArchiveEndDate
GO

CREATE PROCEDURE SalesToday (@ProductID int)
AS
SELECT p.name, sum(sod.lineTotal) AS TotalSales, SUM(OrderQty) AS TotalSold
  FROM Sales.SalesOrderHeader soh
    INNER JOIN Sales.SalesOrderDetail sod on soh.SalesOrderID = sod.SalesOrderID
    INNER JOIN Production.Product p on sod.ProductID = p.ProductID
  WHERE DATEADD(dd,dateDiff(dd,0,soh.OrderDate),0) = DATEADD(dd,dateDiff(dd,0,GETDATE()),0)
GO

CREATE PROCEDURE PersonSearch (
  @Surname Varchar(50) = NULL,
  @FirstName Varchar(50) = NULL
)
WITH RECOMPILE
AS

SELECT Firstname, middlename, LastName
  FROM Person.Person
  WHERE (LastName like @surname + '%' OR @Surname IS NULL)
    AND (FirstName like @FirstName + '%' OR @FirstName IS NULL)
GO</pre>
<p>I&#8217;m going to use the same trace definition that I detailed in the <a href="http://www.simple-talk.com/sql/performance/finding-the-causes-of-poor-performance-in-sql-server,-part-1/">article that I wrote for Simple-Talk</a>, and use the same technique as is in the article to load the trace up and get aggregated totals.</p>
<p>When I query the plan cache, this is what I get back from it.</p>
<p><img class="alignnone size-full wp-image-265" title="Procedure Cache" src="http://sqlinthewild.co.za/wp-content/uploads/2009/07/proccache.png" alt="" width="500" height="96" /></p>
<p>And this is what I got from the trace (with the queries relating to the trace removed)</p>
<p><img class="alignnone size-full wp-image-266" title="Trace" src="http://sqlinthewild.co.za/wp-content/uploads/2009/07/trace.png" alt="" width="499" height="137" /></p>
<p>So why the discrepancy?</p>
<p>Let&#8217;s start with the entries returned in the query of the trace, not the procedure cache.</p>
<p>The ALTER PROCEDURE wouldn&#8217;t be visible in a query of the procedure cache, because DDL statements don&#8217;t have execution plans. There&#8217;s only one way to run an ALTER PROCEDURE, so there&#8217;s no need for a plan, hence there&#8217;s nothing to cache and nothing for the query stats to hook off.</p>
<p>According to the procedure cache, the PersonSearch procedure was never run, but the trace records 35 executions. There&#8217;s no entry for this procedure in the cache, because it&#8217;s marked WITH RECOMPILE. Since a new plan has to be compiled on each execution, the plan is never cached and hence it will never be visible in a query of the plan cache and there will never be saved execution statistics for it.</p>
<p>Now, how about the two with very different execution counts? In each of those cases, something happened to throw the procedure&#8217;s existing plan out of cache part way through the test. When the plan gets thrown from cache the query stats get discarded as well.</p>
<p>In the case of the SalesToday procedure, the procedure was altered part way through the test. Altering a procedure or any object that the procedure depends upon will invalidate the cached plan and cause it to be discarded</p>
<p>The other procedure, GetLatestPriorWeeksTransactions, had it&#8217;s plan invalidated due to a statistics update. The archiving of TransactionHistory changed enough rows in the table that the next time a query ran it triggered a statistics update. That statistics update would have invalidated any plans that used those statistics. In general, this doesn&#8217;t have to be stats update on a permanent table. If a procedure uses a temp table and adds rows to that temp table, there&#8217;s a good chance of getting statistics-based recompiles of statements within that procedure, thereby skewing the results of queries against the plan cache.</p>
<p>In conclusion, while the DMVs exposing the plan cache are very useful in seeing how queries are running, they cannot be seen as a complete replacement for SQL Trace because of the possibility of certain types of commands not getting cached at all, and the possibility of plans getting invalidated and dropped from cache for various reasons.</p>
]]></content:encoded>
			<wfw:commentRss>http://sqlinthewild.co.za/index.php/2009/07/10/why-the-dmvs-are-not-a-replacement-for-sql-trace/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Deleting the transaction log</title>
		<link>http://sqlinthewild.co.za/index.php/2009/06/09/deleting-the-transaction-log/</link>
		<comments>http://sqlinthewild.co.za/index.php/2009/06/09/deleting-the-transaction-log/#comments</comments>
		<pubDate>Tue, 09 Jun 2009 21:45:52 +0000</pubDate>
		<dc:creator>Gail</dc:creator>
				<category><![CDATA[Admin]]></category>
		<category><![CDATA[Corruption]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Syndication]]></category>

		<guid isPermaLink="false">http://sqlinthewild.co.za/?p=250</guid>
		<description><![CDATA[Or &#8220;Why is my database now inaccessible?&#8221; This is another things that I&#8217;ve seen a few things recently on various forums. A DB&#8217;s transaction log fills the disk, probably due to a lack of log backups, and then either SQL is stopped and the log file deleted or the database is detached and the log [...]]]></description>
			<content:encoded><![CDATA[<p>Or &#8220;<em>Why is my database now inaccessible?</em>&#8221;</p>
<p>This is another things that I&#8217;ve seen a few things recently on various forums. A DB&#8217;s transaction log fills the disk, probably due to a lack of log backups, and then either SQL is stopped and the log file deleted or the database is detached and the log file deleted. Either way it&#8217;s not a particularly good thing to do.</p>
<p>No, I&#8217;ll be blunt, it&#8217;s a appallingly bad thing to do. The transaction log is not an optional piece of the database. It&#8217;s not like an installation log or activity log where the entries are there just in case anyone&#8217;s interested. The transaction log is what SQL uses to ensure, at all times, that the data in the database is transactionally consistent. It&#8217;s what gives SQL databases the consistency and durability properties that are required from a relational database engine.</p>
<p>The transaction log has a number of uses within SQL.</p>
<ol>
<li>In SQL 2000 and before, the inserted and deleted tables were materialised from the transaction log. This was changed in SQL 2005 and they&#8217;re now materialised from the row version store in TempDB.</li>
<li>A transaction rollback uses the transaction log to determine what needs to be undone.</li>
<li>In transactional replication, the log reader uses the transaction log to determine what changes need to be replicated</li>
<li>Used by Change Data Capture in SQL 2008 to extract changes made to registered tables</li>
<li>During restart-recovery to ensure that transactions that had committed when the service stopped but whose changes had not been written to the data file are replayed and to ensure that transactions that hadn&#8217;t completed are rolled back.</li>
</ol>
<p>For now, I&#8217;m just going to consider the last one.</p>
<p><span id="more-250"></span>When the SQL Service is stopped or a database detached, SQL will try to shut the database down cleanly. That means running a checkpoint and writing all dirty data pages to disk. The checkpoint has to write into the log that it has run. If there&#8217;s no more space in the log, then the checkpoint cannot run and the database cannot be cleanly shut down. This is not usually a problem. When the database is attached or the service restarted SQL will run restart-recovery on it, the transaction log will be used to bring the database back to a transactionally consistent state. That&#8217;s great, but what happens if the transaction log&#8217;s not there?</p>
<p>To see exactly what will happen, I&#8217;m going to set up a database that&#8217;s got a very small max size for the log file (because I don&#8217;t want to have to fill the drive to get results), set it to full recovery and take a backup. Taking a backup will start the log chain and ensure that the log will grow until it runs out of space. Reuse of the log will not happen as I&#8217;m not taking any log backups. Once the database is backed up, I&#8217;m going to run inserts until the log fills up.</p>
<p>CREATE DATABASE TestingLogDeletion<br />
ON (NAME = Test_dat,<br />
FILENAME = &#8216;D:\Develop\Databases\TestingLogDeletion.mdf&#8217;,<br />
SIZE = 10,<br />
MAXSIZE = UNLIMITED,<br />
FILEGROWTH = 5 )<br />
LOG ON ( NAME = Test_log,<br />
FILENAME = &#8216;D:\Develop\Databases\TestingLogDeletion.ldf&#8217;,<br />
SIZE = 5MB,<br />
MAXSIZE = 10MB);<br />
GO</p>
<p>ALTER DATABASE TestingLogDeletion SET RECOVERY FULL;<br />
GO</p>
<p>USE TestingLogDeletion<br />
GO</p>
<p>CREATE TABLE Filler (<br />
ID INT IDENTITY PRIMARY KEY,<br />
FillerStr CHAR(300)<br />
)<br />
GO</p>
<p>BACKUP DATABASE TestingLogDeletion TO DISK = &#8216;D:\Develop\Databases\Backups\TestingLogDeletion.bak&#8217;</p>
<p>Right, so that&#8217;s the setup all done. Now to fill the log up.</p>
<p>DECLARE @i INT;<br />
SET @i = 0;</p>
<p>WHILE (@i &lt; 10000)<br />
BEGIN<br />
INSERT INTO Filler (FillerStr) VALUES (CAST(@i AS VARCHAR(10)))<br />
SET @i = @i+1;<br />
END<br />
GO</p>
<p>Doesn&#8217;t take long either. After just 4778 inserts, this popped up.</p>
<p><span style="color: #ff0000;">Msg 9002, Level 17, State 2, Line 6<br />
The transaction log for database &#8216;TestingLogDeletion&#8217; is full. To find out why space in the log cannot be reused, see the log_reuse_wait_desc column in sys.databases</span></p>
<p>Trying to run a checkpoint gives the same error. So there&#8217;s not enough space in the log to do a clean shutdown. First I&#8217;m going to try shutting SQL down, deleting the log and then restarting SQL. See how the database handles that. Note, the highest identity value in that table was 4778 before the shutdown.</p>
<p>Once SQL restarts, I&#8217;m going to query that table, see what&#8217;s in there.</p>
<p>select MAX(ID) from TestingLogDeletion.dbo.Filler</p>
<p><span style="color: #ff0000;">Msg 945, Level 14, State 2, Line 1<br />
Database &#8216;TestingLogDeletion&#8217; cannot be opened due to inaccessible files or insufficient memory or disk space.  See the SQL Server errorlog for details.</span></p>
<p>That&#8217;s not good. The state of the database, according to sys.databases, is RECOVERY_PENDING. Restart recovery has not run and cannot run because the log file&#8217;s missing. The error log says the following</p>
<blockquote><p>Error: 17207, Severity: 16, State: 1.</p>
<p>FileMgr::StartLogFiles: Operating system error 2(The system cannot find the file specified.) occurred while creating or opening file &#8216;D:\Develop\Databases\TestingLogDeletion.ldf&#8217;. Diagnose and correct the operating system error, and retry the operation.</p>
<p>File activation failure. The physical file name &#8220;D:\Develop\Databases\TestingLogDeletion.ldf&#8221; may be incorrect.</p>
<p>The log cannot be rebuilt because the database was not cleanly shut down.</p></blockquote>
<p>There are two ways to fix this. Restore from backup or attempt a log rebuild and repair. If there is a current database backup, the first option is by far the best one. The repair should be a last resort, for when there is no backup.</p>
<p>In this case, for demonstration purposes, I&#8217;m going to pretend there&#8217;s no backup and go for a repair. This technique is given in more detail on Paul Randal&#8217;s blog &#8211; <a href="http://www.sqlskills.com/BLOGS/PAUL/post/Search-Engine-QA-4-Using-EMERGENCY-mode-to-access-a-RECOVERY-PENDING-or-SUSPECT-database.aspx">Using EMERGENCY mode to access a RECOVERY PENDING or SUSPECT database</a></p>
<p><strong>Step 1 &#8211; Set the database into Emergency mode</strong></p>
<p>Fortunately in 2005 and later, using Emergency mode is documented and supported and anyone with sysadmin permissions can set a database into Emergency mode.</p>
<p>ALTER DATABASE TestingLogDeletion SET EMERGENCY</p>
<p>Now that the DB is in Emergency mode I can access it again. So what&#8217;s in that table that I was populating? Remember that the highest identity value before the shutdown and log deletion was 4778.</p>
<p><img class="alignnone size-full wp-image-252" title="records" src="http://sqlinthewild.co.za/wp-content/uploads/2009/06/records.png" alt="" width="435" height="131" /></p>
<p>I&#8217;ve lost almost 3300 records. Imagine if this was a sales system, or stock market trading or something similar.</p>
<p>Because the DB was not shut down cleanly, all the changed data pages were not written to disk. Normally those changes would be replayed from the transaction log during the restart-recovery but because the log was deleted and restart-recovery can&#8217;t run, those changes have been lost, and there is no way to get them back.</p>
<p><strong>Step 2 &#8211; Emergency mode repair</strong></p>
<p>To bring the DB back online I need to run a repair. This will fix any structural problems caused by the missing log and bring the database online.</p>
<p>ALTER DATABASE TestingLogDeletion SET SINGLE_USER<br />
DBCC CHECKDB(TestingLogDeletion, REPAIR_ALLOW_DATA_LOSS)</p>
<p>CheckDB complained about the missing log then went and rebuilt the log with a whole bunch of extra warnings</p>
<blockquote><p>File activation failure. The physical file name &#8220;D:\Develop\Databases\TestingLogDeletion.ldf&#8221; may be incorrect.</p>
<p>The log cannot be rebuilt because the database was not cleanly shut down.</p>
<p>Warning: The log for database &#8216;TestingLogDeletion&#8217; has been rebuilt. Transactional consistency has been lost. The RESTORE chain was broken, and the server no longer has context on the previous log files, so you will need to know what they were. You should run DBCC CHECKDB to validate physical consistency. The database has been put in dbo-only mode. When you are ready to make the database available for use, you will need to reset database options and delete any extra log files.</p>
<p>DBCC results for &#8216;TestingLogDeletion&#8217;.<br />
CHECKDB found 0 allocation errors and 0 consistency errors in database &#8216;TestingLogDeletion&#8217;.</p></blockquote>
<p>In this case there was no corruption. That will not always be the case. Because recovery acts on both user data and the DB&#8217;s structure there may be physical corruption that has to be repaired. It&#8217;s even possible that there&#8217;s irreparable corruption to system tables or allocation pages and if Emergency mode repair fails there&#8217;s no other way to bring the DB back online</p>
<p>After running repair if I check sys.databases the state of the database is Online, so I can bring it out of restricted user mode and it&#8217;s usable again.</p>
<p>Now that was bad enough. Lost data and a database that was unavailable for however long CheckDB takes to repair, and on big databases that could be many hours. Let&#8217;s see how bad things are when I detach the database and then delete the log file.</p>
<p>Same setup, but instead of shutting SQL down, I&#8217;ll detach the database.</p>
<p>Interesting point, if I do the detach through Object Explorer the detach dialog comes back with an error saying that detach failed because the transaction log is full. However the detach actually succeeds, the database is not longer there.</p>
<p>So, DB detached. Now I&#8217;m going to delete the log and use the CREATE DATABASE syntax to reattach it.</p>
<p>CREATE DATABASE TestingLogDeletion<br />
ON (FILENAME = &#8216;D:\Develop\Databases\TestingLogDeletion.mdf&#8217;)<br />
FOR ATTACH_REBUILD_LOG </p>
<p>That should work fine, right. Right?</p>
<p>Wrong.</p>
<blockquote><p>File activation failure. The physical file name &#8220;D:\Develop\Databases\TestingLogDeletion.ldf&#8221; may be incorrect.<br />
The log cannot be rebuilt because the database was not cleanly shut down.<br />
<span style="color: #ff0000;">Msg 1813, Level 16, State 2, Line 1<br />
Could not open new database &#8216;TestingLogDeletion&#8217;. CREATE DATABASE is aborted.</span></p></blockquote>
<p>Much the same as the error that we got when stopping SQL, deleting the log file and restarting SQL but with one very big difference. I can&#8217;t set the DB into emergency mode and run repair. The attach failed, the database is not there.</p>
<p>So this is a bit of a catch-22. I can&#8217;t rebuild the log because the database isn&#8217;t attached and I can&#8217;t attach because the log is missing. Nasty situation. Same as in the first case, the recommended approach here is to restore backups (and we all have backups, right?). If there are no backups, there is a way to hack the DB back into the server, but it isn&#8217;t pretty.</p>
<p>To get that DB back into SQL I need to create a new database with the same number of files and the same (as much as possible) size of files.</p>
<p>CREATE DATABASE TestingLogDeletion_2<br />
ON (NAME = Test_dat,<br />
FILENAME = &#8216;D:\Develop\Databases\TestingLogDeletion_2.mdf&#8217;,<br />
SIZE = 10,<br />
MAXSIZE = UNLIMITED,<br />
FILEGROWTH = 5 )<br />
LOG ON ( NAME = Test_log,<br />
FILENAME = &#8216;D:\Develop\Databases\TestingLogDeletion_2.ldf&#8217;,<br />
SIZE = 5MB,<br />
MAXSIZE = 5MB);<br />
GO</p>
<p>Then stop SQL, delete both of the files of the newly created database and rename the mdf file of the database I detached earlier to match the mdf file of this DB. Once that&#8217;s done, restart SQL. When SQL starts it will find that the log file is missing and the DB not shut down cleanly and it will put the DB into the RECOVERY_PENDING state. From here the steps to get the DB back online are the same as in the first case. Set it into Emergency mode and run CheckDB with a repair option. Again there will be downtime while checkDB repairs and rebuilds the log, there may be some data loss and there&#8217;s always the chance that emergency mode repair will fail.</p>
<p>So, in conclusion. Don&#8217;t delete the transaction log. Sometimes SQL can rebuild it without too many problems, sometimes it can&#8217;t.</p>
]]></content:encoded>
			<wfw:commentRss>http://sqlinthewild.co.za/index.php/2009/06/09/deleting-the-transaction-log/feed/</wfw:commentRss>
		<slash:comments>41</slash:comments>
		</item>
		<item>
		<title>Corruption month</title>
		<link>http://sqlinthewild.co.za/index.php/2009/05/25/corruption-month/</link>
		<comments>http://sqlinthewild.co.za/index.php/2009/05/25/corruption-month/#comments</comments>
		<pubDate>Mon, 25 May 2009 19:01:13 +0000</pubDate>
		<dc:creator>Gail</dc:creator>
				<category><![CDATA[Admin]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://sqlinthewild.co.za/?p=246</guid>
		<description><![CDATA[There&#8217;s been a rash of database-corruption posts recently. On the two forums that I read, there have so far been around 12 corruption-related problems so far this month. That&#8217;s frightening. Many of the problems were only solved either with some data loss or with a lot of work, or both. So what are the two [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s been a rash of database-corruption posts recently. On the two forums that I read, there have so far been around 12 corruption-related problems so far this month. That&#8217;s frightening. Many of the problems were only solved either with some data loss or with a lot of work, or both. So what are the two things that most of these cases had in common.</p>
<ol>
<li>No backups</li>
<li>No corruption checks</li>
</ol>
<h3>Backups</h3>
<p>Having no backups is pretty inexcusable, whether its because no backups were scheduled or whether it&#8217;s because the backups were failing. Paul&#8217;s written about the <a href="http://www.sqlskills.com/BLOGS/PAUL/post/Importance-of-having-the-right-backups.aspx">importance of the right backups</a>, and I&#8217;m not going to repeat him here.</p>
<p>Just having backups is not sufficient. The backups have to be restorable. A backup that&#8217;s not restorable is, in my opinion, worse than no backup at all. That means that the jobs have to be checked to ensure that they did run without error and the backups have to be restored somewhere to test them. Ultimately that&#8217;s the only way to be 100%, absolutely sure that a backup is restorable.</p>
<p><span id="more-246"></span>In SQL 2005 and higher, if the database has checksum page protection and the backup is done with the checksum option then damaged pages will be detected at backup time and damage to the backup set will be detected by RESTORE VERIFYONLY. This may not be the case if the backup was not made with the checksum option.</p>
<p>The other thing that has to be considered is the integrity of the backup media. I&#8217;ve seen a case where an IO problem not only damaged the database but also damaged the backup file to the point where it would not restore, despite the backup being on a different LUN of the SAN with no drives shared between it and the data LUN</p>
<p>So, to conclude this section, do you have backups and are you sure your database backups can be restored? Have you tried recently?</p>
<h3>Corruption checks</h3>
<p>If corruption checks aren&#8217;t done regularly, there&#8217;s a good chance that any corruption that occurs will remain hidden for quite some time. If this does happen, and the database backups are not made with the CHECKSUM option, then the corrupt pages will get backed up. This causes obvious problems when trying to fix corruption by restoring from a backup.</p>
<p>I&#8217;ve seen people say that if they have the Page Verifications et to checksum, there&#8217;s no need to run CheckDB. That is not true. Other than backups (when taken with the CHECKSUM option) there is no other operation that reads and checks all of the page checksums in the database. Just having the page checksums in place doesn&#8217;t help if there&#8217;s never a check made to see that all of them are still correct.</p>
<p>A good database maintenance routine must include running CheckDB regularly or, if  there isn&#8217;t time to run checkDB, a mixture of CheckAlloc, CheckCatalog and CheckTable on all tables.</p>
<p>How often? Often enough that, should corruption be detected, restoring from a clean backup is an option.</p>
<h3>In Conclusion</h3>
<p>I would consider the protection of data to be a DBA&#8217;s top priority. So backups and integrity checks should be top of the list of things to check and double check, because slipping in this area could have very nasty consequences for the business.</p>
<p>Do you have backups of all your critical production systems?<br />
Are they restorable?<br />
Are you sure?<br />
Do you have corruption in any of your databases?<br />
Are you sure?</p>
]]></content:encoded>
			<wfw:commentRss>http://sqlinthewild.co.za/index.php/2009/05/25/corruption-month/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>High Availability != Backups</title>
		<link>http://sqlinthewild.co.za/index.php/2009/05/08/high-availability-backups/</link>
		<comments>http://sqlinthewild.co.za/index.php/2009/05/08/high-availability-backups/#comments</comments>
		<pubDate>Fri, 08 May 2009 16:16:01 +0000</pubDate>
		<dc:creator>Gail</dc:creator>
				<category><![CDATA[Admin]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://sqlinthewild.co.za/?p=242</guid>
		<description><![CDATA[Backup solutions are not the same as high availability solutions. They have different purposes and picking the wrong one for the wrong reasons may be disasterous. A backup solution is a one that creates separate copies of data that can be used to restore the original in the case of data loss. A high availability [...]]]></description>
			<content:encoded><![CDATA[<p>Backup solutions are not the same as high availability solutions. They have different purposes and picking the wrong one for the wrong reasons may be disasterous.</p>
<p>A backup solution is a one that creates separate copies of data that can be used to restore the original in the case of data loss. A high availability solution is one designed to keep a system usable and available in the face of hardware (or similar) failures</p>
<p>Solutions like RAID, database mirroring, clustering and SAN replication are forms of high availability. They are not backup solutions and cannot replace good database backups. Having the database on a RAID array will not help if the DB becomes corrupt. SAN replication or database mirroring is of no use if a user somehow deletes critical records.</p>
<p>On the other hand, a backup strategy, however good, is not going to help much when a critical piece of hardware burns out and the business will be losing millions if the app&#8217;s not up within 10 minutes. If the app is critical, both backups and an appropriate high availability solution have to be considered. Picking the right high availability solution is complex. Entire books have been written on it.</p>
<p>The only time having no backups at all is an acceptable option is if it&#8217;s a system where the data can be completely recreated from another source with no difficulties (example here would be a reporting database that&#8217;s replicated directly from a different server)</p>
<p>Here&#8217;s another take on backups &#8211; <a href="http://www.sqlskills.com/BLOGS/PAUL/post/Importance-of-having-the-right-backups.aspx">http://www.sqlskills.com/BLOGS/PAUL/post/Importance-of-having-the-right-backups.aspx</a></p>
]]></content:encoded>
			<wfw:commentRss>http://sqlinthewild.co.za/index.php/2009/05/08/high-availability-backups/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>When did CheckDB last run?</title>
		<link>http://sqlinthewild.co.za/index.php/2008/12/22/when-did-checkdb-last-run/</link>
		<comments>http://sqlinthewild.co.za/index.php/2008/12/22/when-did-checkdb-last-run/#comments</comments>
		<pubDate>Mon, 22 Dec 2008 16:39:26 +0000</pubDate>
		<dc:creator>Gail</dc:creator>
				<category><![CDATA[Admin]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://sqlinthewild.co.za/?p=180</guid>
		<description><![CDATA[If corruption is found in a database it&#8217;s very important to know when the corruption started. In the cases where a restore is needed to fix the corruption, knowing which backup is clean can save a great deal of time in restoring databases and checking them. On SQL 2000, the only way to know was [...]]]></description>
			<content:encoded><![CDATA[<p>If corruption is found in a database it&#8217;s very important to know when the corruption started. In the cases where a restore is needed to fix the corruption, knowing which backup is clean can save a great deal of time in restoring databases and checking them.</p>
<p>On SQL 2000, the only way to know was to to go back through the history of the checkDB jobs (everyone is running checkDB regularly, right?) and see when the last successful run was.</p>
<p>On SQL 2005 and higher, when checkDB runs successfully, ie without finding any errors, it writes the date of the last run into the database&#8217;s boot page.  Whenever SQL Server then starts that database up, be it during a server start, a database restore or bringing the database online, SQL prints a message into the error log.</p>
<p style="padding-left: 30px;"><span id="more-180"></span>CHECKDB for database &#8216;Testing&#8217; finished without errors on 2008-12-22 10:20:06.007 (local time).</p>
<p>This makes it very easy to see when the database was last known to be clean (without any corruption). Note that SQLL is not running checkDB when it prints that. It&#8217;s simply printing out the date that CheckDB last completed without finding any problems. The information can also be read out of the boot page using an undocumented DBCC command.</p>
<p>Use Testing<br />
GO</p>
<p>DBCC TRACEON(3604)<br />
DBCC DBINFO<br />
DBCC TRACEOFF(3604)</p>
<p>This prints out a whole bunch of information, all found in the database&#8217;s boot page. The info of interest here is in the second block (on SQL 2008 RTM)</p>
<p style="padding-left: 30px;">dbi_dbccLastKnownGood = 2008-12-22 10:20:06.007</p>
<p>If the date listed is 1900-01-01 00:00:00, it means that CheckDB has never run successfully on that database. If that is the case, there will be no entries in the error log when the database is started.</p>
]]></content:encoded>
			<wfw:commentRss>http://sqlinthewild.co.za/index.php/2008/12/22/when-did-checkdb-last-run/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>When is a critical IO error not a critical IO error?</title>
		<link>http://sqlinthewild.co.za/index.php/2008/12/06/when-is-a-critical-io-error-not-a-critical-io-error/</link>
		<comments>http://sqlinthewild.co.za/index.php/2008/12/06/when-is-a-critical-io-error-not-a-critical-io-error/#comments</comments>
		<pubDate>Sat, 06 Dec 2008 10:33:09 +0000</pubDate>
		<dc:creator>Gail</dc:creator>
				<category><![CDATA[Admin]]></category>
		<category><![CDATA[Corruption]]></category>
		<category><![CDATA[SQL Server]]></category>

		<guid isPermaLink="false">http://sqlinthewild.co.za/?p=164</guid>
		<description><![CDATA[When it succeeds on the second try. Anyone who&#8217;s done any research at all on database corruption and IO problems has probably seen an example of the 823 and 824 errors. Error 823 is a physical IO error. It means that, for some reason, the OS was incapable of completing the requested IO. It may [...]]]></description>
			<content:encoded><![CDATA[<p>When it succeeds on the second try.</p>
<p>Anyone who&#8217;s done any research at all on database corruption and IO problems has probably seen an example of the 823 and 824 errors.</p>
<p>Error 823 is a physical IO error. It means that, for some reason, the OS was incapable of completing the requested IO. It may mean that the disk has failed, the disk is missing, a filter driver is misbehaving, or a number of other things. On SQL 2005 it looks something like this:</p>
<p style="padding-left: 30px;">Error: 823, Severity: 24, State: 2.<br />
The operating system returned error 21(The device is not ready.) to SQL Server during a read at offset 0x0000d2364e2000 in file &#8216;D:\Data\SomeDB.mdf&#8217;. Additional messages in the SQL Server error log and system event log may provide more detail. This is a severe system-level error condition that threatens database integrity and must be corrected immediately. Complete a full database consistency check (DBCC CHECKDB). This error can be caused by many factors; for more information, see SQL Server Books Online.</p>
<p>Error 823 is classified as a severity 24, the second highest severity error that SQL has. As the error message says, it&#8217;s a very serious condition.</p>
<p>Error 824 is a logical IO error. It means that the page requested was read from disk successfully, but there was something wrong with the page. The page header may have invalid values in it, the checksum may be incorrect, the torn page bits may be incorrect, etc. On SQL 2005, it looks something like this:</p>
<p style="padding-left: 30px;"><span id="more-164"></span>Msg 824, Level 24, State 2, Line 1.<br />
SQL Server detected a logical consistency-based I/O error: incorrect checksum (expected: 0x7532c420; actual: 0x320e4240). It occurred during a read of page (1:342) in database ID 15 at offset 0x00000020e24000 in file &#8216;D:\Data\SomeDB.mdf&#8217;. Additional messages in the SQL Server error log or system event log may provide more detail. This is a severe error condition that threatens database integrity and must be corrected immediately. Complete a full database consistency check (DBCC CHECKDB). This error can be caused by many factors; for more information, see SQL Server Books Online.</p>
<p>Error 824 is also classified a severity 24, which is appropriate, seeing as it&#8217;s saying that some pages within the data file are absolute garbage.</p>
<p>So far, all well and good. They&#8217;re severe errors with very high severities and will be picked up by agent alerts. But there&#8217;s another IO error that&#8217;s less well known and harder to notice, though in my opinion, no less severe.</p>
<p>Error 825 is called a read-retry error. What it means is that an IO was requested and either the IO failed or the resulting page was corrupt. SQL then tried a couple more times and on either the 2nd, 3rd or 4th try, the IO succeeded.</p>
<p>The error looks something like this:</p>
<p style="padding-left: 30px;">Msg 825, Level 10, State 2, Line 1.<br />
A read of the file &#8216;D:\Data\SomeDB.mdf&#8217; at offset 0x00000020e24000 succeeded after failing 1 time(s) with error: incorrect checksum (expected: 0x7532c420; actual: 0x320e4240). Additional messages in the SQL Server error log and system event log may provide more detail. This error condition threatens database integrity and must be corrected. Complete a full database consistency check (DBCC CHECKDB). This error can be caused by many factors; for more information, see SQL Server Books Online.</p>
<p>The big thing to note about this is that it&#8217;s a severity 10. An informational message. That means that agent alerts set for the higher severity errors will completely miss this, and intermittent IO errors is perhaps not something that DBAs want to be ignorant of. The read may have eventually succeeded this time, but there&#8217;s no guarantee that it will eventually succeed the next time it&#8217;s tried.</p>
]]></content:encoded>
			<wfw:commentRss>http://sqlinthewild.co.za/index.php/2008/12/06/when-is-a-critical-io-error-not-a-critical-io-error/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

