2010년 5월 23일 일요일

MySQL성능측정2

Super-Smack(http://vegan.net/tony/supersmack/)은 MySQL벤치마킹툴이다.

특징으로는 다음과 같은 것이 있다.

  • MySQL과 PostgreSQL에서 동작
  • C++로 만들어졌으므로 쓸데없는 준비가 필요없다. (자바나 펄이면 MySQL용 드라이버가 필요), C의 AP를 사용해서 서버에 접속하므로 쓸 데 없는 잡음이 들어가지 않는다. 개조나 확장하기 쉬운 구조로 되어있다. 예를 들면 MySQL고유의 처리는 mysql-client.cc파일에 정리되어져 있으므로 이것을 참고로 Firebird대응도 가능할 것이다.
  • 시나리오 파일(smack파일)로 자유롭게 실행하는 쿼리를 여러개 지정할 수 있다.
  • 복수의 클라이언트를 가상으로 fork()로 생성하고 각 클라이언트(자식 프로세스)로 쿼리를 실행할 수 있다. 모든 클라이언트는 같은 시나리오로 동작한다.
  • 데이터(영문숫자)를 생성하는 툴이 부속되어있다.
  • 쿼리는 mysql_query()와 PQexec()를 실행. stored procedure는 사용하지 않음.
  • SELECT결과는 fetch하지 않는다.
■컴파일
소스를 풀어놓은 후 configure, make한다. MySQL를 지원하려면 --with-mysql, --with-mysql-lib=, --with-mysql-include=를 지정한다.

make한 후 super-smack(이것이 본체)라는 명령어와 gen-data(데이터 생성 툴)이라는 명령어가 생기게 된다.

■사용방법
super-smack -d {pg|mysql} 시나리오파일 [인수 [인수] ...]
(pg: postgresql, mysql:MySQL, 인수는 시나리오 파일에서 사용하는 변수($1, $2...)가 된다. )
gen-data [-n행수 또는 --num-rows=행수] [-f포맷 또는 --format=포맷]
데이터를 생성하는 명령어로 생성할 레코드 수 , 레코드의 포맷을 지정한다.

■시나리오 파일 기술
다음의 블럭을 기술한다. (main, client, query, dictionary, table )

  • main{} : 근간이 된다. 접속, 절단 그리고 어느 쿼리를 몇번이나 실행할 것인지 등의 기본이 되는 동작의 지시를 한다.
  • client{} : 여러개 정의가 가능하다. 접속정보나 쿼리단위 정의를 한다.
  • query{}: 여러개 정의가 가능하다. 쿼리를 실제로 기술하는 블럭이다.
  • dictionry{}:여러개 정의가 가능하다. 필수조건은 아니다. 쿼리에 부여하는 값을 룰을 기술한다.
  • table{}:여러개 정의가 가능하다. 필수조건은 아니다. 테이블의 존재를 체크해 없으면 생성한다. 또 레코드수를 체크해서 적으면 일단 테이블을 drop하고 테이블작성과 레코드 작성을 수행한다.
■결점
Super-Smack은 만능은 아니로 다음과 같은 결점도 있다.
  • 여러개의 연속되는 쿼리에서 같은 값을 사용할 수 없다. 예를 들어 SELECT * FROM tbl WHERE col=$dict; UPDATE tbl SET col2=xxx WHERE col=$dict; 처럼 연속되는 쿼리의 $dict에는 다른값이 들어 가 버린다.
  • 같은 쿼리내에서도 같은 값을 사용할 수 없다. SELECT $dict, $dict; 라고 해도 예를 들어 SELECT 1, 999;처럼 다른 값이 처리된다.
  • 전에 실행한 SELECT의 결과를 새로운 쿼리에서 사용할 수 없다. 예를 들어 SELECT price FROM item WHERE id=1; 에서의 price값을 재 사용할 수 없다.










2010년 5월 18일 화요일

MySQL 성능 측정1

MySQL처리 성능을 측정하는 툴을 알아보자.

툴을 사용하면 튜닝이나 설계에 도움이 된다.

그러나 툴을 사용하기 또는 툴의 결과를 분석하는 경우는 기술자로서의 냉정한 눈이 필요하게 된다.

제3자의 실험결과를 그대로 믿어버리는 것이 아니라 자기 스스로 확인해야할 것이다.

하드웨어, 툴 설계 , 테이블 구조, 데이터양, ODBC,Perl, PHP, Java등의 중간층의 구현등 MySQL본체 이외에도 다양한 인자가 실험을 좌우한다.

툴과 그 결과는 절대적인 것이 아니므로 주의하면서 실험과 고찰을 해나가야한다.

물론 기존의 툴을 사용하지 않고 자기가 단순한 테스트 프로그램을 스스로 작성해서 확인해도 좋을 것이다.

MySQL의 C API는 단순하므로 바로 사용할 수 있을 것이다.

2010년 5월 10일 월요일

MySQL를 MRTG로 감시

「MySQL을 snmpd로 감시」에서 설명한 것은 SNMP서버가 MySQL값을 처리하는 방법이었다.

여기에서는 SNMP클라이언트인 MRTG가 MySQL값을 조사하는 방법을 소개한다.

SNMP클라이언트로 조사할 것인지 SNMP서버로 조사할 것인지 상황에 맞게 선택하면 될 것이다.

Debian에서는 다음과 같은 조작으로 MRTG가 설치된다.

root@shell# aptitude install mrtg mrtg-contrib


사용방법

MRTG설정파일에 MRTG가 명령어(스크립트)를 실행해서 그 결과를 처리하도록 해보자.

Target[Threads_connected]: `/etc/snmp/mysql_mrtg.sh`
Title[Threads_connected]: "MySQL Threads_connected"
Options[Threads_connected]: growright,nopercent,gauge
YLegend[Threads_connected]: times
ShortLegend[Threads_connected]: times
Legend1[Threads_connected]: times
Legent2[Threads_connected]: times
LegentO[Threads_connected]:

Target키워드는 Threads_connected를 조사하는 스크립트를 「`」로 묶어서 지정한다.
스크립트는 /etc/snmp/mysql_mrtg.sh로 한다. 이 스크립트에는 실행권한을 chmod로 부여해둔다. 또 Options에 nopercent를 지정해서 %를 다루지 않게 한다. Options의 gauge는 값을 차이처리, 평균화(/sec.)를 하지않는다는 것을 의미한다.

MRTG는 새롭게 취득한 값과 전에 취득한 값의 차이를 계산하여 그것을 기준으로 그래프를 그린다. 보통 네트워크의 인터페이스의 입출력패킷 양의 수치는 누적되어 처리되므로 이번에 얻은 값과 전에 얻은 값의 차이를 계산해서 출력한다.

그러나 이번에 측정하려고 하는 것은 MySQL의 Threads_connected 즉 지금 접속하고 있는 수이므로 gauge를 이용한다.

참고로 디스크사용량이나 미사용량은 gauge처리를 하는 것이 좋다.

MRTG는 보통 값을 초간격으로 평균(값/sec.)을 낸다. gauge의 경우, 값을 평균화하지 않고 측정값이 그대로 출력된다. 즉 순간순간 측정된 값이 출력된다.

gauge하고 비슷한 것이 absolute가 있다. 이것은 값을 초간격으로 평균처리하는 점이 gauge하고 다른 점이다.

Legend는 축의 단위이다. 단순히 표시할 때의 문자열을 나타내므로 편한대로 설정하면 될 것이다. LegendO[]:처럼 단위를 지정하지 않으면 Outbound선을 출력하지 않는다.

스크립트는 다음과 같이 처리한다.
간략화한 것이므로 인수처리, 에러처리, 배타처리등은 생략한다.

#!/bin/sh
export PATH=/usr/local/mysql/bin:/usr/local/bin:/usr/bin:/bin:/sbin:/usr/sbin

TMPFILE=/tmp/mysql_mrtg.$$

mysql -uroot -e 'SHOW STATUS' > $TMPFILE

N=`grep -i '^Threads_connected' $TMPFILE | awk '{print $2}'`
T=`grep -i '^Uptime' $TMPFILE | awk '{print $2}'`

rm TMPFILE

echo "$N"
echo 0
echo "$(expr $T / 86400) days"
echo "MySQL Server Threads_connected"

exit 0

출력포맷은 다음과 같다.

Inbound의 값(수치)
Outbound의 값(수치)
가동시간(문자열)
코멘트(문자열)

MRTG는 인터페이스 패킷의 입출력을 조사하는 것을 전제로 하고 있다.
따라서 인터페이스의 Inbound와 Outbound 둘다 값이 필요하다.
이번 예에서는 한개만 필요하므로 Outbound를 0으로 고정하고 있다. 이것은 숫자이다.

나머지 가동시간, 코멘트는 인간이 읽을 수 있는 문자열이면 뭐든지 괜찮다.