oracle) JDBC Client로 연결된 특정 사용자에 대해서 sql trace 설정

-- SQL TRACE 활성화

SELECT 'exec sys.dbms_system.set_sql_trace_in_session(' || sid || ', '|| serial# || ', TRUE);' AS text 

FROM v$session where username='userId' 

AND module = 'JDBC Thin Client';


-- SQL TRACE  비활성화

SELECT 'exec sys.dbms_system.set_sql_trace_in_session(' || sid || ', '|| serial# || ', FALSE);' AS text 

FROM v$session where username='userId

AND module = 'JDBC Thin Client';


-- SQL 10053 TRACE 활성화

SELECT 'exec SYS.DBMS_SYSTEM.SET_EV(' || sid || ',' || serial# || ',10053,12,'''');' AS text 

FROM v$session where username='userId

AND module = 'JDBC Thin Client';


-- SQL 10053 TRACE 비 활성화

SELECT 'exec SYS.DBMS_SYSTEM.SET_EV(' || sid || ',' || serial# || ',10053,0,'''');' AS text 

FROM v$session where username='userId

AND module = 'JDBC Thin Client';


-- DBMS SUPPORT를 이용한 SQL TRACE 활성화

SELECT 'exec sys.dbms_support.start_trace_in_session(' || sid || ',' || serial# || ',waits=>true, binds=>true);' AS text 

FROM v$session where username='userId

AND module = 'JDBC Thin Client';


-- DBMS SUPPORT를 이용한 SQL TRACE 비활성화

SELECT 'exec sys.dbms_support.stop_trace_in_session(' || sid || ',' || serial# || ');' AS text 

FROM v$session where username='userId

AND module = 'JDBC Thin Client';


* DBMS_SUPPORT가 설치되어 있지 않으면 설치해야 한다.

SQL> @$ORACLE_HOME/rdbms/admin/dbmssupp.sql

oracle) trace

- 실행계획과 autotrace 보다 강력한 튜닝도구

▣ SQL Trace 사용 방법 - 자기세션에서 트레이스

(1) 1단계 - alter 문 사용하여 SQL 문 실행하기

alter session set sql_trace=true;

select * from emp where empno=7900;

alter session set sql_trace=false;

(2) 2단계 - 트레이스 파일찾는 스크립트 실행(trc 파일의 이름이 출력된다)

select r.value || '/' || lower(t.instance_name) || '_ora_'

|| ltrim(to_char(p.spid)) || '.trc' trace_file

from v$process p, v$session s, v$parameter r, v$instance t

where p.addr = s.paddr

and r.name = 'user_dump_dest'

and s.sid = (select sid from v$mystat where rownum = 1) ;

(3) tkprof 사용하여 프로파일 파일 생성하기(DOS 명령어, report.prf를 생성한다.)

tkprof orcl_ora_4000.trc report.prf sys=no; 

(실습결과)

fig3-1.jpg 


(4) 이벤트 트레이스를 추가하는 방법 - 아래 명령어를 실행한 다음 (1),(2),(3) 과정 반복

alter session set events '10046 trace name context forever, level 8';

 

(실습결과)

fig3-5.jpg


 

▣ SQL Trace 설명

- Elapsed time = cpu time + wait time = reponse 시점 - call 시점

- call count

SELECT 문 = Parse + Execute + Fetch

DML 문 = Parse + Execute

- Fetch call = 레코드 건수 / ArraySize

(실습결과)

fig3-3.jpg 


(질의문 실행 흐름)

fig3-4.jpg 


▣ SQL Trace 사용 방법 - 다른세션에서 트레이스

(1) 9i에서

exec dbms_system.set_ev(145, 3, 10046, 12, '');

=> 시리얼 번호가 3인 145번 세션에서 레벨 12로 10046 이벤트 트레이스

(2) 10g

(시작)

begin

dbms_monitor.session_trace_enable(

session_id=>145, serial_num=>3,

waits=>TRUE, binds=>TRUE);

end;

(해제)

begin

dbms_monitor.session_trace_disable(

session_id=>145, serial_num=>3);

end;

(3) oradebug 명령어

oradebug help

oradebug setospid 3796

oradebug unlimit /* 트레이스 파일의 크기를 없앰 */

oradebug event 10046 trace name context forever, level 8

oradebug tracefile_name /* 트레이스 파일 이름 확인 */

oradebug event 10046 trace name context off /* 트레이스 해제 */

oradebug close_trace

▣ SQL Trace 사용 방법 - Service, Modele, Action 단위로 트레이스 걸기- 10g

- show parameter service_name;

- /* 서비스나 모듈 이름 보는 방법 */

select sid, service_name, module, action

from v$session

where service_name <> 'SYS$BACKGROUND';

(1) 세션에 거는 방법 - 세션 이름이 eCRM인 세션에 모두 트레이스 걸기

begin

dbms_monitor.serv_mod_act_trace_enable(

service_name=>'eCRM',

module_name=>dbms_monitor.all_modules,

action_name=>dbms_monitor.all_actions,

waits=>true, binds=>true);

end;

/

(트레이스 설정 확인)

select primary_id service_name, qualifier_id1 module, qualifier_id2 action,

waits, binds

from dba_enabled_traces;

(트레이스 해제)

begin

dbms_monitor.serv_mod_act_trace_disable(

service_name=>'eCRM',

module_name=>dbms_monitor.all_modules,

action_name=>dbms_monitor.all_actions);

end;

/

(2) 모듈에 거는 방법

(모듈 이름 바꾸기)

begin

dbms_application_info.set_module(

module_name=>'emp manager',

action_name=>'select emp');

end;

/

(확인)

select sid, service_name, module, action

from v$session

where service_name <> 'SYS$BACKGROUND';

(모듈에 걸기)

begin

dbms_monitor.serv_mod_act_trace_enable(

service_name=>'eCRM', module_name=>'emp manager',

action_name=>dbms_monitor.all_actions,

waits=>true, binds=>true);

end;

/

(트레이스 설정 확인)

select primary_id service_name, qualifier_id1 module, qualifier_id2 action,

waits, binds

from dba_enabled_traces;

(트레이스 해제)

begin

dbms_monitor.serv_mod_act_trace_disable(

service_name=>'eCRM', module_name=>'emp manager',

action_name=>dbms_monitor.all_actions);

end;

/

(실행 중 부분 모듈에 걸기)

..

dbms_application_info.set_action('update emp');

..

begin

dbms_monitor.serv_mod_act_trace_enable(

service_name=>'eCRM', module_name=>‘emp manager',

action_name=>'update emp',

waits=>true, binds=>true);

end;

/

select primary_id service_name, qualifier_id1 module, qualifier_id2 action,

waits, binds

from dba_enabled_traces;

(특정값으로 설정된 세션에만 트레이스 걸기)

- 설정

exec dbms_session.set_identifier('oraking');

- 트레이스 걸기

begin

dbms_monitor.client_id_trace_enable(

client_id=>'oraking',

waits=>false, binds=>false);

end;

/


출처 : http://bysql.net/index.php?document_srl=5030&mid=w201002


jps 사용법

자바로 개발할 때 보통 java와 javac만 사용하지만, JDK에는 이 이외에도 많은 도구가 포함되어 있다. 그 중 하나인 jps를 살펴보자.

jps는 JVM 프로세스 상태를 보는 도구로 UNIX의 ps와 비슷하다. ps는 운영체계의 모든 프로세스 상태를 보여주지만 jps는 JVM 프로세스만 보여준다는 차이가 있다. jps 실행 시 목표 시스템(target system)을 지정하면 원격 시스템의 JVM 프로세스 상태도 확인할 수 있다.

사용법

$ jps [options] [hostid]

옵션

  • -q 클래스 이름, JAR 파일 이름, main 메서드에 전달된 인자를 모두 생략하고 JVM 아이디(보통 OS 프로세스 아이디와 동일. 반드시 그럴 필요는 없음)만 표시한다.
  • -m main 메서드에 전달된 인자를 표시한다.
  • -l 애플리케이션 main 클래스의 전체 패키지 이름 또는 JAR 파일의 전체 경로를 표시한다.
  • -v JVM에 전달된 인자를 표시한다.
  • -V 클래스 이름, JAR 파일 이름, main 메서드에 전달된 인자를 모두 생략한다.

호스트 아이디

목표 시스템을 지정하는 문자열로 다음과 같은 형식이다.

[protocol:][[//]hostname][:port][/servername]
  • protocol 통신 프로토콜. protocol과 hostname이 함께 생략된 경우에는 로컬 프로토콜. protocol은 생략했지만 hostname이 지정된 경우에는 디폴트로 rmi 프로토콜이 사용됨.
  • hostname 호스트 이름 또는 IP 주소. 생략하면 localhost가 사용됨.
  • port 원격 서버와 통신할 포트. port가 생략되고 protocol이 rmi인 경우 1099가 사용됨.
  • servername 로컬 프로토콜인 경우에는 무시됨. rmi 프로토콜인 경우에는 RMI 원격 객체의 이름.

사용 예

$ jps -l
6176 clojure.main
6514 sun.tools.jps.Jps
6179 clojure.main
$ jps -m
6176 main -m leiningen.core.main repl
6179 main -i /private/var/folders/sl/j6.../T/form-init143...99.clj
6521 Jps -m

참고

출처 : http://ntalbs.github.io/2014/08/05/jps/

[HTML5] WEB WORKERS (웹 워커)

HTML 5 의 많은 기능 중 웹 페이지가 단순 문서 표현을 넘어 응용프로그램과 같이 동작할 수 있도록
하는 주요한 기능 중 하나가 바로 Web Workders 이다

요즘 웬만한 응용프로그램들은 멀티 프로세스, 멀티 쓰레드를 구현하고 있다
웹 페이지도 이러한 멀티 쓰레드 구현이 가능하게 된 것이다

그간 웹 페이지는 단일 쓰레드 모드에서 수행될 수 밖에 없었다
만일 값을 반환하기까지 작업이 오래 걸리는 스크립트를 수행한다면 다른 UI 작업을
스크립트 작업이 종료될 때 까지 대기해야만 했다

그러나 HTML 5 에는 Web Worker 라는 스펙을 추가 했으며 브라우저에서는 이 스펙을 기반으로
멀티 쓰레드 구동이 가능하도록 브라우저를 설계하기에 이르렀다


롱~타임(Long~ Time) 작업은 워커에게 맡기기

이제 스크립트 작업이 오래 걸린다고 해서 페이지를 멈추고 기다릴 필요가 없어졌다
웹 워커는 자바스크립트 코드를 UI 쓰레드와는 별도인 백그라운드에서 수행될 수 있도록 하는 표준적인 방법을 제공하기 때문에 웹 페이지를 가로막지 않고 스크립트를 돌릴 수 있게 되었다

다음과 같은 롱~타임 스크립트 작업에 웹워커는 안성맞춤 일 것이다
- 매우 복잡한 수학적 계산 작업
- 원격지에 있는 리소스에 대한 액세스 작업(또는 로컬 스토로지를 액세스 하는 경우)
- 백그라운드에서 조용히(?) 오랜시간 작업해야 하는 경우 
- UI 쓰레드에 방해 없이 지속적으로 수행해야 하는 작업 등

사실 웹 워커 만의 지침은 없다. 일반적인 응용프로그램의 백그라운드 작업을 연상하면 된다


브라우저가 Web Worker 를 지원하나요?
HTML 5 가 아직 산업 표준이 완료된 것이 아니기에 브라우저별로 지원 여부가 상이할 수 있다
그리고 브라우저 버전별로도 지원 유/무가 다르기도 하다

따라서 웹 페이지에 웹 워커를 동작시키기 전에, 현재 페이지를 랜더링 하고 있는 브라우저가
웹 워커를 지원하는지 체크하는 것이 필수이다 (이것은 하위 호환성을 위해서도 중요하다)

브라우저의 웹 워커 지원 유/무 체크는 매우 간단한 방법으로 할 수 있다
전역 윈도우 객체의 워커(Worker) 속성을 살펴보면 된다. 아래는 샘플 코드이다

if(!!window.Worker){
      alert("이 브라우저는 웹 워커를 지원합니다")
}
else{
      alert("이 브라우저는 웹 워커를 지원하지 않습니다")
 }


Web Workers 개념도
웹 워커는 HTML 페이지에서 Worker 라는 객체를 통해 실행된다
HTML 페이지에 Worker 객체를 생성하기 위해서는 워커의 작업을 정의한 자바스크립트파일(.js) 
을 Worker 객체 생성 시 전달해 줘야 한다
ex) var worker = new Worker("worker.js")

이후 롱~타임 작업은 .js 파일에 정의된 스크립트로 수행되며,
HTML 페이지와는 서로 데이터를 주고 받을 수 있는 매커니즘이 제공되는 것이다

양쪽 모두 상대에게 데이터를 송신할 때는 postMessage 라는 메서드를 이용하며
데이터를 수신할 때는 onmessage 이벤트를 통해 전달 받는다

아래 그림은 기본적인 (단일) 워커와 HTML 페이지 간 데이터 송/수신 개념도 이다





Web Workers 브라우저 지원 현황
현재 IE를 제외한 대부분의 웹브라우저에서 웹 워커를 지원하고 있다
아래 표는 http://caniuse.com/ 에서 제공하는 브라우저(버전)별 웹 워커 지원 표이다
(데스크탑 용 브라우저 기준이다)

MS IE 9 가 unknown 이라고 되어 있지만 아마 지원하게 될 것이다.
MS 가 HTML 5 지원을 강력히 표명하고 있기 때문이다






위 표는 데스크탑 버전의 브라우저 지원 현황이다
모바일 환경은 이와 좀 다를 수 있는데 대표적인 예로 사파리를 들 수 있다

사파리의 경우 데스크탑 사파리는 Web Workers 를 지원하는데 반해,
아이폰 사파리는 Web Workers 를 현재까지 지원하지 않고 있다

아이폰에 내장된 사파리의 경우 대부분의 HTML5를 지원하지만,
유독 Web Worker 는 아직 지원하지 않고 있는 것이 의아하다

현재 모바일 웹 구축 시 제일 먼저 고려되는 플랫폼이 아이폰 환경인데 말이지...


Web Workers 데모 만들어 보기
지금까지 웹 워커에 대한 개념적 내용을 살펴 보았다
그럼 이제 웹 워커를 이용한 매우 기본적인 데모 코드를 작성해 보도록 하자

웹 워커의 장점을 알려면 웹 워커를 사용하지 않을 때의 단점을 알아보고 
그 단점을 웹 워커로 해결하는 식의 접근이 이해하기 보다 수월할 수 있다
따라서 먼저 웹 워커 없이 시간이 오래 걸리는 스크립트 코드를 돌려 보자

시나리오를 단순하게 하기 위해,
샘플에서는 특별히 오래 걸리는 특정 작업을 구현하기 보다는 간단하게,
주어진 시간동안 반복(loop)문을 돌리는 것으로 대신하겠다. 
일종의 대기(sleep) 시간이며 다음과 같이 스크립트 함수를 작성하도록 한다

- 시간이 오래 걸리는 작업(일종의 sleep 기능)
function sleep(milliSeconds){  
    var startTime = new Date().getTime(); 
    while (new Date().getTime() < startTime + milliSeconds);
}

이제 이 코드를 HTML 페이지에 삽입하여 실행해 보도록 하자

- HTML 페이지
아래와 같이 HTML 과 스크립트를 작성한다. 대략 10초 동안 대기(sleep) 시킨다
그리고 텍스트 상자는 대기시간동안 글 작성이 가능한지 보기 위해 삽입하였다
<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript">
      function sleep(milliSeconds){  
        var startTime = new Date().getTime(); 
        while (new Date().getTime() < startTime + milliSeconds); 
      }      
      function callNotWorker(){
        sleep(10000); //10초 동안 대기 시킨다
      }    
           
    </script>
  </head>
  <body>
    <button onclick="callNotWorker()">워커없이 호출</button>    
    <br>    
    <input type="text">
  </body>
</html>

- 실행 화면
HTML 파일을 웹 브라우저(데스크 탑 사파리)에서 실행하면 약 10초 이 후 완료 메시지가 나타난다
그런데 문제는 대기 시간 10초 동안 브라우저에서 다른 작업을 할 수 없다는 것이다
브라우저를 움직일 수도 없고 텍스트 상자에 글을 입력할 수도 없는 듯 마치 꽁꽁 얼어버린 듯 하다
10초 후 메시지가 나타난 이후부터 다른 작업을 할 수 있게 되는 것이다



이것이 바로 단일 쓰레드(UI 쓰레드) 환경의 특징이다
스크립트에서 시간이 오래 걸리는 작업을 하는 동안 다른 일을 할 수가 없는 것이다

웹 워커는 이런 형태의 작업을 멀티 쓰레드 환경처럼 동작하도록 만들어 준다
즉 시간이 오래 걸리는 작업은 백그라운드에서 실행되기 때문에 UI 쓰레드는 다른 일을 
동시에 할 수 있는 것이다. 그럼 웹 워커를 사용하는 버전을 수정해 보도록 하자

- 워커 정의하기(JS 파일에 정의한다)
시간이 오래 걸리는 스크립트 코드 즉 백그라운드 환경에서 실행되어야 하는 스크립트는
별도의 자바스크립트파일(worker.js) 로 작성한다

//메세지 수신하여 시간이 오래 걸리는 작업을 처리한다
onmessage = function(event){
  var receiveData = event.data;
  sleep(10000); 
    
  //워커를 호출한 곳으로 결과 메시지를 전송한다
  var sendData = receiveData + "OK~ I'm Worker"
  postMessage(sendData)
}

function sleep(milliSeconds){  
  var startTime = new Date().getTime(); // get the current time   
  while (new Date().getTime() < startTime + milliSeconds); // hog cpu 


- HTML 페이지
이제 이 워커(파일)을 이용하는 HTML 페이지를 아래와 같이 작성한다
앞서 정의한 worker.js 파일을 기반으로 Worker 객체를 생성하고 postMessage 메서드를 통해
워커로 메시지를 전달한다. 또한 onmessage 이벤트를 정의하여 워커로 부터 전달되는 메시지를
받을 수 있도록 한다. 그리고 워커의 작업을 중지시키려면 terminate 메서드를 호출하면 된다

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript">              
      var worker;      
      function callWorker(){      
        if(!!window.Worker){ //브라우저가 웹 워커를 지원하는지 검사한다    
            
          if(worker) worker.terminate();      //워커가 이미 존재하면 종료시킨다                     
          worker = new Worker("worker.js");  //새로운 워커(객체)를 생성한다       
                       
          worker.onmessage = function(event){ //워커로부터 전달되는 메시지를 받는다
            alert(event.data);
          };
                            
          worker.postMessage("워커야! 깨어나라!"); //워커에게 메시지를 전달한다        
        }
        else{
          alert("현재 브라우저는 웹 워커를 지원하지 않습니다")
        }
      }
                
      function stopWorker(){
        if(worker){
          worker.terminate();
          alert("워커 작업이 중지되었습니다");
        }
      }
    </script>
  </head>
  <body>
    <button onclick="callWorker()">웹워커 호출</button>
    <button onclick="stopWorker()">웹워커 중지</button>    
    <br>    
    <input type="text">
  </body>
</html>

- 실행 화면
HTML 파일을 웹 브라우저(데스크 탑 사파리)에서 실행하면 10초 후에 메시지가 나타난다
또한 워커를 사용했기 때문에 브라우저가 얼어 버리는 일은 없다
즉 10초라는 대기 시간 동안에도 브라우저를 움직이거나 텍스트 상자에 글을 입력할 수 있게 되는 것이다



결과적으로 두 작업이 동시에 처리되는 병렬작업이 가능하게 되는 것이다
이러한 병렬처리는 응용프로그램의 중요한 요구사항이며 이제 워커 덕분에
웹 페이지에서도 이러한 응용 환경 구현이 가능하게 된 것이다

마지막으로 아래 사이트에서 웹워커 관련 데모를 추가로 확인해 보자
http://html5demos.com/worker

출처: http://m.mkexdev.net/52

Unicode Character 'LEFT-TO-RIGHT MARK' (U+200E)

direction: rtl로 설정되어 있을때 문자가 짤려 보일때는 css에 아래와 같이 넣어준다.

class:after {

    content: "\200E";

}