2011년 11월 30일 수요일

marked as crashed and should be repaired

Problem
디비 서버를 운영하다보면 아래와 같은 에러와 함께 db서버가 죽어버리는 경우가 있다.
091030 13:40:29 [ERROR] /usr/libexec/mysqld: Table ‘.some_table’ is marked as crashed and should be repaired
Solution
mysql> analyze table some_table;
mysql> repaire table some_table;
//위에서 실패하면 아래 실행
]# myisamchk -r some_table;
위와 같이 repair를 하면 쉽게 해결되기는 하지만, 그 원인은 뭘까?
mysql Reference에서 How to Repair MyISAM Tables 페이지에서 찾을 수 있었다.
위의 문제는 다음과 같은 충돌들로 일어날 수 있다.
  • tbl_name.frm이 변경에 대해서 락이 걸려있는 경우
  • tbl_name.MYI(Errcod:nnn)을 찾을 수 없는 경우
  • 파일이 unexpected end일 경우
  • 저장 파일이 충돌했을 경우
  • 테이블 핸들러로부터 nnn에러를 받았을 경우
위에서 말하는 nnn 에러는 system error로 다음 커맨드로 그 의미를 알아볼 수 있다.
]# perror 126 127 132 134 135 136 141 144 145
MySQL error code 126 = Index file is crashed
MySQL error code 127 = Record-file is crashed
MySQL error code 132 = Old database file
MySQL error code 134 = Record was already deleted (or record file crashed)
MySQL error code 135 = No more room in record file
MySQL error code 136 = No more room in index file
MySQL error code 141 = Duplicate unique key or constraint on write or update
MySQL error code 144 = Table is crashed and last repair failed
MySQL error code 145 = Table was marked as crashed and should be repaired
위의 145 번 에러 코드가 이번 경우에 해당 되었다.
참고로 135번과 136번에러는 테이블의 MAX_ROWS와 AVG_ROW_LENGTH를 수정해서 고칠 수 있다.
mysql>ALTER TABLE tbl_name MAX_ROWS=xxxAVG_ROW_LENGTH=yyy;
현재 테이블 옵션이 어떻게 되어 있는지 보려면 아래 명령어로 보자.
mysql>SHOW CREATE TABLE some_table;
다른 에러들에 대한 대처는 myisamchk르 대부분이 찾아내서 고칠 수 있다.
이 작업을 하기 전에 디비 테이블 파일들에 대한 권한을 확인한다.(없으면 부여)
먼저 mysqld서버를 중지한다.(유의: 중지 후 바로 디비 서버가 바로 죽지 않는다. 모든 index 변경사항이 디스크에 플러시 될때까지가 중지되는 시점이다)
Stage 1: 테이블 검사
]# myisamchk *.MYI
이 작업으로 error라고 판별된 테이블에 대해서만 Stage 2에서 고쳐질 수 있으며, 이 커맨드 과정에서 에러(e.g. out of memory)가 나면 Stage 3로 너어가면 된다.
Stage 2: Easy safe repair
]# myisamchk -r -q tbl_name (-r -q 은 “빠른 복구 모드”)
이는 data file을 건들지 않고 index file을 고치는 커맨드이다.
  1. Make a backup of the data file before continuing.
  2. Use myisamchk -r tbl_name (-r means “recovery mode”). This removes incorrect rows and deleted rows from the data file and reconstructs the index file.
  3. If the preceding step fails, use myisamchk –safe-recovertbl_name. Safe recovery mode uses an old recovery method that handles a few cases that regular recovery mode does not (but is slower).
나는 여기까지로 대부분이 해결이 되었다.
stage 3에 대한 방법, 그 외의 방법은 How to Repair MyISAM Tables를 참고하면 되겠다.

MySQL/PgSQL 웹 연동시 too many connection 에러 처리

MySQL이나 PgSQL을 아파치/PHP와 연동하여 사용할 때 db와 연결이 잘 되지 않는 경우가 종종 발생하며 사용자가 많지 않은데도 접속 에러가 뜨는 경우가 많이 있습니다.

이는 db 서버와 웹서버, 그리고 PHP의 설정 파라미터를 조정해 줌으로서 쉽게 해결할 수 있습니다. 점검해볼 항목은 다음과 같습니다.

PgSQL의 경우 /etc/postgresql/postgresql.conf 에 보면

max_connections = 64

와 같은 부분이 있습니다. 이는 PgSQL이 동시에 받아들일 수 있는 최대 접속 수입니다.

아파치 웹서버 설정 파일인 httpd.conf에는

MaxClients 90

과 같은 부분이 있습니다. 이는 아파치 웹서버가 동시에 처리할 수 있는 클라이언트의 숫자입니다.

PgSQL을 예로 들자면, php.ini에 다음과 같은 내용이 있습니다.

pgsql.allow_persistent = On 
pgsql.max_persistent = 2 #max persistant links per process
pgsql.max_links = 16 # max pers/non-pers links per process

여기서 웹서버(PHP)가 PgSQL에 정의된 숫자보다 더 많은 접속을 시도할 경우 접속을 하지 못하고 에러가 발생하게 됩니다.

그러므로 MaxClients * pgsql.max_persistent < max_connections 가 되도록 설정값을 조정해 주어야 합니다.

지금 적힌 대로 시스템이 설정되어 있다면 90 * 2 > 64 이므로 위의 식을 만족하지 못하기 때문에 금방 db 커넥션 관련 에러가 발생하게 됩니다.

웹서버가 좀더 많은 사용자를 커버할 수 있도록 튜닝을 하더라도 위의 공식을 염두에 두고 튜닝을 해야 사용자가 얼마 없는 상황에서 db 접속을 하지 못하는 현상을 방지할 수 있습니다.

만약 위의 경우에서 웹서버와 db서버가 분리된 상태라면 각각의 MaxClients * pgsql.max_persistent 값을 더한 것이 db서버측의 max_connections를 넘지 않도록 튜닝해야 합니다.

MySQL의 경우 wait_timeout값을 매우 짧게 설정함으로서 idle 프로세스를 최대한 줄이는 방법도 있습니다만 db서버와 웹서버의 관계를 잘 고려하여 튜닝을 한다면 같은 하드웨어 사양으로도 좀더 효율적인 튜닝이 가능할 것입니다.

저도 이문제 때문에 한참을 고민하다가 postgresql 메일링 리스트에서 힌트를 얻었습니다. 위의 글은 PgSQL기준이지만 MySQL에서도 기본은 같으므로 따로 설명을 하지는 않겠습니다.

도움이 되었기를 바랍니다....

[mysql]too many connections 해결

mysql을 설치하여 사용하다보면, 서버부하가 없음에도 불구하고 "Warning...too many connections...."라는 메시지와 함께 MySQL 이 뻗어버리는 경우가 있습니다.
원인은 Mysql의 실행환경변수 설정에 있다 .
우선 Mysql설치홈의 bin디렉토리에서 "./mysqladmin -u -p variables"라고 해보시면 다음과 유사한 결과를 얻으실수 있다.

위의 결과에서

max_connections            | 1000
wait_timeout               | 300  

와 같은 것을 볼수 있습니다 .

max_connections는 mysql에 connect할수 있는 최대 갯수를 지정해 둔것이다.
"too many connections"라는 메시지는 이 갯수를 초과해서 connect하려고 할때 발생하는 메시지이다.

결론부터 말씀드리자면 이 갯수를 적절히 조절해야한다고 말씀드릴수 있다.
하지만, max_connections 아래에 있는 wait_timeout이란 variable은 connect된 후에 몇초간 지속적으로 연결을 유지할 것인가를 지정해 둔 것이다.

이를 설명하기 위해서는 mysql_connect()와 mysql_pconnect의 차이점 그리고, mysql_close()함수에 대한 정확한 이해가 필요하다.

간단히 설명해 보자면, mysql_connect()함수로 DB connect를 했다면 해당스크립트가 종료됨과 동시에 mysql_close()함수를 호출하지않아도 자동으로 연결이 종료된다.

하지만, mysql_pconnect()함수는 해당스크립트가 종료된후 mysql_close()함수가 호출되었더라도 연결이 끊어지지않은채로 계속 연결을 유지하고 있다.

따라서, 얼핏보기에는 "too many connections"라는 에러메시지는 mysql_pconnect()라는 함수의 사용때문에 발생하는 것 같지만, 그런 이유도 있을수 있지만, 직접적인 이유는 그것이 아니라 MySQL의 메뉴얼을 보면 mysql_connect()함수를 사용하면 해당스크립트의 종료와 함께 연결이 종료된다고 되어있지만
./mysqladmin -u -p processlist"라는 명령어를 통해서 살펴보면 그대로 살아 있음을 알수 있다.


맨위에서 살펴보았던 "mysqladmin -u -p variables"의 결과로서 볼수 있는 여러가지 시작옵션들중 "wait_timeout"의 값만큼 서버에 그대로 연결을 유지한채로 남아 있는 것이다.

따라서, 이것이 "too many connections"의 직접적인 이유인 것이다.

그렇다면 문제의 해결은 간단하다.

실행옵션을 주어서 이들 값들을 자기가 운용하고 있는 서버의 성능과 용도에 알맞게 수정해 주면 되는 것이다.

MySQL실행시에 주는 실행옵션값은 다음과 같다.

./safe_mysqld -O max_connections=1000 -O table_cache=256 -O wait_timeout=300 &

일반적으로 실행시킬때에는 기본옵션을 그대로 사용하는 "./safe_mysqld"라는 옵션을 사용했다.

이렇게 실행하면 36개의 MySQL시작옵션중에서 위의 3가지 옵션들만 값들을 임의로 지정하여 실행시킨 것이다.
이렇게 실행시킨후에 다시 "mysqladmin -u -p variables"로 옵션들값을 확인해 보면 변경되어 있음을 알수 있을 것이다.

그리고, 참고로 리눅스 실행시에 mysql을 자동으로 시작하도록 설정해둔 /etc/rc.d/rc.local파일에도
위와 같이 옵션을 함께 주어서 실행하도록 설정하는 것을 잊지말기 바란다.

[MYSQL] MySQL 설치/사용시 나는 에러 유형별 대처방법

1. ./configure 시에 에러증상1
checking for tgetent in -lncurses... no
checking for tgetent in -lcurses... no
checking for tgetent in -ltermcap... nochecking for termcap functions library... configure: error: No curses/termcap library found[root@localhost mysql-4.0.13]# makemake: *** No targets specified and no makefile found. stop.
Q1 : 왜 이런 메세지가 뜨냐?
A1: gcc가 없던지 PATH가 안잡혀 있는 경우

Q2 : configure: error: no acceptable C compiler found in $PATH
 설치를 잘못 한건가?
[root@localhost mysql-4.0.13]make 실행 시
make: *** No targets specified and no makefile found.  멈춤.
메세지 뜨는데 어케?

A2 : 리눅스에 gcc가 설치됐는지 확인하라.
# rpm -qa| grep gcc

2. 소스 설치시 "NOTE: This is a MySQL binary distribution." 라는 메시지의 경우Q : It's ready to run, you don't need to configure it! 나옵니다. 이유가?

A : 컴파일이 필요없는 바이너리를 받은거 같다. 이미 컴파일한 거다.
  압축풀고 적당한 위치로 이동시켜라.

tar zxvf mysql-xx.xx.tar.gz
mv mysql-xx.xx /usr/local/
ln -s /usr/local/mysqlxx.xx /usr/local/mysql

3. mysql을 실행하면 (2)번 에러
Q : ERROR 2002: Can't connect to local MySQL server through socket '/var/lib/mysql/m
ysql.sock' (2) 무슨 에러인지요?

A : 데몬 구동시 ./safe_mysqld --user=mysql & 실행 시켜보라.
그래도 에러가 날 경우 ln -s /tmp/mysql.sock /var/lib/mysql/mysql.sock 해보라.

4. mysql.sock 중에 (40)번에러
Q : ERROR 2002: Can't connect to local MySQL server through socket '/var/lib/mysql/m
ysql.sock' (40)

A : chown mysql.mysql -R /var/lib/mysql 를 하기 바란다.
그리고 참고로 php에서의 mysql socket 은 /etc/php.ini 에서 경로를 수정할 수 있다.

5. mysql 데몬이 죽어버릴때
Q : # ./mysqld_safe &
    chown mysql .. <-- 비슷한 오류가 뜨면서 데몬이 죽어버린다.어케?

A : 레드햇 리눅스라면 groupadd 와 useradd 에 '-r' 옵션을 사용하라.
# useradd -r -d /usr/local/mysql mysql
이렇게 하면 500 보다 작은 UID, GID를 가진 mysql 그룹과 사용자가 생성된다.
6. mysql 실행시 데몬 바로 죽음
Q :
030527 22:33:39  mysqld started
030527 22:33:39  Can't start server: Bind on TCP/IP port: 주소가 이미 사용 중
030527 22:33:39  Do you already have another mysqld server running on port: 3306 ?
030527 22:33:39  Aborting
030527 22:39:50  /usr/local/mysql/libexec/mysqld: Shutdown 이 완료됨!
030527 22:39:50  mysqld ended

A : 3306 포트에 이미 다른 mysqld 가 실행되고 있다.
# vi /mysql/scripts/mysql_config 을 열어서 포트번호 수정.

7. mysql-4.0.12 설치후 데몬이 안띄워지고 바로 죽을 경우.
Q 정상적으로 소스 설치하고 나서,,
  /usr/local/mysql/bin/mysqld_safe & 실행하면,,, 데몬이 시작하자 마자 바로 죽는다.
 ./safe_mysqld Starting mysqld daemon with databases from /usr/local/mysql/var
   mysqld ended
에러 메세지를 보기 위해 /usr/local/mysql/var 로 이동  vinnylover.err 파일을 열어보니
아래와 같은 메세지가 있더군.
mysqld started
InnoDB: Started
Fetal error: Can't open privilege tables: Can't find file: ' ./mysql/host.frm'(errno: 13)'
Aborting

A : mysql_install_db 스크립트를 실행해서 초기 테이블을 생성.
   # ./mysql_install_db 하면 된다. (/usr/local/mysql/bin 아래에서 하라)

8. mysql sock 에러 문제의 확실한 해결법
Q : 접속하면 >/var/lib/mysql/mysql.sock ... (111)

A : 디렉토리 퍼미션 문제
# killall mysqld
# chmod 755 -R /var/lib/mysql
# chown mysql.mysql -R /var/lib/mysql
# mysqld_safe --language=korean &

9. make 명령어를 실행하면 설치가 해제
Q : make[2]: *** No rule to make target `ctype-euc_kr.lo', needed by `bmove_upp.lo'. 멈춤.
make[2]: 나감 `/usr/local/down/mysql-3.23.38/libmysql' 디렉토리
make[1]: *** [all-recursive] 오류 1
make[1]: 나감 `/usr/local/down/mysql-3.23.38' 디렉토리
make: *** [all-recursive-am] 오류 2
A : 먼저 LD_LIBRARY_PATH에 모든 라이브러리 경로가 들어가 있어야 한다.
이런 경우때문에 필요한 라이브러리를 찾지못해 에러가 발생.
거의 필요한 패키지를 설치했는데도 에러가 나면 LD_LIBRARY_PATH를 확인해볼 필요가 있다.

10. mysql 설치시 gcc에러나는데 해결책
Q :
# ./configure --prefix=/usr/local/mysql --with-charset=euc_kr
checking for c++... c++
checking whether the C++ compiler (c++   ) works... no
configure: error: installation or configuration problem: C++ compiler cannot create executables.
A : rpm으로 찾아서 다 설치하고 나서 컴파일 하면 된다.
rpmfind.net에서 찾으실 수 있습니다. 에러 보고 하나하나 다 설치하면 된다.

11. 인스톨 설치도중 103 에러
Q : an error occured move data process: -103
compenent : server

A : mysql 설치된 폴더를 완전시 삭제 후 재설치

12. mysql설치 시 invalid user 오류
Q : chown: mysql: invalid user
Starting mysqld daemon with databases from /usr/local/mysql/data
030417 11:42:35  mysqld ended

A : mysql 이란 유져가 유효하지 않다라는 에러로써 현재 mysql이란 계정이 존재하지 않기때문에 나는 에러
# /usr/sbin/useradd mysql -M -s /bin/false
# chown -R root /usr/local/mysql
# chown -R mysql /usr/local/mysql/var
# chgrp -R mysql /usr/local/mysql

13. mysql 4.0.12 설치 시 "Check your system clock" 오류
Q
# ./configure --prefix=/usr/local/mysql --with-charset=euc_kr
이렇게 했는데 다음과 같은 메세지의 경우....
checking build system type... i686-pc-linux
checking host system type... i686-pc-linux
checking target system type... i686-pc-linux
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... configure: error: newly created file is older than distributed files!
Check your system clock

A : mysql이 개발된 시간보다 현재시간 차이로 생기는 문제
인터넷(네트웍)이 되는 상황이라면
# date
# rdate -s time.bora.net   => rdate -s time.nuri.net와 같이 다른서버로 해도 된다.
# date


14. 설치시 configure: error: no acceptable cc found in $PATH 에러
Q :
configure: error: no acceptable cc found in $PATH

A : cc 즉 c complier 가 없다
c 컴파일러가 PATH에 안잡혀 있을 수 있다. path를 추가하거나 gcc를 재설치
# vi /etc/profile
PATH=$PATH:.:/usr/local/mysql/bin

15. config시 ERROR: 1062 Duplicate entry 'localhost-root' for key 1
Q : mysql 소스설치 config시 에러의 경우
rpm버전 삭제했는데 데몬이 살아 있나? ps -ax | grep mysql 하면 암것도 안나온다.
ERROR: 1062 Duplicate entry 'localhost-root' for key 1
ERROR: 1062 Duplicate entry 'localhost-root' for key 1
030312 14:58:03 ./bin/mysqld: Shutdown Complete

A : 캐시에 이전데몬이 살아있기 때문이다.
kill  또는 killall 명령으로 프로세스를 완전히 죽이고 설치하라

16. configure 에러로 "error : No curses/termcap library found" 에러?
Q : checking for termcap functions library...
configure: error : No curses/termcap library found

A : libtermcap-devel-xxx 패키지가 필요해서 발생하는 에러
설치시디를 넣으시고 설치를 하면 해결된다.

2011년 11월 22일 화요일

vim tip

Vim diff 잘써보기
두개의 파일을 비교하는 방법은
vimdiff a.c b.c
이렇게 바로 실행하거나,
1) vim a.c
2) :diffs b.c              (:diffsplit b.c  로도 사용할 수 있습니다.)
3) ^wJ
이렇게 수평으로 열어서 세로로 맞출 수도 있구요.
1) vim a.c
2) :vert diffs b.c         (:vertical diffsplit b.c 로도 사용할 수 있습니다.)
이렇게 한 번에 열수도 있습니다.
1) vim a.c
2) :sp b.c
3) :diffthis
4) ^ww
5) :diffthis
위 방법은 두 개를 열어 놓고, diff 에 참여시키는 방법입니다.
vimdiff 는 vim의 softlink에 불과한데, vim은 구동시에 어떤 이름으로 시작되느냐에 따라 readonly, vi compatible, diff mode 등으로 전환되는 trick을 가지고 있습니다.
이상은 어떻게 하면 비교할 파일을 열어서 보는 다양한 방법을 설명한 것이고, 다음은 비교하는 파일을 편집하는 것을 알아 보겠습니다.
비교하는 파일의 편집이란, 한쪽의 내용을 다른쪽으로 copy하는 것을 말합니다.
:diffget

:diffset
명령입니다. 현재 cursor가 위치한 반대편의 내용으로부터 가져오거나 보내는 것이지요.
단, 복사하자 마자 같은 내용이 되기때문에 diff 화면에서는 사라집니다.
안보이는 거 보이게 하려면
zR
zM
을 사용하세요...
간단한 팁.. 정리해보면..
:diffsplit
:diffget
:diffput
세가지 명령어와
:vertical diffsplit
:diffthis
정도 알아 두시면 더 유용합니다.

Punctuation

쩜(.):period(US), full stop(EN)
샾(#): number sign
언더바(_): underscore
역따옴표(`): grave accent. 여기서 grave는 무덤, 새기다 뜻이 아닌 무겁다, 엄숙하다의 뜻임. grave accent를 우리말로 번역하면 저음 액센트
파이프(|): vertical bar
꺽쇠(^): caret
골뱅이(@): at sign
부등호(<): less-than sign
물결표(~): tilde. 발음은 틸드/틸더
작은따옴표('): apostrophe
부등호(>): greater-than sign
대괄호([]): square brackets 또는 brackets
중괄호({}): curly brackets 또는 braces
소괄호(()): round brackets 또는 parentheses
역슬래쉬(\): Backslash

2011년 11월 20일 일요일

Aptana Studio 2.0 에서 EUC-KR 설정이 안 될 경우.

보통 Eclipse 나 Aptana 에서 한글 설정을 위해

Window->Preferebces 에서

encoding으로 검색하거나 General-> Workspace에서 UTF-8로 해주거나

강제로 셀렉트 박스에다가 EUC-KR을 입력해준다.

그런데 EUC-KR을 해줘도 Apply가 활성이 안 될 경우에는

Aptana 설치 폴더로 가서 JRE 폴더를 삭제 해주면 된다.

아마 Aptana 와 함께 설치 된 Java Machine 에 euckr encoding 이 포함되어 있지 않아 문제


가 발생한 것 같다