Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

<!>미완성

Contents

소개

어쩌다 보니 Postgresql(pgsql) 데이터베이스를 Mysql 데이터베이스로 마이그레이션 해야 한다. 우여곡절 끝에 마이그레이션을 끝낸 상태에서, 마이그레이션하면서 신경써야 할 것들과 마이그레이션 방법등을 정리한다.

현재 상황

현재 상황은 다음과 같다.
  1. 운영 중에 있는 서비스다. 서비스의 데이터는 AWS상에서 pgsql로 관리하고 있다. 즉 EC2 인스턴스다.
  2. pgsql을 RDS(mysql)로 마이그레이션 해야 한다.
  3. 마이그레이션 범위는 다음과 같다.
    1. 데이터베이스 스키마는 그대로 유지한다.
    2. 기존 데이터도 마이그레이션 대상이다.
    3. 다운 타임없이 혹은 최소화(희망사항)

상황에 대한 평가

마이그레이션 이유

왜 마이그레이션 하는가. 마이그레이션 할 만한 가치가 있는가에 대한 평가다.
  1. Mysql에 비해서 Postgresql을 잘 다룰 수 있는 엔지니어가 많지 않다. 유지보수가 제대로 안된다.
  2. RDS를 사용하면 유지보수에 신경서야 하는 비용을 줄일 수 있다. Scale-in/out, 모니터링, HA, Replica cluster 구성등등을 한번에 끝낼 수 있다. Postgresql로 하려면 고민좀 해야 할 거다. 더 중요한건 제대로 고민해줄 만한 엔지니어가 없다는 점.
여기에 대한 내 생각..

"이런 이유로 마이그레이션 하지 말라." Postgresql 운영이 문제라면, 마이그레이션 할 시간에 postgresql을 공부해서 제대로 관리할 수 있는 엔지니어를 키우는게 낫다. 왜 이런 생각을 하게 됐냐하면
  • 이 기종간 마이그레이션은 사람이 할 만한 일이 아니다.
때문이다.

처음엔 간단하게 생각했는데, 생각만큼 간단하지가 않다. 만약 대상이 oracle이나 mssql과 같은 상용 RDBMS였다면, 이 기종간 마이그레이션이라 하더라도 별 어려움이 없었을 것이다. 마이그레이션 툴의 완성도가 높기 때문이다. 그러나 mysql과 postgresql은 마땅한 툴이 없다. 그나마 선택할 수 있는 툴이
  • pg2mysql
  • mysql-workbench
이다. 그런데, 완성도가 한참이나 떨어진다. pg2mysql을 선택했는가 ? 그렇다면, 직접 마이그레이션 프로그램을 짜는 거랑 별 차이를 느낄 수 없을 것이다. 정말이다. 그냥 (pg2mysql을 참고해서)새로 만드는게 낫다. mysql-workbench의 migration wizard 기능을 사용하면 훨씬 낫다. 하지만 pg2mysql에 비해서 그렇다는 거다. mysql-workbench에 migration wizard 형식으로 postgresql을 지원한게 채 1년이 안된다. 그냥 베타버전이라고 보면된다(실제로도 그렇다)

Mysql-workbench를 이용하더라도 "한번에 성공"하는 건 꿈꾸지 말아야 한다. 나는 mysql-workbench를 사용하기로 했다.

무정지 마이그레이션

무정지 마이그레이션 같은 거 생각하지 말자. 이런건 같은 기종간 혹은 (툴이 검증된)상용 RDBMS간에나 고려하기 바란다.

처음엔 별 생각 없이 DML 로그를 이용하면 될거라고 생각했지만, 결국 불가능하다는 결론에 도달 서비스 중지 후 마이그레이션 작업을 진행했다.

DML로그는 "insert, delete, update"등의 로그를 남긴다. 언뜻 생각하기에 이들 로그만 문제없이 남긴다면, 마이그레이션 후 DML로그를 새로운 데이터베이스에 적용하면 될 것으로 생각했다. 하지만 아래의 문제가 발생했다.
  • Auto increment 필드가 문제된다. insert 할 때 Auto increment 필드의 값이 log에 남지 않는다. 따라서 update 시 key를 일치시킬 수가 없다. 예를 들어 ID가 auto increment 필드다. insert 했을 때 값이 10000 이다. 나중에 update ... where id=10000 을 한다. 이 id=10000이 정말로 update 하고자하는 레코드를 의미하는지 보장할 수가 없다.
조금만 깊이 생각했다면, 알아챌 수 있는 문제였는데 초기에 놓쳐버렸다.

다운타임 최소화

무정지 마이그레이션은 포기하더라도 서비스 다운타임은 최소화 해야 겠다. 가장 큰 고려사항은 AWS Instance에서 AWS Instance(RDS)로의 마이그레이션이라는 점이다.

Online 마이그레이션 같은 건 꿈또 꾸지말자. 모든 작업은 로컬에서 진행하는 걸로 한다.
  • 빵빵한 로컬 시스템 구축한다.
    • 데이터 양에 따라 다른데, 메모리는 16G 정도로 한다.
    • SSD 사용한다. 필수다. 시간을 4배는 단축할 수 있다.
  • 로컬에서 로컬로 마이그레이션 한다.
    • 원격에 있는 데이터베이스를 dump 뜬다음 로컬 데이터베이스에 밀어 넣는다.
    • 로컬 데이터베이스에 있는걸 로컬로 마이그레이션 한다.
    • 마이그레이션 끝난걸 dump 한다음에 최종 목적지 RDS에 restore 한다.

마이그레이션시 고려해야 할 사항

마이그레이션 대상 데이터베이스 크기 확인

Postgresql 데이터베이스 크기 확인
postgres=# SELECT pg_database_size ('db_name');
 pg_database_size 
------------------
        102194978
(1 row)

참고로 mysql 데이터베이스 크기 확인
mysql> SELECT table_schema "Database Name", SUM(data_length + index_length) / 1024 / 1024 "Size(MB)" FROM information_schema.TABLES GROUP BY table_schema;
+--------------------+-------------+
| Database Name      | Size(MB)    |
+--------------------+-------------+
| information_schema |  0.00781250 |
| mysql              |  0.62274456 |
| phpbb              | 52.52191901 |
+--------------------+-------------+
3 rows in set (0.09 sec)

index length 크기 제한

Mysql의 한 row가 가질 수 있는 index 최대 크기는 (InnoDB 에서)767 byte다. 반면 Pgsql은 8191로 text 데이터 타입을 index하기에 충분한 크기다. 만약 마이그레이션 하려는 pgsql 데이터베이스의 text 데이터 타입이 index가 걸려있다면, index 최대 크기를 넘기는 경우를 고민해야 한다.

가장 좋은 방법은 mysql의 index prefix 기능이지 싶다.

테스트를 위해서 idxtest 테이블을 만든 다음 prefix index를 추가했다. index length는 32로 했다.
mysql> create table idxtest (str text, age int);
mysql> ALTER TABLE test ADD UNIQUE INDEX stridx (str(32));
인덱스 정보를 확인해 봤다.
mysql> show index from idxtest\G
*************************** 1. row ***************************
        Table: idxtest
   Non_unique: 0
     Key_name: stridx
 Seq_in_index: 1
  Column_name: str
    Collation: A
  Cardinality: 1
     Sub_part: 32
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment: 
Index_comment: 
1 row in set (0.00 sec)

UTF8에서의 Index 크기

앞서 mysql에서 하나의 row가 가질 수 있는 최대 index 길이는 767 byte라고 했다. 이건 1byte언어에서의 경우이고, charater set으로 UTF8을 쓴다면, index의 길이는 더 줄어든다. UTF8의 경우 문자 하나는 3byte를 차지하므로 prefix index의 길이는 255로 줄어든다. 원칙적으로 UTF8의 경우 영문자와 숫자는 1byte로 처리하고 나머지를 3byte로 처리하지만, prefix index는 무조건 x3을 해버린다.
mysql> create table mytest (str text, id int) DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
mysql> ALTER TABLE mytest ADD UNIQUE INDEX (str(500));
ERROR 1709 (HY000): Index column size too large. The maximum column size is 767 bytes.
prefix의 크기를 500으로 했지만 500 * 3 == 1500 해서 767을 초과해 버리는 거다.

이 경우 innodb_large_prefix 옵션을 사용하면 된다. 이 옵션을 ON하면, 3072 byte까지 사용할 수 있다. large prefix를 하기 위해서는 몇가지 설정 변경이 필요하다. my.cnf를 수정하기로 했다.
# cat /etc/mysql/my.cnf
....
....
[mysqld]
default-storage-engine = INNODB
innodb_file_per_table
innodb_file_format=Barracuda
innodb_large_prefix
....
mysql server를 재시작 한 후, 설정값들이 제대로 적용됐는지 확인해 보자.
mysql> select  @@global.innodb_file_format;
+-----------------------------+
| @@global.innodb_file_format |
+-----------------------------+
| Barracuda                   |
+-----------------------------+
1 row in set (0.00 sec)

mysql> select  @@global.innodb_large_prefix;
+------------------------------+
| @@global.innodb_large_prefix |
+------------------------------+
|                            1 |
+------------------------------+
1 row in set (0.00 sec)

select  @@global.innodb_file_per_table;
+--------------------------------+
| @@global.innodb_file_per_table |
+--------------------------------+
|                              1 |
+--------------------------------+
1 row in set (0.00 sec)

테이블을 만들 때도 설정이 필요하다. ROW_MORMAT=DYNAMIC로 해준다.
mysql> create table mytest (str text, id int) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin ROW_FORMAT=DYNAMIC;
mysql> ALTER TABLE mytest ADD UNIQUE INDEX (str(500));
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0
오케이 성공이다.

궁금해서 실제 가능한 index length 크기 확인
mysql> ALTER TABLE mytest ADD UNIQUE INDEX (str(1000));
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0
....
mysql> ALTER TABLE mytest ADD UNIQUE INDEX (str(1200));
ERROR 1071 (42000): Specified key was too long; max key length is 3072 bytes

index 필드의 case-sensitive

pgsql의 index는 case-sensitive하다. 하지만 mysql의 index는 case-insensitive, 대소문자를 구분하지 않는다. 예를 들어 pgsql에서 'aAa'와 'AAa'는 서로 다른 값으로 index에 문제가 없지만 mysql에서는 Duplicate 에러가 발생한다.
mysql> insert into idxtest values ('yundream', 19);
mysql> insert into idxtest values ('Yundream', 19);
ERROR 1062 (23000): Duplicate entry 'Yundream' for key 'stridx'

다음과 같이 필드에 COLLATE 설정을 적용하는 것으로 해결할 수 있다.
mysql> DROP TABLE idxtest;
mysql> CREATE TABLE idxtest ( str text COLLATE latin1_general_cs, age int);
mysql> ALTER TABLE idxtest ADD UNIQUE INDEX stridx (str(32));
mysql> insert into idxtest values ('Yundream', 29);
Query OK, 1 row affected (0.00 sec)

mysql> insert into idxtest values ('yundream', 29);
Query OK, 1 row affected (0.01 sec)

mysql> insert into idxtest values ('yundream', 29);
ERROR 1062 (23000): Duplicate entry 'yundream' for key 'stridx'
_cs는 case-sensitive, _ci는 case-insensitive를 의미한다.

Collation은 데이터베이스에 저장된 값을 검색하거나 정렬하는 작업을 할때, 문자열들 간의 비교 규칙을 정의하기 위해서 사용한다. 따라서 CHAR, VARCHAR, TEXT 같은 데이터 타입에 대해서 사용할 수 있다.

만약 다루는 문자열이 UTF8이라면 문제가 좀 복잡해 진다. COLLATE utf8_general_cs을 사용하면 될 것 같지만, 현재(2012년 2월) 버전에서는 에러가 출력된다. 지금은 _ci 만 허용한다. 이 경우 utf8_bin을 사용하면 된다.

Timestamp

Postgresql과 mysql 모두 timestamp를 지원한다. 거의 동일하게 사용할 수 있는데, Postgresql은 필드 단위로 time zone을 지정할 수 있다. Mysql은 필드 단위로는 지정할 수 없고, 데이터베이스 단위로의 지정만 가능하다.

Postgresql은 timestamp 타입에 timestamp without time zonetimestamp with time zone이 있다. timestamp로만 지정할 경우 timestamp without time zone으로 설정된다. timestamp with time zone으로 설정하면, 시간뒤에 UTC 시간 편차를 출력한다.

timestamp 필드를 마이그레이션 하는데는 문제 없지만 mysql의 time zone을 맞춰주는게 좋다.
mysql> SET GLOBAL time_zone='+09:00'
mysql> SET time_zone='+09:00'
GLOBAL은 시스템 전역으로 지정하기 위해서 사용한다. GLOBAL을 사용하지 않으면, 클라이언트 세션에 대해서만 time zone을 지정한다.

위의 입력 결과를 확인해 보자.
mysql> select @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| SYSTEM             | +09:00              |
+--------------------+---------------------+

Mysql에서 두개의 timestamp를 사용할 경우 조심해야 한다. 아래의 경우를 보자. 처음 timestamp field만 CURRENT_TIMESTAMP로 채워졌다. 그러면 ts2에 DEFAULT CURRENT_TIMESTAMP를 주면 될 거라고 생각할 수도 있지만, mysql은 하나의 row에 하나의 DEFAULT CURRENT_TIMESTAMP만 가능하다.
mysql> create table mytest04 (ts timestamp NOT NULL, ts2 timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, str text);
ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
Mysql 데이터베이스가 처리해 주지 않기 때문에 소프트웨어 영역에서 신경써서 처리해 줘야 한다.

Foreign key

Auto increment

Mysql과 Postgresql모두 auto increment field를 지원하지만 방식에 차이가 있다.

postgresql 방식 : table_name 테이블의 column_name 칼럼에 auto increment를 적용한다.
ALTER TABLE table_name ALTER COLUMN cloumn_name SET DEFAULT nextval('seqname'::regclass);

mysql 방식 : table_name 테이블의 column_name 칼럼에 auto increment를 적용한다.
ALTER TABLE table_name MODIFY id int AUTO_INCREMENT;

따라서 nextval을 grep 해서 mysql 방식으로 변경해야 한다. 대략 아래와 같은 Perl 코드로 변경할 수 있다.
$line =~ s/^ALTER TABLE ([a-zA-Z0-9_]+) ALTER COLUMN ([a-zA-Z0-9]+) .+/ALTER TABLE \1 MODIFY \2 int AUTO_INCREMENT/;

Migration tool

먼저 postgresql에서 mysql로 변환해주는 (공개)툴을 찾아봤다. 완벽한 툴은 없는 것 같다. 위의 제약들 때문에 완벽하게 마이그레이션 해주는 툴을 찾는 것은 쉽지 않을 거 같다. 필드변환도 해줘야 하고, 데이터베이스 옵션도 변경해야 하고.

그래서 선택한 툴이 pg2mysql이다. php로 작성된 건데, postgresql 구문을 mysql 구문으로 변환해 준다. 하지만 완벽하지 않으며, 그럭저럭 괜찮은 변환물을 얻을려면 소스코드를 수정해야 한다. 그리고 2차 변환툴도 만들어야 제대로된 마이그레이션 툴을 가질 수 있을거다. 2차 변환툴은 perl로 개발했다.

마이그레이션 정합성 확인 절차

다른 데이터베이스로의 마이그레이션이라서 신경쓸것들이 좀 있다.
  1. 모든 데이터베이스와 모든 테이블이 만들어져야 한다.
  2. Index, Auto incremet, Foreign key, char set, filed data type 등을 일치시켜야 한다. 일치하지 않을 경우 동일한 효과를 가질 수 있도록 수정해줘야 한다.
  3. 모든 테이블에 모든 값이 insert 돼야 한다.
  4. 입력된 모든 값을 확인한다.

모든 테이블에 대한 row 값 확인

테이블에 있는 row 값을 저장하고 diff로 확인한다. 이것으로 데이터베이스와 테이블이 제대로 만들어졌는지, 그리고 데이터가 제대로 입력됐는지를 확인할 수 있다.

데이터베이스의 모든 Table의 count
#!/bin/bash
database=database_name
user=postgres
echo "Database : $database"
PGCOMMAND=" psql -U $user -d $database -At -c \"
            SELECT   table_name
            FROM     information_schema.tables
            WHERE    table_type='BASE TABLE'
            AND      table_schema='public'
            \""

TABLENAMES=$(export PGPASSWORD=test; eval "$PGCOMMAND")

for TABLENAME in $TABLENAMES; do
    PGCOMMAND=" psql -U $user -d $database -At -c \"  
                SELECT   '$TABLENAME',  
                         count(*)   
                FROM     $TABLENAME  
                \""
    eval "$PGCOMMAND"
done

데이터베이스의 모든 테이블을 덤프 받는다.
#!/bin/bash
database=database_name
user=user_name
PGCOMMAND=" psql -U $user -d $database -At -c \"
            SELECT   table_name
            FROM     information_schema.tables
            WHERE    table_type='BASE TABLE'
            AND      table_schema='public'
            \""

TABLENAMES=$(export PGPASSWORD=test; eval "$PGCOMMAND")

for TABLENAME in $TABLENAMES; do
    midfile="/tmp/postgres.$database.$TABLENAME.mid"
    dstfile="/tmp/postgres.$database.$TABLENAME.csv"
    PGCOMMAND=" psql -U $user -d $database -At -c \"
        copy(select * from $TABLENAME order by id) to '$midfile' DELIMITER ',' CSV HEADER;
                \""
    eval "$PGCOMMAND"
    cat $midfile | sed -e "s/\"//g" > $dstfile
done

Mysql용 스크립트
#!/bin/bash
database=database_name
for name in `mysql -u root -ppassword $database -B -e "show tables"`;
do
   mysql -B --vertical -u root -ppassword $database -e "select count(*) as $name from $name" | grep -v '^\*' | replace ": " "|"
done

입력데이터 확인

일단 테이블에 모든 값이 들어갔다는 것은 확인했다. 이제 값이 제대로 들어갔는지를 확인할 차례다. Postgresql, Mysql 모두 데이터를 csv로 export 한 다음에 diff로 확인하는 방법을 사용하기로 했다.

Postgresql용 스크립트
database=database_name
user=user_name
PGCOMMAND=" psql -U $user -d $database -At -c \"
            SELECT   table_name
            FROM     information_schema.tables
            WHERE    table_type='BASE TABLE'
            AND      table_schema='public'
            \""

TABLENAMES=$(export PGPASSWORD=test; eval "$PGCOMMAND")

for TABLENAME in $TABLENAMES; do
    midfile="/tmp/postgres.$database.$TABLENAME.mid"
    dstfile="/tmp/postgres.$database.$TABLENAME.csv"
    PGCOMMAND=" psql -U $user -d $database -At -c \"
        copy(select * from $TABLENAME order by id) to '$midfile' DELIMITER ',' CSV HEADER;
                \""
    eval "$PGCOMMAND"
    cat $midfile | sed -e "s/\"//g" > $dstfile
done

Mysql용 스크립트
#!/bin/sh

database=database_name
for name in `mysql -u root -ppassword $database -B -e "show tables"`;
do
   midfile="/tmp/mysql.$database.$name.mid"
   dstfile="/tmp/mysql.$database.$name.csv"
   mysql -u root -ppassword $database -e "SELECT * INTO OUTFILE '$midfile'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY ''
LINES TERMINATED BY '\n'
FROM $name;"
    if [ $? -eq 0 ]
    then
        cat $midfile | sed -e "s/[\"']//g" -e "s/\\N//g" -e "s/\\\\//g" > $dstfile
    fi
done
출력형식에 약간의 차이가 있는데, sed로 보정했다. 이제 diff로 csv 파일을 비교하면 된다.

Query LOG 분석

Mysql Log

마이그레이션 후 DB 애플리케이션이 제대로 작동하는지 확인하려면, Mysql log를 확인해야 한다. 두 가지 방법이 있다.

my.cnf를 수정하는 방법
[mysqld]
...
general_log_file        = /var/log/mysql/mysql.log
general_log             = 1
...
tail로 쿼리 내용을 실시간으로 확인할 수 있다.
yundream@yundream:~$ tail -f /var/log/mysql/mysql.log 
                   34 Query     select @@version_comment limit 1
                   34 Query     select count(*) into @discard from `mysql`.`time_zone_transition_type`
                   34 Quit
                   35 Connect   debian-sys-maint@localhost on 
                   35 Query     select @@version_comment limit 1
                   35 Query     select count(*) into @discard from `mysql`.`user`
                   35 Quit
130302  0:57:06    36 Connect   root@localhost on 
                   36 Query     select @@version_comment limit 1
130302  0:57:11    36 Query     create database mydb
130302  0:57:38    36 Query     SELECT DATABASE()
                   36 Init DB   mydb
                   36 Query     show databases
                   36 Query     show tables
130302  0:58:05    36 Query     create table test01 (id int, name varchar(32))
130302  0:58:13    36 Query     insert into test01 (1, 'test')
130302  0:58:23    36 Quit
이 방법은 편하고 확실하긴 하지만 mysql 서버에 대한 권한을 가지고 있어야 한다는 제약이 있다.

Mysql 서버에 대한 권한을 가지고 있지 않다면, tcpdump를 이용해서 패킷을 분석하는 방법도 있다.
# tcpdump -i eth0 -s 0 -l -w - dst port 3306 -n | strings
tcpdump: listening on vboxnet1, link-type EN10MB (Ethernet), capture size 65535 bytes
show tables
select * from test01
예제에서 사용한 tcpdump 옵션들에 대해서 알아보고 넘어가자.
  • -i : 패킷 덤프할 network interface를 설정한다.
  • -s : tcpdump는 모든 입력된 패킷의 모든 내용을 분석하지는 않는다. 처리하는 패킷의 크기가 커지면 그만큼 많은 cpu 자원이 소모되기 때문이다. 예컨데 ip 정보만을 보고 싶다면 패킷의 처음 68 byte 정도만 분석하면 될테다. -s 를 이용해서 이 길이를 조절할 수 있다. 이 경우 패킷의 유저 데이터 부분을 읽어야 하기 때문에 -s 를 크게 할 필요가 있다. 0을 설정하면 65536으로 잡는다.
  • -l : 표준 출력을 line buffering 한다. fflush라고 보면 된다.
    • -w : 캡춰한 패킷을 분석하지 않고 그대로 출력한다 "-"면 표준출력이다.

    Postgresql LOG

    무중단 마이그레이션

    마이그레이션을 하는 가장 간단한 방법은 다음과 같다.
    1. 서비스를 내린다.
    2. 마이그레이션을 한다.
    3. 서비스를 올린다.
    간단하고 안전하기는 한데, 마이그레이션 시간이 길어질 수 있다는게 문제다. 짧게는 몇시간 길게는 하루를 꼬박 넘길 수 있는데, 그 시간 동안 서비스 중단 공지사항을 보여주는 건 좀 문제다.

    가능하면 서비스를 중지하지 않고 마이그레이션을 하면 좋겠으니, 방법을 생각해 보자. 내가 생각한 방법은 다음과 같다.
    1. 서비스를 내린다.
    2. 데이터베이스를 덤프 받는다.
    3. DML query를 남기도록 dbms 설정을 변경한다.
    4. 서비스를 올린다. 이제 서비스 중에 발생한 query 정보는 로그에 저장된다.
    5. 뒷단에서 열심히 데이터베이스를 마이그레이션 한다.
    6. 마이그레이션이 다 끝낫다면,
    7. 서비스를 내린다.
    8. 그동안 쌓인 DML 정보를 토대로 운영중 변경된 데이터베이스 내용을 마저 적용한다.
    9. 서비스를 올린다.
    무중단이라고 할 수는 없지만, 서비스에 영향을 최소화 하면서 안정적으로 마이그레이션 할 수 있다.

    말 그대로의 무중단 마이그레이션을 계획할 수 있겠는데, 지금 처럼 다른 dbms로의 마이그레이션에서 무중단을 고려하는 것은 좀 너무 오바스럽지 싶다.

    마이그레이션 성능이슈

    update

    무중단 마이그레이션을 위해서 DML로그를 이용하기로 했다. 실행하는건 문제될게 없는데 DML 로그가 많을 경우 실행시간이 문제가 될 수 있다. Update 성능을 높여야 겠다.

    Restore가 목적이니 bin log를 남길 필요는 없겠다.
    SET SQL_LOG_BIN=0; 

    Update하기 전에 key 필드에 대한 색인 작업은 걸어둬야 겠지 ?

    참고

    히스토리

    • 작성일 :
    • 수정
      • : 무중단 마이그레이션