这篇文章跟大家分析一下“在SQL Server里怎么进行页级别的恢复”。内容详细易懂,对“在SQL Server里怎么进行页级别的恢复”感兴趣的朋友可以跟着小编的思路慢慢深入来阅读一下,希望阅读后能够对大家有所帮助。下面跟着小编一起深入学习“在SQL Server里怎么进行页级别的恢复”的知识吧。
在今天的文章里我想谈下每个DBA应该知道的一个重要话题:在SQL Server里如何进行页级别还原操作。假设在SQL Server里你有一个损坏的页,你要从最近的数据库备份只还原有问题的页,而不是还原整个数据库。
我们来破坏一个页
第一步我想向你展示下如何建立表(或索引)里有个特定页损坏的情景,这里我们会进行一些魔术,因为开箱即用(out-of-box)的SQL Server本身不会引入任何损坏的页(如果有的话,恭喜你找到了一个BUG)。我们从创建一个新的数据库,往新建的表插入一些记录开始。
1 USE master 2 GO 3 4 CREATE DATABASE PageLevelRestores 5 GO 6 7 USE PageLevelRestores 8 GO 9 10 -- Create a table where every record fits onto 1 page of 8kb 11 CREATE TABLE Test 12 ( 13 Filler CHAR(8000) 14 ) 15 GO 16 17 -- Insert 4 records 18 INSERT INTO Test VALUES (REPLICATE('A', 8000)) 19 INSERT INTO Test VALUES (REPLICATE('B', 8000)) 20 INSERT INTO Test VALUES (REPLICATE('C', 8000)) 21 INSERT INTO Test VALUES (REPLICATE('D', 8000)) 22 GO 23 24 -- Retrieve the selected records 25 SELECT * FROM Test 26 GO
下一步我进行完整数据库备份。这就是说这个备份包含了属于Test表的所有页。这非常重要,因为接下来我们会破坏这个表的一个特定页。为了找出属于Test表的页,我用DBCC IND命令来返回所有属于这个表的页。
1 -- Perform a full database backup 2 BACKUP DATABASE PageLevelRestores TO DISK = N'C:\Backups\PageLevelRestores.bak' 3 GO 4 5 -- Retrieve the first data page for the specified table (columns PageFID and PagePID) 6 DBCC IND(PageLevelRestores, Test, -1) 7 GO
为了破坏一个特定的页,我使用未公开的DBCC WRITEPAGE命令。是的,在SQL Server里有个可用的DBCC WRITEPAGE命令,但请不要告诉任何人……
1 ALTER DATABASE PageLevelRestores SET SINGLE_USER WITH ROLLBACK IMMEDIATE 2 GO 3 4 -- Let's corrupt page 90... 5 DBCC WRITEPAGE(PageLevelRestores, 1, 90, 0, 1, 0x41, 1) 6 DBCC WRITEPAGE(PageLevelRestores, 1, 90, 1, 1, 0x41, 1) 7 DBCC WRITEPAGE(PageLevelRestores, 1, 90, 2, 1, 0x41, 1) 8 GO 9 10 ALTER DATABASE PageLevelRestores SET MULTI_USER 11 GO
为了使用DBCC WRITEPAGE,问题数据库必须设置如代码所示的单用户模式(Single-User mode)。这里我模拟了有个存储错误,写了一些垃圾到存储的页里(是的,这个在你工作中也会碰到!)。现在当你从表再次读取数据库,SQL Server会返回你一个824 I/O错误,因为对损坏页的校验失败了。
1 -- Retrieve the selected records 2 SELECT * FROM Test 3 GO
一旦SQL Server在I/O访问期间检测到一个损坏的页,在msdb.dbo.suspect_pages里,损坏的页也会被记录,如下图所示。
1 SELECT * FROM msdb.dbo.suspect_pages
对msdb里对特定表进行监控是个很好的想法,可以得到你的数据库里是否有损坏的页。现在我们让事情变得更糟糕,下列代码会往表里插入另外一条记录。
1 -- Now we have additional transaction that we don't want to loose... 2 INSERT INTO Test VALUES (REPLICATE('E', 8000)) 3 GO
我们来还原损坏的页
现在你是DBA,你想恢复这个数据库到正确状态且不丢失数据(像我们在***一步插入的记录)。你会怎么做?首先你要进行所谓的尾日志备份(Tail-Log Backup):你要备份自上次事务日志备份后的已发生的事务。
1 -- Backup the transaction log 2 BACKUP LOG PageLevelRestores TO 3 DISK = 'C:\Backups\PageLevelRestores_LOG1.bak' 4 WITH INIT 5 GO
在这里还没有进行过事务日志备份,因此我们的备份会包含自完整备份后,所有已执行的事务。现在我们可以在SQL Server里初始页级别还原操作。这里你使用传统的RESTORE DATABASE的T-SQL命令,但你只要指定想要还原的页,不用还原整个数据库,我们只要还原有问题的页。如果你在处理很大的数据库,这会有很大的区别。
1 USE master 2 -- Restore full database backup 3 RESTORE DATABASE PageLevelRestores 4 PAGE = '1:90' 5 FROM DISK = 'C:\Backups\PageLevelRestores.bak' 6 WITH NORECOVERY 7 GO
现在到了棘手的部分:在RESTORE DATABASE的T-SQL命令后,你要进行另一个事务日志备份。这个另外的日志备份是需要的,因为接下来你要保证在这个可用页进行的所有改变用作还原。没有这个额外的日志备份,SQL Server不能把你的页重新上线。
1 -- Backup the tail of the log... 2 BACKUP LOG PageLevelRestores TO 3 DISK = 'C:\Backups\PageLevelRestores_LOG_TAIL.bak' 4 WITH INIT 5 GO
进行完这个额外日志备份后,你可以在正确的顺序里恢复所有的日志备份,可以把数据库恢复上线。
1 -- Restore all available log backups in the correct order 2 RESTORE LOG PageLevelRestores FROM 3 DISK = 'C:\Backups\PageLevelRestores_LOG1.bak' 4 WITH NORECOVERY 5 GO 6 7 -- Finally restore the tail log backup 8 RESTORE LOG PageLevelRestores FROM 9 DISK = 'C:\Backups\PageLevelRestores_LOG_TAIL.bak' 10 WITH NORECOVERY 11 GO 12 13 -- Finally finish with the restore sequence 14 RESTORE DATABASE PageLevelRestores WITH RECOVERY 15 GO
现在当你再次查询表时,你会看到SELECT语句成功执行没有任何I/O错误,在这个表里没有丢失任何数据。还是很简单,是不是?
1 USE PageLevelRestores 2 GO 3 4 -- Retrieve the selected records 5 SELECT * FROM Test 6 GO
关于在SQL Server里怎么进行页级别的恢复就分享到这里啦,希望上述内容能够让大家有所提升。如果想要学习更多知识,请大家多多留意小编的更新。谢谢大家关注一下亿速云网站!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。