레이블이 oracle databas ebuffer cache인 게시물을 표시합니다. 모든 게시물 표시
레이블이 oracle databas ebuffer cache인 게시물을 표시합니다. 모든 게시물 표시

2013년 10월 12일 토요일

스프링3.2,하이버네이트4.2.3 [Spring3.x, Hibernate4연동하기] 1. 하이버네이트 다운로드

[Spring3.x, Hibernate4연동하기] 1. 하이버네이트 다운로드 www.hibernate.org (hibernate-4.2.3.Final.zip 사용) 

[Spring3.x, Hibernate4연동하기]
1. 하이버네이트 다운로드
 다운로드
 www.hibernate.org (hibernate-4.2.3.Final.zip 사용)
 lib : 하이버네이트를 실행 시 필요한 JAR 파일
 project : 각종 소스 코드
 documentation : 문서들
 하이버네이트를 실행하기 위해서는 hibernate4.2.3.jar 파일 뿐 아니라 lib 폴더의 각종 jar 파일이 필요하다.
 물론 이클립스 하이버네이트 플러그인을 설치해도 된다. 현재 Eclipse INDIGO 까지 나와 있다.

2. 준비
 이클립스 ? Spring Project
hibernate4 및 spring 관련 라이브러리 추가
(하이버네이트4 의 경우 스프링 3,1 이상이 필요)
주) 스프링의 Template Project에서 hhibernate Template을 이용하여 하이버네이트 APP 작성가능하나 라이브러리 버전이 맞지 않아 hibernate4 예제와 연동 어려움
    

예제 테이블 작성
  create table myemp (
      empno number ,
      ename varchar2(10)
  )

 
 

3. MyEmp.java
package edu.onj.hibernate;
public class MyEmp {
private int empno;
private String ename;
 public MyEmp() {}
 public MyEmp(int empno, String ename) {
  this.empno = empno;    this.ename = ename;
 }
 public int getEmpno() { return empno;  }
 public void setEmpno(int empno) {this.empno = empno;}
 public String getEname() {
  return ename;
 }
 public void setEname(String ename) {
  this.ename = ename;
 }
}
 
 
4. MyempDao.java

package edu.onj.hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Repository
@Transactional(propagation=Propagation.REQUIRED)
public class MyEmpDao {
private SessionFactory sessionFactory;
private Session session;
public MyEmpDao() {}
//constructor injection(생성자 주입)
@Autowired
public MyEmpDao(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public Session getSession() {
return sessionFactory.getCurrentSession();
}
public void insertMyEmp(MyEmp myemp) {
getSession().save(myemp);
}
public void deleteMyEmp(int empno) {
getSession().delete(getMyEmpByEmpno(empno));
}
public MyEmp getMyEmpByEmpno(int empno) {
return (MyEmp)getSession().get(MyEmp.class, empno);
}
public void saveMyEmp(MyEmp myemp) {
getSession().update(myemp);
}
}
 
5. myemp.hbm.xml
<?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
    <hibernate-mapping>
    <class    name="edu.onj.hibernate.MyEmp"    table="MyEmp"    lazy="false">
        <id name="empno"  type="java.lang.Integer"   column="empno"  />
        <property  name="ename" type="java.lang.String"  column="ENAME" length="10"/>
    </class>
    </hibernate-mapping>
 
6. spring-hibernate.xml
 
<?xml version="1.0" encoding="UTF-8"?>
    <beans
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:util="http://www.springframework.org/schema/util"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation=
        "http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context-3.0.xsd
         http://www.springframework.org/schema/tx
         http://www.springframework.org/schema/tx/spring-tx.xsd
         http://www.springframework.org/schema/util
         http://www.springframework.org/schema/util/spring-util.xsd" >

<!-- Annotation 쓰기 위해서 -->
      <context:annotation-config />
      <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
        <property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>
        <property name="url"><value>jdbc:oracle:thin:@localhost:1521:onj</value></property>
        <property name="username"><value>scott</value></property>
        <property name="password"><value>tiger</value></property>
      </bean>
      <!-- Hibernate Session Factory 설정 -->
      <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource"><ref bean="dataSource"/></property>
        <property name="mappingResources">
          <list>
            <value>myemp.hbm.xml</value>
          </list>
        </property>
        <property name="hibernateProperties">
          <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
          </props>
        </property>
      </bean>
      <!-- 트랜잭션 -->
      <tx:annotation-driven transaction-manager="transactionManager" />
      <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
          <property name="sessionFactory" ref="sessionFactory" />
      </bean>
      <!-- MyEmpDAO autowiring  -->
      <bean id="myEmpDao" class="edu.onj.hibernate.MyEmpDao"> </bean>
   </beans>
  
  
7.    SpringHibernateExam.java

public class SpringHibernateExam {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-hibernate.xml");
MyEmpDao myEmpDao = (MyEmpDao)ctx.getBean("myEmpDao");
try {
MyEmp myemp1 = new MyEmp(1, "1길동");
MyEmp myemp2 = new MyEmp(2, "2길동");
MyEmp myemp3 = new MyEmp(3, "3길동");
myEmpDao.insertMyEmp(myemp1);
myEmpDao.insertMyEmp(myemp2);
myEmpDao.deleteMyEmp(1);
myEmpDao.insertMyEmp(myemp3);
MyEmp emp1 = (MyEmp)myEmpDao.getMyEmpByEmpno(3);
System.out.println(emp1.getEmpno() + "::" + emp1.getEname());
myemp2.setEname("2가아니고4");
myEmpDao.saveMyEmp(myemp2);
MyEmp emp2 = (MyEmp)myEmpDao.getMyEmpByEmpno(2);
System.out.println(emp2.getEmpno() + "::" + emp2.getEname());
}
catch (HibernateException e)
        {             e.printStackTrace();         }
        finally        {                }
}
}
 
8. 결과
/*
SQL> select * from myemp;
EMPNO ENAME
---------- ----------
    2 2가아니고4
    3 3길동
*/

  


오라클자바커뮤니티에서 설립한 개발자교육6년차 오엔제이프로그래밍 실무교육센터(오라클SQL,튜닝,힌트,자바프레임워크,안드로이드,아이폰,닷넷 실무개발강의)  

[개강확정강좌]오라클자바커뮤니티에서 운영하는 개발자 전문교육 ,개인80%환급(www.onjprogramming.co.kr) 




2013년 8월 8일 목요일

[ORACLEJAVA커뮤니티,ORACLEJAVANEW.KR]사용자가 로그인 했는지를 확인하는 커스텀태그(cart.jsp에서 사용), 자바교육

사용자가 로그인 했는지를 확인하는 커스텀태그(cart.jsp에서 사용) 예제입니다. 참고하세요~~~~~


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  




 이번에는 장바구니와는 별개 이지만 cart.jsp에서 사용되었던... 사용자가 로그인을 했는지를 확인하는 사용자 정의 태그에 대한 소개 입니다.


cart.jsp의 상단에서 사용되었던 다음부분이죠^^..

음 ...

refer라는 속성은 로그인을 한 후 다시 돌아올 URL을 기술한겁니다.

<%@ taglib uri="/WEB-INF/login_tld/app.tld" prefix="loginChk" %>

<!-------------------------------------------------------->
<!-- 로그인이 되어 있는지 확인 (로그인 해야 볼수 있는 페이) -->
<!-------------------------------------------------------->
<loginChk:IsLogin refer="/yfarm/goods/cart.jsp"/>


1. taglib을 위한 tld 파일(app.tld)

<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE taglib  PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
  "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
  <tlibversion>1.0</tlibversion>
  <jspversion>1.1</jspversion>
  <shortname>Application Tag Library</shortname>
  <uri>http://jakarta.apache.org/taglibs/struts-example-1.0</uri>
  <info>
    Example Application.
  </info>
  <tag>
    <name>IsLogin</name>
    <tagclass>login.IsLogin</tagclass>
    <bodycontent>empty</bodycontent>
    <info>
          로그인 체크를 위한 커스텀 태그 용 TLD 파일
    </info>
    <attribute>
      <name>name</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
      <name>page</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>     
    </attribute>
    <attribute>
      <name>refer</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>     
    </attribute>
  </tag>
</taglib>



2. 다음은 로그인을 했는지를 검사하는 IsLogin.java 입니다.

package login;

import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

import yfarm.Constants;


public final class IsLogin extends TagSupport {
        private String name = yfarm.Constants.USER_KEY;
        private String page = "/index.jsp";
        private String refer = null;
       
        public String getRefer() {
            return refer;
        }
       
        public void setRefer(String refer) {
            this.refer = refer;
        }
       
        public String getName() {
                return (this.name);
        } 

        public void setName(String name) {
                this.name = name;
        }

        public String getPage() {
                return (this.page);
        }

        public void setPage(String page) {
                this.page = page;
        }

        public int doStartTag() throws JspException {
                return (SKIP_BODY);
        }

        public int doEndTag() throws JspException {
            // Is there a valid user logged on?
            boolean isLogin = false;
            HttpSession session = pageContext.getSession();
            if ((session != null) && (session.getAttribute(name) != null)) {
                isLogin = true;           
            }
 

            // Forward control based on the results
            if (isLogin)
                return (EVAL_PAGE);  //JSP 페이지의 다음을 수행
            else {
                try {
                    pageContext.getOut().println("<script>");
                    pageContext.getOut().println("alert('로그인을 하셔야 합니다.');");
                    pageContext.getOut().println("location.href='/yfarm/main/login.jsp?uri=" + refer + "'");
                    pageContext.getOut().println("</script>");
                   
                    session.invalidate();
                   
                    //pageContext.forward(page);
                } catch (Exception e) {
                    throw new JspException(e.toString());
                }
                return (SKIP_PAGE);  //JSP 페이지의 다음을 스킵
            }
        }

        /**
        * Release any acquired resources.
        */
        public void release() {
            super.release();
            this.name = Constants.USER_KEY;
            this.page = "/index.jsp";
        }
}

2013년 8월 6일 화요일

다중 애플리케이션(Struts Multi-Application)

다중 애플리케이션(Multi-Application)


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)   
 스트럿츠 1.1이상에서는 다중 애플리케이션 사용이 가능 합니다.

애플리케이션의 모듈이 동일한 웹애플리케이션의 일부 이지만 서로 독립적입니다.

다중 애플리케이션을 사용하는 이유는 업무를 좀 더 조직화, 세분화 할 수 있다는 장점이 있습니다.

쇼핑몰을 개발하는데 상품의 디스플레이 부분과 쇼핑카트를 구현 하는 부분을 별도의 다중 애플리케이션으로 구성 하는 것이 가능 합니다. 이렇게 하는 이유는 상호 독립적이고 수평적인 개발이 가능하도록 하기 위해서 입니다.


기본 애플리케이션이 아닌 모듈은 config/ 로 시작 합니다.

config/ 다음에 오는 부분은 애플리케이션 모듈의 접두어가 되며 프레임웍 전반을 걸쳐클라이언트의 요청을 처리하는데 사용 됩니다.

아래에 간략히 방법을 설명 하고 예제를 만들어 보도록 합니다.
(이클립스에서 톰캣 애플리테이션으로 Login이라는 프로젝트를 작성 후… 별도의 test라는 독립된 애플리케이션을 만들려고 합니다.)

1.        웹 애플리테이션의 web.xml 파일에 다중 애플리케이션을 위한 설정을 합니다.

<servlet>
          <servlet-name>action</servlet-name>
          <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
          <init-param>
                        <param-name>config</param-name>
                        <param-value>/WEB-INF/struts-config.xml</param-value>
          </init-param>
          <init-param>
                  <param-name>config/test</param-name>
                  <param-value>/WEB-INF/struts-test-config.xml</param-value>
          </init-param>
          <load-on-startup>1</load-on-startup>               
        </servlet>


2.        이번에 어떻게 모듈(애플리케이션)을 Switch하는지 알아 봅니다.

두 가지의 큰 방법이 있는데 아래와 같습니다.

-        forward를 이용하는 방법

struts-config.xml에서 test 애플리케이션으로 스위칭을 하기 위해서 forward를 이용합니다.

유심히 볼 부분은 contextRelative가 true가 되어 있다는 것이다. 이 값은 하나의 웹 애플리테이션을 사용 하는 경우에는 false(path 설정 시 기준을 애플리케이션을 기준으로)  이지만 다중 웹 애플리케이션을 사용 하기 위해서는 true(path 설정 시 기준이 context가 기준)로 설정 합니다.

즉 아래에서 test 라는 또 하나의 애플리케이션을 가리킬 때 /test/mysubmit과 같이 컨텍스트를 기준으로 경로를 사용 했습니다. (현재 톰캣 프로젝트를 하나 만들었죠^^ Login 이라는 것을…)

<struts-config>
...
<global-forwards>
<forward name="toModuleB"
contextRelative="true"
path="/test/mysubmit"
redirect="true"/>
...
</global-forwards>

</struts-config>



- org.apache.struts.actions.SwitchAction를 이용하는 방법

<action-mappings>
<action path="/toModule"
type="org.apache.struts.actions.SwitchAction"/>
...
</action-mappings>



이제 예제를 만들어 보도록 하겠습니다. 예제는 개념을 익히기 위해 최대한 간단히 작성 했습니다.


[처리흐름]

Login이라는 톰캣 프로젝트(웹애플리케이션)를 하나 만들고 별도의 독립적인 test라는 애플리케이션을 만들어 struts-config.xml과는 별도로 struts-test-config.xml을 만들어 보겠습니다. (물론 둘은 업무적으로 어떤 연관성을 가지지는 않고 있습니다. 예문에서는 단지 다중 애플리케이션을 설정하고 로딩 하는 것만 살펴 볼테니까요…)

사용자가 /Login/login.jsp를 실행 합니다.

실행 화면은 다음과 같습니다. (간단히 ID와 PASSWORD만 입력 받고 submit 버튼을 누릅니다.)

 

Submit 버튼을 누르면 이 액션을 /toTest라는 path로 넘어갑니다. 이 요청을 우선 Login 애플리케이션에서 받습니다.

<action
                path="/toTest"
                type="login2.toTest"
                validate="false" 
                name="loginForm"             
        />

위와 같이 설정이 되어 있습니다. 그래서 login2.toTest 라는 클래스가 실행을 하겠죠…

toTest.java 에서는 간단히 위에서 설명한 2번 방법대로 forward를 이용하여 test라는 애플리케이션으로 스위칭을 해 버립니다.

public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
                               
                //sub application인 test로 버네기 위해 forward 이용
                return (mapping.findForward("toTest"));
               
        }

위에서 return (mapping.findForward("toTest")); 부분의 처리를 위해 당연히 “toTest” 라는 forward가 있어야 겠죠^^

메인 설정 파일인 struts-config.xml에서 아래와 같이 정의하고 있습니다.

<forward name="toTest"
                contextRelative="true"
                path="/test/mysubmit.do"
                redirect="true"/>


이제 제어가 /test/mysubmit.do라는 액션으로 인해 test 라는 애플리케이션으로 넘어 가게 됩니다. 물론 위의 /test/mysubmit.do 는 struts-test-config.xml에서 정의를 하고 있습니다. 그 설정 내용은 다음과 같습니다.

<action-mappings>           
        <!-- 현재의 설정 파일은 struts-test-config.xml 이므로... path에 "/test/mysubmit" 아님을 주의! -->
        <action
                path="/mysubmit"   
                type="login2.Welcome2"   
                validate="false"                 
        />
         
    </action-mappings>


이제는 login2.Welcom2라는 클래스가 실행 되겠죠^^

그 내용은 단순히 result.jsp로 포워딩 시키는 일을 합니다.

요기까지 입니다.

그럼 이젠 전체 소스를 확인 하도록 하죠….

====================================================================


-------------------------------
/Login/test/login.jsp
-------------------------------
<%@ page pageEncoding="euc-kr" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<html>
<body>

<html:form action="/toTest" focus="id">
        <table>             
                <tr>                       
                        <th align="right">ID</th>                                             
                        <td><html:text property="id" value=""/></td>
                </tr>
                <tr>
                        <th align="right">PASSWORD</th>                                             
                        <td><html:password property="pwd" redisplay="false"/></td>
                </tr>
                <tr>                     
                        <th></th>
                        <td>
                            <html:submit/>
                            <html:reset/>                             
                        </td>
                </tr>                               
        </table>
</html:form>
</body>
</html>


-------------------------------
/WEB-INF/struts-config.xml
-------------------------------

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
     
    <!-- ========== Form Bean Definitions ================================== -->
    <form-beans>
        <form-bean name="loginForm" type="login2.LoginForm">                 
            <form-property name="pwd" type="java.lang.String" />
            <form-property name="id" type="java.lang.String" />           
        </form-bean>           
    </form-beans>
   
 
    <!-- ========== Global Forward Definitions =============================== -->
    <global-forwards>
        <forward name="toTest"
                contextRelative="true"
                path="/test/mysubmit.do"
                redirect="true"/>
    </global-forwards>
   
    <!-- ========== Action Mapping Definitions =============================== -->
    <!-- valiedate를 true라고 함으로써 LoginForm의 validate가 호출 됩니다.            -->
    <action-mappings>           
        <action
                path="/toTest"
                type="login2.toTest"
                validate="false" 
                name="loginForm"             
        />         
    </action-mappings> 
       
</struts-config>



-------------------------------
/WEB-INF/struts-test-config.xml
-------------------------------

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
   
    <!-- ========== Global Forward Definitions =============================== -->
    <global-forwards>
        <forward name="success" path="/result.jsp"/>
    </global-forwards>
   
    <action-mappings>           
        <!-- 현재의 설정 파일은 struts-test-config.xml 이므로... path에 "/test/mysubmit" 아님을 주의!  메인 애플리케이션의 foreard에 기술한 /test/mysubmit에 의해 아래의 매핑과 연결됨, 결국 login2.Welcom2가 실행됨-->
        <action
                path="/mysubmit"   
                type="login2.Welcome2"   
                validate="false"                 
        />
         
    </action-mappings>                         
</struts-config>


-------------------------------
/WEB-INF/src/login2/toTest.java
-------------------------------
package login2;

import org.apache.struts.action.Action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;


public class toTest extends Action {       
       
        public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
                               
                //sub application인 test로 보내기 위해 forward 이용
                return (mapping.findForward("toTest"));
               
        }
}


-------------------------------
/WEB-INF/src/login2/Welcome2.java
-------------------------------
package login2;

import org.apache.struts.action.Action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import login2.Constants;

public class Welcome2 extends Action {       
       
        public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
                               
                //성공적으로 처리 되었음, test 애플리케이션의 result.jsp로 보내버림...                return (mapping.findForward(Constants.SUCCESS));
               
        }
}




-------------------------------
/Login/test/result.jsp
-------------------------------
OK~ 

2013년 8월 5일 월요일

ORACLE DataBase Buffer Cache Tuning

DataBase Buffer Cache의 튜닝


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의) 
 www.onjprogramming.co.kr 


 데이터베이스 버퍼 캐시는 데이터 처리를 위해 사용되는 부분이며 가장 최근에 사용 되어진 DB 블록을 저장하고 있는 SGA의 구성 요소 입니다. 말그대로 버퍼 캐시이므로 수향 속도와 밀접한 관계가 있습니다. 최근에 사용되어진 데이터를 메모리에 보관해 추후 질의시 이를 이용하여 디스크에서 직접 데이터를 가지고 오지 않고 메모리에서 읽어 오므로 성능의 향상을 꽤 할 수 있는 겁니다. 이 곳에는 변경되지 않은 데이터 뿐 아니라 변경된 데이터도 가지고 있습니다. 또한 DataBase Buffer Cache는 chain list, dirty list, LRU list로 구성 되어져 있습니다. 오라클의 백그라운드 프로세스인 DBWR는 FREE BUFFER의 확보를 위해 변경된 데이테베이스 블록을 디스크(데이터베이스 파일)에 기록하는 역할을 합니다.

 DataBase Buffer Cache의 BUFFER는 LRU list와 dirty list로 구성되는데 LRU list의 버퍼들은 Free buffer, Pinned Buffer, Dirty Buffe중 하나로 존재하게 됩니다. 처음엔 버퍼가 free 상태인데 사용자가 질의를 해서 디스크에서 테이블의 내용을 읽으면 이 블록들은 LRU에서 가장 최근에 읽은 것이므로  HEADER 부분(MRU, Most recently used)에 위치하게 됩니다. 이 버퍼들이 차츰 다른 테이블의 내용들이 읽혀 짐에 따라 LRU의 tail부분인 LRU(Lease Recent Used)로 이동되게 되는 겁니다. 만약 사용자가 대량의 데이터를 질의하여 버퍼가 필요한데 빈 버퍼가 없다면 제일 사용된 빈도가 작은 블록을 찾기 위해 LRU 알고리즘에 의해 LRU list의 맨 끝인 tail 부분부터 검색하기 시작 합니다.

 LRU list의 작 버퍼에 대해 살펴 보면 Pinned Buffer는 현재 사용자가 사용중이므로 재사용 될 수 없는 상태이며 Free Buffer는 dirty buffer등이 데이터파일(디스크)에 기록되어져서 free로 mark가 되어 사용될 수 있는 상태의 버퍼 입니다. 또는 modify 되지않아 사용가능 한 상태를 나타 냅니다. 그리고 dirty buffer는 사용자가 사용하여 내용이 변경되었지만 아직 디스크에 기록되지 않은 버퍼를 나타냅니다.

LRUW(dirty list)는 서버 프로세스에 의해 모아진 dirty buffer들이 모여 있는 곳 입니다. 이 dirty buffer들은 오라클 프로세스들이 빈 버퍼(free buffer)를 찾기 위해 LRU의 tail 부분부터 찾아 가다가 dirty buffer를 만나면 LRUW(dirty list)에 옮겨 놓게 되는 겁니다. 이 버퍼들은 추후 DBWR에 의해 디스크에 있는 데이터파일에 기록되고 다시 free로 mark 되어 LRU list에 자게 되는 것입니다.

이번에는 버퍼 캐시의 튜닝에 대해 알아 보겠습니다.

 버퍼 캐시에 대한 hit ratio는 논리적인 IO와 물리적인 IO에 대한 비율을 의미하며 DataBase Buffer Cache의 성능을 측정 하기 위한 주요한 척도가 됩니다. DataBase Buffer  Cache의 hit ratio는 V$sysstat에서 DB BLOCK GETS와 CONSISTENT GETS, physical reads 값으로 구해지는데 DB BLOCK GETS와 CONSISTENT GETS는 logical read를 의미하며 메모리상의 버퍼에서 access되는 블록을 뜻합니다. Physical reads는 디스크에서 읽는 것을 나타내며 데이터파일에서 로딩되는 블록의 수를 나타냅니다.

 Hit ratio는 90%이상을 유지하는 것이 좋으며 70% 이하기 되었을 때는 db_block_buffers 또는 유_cache_size를 증가 시키는 것이 바람직 합니다. 과거의 Oracle7,8에서는 아래처럼 hit ratio를 구했습니다.

                            (physical reads)
    Hit ratio = ---------------------------------
                          (consistent reads + db_block_gets)

SQL> conn / as sysdba
연결되었습니다.
SQL> select trunc((1-(phy.value/(curr.value + consis.value))) * 100,5)
  2      from v$sysstat phy, v$sysstat curr, v$sysstat consis
  3      where phy.name = 'physical reads'
  4    and curr.name = 'db block gets'
  5      and consis.name = 'consistent gets'
  6  /

하지만 Oracle 8i, 9i에서는 좀더 정확한 값을 구하기 위해 아래처럼 physical reads direct + physical reads direct(lob)를 포함 합니다.

SQL> set serveroutput on
SQL> declare
  2    physicalreads number;
  3    physicalreadsdirect number;
  4    physicalreadsdirectlob number;
  5    dbblockgets number;
  6    consis number;
  7    hratio number;
  8  begin
  9    select value into physicalreads from v$sysstat where name = 'physical r
ads';
 10    select value into physicalreadsdirect from v$sysstat where name = 'phys
cal reads direct';
 11    select value into physicalreadsdirectlob from v$sysstat where name = 'p
ysical reads direct (lob)';
 12    select value into dbblockgets from v$sysstat where name = 'db block get
';
 13    select value into consis from v$sysstat where name = 'consistent gets';
 14    select 100 * (1- (physicalreads - (physicalreadsdirect + physicalreadsd
rectlob))
 15                      /(dbblockgets + consis - physicalreadsdirect -physical
eadsdirectlob )) into hratio
 16          from dual;
 17          dbms_output.put_line('DB Buffer Cache Hit Ratio : ' || hratio);
 18  end;
 19  /