블로그 이미지
SQL Server VS. 석이 minsouk@hotmail.com MSSQL 쿼리성능 관련해 궁금한 사항이 있다면 언제나 누구나 TeamViewer + Line (네이버 japan 메신저) 에 minsouk1 추가 후 연락주세요~ 010-9967-0955 보미아빠

카테고리

보미아빠, 석이 (436)
밥벌이 (16)
싸이클 (1)
일상 (1)
Total192,362
Today5
Yesterday67

달력

« » 2017.10
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        

공지사항

dbcc writepage

분류없음 / 2015.11.27 18:40

아래 명령어를 써 문제가 되면 아무도 책임져 주지 않습니다.

목숨 걸어야 할때만 쓰세요 (백업도 없고.....-_- 아무도 안도와줘~ )


823 윈도우 api 로 읽기 쓰기할때 장치가 없거나 억세스 할 수 없을때 로깅
824 checksum 값이 실제값과 예상값이 틀림


오류: 824, 심각도: 24, 상태: 2.

SQL Server detected a logical consistency-based I/O error: 체크섬이 잘못되었습니다(예상: 0xfc3881de, 실제: 0xa0e6ae8a).. It occurred during a 읽기 of page (4:133015609) in database ID 6 at offset 0x0000fdb5072000 in file 'O:\db.ndf'.  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. 



1개 페이지의 내용의 잘못된 값은 포기하고, 실제 계산된 체크섬값을 기록해 보기로 한다면,
dbcc traceon (3604, -1)
dbcc WRITEPAGE ('db', 4, 133015609, 60, 4, 0x8aaee6a0, 1) 명령어를 이용해 수정을 시도 합니다.
인자는 (데이터베이스 이름, 파일번호, 체크섬값의 offset 위치 항상 같음, 몇바이트를 라이트할지, 입력할 값, 디스크에 바로기록)

위 로그에서 offset 값은  0x0000fdb5072000  에서 8192로 나누면 page번호값이 나옵니다. 왜 두번 나오게 했나 몰라 -_-~
0x0000fdb5072000 / 8192 = 133015609


클러스터 시스템에서 운영되는 SQL Server 는 OS 에서 SQL 서버 먼저 내리고 끌것!
원래 shutdown 을 클릭하면 리소스를 넘기고 꺼지지만, 어떤 오류가 있어 리소스를 정상적으로 offline 못 시키고 다운 될 경우도 있고 이 경우 디스크가 먼저 떨어져 sql 에서 파일을 핸들링 하려고 하는데, 디스크가 없어져버리는 823을 일으킬 가능성이 있고, 또 이것이 데이터만 쓰고 체크섬은 기록하지 못하는 824 오류를 만들어 낼 수 있다.

더 심각한 것은 데이터베이스 복구는 roll-forward roll-back 이라는 잘 알려진 프로세스에 의해 복구가 된다. 최근 페이지에 checkpoint 후 발생한 어떤 트랜젝션에서 commit 이 있었다면 roll-forward 를 이용해 다시 써야 한다. 그런데, 해당 페이지에 824 checksum 미스매치가 발생했다면 복구 프로세스를 완료하지 못하게 된다. 사실 이 페이지가 checksum 오류가 일어나기 쉬운 포인트 이기도 하다. 디스크에 써 지다가 디스크가 떨어져 버렸으니 말이다.

엔터프라이즈의 경우 deffered transaction 이나 자동 페이지복구 기능으로 복구가 가능할 수 있다.

Transaction rollforard 에서 걸리는 경우 복구 가능한지는 테스트가 필요하다.

 

https://msdn.microsoft.com/en-us/library/ms188290.aspx
https://msdn.microsoft.com/ko-kr/library/bb677167(v=sql.120).aspx
http://www.sqlskills.com/blogs/paul/disaster-recovery-101-dealing-with-negative-spids-2-and-3/


실제

오류: 824, 심각도: 24, 상태: 2.

오류: 3313, 심각도: 21, 상태: 2.

SQL Server detected a logical consistency-based I/O error: 체크섬이 잘못되었습니다(예상: 0xfc3881de, 실제: 0xa0e6ae8a).. It occurred during a 읽기 of page (4:133015609) in database ID 6 at offset 0x0000fdb5072000 in file 'O:\xx.ndf'.  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.

During redoing of a logged operation in database 'paperbbs7', an error occurred at log record ID (2384385:3223121:189). Typically, the specific failure is previously logged as an error in the Windows Event Log service. Restore the database from a full backup, or repair the database.

오류: 3414, 심각도: 21, 상태: 1.

An error occurred during recovery, preventing the database 'xx' (database ID 6) from restarting. Diagnose the recovery errors and fix them, or restore from a known good backup. If errors are not corrected or expected, contact Technical Support.




------------------------------------########################################------------------------------------------------

일반적인 테스트 시나리오

------------------------------------########################################------------------------------------------------

USE MASTER

GO

 

 

ALTER DATABASE CURRUPTDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE

 

DROP DATABASE CURRUPTDB

 

CREATE DATABASE CURRUPTDB

GO

 

USE CURRUPTDB

GO

 

CREATE TABLE TBLX

(

 C1 VARCHAR(500)

,C2 VARCHAR(1000)

)

GO

 

INSERT INTO TBLX (C1, C2) VALUES ('A', REPLICATE('B',5))

INSERT INTO TBLX (C1, C2) VALUES ('C', REPLICATE('D',5))

 

SELECT * FROM TBLX

C1        C2

A        BBBBB

C        DDDDD

 

DBCC IND (CURRUPTDB, TBLX, -1)

 

PageFID        PagePID        IAMFID        IAMPID        ObjectID        IndexID        PartitionNumber        PartitionID        iam_chain_type        PageType        IndexLevel        NextPageFID        NextPagePID        PrevPageFID        PrevPagePID

1        89        NULL        NULL        245575913        0        1        72057594040549376        In-row data        10        NULL        0        0        0        0

1        80        1        89        245575913        0        1        72057594040549376        In-row data        1        0        0        0        0        0

 

DBCC TRACEON(3604,-1)

 

 

DBCC PAGE (CURRUPTDB, 1, 80, 2)

DBCC PAGE (CURRUPTDB, 1, 80, 3)

 

Memory Dump @0x000000000968A000

 

000000000968A000:   01010000 00800001 00000000 00000400 00000000  ....................

000000000968A014:   00000200 78000000 761f8600 50000000 01000000  ....x...v...P.......

000000000968A028:   22000000 59000000 02000000 00000000 00000000  "...Y...............

000000000968A03C:   00000000 01000000 00000000 00000000 00000000  ....................

000000000968A050:   00000000 00000000 00000000 00000000 30000400  ................0...

000000000968A064:   02000002 000e0013 00414242 42424230 00040002  .........ABBBBB0....

000000000968A078:   00000200 0e001300 43444444 44440000 00000000  ........CDDDDD......

000000000968A08C:   01000000 00000000 00000000 00000000 00000000  ....................

 

5줄 SKIP -> 20 * 5 = 100

9BYTE SKIP -> 100 + 9  = 109

110 BYTE 부터 1BYTE 를 42 로 업데이트 하면 A 가 B로 바뀌게 된다.

(정확하게 제외할 바이트만 계산해서 그 값부터 쓰면된다. 그게 DBCC WRITEPAGE 명령어 이다)

 

-- 단일사용자 모드에서 동작시킨다.

USE MASTER

GO

ALTER DATABASE CURRUPTDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE

 

DBCC WRITEPAGE (N'CURRUPTDB', 1, 80, 109, 1, 0x42, 1);

 

USE CURRUPTDB

GO

 

SELECT * FROM TBLX

 

메시지 824, 수준 24, 상태 2, 줄 64

SQL Server에서 일관성 기반의 논리적인 I/O 오류가 검색되었습니다: 체크섬이 잘못되었습니다(예상: 0xe472b33a, 실제: 0xe5f2b33a).. 파일 'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\CURRUPTDB.mdf'의 오프셋 0x000000000a0000에서 데이터베이스 ID 9에 있는 페이지 (1:80)의 읽기 중 이 오류가 발생했습니다. 자세한 내용은 SQL Server 오류 로그 또는 시스템 이벤트 로그의 추가 메시지에서 확인할 수 있습니다. 이는 데이터베이스 무결성을 위협하는 심각한 오류 상태이며 즉시 수정해야 합니다. 전체 데이터베이스 일관성 검사(DBCC CHECKDB)를 완료하십시오. 이 오류는 다양한 요인으로 인해 발생할 수 있습니다. 자세한 내용은 SQL Server 온라인 설명서를 참조하십시오.

 

 

이고 실제 다시 DBCC PAGE 를 보면 값을 바꾸었을때 디스크에 써져있는 예상한 체크섬(예상: 0xe472b33a)과 실제로 다시 계산한 체크섬값 0xe5f2b33a 이 값이 틀려 문제를 일으킨다.

실제값을 리틀엔디언 0x3ab3f2e5 으로 변경 후 이 값으로 바꾸어 주면 문제가 해결된다.

 

체크섬은 항상 OFFSET 값 60에서 시작하니 뭐 쉽게 바꿀수 있다.

DBCC WRITEPAGE (N'CURRUPTDB', 1, 80, 60, 4, 0x3ab3f2e5, 1);

 

DBCC PAGE (CURRUPTDB, 1, 80, 2)

 

Memory Dump @0x0000000010D1A000

 

0000000010D1A000:   01010000 00820001 00000000 00000400 00000000  ....................

0000000010D1A014:   00000200 78000000 761f8600 50000000 01000000  ....x...v...P.......

0000000010D1A028:   22000000 59000000 02000000 00000000 00000000  "...Y...............

0000000010D1A03C:   3ab3f2e5 00000000 00000000 00000000 00000000  :...................

0000000010D1A050:   00000000 00000000 00000000 00000000 30000400  ................0...

0000000010D1A064:   02000002 000e0013 00424242 42424230 00040002  .........BBBBBB0....

0000000010D1A078:   00000200 0e001300 43444444 44440000 00000000  ........CDDDDD......

0000000010D1A08C:   01000000 00000000 00000000 00000000 00000000  ....................

 

 

SELECT * FROM TBLX

C1        C2

B        BBBBB

C        DDDDD







저작자 표시 비영리 변경 금지
신고
Posted by 보미아빠

최근에 달린 댓글

최근에 받은 트랙백

글 보관함