MySQL에서 파티션 일부를 다른 파티션 테이블로 옮겨보기

Overview

한동안 운영에 치여, 문서를 못봤더니, 재미난 사례를 많이 놓친듯.
그래서 여기저기 떠도는 문서 중 재미난 사례 하나를 내 입맛에 맞게 샘플을 변경해서 공유해봅니다.
(영혼없이 붙여넣기만 해도 알아보기 쉽게 ㅋㅋ)

Preview

파티셔닝 특정 부분을 다른 테이블 혹은 파티셔닝 일부로 넘기는 방안에 대한 것인데..

move-partition-data-file
move-partition-data-file

하단 포스팅 내용 중 미흡한 부분을 보완해서 정리해본 것입니다
https://dzone.com/articles/how-to-move-a-mysql-partition-from-one-table-to-an?utm_medium=feed&utm_source=feedpress.me&utm_campaign=Feed:%20dzone

Generate Test Data

먼저 테스트 데이터를 생성해야할테니..

mysql> create table f_tb (
      seq bigint(20) not null default '0',
      regdate date not null,
      cont text not null,
      primary key (seq,regdate)
  ) engine=innodb collate=utf8_unicode_ci
  /*!50500 partition by range columns(regdate)
  (partition p09 values less than ('2016-10-01'),
   partition p10 values less than ('2016-11-01'),
   partition p11 values less than ('2016-12-01'),
   partition p12 values less than ('2017-01-01')) */;

아래처럼 테스트로 사용할 데이터를 간단하게 생성해봅니다. 2017-01-01 기점으로 랜덤하게 120일 사이 일을 빼서 마치 파티셔닝 테이블이 관리된 것처럼 데이터를 밀어넣는 것이죠.

## 1건 데이터 생성
mysql> insert ignore into f_tb values 
    (rand()*1000000000, date_sub('2017-01-01', interval rand()*120 day), repeat(uuid(),5));

## 원하는 만큼 반복 수행
mysql> insert ignore into f_tb 
  select rand()*1000000000, 
      date_sub('2017-01-01', 
      interval rand()*120 day), repeat(uuid(),5) 
  from f_tb;

위에서 만든 이후 실제 테이블 데이터 건 수를 보면.. (전 대략 8000건만 만들었어요. 귀찮아서. ㅋ)

mysql> select count(*) from f_tb;
+----------+
| count(*) |
+----------+
|     8064 |
+----------+

Move Datafile to Temporay Table

자~ 이제 특정 파티셔닝 파일을 다릍 파티셔닝의 일부로 옮기는 작업을 해볼까요.

1) 동일한 테이블을 만들고, 파티셔닝이 없는 일반 테이블로 구성한다.

mysql> create table f_tb_p09 like f_tb;
mysql> alter table f_tb_p09 remove partitioning;

2) 임시 테이블 discard처리

f_tb에서 9월 데이터를 가져오기 위해, 테이블스페이스에서 discard 하도록 수행합니다. 임시 깡통 데이터가 사라지겠지요.

mysql> alter table f_tb_p09 discard tablespace;

3) 테이블 데이터 복사

파일 복사 이전에, 원본 테이블에 export를 위한 락을 걸고, 데이터 카피 후 락을 풀어줍니다.
(두개 세션 열기 귀찮으니.. MySQL 콘솔 클라이언트에서 바로 파일을 복사하도록.. ㅋㅋ)

mysql> flush table f_tb for export;
mysql> \! cp /data/mysql/test_db/f_tb#p#p09.ibd /data/mysql/test_db/f_tb_p09.ibd
mysql> unlock tables;

4) 임시 테이블에 데이터파일 Import

옮겨온 데이터파일을 실제 임시로 생성한 테이블에서 읽을 수 있도록 import 처리 해줍니다.

mysql> alter table f_tb_p09 import tablespace;

자~ 이제 정상적으로 데이터가 잘 옮겨졌는지 카운트를 해볼까요?

mysql> select count(*) from f_tb_p09;
+----------+
| count(*) |
+----------+
|     1860 |
+----------+

굳~ 잘 되었네요.

Import to archive

아카이브 테이블이 없다는 가정하에.. 아래와 같이 타겟 파티셔닝 테이블을 생성합니다. 당연한 이야기겠지만, 파티셔닝 정의를 제외한 테이블 구조는 동일해야하겠지요?

mysql> create table t_tb (
      seq bigint(20) not null default '0',
      regdate date not null,
      cont text not null,
      primary key (seq,regdate)
  ) engine=innodb collate=utf8_unicode_ci
  /*!50500 partition by range columns(regdate)
  (partition p09 values less than ('2016-10-01'),
   partition p10 values less than ('2016-11-01')) */;

mysql> select count(*) from t_tb;
+----------+
| count(*) |
+----------+
|        0 |
+----------+

자~ 끝판왕.. 마지막으로.. 타겟 파티셔닝 파일에 데이터파일을 변경해준다는 하단 alter 구문만 날려주면 끝~

mysql> alter table t_tb exchange partition p09 with table f_tb_p09;

mysql> select count(*) from t_tb;
+----------+
| count(*) |
+----------+
|     1860 |
+----------+

중요치는 않지만.. 임시 테이블 데이터는 깡통으로 남지요.
(COPY가 아닙니다. 임시 테이블에 데이터는 사라져요. ㅋ)

mysql> select count(*) from f_tb_p09;
+----------+
| count(*) |
+----------+
|        0 |
+----------+

Conclusion

신기하기는 했지만.. 이걸 어디에 쓸 수 있을까 잠깐 생각을 해봤는데.. 대고객 온라인 서비스에서는 큰 의미는 없다고 생각되는데요.

MySQL의 가장 큰 강점은 개인적으로 “데이터 복제”라고 생각합니다. Replication.. 그러나.. 위와 같이 데이터파일을 옮긴다면.. 아무래도 OS 상에서 동작하기에.. 데이터 복제 개념과는 동떨어진 처리입니다. 즉.. 설혹 마스터에서 특정 테이블 일부 데이터를 다른 테이블의 일부로 옮겨놓아도, 실제 슬레이브에서는 이 명령이 그대로 적용되지 않음을 의미하죠.

그러나!

만약 “특정 테이블”에 대한 데이터 분석 혹은 보관과 같은 이슈가 있을 시.. 덤프 없이, 놀고 있는 슬레이브, 혹은 스탠바이, 장비에서 일시적으로 잠금 처리를 한 후 파일 단위로 빠르게 옮겨봄으로써 의외로 쉽게 대응이 가능합니다. 물로 반드시 파티셔닝 테이블에 포함해야할 필요는 없지만.. ^^ 어플리케이션 복잡도를 줄이기 위해서라면 위와 같이 파티셔닝 테이블의 일부로 적용하는 것도 좋은 케이스이겠고요.

감사합니다. ^^

PowerDNS와 MySQL로 DNS를 해보고 싶어요~

Overview

PowerDNS란 범용적(?)으로 사용되는 오픈소스 기반의 DNS서버이고, 다양한 백엔드를 지원하는 멋진(?) DNS 이기도 합니다. 얼마전, 이 관련되어 간단한 사례에 대해 세미나를 진행을 하였고, 이 구성에 대한 설명이 미흡하여 간단하게 정리해봅니다. ^^

Install PowerDNS

CentOS 6.7 버전에서 구성을 하였고, 실제 설치 작업에는 아래와 같이 같단합니다.
(참고 : https://doc.powerdns.com/md/authoritative/installation/#binary-packages)

$ yum install pdns
$ yum install pdns-backend-mysql

(단, 여기서 MySQL 은 이미 구성되어 있다는 가정하에 진행합니다.)

Configuration

자~ 이제 DNS 데몬을 설치하였으니..(두줄에.. 끝? -_-;; 헐~)

이제,설정을 해보도록 합시다~ 먼저.. MySQL의 계정 및 스키마를 생성을 해보고..

$ mysql -uroot -p << EOF
  create database pdns_production;
  grant all on pdns_production.* to pdns@127.0.0.1 identified by 'pdns';
EOF

DNS 서버에서 사용할 스키마를 아래와 같이 생성을 합니다. 귀찮으니.. 그냥 콘솔 쉘에서 할 수 있도록.. 아래와 같이.. ㅋㅋ

$ mysql -uroot -p pdns_production << EOF
create table domains (
 id int auto_increment,
 name varchar(255) not null,
 master varchar(128) default null,
 last_check int default null,
 type varchar(6) not null,
 notified_serial int default null,
 account varchar(40) default null,
 primary key (id)
) engine=innodb;

create unique index name_index on domains(name);

create table records (
 id int auto_increment,
 domain_id int default null,
 name varchar(255) default null,
 type varchar(10) default null,
 content text default null,
 ttl int default null,
 prio int default null,
 change_date int default null,
 disabled tinyint(1) default 0,
 ordername varchar(255) binary default null,
 auth tinyint(1) default 1,
 primary key (id)
) engine=innodb;

create index nametype_index on records(name,type);
create index domain_id on records(domain_id);
create index recordorder on records (domain_id, ordername);

create table supermasters (
 ip varchar(64) not null,
 nameserver varchar(255) not null,
 account varchar(40) not null,
 primary key (ip, nameserver)
) engine=innodb;

create table comments (
 id int auto_increment,
 domain_id int not null,
 name varchar(255) not null,
 type varchar(10) not null,
 modified_at int not null,
 account varchar(40) not null,
 comment text not null,
 primary key (id)
) engine=innodb;

create index comments_domain_id_idx on comments (domain_id);
create index comments_name_type_idx on comments (name, type);
create index comments_order_idx on comments (domain_id, modified_at);

create table domainmetadata (
 id int auto_increment,
 domain_id int not null,
 kind varchar(32),
 content text,
 primary key (id)
) engine=innodb;

create index domainmetadata_idx on domainmetadata (domain_id, kind);

create table cryptokeys (
 id int auto_increment,
 domain_id int not null,
 flags int not null,
 active bool,
 content text,
 primary key(id)
) engine=innodb;

create index domainidindex on cryptokeys(domain_id);

create table tsigkeys (
 id int auto_increment,
 name varchar(255),
 algorithm varchar(50),
 secret varchar(255),
 primary key (id)
) engine=innodb;
create unique index namealgoindex on tsigkeys(name, algorithm);
EOF

pdns 설정 파일을 열어서.. 기본적으로  파일 기반인 BIND로 설정되어 있는 부분을 주석처리하고 MySQL접속 정보를 넣어줍니다. 위에서 계정 생성을 127.0.0.1로 접근 호스트를 생성하였으니.. 패스워드는 간단하게 설정하였습니다. (다른곳에서는 접근이 불가할테니요. ^^)

$ vi /etc/pdns/pdns.conf
#setuid=pdns
#setgid=pdns
#launch=bind

launch=gmysql
gmysql-host=127.0.0.1
gmysql-user=pdns
gmysql-password=pdns
gmysql-dbname=pdns_production

관리 서버를 올리고 싶다면.. 아래와 같이 pdns.conf에서 웹서버 부분을 변경 설정하여 올립니다. (여기서는 쿼리로만 추가 변경 테스트를 할테니, 굳이 필수 요소는 아닙니다. ^^)

webserver=yes
webserver-address=0.0.0.0
webserver-port=8081
$ /etc/init.d/pdns start

이 모든 과정은.. 하단 메뉴얼에 친절하게 잘 명시되어 있고.. 제 입맛에 맞게 편집을 하였습니다. ㅋㅋ

참고 : https://doc.powerdns.com/md/authoritative/howtos/#basic-setup-configuring-database-connectivity

DNS Test with SQL

먼저 아래와 같이 없는 DNS질의를 해보면 전혀~ 도메인에 대한 정보가 보여지지 않습니다.

$ dig +short aaa.db.io @127.0.0.1

이제 테스트를 위해 아래 쿼리를 밀어넣어줍니다. (참고로, 테이블에는 데이터가 전~혀 없다는 가정으로 테스트합니다.) 여기서 중요한 것은 SOA 는 필수입니다. 도메인의 영역을 표시할 뿐만 아니라, 어떻게 관리되어야할 지를 알려주는 도메인 Zone 개념을 내포하기 때문이죠.

저에게 중요한 것은 TTL이 0인 A타입의 도메인이기에.. A레코드인 경우는 TTL을 0으로 지정하여 넣어줍니다.

INSERT INTO domains (name, type) values ('db.io', 'NATIVE');
INSERT INTO records (domain_id, name, content, type,ttl,prio) VALUES
(1,'db.io','admin.db.io','SOA',86400,NULL),
(1,'aaa.db.io','192.0.0.1','A',0,NULL),
(1,'bbb.db.io','192.0.0.2','A',0,NULL),
(1,'ccc.db.io','192.0.0.3','A',0,NULL);

자. 아까 질의했던 도메인을 다시 확인해볼까요? 조금전에 DB에 밀어넣은 IP를 알려줍니다.

$ dig +short aaa.db.io @127.0.0.1
192.0.0.1

조금 더 자세하게.. 하단과 같이 질의를 해보면, TTL(ANSWER SECTION) 또한 0으로 잘~ 세팅되어 있다는 것도 확인할 수 있지요.

 $ dig aaa.db.io @127.0.0.1

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.47.rc1.el6 <<>> aaa.db.io @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21973
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;aaa.db.io. IN A

;; ANSWER SECTION:
aaa.db.io. 0 IN A 192.0.0.1

;; Query time: 6 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Tue Jan 17 22:09:03 2017
;; MSG SIZE rcvd: 43

이제 쿼리로 도메인의 아이피를 바꿔볼까요?

$ mysql -uroot -p pdns_production << EOF
 update records set content = '192.0.0.4' where name = 'aaa.db.io'
EOF

쿼리 실행 후 DNS 질의를 해보면.. 바로 변경된 아이피를 확인할 수 있습니다.

$ dig +short aaa.db.io @127.0.0.1
192.0.0.4

이 내용 또한 앞선 매뉴얼의 테스트 내용을 약간 제 입맛에 맞게 살을 붙여서 만들어보았습니다.^^

Conclusion

여전히 대부분의 DNS는 BIND기반으로 동작하고 있고.. 안정성 또한 입증된 방식이기도 하죠.

그렇지만 MySQL 을 백엔드로 가지는 PowerDNS는 DB가 가지는 강점.. 예를 들면 데이터 처리 및 보안 등등 BIND에서 가져갈 수 없는 강점을 가지기도 하지요. 이를테면.. 존 추가 이후에 서버 재시작이 필요없다거나.. 파일이 아닌 DNS쿼리 하나하나의 ROW Level Locking.. 트랜잭션 등등~~

이 포스팅에서는 간단하게.. 테스트를 수행할 수 있는 정도의 PowerDNS with MySQL 구성 방법을 설명해 보았습니다. 좋은 사례가 있으면 앞으로도 쭉 나왔으면 합니다. ^^

감사합니다.

pt-online-schema-change에 숨겨진 무시무시한 이슈!

Overview

최근들어 거의 연단위로 블로깅을 하나씩 올리는 듯 하는군요. 여기저기 시국이 어지럽고, 바쁘다는 말도 안되는 핑계를 무마시키기 위해.. 아무튼 간만에 블로깅 하나 올려봅니다.

MySQL은.. 특히나 온라인 스키마 변경이 취약합니다. 물론 5.6부터는 online alter기능이 포함되어 있다고는 하나.. 100% 완벽하게 모든 상황을 온라인스럽게 제공해주지도 않고.. 그렇다하더라도, 일정 트래픽 이상의 데이터 변경이 이루어지는 경우, 게다가 슬레이브 지연을 염두한다면.. 꺼려지는 상황이 있지요. (참고로, 마스터에서 온라인 스키마 변경이 이루어졌을지라도, 이 관련 alter구문이 슬레이브로 넘어갔을 때는, alter이후 데이터 변경을 수행해야 하므로, 그만큼 복제 지연이 발생합니다. 미네럴~)

아무튼.. 이런저런 이유로.. 기승전툴이라는 생각이드는데요. 그중, Percona에서 오픈소스 라이선스로 제공하는 pt-toolkit에 포함된 pt-online-schema-change툴을 저는 애용합니다.

참 좋지만.. 반드시 짚고 넘어가야할 이슈 하나만은 반드시 공유할 필요가 있다는 생각이 들어, 이렇게 늦은 시간 포스팅을 합니다. 🙂

pt-online-schema-change?

문제를 말하기에 앞서서, 먼저 pt-online-schema-change의 동작 방식에 대해서 정말 간~략하게 알아볼 필요가 있겠군요.

이 툴은 서비스 중지 없이 실시간으로 테이블 DDL Alter구문을 적용할 수 있도록 도와주는 하나의 “유틸리티”이며, 흔한 RDBMS에서 제공하는 기능 몇가지와, 머리좋은 개발자의 “꼼수”가 환상적인 조합을 이루며 만들어진 멋진 툴입니다. 짝짝짝~

간단한 테이블 변경 순서는 아래와 같아요.

  1.  클론 테이블 생성 후 의도한 스키마를 적용한다.
  2.  원본 테이블 변경 시 트리거로 이를 클론 테이블에 적용한다. (replace into/delete)
  3.  조각 조각 데이터를 잘라서, 데이터를 중복은 무시한 채 복사한다. (insert ignore)
  4.  테이블 복사가 완료되면, 클론<->원본 테이블명을 스위칭한다.
pt-online-schema-change
pt-online-schema-change

Percona..당신들의 잉여력은 많은 이들을 행복하게 하였습니다. 땡큐~!!

 

Problem

물론, pt-online-schema-change도 하나의 툴인 이상.. 분명 100% 모든 상황에 적합하지는 않습니다.

뭐.. 예를 들면.. 아무래도 데이터를 조각조각 나누어서 복사를 해야하는만큼, Primary Key는 반드시 존재해야하는 상황이어야하고, Foreign Key가 정의된 경우에도 제약이 있고.. 궁시렁궁시렁..

그렇지만, 오늘 여기서 짚어보자하는 문제는.. 사실은 pt-online-schema-change가 충분히 동작할 수 있는 상황에서, 데이터가 달라질 수 있는.. 곰곰히 생각을 해보면 서비스 오류까지 발생할 수 있는 그런 상황입니다요.

pt-online-schema-change에서 앞서 설명을 간단하게 했던 것처럼, 트리거를 통해서 현재 데이터 변경된 이력을 클론 테이블(스키마 적용된 최종본 구조 테이블)로 적용합니다. 적용시 insert/update 구문 모두 아래와 같이 replace into 구문으로 대동단결 하는데요. (참고로 _test_tmp는 클론테이블입니다.)

DELIMITER $$
CREATE TRIGGER trg_test_update
AFTER UPDATE ON test
FOR EACH ROW
BEGIN
 REPLACE INTO _test_tmp VALUES (NEW.id, .., NEW.created_at);
END$$
DELIMITER ;

동일 트리거이니.. 문제삼을 update 트리거만..

멀쩡한 상황에서는 이슈가 아닙니다만.. 여기서 replace의 동작 방식을 이해하고, 조금만 고개를 갸우뚱거리면 무엇이 문제인지 이해하실 수 있을 것이예요. 귀찮으니, 매뉴얼 원문을 퍼오겠습니다. 크하하

REPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserte

그렇답니다. 기존의 pk/uk와 같이 충돌나는 것들은 다 날리고.. 신규 데이터로 밀어넣는다는 것인데요. 그렇기에 pk가 없으면 대 재앙일 것이고.. 이런 부분에 대해서는 나름 pt-online-chema-change에서 제약 조건을 체크하기는 합니다. (그랬던가.. 가물가물..)

그렇다면.. 이런 경우 말고.. PK가 변경되는 상황을 생각해볼까요? 이런 상황에서도 역시 replace into 구문으로 트리거는 동작할 것이고.. 트리거 내부에는 “NEW.id, .., NEW.created_at”와 같이 변경될 데이터 기준으로 클론 테이블에 적용될 것이고.. NEW.id가 PK라면, 이 기준과 동일한 데이터를 날리고 엎어버릴 것이고..

그렇다면.. 우움.. 기준이 되는 NEW.id가 변경된 경우에는.. -_-;; 예전 OLD.id의 행방은??

딩동댕~ 맞습니다. ㅠㅠ 어이없게도.. 업데이터로 동작을 해야할 상황이.. 기준점이 변경되었다는 이유로.. 여전히 남아있는 상태가 되겠지요. 미네럴2.

즉.. 로직적인 이슈로.. 기준점이 되는 PK를 변경하는 경우 여전히 과거의 이력이 남아있게 되는.. 어이없는 상황이 발생한다는 것입니다!! <==== 주의주의1

Solutions

사실.. 해결책은 의외로 간단합니다.

PK는 업데이트 하지 말고, 트랜잭션으로 묶어서 DELETE -> INSERT 처리한다. 참 쉽죠잉~! 이것은.. 뭐.. 해결방안이라기 보다는 그냥 “우회처리”라고 해야하나.. -_-;;

그치만.. 사용자를 쿼리를 날리는 경우도 있고.. 기타 이런 상황을 인지 못하는 경우를 대비해서.. 본질적인 해결 방안이 필요합니다.

PK가 변경된 경우 트리거 내부적으로 과거 데이터를 날려주는 로직을 넣어준다.

트리거 정의하는 부분에.. PK 변경 시 OLD 이미지에 해당하는 데이터를 날리도록 강제하면 되지요. 뭐.. 아래 예시는.. 쿼리 레벨 간단하게 소스를 약간 수정한 것일뿐.. 조금 수정해서 트리거 내부에 if else 구문을 넣어도 되고..암튼 그렇답니다.

sub create_triggers {
  .. 중략 ..
  ## 추가 ##
  my $upd_index_cols = join(" AND ", map {
    my $new_col = $_;
    my $old_col = $old_col_for{$new_col} || $new_col;
    my $new_qcol = $q->quote($new_col);
    my $old_qcol = $q->quote($old_col);
    "OLD.$old_qcol <=> NEW.$new_qcol"
  } @{$tbl_struct->{keys}->{$del_index}->{cols}} );

  .. 중략 ..

  ## DELETE 부분 추가 ##
  my $update_trigger
    = "CREATE TRIGGER `${prefix}_upd` AFTER UPDATE ON $orig_tbl->{name} "
    . "FOR EACH ROW "
    . "BEGIN "
    . "DELETE IGNORE FROM $new_tbl->{name} WHERE !($upd_index_cols) AND $del_index_cols;"
    . "REPLACE INTO $new_tbl->{name} ($qcols) VALUES ($new_vals);"
    . "END ";
  .. 중략 ..
}

PK가 변경된 경우에는 데이터를 지워버리고, 그렇지 않으면.. 그냥 예전처럼 replace~ 트리거 내부적으로 update시에 쿼리는 많아지겠고, 트랜잭션이 없는 상황에서는 약간 걱정될만한 사항도 있겠지만.. 다들 기본적으로 InnoDB사용하시잖아요? ㅋㅋ

사실.. 이런 부분은 간단하게 소스를 수정해서 활용을 해도 됩니다. 어려운것도 아니고.. 잉여력이 조금 남아있다면 얼마든지 상황에 맞게 고쳐 쓸 수 있겠지요. 그치만.. 이 부분에 대해서 Percona에 문의를 해보니.. 그들의 입장은.. 번역하면 아래와 같았습니다.

어째서 PK가 변경이 되어야하는 것인가? 테이블에서 PK는 절대적이므로, 결코 업데이트 작업이 이루어지지 않아야 한다. 우리들은 이런 현상을 버그로 인정하지 않는다. – 어느 개발자 –

버그가 아니라면.. 이런 상황을 감지해서 제약을 걸든가.. 미네럴3..

사실.. 가장 경계를 해야하는 문제는.. (제 개인적인 의견이지만) 런타임 오류라고 생각합니다. 서비스 오픈 전에 발생하는 모든 이슈는 사전에 불을 끄고 튜닝하고 해결할 수 있지만.. 런타임 도중 특이 케이스에서만 노출되는 이슈는 정말로 답이 없습니다.

위와 같은 동일한 방식은 아니더라도, 적어도 PK변경 시 뒤따르는 이러한 데이터 꼬임 현상에 대한 것들은 Percona 측에서 제대로 이해하고 GE버전에 적용을 해줬으면 하는 마음이 있고.. 뭐.. 개인적으로, 조직적으로 푸시를 넣고 있습니다만..

좋은 소식이 있겠지요. ^^

Conclusion

pt-online-schema-change 툴은 굉장히 유용하고, 제가 정말 자주 쓰는 권고할만한 유틸입니다. 게다가 소스도 오픈되어 있고, 누구나 수정할 수 있는 라이선스 정책이고요.

그렇지만, 오픈소스를 사용하는만큼.. 그렇게 접근을 하기에.. 상용 솔루션과는 다르게 발생하는 이슈에 대해서 분석을 해보고 해결책을 가져가보고, 대안도 고민해보고.. 사용자 자신도 오픈소스를 사용하는 대가를 치뤄야 하겠지요. 뭐.. 제 능력으로는 지금과 같이 경험을 공유하는 것이 그나마 최선일 듯 합니다만.. ^^

올해 금융업에 뛰어들어, 오픈소스DBMS 적용을 어찌어찌 하다보니.. 예전에는 별 생각이 없이 넘어가던 가벼운 생각들도, 꽤나 진지한 주제로 제게 다가오네요.

다음 포스팅은 언제일지는 모르지만.. 시간이 될 때.. adt를 주제로 한번 읊어보는 것도 좋겠다는 생각이..

좋은 밤 되시와요~!!