Mysql 5.0 issue

2년전 버그리포팅한 fts 의 문제에 대해 6.0 에 해결이 되었다는 메일을 40여통을 받았다 ㄱ-
그래.. 2년전엔 생까더니 보다보니 맞는거지.. case closed 까지 시켰다가 지금와서 reveal하는 이유는 뭘까
이제와서 패치한다고 메일질하면 기뻐할줄아는가
이미 mysql의 신뢰도는 개판으로 떨어진거다. 왜?

1. 개발자의 건의를 case closed 로 test result 조차 내지 않고 무시한다.
2. 기능에 이상이 있는걸 2년이나 지난 지금에서야 알아냈다.
3. 지금에서야 패치했다. 그렇다면 그 개발자들은 최하 2년이 넘는 기간동안 정말 단순한 오류하나를 못잡았다는 이야기가 아닌가?
4. 지금에라도 인정을 하니 다행이다 외국기업의 차이겠지만, 그 단순오류 하나때문에;; 시간적 기간적 손실은 크다. 이게 오라클이었으면 소송감이다.
5. 거기다 적용버전은 6.0이다 앞으로 3년은 지나야 이제좀 안정적이겠거니 할듯하다. 한마디로 떡밥이다.
6. 결정적으로 이거때매 검색시스템 새로 구축한다고 삽질한거 외주 인건비로만 쳐도 수천은 들어갔고 시스템 구축비까지 갔다치면 3억은 든다.

결국 bdb 가 윈이란 소리다.

그리고 그때 제기했던 mysql-cluster 에 대한 이슈는 아직도 해결되지 않았다.
slrclub 규모를 mysql-cluster로 올리려면 300기가의 물리적 메모리가 필요하다.
메모리 장사할려고 작정헀나보다. 이게 웃긴게 -_- 1기가짜리 db가 utf-8 로 변환되서 메모리에 올라가면 몇배수로 용량을 잡아먹기 시작한다.
사실 답변은 받았다... "원래 시스템이 그렇다.. 그러니 다올리지 말고 쫌만 올려 써라" 였다.
클러스터링하나 똑바로 안되서 테이블을 쪼개갖고 그걸 프로그래밍으로 해결하라고??

그러니까 오라클이 팔리는거지
전화질이라고 할려다가 천년만년 mysql 쓸것도 아니고.. com이 아니라 ab다.. 두렵다 -_-;;
난 거기서 제일 궁금한게. 모 통신사가 클러스터링을 쓴다는거다. 양키들이라 영어만 쓰니 무관한건지는 모르겠으나 양이 상당할텐데 무슨 슈퍼돔에다 mysql돌리는게 아닐까 하는 생각이 든다. 메모리 20테라 쳐박고.

현재는 mysql 5.1 까지 테스트를 했고 실제서비스에서 동작한지가 어언 1년이 다되간다..
이넘은 리플리케이션 티어로 돌던놈이다..
별다른 문제가 없어보였으나 오늘 막상 안정버전인 5.0 버전을 적용하자마자 (주데이터베이스라)
기현상이 발생하기 시작했다 -_-;;

inner assoc type 의 select query 한방에 전체 데이터베이스가 락이 걸리는 현상이다.
서로다른 3개의 쿼리를 natural과 cross 조인으로 묶고 이를 그루빙한 subquery 를 associative 로 다시 매핑하는 형식의 쿼리다. 그렇다 -_- 통계용 쿼리다.
reference rows도 몇천만개 안된다. 한번돌리고 정신이 멍해졌다...

이거 뭐 트랜잭션 건것도 아닌데 장난하나 -_- 기본으로 트랜잭션이 걸리게 바뀌었나? 건 짐부터 찾아봐야될 문제다.

critical changed issue 를 요약정리를 하는 센스가 없다. 세줄요약이 괜히나온말이 아니다 -_-
5.1 버전대의 큰 변동사항은 매뉴얼 하단에 몇줄 박혀있는걸 보았다. (통상 업그레이드 안내측에 위치한다) 그러나 이내용은 여기에 없다.
release note, change history 를 당장급한데 수십페이지나되는걸 하나하나 정독하고 있어야할판이다.
혹시 누구 정리한사람있으면 링크하나 던져줬음좋겠다.

이틀 잠도 제대로 못자 정신이 멍하다 -_- 거기다 이놈이 막타를 치는구나.

5.0.45 (몇일전까지 GA 릴리즈였던) 버전에는 메모리 리크 결함이 있다. 지금 사이트에 가보면 5.0.5x 로 버전이 변경되었다.
이녀석이 불러일으킨 트러블이었다. 5.0.45 사용자는 즉시 버전업을 할것.
크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기(0) 이올린에 추천하기(0)

Posted by LeCieL

2007/12/15 05:50 2007/12/15 05:50
, , , , , , ,
Response
No Trackback , 3 Comments
RSS :
http://cl.dgtalx.net/rss/response/148

PostgreSQL vs MySQL

체적인 게시판 시스템의 마이그레이션에 앞서....

일단 이 이야기는 적어도 한국의 기준에서, 가장 많은 서버가 가장 많은 서빙을 하고 있는 한 장르에 국한된다.
웹사이트 운영에 있어 필수불가결 사항인 게시판이라는 분야다.

현재를 분석하자면,
최적화된 소스위에 단순하며 엉성한 데이터베이스 구조체를 가진 BBS를 운영중에 있다.
이 BBS는 MySQL 이라는 DBMS를 통해 구동중에 있으며,
현재는 높은 I/O로 인해 부하의 한계에 다다랐다.
그로인해 새로운 구조체를 만들어내게 되었고 새로운 시스템을 고안해야만했다.

한국이라는 한정적인 언어권을 염두해두어야 한다는 문제가 여기에 크게 기인하고 있다.
Full Text Search 의 Function 을 사용할 수 없다는 문제다. (혹자는 사용한다고도 하지만 그 정확도로 볼때 도저히 서비스할 수 있는 수준이 아니다.)
편법적인 방식으로 을/를 는이나 감탄사나 몇가지 조사들을 띄어내는 형식으로 인덱싱을 하는 경우를 포함한 이야기다.


따라 완벽한 서칭은 *스트링* 베이스의 와일드 서치이지만, 이러한 서치는 현실적으로 더이상 제공하기 힘들다는 문제점이 생겼다.
별도의 서치시스템을 분리해내기로 결정을 했지만 여기엔 다른 문제가 있었다.

관리적인 문제와 이상적 게시판 시스템을 위한 구조에는 1개의 테이블에 모든 자료를 저장하는것이 좋다.
이것은 일련화된 record number를 부여함으로 인해 발생하는 관리의 편의성이기도 하다.

이를테면, 게시물을 이동해야 하는 경우, 서로 다른 테이블에 빡빡한 record 사이에 30개의 게시물이 이동했다고 치자, 알고리즘은 크게 2가지로 나뉜다.

1. 이전대상 테이블의 이전시기를 기준 이후의 모든 게시물의 record number를 증가시킨다. (활동량이 많지 않은 게시판의 경우 maximum counting / 약 5천만개 이상의 테이블을 업데이트 해야하는 일이 발생한다)

2. 단순하게 게시물의 소팅오더를 작성일자로 한다.
-> 그러나 스레드 아티클 , 이른바 답글이라는 기능이 여기에 붙게되면 소팅의 기준이 모호해지게된다
물론 몇개 되지 않는 게시물에서는 별다른 문제가 없어보일지 모른다.

생각해야할것은 "밀리세컨드 단위의 필드가" 유니크 프라이머리 키가 될 수 있는가?와 1억건이 넘는 레코드를 매번 리미트 쿼리로 끊어올것인가?
잘 이해가 안될지몰라 부연설명하자면 레코드 기준점이 모호한 상태에서 들쑥날쑥한 인덱스 데이터를 페이징쿼리를 할때에는 더 많은 디스크 I/o가 발생한다.

단순히 생각하라 당신이 가져와야할 인덱스 파일의 크기는 200메가를 초월하고 있다. offset seeking을 한다 하여도 최소 40메가의 디스크 데이터를 액세스 해야한다는 문제에 직면하게된다.

또 이 경우 btree 인덱스 구조가 나타내는 치명적인 문제점이 드러난다. 대량자료의 경우 40% 이상의 옵티마이즈된 렌지를 넘어서게 되면 결과가 뒤섞이는 경우가 존재한다.


여기에 해결책은 rownum/rowcount라 불리는 기능이기도 하다. 이것은 오라클과 postgresql이 지원하고 있는 기능중 하나다.


현재의 시스템은 단순하게.. 새게시물의 최상단에 올라오는정도로밖에는 지원하고 있지 않다.


결국 이러저러한 문제점으로 인해 현재는 MySQL의 Innodb를 기반으로 제작이 거진 완성되어가고 있다.

하지만 방대한 인덱스를 전체적으로 시킹한다는것은 또한 넌센스급의 과제가 되어가고 있다.

현재 성능은 매우 뛰어나다고 할수있을정도로 빡빡한 렌지옵티미제이션과 다른 테이블을 통한 분차별 오류자료 수집/보정 및 캐싱을 구현하고 있다.

소스코드가 매우 복잡해지고 있다는 소리다. 하지만 이것은 빙산의 일각이다.


다른 기업들과 마찬가지로 단순한 게시판 서비스만이 아닌, 진보되고 확장된 연동기능을 상당히 필요로 하게되며 이러한 자료들은 외래키로써 다른 자료와 유기적으로 연동되어야할 필요성이 있다.

그 선택의 끝은 innodb 라는점이었다.


퍼포먼스의 면에서는 PostgreSQL이 압도적으로 좋아보이는 점이 있으며( 아직 자세히 파보진 않아서 모른다.
단순한 고민에 대한 이야기라는것을 다시 기억하자)
사용하고 싶은 데이터베이스로 머리속에 자꾸 맴돌아 오늘 시간이 나서 이것저것 알아보기 시작했다.

pgsql사이트와 DSN에 올라온 게시물을 검토하던중 몇가지 눈에 띄는 이슈를 발견하게된다.

1.SQL쿼리들이 일단 빡빡하다. 나쁘지 않다. 하지만 어느정도의 편의는 필요로 하지 않을까 하는 정도의 아쉬움이 보이긴했다. 일례로 datetime 등의 자료저장이나 null문자 처리등의 형식으로 봐선 C로 만든 데이터베이스 수준이라고 해야할정도다.
물론 불편한만큼 성능은 올라가기 마련이다.
제일 불편한것은 C로 날코딩을 하는것이다. 감히 pgsql은 이 수정하기 힘든 로레벨 언어로 코딩된 db의 압도적인 퍼포먼스에 대항할수 없을것이다.

2.pgsql의 장점이라고 불리오는 커넥션풀러가 아직 불안정해보인다. 몇몇 크리티컬한 버그와 이슈들만 일단 보았다. 과연 이것을 사용해도 될것인가 하는 의문만 쌓여가게되었다.
고쳐진것만 보아서는 안정성이 있지만 그러한 이슈들이 있었다는것은 발견되지 못한 다른 더 많은 이슈가 따라올수있다는 문제가 존재한다.
(언제나 극한의 상황에서는 상상하지 못하는 문제가 벌어진다)

3.Configuration Issue Solved!

more..


-> 최신의 pgsql은 스택오버플로나 kill order 오류등이 모두 해결되었다. (WAL등의 로그형식대안) 따라 이전에 대한 문제사유는 없으며 확실하지는 않지만 모든 유형의 innodb, myisam structures 는 호환되는것으로 보인다.

지금 이런 고민중의 하나는 pgsql은 매혹적인 구조와 성능, 안정되어 보이는듯한 클러스터링,
파츠파츠가 의외로 잘짜여져있는것처럼 보이기 때문일지도 모른다.

장시간의 테스트와 서비스등으로 안정성을 찾아나가야 하는 문제다.
크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기(0) 이올린에 추천하기(0)

Posted by LeCieL

2007/03/24 03:07 2007/03/24 03:07
, ,
Response
No Trackback , a comment
RSS :
http://cl.dgtalx.net/rss/response/107

innodb PK range ordering

잡스런팁 몇가지

1. 물론 모르는 사람이 있겠나 싶지만..

select ~ limit 0,30;

하면 0을 기준으로 30개의 record 를 가져온다.

그리고 limit 30,30 을 하면 30번째 row offset 을 건너뛰고 뒤에 30개를 가져온다.

그러나 이 limit 은 인덱스 시킹을 하여 스키핑을 하는것이므로 실제 칼큐레이셔닝이 도는것과 마찬가지다.

따라 i/o 부하가 발생한다.

궁금하다면 데이터를 1억개 가량 삽입하고 limit 90000000,30; 을 때려보라 시간이 얼마나 걸리나.

이건 innodb 에 국한된것이 아니다.

이를 편리하게 넘나들기 위해서는 오라클의 rowid (rowcounting) 기능이 있다면 금상첨화겠지만.. 없으면 삽질해야한다.


2. hbs 에 사용된 기법중 한가지이지만 지금은 내렸다., 페이징쿼리시 number error correcting 중 골때리는 방식중 한가지가 있다 -_-
리스트의 최상위 pk를 기준으로 별도의 해당 페이지의 페이징 테이블에 인서팅하여 이값을 range selecting 을 통해 근접대 값을 sum적용하여 지워진 글에 대한 갯수를 구해온다.
정확하지는 않지만, 나름 외부로 티나지 않게 깨끗한 방법중 한가지였다.
문제는 정확하지가 않는다는것이다.
또한 게시물이 삭제될 경우 해당 range 에 prepare value를 삽입하였다가 나중에 pk가 리스트를 읽을때 근접 영역에 합산시켜버려야 한다.
별로다 -_-

3. PK (Primary Key)를 기준으로 select 를 해올때 편법적으로 negative numbering 을 사용하는 경우가 있다.
pk 를 -1 부터 시작해 음수로 반환시키는 방법이다.

그리고 별도의 no 값등을 통해 이를 서치하는 방법이다.

별문제가 없을것 같은가..

문제가 있다 -_-

대략 15만개의 레코드를 넘어서면 그 이전의 경우 pk가 아닌 다른 index 값 (예: no) 등을 통해 select 를 하면 order 방식을 삽입된 pk 의 순서대로 (그러니까 이경우는 정상이다) 로 가져오지만

그 영역을 넘어서면 mysql 은 이상동작을 하게된다.

무슨말이냐면 1000, 999, 998 식으로 select한 결과가 나와야하는것이 정상이다.

select ~ where no < 160000 limit 30;
을 때리면 요쯤까지는
159999, 159998, 159997, 159996 ~ 등 번호가 역순으로 잘나온다 생각하겠지만..

where no < 1000 limit 30; 을 때리면..
여기선 1,2,3,4 가 나온다는것이다 -_-

자체 인덱스 처리형식이 그렇다고 한다. pk 가 아닌 index 로 range selection 을 주지 않도록 신경쓰자 -_-

크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기(0) 이올린에 추천하기(0)

Posted by LeCieL

2007/01/19 04:46 2007/01/19 04:46
, , ,
Response
No Trackback , No Comment
RSS :
http://cl.dgtalx.net/rss/response/88

query examples

inner join selection

select a.*, count(b.entry) from first_table as a inner join second_table as b on a.idx=b.no group by a.idx;
(left join 형 a table idx = b table no와 동기화, a.idx로 그룹하여 b테이블의 부가정보 획득)

union selection
(select * from first_tabe where idx=1) union (select field1, field2, field3 from second_table where  no=1) order by idx desc;
필드명은 처음 셀렉트된것을 따른다. 따라서 alias를 주던가 해야되며 뒤에 테이블이 필드갯수가 틀릴때는 위처럼 맞춰주면된다.

select insert
insert into first_table select * from second_table where idx=2;
필드갯수 일치화 필요

view selection
create view testdb.view_table as select * from second_table;
select * from view_table;
이놈은 tmp table 만드는 삽질없이 바로 뷰트리 태워주는놈이다. mysql 5.0에서만 가능

unique selection
select * from first_table group by aa having count(*) > 1
중복레코드 추적 (aa필드기준)

distinct query
select distinct aa from table group by bb where expr
가급적 쓰지않는게 낫다 group by 보다 퍼포먼스 떨어진다. row exam 갯수가 적을때만 대충 편하게 이용.

제작시 자주쓰이는 쿼리들 나열 -> 이거 이외이 삽질은 안하는것이 좋다

주로 sql에서 쓰이는 function 은

select (is_null, if, substr, concat, date_add, date_sub) 정도
datetime filed의 경우 date function 을 쓰는것이 로드에 효율적이다.
그리고 생각해보니 update if select 서브쿼리들 몇개는 썼었는데 트랜잭션으로 바꿧다 -_-
크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기

Posted by LeCieL

2006/11/09 06:17 2006/11/09 06:17
, ,
Response
No Trackback , No Comment
RSS :
http://cl.dgtalx.net/rss/response/45

raid optimization for large myisam tables

대용량의 myisam 테이블을 디스크 어레이 (레이드)를 통해 적절한 튜닝을 위해서는
통상 128KB의 stripe size 설정이 효율적이다.
대용량의 기준은 1GB를 넘느냐 넘지 않느냐다..

belown are optimal raid array stripe size per related each myisam table size
the stripe size relate to how many large myisam table is using, and how much overall table size you have
this optimal value is construct for avoid table scan locking.
i'm recommand using ext3 fs and you should test ext3 journal mode

500 Under (32KB)
500~1GB (64KB)
1GB~2GB (128KB)
2GB~4GB (256KB)

benchmarking on adaptec asr2230 SGL  scsi u320 / raid 10 mode / 8 disks
you should make ext3 with raid stride option like this
mkfs.ext3 ~~~ -R stride=16  (16 means 64KB stripe size, value must divide 4 of your stripe size )

이러한 대용량 테이블의 갯수는 스트라이프 사이즈와 밀접한 관계를 가진다
또한 테이블락을 회피하기 위한 최적화 수치에 대한 언급이다.
이 수치는 제로보드의 테이블 구조를 기반으로 하여 벤치마킹 되었다.
어디까지나 제로보드가 가진 테이블 구조에서 가장 합리적이며 이상적인 query 문으로 바꾸었을때의 이야기다.
ext3 fs 를 권장하며, 저널링모드를 테스트해보길 권장한다.
중요한것은 write 딜레이로 인해 테이블락이 걸리지 않도록 하기 위함이다.
그리고 ext3 를 이용한다면 -R stride=xx 옵션을 주어 스트라이프 사이즈를 일치화시켜줘야한다.
-R stride=값은 자신의 스트라이프 사이즈 (KB)를 4로 나눈값을 입력하면된다.
크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기

Posted by LeCieL

2006/11/09 05:50 2006/11/09 05:50
, , , ,
Response
No Trackback , No Comment
RSS :
http://cl.dgtalx.net/rss/response/44

mysql replication kickstart

mysql replication quick reference by C.L

master 및 slave의 character-set 과 collation 은 일치시켜줘야한다.

master server >

my.cnf 수정사항
server-id=1
log-bin #binary log 활성화
binlog-do-db = testdb # 이 db이름에 한해 binary log를 활성화함. 물론 킥스타트라 넣은것이고 통짜하면 안쓰면그만.

mysql 접근해서
grant replication slave on *.* to '아이디'@'슬레이브서버IP' identified by '비밀번호';
flush privileges; #왜하는지 모를린 없겠지..

slave server >

my.cnf 수정사항
log-bin #당근켜야지
server-id=3    #대충써주자
master-host=1.2.3.4  #메인서버IP
master-port=3306 #기본값
master-user=위에만든ID
master-password=위에친 비번
replicate-do-table=testdb.testing_table   # 해당 binlog는 db단위로 오지만 여기선 저 테이블만 리플리케이션할수있다. 이 옵션을 끄면 testdb가 리플리케이션된다.


사전준비 다됬는가..
마스터서버로 돌아와서..
서비스가 구동중이면 그냥 꺼라 -_- 웹서버고 나발이고 다 꺼라 lock 걸었다가 무슨일이 터질지 모른다..
물론 대용량 기준이다.. 용량 얼마 안되도 그냥 꺼라.. 몇사람 안본단소리다..
대형서비스들은 db만 껏다가 웹서버 줄사망하는일이 발생한다.

끄고나서
tar czvf file.tgz /디비경로/testdb/*
로 압축한뒤 (testdb는 가상이다. 실제있는db필요) 이 디비를 통째로 백업받아다가
슬레이브 서버에 집어넣어라.. 테이블만할꺼면 정한 테이블만 받으면된다..
그리고 압축풀고 퍼미션 맞춰줘라 chown mysql.mysql *
그리고 마스터, 슬레이브 순으로 mysql 스타트 하면된다..

그리고 앞단에 l4나 lvs붙여서 로드밸런싱 걸면된다..
크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기

Posted by LeCieL

2006/11/09 05:30 2006/11/09 05:30
,
Response
No Trackback , No Comment
RSS :
http://cl.dgtalx.net/rss/response/43

mysql clustering

중요포인트

datanode (ndb) ->
ndb 들어갈 경우 메모리는 static char 계열로 계산하라
total stored size x3 의 사이즈가 ndb로 입력했을때 필요로 한 사이즈다.
따라 인덱스 사이즈도 적절히 여분을 두고 구성해야한다. (datamemory, indexmemory)

또 여기의 x2 가 디스크 스토리지에 필요한 사이즈다.

ndb node는 shm 형식의 network data block 이므로 shared 된다. 그러나 어떤테이블의 alloc을 어느 노드의 어느 allocation 이 가지고 있는지는 모른다.
failover시 query result 가 변동되며, 이상태에서 update, insert 가 동작한다는 문제점이 있다는것을 주의하라.
(stored procedures는 동작하지 않는다, 또한 극도로 위험한 부분이기도 하다)
failover risk migration 은 사실상 힘든부분이며 db활용형식에 따라 틀리다. 전체 row를 exam하는 경우 혹은 특정 row를 exam하여 값을 입력하는 경우는 failover시 대응책이 없다.
따라 replica를 올려 서버를 증량한다. 동일메모리 블락구간을 복제하여야 한다.

10GB의 sql data (dbtype)을 가지고 있다면, 통상 80GB의 메모리를 운용하여야한다.(안정적 운영시)

10gb * 3 = 30GB <- 필요 최소메모리
+ 30 GB (리플리카 더미) + 20GB (테이블 증량분을 위한 대책)

노드가 끊어지면 메모리할당공간부족으로.. insert가 안되는 경우도 발생한다는걸 잊지마라.
크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기

Posted by LeCieL

2006/11/09 05:18 2006/11/09 05:18
, ,
Response
No Trackback , No Comment
RSS :
http://cl.dgtalx.net/rss/response/42


Archives

Calendar

«   2010/09   »
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30