SQL Q&A데이터베이스 크기, 미러링 및 표시된 트랜잭션 등

편집자: Nancy Michell

클러스터 이동

Q: Windows® 클러스터와 SQL Server™ 클러스터를 비롯한 실제 기본 서버의 새 IP 주소로 SQL Server 2000 클러스터를 이동해야 합니다. 전체 솔루션을 다시 빌드해야 합니까?

A: 아니요. SQL Server 설치 프로그램을 실행하여 IP 주소를 수정하기만 하면 됩니다. 자세한 내용은 기술 자료 문서를 참조하십시오.

데이터베이스 크기

Q: 10GB에 육박하는 업무에 중요한 데이터베이스, 단순 복구 모델, 9,850MB의 주 파일 및 88MB의 트랜잭션 로그 파일이 포함된 SQL Server 2000 SP4를 프로덕션 환경에서 사용하고 있습니다. 데이터베이스 백업 크기도 거의 10GB에 달합니다. 보다 나은 성능을 얻으려면 데이터베이스 크기를 줄여야 합니까? 크기를 줄여야 할 경우 DBCC SHRINKDATABASE 또는 DBCC SHRINKFILE을 사용해야 합니까? 아쉽게도 항상 사용량이 많아서 이러한 유지 보수 작업을 수행하기에 적합한 시간대가 없습니다.

A: DBCC SHRINKDATABASE 또는 DBCC SHRINKFILE은 데이터베이스에서 삭제와 업데이트가 여러 번 수행되어 데이터 볼륨이 줄어드는 경우에만 유용합니다. 그러나 이것은 큰 문제가 되지 않을 것 같습니다. 10GB의 디스크 공간은 오늘날 20달러 정도의 가치를 갖습니다. 100GB 정도의 디스크 공간을 추가하여 그대로 실행하는 것이 더 효율적이지 않을까요? 디스크 공간이 더 많은 조각으로 분할되면 성능이 저하되지만 별다른 유지 관리 작업을 수행할 수 없다면 선택의 폭은 넓지 않습니다. 이러한 경우 두 번째 데이터베이스 복사본을 사용하는 사용자들도 있습니다. 이러한 사용자들은 복제를 통해 백업 복사본을 최신 상태로 유지하고 백업 복사본을 유지 관리한 다음 응용 프로그램을 백업으로 전환합니다. 이렇게 하려면 약간의 코드 변경이 필요하고 단순 복구 모델을 FULL 또는 BULK_LOGGED로 변경해야 하지만 장기적으로는 보면 좋은 효과를 가져올 수 있습니다.

업그레이드 및 성능

Q: 두 개의 응용 프로그램을 SQL Server 2000에서 SQL Server 2005로 이동해야 합니다. 업그레이드 중 어떻게 하면 성능 저하 문제를 피할 수 있습니까?

A: 일반적으로 업그레이드 중에는 다음과 같은 상황으로 인해 성능 저하가 발생할 수 있으므로 이러한 상황이 발생하지 않도록 해야 합니다.

  1. SQL Server 2005로 업그레이드한 후 통계를 다시 작성하지 않은 경우.
  2. 서로 다른 두 가지 데이터 형식을 비교하는 JOINS 및 WHERE 절이 있는 경우 이로 인해 성능이 저하됩니다. 특히 SQL Server 2000 SP3 또는 이전 버전에서 실행했었던 경우에 더욱 그렇습니다(support.microsoft.com/kb/271566/ 참조).
  3. SQL Server 2005 인스턴스가 올바르게 구성되어 있지 않으며, 메모리, AWE(Address Windowing Extension), 드라이버 등이 잘못 구성되어 있는 경우. SQL Server 2000을 실행하는 시스템의 설정이 수정되었는데 이를 수행한 사용자가 문서화하지 않고 퇴사하여 SQL Server 2005 인스턴스에 대해서는 적용되지 않았습니다.
  4. 하드웨어에 문제가 있는 경우. 새 하드웨어가 사양 면에서는 좋아 보여서 구입하지만 실제 성능 면에서는 그렇지 못한 경우가 종종 있습니다.

SQL Server 인스턴스를 프로덕션 환경에 적용하기 전에 기준선을 설정하여 성능이 예상대로 구현되는지 확인해야 합니다. 이 경우 인프라는 발생 가능한 문제에서 제외할 수 있습니다. 디스크, I/O, 메모리와 같은 Perfmon 카운터를 확인하고 인스턴스 간에 이 카운터를 비교해야 합니다.

데이터베이스 미러링

Q: 데이터베이스 미러링을 사용하고 있는데 READ_COMMITTED_SNAPSHOT 데이터베이스 옵션을 설정하고 싶습니다. 그런데 미러링을 설정한 후 이 데이터베이스 옵션을 설정하려고 하면 DB가 미러링 세션에 있어서 명령을 실행할 수 없다는 예외 메시지가 표시됩니다.

A: READ_COMMITTED_SNAPSHOT 옵션을 설정하고 적용하려면 데이터베이스를 다시 시작해야 하기 때문에 이와 같은 문제가 발생합니다. 따라서 미러링 세션을 중단하고 옵션을 설정한 다음 데이터베이스를 다시 시작해야 합니다. 이러한 단계를 수행한 후에야 미러링을 다시 설정할 수 있습니다. 미러 데이터베이스는 세션이 설정된 후 옵션을 선택하고 장애 조치가 발생할 경우 선택한 옵션을 사용합니다.

Q: 비동기 미러링을 설정하려고 하는데 1418 오류가 표시됩니다. Netstat –ano를 실행하면 SQL Server가 모든 서버에서 올바른 포트를 수신하고 있다는 메시지가 표시됩니다. 그런데 미러링을 시작하려고 하면 오류가 표시됩니다. 왜 그런 것인지요?

A: 방화벽이 통신을 차단하는 것이 원인일 수 있습니다. 이 문제는 비교적 자주 발생하는 문제이므로 확인해 봐야 합니다. 자세한 내용은 데이터베이스 미러링 설정 문제 해결MSSQLSERVER_1418(영문) 백서를 참조하십시오.

이 문제는 비동기 미러링에 국한된 문제가 아닙니다. 실제로, 동기 미러링에서도 발생할 수 있습니다.

표시되는 오류 메시지("서버 네트워크 주소 "%.*ls"에 연결할 수 없거나 주소가 없습니다. 네트워크 주소 이름 및 로컬과 원격 끝점이 작동 중인지 확인하십시오.")는 올바른 것입니다. 이 오류의 원인은 대개 원격 파트너가 없기 때문이 아니라 단순히 원격 파트너에 연결할 수 없기 때문입니다.

이 문제는 원격 파트너가 다운되거나 포트를 수신하지 않거나 끝점이 다운된 경우(파트너가 동일한 암호화 메커니즘을 협상할 수 없거나 기타 다른 인증 문제가 있는 경우 나타날 수 있음)에 발생할 수 있습니다. 또한 명령을 보낸 파트너 쪽의 방화벽에서 파트너를 차단하는 경우도 문제의 원인이 될 수 있습니다.

흔히 간과될 수 있는 몇 가지 다른 문제로는 데이터 원본 이름(DSN) 및 이름 확인 문제가 있습니다. 이 문제의 경우 일반적으로 정규화된 도메인 이름을 사용하는 것이 좋습니다. 따라서 방화벽에서 문제가 자주 발생할 경우 원인은 여러 가지일 수 있다는 점을 유념하십시오.

Q: SQL Server 2005 미러링을 사용하려고 합니다. 여러 응용 프로그램을 동일한 SQL Server 인스턴스의 여러 데이터베이스에 연결할 때는 미러링을 사용하지 않는 것이 좋다고 들었습니다. 맞습니까?

A: 응용 프로그램마다 자체 데이터베이스를 가지고 있는지 또는 응용 프로그램에서 데이터베이스 간 트랜잭션 또는 DTC(Distributed Transaction Coordinator) 트랜잭션을 사용하는지 여부에 따라 답은 달라집니다. 데이터베이스 간 트랜잭션을 사용할 경우 미러링으로 인해 논리적 불일치가 발생하여 트랜잭션이 예상대로 커밋되지 않을 수 있습니다. 이 경우 발생할 수 있는 문제에 대한 자세한 내용은 여기(영문)를 참조하십시오.

여러 응용 프로그램에서 여러 개의 데이터베이스를 사용하지만 각 응용 프로그램이 자체 데이터베이스를 가지고 있는 경우에는 미러링으로 인해 이러한 문제가 발생하지는 않습니다.

표시된 트랜잭션

Q: 표시된 트랜잭션이란 정확히 무엇이며, 한 데이터베이스는 SQL Server이고 다른 한 데이터베이스는 Oracle일 경우 이것을 어떻게 사용할 수 있습니까?

A: 트랜잭션을 표시한다는 것은 DBA가 정기적으로 모든 로그의 동일한 위치에 표시를 하는 작업을 말합니다. 테이블을 트랜잭션 표시까지 복원하는 기능과 병행하여 이 작업을 수행하면 모든 데이터베이스를 동일한 지점까지 복원할 수 있습니다. 그러나 이렇게 하면 관련된 모든 데이터베이스를 복원해야 하고 모든 데이터베이스의 데이터가 손실되기 때문에 매우 위험할 수 있으므로 로그 파일이 손실되지 않도록 하여 이러한 상황을 피해야 합니다. 표시된 트랜잭션은 SQL Server에만 해당하는 사항이므로 분산 트랜잭션에 SQL Server가 아닌 다른 데이터베이스가 포함되어 있을 경우에는 트랜잭션 표시를 수행할 수 없습니다. 일반적으로 트랜잭션 표시를 사용하는 분산 데이터베이스 시스템은 극소수입니다. 이러한 시스템에서는 트랜잭션 로그가 하나라도 손실되는 것을 치명적인 이벤트로 간주하므로 이를 복구하는 데는 엄청난 수작업이 수반됩니다.

Access에서 T-SQL로의 변환 도구

Q: 저장 프로시저에 사용할 수 있는 자동화된 Access™ SQL 대 T-SQL 변환 도구가 있습니까?

A: 여기(영문)에서 다운로드할 수 있는 SQL Server Migration Assistant(SSMA) for Access를 사용해 보십시오. 이 사이트에서는 SQL Server Migration Assistant for Oracle, SQL Server Migration Assistant for Sybase 및 Informix 데이터베이스를 Microsoft® SQL Server 2000으로 마이그레이션하는 방법도 확인할 수 있습니다.

Access에서 SQL Server로 업사이징하는 경우 Office 업사이징 마법사를 사용할 수도 있지만 그림 1에 표시된 것처럼 SSMA for Access를 사용하면 변환 평가 보고서 및 네트워크 검색 등의 더 많은 기능을 사용할 수 있습니다. 또한 SSMA for Access를 사용하면 Office 업사이징 마법사에서는 제대로 처리할 수 없는 여러 가지 문제도 해결할 수 있습니다.

그림 1 SQL Server Migration Assistant for Access

그림 1** SQL Server Migration Assistant for Access **(더 크게 보려면 이미지를 클릭하십시오.)

비클러스터형 인덱스

Q: 두 개의 GUID(GUID1 및 GUID2)로 기본 키를 만든 테이블이 있으며 GUID1과 GUID2에는 이미 고유 클러스터형 인덱스가 있습니다. 성능 향상을 위해 GUID1과 GUID2에 또 다른 비클러스터형 인덱스를 만들려고 합니다. 이 인덱스를 고유 인덱스로 선언할 경우 성능 오버헤드가 발생할까요?

A: 비클러스터형 인덱스를 고유 인덱스로 선언할 경우 성능 저하가 발생하지는 않지만 실제로 인덱스 트리의 수준 수가 줄어들 수 있습니다.

비클러스터형 인덱스를 고유하지 않은 인덱스로 선언할 경우 루트 및 비-리프 페이지에서 인덱스 항목의 키 부분에 행 로케이터가 추가됩니다. 이는 중복된 키가 있을 경우 동의어 체인을 검색하지 않도록 하여 인덱스 항목을 쉽게 삭제하고 업데이트하기 위한 것으로, 로케이터가 추가된 해당 키의 시스템 검색(Seek) 작업을 통해 변경할 특정 항목의 위치를 찾을 수 있습니다. 그 결과로 해당 항목이 더 길어집니다. 선택한 클러스터 키를 사용할 경우에는 더욱 길어집니다. 따라서 루트 및 비-리프 페이지가 보다 빠르게 채워집니다. 인덱스가 고유한 경우에는 이와 같이 선언해야 합니다.

요약하자면, 테이블에 클러스터형 인덱스가 있는지 여부와 관계없이 테이블에 있는 비클러스터형 인덱스를 고유하지 않은 인덱스로 선언할 경우 루트 및 다른 비-리프 페이지의 인덱스 항목에 로케이터가 추가됩니다.

또한 int 식별자 열을 서로게이트 키로 사용한 다음 두 개의 고유 인덱스인 (GUID1, GUID2) 및 (GUID2, GUID1)을 추가할 경우 인덱스에 32바이트 클러스터링 키 대신 4바이트 클러스터링 키가 생기므로 성능이 향상됩니다.

업데이트 잠금

Q: 다음과 같은 구조의 저장 프로시저가 있습니다.

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION

-- Get The lock if available
UPDATE    ProcessingInstances 
SET       LockHolder = @MessageId
WHERE     ( InstanceId = @InstanceId ) 
AND       ( LockHolder IS NULL )

COMMIT TRANSACTION

이 저장 프로시저는 잠금을 수행하는 데 하나의 호출자만 허용하므로 다른 호출자는 기다려야 합니다. 격리 수준을 줄여서 동일한 결과를 얻을 수 있을까요?

이 트랜잭션에는 쿼리가 한 개뿐이므로 READ COMMITTED는 올바른 격리 수준으로 보입니다. 또한 다른 트랜잭션에서 동일한 레코드를 업데이트하고 있을 경우 이 트랜잭션은 다른 트랜잭션을 기다려야 합니다. 맞습니까?

A: 이 경우 다른 호출자를 기다리게 하는 것은 직렬화 가능 설정이 아니라 업데이트 자체입니다. 격리 수준을 READ COMMITTED로 설정할 수 있으며 업데이트 시 사용되는 인덱스에 대해서는 기본적으로 업데이트 잠금이 설정됩니다. 이로 인해 업데이트 중 동일한 명령문을 실행하는 다른 프로세스에서는 문제가 발생하므로 업데이트가 완료될 때까지 다른 프로세스는 차단됩니다. UPDATE가 유일한 문일 경우 여기에 명시적 트랜잭션은 필요하지 않으며 문이 명시적 트랜잭션에 없을 경우 각 문은 암시적으로 자체 트랜잭션에 존재합니다.

그러나 UPDATE 문의 WHERE 절과 일치하는 행이 없을 경우 직렬화 가능 격리 수준을 사용하면 이러한 행이 다른 트랜잭션에서 삽입되거나 수정되는 것을 방지할 수 있습니다. READ COMMITTED 격리에서 UPDATE를 실행할 경우에는 이러한 문제가 발생하지 않으며 다른 트랜잭션에서는 업데이트를 충족하는 행을 사용할 수 있습니다. 저장 프로시저 코드가 여기에 표시된 코드와 유사할 경우 이러한 방법(직렬화 가능 또는 트랜잭션)을 사용하는 것이 적절하지 않을 수 있으므로 그냥 업데이트를 수행하십시오.

기술적 자문을 주신 Microsoft IT 전문가: Gaurav Aggarwal, Anthony Bloesch, Todd Briley, Shaun Cox, Roberto Di Pietro, Michael Epprecht, Kevin Farlee, Umachandar Jayachandran, Chuck Ladd, Kaloian Manassiev, Luciano Moreira, Ward Pond, Mark Prazak, Arunachalam Thirupathi, Roger Wolter, Clement Yip 및 Frankie Yuen

© 2008 Microsoft Corporation 및 CMP Media, LLC. All rights reserved. 이 문서의 전부 또는 일부를 무단으로 복제하는 행위는 금지됩니다..