시스템이야기2008. 11. 26. 01:19
MySQL서버는 log 옵션(my.cnf에서 log=파일명. slow query는 log-slow-queries=파일명)을 통해서 실행된 DB 쿼리를 모두 파일로 저장할 수가 있다. 그러나 DB 서버에서 작은 사이트가 아니고선 엄청난 양의 실시간 쿼리를 모두 쌓는다는 것은 힘들다. DB 운영도중에 잠시동안 쿼리 로그를 쌓겠다고 MySQL 재실행할 수도 없는 노릇이다. MySQL 5.1에서는 재실행없이 로그를 쌓을 것인지 안할 것인지를 결정할 수 있지만, 이부분은 뒤에서 설명하기로 하고, 패킷 스니핑 방법으로 실시간으로 살펴보는 방법을 소개한다.

Poor man’s query logging (Posted by Maciej Dobrzanski) 에서 tcpdump와 perl의 정규표현으로 실시간 쿼리를 살펴보는 괜찮은 방법을 소개하고 있다.

* 위 블로그에 올라온 간단한 명령
     # tcpdump -i eth0 -s 0 -l -w - dst port 3306 | strings | perl -e '
while(<>) { chomp; next if /^[^ ]+[ ]*$/;
   if(/^(SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER)/i) {
      if (defined $q) { print “$q\n”; }
      $q=$_;
   } else {
      $_ =~ s/^[ \t]+//; $q.=” $_”;
   }
}’
    
위 명령을 활용하여 SELECT/UPDATE/DELETE/INSERT 등을 highlight 하도록 작성했다. highlight 에 대한 자세한 글은 '로그 모니터링시 특정 문자를 highlight하기 (2008.1, 글 좋은진호)'를 살펴보기 바란다.

* query_sniff.sh 내려받기
* query_view.pl 내려받기

[ MySQL 쿼리를 스니핑한 후 highlight. 'count'문자도 함께 highlight ]


MySQL 5.1에서는 쿼리를 로깅할지 안할지 여부를 재실행없이 변경할 수 있는 기능이 있다. 다음과 같이 로그 저장을 ON으로 설정할 수 있고, 필요없을 때 다시 OFF를 하면 된다.

SET GLOBAL general_log = 'ON';
SET GLOBAL slow_query_log = 'ON';
... 생략 ...
SET GLOBAL general_log = 'OFF';
SET GLOBAL slow_query_log = 'OFF';

파일이 아닌 테이블로 로그를 저장하려면 다음과 같이 설정한다.
SET GLOBAL log_output = 'TABLE';

log_output= 설정 값으로는 FILE, TABLE, NONE (log_output = 'FILE', log_output = 'TABLE', ..)을 지정할 수 있다. DB 테이블로 쿼리를 저장하게 되면 쿼리 전체는 general_log 테이블에, slow 쿼리는 slow_log 테이블에 각각 저장된다. general_log 테이블의 스키마는 다음과 같으며, slow_log 테이블은 query_time, lock_time 등 다른 형식의 데이터들이 저장된다.

mysql> desc mysql.general_log;
+--------------+-------------+------+-----+-------------------+-----------------------------+
| Field        | Type        | Null | Key | Default           | Extra                       |
+--------------+-------------+------+-----+-------------------+-----------------------------+
| event_time   | timestamp   | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| user_host    | mediumtext  | NO   |     | NULL              |                             |
| thread_id    | int(11)     | NO   |     | NULL              |                             |
| server_id    | int(11)     | NO   |     | NULL              |                             |
| command_type | varchar(64) | NO   |     | NULL              |                             |
| argument     | mediumtext  | NO   |     | NULL              |                             |
+--------------+-------------+------+-----+-------------------+-----------------------------+
6 rows in set (0.00 sec)

보다 자세한 것은 커피닉스에 써둔 'MySQL 쿼리 실시간 모니터링 및 저장하기'를 살펴보기 바란다.
Posted by 좋은진호