직업병은 어쩔 수 없지



퇴근할라는 김 모 수석 붙잡고 나눈 대화중 건질만한거 몇가지.

쥔장/대량 데이터 마이그레이션 할 때 저희가 하는 것처럼 SSIS가지고 병렬로 읽어서 하는거 괜찮나요?

김 수석/네. 대용량에서는 그렇게 해야됩니다. 클러스터 인덱스 잡는거 한방에 실행시키는거는 원 트랜잭션이고 엄청나게 데이터가 클때 트랜잭션 로그도 많이 쓰고 소팅하는데 디스크도 많이 잡아먹습니다. 병렬로 쪼개서 읽어서 부으면 제일 좋지요. 하지만 bulk insert 베스트 프랙티스에서 이야기하는 것처럼 클러스터 인덱스 순으로 데이터를 부어도 공간이 연속적으로 할당되지 않을 가능성도 크고, 병렬로 부으면 데이터 들어가는 순서가 클러스터 인덱스 순서로 들어간다는 보장이 없으므로 클러스터 인덱스 빌드 속도는 생각보다 빠르지 않을 수 있습니다. 그래도 create clustered index 문 날리는 것보단 훨씬 빠릅니다.

BI나 DW같은 플젝할때는 대량 데이터 옮길때 저렇게 하는게 당연한데, 제가 삼성생명 플젝 할 때 메인프레임에서 내려온 데이터가 1조개였습니다. (흐어.. 1조!!! -_-) 이걸 저렇게 쪼개서 밀어넣었죠.

그리고 bulk insert 할 때 여러개를 완전히 동시에 돌리진 마십시오. 잘못하면 bulk insert api 콜할때 경합이 생겨서 한두개가 실패할 수도 있습니다. 1분정도 시차를 두고 돌리는게 안전합니다.


쥔장/sp_executesql 과 sp 에서 동일한 쿼리를 돌리는데도 실행계획이 다르게 나오는 경우가 있더군요. 이게 가능한 일입니까?

김 수석/네 가능합니다. 원래 sp 가 먼저 나온거고 옵티마이저는 sp 를 최적화하는 것을 가정하여 만들어져 있습니다. 그런데 sp_executesql 은 ad-hoc 을 sp 처럼 돌도록 하기 위해서 흉내를 내주는건데, 그게 sp 를 최적화하는거하고 완전히 똑같지는 않습니다(어떻게 다른지는 자세히 설명하지 않음. 설명해도 못알아들었을것임-_-) 그래서 실행계획이 다르게 나올 수 있습니다. 중요한 업무에는 sp를 분기해서라도 sp를 쓰시고 중요하지 않은 업무에서는 sp_executesql 을 쓰세요.

쥔장/앗. 제가 보니까 JDBC로 SQL2000 에 붙을 때 DB에서 보면 인풋버퍼가 sp_executesql;1 로 다 찍히던데 이렇게 되면 잘못하면 실행계획 엉뚱한거 만들어져서 난리가 날 수도 있겠네요???

김 수석/네 그렇지요. 대단히 복잡한 SQL을 JDBC로 매우 자주 날리면 완전 쥐약입니다.

쥔장/MS에서 나온 JDBC 드라이버 써도 그래요?

김 수석/네

쥔장/그럼 Java는 Oracle하고만 써야되나요?

김 수석/Oracle하고 붙여도 썩 좋지는 않습니다. Oracle은 OCI Call로 들어오는게 최선인데 JDBC는 범용적으로 돌아가게 만들다보니 별로입니다

(음.. 그런데 이건 좀 아닌것같기도... 예전에 얼핏보니 JDBC콜이 OCI콜로 변환이 되는 Oracle 드라이버가 있었던 것 같은데... 내가 자바를 잘 모르니 패스~ 아시는 분은 댓글로 좀 달아주세요...)


김 수석/쿼리 비용 평가를 할 때 MS내부의 테스트 머신에서 1초 돌아가는걸 비용 1로 본다고 책에 나와있죠? 그 테스트 머신 사양이 386PC 입니다. 예전에 SQL2.x, 3.x 개발할 때 쓰던 머신이라고 하는군요.

쥔장/ 오옷...

김 수석/근데 MS DB엔진 개발자들이 옵티마이저 개발할 때 특정 SQL에 대해서 어떤 코드가 저 기계 기준으로 비용 임계치를 초과하면 코드를 다시 만들어야 된다고 합니다. 임계치 안으로 들어올때까지 옵티마이저 코드를 계속 튜닝하는거죠. 사람 머리가 한계가 있는데 머리 빠개지겠죠???

쥔장/오옷....

김 수석/그리고 MS 제품 개발할 때 특정 시간이 되면 소스관리 서버가 개발자 PC에서 코드를 강제로 체크인 시킵니다. 그리고 자동빌드가 도는데, 빌드에 실패하면 그 개발자는 페널티를 받습니다. 그리고 페널티가 몇번 반복되면 그냥 짤립니다. 영주권이 없는 외국인 엔지니어들은 짤리면 일주일내에 귀국해야되기 때문에 그야말로 초긴장 상태로 일합니다. 그러다보니 시키지 않아도 밤새서 일하는 사람도 많지요. 그러다보니 빨리 승진도 하고 뭐 그런다더군요. 시간되면 칼퇴근 하는 사람들도 물론 있지만 안짤리기 위해서 낮밤 없이 일하는 사람도 많아요~

쥔장/오옷....

김 수석/LATCH_XX 같은 대기의 시간이 길어지면 이건 정말 심각한겁니다. 보통 LATCH는 일반적인 LOCK을 잡을 필요가 없을 때 잠깐 잡히고 사라지는게 정상인데 LATCH가 떠서 오래 지속되면 이건 리소스 고갈을 의심해볼 필요가 있습니다. DB입장에서 보면 일반적인 LOCK이 필요한 상황인데 리소스가 모자라서 LATCH를 요청한걸수 있거든요. 그런데 그게 대기시간이 오래되면 심각한거죠.

쥔장/오옷....

(LOCK 메카니즘에 대한 깊은 이해가 없어서 진위를 판단하기 힘들었음. 누가 아는 사람 없나요??? )

(근데 리소스를 고갈시키는 넘은 뭐가 될지 모르기 때문에 그게 문제. DB내부의 서버 프로세스라면 sysprocesses 에서 보이긴 하지만 DB에 액세스하는 서드파티 솔루션이라던가... 뭐 그딴 넘이라면 블러킹에 잡히지도 않고 그저 주변 상황보고 판단하는 수 밖에 없는데 실제 장애가 벌어진 상황에서 그걸 재빨리 판단하기란 쉽지 않다.. -_-)

쥔장/SQL서버 공부할 때 시중에 나와 있는 책, white paper, 블로그 글들 말고 특별히 더 구할 수 있는 것들이 있나요?

김 수석/사실 저희들도 그 이상 되는 자료들은 쉽게 접하기 힘듭니다. 내부적으로 100, 200, 300, 400 레벨 교육이 있는데 Inside SQL Server 2005 시리즈 책들은 200~300 레벨 정도 됩니다. MS본사 엔지니어들 블로그의 글들은 그보다는 좀 높구요. 400레벨 정도 되는 것은 일단 굉장히 어렵고 특허나 지적재산권에 관련된 것들이 많아서 외부에 공개가 안됩니다. 공개된 자료를 모두 다 깊이 이해하는 것도 그렇게 만만한 일이 아닙니다.

쥔장/한국MS연봉 마니 주나요? ㅋㅋㅋㅋ

김 수석/연봉 산정할 때 경쟁사로 생각되는 회사 10개사의 평균연봉을 구하고 언제나 6위에 위치하도록 합니다. 경쟁사는 어떤 회사가 될지는 알 수 없습니다. MS에 들어오면 얻는 거는 회사 이름값밖에 없습니다. ^^

(한국MS매력도 급감 ㅋㅋㅋㅋ)

Posted by maceo

05 30, 2007 23:38 05 30, 2007 23:38
, , , ,
Response
No Trackback , No Comment
RSS :
http://merritt.co.kr/tt/rss/response/101

거대용량 시스템 아키텍쳐

이베이 아키텍쳐 가 작년에 화제였다고 한다. 뒤늦게 알고선 회사에 공유차원에서 뿌렸다. 다들 어느 정도 충격을 받은 분위기. 그런데 이번에 MS에서 컨설팅하러 들어온 김 모 수석 컨설턴트에게 이베이 아키텍쳐에 대한 의견을 물었더니 흥미로운 대답을 해줬다.

"이베이 아키텍쳐요? DB를 SAM파일 수준으로만 사용하고 그 위에 OR매핑 올린거 말씀이죠? 몇년전에는 몰라도 지금은 시대에 뒤떨어인 아키텍쳐지요. 이런 아키텍쳐의 근본적인 사상은 옛날 TP모니터 시절, 모든 트랜잭션은 TP모니터에서 관리해야 한다는 사상에서 나온건데 이건 너무 이상적인 것이죠.

이거 만들 때 SUN에서 이베이에 상당 금액을 펀딩해서 레퍼런스 한번 만들 작정으로 밀어붙인거지, 그게 아니었으면 못했을겁니다. 일년 반정도 걸린걸로 알고 있습니다.  요즘의 추세는 용도별/업무별로 DB를 분리하고, 이건 똑같습니다만, EAI를 도입해서 업무가 비동기적으로 처리될 수 있도록 하는겁니다. 여러 DB를 참조하는 요구사항은 최대한 쳐내긴 하지만, 그렇지 못한 것들은 EAI 를 태워서 비동기적으로 처리합니다. 그렇게 했을 때 만족할만한 응답시간을 보이지 못하는 것들은 가끔 분산트랜잭션을 써서라도 동기적으로 처리하기도 합니다. 물론 성능에 희생이 약간 있습니다. MSDTC를 켜놓으면 관리상 어려움도 있죠. 하지만 이베이 수준의 OR매퍼 새로 만드는 것보다는 훨씬 쉽습니다..

KT NeOSS사이트가 2004년 당시 완전 재구축할 때 저런 아키텍쳐를 기반으로 했습니다. 당시로써는 MS플랫폼하에 세계에서 몇손가락 안에 꼽히는 규모였죠."

덧붙이자면 KT NeOSS 는 KT의 네트워크 관련된 고객 영업지원 시스템인데, 메가패스, ADSL 전용망  전화 관련된 기기 관리 회선 관리 고객 관리 뭐 그런 것들 해준다. 김 수석 얘기로는 회선이 2억 넘고 고객숫자도 거의 1억(개인,기업고객들..) 서비스 사용기록 등등의 데이터는 상상을 초월한다고 한다. 이런 사이트는 각 업무별로 DB를 분리하고(슈퍼돔 64way 16대가 들어가  있다) EAI로는 BizTalk을 썼다고 한다. 잘 돌아간다네~

그리고 Scalibility 관련하여 마이스페이스 DBA랑 같이 교육받으면서 들었다면서 마이스페이스 사례도 얘기해줬다. 마이스페이스의 트래픽은 정말 상상을 초월한다. 이베이보다도 훨씬 크다. 여기는 SQL서버 인스턴스가 500개가 돌아간다고 한다. 당연히 용도별로 DB분리되어 있는데, 여기 아키텍쳐에서 신기한 것은 캐쉬 데이터베이스가 있다는거다. 자주 사용되는 데이터를 별도의 DB서버에 갖다놓고 거기서 읽어가게 한다는거지. 그런 서버가 메인DB앞단에 수십대가 있다고 한다. 캐쉬할 데이터는 전날치 트래픽을 분석해서 자주 요청되는 데이터들을 모아서 하루에 한번씩 각 서버에 배치시켜 놓는다고. 여기에 SQL2005 의 Shared database 기술이 쓰였고, 데이터 갖다놓는 알고리즘은 자체적으로 만들었다는구먼. 아 신기한 아키텍쳐다...

아, 오라클 10g의 RAC에 대한 의견도 피력함. 실제 헤비한 로드가 들어오는 운영상황에서는 8 node 정도가 한계이고 더 이상 붙이면 아무리 메모리 공유를 한다고 하더라도 노드들끼리 메모리 동기화시키는 로드 때문에 성능향상이 별로 없다고.... 따라서 이베이나 마이스페이스급 트래픽을 보이는 곳에서는 먹히지 않는 방법이라고 한다. 이에 대해 나름 한국 오라클 출신 울팀 권대리는 "MS사람답게 얘기하네요" 라는 짤막한 촌평을... ㅎㅎㅎ 오라클 구루들은 이에 대해 뭐라 그럴지 궁금하군....

--------------

DB가 용도별로 쪼개져 있는거 좋다. 그런데 비즈니스 로직은 어떻게 되어야 할까? DB에 sp의 형태로 들어가 있어야 하나? 도메인 레이어가 있어야 하나? 시스템 아키텍쳐와는 별개로 SW아키텍쳐를 구성하는 것도 참 문제다. 정답이 없는건 당연한데, 정답에 접근하는 방법조차도 나와 있는게 너무 없다. 아키텍쳐는 역시 어렵다.

--------------

MCA:Database 라는게 생겼다. Microsoft Certified Architect : Database 이다. 국내엔 한명도 없다. 한국MS에도 없다. 전세계에는 100명 정도란다. MS 프로덕트 그룹하고 바로 컨택을 할 수 있는 거의 유일한 통로라는군. 미국가서 5주 교육받는데 2만5천 달러다. 교육받고 셤보는데 드럽게 어렵다고 한다. MS홈페쥐가서 찾아보자.

Posted by maceo

05 30, 2007 00:07 05 30, 2007 00:07
, ,
Response
No Trackback , 6 Comments
RSS :
http://merritt.co.kr/tt/rss/response/100


일전에 번역한 1TB 를 1시간에 로드하기를 근간으로 하고 sqlleade.com 의 문서도 읽어보고

여러가지 테스트를 해본 결과, 다음 설정이 베스트가 아닌가 싶다.

A서버(2000 or 2005) -> B서버(2005) 로 BIG_TABLE 을 이관한다고 가정하면

1. B서버에 SSIS 를 설치하고

2. B서버에 BIG_TABLE 을 생성. clustered index 도 생성해줌. 2005라면 파티션드 테이블로 함. 파티션을 n개로 했다면...

3. A서버의 BIG_TABLE을 읽어서 B서버의 BIG_TABLE로 FastLoad 하는 n개의 SSIS 패키지를 생성. SSIS와 SQL2005가 같은 머신에 있으면 OLEDB대상 말고 SQL서버 대상으로 함. 이건 Shared Memory를 통해서 DB에 데이터 넣으므로 조금 더 빠름. FastLoad 할 때는 TABLOCK 잡도록 함. 읽어올 때 where 조건은 clustered index 를 기준으로 데이터 안겹치게 함. 파티션 테이블 만들때 기준으로 하면 될 것임. 데이터 읽어올때는 order by clustered index 컬럼을 넣어줌. 이렇게 하면 데이터 들어가는 순서와 클러스터드 인덱스의 정렬순서가 동일하기 때문에 추가적인 부하가 거의 없이 클러스터드 인덱스를 만들 수 있음. 자세한 것은 BOL의 BULK INSERT 성능 최적화 부분을 읽어보면 됨.

4. 패키지를 실행하는 bat파일을 n개 만들고 한꺼번에 실행.

5. 네크웍을 마구 써대면서 테이블에 집어넣음. 테이블에 데이터 넣으면서 블러킹 발생하지 않는지 관찰. 파티션드 테이블이므로 블러킹이 없을 것임. 만약 2000 서버의 통짜 테이블이라면 FastLoad, rows_per_batch = 2500 commit_size = 2500 정도로 하는게 익스텐트 할당할 때 블러킹 거의 없이 잘 들어가는 것 같음.

위와 같이 하면 bcp로 텍스트로 내리는 과정 없이 네트웍타고 바로 넣어버리기 때문에 무쟈게 빠름. 아, 서버간 네트웍은 기가비트 이더넷이고 A서버 B서버 스토리지 모두가 괴물급 스토리지면 완전 대박임.

Posted by maceo

05 18, 2007 20:39 05 18, 2007 20:39
, ,
Response
No Trackback , No Comment
RSS :
http://merritt.co.kr/tt/rss/response/98

  T-SQL Progarmming - Inside Microsoft SQL Server 2005  Itzik Ben-Gan 외 지음, 필라넷 DB 사업부 옮김, 김정선 감수
T-SQL 내부 아키텍처에 대한 상세한 정보와 풍부한 프로그래밍 레퍼런스를 소개한다. 데이터베이스 개발자와 관리자가 실제 운영 환경에서 직면할 수 있는 복잡한 문제에 대한 솔루션으로 활용할 수 있는 권장 사례, 전문가의 비법, 예제 코드를 얻을 수 있다.

SQL2000 의 T-SQL 개발에 어느정도 익숙한 개발자라면 큰 무리없이 읽을 수 있다. 대단한 충격을 주는 내용은 아니지만 구석구석 알아두면 좋은 팁들이 많다. 번역 상당히 잘된 것 같다. SQL서버는 안그래도 자료도 별로 없고 공부할꺼리도 별로 없는데 그나마 이거라도 있으니 다행이다. 평이 좀 시큰둥하긴 한데, 상당히 좋은 책이다 ;-)

User inserted image

이제 1/3 가까이 읽었는데 역시 영어라 진도가 잘 안나가긴 한다. 대체로 쿼리의 난이도가 높지는 않지만, 잊기 쉬운 기본적인 사항을 잘 설명해주고 있다. 미처 몰랐던 것들도 몇개 배웠다. 역시나 좋은 책이다. SQL2005 공부하는 사람들은 기본기를 다지는 차원에서 꼭 봐야할 듯.







켄 헨더슨의 아키텍쳐 & 인터널 책이 MS내부 엔지니어 교육수준으로 200레벨밖에 안된다고 한다. 한국MS 내부 엔지니어가 그랬으니 이건 확실하다. 내부 엔지니어 교육은 500레벨까지 있다. 위의 책들은 한 150레벨 정도 되려나? 생짜 초보자용 책은 아니지만 이해에 크게 무리는 없으니...

그런데 상당수의 DBA들이 켄 헨더슨 책은 말할 것도 없고 저정도 되는 책도 안본다. 영어이기 때문이다. 책도 안보고 white paper 도 잘 안본다. 그러니까 결국 누구나 볼 수 있는 자료도 안본다는 얘기다. 이런 사람들이라면 아마도 MS기준으로 한 110~120레벨 되려나? 이정도는 상식적인 사고가 가능한 사람이 2,3년 경험 쌓으면 누구나 도달할 수 있다. 아무나 뽑아놓고 굴리면 다 할 수 있다. 이래서는 전혀 차별성이 없다.

사실 200레벨을 완벽하게 이해하는 DBA도 국내엔 몇 없을 걸로 본다. 서버 내부로 들어가면 사실상 OS 공부나 마찬가지다. 비전공자의 한계가 여기서 명확하게 드러난다. 그리고 국내 실정상 웹개발 몇년 하다가 DB로 오는 경우가 많아서 멀티스레드, IO, 메모리 관리 경험이 없는 DBA들이 대부분이다. KAIST, 서울대 정도 말고는 학부레벨에서 OS를 직접 만들어본 전산 전공자도 거의 없으니 어차피 대부분의 전산전공자들도 OS에 대한 이해는 피상적일 수밖에 없을거다. 위에서 잠깐 얘기한 한국MS 엔지니어도 SQLOS가 전문 영역이긴 한데, 자기도 전산전공이지만 OS는 책으로만 배웠다고 했다. 이 사람 얘기로는 한국MS SQL서버 엔지니어들은 Inside Windows 2000 하고 Inside SQL Server 2000, 아키텍쳐 & 인터널 책을 두세번 반복해서 읽는다고 한다. 그러면 서버 내부 돌아가는게 대충 이해가 간다는군. 근데 아키텍쳐 & 인터널 읽어보면 알겠지만 존내 어렵다 -_-;;;;

하여간 DB밑바닥은 밑바닥으로 가면 갈수록 이해가 어렵고 그다지 중요성도 못느끼기 때문에 DB에 관심있다는 사람들은 튜닝 정도 하다가 대부분 위쪽 영역으로 올라간다. 모델링, 메타데이터, 데이터 아키텍쳐 뭐 그런 영역 말이다. 하지만 역시 거기도 상식적인 사고가 가능하면 이해가 어렵지 않은 분야라 그냥 열심히만 하면 된다. 차라리 그 동네에서 이야기하는 이상을 실현하기 위해서 조직을 바꿔내는게 훨씬 더 힘든 문제라면 문제겠지...

아 진짜 두서없다.

그러니까 결론은 DB하는 사람들 공부 의외로 디게 안한다는거다. 고시공부하듯 DB공부하는 사람 하나도 못봤다. 근데 뭐든 경지에 오르려면 고시공부하듯 최소 1년이상은 파야된다. 떡하니 고시붙은건 아니지만 그 비슷한 공부를 해보니 알겠더라. 근데 문제는 이렇게 공부해봐야 알아주는 사람도 별로 없고 돈버는길도 별로 안보인다는거다. 흠... 그래서 다들 공부를 안하는거였나? -_-;;;;;;;



Posted by maceo

05 18, 2007 18:37 05 18, 2007 18:37
, ,
Response
No Trackback , No Comment
RSS :
http://merritt.co.kr/tt/rss/response/97


테이블 레벨에 제약조건을 걸 때 함수를 쓰게 된다. 이런 식이다.

create function dbo.uf_AAAA (@t int)
returns int
as
begin
   declare @cnt int
   select @cnt = count(*) from test_table where col1 = @t and reg_dt is null
   return @cnt
end


alter table test table add constraint CK__DUP_CHECK check ( dbo.uf_AAAA(col1) <= 1)

이렇게 하면 테이블에 데이터가 들어갈 때나 지워질 때, 수정될 때 언제나 위의 함수가 수행되게 된다. 그런데 만약 함수안에 들어가 있는 SQL문을 만족하는 인덱스가 없다면 test_table에 대한 풀스캔이 일어나게 되어 급격하게 성능이 나빠진다.

더욱 심각한 것은, 함수로 인한 성능저하는 실행계획에 잡히지도 않아서 알아내기가 매우 까다롭다. 그리고 위의 SQL이 트랜잭션 도중에 진행된다면 with(nolock) 이 없기 때문에 블러킹이 일어날 수가 있다. 이때 master..sysprocesses.blocked 컬럼에 spid가 0이 나온다. 즉 블러킹이 없다고 나오게 된다. 역시나 알아내기 힘들다. 또는 함수내의 SQL문이 복잡하다면 이 함수의 실행계획이 꼬일 가능성도 배제하지 못한다.

위와 같은 경우 master..sysprocesses 만 봐서는 상황을 알아내기가 힘들다.

조치법은 대략 다음과 같다.

1. 먼저 SQL2000 SP4를 깔자.
2. 구글에서 aba_lockinfo 를 쳐서 나오는 Sommerg? 의 블로그에서 aba_lockinfo 를 받아서 DB에 설치하자.
3. 블러킹 상황이 발생하면 aba_lockinfo 를 돌린다.

이 sp의 좋은 점은 블러킹 체인의 시작점을 보여줄 뿐 아니라 inputbuffer 와 함께 현재 시점에 실행중인 SQL문을 정확하게 잡아주는 것이다. 이걸 이용하면 테이블 레벨 제약조건에 걸린 함수가 문제를 일으키고 있음을 명시적으로 확인할 수 있다.

만약 함수내의 SQL이 비효율적이면 튜닝하거나 인덱스를 잡아주고, 함수의 실행계획이 잘못 잡혀 있으면 리컴파일 해주거나 drop 했다가 다시 create 해준다.



Posted by maceo

12 21, 2006 17:55 12 21, 2006 17:55
, , , ,
Response
No Trackback , No Comment
RSS :
http://merritt.co.kr/tt/rss/response/85

tempdb log growth 로 인한 tempdb contention


일반적인 경우 tempdb contention 은 커서, temp table, table 변수의 과도한 사용때문에 일어난다. tempdb contention 을 확인하려면

select * from master..sysprocesses where spid > 50 and waittime > 0


을 날려봐서 waittype 이 PAGELATCH_XX 또는 PAGEIOLATCH_XX 이고 waitresource가 2:XXXXXXX:XX 처럼 나올 때(2는 tempdb의 dbid임) tempdb contention 이라고 판단하면 된다. 이때 inputbuffer를 봐서 해당 쿼리에서 table 변수, order by, group by, temp table 사용을 제거하는 것이 1차적인 조치법이다.

하지만 tempdb log growth로 인해서 tempdb contention 이 발생하는 경우도 있다. 대기를 보면 마찬가지로 tempdb 에 대기가 생기는데, 정작 inputbuffer로 본 sp들은 tempdb를 그렇게 과도하게 사용하지 않거나 contention이 몇분정도 지난 후 자연스럽게 풀리는 경우 tempdb log growth로 인한 contention이라고 의심해볼 수 있다.

tempdb는 복구모드가 simple 이고 2,3시간에 한번씩 로그를 떨어내는데, 로그 떨어내는 시점에 활성 트랜잭션이 tempdb 에 걸려있으면 로그 떨어내는게 실패하고 log growth 가 일어나게 된다. 굉장히 드문 경우다.

log growth 를 확인하는 것도 어렵다. log growth가 성공한다 하더라도 아무런 기록이 남지 않는다. 단지 파일 크기의 증가로 확인할 수 있을 뿐이다. log growth가 실패하면 그때야 비로소 에러로그에 남는다. log growth 가 실패하는 경우는 과도한 IO부하가 원인일 때가 많다. 이것도 에러로그에 남는다. 그런데 IO부하로 log growth가 실패할 정도로 과도한 IO를 보이는 사이트는 국내에 몇개 없다.-_-;;;

사실 log growth가 성공할 때도 에러로그를 남기는 undocumented trace flag가 있다고 하는데, 뭔지도 모르겠고 undocumented 이므로 MS의 공식적인 기술지원이 없다면 쓰지 않는 것이 현명하겠다. 사실 tempdb log growth로 인한 contention이 일어날 정도의 사이트가 국내에는... 다섯군데도 안될거라 본다. 모두 MS기술지원 받고 있겠지머-_-;;;;;;

조치법은 간단하다.

주기적으로 tempdb log에 대해서 truncate log 를 해서 비워주면 된다.
dbcc loginfo 로 tempdb log 사용량에 대한 모니터링도 지속하자.

Posted by maceo

12 18, 2006 11:33 12 18, 2006 11:33
,
Response
No Trackback , No Comment
RSS :
http://merritt.co.kr/tt/rss/response/84

SQL Server 에서 index merge 유도하기


http://merritt.co.kr/tt/73 에서 인덱스 머지에 관한 기초적인 이야기를 썼는데, 1억건이 넘어가는 엄청나게 큰 테이블들에 조회조건이 굉장히 다양하게 들어올 때 인덱스 구조를 잡는 것이 상당한 고민이 된다.

이때 인덱스 머지 전략을 적절하게 사용하면 인덱스 길이를 최소화하면서 성능도 그렇게 떨어지지 않는 쿼리를 만들어낼 수 있다. 그러면 인덱스 머지를 어떻게 유도할 것이냐가 문제다. 대부분의 경우 서버가 알아서 실행계획을 세워준다지만, 힌트를 줘서 유도할 수 있으면 싶을 때도 있다.

SQL 서버에는 인덱스 머지라는 힌트는 없지만, index 를 여러개 지정함으로써 인덱스 머지 플랜을 유도할 수 있다. 자세한 것은 SELECT 문에 대한 BOL 의 설명을 자세히 읽어보면 된다.

select * from table1 a with(index(ix_1, ix_2) where col1 = 'A' and col2 = 2

이렇게 하면 ix_1 과 ix_2 를 각각 읽어서 clustered index key 를 이용한 join 을 수행하게 된다. 컬럼의 분포도와 선택성을 고려해서 여러가지로 테스트해보면 이런 전략이 유용할 때가 있다.

Posted by maceo

12 18, 2006 11:13 12 18, 2006 11:13
, , , ,
Response
No Trackback , No Comment
RSS :
http://merritt.co.kr/tt/rss/response/83



local server 에서

update a set col1 = 'A' from [remote].dbo.db_name.table1 where col2 = 123


을 날리면

remote 서버와의 통신상태가 좋지 않을 경우 OLEDB 대기가 걸릴 수 있다.

OLEDB대기는 local server에서

select * from master..sysprocesses where spid > 50 and waittime > 0


으로 확인가능하며, 이때 waittype은 OLEDB, waitresource 는 remote(SPID:xx) 와 같은 형식으로 나오게 된다. 잽싸게 remote 로 들어가서

select * from master..sysprocesses where spid = xx
dbcc inputbuffer(xx)


를 해보자. 블러킹이 걸렸을 수도 있는데, 이럴때는 블러킹 해결하면 되고  sp_cursorfetch;1 이라고 나오는 경우가 있다. 이거는 remote 연결에서 server cursor 를 쓴다는 의미이다.

(참조) http://www.dbguide.net/know/know101003.jsp?&catenum=14&IDX=542

local server에서 remote로 바로 update를 날리지 말고 remote 에 sp 를 만들어두고 그걸 호출하도록 하자. 아, 물론 remote에 대해서 rpc in, rpc out 설정이 되어 있어야 된다.

Posted by maceo

12 18, 2006 10:53 12 18, 2006 10:53
, , ,
Response
No Trackback , No Comment
RSS :
http://merritt.co.kr/tt/rss/response/82

장난이 아니다 ㅠ_ㅠ

select * into t from AAAAA

이렇게 날리면 physical_io 가 초당 1500정도 나오고 쿼리 취소하면 순식간에 취소되는 것이

create table t (seq int identity(1,1))
set identity_insert t on
insert into t (seq) select seq from AAAAA

이렇게 하고 돌리면 physical_io 가 1/4 수준으로 줄어들고 쿼리 취소시 롤백도 한참 걸린다.

울회사 메인DB서버 스토리지 같은 괴물 스토리지에서도 똑같은 걸 보니 identity_insert on

옵션이 SQL서버 내부적으로 굉장히 복잡한 처리 과정을 거치는 것으로 생각된다.

insert 할 때 병렬 실행 계획이 세워지지도 않는다.

아. 이런.. ㅠ_ㅠ


Posted by maceo

10 27, 2006 06:02 10 27, 2006 06:02
, ,
Response
No Trackback , No Comment
RSS :
http://merritt.co.kr/tt/rss/response/80

길다란 복합 인덱스가 능사가 아니다?


작성: 박노철(maceo.park@gmail.com)


오늘 기존 테이블에 대한 index tuning 을 하다가 발견한 현상.

테이블 T1 사이즈 : 1500만건
T1에는 클러스터드 인덱스가 있다고 가정하자.

select * from T1 where a = 1 and b = 1 and c = 1 and d = 1

이라는 쿼리가 있다고 치자. 이럴때는 보통

create index idx__a_b_c_d on T1 (a,b,c,d)

이렇게 잡는다.

그런데 다음 쿼리가 들어왔다.

select * from T1 where c = 1 and d = 1

그러면 c,d 에
create index idx__c_d on T1 (c,d)

복합인덱스를 잡으면 된다.

이제 우리는 a,b,c,d 와 c,d 에 대한 인덱스 두개를 가지고 있다. 일반적으로 위와 같이 해결 하지만 다른 방법도 생각해볼 수 있다. where조건을 구성하는 컬럼을 분해해서 다음과 같이 인덱스를 구성하는 것이다.

create index idx__a_b on T1 (a,b)
create index idx__c_d on T1 (c,d)

좀 이상하지 않은가?????

이렇게 하면 where a=1 & b=1 & c=1 & d=1 에 대해서 idx__a_b를 타게 될테니 idx__a_b_c_d가 있을 때보다 읽기수가 대폭 증가할 것이라고 예상이 된다. idx__a_b를 탄 후에 bookmark lookup 을 해서 c,d를 체크해야 할 테니. 하지만 이런 경우 SQL Server는 똑똑하게 동작한다. 옵티마이저는 bookmark lookup 의 비용이 과도하다고 판단하면 T1의 두개의 인덱스 idx__a_b와 idx__c_d를 동시에 Index Seek을 해서 join 을 해버린다. maxdop 가 높고 시스템 가용자원이 남아서 병렬 계획을 수립할 가능성이 높으면 더더욱 두개의 인덱스를 병렬로 seek하는 방향으로 실행계획이 유도된다. join 할 때는 각각의 인덱스 끝에 붙어 있는 클러스터드 인덱스 키를 이용하는 것 같다. a,b의 선택성이 좋아서 bookmark lookup 비용이 과도하지 않으면 저렇게 동작하지 않는 것 같다.

인덱스를 위와 같이 잡을 때의 이점은 명백하다. c,d 컬럼에 대해서 중복 인덱스를 잡을 필요가 없어진다. 그렇다고 해서 idx__a_b_c_d가 있을 때보다 읽기수가 엄청나게 증가하는 것은 아니다. 물론 늘어나긴 하지만 감당할만한 수준이다.


결론: 액세스가 빈번하지는 않으나 테이블 사이즈가 매우 커서 공간을 절약할 필요가 있는 경우 where조건을 구성하는 컬럼을 분해해서 각각의 index를 잡는 전략을 고려해볼 수 있다.

Posted by maceo

09 28, 2006 17:36 09 28, 2006 17:36
, ,
Response
No Trackback , a comment
RSS :
http://merritt.co.kr/tt/rss/response/73


블로그 이미지

가늘어도 긴놈이 장땡

- maceo

Archives

Authors

  1. maceo

Calendar

«   3 2010   »
  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      

Site Stats

Total hits:
170306
Today:
4
Yesterday:
46