이펙티브 오라클 (2008년)
클러스터링 이용 0 0 5,531

by 구루비스터디 GRID RAC 클러스터 [2009.04.30]


I. GRID/RAC 개념

1. GRID 개념

GRID 개념
  • 진공관의 음극과 양극 중간에서 전류의 흐름을 제어하는 '격자(格子)'에서 유래한 그리드는 인터넷 확산의 기폭제가 되었던 월드와이드웹(www)과 차세대 인터넷을 연결시켜 주는 징검다리
  • 미국 시카고대학 이안 포스터 컴퓨터공학과 교수가 창시했으며 한 번에 한곳에만 연결할 수 있는 웹과 달리 신경조직처럼 작동하는 인터넷망구조
  • PC나 서버, PDA 등 모든 컴퓨팅 기기를 하나의 네트워크로 연결해, 정보처리 능력을 슈퍼컴퓨터 혹은 그 이상의 수준으로 극대화하는 개념
  • 즉, 분산된 컴퓨팅 자원을 초고속네트워크로 모아 활용하는 개념


h.6 GRID 원리

  • 가상의 슈퍼컴퓨팅파워를 구축해 주는 범네트워크 원리
  • 세계 각지에 흩어져 있는 수억대의 PC와 첨단장비를 하나로 묶어서 제어하는 것
  • 이렇게 완성된 네트워크는 하나의 자원보다 수천, 수만배의 능력을 발휘할 수 있다.


GRID 목적
  • 거시적 관점
    • Gird는 4A를 목표로 추진되고 있다.
    • 4A란 지능화된 네트워크, 고성능 컴퓨터 및 장비, 첨단 애플리케이션, 고급 과학기술 등이 그것이다.
지능화된 네트워크광케이블- IPv6를 비롯해 고성능 미들웨어와 인공지능 브라우저가 포함되는 개념
고성능 컴퓨터 및 장비고속연산 및 정보처리가 가능한 컴퓨터와 초대용량 DB장치를 비롯해 생명공학(BT),
나노공학(NT),환경공학(ET)을 지원하는 가속기, 열분석기, 전자현미경 등 고가의 장비가 포함
첨단 애플리케이션그리드환경에서 적용할 수 있는 BT- NT- ET 그리고 몰입형가상현실(CAVE)과 같은 차세대 IT애플리케이션들
고급 과학기술그리드를 개발하고 구축하며 운영할 수 있는 인력의 양성


  • 기업의 관점
    • 저렴한 가격으로 기업의 인프라를 효율적으로 활용 할 수 있는 최적의 솔루션
    • 저비용 고효율을 강조하는 기업환경에서 오라클 GRID컴퓨팅 기술을 통해 저렴한 여러개의 서버를 연결시켜 하나의 커다란 서버로 활용가능
    • 기존에 서버도입을 할 때 고려하여왔던 최대접속량을 고려해 무리하게 서버를 구입할 필요가 없게 됨으로써 기업 경영의 최대 화두로 떠오른 비용절감을 실현시켜줄 수 있다.


  • Oracle에서의 GRID
    • Oracle 10g 에서의 g가 바로 GRID(Grid)의 g
    • 오라클의 GRID 컴퓨팅은 기업 내에 산재한 소형 서버들을 연결해 하나의 커다란 컴퓨터처럼 사용한다는 개념에 따라, 값비싼 대형 시스템을 도입할 필요가 없으며, 고성능을 유지하면서 대형 시스템보다 더욱 많은 자원을 활용할 수 있다는 점에서 비용절감을 위한 최적의 방안
    • 언제 어디서나 원하는 정보를 요청하거나 연산 작업을 수행할 수 있도록 하는 GRID 컴퓨팅은 자유로운 접속을 통해 데이터 파일을 공유, 복사, 전송이 가능해 지금까지 데이타 자원을 별도 관리해야 했던 복잡성과 유지보수에 따른 비용 낭비를 감소 시켜 줄 수 있다.
    • 원격 데이터 접속을 통해 애플리케이션을 어떠한 데이터베이스에서도 수행할 수 있으며 스케줄링과 자원 관리,오라클 리소스매니저 그리고 표준 GRID 환경,빠른 이식성을 제공한다.
    • 또한 관리 자동화로 인한 Oracle Database 10g 의 관리적 부담은 최상의 서비스를 제공하면서도, 비용은 감소시킬 수 있을 것이다.


2. RAC 개념

  • Oracle Real Application Cluster는 OPS(Oracle Parallel Server)의 후속 제품으로 개발되어 Oracle 9i 버전부터 적용되어 있다.

OPS(Oracle Parallel Server)란?

다수의 loosely coupled (clustering system :shared disk ) 또는 MPP system(shared nothing system)들간의
원활한 resource sharing을 위해 제공되는 dlm(distributed lock manager)을 이용하여 동시에 다수의 사용자가
어떤 node를 통하던지 한 database를 access함으로써 시스템의 가용성과 전체적인 성능을 극대화 시키기 위한 시스템이다.

과거 OPS를 사용하는 경우에는 노드간 데이터를 주고받는 핑에 의한 성능의 저하로, OPS의 설계를 잘못했을 경우
1+1=0.7로 되어버리는,즉 2대의 서버로 구축한 OPS 시스템이 하나의 시스템으로 운영하는 시스템보다 성능이
떨어지는 경우가 있었다. 그래서 어떤 경우에는 한 쪽 노드만을 사용하고,다른 쪽 노드는 장애 발생시에 Fail-over
하기 위한 용도로 사용하는 HotStandby 시스템으로 운영하기도 했다.

그러나 현재의 RAC(오라클9i,10g)에서는 이러한 제약사항이 많이 개선되었다.
과거의 OPS가 1+1=0.7이 되었다면 현재의 RAC은 1+1=1.8 정도의 확장성을 제공한다.

Oracle RAC와 OPS의 가장 큰 차이는 새로 추가된 캐시 결합 기능이다.
OPS에서는 한 노드에서 다른 노드로 데이타를 요청할 경우 해당 데이타를 먼저 디스크에 기록한 다음에야 요청 노드에서 데이타를
읽을 수 있다. 하지만 캐시 결합 기능을 사용할 경우 데이타는 잠금 상태를 거치지 않고 바로 전송된다.

이처럼 Oracle Clustering Solution은 노드간 캐시의 일치성을 보장하기 위한 서버간의 통신 방식을 디스크를 이용한 방식에서
초고속 인터커넥트를 이용한 캐시 퓨전(Cache Fusion)으로 변경하면서 획기적인 발전을 가져오게 되었다.


  • 동일 데이터베이스를 여러 인스턴스가 접근할 수 있다
  • 모든 노드가 동일한 데이터베이스에 접속가능하다
  • 데이터베이스 디스크는 모든 노드가 Database에 access를 허용하기 위해 전역으로 사용해야 한다.

MS-SQL Server와 Oracle Cluster 비교

1. MS-SQL Server

  • MS-SQL Server에서는 공유 스토리지가 사용되지 않는다.
  • 즉, 데이타를 전체적으로 공유하는 대신 여러 시스템에 분산시켜두는 연합클러스터 (federated cluster)라는 이름의 방식을 사용한다.

2. Oracle

  • 여러 노드가 동일 디스크 세트를 사용하여 데이타를 저장한다.
  • 데이타, 리두 로그, 제어 및 아카이브 로그 파일은 원시 디스크 장치의 공유 스토리지 또는 클러스터화된 파일 시스템에 보관된다.


3. RAC 장점

확장성
  • 일반적으로 많은 고객들이 용량을 고려하여 시스템을 구축하지만 시간의 흐름에 따라 데이터는 증가하고, 또한 사용자의 새로운 요구사항으로 신규 애플리케이션이 추가되어 시스템의 부하는 점점 커지게 된다.
  • 따라서 하나의 하드웨어에서 최대의 용량으로 증설하더라도 용량 부족 문제가 해결되지 않 는 경우가 종종 생기게 되는데 이렇게 되면 시스템 운영 중에 많은 돈을 투자하여 더욱 큰 시스템을 도입하고, 기존의 운영 중이던 시스템을 신규 시스템으로 이관하는 작업을 하게된다.



고가용성
  • 하나의 서버로 구성된 데이터베이스인 경우 서버에 돌발 장애가 발생하게 되면 장애에 대한 복구가 완료될 때까지 모든 서비스는 불가 하였다.
  • 그러나 RAC의 경우에는 하나의 서버에 장애가 발생하더라도 나머지 서버에서 지속적인 서비스를 제공할 수 있으므로 서비스를 중지 하지 않아도 된다.
  • 또한 RAC의 경우에는 HW의 유지 보수,패치 적용,업그레이드를 하는 경우에도 정지 없이 서비스를 제공할 수 있다.


II. RAC 구조 및 동작원리

1. RAC 구조

  • 물리적인 하나의 데이터베이스를 여러대의 서버가 공유하는 것 모든 노드들은 같은 데이터를 사용하게 되어 논리적으로는 하나의 데이터베이스를 이용한다.


RAC 구조

  • Storage Area Network 등으로 구성된 Shared Disk를 사용하여 여러대의 NODE가 Shared Disk를 공유
  • Shared Cache 기술을 이용하여 각각의 NODE가 데이터를 공유
  • Client는 여러대로 구성된 NODE중 특정 NODE로 Request를 보내어 서비스를 제공받는다.


노드 3개를 이용하여 RAC를 구성한 예

  • NODE 3개를 이용하여 RAC 환경을 구성한 예로서 각각의 NODE 에 별도의 오라클 Instance를 설치하여 구성한 예
  • 각각의 NODE에 오라클 Instance를 각각 설치 한 후 데이터 저장을 위한 Shared Disk를 이용하여 Datafile들을 공유하는 환경으로 Database를 구성하게 된다.
  • 각각의 NODE는 Cache Fusion 기능을 위해 NODE간 High-speed InterconnectNetwork 이 필수 요소. 이러한 InterconnectNetwork은 원활한 서비스를 위해 최소한 GigaNetwork 구성이 필수이다.


최적의 구성예

  • 위의 그림에서 보여주는 RAC 구성이 일반적으로 말하는 RAC의 최적화 구성이라고 할 수 있다.
  • 각각의 NODE의 LocalDisk에 Oracle Engine과 Archive Log를 두고 Shared Disk 부분에 Datafiles,Controlfiles, Redo Log Files,Spfile을 두는 구조입니다. Redo Log File을 Shared Disk에 두는 목적은 Database 복구를 위해 Redo Log File을 필요로 하게 되는데 이때 다른 Node에서 발생한 트랙잭션 정보가 담겨있는 Redo Log File을 공유함으로써 Database 복구가 필요한 경우 이를 신속히 복구하기 위함이다.


2. 동작원리

  • 위의 그림과 같이 각각 NODE의 Instance에는 CRS 와 CSS 데몬이 구동되게 된다.
  • 각각의 NODE에는 CRS(ClusterReady Service)데몬이 구동되어 기본적인 H/W의 Resource들을 관리하게 되며, CSS(ClusterSynchronization Service)데몬에 의해서 Oracle Instance 단에서의 복구 처리를 담당하게 된다.
  • 만약 이와 같은 데몬에 문제가 발생한다면 CRS,CSS 데몬은 RAC에서 가장 중요하면서도 기본이 되는 데몬이기 때문에 해당 데몬이 비정상적으로든 정상적으로든 종료되게 된다면 해당 데이터베이스는 종료되게 되며, 최악의 경우에는 해당 NODE가 Shutdown 되게 된다.


III. RAC 구성 시 고려사항

1. RAC 구조 내 오브젝트 관리


인스턴스별로 사용하는 오브젝트에 대한 파티션 나누기
  • 공유테이블 생성시 경합을 최소화 하기 위해 extent 를 인스턴스별로 할당한다.
  • 시퀀스 같이 공유하는 오브젝트의 캐시값을 증대시킨다.


LOCK의 배분을 조절(init.ora의 gc_files_to_lock, gc_rollback_segment 등)
  • 공유 오브젝트를 중점 관리 테이블스페이스에 집중화 하고, 이 테이블스페이스에 많은 LOCK을 할당한다.
  • 조회 위주의 데이터와 전혀 공유하지 않는 데이터(한 노드에서만 사용하는 데이터) 에는 LOCK을 최소화 한다.


동시에 같은 데이터를 액세스 하는 애플리케이션은 한 노드에서 수행하도록 하는 어플리케이션 파티셔팅
  • 동일한 어플리케이션은 같은 노드에서 수행하도록 배치한다.
  • 업무별로 그룹핑하여 노드간에 경합이 없도록 한다.\


2. 인스턴스 장애 시 복구 요구 시간 산정

  • 하나의 노드에 장애가 발생 했을때 얼마나 빠른 시간내에 서비스를 할수 있는가에 대한 요구사항을 기반으로 인스턴스 복구 시간을 고려해 구성해야 함.


3. 애플리케이션 서비스의 자동 복구 요구

  • 돌발 장애시에 만약 사용자가 모르는 사이 복구되기를 원한다면 TAF (Transportation Application Failover)와 CTF(Connection Time Failover)기능을 사용해야 한다.
  • 그러나 현재의 버전에서 조회를 하는 Application인 경우에만 TAF의 기능을 이용하여 Application의 수정 없이 Failover를 구현할 수 있다.
  • CTF는 장애 발생시 새로 접속하는 사용자가 가용한 노드로 자동으로 접속할 수 있도록 구성하는 것으로 이와 같이 TAF와 CTF를 통해 돌발 장애 시 서비스의 정지 없이 혹은 수초 내에 가용한 노드로 접속을 넘김으로써 시스템의 가용성을 극대화시킬 수 있다.


4. 자원의 효율적인 사용 요구

  • 많은 사용자가 시스템 사용시 모든 노드가 균일하게 사용하도록 해야 한다


IV. RAC CACHE FUSION의 작동 원리_Reference_김종원

  • 싱글 인스턴스 환경과 비교하여 Real Application Cluster에서는 노드간의 동기화를 위하여 부가적인 구성요소가 필요하다.
  • 참고로 이는 Oracle Parallel Server에서는 DLM이라고 말하던 부분이며, Real Application Cluster에서는 캐시 퓨전 기능이
  • 추가되어 GES(Global Enqueue Service) 와 GCS(Global Cache Service)의 두 가지 서비스로 나누어진다.


1. Gobal Enqueue Service & Global Cache Service

Global Enqueue Service(GES)
  • GES는 사용자가 어느 노드에 접속되었는지에 상관 없이 트랜잭션에 대한 록(lock)을 조정하는 서비스
  • 예를 들어 1번 노드에서 특정 테이블의 특정 레코드에 대하여 DML을 수행하고 커밋 또는 롤백을 하지 않았다면 싱글 인스턴스 환경에서와 마찬가지로 2번 노드에서도 해당 레코드에 대하여 DML을 수행할 수 없다.
  • GES는 오라클 백그라운드 프로세스중에 LMD가 수행한다.


Global Cache Service(GCS)
  • GCS는 캐시 퓨전과 함께 작동하는 서비스
  • 예를 들어 자신의 노드에 있는 캐시에서 원하는 블록을 찾지 못했을 때 다른 노드의 캐시를 확인하여 이미 다른 노드의 캐시에 원하는 블록이 올라와 있다면, 디스크에 접근할 필요 없이 인터커넥트를 통하여 블록을 전달해 준다.
  • 이때 데이터의 일관성을 위하여 캐시에 올라온 블록에 대해서 GCS는 리소스를 할당 하여 상태(모드)를 지속적으로 관리한다.
  • GCS 리소스의 상태는 다음과 같이 3가지가 있다.
Null(N) 모드현재 해당 블록에 대하여 쓰기 또는 읽기를 수행중인 세션이 없는 상태
Share(S) 모드현재 해당 블록을 읽는 세션이 적어도 하나 있는 상태
Exclusive(X) 모드현재 해당 블록에 대하여 쓰기를 수행중인 세션이 적어도 하나 있는 상태
  • 이 중 S 모드는 특정 시점에 서로 다른 두 노드에서 공존할 수 있으나, X 모드는 특정 시점에 반드시 하나의 노드에서만 존재할 수 있다.
  • 즉, 한 노드에서 특정 블록에 대하여 쓰기를 하고 싶다면 반드시 X 모드로 GCS 리소스를 할당 받아야 하며, 반대로 그 이전에 X 모드로
  • 잡고 있던 노드에서는 N 모드로 다운그레이드가 된다. 캐시에 올라온 각각의 블록에 대하여 GCS 리소스는 하나의 노드가 마스터가 되어 관리하며, 어느 노드가 어느 블록을 관리할 것인가는 인스턴스를 시작할 때 오라클 내부적으로 Hashing 알고리즘에 따라서 결정되므로 동적으로 할당된다.
  • GCS는 오라클 백그라운드 프로세스 중에LMS가 수행한다.


2. 사례 살펴보기

그림 1은 4노드 Real Application Cluster 구성을 간단하게 나타낸 그림으로, 이해를 돕기 위해 최초에 디스크에 있던 하나의 블록이 캐시 퓨전을 통해 어떻게 움직이는지 따라가보도록 하겠다.
최초에 디스크에 있던 블록의 버전을 나타내는 SCN(System Change Number)은1008번이다.
1. 인스턴스 C에서 블록을 읽으려고 한다. 이때 자신의 캐시에 없으므로 이 블록을 마스터하고 있는 인스턴스에게 해당 블록의 상태를 확인한다. 여기서 우리가 살펴볼 블록의 마스터는 인스턴스 D라고 가정한다.
2. 마스터 노드인 인스턴스 D는 현재 어느 노드의 캐시에도 해당 블록이 올라와 있지 않으므로, 그 사실을 알려주면서 요구하는 인스턴스 C에게 GCS 리소스를 S 모드로 할당한다.
3. 인스턴스 C는 S 모드로 GCS 리소스를 할당 받은 후 디스크에 접근한다.
4. 이제 자신의 캐시로 해당 블록이 올라와 있으며, 읽기만 했기 때문에SCN은 계속 1008번이 된다.
이제 또 다른 인스턴스 B가 같은 블록을 읽으려고 한다.
1.예제 1과 마찬가지로 일단 자신의 캐시에 원하는 블록이 없으므로 마스터 노드에게 가서 해당 블록의 상태를 확인한다.
2. 마스터 노드인 인스턴스 D는 이미 인스턴스 C의 캐시에 해당 블록이 올라와 있기 때문에 인스턴스 C에게 현재 해당 블록을 요구하는 인스턴스 B로 블록을 보내주도록 지시한다.
3. 인스턴스 C는 인스턴스 B에게 블록을 보내주며, 이때 바로 읽기/읽기 캐시 퓨전이 일어나게 된다.
4. 인스턴스 B는 이제 원하는 블록을 캐시에 받고, GCS 리소스 모드 또한 읽기를 위해 S 모드로 할당 받는다.
이때 주목해야 할 점은, 이전 Oracle Parallel Server에서는 이와 같은 경우에 인스턴스 B 는 마스터 노드로 확인하는 과정 없이 바로 예제 1과 같이 디스크로부터 블록을 찾았다는 점이다. 핑(Ping)은 일어나지 않지만, 디스크를 접근하므로 성능은 Real Application Cluster에 비해 상대적으로 떨어진다.
이제 블록을 캐시로 전달 받은 인스턴스 B가 같은 블록에 대하여 업데이트를 하려 한다.
1. 인스턴스 B가 블록을 업데이트하려면 일단 GCS 리소스를 X 모드로 할당 받아야 하므로 다시 마스터 노드인 인스턴스 D로 가서 리소스 모드 업그레이드를 요청한다.
2. 인스턴스 B,C 둘 다 이전에는 S모드로 가지고 있었으므로, 인스턴스 D가 X 모드로 업그레이드하기 위해서는 인스턴스 C가N 모드로 다운그레이드되어야 한다. 마스터 노드는 인스턴스 C에게 다운그레이드를 지시한다.
3. 인스턴스 C가 다운그레이드를 완료하면 이제 인스턴스 B에게 알려주어 S에서 X 모드로 업그레이드를 할 수 있다.
4. 인스턴스 B는 이제 원하는 X 모드로 GCS 리소스를 받았다는 사실을 마스터 노드에게 알려준다. 이때 인스턴스 C도 N 모드로 다운그레이드되었다는 사실까지 함께 알려 준다. 이것이 완료되면 비로소 인스턴스 B는 해당 블록을 업데이트할 수 있으며, 그림 3과 같이 SCN이 1009번으로 바뀐 것으로 나타난다.
디스크에는 여전히 SCN이 1008번으로 남아 있으며, 따라서 현재 가장 최근의 블록 이미지는 인스턴스 B의 캐시에 SCN 1009번으로 놓여 있다는 사실에 주목하자.
이제 인스턴스 A가 또다시 해당 블록에 대하여 업데이트를 하려고 한다.
1. 인스턴스 A는 자신의 캐시에 해당 블록이 없으므로 마스터 노드에 정보를 요구한다.
2. 마스터 노드인 인스턴스 D는 인스턴스 B가 X 모드로 GCS를 잡고 있으므로 가장 최근의 이미지를 가지고 있다는 사실을 알고 있다. 따라서 인스턴스B에게 요구하는 인스턴스A로 블록을 보내주도록 지시한다.
3. 인스턴스 B는 우선 GCS 리소스를 N 모드로 다운그레이드한 후 요구하는 인스턴스 A로 블록을 보낸다. 이때 바로 쓰기/쓰기 캐시 퓨전이 일어난다.
4. 인스턴스 A는 GCS 리소스를 X 모드로 업그레이드한 후 마스터 노드로 그 정보를 보내 준다. 이제 비로소 인스턴스 A는 해당 블록에 업데이트할 수 있으며, 가장 최근의 블록 이미지는 인스턴스 A에있다. 그림 4에서는 SCN이 1013번으로 바뀐 것을 볼 수 있다.
Oracle Parallel Server에서는 이와 같은 시나리오에서 인스턴스 B는 일단 디스크에 블록을 쓰고, 인스턴스 A에서는 다시 디스크에서 읽는 과정을 거쳐야만 했으며, 이 디스크를 거쳐가는 동기화 과정을'핑(Ping)'이라고 불렀다. Real Application Cluster에서는 쓰기/쓰기 캐시 퓨전이 가능해지면서 핑이 완전히 사라져, 성능이 눈에 띄게 향상되면서 확장이 용이하게 되었다. 즉 현재 싱글 인스턴스 환경은 언제든 Real Application Cluster 환경으로 전환할 수 있다.
이제 인스턴스C에서 다시 해당 블록을 읽고자 한다. 예제 3에서 인스턴스 C는 해당 블록에 대하여N 모드로 GCS 리소스를 다운그레이드했음을 기억하자.
1. 인스턴스 C는 해당 블록에 대하여 N 모드로 GCS 리소스를 가지고 있었으므로, 다시 읽기를 위하여 S 모드로 업그레이드하기 위해 마스터 노드에 정보를 확인한다.
2. 마스터 노드는 인스턴스 A가 가장 최근 이미지를 X 모드로 가지고 있다는 사실을 알고 있으므로 인스턴스 A에게 요구하는 인스턴스 C로 블록을 보내라고 지시한다.
3. 인스턴스 A는 X에서 S로 GCS 리소스를 다운그레이드하고 인스턴스 C로 블록을 보내 준다. 이때 바로 쓰기/읽기 캐시 퓨전이 일어난다. 참고로 이 기능은 Oracle8i Oracle Parallel Server에서부터 있던 기능이다.
4. 인스턴스 C는 N에서 S로 GCS 리소스를 업그레이드하고 다시 마스터 노드에게 이 사실을 알려 준다. 이제 SCN 1013번의 블록 이미지가 인스턴스 A와 인스턴스 C의 캐시에 동시에 놓여 있으며, 이제 인스턴스 C는 원하는 대로 블록을 읽을 수 있다.
이때 디스크에는 여전히 SCN 1008번이 놓여 있으며, 인스턴스 B에는 디스크에 있는 이미지보다는 새로운 이미지지만, 인스턴스 A 또는 C보다는 오래된 이미지인 SCN 1009번으로 캐시에 블록을 가지고 있다. 하지만 GCS 리소스가 N 모드이기 때문에 차후에 읽기 또는 쓰기를 할 때는 캐시에 해당 블록을 가지고 있더라도 반드시 마스터 노드에게 정보를 확인하게 되며, 유효하지 않은 SCN 1009번 이미지를 읽을 경우는 없다. 이때 시나리오는 예제 2(read) 또는 예제 3(write)와 같이 이루어지게 된다.
"구루비 데이터베이스 스터디모임" 에서 2008년에 "이펙티브 오라클" 도서를 스터디하면서 정리한 내용 입니다.

- 강좌 URL : http://www.gurubee.net/lecture/3536

- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^

- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입