• MySQL매뉴얼
    • MySQL 5.6 매뉴얼
    • MySQL 5.1 매뉴얼
    • MySQL 5.0 매뉴얼
    • MySQL HA 매뉴얼
  • 기술문서
    • Xtrabackup 구성
    • 메모리 사용량 모니터링
  • 서비스
    • MySQL유지보수
    • MySQL라이선스
  • 온라인문의
  • 회사소개
  • → 목 록 (MySQL5.1 한글메뉴얼) [close]
  • 1. MySQL 5.1 Reference Manual
  • 2. Installing and MySQL 업그레이드하기
  • 3. 사용 설명서 (Tutorial)
  • 4. MySQL 프로그램 사용하기
  • 5. 데이터베이스 관리
  • 6. 리플리케이션
  • 7. 최적화 (Optimization)
  • 8. 클라이언트 및 유틸리티 프로그램
  • 9. 언어 구조 (Language Structure)
  • 10. 문자 셋 지원
  • 24. API 및 라이브러리
  • 1. libmysqld, 임베디드 MySQL 서버 라이브러리
    2. MySQL C API
    1. C API 데이터 타입
    2. C API 함수 개요
    3. C API 함수 상세 내용
    4. C API 프리페어드 명령문
    5. C API 프리페어드 명령문 데이터 타입
    6. C API 프리페어드 명령문 함수 개요
    7. C API 프리페어드 명령문 함수 상세 내용
    8. C API 프리페어드 명령문의 문제점
    9. C API 멀티 명령문 실행
    10. C API 데이터 및 타입 값 처리
    11. C API 쓰레드 함수 상세 내역
    12. C API 임베디드 서버 함수 상세 내역
    13. 자동 재 접속 동작 제어
    14. C API를 사용할 때 자주 발생하는 문제점
    15. 클라이언트 프로그램 구축하기
    16. 쓰레디드 클라이언트 만들기
    3. MySQL PHP API
    4. MySQL Perl API
    5. MySQL C++ API
    6. MySQL Python API
    7. MySQL Tcl API
    8. MySQL Eiffel Wrapper
    9. MySQL프로그램 개발 유틸리티
  • 25. Connectors

24.2.16. 쓰레디드 클라이언트 만들기

 

클라이언트 라이브러리는 대부분 쓰레드-세이프이다. 가장 어려운 문제는 소켓에서 읽는 net.c의 서브루틴이 인터럽트-세이프가 아니라는 것이다. SIGPIPE 인터럽트용 인터럽트 핸들러를 설치한다면, 소켓 처리는 쓰레드-세이프가 된다.

연결이 종료될 때 프로그램이 중지되는 것을 피하기 위해서, MySQL은 mysql_library_init(), mysql_init(), 또는 mysql_connect()에 대한 첫번째 호출에서 SIGPIPE를 막는다. 사용자 자신의 SIGPIPE 핸들러를 사용하고자 한다면, 우선 mysql_library_init()를 실행한 후에 사용자 핸들러를 설치하도록 한다.

다른 쓰레드에서 클라이언트를 인터럽트할 수 있는 쓰레디드 클라이언트를 얻고 MySQL 서버와 통신을 할 때 타임 아웃을 설정하기 위해서는 서버가 사용하는 net_serv.o 코드와 -lmysys, -lmystrings, 그리고 -ldbug 라이브러리를 사용하도록 한다.

인터럽트 및 타임아웃이 필요없다면, 쓰레드-세이프 클라이언트 라이브러리 (mysqlclient_r)를 컴파일해서 사용하도록 한다.

쓰레디드 클라이언트를 사용할 때 타임아웃과 인터럽트를 사용한다면, 파일에 들어 있는 thr_alarm.c 파일을 많이 활용할 수 있을 것이다. mysys 라이브러리에서 루틴을 사용한다면, my_init()를 가장 먼저 호출해야 한다는 점만 기억하도록 한다!

어떠한 경우에서라도 다른 MySQL 함수를 호출하기 전에 반드시 mysql_library_init()를 실행해서 클라이언트 라이브러리를 초기화 시켜야 한다는 점을 명심하도록 한다. 라이브러리와 함께 업무를 종료한 후에는, mysql_library_end()를 실행하도록 한다.

mysql_real_connect()는 디폴트로 쓰레드-세이프가 아니다. 쓰레드-세이프 클라이언트 라이브러리를 컴파일하고 쓰레드-세이프 방식으로 그것을 사용하는 방법은 아래에 나와 있다.

mysql_real_connect()를 쓰레드-세이프로 만들기 위해서는, MySQL 배포판을 다음과 같은 명령문을 사용해서 구성해야 한다:

 

shell> ./configure --enable-thread-safe-client

 

그런 다음에, 배포판이 쓰레드-세이프 클라이언트 라이브러리 libmysqlclient_r를 생성하도록 다시 컴파일 한다. 이 라이브러리는 연결 별로 쓰레드-세이프가 된다. 다음에 나오는 캐빗 (caveat)을 사용하면 두 개의 쓰레드가 동일한 연결을 공유할 수 있도록 할 수 있다:

  • 두 개의 쓰레드는 동일한 연결 상에서 두 대의 MySQL 서버에 동시에 하나의 쿼리를 보낼 수 없다. 특히, mysql_query()와 mysql_store_result()를 호출하는 동안에는 어떠한 다른 쓰레드도 동일한 연결을 사용하지 않음을 확인해야 한다.
  • 많은 종류의 쓰레드가 mysql_store_result()로 추출되는 서로 다른 결과 셋에 접속할 수 있다.
  • mysql_use_result를 사용한다면, 결과 셋이 닫히기 전에는 어떠한 다른 쓰레드도 동일한 연결을 사용하지 않음을 확인해야 한다. 하지만, 동일한 연결을 공유하는 쓰레디드 클라이언트는 mysql_store_result()를 사용하도록 하는 것이 가장 바람직하다.
  • 동일한 연결 상에서 여러 개의 쓰레드를 사용하고자 한다면, mysql_query()와 mysql_store_result() 호출에 대해서는 뮤텍스 (mutex) 잠금을 반드시 해두도록 한다. 일단 mysql_store_result()가 준비되면, 잠금을 풀수 있고 다른 쓰레드가 동일한 연결을 쿼리할 수도 있다.
  • POSIX 쓰레드를 사용한다면, 뮤텍스 잠금을 구축하고 풀 때 pthread_mutex_lock() 및 pthread_mutex_unlock()를 각각 사용할 수 있다.

MySQL 데이터베이스에 대한 연결을 생성하지 않은 MySQL 함수를 호출하는 쓰레드를 가지고 있다면 다음에 설명하는 사항을 알아야 한다:

mysql_init() 또는 mysql_connect()를 호출하면 MySQL은 디버그 라이브러리가 사용하는 쓰레드용으로 쓰레드-관련 변수를 생성한다.

쓰레드가 mysql_init() 또는 mysql_connect()를 호출하기 전에 MySQL 함수를 호출한다면, 쓰레드는 필요한 쓰레드-관련 변수를 가지고 있지 않기 때문에 조만간 코어 덤프를 사용해서 끝마쳐야 할 수도 있을 것이다.

다음 과정을 처리하도록 한다:

 

1.     다른 MySQL 함수를 호출하기 전에 mysql_library_init()를 실행하도록 한다. 이것은 쓰레드-세이프가 아니기 때문에, 쓰레드를 생성하기 전에 호출하거나, 또는 뮤텍스를 사용해서 호출을 하지 못하도록 한다.

2.     다른 MySQL 함수를 호출하기 전에 쓰레드 핸들러에서 초기에 mysql_thread_init()를 호출하도록 정렬한다. mysql_init() 또는 mysql_connect()를 호출한다면, 이것들은 mysql_thread_init()를 호출한다.

3.     쓰레드에서, pthread_exit()를 호출하기 전에 mysql_thread_end()를 실행한다. 이렇게 하면 MySQL 쓰레드-관련 변수가 사용한 메모리를 풀게 된다.

서울시 강남구 영동대로 602 6층  TEL: 02-6061-0006
주식회사 이노클러스터  등록번호 : 727-86-02261
Copyright © innocluster Co. ltd. all rights reserved