카테고리 없음 2011. 8. 22. 16:01
MyISAM과 달리 InnoDB 테이블들은 매우 안정적이며, 왠만해서는 데이터 파일이 깨어지는 경우는 거의 경험하지 못했다.
하지만, 데이터 파일이 깨어진다면 어떻게 해야 할까 ?. DBMS 벤더를 불문하고 손상된(깨어진) 데이터 파일을 복구한다는 것은 쉽지 않은 문제이며 위험도 크다.
이런 비 정상적인 현상은 어느 DBMS에서나 발생할 수 있는 현상이며, 이를 위해서 우리는 데이터베이스를 그렇게 열심히 백업하고 있었던 것이다.
만약, 백업마저도 복구가 안 된다면, 결국 지금의 깨어진 데이터 파일이라도 어떻게든 복구를 해야 한다.
하지만, InnoDB myisamchk와 같은 별도의 복구 도구를 제공하지 않는다.
손상된 InnoDB 테이블의 복구는 우선 MySQL을 기동시켜서 데이터를 덤프(mysqldump, SELECT INTO OUTFILE…)를 받는 것이 유일한 방법이다.
하지만, InnoDB Boot-up 과정에서 여러 가지 체크 및 정리 작업들을 하게 되는데, 이 중에서 하나라도 문제가 있을 경우 시작이 되지 않는다. (MySQL이 시작도 안 되는데 어떻게 덤프를 받지? ㅠㅠ)
그래서 MySQL의 설정 옵션 중에서 "innodb_force_recovery" 라는 설정 변수를 제공하고 있다
아래와 같이 MySQL의 설정 파일(my.cnf, my.ini)에 설정하면, 이 설정 값에 의해서 InnoDB에게 어떤 체크나 정리 작업을 건너뛰어야 할지를 알려 줄 수 잇다.

## 0 ~ 6까지의 값 중에서 하나를 설정 (0은 정상 상태인 경우이며 그 이상의 경우 강제 복구모드에 해당됨)
innodb_force_recovery = 1


기본 설정 값은 "0" 인데, 이는 InnoDB에게 모든 체크와 정리 작업을 정상적으로 실행하도록 명령하는 것이다.

그 이외의 설정 값은 모두 비 정상적인 상황을 위한 설정 값이며, 일반적인 서비스 환경에서는 사용하면 안 된다.
또한 "0"이 아닌 그 이외의 값을 설정하게 되면, InnoDB는 복구 모드라고 가정하고 SELECT 이외의 데이터를 변경하는 SQL들은 모두 처리를 거절해 버린다.


각 설정값별 복구 내용과 방식을 간단히 살펴보자. 

·         1 ( SRV_FORCE_IGNORE_CORRUPT )
데이터 파일의 손상된 페이지가 발견되어도 무시하고 MySQL을 기동시킨다.  일단 MySQL이 기동되면, SELECT * FROM tbl_name; 명령문을 실행하여 데이터를 덤프하여 다시 적재하거나 다른 데이터베이스로 이전하는 것이 좋다. 이 때, 손상된 인덱스 레코드와 페이지는 모두 건너뛰게 된다. (, 무시해 버리므로 데이터를 잃게 된다.)
에러 로그 파일에 "Database page corruption on disk or a failed "라고 출력되는 경우, 대부분 이 케이스인데 이는 테이블 스페이스의 페이지가 손상되어서 발생하는 문제이다. 이 경우에는 이 모드로 MySQL의 기동 후, mysqldump SELECT INTO OUTFILE...을 이용하여 덤프 및 재 적재가 가능하다.

·         2 ( SRV_FORCE_NO_BACKGROUND )
InnoDB의 여러 가지 Background thread들 중에서 Main thread를 시작하지 않고 MySQL을 기동시킨다. InnoDB의 경우 트랜잭션과 동시성 향상(MVCC)을 위해서 Undo 정보를 보존하게 되는데, Undo 정보는 변경되기 전 데이터를 가지게 된다. 이러한 Undo 정보는 여러 가지 상황에 맞춰서 적절한 시점에 삭제가 되어야 하는데 이 작업을 Main thread가 처리한다 (이 작업을 Purge라고도 부른다.). 그런데 만약 MySQL 의 시작 과정에서 InnoDB가 이러한 Purge 작업 중 오류를 발생시킨다면, MySQL의 기동 시에 Main thread를 시작시키지 않기 때문에 Purge 작업 중의 오류를 피할 수 있게 되므로, 일단 MySQL을 시작시킬 수는 있게 된다. Undo 정보는 InnoDB의 시스템 테이블 스페이스에 관리되기 때문에, 이 경우에는 전체 데이터베이스를 덤프 받은 후 다시 MySQL 서버를 구성해야 한다.

·         3 ( SRV_FORCE_NO_TRX_UNDO )
MySQL을 종료하던 시점에 만약 진행 중인 트랜잭션이 있었다면, MySQL은 그냥 단순히 그 Connection을 강제로 끊어 버리게 된다. 그 이후 별도의 정리 작업은 진행하지 않게 된다. MySQL은 종료되었지만, 진행 중이던 트랜잭션의 정리 작업은 하지 않게 되는 것이다. MySQL이 다시 시작하게 되면, InnoDB 엔진은 트랜잭션 로그(Redo log라고도 함)를 읽어서 다시 처리 해주고(이 작업을  Roll forward라고 함), 최종적으로 어떤 트랜잭션이 완료되지 않고 Connection이 종료되었는지 판단 후, 그 트랜잭션들은 InnoDB 엔진이 Rollback을 시키게 되는데, 만약 Undo 영역이나 다른 관련된 데이터들이 손상된 경우에는 Rollback 처리를 해줄 수 없게 되는데, 이 경우에 사용하는 복구 모드이다. 이 경우에는 사실은 Rollback되어야 하지만, 실제 데이터 파일에는 그 데이터가 남아 있을 수 있다. (이 부분은 Binary log Application의 로그를 통해서 수동으로 보완해 주거나 무시하는 방법밖에 없다.)

·         4 ( SRV_FORCE_NO_IBUF_MERGE )
MySQL InnoDBINSERT, UPDATE, DELETE 등의 데이터 변경 작업으로 발생하는 인덱스 변경 작업들을 상황에 따라서 즉시 실행할 수도 또는 나중에 처리하도록 지연시킬 수 도 있다. 이렇게 나중에 처리하도록 지연시키기 위해서는 변경 내용을 어딘가에 기록해 두어야 하는데, 그 용도로 사용되는 버퍼가 "Insert Buffer"이다. Insert Buffer의 내용은 언제 데이터 파일에 병합(Merge)될지 알 수 없다. MySQL을 종료해도 병합되지 않을 수 있는데, 만약 MySQL이 재 시작 되면서 Insert Buffer의 손상을 감지하게 되면 Insert Buffer의 병합 작업이 실패하고 MySQL이 기동하지 못하게 된다. 이 경우 사용할 수 있는 강제 복구 모드이다. (이 경우에는 테이블 통계 정보 갱신을 유발하는 작업들을 해서는 안 된다. 주로 DDL이나 ANALYZE 명령 등). Insert Buffer는 실제 데이터와 관련된 부분이 아니라 인덱스에 관련된 부분이라 테이블을 덤프 후 다시 적재하면 처리될 수도 있고, 아니면 단순히 "ALTER TABLE tbl_name ENGINE=InnoDB;" 명령만으로 해결될 수도 있다.

·         5 ( SRV_FORCE_NO_UNDO_LOG_SCAN )
복구 모드 3 ( SRV_FORCE_NO_TRX_UNDO )의 처리와 비슷하며, 이 모드에서는 Undo 로그를 완전히 무시하고 완전히 종료되지 않은 트랜잭션(COMMIT/ROLLBACK되지 않은)을 모두 COMMIT된 것으로 처리해 버린다.  또한 이 모드에서는 Undo 로그를 전혀 참조하지 않는 형태로 강제 복구 시킨다.

·         6 ( SRV_FORCE_NO_LOG_REDO )
이것은 MySQL 서버가 재 시작되기 전 가장 뒤에 발생한 체크 포인트 이후의 모든 트랜잭션을 버리고 복구 시키는 모드이다. 당연히 Redo 로그를 참조하지 않으므로 Roll forward라는 작업도 하지 않고 강제 복구시키게 된다. Redo 로그가 손상된 경우 이 모드로 강제 복구가 가능하다.

여기서 설명된 강제 복구 모드는 그 설정 값이 높아질수록 손실되는 데이터가 많아지기(복구 가능한 데이터가 적어지기) 때문에, 가능한 강제 복구 모드를 낮은 것(1 -> 2 -> 3 -> 4 -> 5 -> 6)부터 시도해 볼 것을 추천한다.

아래 내용은 HighPerformanceMySQL 블로그에서 발췌한 내용을 번역한 것인데, 같이 참조하면 좋을 듯 하다.
InnoDB 테이블이 손상되는 경우는 상당히 희박
Double write, Checksum 그리고 기타 Validation 로직들과 버그 보완으로 인해서, 실제로 MyISAM에 비해서 InnoDB 테이블 스페이스 및 데이터 파일은 상당히 안정적이다.

대부분의 손상은 인덱스에서 발생
많은 사람들이 경험하는 InnoDB 데이터 파일의 손상은 80~90% 정도가 InnoDB 인덱스 (Secondary index)에 발생한 손상인 경우이며, 이 경우에는 단순히 ALTER TABLE 또는 데이터 덤프 및 재 적재만으로 해결된다. 복구 모드 "1 ( SRV_FORCE_IGNORE_CORRUPT )" 참조.

이 이외의 InnoDB 테이블의 문제점들의 경우는 덤프 및 적재
이 이외의 복잡한 형태의 장애에 대해서는, (아주 심한 경우가 아니라면)데이터베이스 전체를 덤프하고 다시 적재하는 것으로 해결될 수 있다. 하지만, 가장 최근의 백업에 Binary log Replay (재 실행)해주는 것보다 빠를지는 상황을 적절히 판단해서 결정하는 것이 좋을 듯 하다.


이래도 저래도 안 되는 경우에는(대표적으로 InnoDB의 시스템 테이블 스페이스가 손상된 경우) 아래 URL의 도구를 참조하는 것도 도움이 될 수 있을 듯 하다.
(사용해 본 경험이 없어서, 얼마나 작동할지는 잘 모르겠다.)
posted by 티니
:
Language 2009. 11. 21. 00:51

PHP 5.3.0 이상의 버전에서 mail() 함수로 메일을 발송할때
메일이 깨져서 발송되는걸 확인했다.

왜 그럴까 하고 메일헤더를 열어봤더니 평소에 볼 수 없던
'X-PHP-Originating-Script' 라는 헤더가 추가된걸 발견할 수 있었다.

도대체 이놈이 왜 붙나 한참을 고민하다 php.net을 찾아봤더니
PHP 5.3.0 부터 php.ini에 mail.add_x_header 라는 지시어가 추가된 것을 알 수 있었다.

이놈이 뭔가 했더니 스크립트의 UID와 파일명을 가지는 X-PHP-Originating-Script를 추가한다고 한다.

간단히 말해서..
'난 foobar.php 라는 놈에서 실행됐고 uid가 500으로 되어 있다.
의도하지 않은(인젝션 등) 메일이 발송된것이라면 이 파일을 잘 다듬어 봐라'
뭐 대략 이런 의도로 추가되지 않았을까 싶다.

우리 회사에서 저게 필요할까? 하고 잠깐 생각해봤으나
웹으로 메일 쏠 일이 매우 한정적이므로 불필요한 옵션이라 판단하고,
php.ini에서 mail.add_x_header = Off 시켜줌으로써 해결했다.

posted by 티니
:
리눅스 2009. 11. 3. 13:34
L4, LVS, DNS RR 등으로 여러대의 웹서버를 운영하다보면
늘 고민하게 되는게 세션 공유일 것 같다.

물론 L4의 Metric 중에 Hash를 이용하면 어느정도 해결 될 수 있는 문제이지만,
가끔 클라이언트가 다른 서버로 세션이 할당되는 경우를 볼 수 있다.

나 또한 이 문제로 많은 고민을 했고, 여러 많은 HOW를 보았지만 썩 마음에 드는것이 없었다.
아마 세션 공유를 위해서 사용되는 방법은 아래의 3가지가 가장 보편적이지 않을까 싶다.

1. NFS, Samba
특정 서버의 디렉토리를 다수의 웹서버에서 Network를 통해 공유하는 것이다.
그럼 한곳의 디렉토리에 모든 세션 파일이 존재할 것이고 문제는 해결이 된다.
그렇지만 NFS나 Samba는 Write 효율성이 상당히 떨어지는 데몬이다.
세션은 그 특성상 read/write가 매우 빈번히 일어나기 때문에 효율성 면에서는 좋지 않다.
(개인적으로 이 방법을 사용하다가 피본적이 있다-_-;;)

2. DBMS
세션 데이터를 DBMS와 연동하여 DB에 저장하는 방식이다.
보편적으로 주로 사용되는 방법이지만, 접속자가 매우 많은 환경에서는
DB서버에 부하가 늘어날 수 밖에 없는 구조이다.
또한 DBMS에서 생기는 lock도 무시못할 변수로 떠오를 수 있다.

3. Daemon
말 그대로 데몬을 이용하여 세션을 공유하는 방식이다.
세션서버를 따로 구축하기에 제일 적절한 방법이 아닐까 싶다.

늘 그렇지만.. 난 언제나 서론이 참 길다.
오늘은 sharedance 라는 데몬을 소개하고자 한다.
지인의 소개로 알게된 데몬인데..
약 2년정도를 15대의 웹서버에 적용해서 사용하고 계신다는데.. 별 문제는 없으시다고 한다.
그래서 현재 우리 회사에서도 적용중인 데몬이다.

1. 세션 서버 구성
이 데몬은 세션 서버로 사용될 서버에만 설치해주면 된다. 웹서버에는 설치할 필요가 없다.
sharedance의 최신버전은 http://sharedance.pureftpd.org/ 여기서 구할 수 있으며,
RPM으로 구하고 싶다면 http://rpm.pbone.net/ 에서 sharedance로 검색하면 된다.

1-1. RPM 설치
설치 끝났다. 참 쉽다. -_-

1-2. config 설정
sharedance의 환경설정 파일은 /etc/sysconfig/sharedance 에서 해주면 된다.
설정할 내용이 많은 것도 아니고, 달랑 2개면 된다.
SHAREDANCE_DIR="/var/lib/sharedance"
SHAREDANCE_OPTIONS="--expiration=1800 --timeout=1800"
SHAREDANCE_DIR 은 세션 파일이 저장될 디렉토리를 의미한다.
SHAREDANCE_OPTIONS 는 데몬을 시작할때 사용할 옵션을 지정해주는 것이다.
어떤 옵션들이 있는지 보고 싶다면 sharedanced --help 라고 치면 나온다.

1-3. sharedance 시작
[root@localhost]# /etc/init.d/sharedance start
이제 sharedance 사용 준비가 모두 완료 되었다.


2. Client 설정 (웹서버)
웹서버는 크게 설정하거나 설치할 내용이 없다.
단순히 php.ini에서 sharedance의 handler 파일만 호출해주도록 설정하면 된다.

2-1. handler 파일 준비
이 파일을 직접 만들 필요는 없고, sharedance 에서 제공하는 파일을 그대로 가져다 쓰면 된다.
세션서버에서 sharedance를 RPM으로 설치했다면,
/usr/share/doc/sharedance-0.6/php/ 에 핸들러 파일이 존재할 것이다.
[root@localhost]# ls /usr/share/doc/sharedance-0.6/php
session_handler.php  sharedance.php  test_session.php  test_sharedance.php
필요한 파일은 session_handler.php와 sharedance.php 파일이다.
이 2개의 파일을 웹서버로 전송한다.

2-2. handler 파일 복사 및 설정
세션서버에서 전송받은 핸들러 파일을 적당한곳에 잘 복사해두면 된다.
필자는 편의상 서버 운영에 필요한 파일을 한곳에 몰아서 관리하고 있기 때문에
/etc/sadmin/httpd/sharedance 에 복사를 했다.

핸들러 파일이 세션서버를 이용할 수 있도록, 핸들러 파일을 약간 수정해야 된다.
그렇지만 그리 어려운 내용은 아니기 때문에 쉽게 수정할 수 있다.
[root@localhost]# vi /etc/sadmin/httpd/sharedance/session_handler.php
define('SESSION_HANDLER_HOST', '192.168.0.100');
이 부분은 세션서버를 지정해주는 부분이다.
만약 세션서버가 같은 서버에서 돌고 있다면 localhost로 지정하면 될 것이고,
다른 서버에서 돌고 있다면 그 서버의 ip 혹은 host를 적어주면 된다.

[root@localhost]# vi /etc/sadmin/httpd/sharedance/sharedance.php
define('SHAREDANCE_DEFAULT_PORT', 1042);
define('SHAREDANCE_DEFAULT_TIMEOUT', 10);
이 부분은 세션서버의 listening port와 timeout 시간을 설정해주는 부분이다.
만약 세션서버에서 데몬의 포트가 다르게 설정되어 있다면 이곳에서 수정을 해주면 된다.

2-3. php.ini 설정
이제 모든 준비가 끝났으므로 웹서버의 PHP에서 session을 이용할때
sharedance의 핸들러를 통해 세션서버와 통신하도록 설정해주기만 하면 된다.
[root@localhost]# vi /etc/php.ini
...
auto_prepend_file = /etc/sadmin/httpd/sharedance/session_handler.php
...
session.save_handler = user
php.ini 수정이 모두 끝났으면 웹서버를 재시작하여 변경된 php.ini의 내용을 reload 시킨다.

3. sharedance 확인
모든 설정과 준비가 끝났다.
세션서버에 세션파일이 잘 생성 되는지 확인을 해보자.
[root@localhost]# ls /var/lib/sharedance
01c6hof0u872jp3grka4ifo3u4  4u44789jq4vtjt7l2fp3t1ime6  e7d6nq244j27l8bllif792pp25
...
...
위와 같이 세션파일이 생성이 된다면, 정상적으로 웹서버와 세션서버가 통신하고 있는 것이다.
posted by 티니
:
리눅스 2009. 7. 6. 09:54
회사에 새로운 솔루션이 도입이 되면서, DBMS의 파티셔닝 테이블을 필요로 했다.
그리고 MySQL은 5.1부터 파티셔닝 테이블을 지원한다.
그러나...
CentOS 5에서는 MySQL 5.0 버전을 지원하고 있는 관계로 그냥 사용할 수가 없다.

물론 간단히 소스컴파일 해서 사용하면 되지 않겠냐고 말하는 분들 있겠지만..
과감히 이런 멘트를 날려준다.
'아직도 컴파일이 멋지다고 생각하는가? 가장 좋을거라 생각하는가? 착각이다'
최적의 환경에서, 최적의 빌드옵션으로 빌드 할 자신 없다면 관둬라
불필요한 컴파일로 성능저하나 안일어나면 다행이다.

서론이 길었다.
그럼 어떻게 해야될까? 나의 repo tree를 뒤적뒤적 찾아보니...
오! thanks for Remi!!
MySQL 5.1을 지원해주고 있는 repository를 찾았다. (덤으로 PHP 5.2까지..)
바로 설치에 들어가보자 고고싱..

1. Remi의 yum repository 세팅
[root@localhost]# wget http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm
[root@localhost]# wget http://rpms.famillecollet.com/enterprise/remi-release-5.rpm
[root@localhost]# rpm -Uvh remi-release-5*.rpm epel-release-5*.rpm
/etc/yum.repos.d 안에 remi.repo 파일과 epel.repo 파일이 생성이 된다.
이제 사용할 준비가 완료 되었다. (너무 쉬운가?!)

2. MySQL 설치
[root@localhost]# yum --disablerepo \* --enablerepo remi install mysql
[root@localhost]# yum --disablerepo \* --enablerepo remi install mysqlclient15 mysqlclient15-devel
[root@localhost]# yum --disablerepo \* --enablerepo remi install mysql-server mysql-libs mysql-devel
remi의 repo를 enable 시켜줌과 동시에 모든 repo를 disable 시켜주는 이유는
centos base repo의 mysql(5.0)과 remi의 mysql(5.1)이 중복되지 않게 하기 위해서이다.

그리고 두번째 라인의 mysqlclient15 패키지는.. PHP에서 사용하는 라이브러리가 들어있다.
완전히 독립적인 DB 서버의 경우는 설치하지 않아도 되지만,
APM이 하나의 서버에서 운영되는 경우에는 반드시 설치해야 의존성 에러를 피할 수 있다.

자 설치가 다 끝났다. 이제 잘 쓰자.
참 쉽죠잉~?!
posted by 티니
:
카테고리 없음 2008. 12. 11. 11:20

반성16

술에 취하여
나는 수첩에다가 뭐라고 써 놓았다.
술이 깨니까
나는 그 글씨를 알아볼 수가 없었다.
세 병쯤 소주를 마시니까

'다시는 술마시지 말자'
고 써 있는 그 글씨가 보였다.


김영승의 詩集 '반성' 중에서...

... 가슴에 와닿는다.. -ㅅ-)y~ooO

posted by 티니
:
Flex 2008. 10. 13. 15:56

최근 웹 표준 2.0이다 뭐다해서 Ajax, Flex 등 관심이 많다.
나 또한 컴퓨터로 밥 벌어 먹는 사람이다보니, 자연스레 관심이 가기 마련이고..
한번 공부 해볼까?! 하는 열정이 또 끓어올랐다.

그러나 나의 열정은 곧 좌절로 이어질 수 밖에 없었는데..
Adobe에서 제공하는 튜토리얼이 영..-_-;;
영어로 설명되어 있는거 뭐 이런거야 그렇다치더라도..
너~~무 Flex Builder에 의존되어 있는 설명...
쳇-_- 결국 돈주고 사서 쓰라는거냐.. (궁시렁 궁시렁..)

한번 쓴맛을 보고 누군가 쉽게 써놓은 문서가 있지 않을까? 하는 생각에
평소 버릇처럼 검색엔진을 뒤적뒤적 하는데... 뭐..뭐냐..
참.. 할 말이 없었다.

결국 그냥 깡 삽질 시작..
이제부터 그 삽질을 좀 정리해서 써볼까 한다.

아아.. 잡설이 너무 길었다.
간단하게 정리부터 해보자면 Flex 개발환경은 크게 2가지로 구축할 수 있다.

1. Flex Builder
2. Flash Develop + Flex SDK (+ JRE)

첫번째로는 어도비에서 상용으로 제공하는 빌더가 있다.
프로페셔널 에디션 버전이 $699 정도 하는데......
일하는거면 몰라두.. 공부하고자 하는데 돈 투자하기 솔직히 힘든게 사실..
(혹시해서 잠깐 검색해봤지만.. 역시 전세계 유틸리터들 멋지다. 벌써 크랙 엄청 많다)
그러나 역시 개발 생산성을 고려한다면 전문 빌더만큼 추천할만한게 또 있을까 싶기도 하다.

두번째로는 Flash Develop을 이용하는 방법이 있다.
이건.. 일일히 개발환경을 다~~ 세팅해야된다. 손수!
난 이제부터 이 두번째 방법을 설명할 것이다.

1. Java Runtime Environment(JRE) 설치
(다운로드: http://www.java.com/ko/download/)
Flex SDK를 이용하려면 JRE(혹은 JDK)가 필요하다.
왜냐고?! 필요하니까 필요하겠지-.-;; (퍽!)

왠지 첨부터 되게 어려울것 같은 느낌인가?! 긴장 풀어라. 별거 없다.
그냥 다운로드 URL로 가서 '무료 Java Download' 라는 이미지만 클릭하면 끝난다.

2. .NET Framework 2.0 Redistributable 설치
(다운로드: http://www.microsoft.com/downloads/details.aspx?displaylang=ko&FamilyID=333325fd-ae52-4e35-b531-508d977d32a6)
이것 또한 다운로드 받아서 설치만 해주면 된다.

3. Flex SDK 설치
(다운로드: http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+3/)
Flex SDK는 여러가지 버전이 존재한다.
- (Free)Adobe Flex SDK : 공식 제품 버전
- Open Source Flex SDK : 오픈소스 코드가 포함된 버전
- Adobe Add-ons : 오픈소스SDK에 포함되지 않은 Flex Builer에 있는 잡종들(?)을 제공
이처럼 여러가지 버전이 존재하는데, 이중 나는 공식버전을 사용할 것이다.

3-1. 다운로드 및 설치
다운로드 URL로 가서 Stable Builds에 있는 Adobe Flex SDK 최신버전을 다운로드 받으면 된다.

딱히 인스톨 파일이나 그런걸로 제공하는건 아니고, 그냥 압축 파일이다.
그래서 나는 C:\Program Files\Adobe\Flex SDK3 에 압축을 풀었다.

3-2. 시스템 환경설정
매번 빌드시마다 저 풀 경로를 써야 된다고 생각해보았는가?!
어우.. 그런일은 상상조차 하지마라. 끔찍하다.
따라서 시스템 환경설정에 저 경로를 입력해 주도록 하겠다.
시스템 환경설정하는 방법이 조금 어려울 수 있는데.. 잘 따라하면 쉽게 끝날 수 있다.

※ 대괄호[]로 묶인 부분은 새로 뜨는 창 이름이다.
ㄱ. 제어판 -> 시스템 -> [시스템등록정보] -> 고급 -> 환경변수
ㄴ. 시스템변수 ANT_PATH 추가
 * [환경변수] -> 새로만들기(시스템변수) -> [새 시스템 변수]
 - 변수이름 : ANT_PATH
 - 변수 값 : C:\Program Files\Adobe\Flex SDK3\ant
ㄷ. 시스템변수 Path 수정
 * 시스템변수 내용중 Path를 찾아서 편집(시스템변수)
 - 변수값 내용 끝에 ;%ANT_PATH%\bin 라고 추가
 (※ 주의!! 기존 내용을 지우면 안됨. 간혹 지우시는 분들 계심--;;)

4. Flash Player Debugger 설치
(다운로드: http://www.adobe.com/support/flashplayer/downloads.html)

이건 말 그대로 디버거이다. 디버깅 할때 사용하는 툴이니.. 옵션이다.
설치하고 싶은 사람만 설치하라. (참고로 나는 그냥 패스..)

다운로드 URL로 가서 Adobe Flash Player 9 — Debugger Versions (aka debug players or content debuggers) for Flex and Flash Developers 라는 곳을 보라.
각자 사용하는 브라우저에 맞는 디버거 버전을 다운로드 받아서 설치하면 된다.

5. Flash Develop 설치
다운로드: http://www.flashdevelop.org/community/viewforum.php?f=11)
드디어 마지막이다. Hello World가 얼마 남지 않았다-.-
별도 설명 필요 없다. 설치 고고싱!

posted by 티니
:
리눅스 2008. 7. 10. 11:47

작년초 구입했던 6TB DAS 용량이 거의 풀인 관계로...
이번엔 10TB DAS를 구입했다.

헤더는 147GB SAS 2.5' 10k * 4EA로 구성되어 있고, RAID-10으로 묶어둔 상태이다.
바디는 뭐 말할것두 없이 RAID-5이고...

OS는 CentOS 5.2 x86_64 버전을 설치 했다.

헤더에 OS 설치하고, 바디 파티션 세팅하기에 앞서 이거저거 생각하다보니.. 음...-_-
ext3는 8TB 밖에 지원이 안되네.. 흠흠..
그래서 xfs를 사용하기로 결정했다. (ext4가 어여 stable이 되었으면 좋겠건만...)

자.. 우선 fdisk로 확인을 해보자..
[root@str3 ~]# fdisk -l
Disk /dev/sda: 292.3 GB, 292326211584 bytes
255 heads, 63 sectors/track, 35539 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
 
   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          33      265041   83  Linux
/dev/sda2              34         425     3148740   83  Linux
/dev/sda3             426         686     2096482+  83  Linux
/dev/sda4             687       35539   279956722+   5  Extended
/dev/sda5             687        1991    10482381   83  Linux
/dev/sda6            1992        2252     2096451   82  Linux swap / Solaris
/dev/sda7            2253        2513     2096451   82  Linux swap / Solaris
/dev/sda8            2514        2774     2096451   83  Linux
/dev/sda9            2775        2839      522081   83  Linux
/dev/sda10           2840       35539   262662718+  83  Linux
 
WARNING: GPT (GUID Partition Table) detected on '/dev/sdb'! The util fdisk doesn't support GPT. Use GNU Parted.
 
 
Disk /dev/sdb: 10494.4 GB, 10494484152320 bytes
255 heads, 63 sectors/track, 1275881 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
 
   Device Boot      Start         End      Blocks   Id  System

흠흠... fdisk에서 졸라 큰 파티션(10494.4GB/10TB)을 발견했다고 경고를 한다.
걍 쌩까자-_-);; 쟤는 맨날 저런다-_-;;

이제 파티션을 구성해야겠지?
지난번 6TB DAS 세팅할때도 말했지만.. fdisk에선 2TB 이상 지원 못한다.
그러니 parted 유틸리티를 이용하자.
[root@str3 ~]# parted /dev/sdb
GNU Parted 1.8.1
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) p
 
Model: DELL PERC 6/E Adapter (scsi)
Disk /dev/sdb: 10.5TB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
 
Number  Start  End  Size  File system  Name  Flags
(parted) mkpart
Partition name?  []?
File system type?  [ext2]? xfs
Start? 0
End? 10.5TB
(parted) p
Model: DELL PERC 6/E Adapter (scsi)
Disk /dev/sdb: 10.5TB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Number  Start   End     Size    File system  Name  Flags
 1      17.4kB  10.5TB  10.5TB
(parted) quit
Information: Don't forget to update /etc/fstab, if necessary.

자.. 이제 파티션을 생성했으니.. 파일시스템을 생성해서 사용하기만 하면 된다.
그러나 여기서 잠깐!
이 상태에서는 xfs 파일시스템을 생성할 수가 없다.
왜냐하면, redhat 에서는 기본적으로 xfs를 서포트하고 있지 않기 때문이다.
따라서 몇가지 xfs 관련 패키지를 설치해주어야 된다.
[root@str3 ~]# yum -y install xfsprogs xfsdump kmod-xfs
Setting up Install Process
...
...
Complete!

패키지를 모두 설치했으면, 이제 파일시스템을 생성해보자.
[root@str3 ~]# mkfs -t xfs /dev/sdb1
meta-data=/dev/sdb1              isize=256    agcount=32, agsize=80066559 blks
         =                       sectsz=512   attr=0
data     =                       bsize=4096   blocks=2562129888, imaxpct=25
         =                       sunit=0      swidth=0 blks, unwritten=1
naming   =version 2              bsize=4096 
log      =internal log           bsize=4096   blocks=32768, version=1
         =                       sectsz=512   sunit=0 blks, lazy-count=0
realtime =none                   extsz=4096   blocks=0, rtextents=0

정상적으로 파일시스템이 생성되었다.
이제 마운트하고 잘 쓰자 -_-);;
posted by 티니
:
카테고리 없음 2008. 6. 19. 16:46


posted by 티니
:
Language 2008. 5. 28. 14:19

------
원문 출처를 모릅니다.. 아시는분 알려주세요..
------

이 속도 테스트 보다 더 중요한 것이 PHP보안 입니다. 보안이 가장 중요함당 !!!

PHP로 코딩 함에 있어서 알아야 할 속도 테스트 입니다.
조금더 빠른 PHP 속도를 유지 하기 위한 것이죠 ^^

작은 것이 모여서, 대따 오랜 시간이 걸릴 수 가 있는 것 입니다. !!
되도록이면 속도가 빠른 것을 사용하시는 것이 좋습니다.

물론 함수 마다 기능 마다 장단이 있지만요....^^

다른 비교가 있으면 알려주셍 ^^ 답변 달아 주세용 ^^
계속 적으로 업글 됩니다.

★ mysql 총 게시물 수 세기

<?php
    $numresults=mysql_query("select code from $board");
    $numrows=mysql_num_rows($numresults);
    //2초 이상 ...게시물 10만개
?>
VS
<?php
    $numresults=mysql_query("select count(code) as code from $board");
    $row_num=mysql_fetch_array($numresults);
    $numrows=$row_num[code];
// 0.2  ...게시물 10만개
?>
아래것이 훠얼씬 빠름다..
도대체 mysql_num_row() 는 왜 만들어 놓은 것일까용???
 


★ mysql_fetch_row  > mysql_fetch_array >>> mysql_result 입니다.


row 가 array 보다 약간 빠르고, result 보다는 훠얼씬 빠름당 ^^
row 는 불편한게 숫자로 칼럼을 불러와서 불편합니다.
array 가 약간 느리지만, 문자 칼럼을 불러 올 수 있으니 array 쓰는 것도 양호 ^^
아직도 mysql_result() 를 사용하시나요?
 


★print , echo ,printf 함수 속도 비교

HTML 출력 >> echo > print >> printf

print 와 printf 함수는 복잡한곳에 적격이고, 약간 느리다.
echo 는 단순한곳에 적격이고...빠르다.
printf 는 형식화된 출력을 해주므로 그래도 좋죠 ^^
 


★  인라인


a.php
<?php
    $aa="sdsdsdsd";
    echo ("
      <table>
      <td> $aa </td>
      </table>
      ");
?>
위 랑..

b.php
<?php $aa="sdsdsdsd"; ?>
<table>
<td><?=$aa;?></td>
</table>

랑 도대체 어케 코딩 하느냐죠 ?
솔직히 코딩은 a.php 가 편합니다.
<?php ?> 를 한번 만 쓰니까 효율적일 수 있습니당..
그러나 아무리 아무리 PHP가 빠르다고 해도 HTML 이 더 빠릅니당.. !!!
쿠쿠쿠
b.php 처럼 코딩 하는 습관을 가지세용 ^^
변수가 많아 질 경우 b.php 파일이 느립니다.
그러나 소스 코드 분리 측면에서는 b.php 파일 형태가 좋습니다.
이 부분은 여러분들이나 저나 각종소스를 가지고 연구해 봐야만 할검당 ^^
 


★ zend cache , APC ,Bware 캐쉬 비교

Zend cache > APC > Bware
zend cache 는 캐쉬 입니다. 울나라에서 포탈에서도 몇군데 사용하죠.
PHP 프로그램 변환 없이 속도를 빠르게 해 줍니다. ^^
zend cache 를 살 돈이 없으시다구용?
그러면 APC 나 zend optimizer 를 반드쉬 설치 하세용 !!
■ 그런디 Zend Cache 만한 무료 캐쉬가 나왔다고 합니당...^^
http://www.php-accelerator.co.uk/index.php
도대체 캐쉬의 작동 원리는 어케 되는가?
캐쉬는 여러가지로 작동 할 수 있습니다.
가장 많이 아는 것이 메모리에 페이지를 띄워 놓고 읽어 오는 것입니다.
하드에서 읽는 것 보다 빠르기 때문이죠.
그리고 HTML 로 만드는 것도 캐쉬 입니다.조금 더 빠르다면 캐쉬 라고 할 수 있습니다.
게시판 목록 보기 페이지는 디비 연결이 많습니다. 쓰기 보다 , 읽기가 20배 정도 많습니다.
게시판을 마니 운영해 봤다면 아시겟죠 ^^?
그래서 게시판 목록을 HTML 로 저장 시키고, 쓰기, 삭제 가 있을때 마다 HTML 로 만들어 주는 것 입니다.
그러면 디비 부하는 상당히 줄어 듭니다.
또는 코딩을 할때 enter 이나 tab 키를 많이 사용해서 합니다.
저번에 본 캐쉬는 enter 이나 tab 키를 없에 주는 캐쉬 였습니다.
enter 이나 tab 를 없엘 경우 최대 1-2k 정도 절약이 되죵 ^^
 


★ ereg_replace <<<  preg_replace 정규표현식

ereg_replace () 가 장난 아니게 느림다.
40개 정도 변환 하는데 1초나 걸려요.preg_replace 는 0.3초 정도요.
되도록이면 preg_replace() 를 사용하세요 !!!
www.php.net/preg_replace
tood.net preg_replace 강좌
http://www.tood.net/tood/toodboard/toodread.php?board=tootech&tcode=907
 


★ foreach , list 함수 속도 차이 35%

foreach($string as $a);  >>>  while(list(,$a) = each($string));
foreach() 를 사용하는 것이 35% 정도 빠릅니다...!!
 


★ explode() Vs split() Vs preg_split

explode() 와  split() 와 preg_split 는 문자열을 자르는 함수 입니다.
테스뚜 해보시면 아시겟지만 explode() 가 훨 빠릅니당..!!!
70% 정도 빠릅니다.
 



★mysql_connect Vs mysql_pconnect

서로 장단이 있다 합니다.
mysql_pconnect 가 더 빠르다고 합니다.
persistant
메뉴얼에 영구적인 이렇게 되어 있으니까요..
일정시간 동안 mysql 을 열어 놓기 때문에, 다시 열 필요가 없어서 빠르다고 합니다.
단점은 계속 열기 때문에 메모리를 많이 잡아 먹슴당...^^
mysql_pconnect 경우는 최소 메모리가 1G 이상 되어야 사용하시는 것이 좋습니다.
 


★ 큰따옴표(") , 작은 따옴표(')

큰따옴표는 PHP가 파싱을 합니다. 그러나 작은 따옴표는 파싱을 하지 않습니다.
작은 따옴표를 사용하시는 것이 빠릅니다.
코딩시 echo ' test '.$aaa.' tood ';
요런식으로 하시는 게 가장 빠름당 !!
 


★ mysql 데이터 저장 공간 크기 ?

id int(11) unsigned NOT NULL auto_increment,
   bbs smallint(5) unsigned NOT NULL,
   lens mediumint(8) unsigned NOT NULL,
  
int 도 무자게 많슴당..
각각의 크기에 맞게 하는 것이 속도가 빨라 집니당 ^^
not null 를 주는 것도 속도가 빨라 집니당..
작은 사이트 조회수 경우 1만을 넘기도 힘듭니다. 그럴 경우 smallint 를 사용하시면 됩니다.
 


★ where 절에 모든 것은 인덱스를 걸어라 !!!

mysql 에서 쿼리시에 where 절에 사용되는 비교의 칼럼은 반드쉬 인덱스를 거세용 !!!
mysql 인덱스 가 여러 분들의 게시판 속도를 업 시켜 줍니당 !!
 


★메인페이지에서 속도를 빠르게 하려면, .htm 으로 만드는 것이 좋습니다.

그러니까..제 사이트 페이지 오른쪽 에는 모두 최신 게시물로 디비를 불러오는 부분
입니다.
디비 연결은 부하를 줄 수 있습니다.
그러니까..이예는 사이트가 상당히 활성화된 사이트일 경우 입니다.
하루에 2번 정도 .htm 으로 만들어 페이지를 업시키는 것이 좋습니다.
아무리 PHP가 빨라도 HTML 보다는 빠르지 않습니다.. !!!
HTML 로 만드는 것은 생각 할것이 게시판 목록수 만큼 파일이 생성이 됩니다. 1만개 게시물이면 1만개 HTML
이 생기죠. 그런데 조회수가 보통 1000-3000 을 넘는 게시판 경우는 효율성이 중대 됩니다.
그러나 조회수가 100 비스므리 하다면...생각해봐야 합니다.
그러기 위해서는 ★cron 를 알아야 합니다 PHP강좌 게시판에서 cron 으로 검색하세용 !!
윈도우 사용자는 멀 쓰는지 잘 모르겠슴당...아시면 답글 부탁  ^^
 


★ 초보자 Vs 전문가

www.zend.com 에서 제가 2000년 5월에 퍼온건데용 ^^  
함 주석을 붙일까 해서용^^

Beginner vs Experienced   
Author:  Boaz Yahav   
Date  23/05/2000   
Beginner : echo "$var";  
Experienced : echo $var;  

Beginner:echo "<a href=\"http://www.php.net\">PHP</a>";  ;
Experienced : ?><a href="http://www.php.net">PHP</a> color="#0000CC"><?  ... ?>  
◆ "(따옴표) 가 굉장히 중요한것이라는 한 대목이죵 ^^
전 보통의 경우 php 변수 값이 들어갈 경우는 초보자 처럼 쓰구요 ^^ 안들어 갈 경우 는 전문가 처럼 씀다.
Beginner : $a[0]=1; $a[1]=2; $a[2]=3;  
Experienced : $a = array(1,2,3, 1);  
둘다 사용하는 데요. 전문가 쪽이 편함다. ^^
Beginner : if($a>1) { $b=2; } else { $b=3; }  
Experienced : $b = ($a>1) ? 2:3;  
요건 완존히 소스 어렵게 짜는 넘이 최고 라는 소리 같네용 ^^
전문가 쪽것은 C 언어 에서 배웠는데도 역시 전 if 씀다. ^^
Beginner : $result=mysql_query(...);  
Experienced: $result=mysql_query(...) OR die   
        (mysql_error());  
요즘 들어 새삼 전문가 쪽으로 씀다.^^
보통의 경우
<?php
$result=mysql_query(...)  
if (!$result)
{
     echo error()."<P>";
     echo errno();
}
?>
이렇게 사용함다. ^^
or 이 설명이고 no 가 에러 번호 일 검다. ^^
 


★MySQL,ADODB,PHPLib,PEAR 벤치마킹  

ADODB > PHPlib > PEAR
MySQL     1.14      -
ADODB     1.45     27%
PHPLib    1.60     40%
PEAR     2.87     152% (fetchInto)
MySQL,ADODB,PHPLib,PEAR  는 모두 데이터베이스 인가요? 당근 아닙니다.
MySQL만 데이터베이스 구요.
ADODB,PHPLib,PEAR 는 PHP 프로그램 입니다.
3개 다 MySQL연결을 편하게 하는 클래스 프로그램 입니다.
그런디 벤치 마킹 결과 MySQL 에서 직접 쿼리하는 것 다음으로 ADODB 가 뽑혔슴당 ^^
PEAR 가 굉장히 늦군요. PEAR DB 나 ADODB 를 사용해 보았는데, 움..역시나 ADODB 가 좋군요.
오라클, mysql , ms sql 연결시 1개의 API 만 사용할 수 있는 프로그램 들 이 PEAR 과 ADODB 입니당 ^^
 


★ 페이지 네비게이션- 페이지 분활

페이지 분활도 속도 차이가 납니다. 각각의 페이지 분활을 테스트 해보시면 아시겟지만,
10만개,20만개의 데이터를 넣어 보세요. 빠른것은 0.03초 정도, 느린것은 3초나 걸립니다.
인덱스를 걸어서 빨리 뜨는데, 머가 늦는 걸까 했는데, 페이지 네비게이션 알고리즘이 문제더군요. ^^
 


★ 속도 테스트는 어케 하는가 ? microtime() 사용하면 됩니다.

<?php
function pageTime($page) {
$mstart = explode(" ", $m);
$mend = explode(" ", microtime());
$mtime = ($mend[1] - $mstart[1]) + ($mend[0] - $mstart[0]);
echo " $m[1]  $mend[1]<P>";
echo " $m[0]  $mend[0]<P>";
print("tood.net 페이지 로딩 시간 : " . $mtime . " microseconds");
}
pageTime(basename($PHP_SELF));
?>
 


조금 더 빠른 쿼리

$sql = "SELECT table.column FROM table WHERE criteria LIKE $myrow[variable]";
아래 처럼 하면 파싱 되지 않기 때문에 아주 아주 쪼금 빨라 짐다..0.0000x 초;
$sql = "SELECT table.column FROM table WHERE criteria LIKE " . $myrow['variable'];
 


최적화 컴파일 옵션 사용 !

PHP counfigure 시에 최적화 방법 입니다.
http://www.tood.net/tood/toodboard/toodread.php?board=tootech&tcode=1070

posted by 티니
:
리눅스 2008. 5. 19. 09:11

grep : 패턴을 이용한 search => regular expression을 잘 만드는 것이 필요하다.

  grep option(s) pattern filename(s)

OS/tdir] grep -n dba /etc/group       # -n : 파일 안에서의 패턴이 발견된 라인 및 라인 번호
OS/tdir] grep
-v dba /etc/group           # -v  : 패턴이 발견되지 않은 라인
OS/tdir] grep -n dba
/etc/group /etc/passwd          # 파일을 여러개 나열...
OS/tdir] grep
-i the ~/tdir/*                 # -i : 대소구분 무시(ignore) => the 대소구분 없이
OS/tdir] grep
-li the ~/tdir/*                 # -l : 패턴이 들어있는 파일 이름만... 
OS/tdir] grep
-c the ~/tdir/*                 # -c : 패턴이 들어있는 라인 번호만...

[패턴을 좀더 정교하게 표현하려면 regular expression을 사용해야 한다]

^      : ^패턴            : 패턴으로 시작하는 모든 라인 찾기
$      : 패턴$           : 패턴으로 끝나는 모든 라인 찾기
.       : d...              : d로 시작하는 4자리 character 찾기
*      : [a-d]*          : a, b, c, d로 시작하는 character 찾기
[]    : [Dd]atabase  : Database 또는 database 찾기
[^]   : [^D]             : D가 나타나지 않는 라인 찾기

OS/tdir] grep -i ^the ~/tdir/*              # the로 시작하는 라인 찾기
OS/tdir] grep -i
meal.$ ~/tdir/*          # meal.으로 끝나는 라인 찾기
OS/tdir] grep
c...d ~/tdir/*                # c로 시작하고 d로 끝나는 5자리 character 찾기

================================================================

▒  egrep(expression grep) : searches  files  for  a pattern of characters
                                           and prints all lines that contain that pattern.

 

OS/tdir] egrep '(a|A)d+' /etc/passwd   # ad 또는 Ad가 포함된 라인 찾기
OS/tdir] vi grep_test                               # 아래 내용을 추가하세요... 붙여넣기... ^^

An Oracle database is a collection of data treated as a unit.
The purpose of a database is to store and retrieve related information.
A database server is the key to solving the problems of information management.

OS/tdir] egrep 'Oracle|purpose' grep_test   # Oracle 또는 purpose가 포함된 라인 찾기

===============================================================

sed : stream editor => file을 열지 않고 data를 편집하는 기능

  sed [-options] [address] command file... [>newfile]

 

# sed '/pattern/d' filename # file에서 패턴이 포함된 라인을 지우고 그 결과를 화면에 표시
                                          #
원본 파일에는 아무런 변화가 없다.

OS/tdir] cp grep_test sed_test
OS/tdir] cat sed_test
OS/tdir] sed
'/purpose/d' sed_test                  # purpose 라는 단어가 들어간 라인 삭제

 # sed '#d' filename      : # 라인만 삭제
# sed
'$d' filename      : 마지막 라인 삭제
# sed
'#,$d' filename   : # 라인부터 마지막 라인까지 지우기
# sed
'#,#d' filename   : # 라인부터 # 라인까지 지우기  

OS/tdir] sed '1d' sed_test     # 1 라인만 삭제
OS/tdir] sed
'$d' sed_test     # 마지막 라인만 삭제

OS/tdir] sed '/purpose/d' sed_test > set_out     # sed 처리 결과를 sed_out 으로 저장
OS/tdir] cat set_out

OS/tdir] sed '/purpose/p' sed_test             # 패턴이 포함된 라인이 두번 출력(print)된다.
OS/tdir] sed
-n '/purpose/p' sed_test        # 패턴이 포함된 라인만 출력된다.

OS/tdir] sed 's/$/  Oracle/' sed_test       # 각 라인의 마지막에 원하는 글자 추가

OS/tdir] sed 's/  */#/g' sed_test              # space를 찾아서 #기호로 변환한다.
OS/tdir] sed '
s/  */-/g' sed_test              # space를 찾아서 -기호로 변환한다.
                                                                      # * 기호 앞에 space가 두개라는 점에 유의

OS/tdir] # 한번에 여러 가지 편집 수행
OS/tdir] sed
-e 's/database/DATABASE/g' -e 's/information/INFORMATION/g' sed_test

===============================================================

awk : 패턴 검색과 처리를 위한 언어

=> 명령어의 이름은 개발자인 Alfred V. Aho, Peter J. Weinberger, Brian W. Kernighan 3인의
    머리글자를 사용해서 만든 것이다.

  awk '{ action}' filename

OS/tdir] ls -l | awk '{print $0}'              # 전체 필드가 모두 나타나도록...

drwxr-xr-x   2   prof9i4  dba          512  4월   25일  15:44   a_dir
drwxr-xr-x   2   prof9i4  dba          512  4월   18일  23:53   b_dir

     $1     $2     $3   $4        $5  $6   $7     $8    $9
                                        $0                                            

 

OS/tdir] ls -l | awk '{print $1}'                    # 1번 필드만 나타도록...
OS/tdir] ls -l | awk '{print $1, $9}'               # 1번과 9번 필드만 나타나도록...
OS/tdir] ls -l | awk '{print $3 "\t" $4 "\t" $9}'                # Tab 키가 적용된 결과...
OS/tdir] ls -lt | awk '{print $9, "is using", $5, "bytes"}'     # text 추가
OS/tdir] ls -lt | awk '
$5 <= 200 {print $0}'   # 5번 필드가 200 이하일 경우 출력

posted by 티니
: