{"id":33,"date":"2012-02-01T23:47:56","date_gmt":"2012-02-02T05:47:56","guid":{"rendered":"https:\/\/www.sqlphilosopher.com\/wp\/?p=33"},"modified":"2012-02-02T21:31:31","modified_gmt":"2012-02-03T03:31:31","slug":"perform-dbcc-checkdb-weekly-using-red-gate-sql-virtual-restore","status":"publish","type":"post","link":"https:\/\/www.sqlphilosopher.com\/wp\/2012\/02\/perform-dbcc-checkdb-weekly-using-red-gate-sql-virtual-restore\/","title":{"rendered":"Perform DBCC CheckDB Weekly using Red-Gate SQL Virtual Restore"},"content":{"rendered":"<p>There are many articles on the Internet explaining why it is important to check the consistency of all of your databases on a regular basis.\u00a0 If you are not made aware of corruption in your system as soon as possible, it is likely that you could miss a growing problem until you are in a crisis.\u00a0 However, even though we know consistency checking is important, it can be hard to find a time when you can afford the large performance hit upon your production machines, due to the resource intensity of CheckDB.<\/p>\n<p>So, rather than run CheckDB on my production boxes, I made the choice to take the latest full backup and restore it to a test server, and run CheckDB against that every week.\u00a0 While this does not avoid the possibility of corruption happening since the last full backup, it does let me know that, at the very least, my last full backup is safe.\u00a0 I also get the added built-in benefit of testing my restore strategy each week.<\/p>\n<p>However, this poses other problems.\u00a0 Some of my databases are quite large, and doing a full restore takes a considerable amount of time and disk space.\u00a0 This is where <a title=\"redgate - ingeniously simple tools\" href=\"http:\/\/www.red-gate.com\" target=\"_blank\">Red-Gate<\/a> comes in.<\/p>\n<p>Red-Gate recently added a tool to their arsenal called <a title=\"SQL Virtual Restore\" href=\"http:\/\/www.red-gate.com\/products\/dba\/sql-virtual-restore\/\" target=\"_blank\">SQL Virtual Restore<\/a>.\u00a0 This tool allows the DBA to use Red-Gate&#8217;s <a title=\"HyperBac Powered\" href=\"http:\/\/www.red-gate.com\/products\/dba\/sql-virtual-restore\/hyperbac-powered\" target=\"_blank\">HyperBac Filter Driver<\/a> to allow you to restore a virtual copy of a database using far less space, spending less time, and all utilizing native SQL Backup and Restore syntax.\u00a0 SQL Virtual Restore references the backups you supply to it, creates custom &#8220;indexes&#8221; on your local disk (to help Red-Gate transcend your backups quickly), and creates small empty structures for your files (virtual database files).\u00a0 This allows you to have an unaltered database backup serve your reads and the virtual database files serve your writes.\u00a0 The savings are truly amazing:<\/p>\n<p><a href=\"https:\/\/www.sqlphilosopher.com\/wp\/wp-content\/uploads\/2012\/02\/SQLVirtualRestoreResults_3TB.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-37\" title=\"SQLVirtualRestoreResults_3TB\" src=\"https:\/\/www.sqlphilosopher.com\/wp\/wp-content\/uploads\/2012\/02\/SQLVirtualRestoreResults_3TB.jpg\" alt=\"\" width=\"570\" height=\"273\" srcset=\"https:\/\/www.sqlphilosopher.com\/wp\/wp-content\/uploads\/2012\/02\/SQLVirtualRestoreResults_3TB.jpg 570w, https:\/\/www.sqlphilosopher.com\/wp\/wp-content\/uploads\/2012\/02\/SQLVirtualRestoreResults_3TB-300x143.jpg 300w\" sizes=\"auto, (max-width: 570px) 100vw, 570px\" \/><\/a>With this tool at hand, I next needed to get my scripts written.<\/p>\n<p>I already have a harness for this sort of maintenance &#8211; I have an instance dedicated to DBA tasks.\u00a0 Running in this instance, are different jobs that perform tasks at different intervals; every 15 minutes, every hour, day, week, so forth.\u00a0 These jobs fire off SSIS packages which collect information about my instances in my environment, such as which backups ran successfully in the last week, what security changes have occurred, which databases have datafiles which are going to grow soon, which indexes need attention, which jobs are running longer than usual, and so forth; all based off of a list of instances that I update whenever I add or modify a SQL instance to my environment.<\/p>\n<p>So, since I already have all of the information I will need to write my restore and CheckDB scripts, I am all set.\u00a0 I created a stored procedure that would:<\/p>\n<ul>\n<li>Loop through my list of Instances<\/li>\n<li>For each instance, loop through each database<\/li>\n<ul>\n<li>For each database:<\/li>\n<ul>\n<li>Gather the list of the backup files from the latest successful full backup<\/li>\n<li>Verify that the most recent backup is not &#8220;too old&#8221; (comparing against a configurable value)<\/li>\n<li>Gather all datafile logical names (as of the time the backup was taken)<\/li>\n<li>Copy those backup files locally<\/li>\n<li>Create a native syntax restore script, using dynamic SQL, from the list of backup files and specifying a local location for each virtual data file (one VDF for each logical file in the backup)<\/li>\n<li>Attempt to execute the dynamic SQL restore script, noting any errors that might occur<\/li>\n<li>If the restore was successful, execute DBCC CheckDB against the newly restored database, saving all results to a table<\/li>\n<li>Once the DBCC CheckDB has been performed, I check the results in the table to discover if there were any problems found, noting the result<\/li>\n<li>I then drop the Virtual Database and the local copy of the backups<\/li>\n<\/ul>\n<li>Once every database in the instance has been checked, the script then e-mails me with the results, each database is listed, along with whether the check was successful, found issues that I need to look into, if the latest backup was too old, or if the restore failed (along with any errors)<\/li>\n<\/ul>\n<\/ul>\n<p>Using this method, I am able to consistency check all of my databases every week without ever having to lift a finger.\u00a0 I look over the e-mails I get from the script, for each Instance, and make sure everything was successful.\u00a0 If an error ever pops up, I know that I only have to spend my time on the databases that are actually having problems.<\/p>\n<p>This has been a huge time-saver for me and has given me additional peace of mind.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There are many articles on the Internet explaining why it is important to check the consistency of all of your databases on a regular basis.\u00a0 If you are not made aware of corruption in your system as soon as possible, &hellip;<\/p>\n<p class=\"read-more\"><a href=\"https:\/\/www.sqlphilosopher.com\/wp\/2012\/02\/perform-dbcc-checkdb-weekly-using-red-gate-sql-virtual-restore\/\">Read more &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[17,18],"tags":[],"class_list":["post-33","post","type-post","status-publish","format-standard","hentry","category-database-maintenance","category-tools"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1vS3B-x","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.sqlphilosopher.com\/wp\/wp-json\/wp\/v2\/posts\/33","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sqlphilosopher.com\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sqlphilosopher.com\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sqlphilosopher.com\/wp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sqlphilosopher.com\/wp\/wp-json\/wp\/v2\/comments?post=33"}],"version-history":[{"count":0,"href":"https:\/\/www.sqlphilosopher.com\/wp\/wp-json\/wp\/v2\/posts\/33\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.sqlphilosopher.com\/wp\/wp-json\/wp\/v2\/media?parent=33"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sqlphilosopher.com\/wp\/wp-json\/wp\/v2\/categories?post=33"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sqlphilosopher.com\/wp\/wp-json\/wp\/v2\/tags?post=33"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}