계속 sqlplus가 cpu 100%를 써먹는 상황이 발생하였다.
strace로 확인해 보니, 알 수 없게도.. 특정 파일을 못 읽는 부분 발생하였다..

서버 uptime 200일이 지나면 생기는 버그였는데. 이것을 해결하기 위해서는 다음의 방법을 사용한다.

1. 10g R2(10.2.0.4) client로 업그레이드 하기.
2. OS 64bit버전이라면 64bit버전 client로 업그레이드 하기

'DB' 카테고리의 다른 글

Statement, PreparedStatement 성능 비교  (0) 2009.08.13
Delete와 Truncate의 차이점  (0) 2009.07.23
Mysql 테이블 복제 하기  (0) 2009.07.20
오라클에서 rownum은 Mysql의 Limt과 같은 기능  (0) 2009.07.20
mysql 복제하기  (0) 2009.07.06
Posted by '김용환'
,

Mysql 테이블 복제 하기

DB 2009. 7. 20. 15:39


1) create table .. as select...
이렇게 했더니, 복사만 되고, 업데이트, 추가가 되지 않는다.

2) create table,
    insert into...
이렇게 사용해야 제대로 복사가 된다..


 

Posted by '김용환'
,

오라클의 rownum을 이용하면  mysql  limit과 비슷한 효과를 가질 수 있다.

http://www.oracle.com/technology/global/kr/oramag/oracle/06-sep/o56asktom.html

하지만 아래와 같이 대충 쓰면 사용할 수 없다.
(X)
SELECT sid, user_id, user_pwd, changer_empno, changer_name, change_date, use_start_date, use_end_date, encode_yn        
FROM dbmsuserlist      
where rownum between '10' and '20'    
order by sid, user_id  


아래와 같이 from문에 감싸서 사용해야 한다.

(0)
 SELECT A.sid, A.user_id, A.user_pwd, A.changer_empno, A.changer_name, A.change_date, A.use_start_date, A.use_end_date, A.encode_yn        
FROM (select rownum rnum,  dbmsuserlist.* from dbmsuserlist order by sid, user_id ) A  
WHERE  A.rnum between '11' and '20'      
          
   
                             

'DB' 카테고리의 다른 글

Oracle Client 10g 무한 루프 현상  (0) 2009.07.22
Mysql 테이블 복제 하기  (0) 2009.07.20
mysql 복제하기  (0) 2009.07.06
[Mysql] To connect without /usr/local/mysql/tmp/mysql.sock  (0) 2009.05.08
MERGE INTO Statement  (0) 2009.04.25
Posted by '김용환'
,

mysql 복제하기

DB 2009. 7. 6. 10:24
Posted by '김용환'
,

After I installed mysqld (mysql server), I have met frustrated situation.
When I try to connect mysql server to mysql (default client) by using root, there are some a error message shown on termial. 

Mysql have launched to socket file is used to connect mysql client.

[handbs310:/root]# ./mysqld/bin/mysql -uroot -p
Enter password: 
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

But, I can connect the mysql server by using below command.

./mysqld/bin/mysql -uroot -S /usr/local/mysql/tmp/mysql.sock -p

so, I have to change that, because of bothering. 

To solve the uncomfortable things, there is need to take two steps.

1) Create a symbolic link 

ln -s /home1/irteam/db/mysql/tmp/mysql.sock /tmp/mysock.sock
lrwxrwxrwx  1 root root 37  5¿ù  8 18:20 /tmp/mysock.sock -> /home1/irteam/db/mysql/tmp/mysql.sock


2) Change configuration
[client]
#socket = /usr/local/mysql/tmp/mysql.sock
socket = /tmp/mysql.sock

#default-character-set = utf8
[mysqld]
user    = irteam
port    = 3306
basedir = /usr/local/db/mysql
datadir = /usr/local/db/mysql/data
tmpdir  = /usr/local/db/mysql/tmp
#socket  = /home1/irteam/db/mysql/tmp/mysql.sock
socket  = /tmp/mysql.sock


After taking two steps, kill mysql daemon, and restart it.
Then, You will connect without given -S option by using default mysql client.

 mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.0.40-log MySQL NHN MAX Version

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> Bye

'DB' 카테고리의 다른 글

오라클에서 rownum은 Mysql의 Limt과 같은 기능  (0) 2009.07.20
mysql 복제하기  (0) 2009.07.06
MERGE INTO Statement  (0) 2009.04.25
오라클 Fast Connection Failover  (0) 2009.04.22
checkng(or seeing) oracle jdbc driver(ojdbc.jar) version  (0) 2009.04.22
Posted by '김용환'
,

MERGE INTO Statement

DB 2009. 4. 25. 15:16
I think Merge statement is not standard, but I was wrong.  It was officially introduced in the SQL:2003 standard. In mysql, there is no statement like merge, but have similar statement "replace".

Let's look at merge statement and stduy.
(Reference :http://en.wikipedia.org/wiki/Merge_(SQL)) - until the oracle 9i
MERGE INTO table_name1 USING table_name2 ON (condition
  WHEN MATCHED THEN
  UPDATE SET column1 = value1 [, column2 = value2 ...]
  WHEN NOT MATCHED THEN
  INSERT (column1 [, column2 ...]) VALUES (value1 [, value2 ...])


If a record exist, you want to update it, and if the record does not exist, you want to insert the record. To do this, merge statement is introduced.


In oracle show examples.  (http://www.oracle.com/technology/products/oracle9i/daily/Aug24.html)

Without Merge statement, it will be shown belows. It is used to use in Oracle 8.

UPDATE
     (SELECT
        S.TIME_ID ,S.STORE_ID ,S.REGION_ID,
        S.PARTS s_parts ,S.SALES_AMT s_sales_amt ,S.TAX_AMT s_tax_amt ,S.DISCOUNT s_discount,
        D.PARTS d_parts ,D.SALES_AMT d_sales_amt ,D.TAX_AMT d_tax_amt ,D.DISCOUNT d_discount
     FROM SALES_JUL01 S, SALES_FACT D
     WHERE D.TIME_ID = S.TIME_ID
      AND D.STORE_ID = S.STORE_ID
      AND D.REGION_ID = S.REGION_ID)
JV
       SET d_parts = d_parts + s_parts,
          d_sales_amt = d_sales_amt + s_sales_amt,
          d_tax_amt = d_tax_amt + s_tax_amt,
          d_discount = d_discount + s_discount
;
INSERT INTO SALES_FACT (
     TIME_ID,STORE_ID ,REGION_ID,
     PARTS ,SALES_AMT ,TAX_AMT ,DISCOUNT)
     SELECT
       S.TIME_ID ,S.STORE_ID ,S.REGION_ID,
       S.PARTS ,S.SALES_AMT ,S.TAX_AMT ,S.DISCOUNT
     FROM SALES_JUL01 S
     WHERE (S.TIME_ID, S.STORE_ID, S.REGION_ID) NOT IN (
       SELECT        D.TIME_ID, D.STORE_ID, D.REGION_ID
       FROM SALES_FACT D
       )
     ;

It is very long sentences and verbosely.
So, in Oracle 9 introduce Merge statement. Upper statements changed to belows in ussing merge.

MERGE INTO SALES_FACT D
     USING SALES_JUL01 S
     ON (D.TIME_ID = S.TIME_ID
        AND D.STORE_ID = S.STORE_ID
        AND D.REGION_ID = S.REGION_ID)
     WHEN MATCHED THEN
    UPDATE
     SET d_parts = d_parts + s_parts,
          d_sales_amt = d_sales_amt + s_sales_amt,
          d_tax_amt = d_tax_amt + s_tax_amt,
          d_discount = d_discount + s_discount
      WHEN NOT MATCHED THEN
     INSERT (D.TIME_ID ,D.STORE_ID ,D.REGION_ID,
        D.PARTS ,D.SALES_AMT ,D.TAX_AMT ,D.DISCOUNT)
     VALUES (
        S.TIME_ID ,S.STORE_ID ,S.REGION_ID,
        S.PARTS ,S.SALES_AMT ,S.TAX_AMT ,S.DISCOUNT);


It is very simple, easy to undestand.

There is advancements and enhancements on the merge statement in Oracle 10g.

1) Optional insert and update

-- No matched clause, insert only.
MERGE INTO test1 a
  USING all_objects b
    ON (a.object_id = b.object_id)
  WHEN NOT MATCHED THEN
    INSERT (object_id, status)
    VALUES (b.object_id, b.status);

-- No not-matched clause, update only.
MERGE INTO test1 a
  USING all_objects b
    ON (a.object_id = b.object_id)
  WHEN MATCHED THEN
    UPDATE SET a.status = b.status;



2) Conditional clause
After to update or delete statement after WHEN MATCHED THEN or WHEN NOT  MATCHED THEN  clause   can have where clauses.

With Oracle 10g, we can can now apply additional conditions(WHERE) to the UPDATE or INSERT operation within a MERGE. It is extremely useful if we have different rules for when a record is updated or inserted but we do not wish to restrict the ON condition that joins source and target together.
-- Both clauses present.
MERGE INTO test1 a
  USING all_objects b
    ON (a.object_id = b.object_id)
  WHEN MATCHED THEN
    UPDATE SET a.status = b.status
    WHERE  b.status != 'VALID'
  WHEN NOT MATCHED THEN
    INSERT (object_id, status)
    VALUES (b.object_id, b.status)
    WHERE  b.status != 'VALID';

-- No matched clause, insert only.
MERGE INTO test1 a
  USING all_objects b
    ON (a.object_id = b.object_id)
  WHEN NOT MATCHED THEN
    INSERT (object_id, status)
    VALUES (b.object_id, b.status)
    WHERE  b.status != 'VALID';

-- No not-matched clause, update only.
MERGE INTO test1 a
  USING all_objects b
    ON (a.object_id = b.object_id)
  WHEN MATCHED THEN
    UPDATE SET a.status = b.status
    WHERE  b.status != 'VALID';


3) Deleting  during merging

You can delete conditionally DELETE rows during an UPDATE operation.

MERGE INTO test1 a
  USING all_objects b
    ON (a.object_id = b.object_id)
  WHEN MATCHED THEN
    UPDATE SET a.status = b.status
    WHERE  b.status != 'VALID'
  DELETE WHERE (b.status = 'VALID');


* examples are referenced on http://www.oracle-base.com/articles/10g/MergeEnhancements10g.php

Posted by '김용환'
,

오라클에서 제공하는 Fast connection Failover는 jdbc 3.0 스펙인 connection pooling과 연관이 있어 보인다. Fast connection failover에 대한 간략한 내용은 아래와 같다.

FCF를 사용하면, connection을 캐시에 저장에 저장합니다. 어떤 db RAC이벤트를 생성하고 JDBC에 연결된 JVM에 전달이 됩니다.

JVM의 데몬 쓰레드가 RAC 이벤트를 받고, Connection Cache Manager에 전달한다고 합니다. JVM에서는 connection을 정리하고 다른 node로 접속 시도를 하게 된다고 한다.


How It Works

Under Fast Connection Failover, each connection in the cache maintains a mapping to a service, instance, database, and hostname.

When a database generates a RAC event, that event is forwarded to the JVM in which JDBC is running. A daemon thread inside the JVM receives the RAC event and passes it on to the Connection Cache Manager. The Connection Cache Manager then throws SQL exceptions to the applications affected by the RAC event.

A typical failover scenario may work like this:

  1. A database instance fails, leaving several stale connections in the cache.

  2. The RAC mechanism in the database generates a RAC event which is sent to the JVM containing JDBC.

  3. The daemon thread inside the JVM finds all the connections affected by the RAC event, notifies them of the closed connection through SQL exceptions, and rolls back any open transactions.

  4. Each individual connection receives a SQL exception and must retry.


인용
http://download.oracle.com/docs/cd/B19306_01/java.102/b14355/fstconfo.htm#CIHECJIJ


실제 테스트 환경은 다음의 동영상에서 확인가능하다.



이 기능을 사용하려면 오라클 서버에서 작업이 필요하며..(DB Server는 connection cache, ONS(Oracle Notification Service) 사용하도록 해야함)
자바 에서 쓰려면 다음과 같이 해야 한다.

DB Client는 이렇게..

ods.setConnectionCachingEnabled(true);

ods.setFastConnectionFailoverEnabled(true):

java실행시 -Doracle.jdbc.FastConnectionFailover  프로퍼티를 줄 것




소스를 보면 좀 명쾌한데.

OracleDataSource.java 안에 쓰레드 생성에 대한 설정 부분이 들어가 있다. 
    public synchronized void setFastConnectionFailoverEnabled(boolean flag)
        throws SQLException
    {
        if(connCachingEnabled)
        {
            if(!fastConnFailover)
            {
                fastConnFailover = flag;
                setSpawnNewThreadToCancel(flag);
            } else
            if(!flag)
                DatabaseError.throwSqlException(255);
        } else
        {
            DatabaseError.throwSqlException(137);
        }
    }



 private void setSpawnNewThreadToCancel(boolean flag)
    {
        if(flag)
        {
            if(connectionProperties == null)
                connectionProperties = new Properties();
            connectionProperties.setProperty("oracle.jdbc.spawnNewThreadToCancel", "true");
        } else
        if(connectionProperties != null)
            connectionProperties.remove("oracle.jdbc.spawnNewThreadToCancel");
    }






private static final boolean fastConnectionFailoverSysProperty = "true".equalsIgnoreCase(OracleDriver.getSystemPropertyFastConnectionFailover("false"));

    void processFastConnectionFailoverSysProperty()
    {
        if(isOracleDataSource && fastConnectionFailoverSysProperty)
        {
            connCachingEnabled = true;
            if(cacheManager == null)
                try
                {
                    cacheManager = OracleConnectionCacheManager.getConnectionCacheManagerInstance();
                }
                catch(SQLException sqlexception) { }
            fastConnFailover = true;
            setSpawnNewThreadToCancel(true);
        }
    }




OracleDriver.java안에는 이런 코드가 있다. 즉 시스템  프로퍼티 (oracle.jdbc.FastConnectionFailove)을 보고 실행할지를 결정한다.
    public static String getSystemPropertyFastConnectionFailover(String s)
    {
        return getSystemProperty("oracle.jdbc.FastConnectionFailover", s);
    }


내부적으로 보면,  OracleConnectionCacheManager 를 생성하는데, 이 클래스에는 한 쓰레드(OracleFailoverEventHandlerThread)가 돌아서 이상시 이벤트를 던지도록 하는 녀석이 존재한다.
이 쓰레드가 connection에 대한 부분에 대해서 실패시 event를 날리고, event를 받은 녀석은 connection을 실패할 때, RAC로 표현된 다른 URL 로 connection을 하게 된다.

    public void createCache(String s, OracleDataSource oracledatasource, Properties properties)
        throws SQLException
    {
        if(oracledatasource == null || !oracledatasource.getConnectionCachingEnabled())
            DatabaseError.throwSqlException(137);
        if(s == null)
            DatabaseError.throwSqlException(138);
        if(m_connCache.containsKey(s))
            DatabaseError.throwSqlException(140);
        boolean flag = oracledatasource.getFastConnectionFailoverEnabled();
        if(flag && failoverEventHandlerThread == null)
        {
            final String onsConfigStr = oracledatasource.getONSConfiguration();
            if(onsConfigStr != null && !onsConfigStr.equals(""))
                synchronized(this)
                {
                    if(!isONSInitializedForRemoteSubscription)
                    {
                        try
                        {
                            AccessController.doPrivileged(new PrivilegedExceptionAction() {

                                public Object run()
                                    throws ONSException
                                {
                                    ONS ons = new ONS(onsConfigStr);
                                    return null;
                                }

                            }
);
                        }
                        catch(PrivilegedActionException privilegedactionexception)
                        {
                            DatabaseError.throwSqlException(175, privilegedactionexception);
                        }
                        isONSInitializedForRemoteSubscription = true;
                    }
                }
            failoverEventHandlerThread = new OracleFailoverEventHandlerThread();
        }
        OracleImplicitConnectionCache oracleimplicitconnectioncache = new OracleImplicitConnectionCache(oracledatasource, properties);
        oracleimplicitconnectioncache.cacheName = s;
        oracledatasource.odsCache = oracleimplicitconnectioncache;
        m_connCache.put(s, oracleimplicitconnectioncache);
        if(flag)
            checkAndStartThread(failoverEventHandlerThread);
    }
Posted by '김용환'
,

Oracle provides the various version of oracle jdbc driver to java developers. But, released jdbc drivers' name are always ojdbc14.jar. 

If you try to run java to see manifest file, you may be failed.
$ java -jar ojdbc14.jar
Failed to load Main-Class manifest attribute from
ojdbc14.jar

So, to know those version. there are 2 measures to check it.

1) Unzip and see MANIFEST.MF in ojdbc14.jar

Manifest-Version: 1.0
Specification-Title: "Oracle JDBC driver classes for use with JDK1.4"
Specification-Version: "Oracle JDBC Driver version - 9.0.2.0.0"
Specification-Vendor: "Oracle Corporation" .
Implementation-Title: "ojdbc14.jar"
Implementation-Version: "Oracle JDBC Driver version - 9.0.2.0.0"
Implementation-Vendor: "Oracle Corporation"
Implementation-Time: "Thu Apr 25 23:14:02 2002"


2) Java coding 

DriverManager.registerDriver (new oracle.jdbc.driver.OracleDriver());

Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@123.345.321.121:231:SID","ID","PASS");

DatabaseMetaData meta = conn.getMetaData ();

System.out.println("Database Product Name  : " + meta.getDatabaseProductName());

System.out.println("Database Product Version :  " + meta.getDatabaseProductVersion());

System.out.println("JDBC Driver Name :" + meta.getDriverName());

System.out.println("JDBC Driver Version : " + meta.getDriverVersion());


3) From the ojdbc14.jar in oracle 11g, you can use below method to verify the version.
java jar ojdbc6.jar


In result, there is need to know the version of ojdbc14.jar, you have to rename the name of jar like ojdbc14-10.0.2.jar. It is easy to understand 

'DB' 카테고리의 다른 글

MERGE INTO Statement  (0) 2009.04.25
오라클 Fast Connection Failover  (0) 2009.04.22
Dynamically creating table in ibatis  (0) 2009.04.21
오라클 10g jdbc driver 특징 중 Fast Connection Fail-Over  (0) 2009.04.10
오라클 메가진  (0) 2009.04.09
Posted by '김용환'
,
Ibatis sqlclient provides "statement" tag to create table in dynamic. "Statement" tag are used in various way.

<ibatis xml file>
<?xml version="1.0" encoding="EUC-KR" standalone="no"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-2.dtd">

<sqlMap namespace="com.google.collector.test">
<statement id="createJavabasic" parameterClass="map" >
     CREATE TABLE exam_$tableid$ (
 logid int(11) NOT NULL auto_increment primary key,
 projectname varchar(30),
 disttype varchar(7),
 contents longtext,
 isSuccess char(1)
);
</statement>

<statement id="dropJavabasic" parameterClass="map" >
DROP TABLE IF EXISTS exam_$tableid$;
</statement>
</sqlMap>


<java code>
Map<String, String> map = new HashMap<String, String>();
map.put("tableid", "test");
sqlMap.queryForObject("com.google.com.test.createJavabasic", map);
Posted by '김용환'
,

우선 오라클 10g jdbc driver의 특징 중 하나인  Fast Connection Fail-Over에 대한 이야기다. 

출처는 다음과 같다. 

http://download.oracle.com/docs/cd/B19306_01/java.102/b14355/fstconfo.htm#CIHJBFhttp://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdbc_readme101020.html

1.   10g jdbc driver  특징

A.     Jdbc 3.0, j2ee 1.3 스펙 지원

                i.         Oracle 9ijdbc 3.0 지원

B.     Named Parameters in CallableStatement and PreparedStatement

C.     New Ref interface and Datalink

D.     J2EE Connector Architecture Resource Adapter

E.      Connection Pooling: see Implicit Connection Caching and Fast Connection Fail-Over

F.      Satement Pooling

G.     BLOB and CLOB update


Fast Connection Fail-Over입니다. RAC용이네요. 사용은 아래와 같이 메소드를 호출해야 한다고 하네요.

 

DB Client는 이렇게..

ods.setConnectionCachingEnabled(true);

ods.setFastConnectionFailoverEnabled(true):

 

DB Serverconnection cache, ONS(Oracle Notification Service) 사용하도록 미리 설정을 해야 하

 

RAC랑 연동할 수 있는 구조라고 합니다. FCF connection을 캐시하고 있다가 오라클 DB down 이 된 것을 dectection하고, 깨끗이 종료된 session을 정리 한다고 합니다. 그리고, 로드 밸런스 및 적절하기 리퀘스트를 분산시킨다고 적혀 있습니다.

DB에서 Application Event를 날려주는 모델입니다.

밑에 동영상보면, 저희가 오늘 하는 테스트랑 비슷하게 하네요.

 

원리

FCF를 사용하면, connection을 캐시에 저장에 저장합니다. 어떤 db RAC이벤트를 생성하고 JDBC에 연결된 JVM에 전달이 됩니다.

JVM의 데몬 쓰레드가 RAC 이벤트를 받고, Connection Cache Manager에 전달한다고 합니다. JVM에서는 connection을 정리하고 다른 node로 접속 시도를 하게 된다고 하네요.

Posted by '김용환'
,