ãŸããã
Gail Shaw ã®èšäºããã«ããç§ã®ããŒã¿ããŒã¹ã¯å£ããŠããŸãã ã㊠ãå é±ç§ãæçš¿ãã翻蚳㯠ãããçš®ã®èå³ãããããŸããããæ®å¿µãªãããç·Žç¿ãã¯å«ãŸããŠããŸããã§ããã ã¯ããããŒã¿ãä¿åããæ¹æ³ã説æããŠããŸãããäŸã¯ãããŸããã
æåã¯åãèè ã®å¥ã®ç¿»èš³ãäœæãããã£ãã®ã§ãããèããŠããåæ©ã«åºã¥ããŠãã®ããã«ãèªåã§ãæçš¿ãæžãããšã«ããŸããã ããããããã«ç§ãä¿ããçç±ã¯ããã¹ãã®çµããã«ãããŒãã§èª¬æããŸãã
SQL Serverã§ã®ããŒã¿ããŒã¹ã®å埩
åã®èšäºã§æ¢ã«è¿°ã¹ãããã«ãã¯ã©ã¹ã¿ãŒåã€ã³ããã¯ã¹ãŸãã¯ããŒãããŒãžãç Žæããå Žåããããã®ããŒãžã«å«ãŸããããŒã¿ã¯å€±ããããããã埩å ããå¯äžã®ãªãã·ã§ã³ã¯ããŒã¿ããŒã¹ãçŽæ¥åŸ©å ããããšã§ãã
SQL Serverã¯ãå€ãã®ããŒã¿ããŒã¹å埩æ©èœãæäŸããŸãã ãŸããããŒã¿ããŒã¹å šäœã®åŸ©å ã§ã-å€ãã®æéãããããŸãïŒããŒã¿ããŒã¹ã®ãµã€ãºãšããŒããã©ã€ãã®é床ã«äŸåããŸãïŒã 次ã«ãããŒã¿ããŒã¹ãè€æ°ã®ãã¡ã€ã«ã°ã«ãŒãïŒãŸãã¯ãããããã¡ã€ã«ïŒã§æ§æãããŠããå Žåãåã ã®ãã¡ã€ã«ã°ã«ãŒããŸãã¯ãã¡ã€ã«ã®åŸ©å ã ãã®å ŽåãããŒã¿ããŒã¹ã®æå·éšåã®ã¿ã埩å ããæ®ãã«åœ±é¿ãäžããããšã¯ãããŸããã ãããã®2çš®é¡ã®ããŒã¿ããŒã¹å埩ã¯éåžžã«é »ç¹ã«äœ¿çšãããå°æ¥çã«ã¯åœ±é¿ãåããŸããã
第äžã«ãSQL Server 2005ã§ã¯ãåã ã®ããŒã¿ããŒã¹ããŒãžã埩å ã§ããããã«ãªããŸãã-ãã®å Žåãæå®ããããŒãžã®ã¿ãããã¯ã¢ãããã埩å ãããŸãã DBCC CHECKDBãã巚倧ãªãã¡ã€ã«ã®ã暪ããããããã€ãã®å·šå€§ãªããŒãã«ã§ããã€ãã®ç ŽæããããŒãžãæ€åºããå Žåããã®ãããªãªã«ããªã¯ç¹ã«éèŠã«ãªããŸãã ãã¡ã€ã«å šäœã埩å ãããããã§ã¯ãªããããŒãã«å šäœã埩å ãããããã§ã¯ãªããæ°ããŒãžã®ã¿ã埩å ããããããããŠã³ã¿ã€ã ãå€§å¹ ã«åæžã§ããŸãã
èŠä»¶ãšå¶é
埩æ§ã¢ãã«ãšãã©ã³ã¶ã¯ã·ã§ã³ãã°ããã¯ã¢ããã®å¯çšæ§
èŠããŠããã¹ãæãéèŠãªããšã¯ãåã ã®ããŒãžã埩å ããããšã§ããããŒã¿ããŒã¹ã¯å®å šïŒå®å šïŒåŸ©æ§ã¢ãã«ããŸãã¯ãã°ãäžå®å šãªïŒäžæ¬ãã°ïŒåŸ©æ§ã¢ãã«ã䜿çšããå¿ èŠããããŸãã ããŒã¿ããŒã¹ãåçŽåŸ©æ§ã¢ãã«ã®å Žåããã以äžèªãããšã¯ã§ããŸããã
2çªç®ã®èŠä»¶ã¯ãå®å šããã¯ã¢ãããšãã©ã³ã¶ã¯ã·ã§ã³ãã°ã®ããã¯ã¢ããããåã£ãŠãåããªãäžé£ã®ãã°ïŒ ãã°ãã§ãŒã³ ïŒã圢æããå¿ èŠãããããšã§ãã BACKUP LOG WITH TRUNCATE_ONLYïŒNO_LOGïŒã³ãã³ããå®è¡ããããã©ã³ã¶ã¯ã·ã§ã³ãã°ãåæžããããã«åçŽãªåŸ©æ§ã¢ãã«ã«åãæ¿ãããç ŽæããããŒãžãå«ãŸãªãæåŸã®å®å šããã¯ã¢ãã以éã®ãã¹ãŠã®ãã©ã³ã¶ã¯ã·ã§ã³ãã°ããã¯ã¢ãããããå ŽåïŒãããå«ãïŒæãå®å šãªããã¯ã¢ããïŒ-éèªã®ãã§ãŒã³ã«ã€ããŠå¿é ããå¿ èŠã¯ãããŸããã
çè«çã«ã¯ããã®ã³ã°ãäžå®å šãªãªã«ããªã¢ãã«ã§ã¯ãäžèšã®æ¡ä»¶ãæºããããæå°ãã®ã³ã°ã§å®è¡ãããæäœã«ãã£ãŠåŸ©å ãããããŒãžãå€æŽãããªãå Žåãåã ã®ããŒãžã®ãªã«ããªã¯æ£åžžã«æ©èœããŸãã
SQL Serverã®ãšãã£ã·ã§ã³
SQL Serverã®ã©ã®ãšãã£ã·ã§ã³ã§ãããŒãžã®åŸ©å ãå¯èœã§ããããšãã£ã·ã§ã³Enterprise Editionããã³Developer Editionã§ã¯ãç ŽæããããŒãžããªã³ã©ã€ã³ã§åŸ©å ã§ããŸãã ãªã«ããªäžã«ããŒã¿ããŒã¹ã«ã¢ã¯ã»ã¹ã§ããŸãïŒããã«ããããã®ããŒãžèªäœãã圱é¿ãåããªããå ŽåãçŸåšåŸ©å äžã®ããŒãžãå±ããããŒãã«ãåç §ããããšãã§ããŸããããã§ãªãå Žåããªã¯ãšã¹ãã¯å€±æããŸãïŒã Enterprise Editionããäžã®ãšãã£ã·ã§ã³ã§ã¯ãããŒãžã®ãªã«ããªããªãã©ã€ã³ã§è¡ããããªã«ããªäžã«ããŒã¿ããŒã¹ã䜿çšã§ããªããªããŸãã
ç ŽæããããŒãžã¿ã€ã
ã€ã³ããã¯ã¹ãŸãã¯ããŒã¿ããŒãžãç Žæããå ŽåãEnterprise Editionã§ãªã³ã©ã€ã³ã§å埩ã§ããŸãã
éèŠãªã·ã¹ãã ããŒãã«ã«ã¢ã¿ããããããŒãžã¯åŸ©å ã§ããŸãããããŒã¿ããŒã¹ã埩å ãããšãSQL Serverã®ã©ã®ãšãã£ã·ã§ã³ã§ã䜿çšã§ããªããªããŸãã
ããã¬ãŒã¹ã¡ã³ãã«ãŒããã¯ãåå¥ã«ã埩å ã§ããŸããã GAMãSGAMãPFSãMLãDIFFããŒãžãç ŽæããŠããå Žåã¯ãããŒã¿ããŒã¹å šäœã埩å ããå¿ èŠããããŸãã å¯äžã®äŸå€ã¯IAMããŒãžã§ãã ãããã¯ããµã€ããããããæããŸãããããŒã¿ããŒã¹å šäœã§ã¯ãªãã1ã€ã®ããŒãã«ã®ã¿ãèšè¿°ãããããã®å埩ã¯å¯èœã§ãã
ããŒã¿ããŒã¹ã®èªã¿èŸŒã¿ããŒãžïŒæåã®ããŒã¿ããŒã¹ãã¡ã€ã«ã®9ããŒãžç®ïŒãšãã¡ã€ã«ããããŒããŒãžïŒåãã¡ã€ã«ã®0ããŒãžç®ïŒãåå¥ã«åŸ©å ããããšã¯ã§ããŸãããç ŽæããŠããå Žåã¯ãããŒã¿ããŒã¹å šäœã埩å ããå¿ èŠããããŸãã
å®éã«ã¯ãå埩
ããŠãæåŸã«ãçè«ããå®è·µã«ç§»ããŸãã
ãŸãããã¬ãŒãã³ã°ã«ã¯ãç ŽæããããŒã¿ããŒã¹ãå¿ èŠã§ãã
ããŒãdb
å®éšã«ã¯ãSQL Serverã«ä»å±ã®AdventureWorksããŒã¿ããŒã¹ã䜿çšããŸãã ã€ã³ã¹ããŒã«ããªãã£ãå Žåãå¿ èŠã«å¿ããŠã ããããããŠã³ããŒãã§ããŸãã å®å šåŸ©æ§ã¢ãã«ã«è»¢éããŸãã
ALTER DATABASE AdventureWorks SET RECOVERY FULL
ç§ã¯ãŸã ãšã©ãŒããªããšç¢ºä¿¡ããŠããŸãïŒ
DBCC CHECKDB('AdventureWorks') WITH NO_INFOMSGS, ALL_ERRORMSGS, DATA_PURITY
å®å
šããã¯ã¢ãããäœæããŸãã
BACKUP DATABASE AdventureWorks TO DISK = 'D:\tmp\aw_backups\aw_full_ok1.bak'

ãã®ããŒã¿ããŒã¹ã§ã¯ãã¯ã©ãã·ã¥ããŒãã«ãäœæããŸãã
CREATE TABLE crash (txt varchar(1000))
varcharåãã£ãŒã«ããå°ç¡ãã«ããŠãçªç¶SQL Serverã圌èªèº«ãæžã蟌ãã ããŒã¿ã§ã¯ãªãå Žåã«äœãèµ·ãããã確èªããŸãã
äœããå°ç¡ãã«ããåã«ããããäœãã§åããå¿ èŠããããŸãã äœæããããŒãã«ã«å·ŠããŒã¿ãæã¡èŸŒã¿ãŸãã
SET NOCOUNT ON DECLARE @i INT SET @i = 1 WHILE @i<100000 BEGIN INSERT INTO crash SELECT REPLICATE('a', 1000) SET @i = @i + 1 END SET NOCOUNT OFF
çŸåšããã©ã³ã¶ã¯ã·ã§ã³ãã°ãããã¯ã¢ããããŠããŸãã
BACKUP LOG AdventureWorks TO DISK = 'D:\tmp\aw_backups\aw_log_ok1.trn'

次ã«ãããŒã¿ãå°ãå€æŽããŠã¿ãŸãããã

ããã§ããã¹ãŠã®æºåãæŽããŸããã ããŒã¿ããŒã¹ãåæããFARïŒãŸãã¯ãã䟿å©ãªãã®ïŒã§mdfãã¡ã€ã«ãéãããã®äžã®æååãzzzzzzzããæ¢ããããã€ãã®ãzããä»»æã®æåã«çœ®ãæããŸãã

ããŒã¿ããŒã¹ãç Žæãããããæ¥ç¶ããŸãã ãããŠãã¯ããåã®èšäºã§ãããŒã¿ããŒã¹ãåæ/æ¥ç¶ãã䟡å€ã¯ãªããšã¯ã£ãããšèšãããããšãèŠããŠããŸãã ããããç§ãã¡ã®å Žåãããã¯çµ¶å¯Ÿã«ãå®å šãã§ã-ãçããããããŒã¿ããŒã¹ã¯èœã¡ãŸããã
ãšã©ãŒãæ¢ã
ãããã£ãŠãç ŽæããããŒã¿ããŒã¹ã¯æ£åžžã«åäœã«æ»ããŸããã æŽåæ§ãã§ãã¯ãå床å®è¡ããŸãã
DBCC CHECKDB('AdventureWorks') WITH NO_INFOMSGS, ALL_ERRORMSGS, DATA_PURITY
ãã®çµæãç§ãã¡ãåŸ
ã£ãŠãããã®ïŒç ŽæããããŒãžã®æ°ãå¿ããªãã§ãã ããïŒ ïŒïŒ
Msg 8928, Level 16, State 1, Line 1
Object ID 1883153754, index ID 0, partition ID 72057594054246400, alloc unit ID 72057594061651968 (type In-row data): Page (1:20455) could not be processed. See other errors for details.
Msg 8939, Level 16, State 98, Line 1
Table error: Object ID 1883153754, index ID 0, partition ID 72057594054246400, alloc unit ID 72057594061651968 (type In-row data), page (1:20455). Test (IS_OFF (BUF_IOERR, pBUF->bstat)) failed. Values are 29493257 and -4.
CHECKDB found 0 allocation errors and 2 consistency errors in table 'crash' (object ID 1883153754).
CHECKDB found 0 allocation errors and 2 consistency errors in database 'AdventureWorks'.
repair_allow_data_loss is the minimum repair level for the errors found by DBCC CHECKDB (AdventureWorks).
ãã®å ŽåãããŒãïŒã€ã³ããã¯ã¹ID = 0ïŒäžã®ããŒã¿èªäœãç ŽæããŠãããããSQL Serverã¯ãã®ããŒã¿ãå埩ã§ããŸããã
次ã®3ã€ã®ãªãã·ã§ã³ããããŸãã
- ããŒã¿æ倱ã«å¯ŸåŠããDBCC CHECKDBïŒ 'AdventureWorks'ãREPAIR_ALLOW_DATA_LOSSïŒãå®è¡ããŸã
- ãã©ã³ã¶ã¯ã·ã§ã³ãã°ã®ã¢ã¯ãã£ããªéšåã®ããã¯ã¢ãããäœæããããŒã¿ããŒã¹å šäœã埩å ããŸãããã®çµæãããŒã¿ã®æ倱ã¯ãããŸããããæéãããããŸãã
- ãã©ã³ã¶ã¯ã·ã§ã³ãã°ã®ã¢ã¯ãã£ããªéšåã®ããã¯ã¢ãããäœæããç ŽæããããŒãžã1ã€ã ãïŒïŒïŒåŸ©å ããŸã
ç ŽæããããŒãžã埩å ãã
ãŸãããã©ã³ã¶ã¯ã·ã§ã³ãã°ã®æåŸã®ãã©ã°ã¡ã³ããããã¯ã¢ããããå¿ èŠããããŸãïŒ ããŒã«ããã¯ã¢ãã ïŒã åæã«ãEnterprise Editionã䜿çšããŠããå Žåã¯ãNORECOVERYãã©ã¡ãŒã¿ãŒãè¿œå ã§ããŸããããã®ãã©ã¡ãŒã¿ãŒã¯ãããŒã¿ããŒã¹ãã埩å ãç¶æ ã«ããŸããããã¯ããã®ãšãã£ã·ã§ã³ããªã³ã©ã€ã³ããŒãžå埩ããµããŒãããŠããããã§ãã ããã«ãEnterprise Editionã§ã¯ããã°ãã§ãŒã³ãäžæãããªãããã«ãã©ã³ã¶ã¯ã·ã§ã³ãã°ã®ããã¯ã¢ãããå®æçã«å®è¡ããŠããå ŽåãCOPY_ONLYããã¯ã¢ãããäœæã§ããŸãã
ç§ã¯ãªãã©ã€ã³å埩ã®éããã©ãã次ã®ããšãè¡ããŸãã
BACKUP LOG AdventureWorks TO DISK = 'D:\tmp\aw_backups\aw_log_fail3.trn' WITH NORECOVERY

ããã§ãç ŽæããããŒãžã修埩ã§ããŸãã ãŸããå®å šããã¯ã¢ããïŒaw_full_ok1.bakïŒã䜿çšããŸãã
RESTORE DATABASE AdventureWorks PAGE = '1:20455' FROM DISK = 'D:\tmp\aw_backups\aw_full_ok1.bak' WITH NORECOVERY
ãã®çµæã次ã®ããšãã§ããŸãã

ãã©ã³ã¶ã¯ã·ã§ã³ãã°ãããŒã«ããã¯ããå¿ èŠããããããNORECOVERYãªãã·ã§ã³ã䜿çšããå¿ èŠãããããšã«æ³šæããŠãã ããã
RESTORE LOG AdventureWorks FROM DISK = 'D:\tmp\aw_backups\aw_log_ok1.trn' WITH NORECOVERY
ãããŠ
RESTORE LOG AdventureWorks FROM DISK = 'D:\tmp\aw_backups\aw_log_fail3.trn' WITH RECOVERY

ãã¹ãŠãããŸããã£ãããã§ãDBCC CHECKDBãèµ·åããŠ...

å埩ã«æåããŸããã
å®å šãªããã¯ã¢ããããããŒã¿ããŒã¹å šäœã埩å ããã®ã§ã¯ãªããç ŽæããããŒãžã®ã¿ã埩å ãããããããŠã³ã¿ã€ã ãççž®ãããããšã«æ³šæããŠãã ããïŒããã¯ã¢ããå šäœã埩å ããå Žåãããã¯ã¢ããã¯8.5ç§ã§å埩ããŸãããããŒã¿ããŒã¹ã倧ããã»ã©ãæéå·®ããããŸãïŒã ãªã³ã©ã€ã³ãªã«ããªã䜿çšããSQL Server Enterprise Editionã®ã©ãããŒãªãã®ã¯ããã°ããã¯ã¢ããããã®ãªã«ããªæéãç¯çŽãããªãã©ã€ã³ãªã«ããªãæ²ããããšã«ããã°ã¯å®å šã«åŠçãããŸãã
ãŸããSQL Server 2005ã2008ã2008 R2ã§ã¯ãT-SQLã䜿çšããå Žåã«ã®ã¿åäžããŒãžã®åŸ©å ãå¯èœã§ããããšãè¿œå ãã䟡å€ããããŸã; Denaliã¯GUIãä»ããŠãããå®è¡ã§ããããã«ãªããŸããã
ããããDBCC CHECKDBã®å Žåã¯ã©ãã§ããããïŒ
念ã®ãããREPAIR_ALLOW_DATA_LOSSãã©ã¡ãŒã¿ãŒãæå®ããŠDBCC CHECKDBãå®è¡ããå Žåã«SQL Serverãäœãå®è¡ãããã確èªããããšã«ããŸããã ãã¹ãŠåããšã©ãŒïŒ

ãŸããããŒã¿ããŒã¹ãSINGLE_USERã¢ãŒãã«ããŸãã
ALTER DATABASE AdventureWorks SET SINGLE_USER
次ã«ããªã«ããªãéå§ããŸãã
DBCC CHECKDB('AdventureWorks', REPAIR_ALLOW_DATA_LOSS) WITH NO_INFOMSGS, ALL_ERRORMSGS, DATA_PURITY
èŠçŽãããšïŒ
Repair: The page (1:20455) has been deallocated from object ID 1883153754, index ID 0, partition ID 72057594054246400, alloc unit ID 72057594061651968 (type In-row data).
ãããSQL Serverã¯ãç ŽæãããŒãžãåé€ããŸããã 誰ã§ãã¢ã¯ã»ã¹ã§ããããã«ããŒã¿ããŒã¹ãMULTI_USERã¢ãŒãã«ããäžè¶³ããŠãããã®ã確èªããŸãã

SQL Serverã®ããŒãžãµã€ãºã8KBã§ããããŠãŒã¶ãŒããŒã¿ã«ã€ããŠã¯äœ¿çšã§ããããŒã¿ãå°ãå°ãªãå Žåããã¹ãŠãèªç¶ã§ãããããããŒãã«ã¯7ã¬ã³ãŒããã€ãæžéããããŸãïŒæåã¯99999ã§ããïŒã ãã®ããŒãã«ã«ã¯ã¯ã©ã¹ã¿ãŒåã€ã³ããã¯ã¹ããªãã£ããããããŒã¿ã¯ã©ã³ãã ãªé åºã§ä¿åã§ããŸãã ã©ã®ããŒã¿ã倱ãããã®ããç¥ãããšããã§ããŸããã§ããã
ãªãã翻蚳ã§ã¯ãªãã®ã§ããããïŒ
ãªãããããŸã 翻蚳ã§ã¯ãªãããåæ©ã«åºã¥ããæçš¿ãªã®ã§ããããã äºå®ããããªãã¯ãã¡ã€ã³ã«ã¯ãGail Shawã«ããèšäºãããŒãžã®åŸ©å ãã¯ãããŸããã SQL Server MVPã®æžç±Deep Dives vol.2ã«ã¯ãã®ãããªã»ã¯ã·ã§ã³ããããããªãå ·äœçãªãéã§è²©å£²ãããŠããŸãïŒãã ããåœç¶ãã€ã³ã¿ãŒãããã§ç°¡åã«èŠã€ãããŸãïŒã翻蚳ãå ¬éããã®ãæ£ãããã©ããã¯ããããŸããã
äžè¬ã«ãç§ã¯ãã®èšäºãèªã¿ãäž»èŠãªç¹ã«æ³šæããããããèªåã§ããã¹ããæžãããã®éçšã§ä¿®åŸ©ã®å®éšãè¡ããŸããã ãã®çµéšã誰ãã«åœ¹ç«ã€ããšãé¡ã£ãŠããŸãã
ãããŠã玳士ããã®å®éšãç¹°ãè¿ãããšã決å®ããå Žåãããªããéåžžã«æ éã«ãªãããšãå¿ããé¡ã£ãŠããŸãïŒäŸãã°ãæ¬çªãµãŒããŒã®ã¡ã€ã³ããŒã¿ããŒã¹ã§å®éšããªãããšïŒã ç§ã¯ããªãã®è¡åã«äžåã®è²¬ä»»ãè² ããŸããã