티스토리 뷰

10gR2부터 Shared Cursor Operation에 대해 기본적으로 Mutex를 사용하게 되었다. 여기서 Shared Cursor Operation이란 library cache latches, library cache pin latches, library cache pins.을 의미한다.

이를 위해 오라클은 _kks_use_mutex_pin라는 파라메터를 제공하고 있는데 이는 기본적으로  True이며 만약 False인 경우는 이전과 같이 Latch와 Pin/Lock의 구조를 사용하게 된다.

 그런데 mutex라는 것이 무엇일까..?

mutex는 mutual exclusion object의 약자로 다수의 스레드 혹은 프로세스가 동일한 리소스를 공유할 수 있게 해주는 것인데 만약 프로그램이 하나 시작된다고 할 때 이는 시스템으로 부터 이 요청에 대해 주어진 리소스를 위한 mutex를 하나 생성하게 되고 시스템은 이를 위해 고유의 id혹은 이름을 부여한다. 이후 어떤 쓰레드가 이 리소스를 필요로 하게 되면 반드시 이 리소스를 사용하는 동안 다른 스레드가 이 리소스에 접근하지 못하도록 mutex를 사용해야만 하는 것이다. 만약 mutex가 이미 다른 쓰레드에 의해 lock이 걸려 있다면 이 쓰레드는 시스템의 대기 queue로 가서 대기하고 mutex가 lock이 풀릴때 주어진 작업(계속 대기 혹은 수행)을 하게 되는 것이다.

마치 이것은 No wait mode의 latch와 유사하다.  그런데 Oracle은 10g에 와서 지금껏 개량을 거듭해 온 latch 구조 대신 mutex를 사용한다고 할까..? 이것에 대해 고민을 참 많이 했었는데 아마도 mutex와 비슷한 구조로 구현이 된 latch대신 mutex를 사용하게 되면 이 제어권을 oracle에서 os로 넘길 수 있게 된다는 점이 있을 수 있다는 점이다. 

특히 mutex를 사용하게 되면 deadlock에 대한 제어를 OS에 넘길 수 있게 된다는 점도 생각할 수 있다. Mutex라는 것은 범 System적인 것이기 때문에 이를 획득하고 놓고 하는 것은 전적으로 System이 관리하게 된다. 또한 Mutex를 소유하고 있는 스레드가 다른 mutex를 잡으려고 하면 system이 이를 놓도록 되어 있다고 한다. Latch의 경우는 각 latch마다 level을 부여하여 deadlock을 방지하고 있다. 버전이 올라가 latch도 증가하면서 점점 더 복잡해 질 수 있는 부분이다.

게다가 SQL을 수행할 때 가장 민감한 영역이면서 빠른 operation이 수행되어야 하는 Cursor부분에 대해 부담을 가지고 있었을지도 모르는 일이다. 별것 아닌것 같지만 Oracle을 코딩하는 입장에서는 큰 굴레를 벗어던진 것 같은 느낌이 아니었을까 하는 생각도 든다.

 그러나 이유야 어찌되었건 Mutex를 사용하게 되면 일단 Spin이라는 작업을 수행하지 않게 되어 가벼울 수는 있지만 이 자체로도 몇가지 문제가 있을 수 있다. mutex는 system자원이기 때문에 문제가 발생하면 일단 Oracle의 해결 범위를 넘어설 수 있다는 것과 무엇보다 중요한 것은 mutex는 복구가 안된다는 점이다. latch의 경우 프로세스가 latch를 잡고 갑자기 죽어버리면 PMON이 이를 cleanup을 수행하도록 되어 있다. 이는 latch에 대한 정보가 latch recovery area에 있기 때문인데 mutex의 경우는 어떻게 동작할지 심히 궁금하다. 아마도 mutex를 놓도록 할 것 같은데 그렇게 되면 sql을 수행하는 입장에서는 어찌될지 궁금할 따름이다.

 그밖에 메타링크나 현장에 나가보면 _kks_use_mutex_pin를 true로 사용하여 발생하는 문제가 발견되는데 이것을 간략히 정리해보려 한다.

 1) bug 5485914 - "cursor: pin S wait on X", MUTEX REPORTED SELF DEADLOCK AFTER DBMS_MONITOR.SESSION_TRACE_ENABLE
10046 trace를 수행할때 cursor: pin S wait on X라는 이벤트만 과도하게 수행되고 세션이 거의 hang되는 현상으로 10.2.0.3버전에서 직접 목격한 버그임 이는 _kks_use_mutex_pin을 false로 하고 사용하면 해결이 되고 보다 근본적인 패치는 11g에 된다고 함

 2) CAS를 지원하지 않는 시스템에서 과도한 CPU 사용이 발견된다고 함
: Mutex는 compare and swap(CAS)이라는 것을 사용하는데 PA-RISC를 사욯하는 HP-UX 인 경우  CAS를 지원하지 않는다고 한다. 이 경우 oracle은 Mutex라는 이름을 가진 latch pool을 만들어서 mutex를 시뮬레이션 하는 식으로 구현을 했다고 한다. 이때 과도한 Spin을 발생시켜 발생하는 버그라고 한다. 이것도 mutex안쓰면 된다. 참고로 Mutex latch는 CAS를 지원하지 않는 시스템에만 존재한다고 한다.

3) 10.2.0.2에서 Cursor:pin S 이벤트가 과도하게 발생
이 이벤트는 같은 cursor에 대해 여러 세션이 동시에 shared mutex pin를 경합할 때 발생하는데 오라클은 이게 굉장히 드문 케이스라고 한다. 그 이유는 mutex의 갱신이 매우 빠르기 때문이란다. 근데 많이 봤다.. 암튼 이것도 mutex에 해당하는 문제인데 mutex의 경합이 심해지면 기존의 latch보다도 더 해결이 더딘것 같은 느낌이다. 이것도 _kks_use_mutex_pin을 false로 해결하라고 한다.

마지막으로 모니터링 중에 잡힌 관련 이벤트의 그림을 첨부한다.

아마도 oracle은 여지껏 그랬듯 버전이 올라가면서 더 나은 솔루션을 제공할 것이라 생각한다.

댓글
댓글쓰기 폼