Mysql HA

DB 2013. 4. 23. 13:50


Mysql HA를 하는 방법이 다양하지만 어느 정도 유명한 것은 3가지인듯 하다.



1. Mysql MMM


과거에 소개했던 multi master replication manager이다.

전통적인 방법이며, 보통 master 2대를 두거나 master 2대 이상을를 두고 하나 이상의 slave를 두는 방식을 사용한다. 


* 참고자료

http://mysql-mmm.org

http://knight76.tistory.com/entry/mysql-에서-동일한-table-schema를-가진-Multi-DB-를-java로-접근하기



2. Mysql MHA

master 가 무너지면, slave 하나가 master 로 promotion이 되도록 한다. replication consistency를 최대한 줄여주는 역할을 한다. (조만간에 사용예정이고. 사용후 자세한 내용은 공유예정 )


http://code.google.com/p/mysql-master-ha/

http://www.slideshare.net/ylouis83/mysqlmha



3. MariaDB진영측 Galera Cluster\

Mysql에서 branch한 maria DB에서 나온 솔루션, mysql mmm진영에서 적극 추천하는 솔루션이다. 

주위에서는 쓰지는 않지만, 지켜봐야할듯 하다. 


http://codership.com/content/using-galera-cluster

https://kb.askmonty.org/en/getting-started-with-mariadb-galera-cluster/





* 참고

최근에 들었던 소식은 한 서비스에서 파코나의 툴킷(http://www.percona.com/doc/percona-toolkit/2.2/)을 활용하면 중단없이 변경하려고 했었던 서비스가 있었다고 한다. DB부하가 너무 높아서 결국 실패했다고 하는 소식을 들었다.. innodb의 특성을 타기도 하고. 데이터 용량 이슈도 있으니. 잘 써야 할 듯 하다.. 




Posted by '김용환'
,

 

Mysql 4.x 대까지는 없었는데, Mysql 5.x대부터 생긴 기능.

 

PK가 있는 테이블이 하나 있다.

 

CREATE TABLE  `revision` (
  `instance_id` int(11) NOT NULL,
  `xid` varchar(33) NOT NULL,
  `status` char(1) DEFAULT 'a',
  `last_revision` bigint(20) NOT NULL DEFAULT '0',
  `start_revision` bigint(20) NOT NULL DEFAULT '0',
  PRIMARY KEY (`instance_id`,`xid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

 

이 테이블에서 xid와 instance_id를 where절 해서 쿼리를 날렸더니, “Impossible WHERE noticed after reading const tables” 라고 뜬다. 분명 PK인데..

 

+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                                               |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Impossible WHERE noticed after reading const tables |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+

 

Mysql 5.x 대부터 query 데이터의 결과가 없으면 이렇게 나온다고 한다.

데이터가 있는 테이블에서 query 데이터의 결과가 나오면 아래와 같이 index가 타는 것을 확인할 수 있다.

 

 

explain SELECT status, last_revision, start_revision FROM revision where instance_id = '42' and xid = '1' ;
+----+-------------+-------------+-------+---------------+---------+---------+-------------+------+-------+
| id | select_type | table       | type  | possible_keys | key     | key_len | ref         | rows | Extra |
+----+-------------+-------------+-------+---------------+---------+---------+-------------+------+-------+
|  1 | SIMPLE      | revision | const | PRIMARY       | PRIMARY | 105     | const,const |    1 |       |
+----+-------------+-------------+-------+---------------+---------+---------+-------------+------+-------+
1 row in set (0.00 sec)

 

결론은. . mysql에서 expain 실행할 때 result data가 나오는 쿼리로 테스트해야 한다.

Posted by '김용환'
,
Posted by '김용환'
,

다음과 같은 Exception이 발생했다.
cubrid.jdbc.driver.CUBRIDException
Has been interrupted.
 at cubrid.jdbc.driver.CUBRIDStatement.checkExecuteError(CUBRIDStatement.java:909)
 at cubrid.jdbc.driver.CUBRIDStatement.executeCoreInternal(CUBRIDStatement.java:802)
 at cubrid.jdbc.driver.CUBRIDStatement.executeCore(CUBRIDStatement.java:769)
 at cubrid.jdbc.driver.CUBRIDPreparedStatement.execute(CUBRIDPreparedStatement.java:453)
 at core.log.impl.PreparedStatementLoggable.execute(PreparedStatementLoggable.java:109)
 at sun.reflect.GeneratedMethodAccessor30.invoke(Unknown Source)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at core.log.aop.handler.DaoInfo.doAround(DaoInfo.java:95)
 at core.log.aop.reflection.profiler.AroundProfiler.invoke(AroundProfiler.java:19)
 at $Proxy3.execute(Unknown Source)
 at sun.reflect.GeneratedMethodAccessor30.invoke(Unknown Source)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at com.ibatis.common.jdbc.logging.PreparedStatementLogProxy.invoke(PreparedStatementLogProxy.java:62)
 at $Proxy4.execute(Unknown Source)
 at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.java:182)
 at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.sqlExecuteQuery(GeneralStatement.java:205)
 at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryWithCallback(GeneralStatement.java:173)
 at com.ibatis.sqlmap.engine.mapping.statement.GeneralStatement.executeQueryForObject(GeneralStatement.java:104)
 at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:565)
 at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryForObject(SqlMapExecutorDelegate.java:540)
 at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryForObject(SqlMapSessionImpl.java:106)
 at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryForObject(SqlMapClientImpl.java:84)


원인은 timeout과 관련된 것으로서, PreparedStatement.setQueryTimeout 으로 지정한 시간보다 긴 Query 실행시 나타날 수 있는 Exception이다. timeout을 길게 해주면 된다.
Posted by '김용환'
,

기억에서 지워지기 전에 잘 써놔야지.

> create database wp
> GRANT USAGE ON *.* TO 'wp'@'localhost' IDENTIFIED BY '1111';
> GRANT ALL PRIVILEGES ON *.* TO 'wp'@'localhost';
> flush privileges;

Posted by '김용환'
,

mysql jdbc driver의 timeout 정보를 모두 살펴보니 다음과 같다.

* connectTimeout
- Timeout for socket connect (in milliseconds), with 0 being no timeout. Only works on JDK-1.4 or newer. Defaults to '0'

* socketTimeout
Timeout on network socket operations (0, the default means no timeout)

* initialTimeout
If autoReconnect is enabled, the initial time to wait between re-connect attempts (in seconds, defaults to '2').

* enableQueryTimeouts
When enabled, query timeouts set via Statement.setQueryTimeout() use a shared java.util.Timer instance for scheduling. Even if the timeout doesn't expire before the query is processed, there will be memory used by the TimerTask for the given timeout which won't be reclaimed until the time the timeout would have expired if it hadn't been cancelled by the driver. High-load environments might want to consider disabling this functionality.

* queryTimeoutKillsConnection
If the timeout given in Statement.setQueryTimeout() expires, should the driver forcibly abort the Connection instead of attempting to abort the query?

* loadBalanceBlacklistTimeout
Time in milliseconds between checks of servers which are unavailable.

* ConnectionKilledDueToTimeout
Connection closed to due to statement timeout being reached and "queryTimeoutKillsConnection" being set to "true".

* LoadBalancingConnectionProxy.badValueForLoadBalanceBlacklistTimeout
Bad value ''{0}'' for property "loadBalanceBlacklistTimeout".






 

Posted by '김용환'
,

DB 성능 테스트 방법론

DB 2011. 8. 16. 15:22

최근에 DB 성능 테스트를 어떻게 하냐고 물어본 분이 계셔서 기억나는데로 언급하고자 한다.
(오래되서 기억이 잘 안나서. 기억나는 것만 체크)

웹 개발자로서 내가 했던 참여 했던 테스트는 총 3가지이다. 보면 알겠지만, 대부분 기존 DB의 가용량과 연관된 테스트였다. 이런 테스트에 참여했다는 게 자체가 사실 영광스럽기는 하다.

1. Oracle RAC
2. Sequoia(지금은 Tungsten)
3. 사내 DB 미들웨어 


DBA의 관점에서 진행하는 것이 아닌. 웹 서버에서 보낸 쿼리를 기반으로 하였다. 일반적인 IO 테스트가 아닌 쿼리 테스트의 관점에서 보는 것이 더 좋을 것 같다. IO 테스트는 DBA나 관련 시스템 엔지니어가 훨씬 더 많이 알 것 같다.
(예, 넥슨 DB팀의 SSD 테스트 http://nexondbteam.tistory.com/55.
큐브리드의 mysql SSD 성능 테스트 http://www.cubrid.org/ssd_performance_test)

또한 기본적인 기능 테스트는 당연히 해야하기 때문에 그냥 패쓰..


내가 측정하려고 했던 것은 웹 서버에서 엄청나게 많은 쿼리를 날렸을 때, DB나 미들웨어가 잘 버텨주는 지에 대한 테스트였다.


0. 철저한 계획
아마도 이 부분이 중요했던 것 같다. 사람들을 설득하고. 어떻게 진행할 것인지 얘기


1. 웹 서버에서는 해야할 일
(1)  개발 DB에 리얼 DB에 있는 데이터를 그대로 덤프해서 저장
    Row개수, index까지 똑같이
(2) 간단한 쿼리 테스트는 기본
(3) Transaction/procedure/join 테스트는 빼먹지 않기
(4) CLOB/한글 이슈 확인 - 응근히 이것을 테스트를 놓치기도 함. 골치 아파짐
   => 결국은 웹 서버나 게임서버에서 사용하는 모든 쿼리 테스트를 진행해야 한다.
(5) PrepareStaement 테스트 진행 (예전 버전의 Sequoia는 된다고 해놓고. 실제로는 지원이 안되었다.)
(6) PrepareStatement 테스트시 Hard 하게 테스트
    (DB의 prepared statement cache size를 넘어서도록 한다. 그래서 항상 DB콜을 할 수 있도록 테스트 환경 구축)
(7) DBA와 충분히 얘기 - 내가 못보는 부분을 DBA입장에서 보도록 함
(8) 웹서버의 bottleneck을 없도록 해서 DB의 성능이 최대한 나오게 개발
(9) 웹 서버는 최대한 많이 두고, 한 서버에 cpu개수 만큼의 JVM Instance(웹 어플리케이션 서버)를 구축

2. 구축환경
load runner   혹은       - >   웹 서버   ->   DB  혹은 DB 미들웨어
성능 테스트툴


3. DB 혹은 DB 미들웨어
(1) 가용성 테스트. (Active-Standby 테스트 : 문제없이 동작되는지 확인)
    - 간단한 테스트
    (프로세스 Kill /  iptables 블락 /  랜선 빼기)
     - Active한 서버를 내리고, Standby가 Active로 잘 돌아가는 지 확인
     - Reconnect 를 통한 fail over 검증 필요
 
(2) 성능 
    - 물리 서버의 성능에 비례, 좋은 장비는 최고의 퍼포먼스
    - 가용량 산정. Throughput 산정 가능
   
(3)  기능 테스트
    - reconnect
    - timeout
    - connection pooling
      connection을 pooling하고 있는데. DB에서 session kill를 하고 나서, 어떻게 하는지 확인

(4) QPS (query per second) 측정
      job queue에 쌓이는 시점을 발견해야 함.. (임계점)
      -> 안정 구간이 얼마정도인지 확보



'DB' 카테고리의 다른 글

[mysql] 테스트용 사용자 계정 추가  (0) 2011.10.24
mysql jdbc driver timeout 정보  (1) 2011.09.06
OSCON Data 2011, Brian Aker, "Living In A Relational World"  (0) 2011.07.27
cubrid DB 관련 정보  (0) 2011.06.22
[Mysql] 운영 잘하기  (0) 2011.05.19
Posted by '김용환'
,



다시 한번 DB와 관련 개념을 돌아보는 시간을 주신 분.
PT에 Sucks 를 단어를 쓰시다니.. 쇼킹했다. 




기억이 남는 부분. 

요즘 볼만한 RDMS의 status?

- Postgress Array types
- MySQL's memcache port
- Drizzle's Proto type/ Multi Master
- MariaDB Virtual Column

 

'DB' 카테고리의 다른 글

mysql jdbc driver timeout 정보  (1) 2011.09.06
DB 성능 테스트 방법론  (0) 2011.08.16
cubrid DB 관련 정보  (0) 2011.06.22
[Mysql] 운영 잘하기  (0) 2011.05.19
[Mssql] 공부  (0) 2011.03.25
Posted by '김용환'
,

cubrid DB 관련 정보

DB 2011. 6. 22. 14:37

쿼리 브라우져 사용 정보
http://blog.naver.com/idjung

큐브리드 DB 및 문의
http://cubrid.com/zbxe/home

큐브리드 슬라이드 정보
http://www.slideshare.net/cubrid

'DB' 카테고리의 다른 글

DB 성능 테스트 방법론  (0) 2011.08.16
OSCON Data 2011, Brian Aker, "Living In A Relational World"  (0) 2011.07.27
[Mysql] 운영 잘하기  (0) 2011.05.19
[Mssql] 공부  (0) 2011.03.25
[DB] 기타 정보  (0) 2011.03.23
Posted by '김용환'
,

[Mysql] 운영 잘하기

DB 2011. 5. 19. 15:31

mysql을 운영하면서 많이 고민했던 케이스였다.
 
 

1) mysql을 이중화하고, master-slave 를 1대 혹은 2대로 구성을 한다.(일반적으로는 slave는 2대) master DB 무너지면, 개발자들은 모두 소스 수정해서 slave DB를 보게 한다.

   -> 사람 손이 많이 감. ACL 문제 발생 가능성

2) mysql을 이중화하고, master-slave 구성하고, L4로 묶는다.. master 무너지면, slave로 자동으로 붙게 한다.

   

3) mysql을 이중화하고,  L4및 MMM 솔루션 (http://mysql-mmm.org/) 사용하는 방법

   -> MMM 솔루션을 통해서 multi-master 를 구성. MMM 솔루션은 loadbalancing, failover 및 모니터링 기능을 제공.

    -> multi-master를 두대, slave는 1대로 둠. multi-master끼리 L4로 엮음
     -> 무결성 확보보다는 빠른 failover 처리가 가장 중요한 관점에서 해결하려고 시도한 것임
 

http://forge.mysql.com/w/images/0/05/DualMasterSetupsWithMMM.pdf

'DB' 카테고리의 다른 글

OSCON Data 2011, Brian Aker, "Living In A Relational World"  (0) 2011.07.27
cubrid DB 관련 정보  (0) 2011.06.22
[Mssql] 공부  (0) 2011.03.25
[DB] 기타 정보  (0) 2011.03.23
mssql 시퀀스  (0) 2011.03.21
Posted by '김용환'
,