'즐거운자료' 카테고리의 다른 글
롯데이라 산리오 인형세트 헬로키티 구매 (0) | 2018.10.20 |
---|---|
개발자로 살아남기 (0) | 2011.01.07 |
롯데이라 산리오 인형세트 헬로키티 구매 (0) | 2018.10.20 |
---|---|
개발자로 살아남기 (0) | 2011.01.07 |
롯데이라 산리오 인형세트 헬로키티 구매 (0) | 2018.10.20 |
---|---|
SI에 대한 통찰 (0) | 2011.01.07 |
만약 $path/libzzz.a 라는 파일로 존재한다면,
컴파일 시에
gcc main.c -L $path -l zzz
라고 하면 그 내용을 사용할 수 있습니다.
물론 소스 파일에서는 저 라이브러리에 있는 헤더파일이 포함되어야 하구요.
좀더 이해하기 쉬우라고 써봤습니다만 --;
-----------------------------------------------------------------------------------------------------------------제가 무지하게 초보인디...어제..제가 공부한게 있길래..한번씁니다..ㅡㅡV
/usr/lib 에 보면 라이브러리들이 무지하게 많지요
정적라이브러리 .a 와 동적라이브러리 .so 가 있습니다.
이들은 ar 명령어로 내용을 확인할수 있는데..
우선 습관적으로 man ar 을 쳐보십시요..^^*
거기에 ar(archive) 은 묶음파일을 만들고 조작하고 추출한다라고
써있습니다.
음...우선 구경하나 하면..
$> ar t libc.a | less
이걸로 해당 .o 파일들이 묶어져있음을 알수있습니다.
라이브러리를 만들려면 우선 오브젝트파일이 필요함을 알수있지요
$> gcc -c test_lib.c
이렇게 하면 test_lib.o 파일이 만들어 집니다.
ar 의 r 옵션은 오브젝트를 추가하는거구여 s 옵션은 인덱스를 만든답니다.
$> ar rs libc.a test_lib.o
이렇게 하면 C 표준 라이브러리파일에 집어넣어주는게 됩니다.
오브젝트 파일을 한꺼번에 쭈~욱 쓰셔서 집어넣으셔두 됩니다.
아 ~ 물론 r 옵션으로 libc.a 말구 새로운걸 만드셔두 됩니다.
$> ar rs libhuk.a test_lib.o
이정도로 하죠
그러면 libhuk.a 가 생깁니다.
gcc -o huk_test_lib huk_test.c -lhuk -L.
이정도로 하시면 됩니다.
-lhuk 은 libhuk.a 를 사용하겠다는 의미이고
-L. 은 현재디렉에서 찼겠다는 겁니다. (이거 안해주면 /usr/lib 에서 libhuk.a 를 찾습니다.)
다시 라이브러리를 고치시구 싶으시면 새로 컴파일 하시구
ar rs 로 라이브러리를 갱신 시키시면 됩니다.
대충 이정도 입니다.
공부를 제대로 했나 모르겟군요...ㅡ.ㅡ;;
(나이먹구 책보구 독학하려니 힘들군요...아~ 전 생업은 있고 프밍을 취미인지라..)
나머지 부분은 man 페이지를 한번 보시는게...^^*
리눅스) umount : device is busy (0) | 2012.02.07 |
---|---|
리눅스) 읽기전용 파일 시스템 (0) | 2012.02.07 |
출처 : http://www.linxus.co.kr/post/43376
exec sp_lock
잠금 관련 정보를 보고합니다.
열 이름 | 데이터 형식 | 설명 |
---|---|---|
spid | smallint | SQL Server 프로세스 ID 번호입니다. |
dbid | smallint | 잠금을 요청하는 데이터베이스 ID 번호입니다. |
ObjId | int | 잠금을 요청하는 개체의 개체 ID 번호입니다. |
IndId | smallint | 인덱스 ID번호입니다. |
Type | nchar(4) | 잠금 유형입니다.
DB = 데이터베이스 |
Resource | nchar(16) | syslockinfo.restext의 값에 해당되는 잠금 리소스입니다. |
Mode | nvarchar(8) | 잠금 요청자의 잠금 모드입니다. 이 잠금 모드는 허가된 모드, 변환 모드 또는 대기 모드를 표시합니다. |
Status | int | 잠금 요청 상태입니다.
허가 |
exec sp_who {sp_id}
현재 Microsoft? SQL Server™ 사용자 및 프로세스에 관한 정보를 제공합니다. 유휴 상태가 아닌 프로세스만 반환하려면 반환되는 정보를 필터링하면 됩니다.
열 | 데이터 형식 | 설명 |
---|---|---|
spid | smallint | 시스템 프로세스 ID입니다. |
ecid | smallint | 특정 SPID와 관련된 주어진 스레드의 실행 컨텍스트 ID입니다.
ECID = {0, 1, 2, 3, ...n}이며, 0은 항상 주 또는 부모 스레드를 의미하며 {1, 2, 3, ...n}는 하위 스레드를 의미합니다. |
status | nchar(30) | 프로세스 상태입니다. |
loginame | nchar(128) | 특정 프로세스와 관련된 로그인 이름입니다. |
hostname | nchar(128) | 각 프로세스의 호스트 또는 컴퓨터 이름입니다. |
blk | char(5) | 프로세스를 차단하는 데 필요한 시스템 프로세스 ID입니다. 단, 존재하는 경우에 한합니다. 없는 경우, 이 열은 0이 됩니다.
고아 분산 트랜잭션이 주어진 spid 와 관련된 트랜잭션을 차단하면 이 열은 고아 트랜잭션을 차단하기 위해 '-2'를 반환합니다. |
dbname | nchar(128) | 프로세스가 사용하는 데이터베이스입니다. |
cmd | nchar(16) | Transact-SQL 문, SQL Server 내부 엔진 프로세스 등, 프로세스 실행에 필요한 SQL Server 명령입니다. |
DBCC INPUTBUFFER( sp_id )
클라이언트에서 Microsoft? SQL Server™에 최종적으로 보낸 명령문을 표시합니다.
DBCC INPUTBUFFER는 다음과 같은 열이 있는 행 집합을 반환합니다.
열 이름 | 데이터 형식 | 설명 |
---|---|---|
EventType | nvarchar(30) | 이벤트 유형(예: RPC, Language, NO Event) |
Parameters | Int | 0 = 텍스트 1- n = 매개 변수 |
EventInfo | nvarchar(255) | RPC EventType의 경우, EventInfo에 프로시저 이름만 포함됩니다. Language 또는 No Event EventType의 경우, 이벤트의 첫 255자만 표시됩니다. |
• | "Understanding Locking in SQL Server" |
• | "Locking Architecture" |
• | "Lock Compatibility" |
• | "Locking Hints" |
• | "Changing Default Locking Behavior in Oracle and SQL Server" |
• | SPID는 잠금(Lock)을 풀기 전에 확장된 시간 동안 리소스 집합에 대해 잠금(Lock)을 겁니다. 이러한 블로킹 유형은 시간이 지나면서 스스로 해결될 수 있지만 성능이 저하될 수 있습니다. |
• | SPID는 리소스 집합에 대해 잠금(Lock)을 걸고 이를 절대로 풀지 않습니다. 이러한 블로킹 유형은 자체적으로 해결되지 않으며 영향을 받은 리소스에 무한정으로 액세스하지 못하게 합니다. |
1. | 블로킹 체인 헤드에서 SPID를 식별합니다. 위의 문서에 나온 스크립트를 사용하는 것 외에 다음과 같이 SQL Enterprise Manager(엔터프라이즈 관리자)를 사용하여 블로킹 체인의 헤드를 식별할 수도 있습니다.
| ||||||||
2. | 블로킹 SPID가 실행 중인 쿼리를 찾습니다. 스크립트 메서드는 다음 쿼리를 사용하여 특정 SPID에서 실행된 명령을 결정합니다. 또는 다음과 같이 SQL Enterprise Manager(엔터프라이즈 관리자)를 사용할 수 있습니다.
| ||||||||
3. | 블로킹 SPID가 걸고 있는 중인 블로킹 유형을 찾습니다. sp_loc 시스템 저장 프로시저(Stored Procedure)를 실행하여 이 정보를 결정할 수 있습니다. 또는 다음과 같이 Enterprise Manager(엔터프라이즈 관리자)를 사용할 수 있습니다.
| ||||||||
4. | 블로킹 SPID의 트랜잭션 중첩 수준(Nesting Level) 및 프로세스 상태를 찾습니다. SPID의 트랜잭션 중첩 수준(Nesting Level)은 @@TRANCOUNT 전역 변수에서 사용할 수 있습니다. 그러나 다음과 같이 sysprocesses 테이블을 쿼리하여 SPID 외부에서 결정될 수 있습니다. 반환된 값은 SPID의 @@TRANCOUNT 값입니다. 이는 블로킹 SPID의 트랜잭션 중첩 수준(Nesting Level)을 보여 주는데, 이는 잠금(Lock)을 건 이유를 설명할 수 있습니다. 예를 들어, 값이 0보다 크면 SPID는 트랜잭션 중간에 있습니다(트랜잭션 격리 수준에 따라 확보한 특정 잠금(Lock)을 걸 것으로 기대하는 경우). DBCC OPENTRAN 데이터베이스_이름을 사용하여 데이터베이스에 장기 개방 트랜잭션이 있는지 확인할 수도 있습니다. |
1. | SQL Server Profiler(프로필러)를 엽니다. | ||||||||||||||||||||||||||||||||||||||||||
2. | Tools 메뉴에서 Options를 누릅니다. | ||||||||||||||||||||||||||||||||||||||||||
3. | All Event Classes 및 All Data Columns 옵션을 선택해야 합니다. | ||||||||||||||||||||||||||||||||||||||||||
4. | OK를 누릅니다. | ||||||||||||||||||||||||||||||||||||||||||
5. | File 메뉴에서 New를 가리키고 Trace를 누릅니다. | ||||||||||||||||||||||||||||||||||||||||||
6. | General 탭에서 데이터를 캡처할 추적(Trace) 이름과 파일을 지정합니다. | ||||||||||||||||||||||||||||||||||||||||||
7. | Events 탭에서 다음과 같은 이벤트 유형을 추적(Trace)에 추가합니다.
이 외에도, 자세한 정보를 위해 다음 이벤트를 포함시킬 수 있습니다. 대량 생산 환경에서 실행하는 경우 위의 이벤트는 블로킹 문제를 해결하기에 충분하므로 이러한 이벤트 중 하나만 사용할 수 있습니다. 아래의 추가 이벤트를 포함하면 문제의 근원을 좀더 쉽게 빨리 결정할 수 있지만 시스템의 로드가 추가되고 추적 출력(Trace Output) 크기가 늘어납니다.
| ||||||||||||||||||||||||||||||||||||||||||
8. | Data Columns 탭에 다음 열(Column)이 있는지 확인하십시오. Start Time, End Time, Connection ID, SPID, Event Class, Text, Integer Data, Binary Data, Application Name, NT User Name 및 SQL User Name. 위의 두번째 테이블에서 추가 이벤트를 포함하면 Duration, CPU, Reads 및 Writes 데이터 열(Column) 또한 포함시키십시오. | ||||||||||||||||||||||||||||||||||||||||||
9. | Filters 탭에서 SQL Server 내부 예외를 제외합니다. Trace Event Criteria 상자에서 Severity를 선택하고 Maximum 상자에 24를 입력합니다. 그런 다음 OK를 누릅니다. SQL Server에서 클라이언트로 보내진 오류를 모니터하는데 대한 자세한 내용은 Microsoft 기술 자료에 있는 다음 문서를 참조하십시오. 199037 INF: Trapping Error Messages Sent to Clients from a SQL Server |
• | sysprocesses 출력을 확인하여 블로킹 체인의 헤드를 파악합니다. 블로킹 스크립트에 대해 고속 모드(Fast Mode)를 지정하지 않은 경우에는 스크립트 출력에는 다른 것을 블로킹하는 SPID를 나열하는 제목이 "SPIDs at head of blocking chains"인 부분이 있습니다. SPIDs at the head of blocking chains spid ------ 9 10고속 옵션(Fast Option)을 지정하면 계속 sysprocesses 출력을 보고 블로킹 헤드를 파악할 수 있습니다. 다음은 간결한 sysprocesses 출력입니다. spid status blocked 9 sleeping 0 10 sleeping 0 11 sleeping 13 12 sleeping 10 13 sleeping 9 14 sleeping 12이러한 경우 SPID 9와 10의 blocked 열(Column)에 0이 있음을 볼 수 있습니다. 이는 둘 다 블로킹되지 않았음을 의미하지만 기타 SPID에 대해 blocked 열(Column)에 나타납니다. 이는 SPID 9와 10이 별도의 블로킹 체인의 헤드에 있음을 나타냅니다. | |||||||||||||||||||||||||||||||||||||||
• | 블로킹 체인 헤드에 있는 SPID에 대한 정보에 대해 sysprocesses 출력을 확인합니다. 다음 sysprocesses 필드를 평가하는 것은 중요합니다.
| |||||||||||||||||||||||||||||||||||||||
• | DBCC INPUTBUFFER 출력을 확인합니다. 블로킹 체인의 헤드에 있는 SPID에 대해 또는 0이 아닌 waittype을 가지고 블로킹 스크립트는 DBCC INPUTBUFFER를 실행하여 그 SPID에 대한 현재 쿼리를 결정합니다. DBCC INPUTBUFFER FOR SPID 9 EventType Parameters EventInfo -------------- ---------- -------------------------------------------- Language Event 0 update titles set title = title대부분의 경우 이 쿼리는 다른 사용자를 블로킹하는 잠금(Lock)을 걸 수 있습니다 . 그러나 트랜잭션에 SPID가 있으면 잠금(Lock)은 현재 쿼리가 아닌 이전에 실행된 쿼리에서 얻을 수 있습니다. 그러므로 inputbuffer만 아니라 SPID에 대해 Profiler(프로필러) 출력도 봐야 합니다. 참고: 블로킹 스크립트는 여러 단계로 구성되므로 SPID는 블로킹 체인의 헤드에 첫 섹션으로 나타날 수 있지만 DBCC INPUTBUFFER 쿼리가 실행될 때 이는 더 이상 블로킹되지 않고 INPUTBUFFER는 캡처되지 않습니다. 이는 그 SPID에 대해 블로킹이 스스로를 해결하고 있음을 나타내는데, 이는 문제가 될 수도 있고 그렇지 않을 수도 있습니다. 이 때 블로킹 스크립트의 고속(Fast) 버전을 사용하여 inputbuffer가 지워지기 전에 이를 캡처하거나(비록 보장할 수는 없어도) 그 시간 프레임에서 Profiler(프로필러) 데이터를 보고 SPID가 실행하는 쿼리를 결정할 수 있습니다. | |||||||||||||||||||||||||||||||||||||||
• | DBCC PSS 출력을 확인합니다. 블로킹 체인의 헤드에 있는 모든 SPID에 대해 DBCC PSS 명령을 실행합니다. PSS는 프로세스 상태 구조로 특정 SPID의 상태에 대한 정보가 들어 있습니다. 블로킹 시나리오의 가장 큰 관심 필드는 ec_stat 필드입니다. 다음은 ec_stat 필드의 일반 값입니다.
참고: 고속 모드(Fast Mode)에서 블로킹 스크립트는 DBCC PSS 명령을 실행하지 않습니다. 이 정보의 대부분은 Profiler(프로필러) 추적(Trace) 데이터를 보고 결정될 수 있습니다. 추적(Trace) 파일에서 ATTENTION 신호와 예외를 볼 수 있습니다. 예를 들어, 프로세스가 교착 상태에 있으면 교착 상태가 발생할 때 클라이언트에 반환되는 오류인 정수 데이터 열(Column) 값이 1205인 예외 이벤트를 볼 수 있습니다. ec_stat 값은 0이 아닐 때 좀더 자세히 살펴 보기 위한 신호로 유용하게 사용됩니다. SPID가 "정상" 상태에 있지 않으면 경고합니다. 위의 표와 Profiler(프로필러) 추적(Trace) 정보에서 이에 대한 원인과 그 진행 방법을 파악할 수 있습니다. |
• | 현재 트랜잭션에서 블로킹 체인의 헤드에 있는 SPID에서 어떤 명령을 실행했습니까? 블로킹 체인의 헤드에 있는 특정 SPID의 추적(Trace) 데이터를 필터합니다(File 메뉴에서 Properties를 누른 다음 Filters 탭에서 SPID 값을 지정함). 그러면 다른 SPID를 블로킹하기 전에 실행한 명령을 확인할 수 있습니다. 트랜잭션 이벤트를 포함하면 트랜잭션이 언제 시작되었는지를 쉽게 식별할 수 있습니다. 그렇지 않으면 Text 열에서 BEGIN, SAVE, COMMIT 또는 ROLLBACK TRANSACTION 작업을 검색할 수 있습니다. sysprocesses 테이블에서 open_tran 값을 사용하여 모든 트랜잭션 이벤트를 잡아야 합니다. 실행된 명령과 트랜잭션 컨텍스트를 알면 SPID에서 잠금(Lock)을 걸고 있는 이유를 파악할 수 있습니다. 이벤트와 데이터 열(Column)을 제거할 수 있다는 것을 유의하십시오. 시작 및 완료 이벤트를 둘 다 보는 대신 하나를 선택하십시오. 블로킹 SPID가 저장 프로시저(Stored Procedure)가 아니면 SP:Starting 또는 SP:Completed 이벤트를 제거합니다. SQLBatch 및 RPC 이벤트는 프로시저 호출을 보여 줍니다. SP 이벤트의 세부 사항 수준을 봐야 하는 경우에만 이를 보십시오. |
• | 블로킹 체인의 헤드에 있는 SPID의 쿼리 기간은 어느 정도입니까? 위의 완료된 이벤트를 포함시킬 경우 Duration 열은 쿼리 실행 시간을 보여 줍니다. 이를 사용하면 블로킹을 일으키는 장기간 실행되는 쿼리를 식별할 수 있습니다. 쿼리의 수행 속도가 느린 이유를 파악하려면 CPU, Read 및 Writes 열(Column)뿐만 아니라 Execution Plan 이벤트도 보십시오. |
1 | 0이 아님 | >= 0 | runnable | 예, 쿼리가 완료할 때입니다. | Physical_IO, CPU 및/또는 Memusage 열(Column)은 시간이 지나면서 증가합니다. 쿼리의 기간은 완료될 때 높아집니다. |
2 | 0x0000 | >0 | sleeping | 아니오, 그러나 SPID는 중단됩니다. | 이 SPID에 대해 Profiler(프로필러) 추적(Trace)에서 주의 신호를 볼 수 있는데 이는 쿼리 시간 제한 또는 취소가 발생하였음을 나타냅니다. |
3 | 0x0000 | >= 0 | runnable | 아니오. 클라이언트가 모든 행을 반입하거나 연결을 닫을 때까지 해결되지 않습니다. SPID는 중단될 수 있습니다. 그러나 중단하는데 30초 정도 걸립니다. | open_tran = 0이고 SPID가 트랜잭션 격리 수준(Isolation Level)이 기본(READ COMMITTED)인 동안 잠금(Lock)을 걸고 있는데, 이것이 그 원인일 가능성이 있습니다. |
4 | 다양화 | >= 0 | runnable | 아니오. 클라이언트가 쿼리를 취소하거나 연결을 닫을 때까지 해결되지 않습니다. SPID는 중단될 수 있습니다. 그러나 중단하는데 30초 정도 걸립니다. | 블로킹 체인의 헤드에 있는 SPID의 sysprocesses의 hostname 열(Column)은 블로킹 중인 SPID 중 하나와 같습니다. |
5 | 0x0000 | >0 | rollback | 예. | 이 SPID의 Profiler(프로필러) 추적(Trace)에서 주의 신호를 볼 수 있는데, 이는 쿼리 시간 제한 또는 취소가 일어났거나 단순히 롤백 문이 실행되었음을 나타냅니다. |
6 | 0x0000 | >0 | sleeping | 결국, Windows NT가 세션이 더 이상 활성화되어 있지 않다고 확인하면 SQL Server 연결은 끊어집니다. | sysprocesses의 last_batch 값은 현재 시간보다 훨씬 앞섰습니다. |
1. | 실행 시간이 긴 일반 실행 쿼리에 의한 블로킹 해결책: 이러한 유형의 블로킹 문제에 대한 해결책은 쿼리를 최저화하는 방법을 찾는 것입니다. 사실 이러한 유형의 블로킹 문제는 성능 문제일 수 있으므로 성능 문제의 관점에서 해결해야 합니다. 쿼리의 실행 시간이 오래 걸리는 문제를 해결하는 방법은 Microsoft 기술 자료에 있는 다음 문서를 참조하십시오. 243589 INF: Troubleshooting Slow-Running Queries on SQL Server 7.0 전반적인 응용 프로그램 성능 문제 해결에 대한 내용은 Microsoft 기술 자료에 있는 다음 문서를 참조하십시오.
224587 INF: Troubleshooting Application Performance with SQL Server 다른 사용자를 블로킹하는 실행 시간이 긴 쿼리가 있는데 이를 최적화할 수 없으면 이를 OLTP 환경에서 의사 결정 지원 시스템으로 이동하십시오. | ||||||||
2. | 트랜잭션 중첩 수준(Nesting Level)의 추적(Trace)을 놓친 Sleeping 상태의 SPID에 의한 블로킹 이러한 블로킹 유형은 일시 정지(Sleeping)되었거나 명령을 기다리는(Waiting) SPID에서 식별될 수 있으나 트랜잭션 중첩 수준(Nesting Level)(@@TRANCOUNT, sysprocesses에서 open_tran)은 0보다 큽니다. 이는 응용 프로그램에서 쿼리 시간 제한을 겪거나 필요한 수만큼의 ROLLBACK 및/또는 COMMIT 문을 실행하지 않고 취소를 실행할 경우에도 발생합니다. SPID가 쿼리 시간을 제한하거나 취소를 받으면 이는 현재 쿼리 및 일괄 처리를 종료하지만 트랜잭션을 자동으로 롤백하거나 커밋하지 않습니다. SQL Server는 취소 중인 단일 쿼리로 인해 전체 트랜잭션을 단순히 롤백해야 한다고 간주할 수 없으므로 응용 프로그램은 이에 대한 책임이 있습니다. 쿼리 시간을 제한하거나 취소하는 것은 Profiler(프로필러) 추적(Trace)에서 SPID에 대해 ATTENTION 신호 이벤트로 나타납니다. 이를 표시하려면 Query Analyzer(쿼리 분석기)에서 다음과 같은 간단한 쿼리를 실행하십시오. 쿼리가 실행 중인 동안 빨간색의 Cancel 단추를 누릅니다. 쿼리가 취소된 다음 SELECT @@TRANSCOUNT는 트랜잭션 중첩 수준(Nesting Level)이 하나임을 나타냅니다. 이것이 DELETE 또는 UPDATE 쿼리이거나 HOLDLOCK가 SELECT에 사용된 경우에는 얻은 잠금(Lock)이 계속 유지됩니다. 위의 쿼리에서조차 다른 쿼리를 얻고 트랜잭션 초기 잠금(Lock)을 건 경우에 위의 SELECT가 취소되어도 계속 유지됩니다. 해결책:
| ||||||||
3. | 모든 결과 행을 완료로 반입하지 못한 해당 클라이언트 응용 프로그램의 SPID에 의한 블로킹 이 문제는 응용 프로그램을 제대로 설계하지 못해 일어납니다. 쿼리를 서버에 보낸 다음 모든 응용 프로그램은 모든 결과 행을 즉시 완료로 반입해야 합니다. 응용 프로그램에서 모든 결과 행을 반입하지 않으면 잠금(Lock)은 다른 사용자를 블로킹하면서 테이블에 남습니다. 투명하게 SQL 문을 서버에 제출하는 응용 프로그램을 사용하는 경우 응용 프로그램은 모든 결과 행을 반입해야 합니다. 그렇게 하지 않으면(그리고 이렇게 하도록 구성되어 있지 않으면) 블로킹 문제를 해결할 수 없습니다. 이러한 문제를 피하려면 제대로 작동하지 않는 응용 프로그램을 보고 또는 의사 결정 지원 데이터베이스로 제한할 수 있습니다. 해결책: 결과의 모든 행을 완료로 반입할 수 있도록 응용 프로그램을 다시 작성해야 합니다. | ||||||||
4. | 분산 클라이언트/서버 교착 상태에 의한 블로킹 전형적인 교착 상태와는 달리 분산 교착 상태는 RDBMS 잠금(Lock) 관리자로 감지할 수 없습니다. 이는 교착 상태에 관련된 유일한 리소스는 SQL Server 잠금(Lock)이라는 사실 때문에 일어납니다. 교착 상태의 다른 측면은 클라이언트 응용 프로그램 수준에서 일어나는데, SQL Server는 이에 대해 제어할 수 없습니다. 다음은 이러한 문제가 발생할 수 있는 두 가지 예제 및 응용 프로그램에서 이를 피할 수 있는 방법입니다.
해결책: 두 가지 확실한 해결책은 쿼리 시간 제한을 사용하거나 바운드 연결을 사용하는 것입니다.
| ||||||||
5. | "골든" 또는 롤백 상태에 있는 SPID에 의한 블로킹 중단되었거나 사용자 정의 트랜잭션 외부에서 취소된 데이터 수정 쿼리는 롤백됩니다. 이는 또한 클라이언트 컴퓨터가 다시 시작되고 해당 네트워크 세션 연결이 끊어지질 때 그 부작용으로서 발생합니다. 마찬가지로 교착 상태의 대상으로 선택된 쿼리는 롤백됩니다. 데이터 수정 쿼리는 종종 변경 사항이 초기에 적용되었을 때보다 더 빠르게 롤백될 수 없습니다. 예를 들어, DELETE, INSERT 또는 UPDATE 문이 몇 시간 동안 실행 중이었으면 롤백하는데 최소한 한 시간은 걸립니다. 변경 사항은 완전히 롤백되거나 데이터베이스에서의 트랜잭션 및 실제 무결성은 보완되므로 이는 예상했던 동작입니다. 이 동작은 반드시 발생해야 하므로 SQL Server는 SPID를 "골든" 또는 롤백(이를 중단하거나 교착 상태 대상으로 선택할 수 없음을 의미) 상태로 표시합니다. ROLLBACK 명령을 나타내는 sp_who의 출력을 관찰하여 이를 확인할 수 있습니다. sysprocesses의 Status 열은 sp_who 출력 또는 SQL Enterprise Manager(엔터프라이즈 관리자) 현재 작업 화면에도 나타나는 ROLLBACK 상태를 나타냅니다. 이 정보를 볼 수 있는 가장 확실한 방법은 문제의 블로킹 SPID의 DBCC PSS를 조사하고 ec_stat 값을 관찰하는 것입니다. "골든" SPID는 ec_stat 값에 0x800를 가집니다. 기타 일반 ec_stat 값은 이 기사의 "DBCC PSS 출력을 확인합니다." 절에 나열되어 있습니다. 해결책: SPID가 변경 사항을 롤백할 때까지 기다려야 합니다. 서버가 이 작업 중간에 종료되면 데이터베이스는 복구 모드에서 다시 시작되고 열린 모든 트랜잭션이 처리될 때까지 액세스할 수 없습니다. 시작 복구는 런타임 복구로서 트랜잭션마다 걸리는 것과 같은 시간이 걸리고 데이터베이스는 이 기간 동안 액세스될 수 없습니다. 그러므로, 서버를 강제로 종료하여 롤백 상태에 있는 SPID를 수정하면 성능이 저하됩니다. 이러한 상황을 피하려면 바쁜 시간에 OLTP 시스템에서 대규모 일괄 처리 INSERT, UPDATE 또는 DELETE 작업을 수행하지 마십시오. 가능하면 이러한 작업을 한가한 시간에 수행하도록 하십시오. | ||||||||
6. | 고아가 된 연결에 의한 블로킹 클라이언트 응용 프로그램이 트랩되거나 클라이언트 워크스테이션이 다시 시작되면 서버에 대한 네트워크 세션은 몇몇 조건 하에서 즉시 취소되지 않을 수도 있습니다. 서버의 측면에서 클라이언트는 계속 존재하는 것으로 나타나고 얻은 모든 잠금(Lock)은 계속 유지되고 있는 것으로 나타납니다. 자세한 내용은 SQL Server 7.0 온라인 설명서에 있는 "Orphaned Connections" 항목을 참조하십시오. 해결책: 클라이언트 응용 프로그램이 해당 리소스를 제대로 정리하지 않고 연결이 끊어진 경우 KILL 명령을 사용하여 SPID를 종료할 수 있습니다. KILL 명령은 SPID 값을 입력으로 받습니다. 예를 들어, SPID 9를 중지하려면 다음 명령을 실행하면 됩니다.
참고: KILL 명령은 KILL 명령에 대한 검사 간의 간격으로 인해 완료하는데 30초 정도 걸립니다. |
(펌) MSSQL Server 백업 / 복구 시나리오 (0) | 2011.10.20 |
---|---|
(펌) MSSQL 2005 백업계획작성 (0) | 2011.10.20 |
(펌) MSSQL Lock (0) | 2010.12.07 |
(펌) MSSQL2005 - New isolation level (0) | 2010.12.07 |
(펌) MSSQL SNAPSHOT 격리 수준 (0) | 2010.12.07 |
(펌) MSSQL Server 백업 / 복구 시나리오 (0) | 2011.10.20 |
---|---|
(펌) MSSQL 2005 백업계획작성 (0) | 2011.10.20 |
(펌) MSSQL lock & blocking (0) | 2010.12.07 |
(펌) MSSQL2005 - New isolation level (0) | 2010.12.07 |
(펌) MSSQL SNAPSHOT 격리 수준 (0) | 2010.12.07 |
출처 : http://www.devpia.co.kr/Maeul/Contents/Detail.aspx?BoardID=42&MAEULNO=17&no=40&page=3
원문 : [SQL Server 2005에서 좋아진 점 No.1] - New isolation level
1. 시작하기 전에
파일 시스템과 데이터베이스 시스템과의 차이점은 어떤 것들이 있을까? 여러 가지가 있겠지만,
이번 강좌에서 다뤄볼 것은 트랜잭션(Transaction)과 동시성(Concurrency)에 관한 것들이다.
이 두가지 개념으로 인하여 많은 상황이 발생한다. 예를 들자면, 이런 것들이다.
- 한 사용자가 데이터를 읽어나가고 있는데, 다른 사용자가 그 데이터를 변경하려 한다면?
- 한 사용자가 데이터 변경작업을 해나가고 있는데, 다른 사용자가 그 데이터를 읽으려
한다면 변경중인 데이터를 읽어야 할까? 아님 변경이 읽어나기전의 데이터를 읽어야 할까?
이런 상황들에 대해서 어느 정도 수준까지 동시성을 제공해줄 수 있는 가를 정의한 것이
격리수준(Isolation level)이라는 것이다. 어느 정도의 격리수준을 제공하는 가에 따라서
동시성이 높아질 수도 낮아질 수도 있다.
개인적으로 SQL Server는 중소형 규모에 적절한 시스템이라 생각한다. 왜 그렇게 생각하는가 하면,
SQL Server가 제공하는 격리수준이 상대적으로 타사의 제품에 비해서 떨어지는 편이기 때문이다.
SQL Server의 기본적인 동시 사용 제어(Concurrency Control)는 비관적 동시 사용 제어 개념을
사용한다. 이 말은 쓰기 작업이 읽기 작업에 영향을 줄 수 있고, 그 반대로 읽기 작업이 쓰기 작업에
영향을 줄 수 있기 때문에 하나의 자원에 대해서 한 가지 형태의 작업이 이뤄지고 있으면 다른 형태의
작업이 접근하지 못하도도록 자원을 잠궈버린다.(Locking)
이 때에 다른 작업은 선행 작업이 끝날때 까지 그 자원에 접근을 하지 못하며 대기 상태가 된다.(Blocking)
근데 이 정도에서 상황이 종료되는 것이 아니다. 기본적으로는 row 단위의 잠금을 하지만,
자원에 대해서 잠금 현상이 점점 많아지게 되면 SQL Server는 잠금에 사용되는 자원를 보다 손쉽게
관리하기 위해서 잠금의 단계를 높여버리게 된다.
예를 들어서 row단위의 잠금을 table단위로 올리는 것이다. 이것을 lock escalation 이라는 말로 표현한다.
잠금의 사용되는 자원을 보다 손쉽게 관리한다는 측면 - SQL Server의 입장에서는 맞는 말일수도 있겠지만,
사용자 측면에서는 잠금 현상의 확대로 인해서 데드 락이 발생하여 무한 대기 상태 또는 세션의 강제 종료 등과
같은 별로 달갑지 않는 현상이 발생해 버린다.
이런 현상을 해결하기 위해서 SQL Server 2000 버전까지는 각 트랜잭션 단위를 빠르고 신속하게 처리할 수 있도록
Query를 튜닝하거나 with nolock 같은 힌트를 이용하는 등을 이용하여 격리수준을 낮춰버리는 등의 작업으로 해결하곤 했다.
각 트랜잭션 단위가 빠르게 수행되도록 하는 Query 튜닝은 어떤 DBMS 제품을 이용하더라도 필수적인 일이겠으나,
운영중인 시스템들은 두 서너개의 Query만을 가지고 있는 것이 아니라, 몇 백, 몇 천개가 넘어가는 Query를 가지는
경우가 대부분이기 때문에 그런 Query들을 튜닝한다는 말은 그리 쉬운 일이 아니다.
그리고 격리 수준을 낮춘다는 말은 데이터의 일관성(consistency)이 깨져버린 믿지 못할 데이터를 이용하고 있다는
말 밖에는 되지 않는다. 자신들이 이용하는 데이터가 신뢰성이 결여된 것을 고객들이 알게 된다면 어떤 일이 벌어질까?
SQL Server 2005에서는 이런 동시성을 높여줄 새로운 Isolation level이 추가 되었다.
사용방법은 정말 간단하다. 옵션의 플래그 값만을 변경해주면 가능하다.
하지만, 그 간단한 작업의 뒷편에는 개념에 대한 충분한 이해와 새로운 이 기능을 적용하기 위해서 고려해야할 사항들이 있다.
그냥 막연하게 새로운 기능이니 좋겠지, 한번 해볼까? 하는 생각만으로 옵션을 변경하지는 말자.
2. 개념
앞서 장황하게 설명했던 새로이 추가된 격리 수준은 SNAPSHOT ISOLATION이다.
이 격리수준은 row versioning이라는 기술을 기반으로 구현된 것이다. 각 row 단위에 14byte의 unique한 식별자를
부여한다. 이 식별자를 기반으로 버전 관리를 하여서 읽기/쓰기 작업에 대한 요청이 들어올 때에 작업에 적절한
버전을 반환하여 해당 버전에 대한 데이타를 작업에 사용하게 하도록 한다.
SNAPSHOT이라는 말에서도 느낌이 오듯이 해당 버전에 대한 데이타의 복사본을 만들어서 요청에
응답하기 때문에 앞서 말한 BLOCKING이나 일관성(CONSISTENT)이 깨진 데이타를 제공하지는 않는다.
이 때문에 잠금 현상이 줄어들어 동시성을 높여줄 수가 있게 되는 것이다.
예를 들어서 설명을 하자면, 이러하다.
VER 1.0에 대한 데이타를 읽기 트랜잭션이 시작되어서 읽어나가고 있다고 하자.
이 때에 쓰기 트랜잭션이 시작되었다면, 블록킹 현상없이 해당 데이터의 버전을
VER 1.1로 기록하고 작업을 해나가면 된다.
또, 쓰기 트랜잭션이 계속되고 있는 상황에서 읽기 트랜잭션이 시작되었다면,
아직 COMMIT이 되지 않아서 반영이 되지 않은 데이타이므로, VER 1.0의 데이타를
블록킹 없이 읽어나가면 된다. 그리고, COMMIT이 된 후에 시작된 읽기
트랜잭션이라면 VER 1.1의 데이타를 읽어가게 될 것이다.
역시 쓰기 작업이 진행되고 있는 상태에서 읽기 작업이 시작되었지만, 블록킹 현상없이 작업이 처리가 될 것이다.
좀 더 세부적으로 알아보자. 크게 두가지 형태로 SNAPSHOT이 제공된다.
SNAPSHOT isolation level
READ COMMITTED SNAPSHOT isolation level
이 두 격리수준의 차이점은 어느정도 수준까지 적용을 해줄 것인가에 관한 것이다.
먼저 SNAPSHOT isolation level은 트랜잭션 단위까지 위의 기술을 제공한다.
두번째로 READ COMMITTED SNAPSHOT ISOLATION LEVEL은 QUERY 단위까지 지원을 한다.
먼저 SNAPSHOT isolation level에서의 예를 들어보면 이렇다.
하나의 트랜잭션이 시작되고 읽기 작업이 시작되었다. VER 1.0의 데이타를 반환하였다.
그리고 중간에 다른 쓰기 트랜잭션이 시작되어 데이타를 변경해버렸다.
그 이후에 첫번째 트랜잭션이 다시 데이타를 읽는 다면 VER 1.0의 데이타를 반환하게 된다.
두번째 READ COMMITTED SNAPSHOT ISOLATION LEVEL은 조금 다르다.
첫번째 커넥션에서 읽기 작업을 했더니 VER 1.0의 데이타를 반환하였다.
중간에 다른 커넥션에서 해당 데이터를 VER 1.1로 반환하였다.
첫번째 커넥션에서 다시 읽기 작업을 하게 되면 VER 1.1로 반환을 하게 된다.
말그대로 작업 시점에 COMMITTED가 된 DATA를 반환하게 되는 것이다. 물론 잠금이나 블록킹 없이 말이다.
근데, 여기서 SNAPSHOT ISOLATION LEVEL에 대해 좀 더 생각하다보면 이런 상황이 발생할 수 있다.
첫번째 트랜잭션에서 읽기 작업이 이뤄져 VER 1.0의 데이타를 반환하였다.
그런데, 첫번째 트랜잭션에서 읽기 작업이 이뤄지는 중에 다른 트랜잭션에서 데이타를 VER 1.1로 변경한 후
COMMIT까지 이뤄져버렸다. 그 후에 첫번째 트랜잭션에서 읽기 작업으로 얻은 데이타를 쓰기 작업을
하려 한다면 어떻게 될까?
VER 1.2가 기록이 되면서 정리가 될까? 아니다.
에러가 나면서 트랜잭션은 롤백처리가 되어버린다. 아주 당연한 일이겠지만, 해당 데이타에 갱신을
하게되는데에 잘못된 데이타 버전을 기반으로 작업을 하려 한 것을 갱신하려고 한 것이기 때문에
데이타의 갱신이 이뤄지면 않된다.
그런 부분까지 꼼꼼히 챙기고 있기 때문에 DATA 일관성에는 별 문제가 없다.
3. 고려해야 할 점
여기까지 읽어본 느낌이 어떠한가? 어라~ 많이 좋아졌네? 이 좋은 기능을 왜 진작에 제공을 하지 않았는가?
등등의 여러 느낌이 있으리라 생각된다.
앞서 이런 말을 했다. 그냥 좋은가보다라는 생각으로 이 옵션을 적용하지 말라고~
새로 제공되는 isolation level은 잠금 현상을 줄여서 동시 사용성을 높여주지만, 대신에 나빠지는 것도 있다.
각 데이터의 버전에 대한 SNAPSHOT을 만든다는 것을 기억하는가?
SQL Sever에서는 row versiong을 위한 data snapshot을 tempdb database에 만들어서 관리한다.
때문에 이 기능을 사용하게 되면 tempdb database에 I/O이 늘어날 수 밖에 없다.
다른쪽에 LOCKING으로 발생하는 병목현상은 해결했지만, TEMPDB DATABASE에 대한 병목현상이
새로이 생겨버리게 된다. 때문에 TEMPDB DATABASE에 대한 I/O 증가로 인한 병목현상에 대한
고려가 있어야 한다.
TEMPDB DATABASE에 대한 확장 옵션, TEMPDB DATABASE가 저장되어 잇는 디스크 시스템 등에
대한 점검과 고려를 충분히 해보고, 테스트를 충분히 해본 다음에 적용을 하길 바란다.
이 옵션은 DEFAULT가 아니다. 이런 부분들에 대한 고려를 해본 다음에 적용하라는 사연이
있어서 그런 것이 아닌가하고 생각해본다. 장점만 있는 기능이라면 DEFAULT가 OFF는 아닐테니 말이다.
4. 적용하기
드디어 적용하기에 돌입했다. 앞서 말한 것처럼 장황하게 부연설명한 것에 비해선 허무할 정도로 간단하다.
먼저 SQL Server에 있는 데이타베이스들에 해당 옵션이 적용되어 있는지를 살펴보자.
아래의 쿼리를 쿼리창을 열어서 실행시켜보자.
SELECT NAME, SNAPSHOT_ISOLATION_STATE,
SNAPSHOT_ISOLATION_STATE_DESC, IS_READ_COMMITTED_SNAPSHOT_ON
FROM SYS.DATABASES
SNAPSHOT_ISOLATION_STATE, IS_READ_COMMITTED_SNAPSHOT_ON의 값이 1이면
적용이 되고 있다는 것이고, 0은 적용이 되고 있지 않다는 뜻이다.
SNAPSHOT ISOLATION LEVEL를 적용하기 위해선 아래의 쿼리를 실행하면 된다.
ALTER DATABASE 데이터베이스명 SET ALLOW_SNAPSHOT_ISOLATION ON
당연히 기능을 정지하려고 할 때에는 OFF로 플래그만 변경해서 실행하면 된다.
READ COMMITTED ISOLATION LEVEL를 적용하기 위해선 아래의 쿼리를 실행한다.
ALTER DATABASE 데이터베이스명 SET READ_COMMITTED_SNAPSHOT ON
역시 해당 기능을 정지하려고 할 때에는 OFF로 플래그만 변경하면 된다.
위 기능을 적용하기 위해서는 데이터베이스에 접속되어 있는 사용자가 없어야한다.
5. 맺음말
이 강좌에서는 개념적인 설명이 많았다. 적용하는 명령은 솔직히 한 줄로도 끝난다.
하지만, 제대로 사용하기 위해서는 개념에 대한 이해가 있어야 하기 때문이다.
이전 버전에 비해선 장족의 발전(?)이라 생각을 한다. 하지만, 아직 완전한 기능(?)은
아닌 것 같다는게 개인적인 느낌이다.
이전 버전과의 호환성 등을 이유로 Default가 OFF인 형태로 제공된듯 하지만,
고려할 점에서 언급한 것처럼 I/O에 대한 추가적인 부하가 있기 때문이다.
그리고 여기서 언급한 isolation 레벨은 오라클에서는 예전부터 제공이 되고 있던 기능이다.
개인적인 느낌으론 TPC에서 나오는 SQL서버 관련 수치들은 앞서 언급한 기능들을 배제하고
만들어낸, 차떼고 포떼고 해서 만들어낸 수치일수도 있다.
그렇다면, 오라클만 좋고 SQL서버는 나쁜 것일까?
회색분자 같이 들릴 수도 있지만, 개인적으론 오라클과 SQL서버 모두 좋아한다.
각각의 DBMS가 주는 장단점이 다르다고 생각하기 때문이다.
정원혁님의 마이크로소프트웨어 기사에서처럼 현시점에선 비용기반으론 SQL 서버가 오라클보다
우위에 있기 때문이다. 비용을 고려하지 않고 프로젝트를 진행하는 곳이 얼마나 될까?
프로젝트를 진행한다는 말은 결국 비용과의 싸움이니까 말이다.
장인은 연장을 탓하지 않는 다는 말이 있다.
최고의 성능을 가진 오라클에서도 엉망진창으로 설계와 코딩을 진행하면 무지하게 느려질 수도 있다.
SQL 서버에서도 제품이 가진 특성을 잘 고려해서 설계와 운영을 해나간다면,
아주 만족스러운 성능을 뽑아낼 수 있는 좋은 제품이라 생각한다.
느려진 DBMS를 탓하기 전에 사용하고 있는 DBMS의 아키텍처는 얼마나 잘 이해하고 있으며,
설계와 관리는 어떻게 하고 있는가를 자문하는 시간을 먼저 가져보는 것이 좋지 않을까 생각한다.
(펌) MSSQL Server 백업 / 복구 시나리오 (0) | 2011.10.20 |
---|---|
(펌) MSSQL 2005 백업계획작성 (0) | 2011.10.20 |
(펌) MSSQL lock & blocking (0) | 2010.12.07 |
(펌) MSSQL Lock (0) | 2010.12.07 |
(펌) MSSQL SNAPSHOT 격리 수준 (0) | 2010.12.07 |