SHELL command예를 들면:
SHELL ls -lh /usr/local/mysql/data
$ /usr/local/sbin/mysql-proxy --proxy-lua-script=shell.lua -D # from a different console $ mysql -U USERNAME -pPASSWORD -h 127.0.0.1 -P 4040데이터베이스 서버에 대한 일반 프록시로 작동함을 보장합니다.
Welcome to the MySQL monitor. Commands end with ; or g. Your MySQL connection id is 49 Server version: 5.0.37-log MySQL Community Server (GPL) Type "help;" or "h" for help. Type "c" to clear the buffer. mysql> use test Database changed mysql> show tables; +----------------+ | Tables_in_test | +----------------+ | t1 | +----------------+ 1 row in set (0.00 sec) mysql> select * from t1; +------+ | id | +------+ | 1 | | 2 | +------+ 2 rows in set (0.00 sec)좋습니다. 일반적인 연산들이 예상대로 작동합니다. 이제 강화된 기능을 테스트 해보겠습니다.
mysql> shell df -h; +--------------------------------------------------------+ | df -h | +--------------------------------------------------------+ | Filesystem Size Used Avail Use% Mounted on | | /dev/md1 15G 3.9G 9.7G 29% / | | /dev/md4 452G 116G 313G 27% /app | | tmpfs 1.7G 0 1.7G 0% /dev/shm | | /dev/md3 253G 159G 82G 67% /home | | /dev/md0 15G 710M 13G 6% /var | +--------------------------------------------------------+ 6 rows in set (0.00 sec)반갑다 쉘! 이것은 정말로 고급 사용자에게는 큰 기쁨을 줄 것입니다. 여러분이 외부 명령어로 접근하는 수단만 취할 수 있다면 여러분은 완전히 창조적인 작업들을 해낼 수 있을 것입니다.
mysql> shell grep key_buffer /usr/local/mysql/my.cnf; +-----------------------------------------+ | grep key_buffer /usr/local/mysql/my.cnf | +-----------------------------------------+ | key_buffer=2000M | +-----------------------------------------+ 1 row in set (0.00 sec)저는 동일한 내용을 SHOW VARIABLES로 확인해 볼 수 있다는 것을 알고 있긴 하지만 이것은 온라인에서도 설정할 수 있는 값이므로 저는 그러한 내용이 설정 파일에도 들어있다는 것을 확인해보고 싶었습니다. 그러면 메모리 상태는 어떻게 되어 있을까요?
mysql> shell free -m; +---------------------------------------------------------------------------+ | free -m | +---------------------------------------------------------------------------+ | total used free shared buffers cached | | Mem: 3280 1720 1560 0 9 1006 | | -/+ buffers/cache: 704 2575 | | Swap: 8189 2 8186 | +---------------------------------------------------------------------------+ 4 rows in set (0.08 sec)나쁘진 않군요. 이제 서버 상태를 볼 수 있어서 기쁜데, 한번 재미있는 걸 해볼까요? 예를 들면 Planet MySQL의 마지막 항목을 확인해 볼 수도 있습니다. 여러분께서는 제가 농담하는 거라 생각하세요? 전혀 아닙니다. 명령어는 꽤 길지만 분명히 작동합니다.
wget -q -O - http://www.planetmysql.org/rss20.xml | perl -nle "print $1 if m{그런데 나열되는 목록이 너무 길어 아무도 그것을 기억하지는 않을 것이므로 그것을 쉘 스크립트로 붙여넣은 다음 last_planet.sh와 같이 호출해야 할 것입니다. 그렇게 하는 방법이 아래에 있습니다!(.*) }" |head -n 21 | tail -n 20;
mysql> shell last_planet.sh; +-------------------------------------------------------------------------------------+ | last_planet.sh | +-------------------------------------------------------------------------------------+ | Top 5 Wishes for MySQL | | Open Source ETL tools. | | MySQL Congratulates FSF on GPLv3 | | Query cache is slow to the point of being unusable - what is being done about that. | | About "semi-unicode" And "quasi Moon Stone" | | My top 5 MySQL wishes | | Four more open source startups to watch | | More on queue... Possible Solution... | | MySQL as universal server | | MySQL Proxy. Playing with the tutorials | | Open source @ Oracle: Mike Olson speaks | | Quick musing on the "Queue" engine. | | Distributed business organization | | Ideas for a MySQL queuing storage engine | | MySQL Test Creation Tool Design Change | | Queue Engine, and why this won" likely happen... | | What?s your disk I/O thoughtput? | | My 5+ Wish List? | | Top 5 best MySql practices | | Packaging and Installing the MySQL Proxy with RPM | +-------------------------------------------------------------------------------------+ 20 rows in set (1.48 sec)쉘에 접근해서 MySQL 클라이언트로부터 웹 컨텐츠를 가져왔습니다!
mysql> shell ls *.lua*; +---------------------+ | ls *.lua* | +---------------------+ | first_example.lua | | first_example.lua~ | | second_example.lua | | second_example.lua~ | +---------------------+ 4 rows in set (0.03 sec) mysql> shell rm *~; Empty set (0.00 sec) mysql> shell ls *.lua*; +--------------------+ | ls *.lua* | +--------------------+ | first_example.lua | | second_example.lua | +--------------------+ 2 rows in set (0.01 sec)쉘 접근시에는 매우 조심해야 합니다!
local log_file = "mysql.log" local fh = io.open(log_file, "a+") function read_query( packet ) if string.byte(packet) == proxy.COM_QUERY then local query = string.sub(packet, 2) fh:write( string.format("%s %6d -- %s n", os.date("%Y-%m-%d %H:%M:%S"), proxy.connection["thread_id"], query)) fh:flush() end end루아 파일을 작성한 다음 Proxy를 시작하고 동일한(concurrent) 세션으로부터 Proxy에 접속합니다. 이 스크립트는 모든 쿼리를 mysql.log라는 이름의 텍스트 파일로 로그로 남길 것입니다. 몇몇 세션이 활동한 뒤의 로그 파일은 다음과 같을 것입니다:
2007-06-29 11:04:28 50 -- select @@version_comment limit 1 2007-06-29 11:04:31 50 -- SELECT DATABASE() 2007-06-29 11:04:35 51 -- select @@version_comment limit 1 2007-06-29 11:04:42 51 -- select USER() 2007-06-29 11:05:03 51 -- SELECT DATABASE() 2007-06-29 11:05:08 50 -- show tables 2007-06-29 11:05:22 50 -- select * from t1 2007-06-29 11:05:30 51 -- show databases 2007-06-29 11:05:30 51 -- show tables 2007-06-29 11:05:33 52 -- select count(*) from user 2007-06-29 11:05:39 51 -- select count(*) from columns로그는 날짜, 시간, 연결 ID, 쿼리를 담고 있습니다. 이러한 짧은 스크립트는 단순하고 효과적입니다. 로그에는 세 개의 세션이 있는데 각 세션의 명령어는 세션별로 정렬되지는 않고 실행된 시간 순으로 정렬된다는 것을 명심하십시오.
sudo iptables -t nat -I PREROUTING -s ! 127.0.0.1 -p tcp --dport 3306 -j REDIRECT --to-ports 4040
sudo iptables -t nat -D PREROUTING -s ! 127.0.0.1 -p tcp --dport 3306 -j REDIRECT --to-ports 4040로깅 커스터마이즈에 관해 좀 더 알아보기
-- logs.lua assert(proxy.PROXY_VERSION >= 0x00600, "you need at least mysql-proxy 0.6.0 to run this module") local log_file = os.getenv("PROXY_LOG_FILE") if (log_file == nil) then log_file = "mysql.log" end local fh = io.open(log_file, "a+") local query = "";스크립트의 대부분이 우리가 적절한 버전의 Proxy를 사용하고 있는지를 확인하는 것인데, 왜냐하면 0.5.0 버전에서는 사용할 수 없는 기능을 사용하고 있기 때문입니다. 그리고 나서 파일명을 지정하는데, 환경변수에서 가져오거나 아니면 기본값을 할당합니다.
function read_query( packet ) if string.byte(packet) == proxy.COM_QUERY then query = string.sub(packet, 2) proxy.queries:append(1, packet ) return proxy.PROXY_SEND_QUERY else query = "" end end첫 번째 함수는 하는 일이 적은데, 쿼리를 프록시 큐에 추가하여 다음 함수가 결과가 준비되었을 때 트리거되도록 합니다.
function read_query_result (inj) local row_count = 0 local res = assert(inj.resultset) local num_cols = string.byte(res.raw, 1) if num_cols > 0 and num_cols < 255 then for row in inj.resultset.rows do row_count = row_count + 1 end end local error_status ="" if res.query_status and (res.query_status < 0 ) then error_status = "[ERR]" end if (res.affected_rows) then row_count = res.affected_rows end -- -- write the query, adding the number of retrieved rows -- fh:write( string.format("%s %6d -- %s {%d} %sn", os.date("%Y-%m-%d %H:%M:%S"), proxy.connection["thread_id"], query, row_count, error_status)) fh:flush() end이 함수에서는 우리가 현재 데이터를 조작하는 쿼리나 select 쿼리를 다루고 있는지를 확인해 볼 수 있습니다. 만약 행(row)이 있으면 함수는 그것들의 개수를 센 다음 그 결과가 로그파일의 중괄호 안에 출력됩니다. 영향을 받은 행이 있으면 로그파일에는 영향을 받은 개수가 기록된다. 게다가 우리는 오류가 있었는지를 확인할 수 있는데, 정보가 중괄호 안에 반환된 경우로서, 결론적으로 말해서 모든 것들이 로그 파일로 기록됩니다. 아래는 이러한 로그파일의 예입니다:
2007-06-29 16:41:10 33 -- show databases {5} 2007-06-29 16:41:10 33 -- show tables {2} 2007-06-29 16:41:12 33 -- Xhow tables {0} [ERR] 2007-06-29 16:44:27 34 -- select * from t1 {6} 2007-06-29 16:44:50 34 -- update t1 set id = id * 100 where c = "a" {2} 2007-06-29 16:45:53 34 -- insert into t1 values (10,"aa") {1} 2007-06-29 16:46:07 34 -- insert into t1 values (20,"aa"),(30,"bb") {2} 2007-06-29 16:46:22 34 -- delete from t1 {9}첫 번째와 두 번째, 그리고 네 번째 줄은 상대적으로 다섯 번째, 두 번째, 여섯 번째 줄로부터 반환된 쿼리임을 말해줍니다. 세 번째 줄은 쿼리가 오류를 반환하였음을 말해줍니다. 다섯 번째 줄은 2개의 행이 UPDATE 명령에 의해 영향을 받았음을 말해줍니다. 그 다음의 라인은 모두 INSERT와 DELETE문에 의해 영향을 받은 행의 개수를 말해줍니다.
이전 글 : MySQL Proxy 시작하기(1)
다음 글 : 리눅스 디바이스 드라이버 심플 소개(1)
최신 콘텐츠