XtraBackup을 이용한 InnoDB 증분백업과 복구하기 ( 4 ) 원격백업



원격백업

XtraBackup을 이용한 InnoDB 증분백업과 복구하기 ( 3 ) 증분백업




Incremental Backup (증분백업)


증분백업이란 바로 이전에 백업했던(그게 풀백업이었던, 증분백업이었던지 간에..)시점부터 현재까지 변경된


내역만 백업하는 방식이다. 설명만으로만 본다면 증분백업은 정말 금방 끝날것같지만 그렇지는 않다.


증분백업도 풀백업과 동일하게 데이터파일을 모두 읽어야 하기 때문이다. 물론 직전 백업의 lsn보다 큰 번호에 


해당하는 것들만 백업하기때문에 풀백업보다는 확실히 시간이 줄고 용량도 적다.




백업 방식


서비스특성이나 관리자 성향에 따라 다 다르겠지만 보통 아래와 같은 방식을 쓴다.


1. 매일매일 풀백업을 한다.

 - 장점 : 속편하다. 설정이 편하다. 복구가 가장 빠르다.

 - 단점 : 새벽에 시작해서 아침에 끝날까? 용량을 너무 먹는다. 1T 데이터를 1주일 저장하면 7T다.

  

2. 풀백업을 한번하고 죽을때까지 증분백업만 한다.

 - 장점 : 용량을 가장 적게 먹는다. 처음 풀백업 외엔 백업시간이 가장 짧다.

 - 단점 : 복구시 오래걸린다. 

 

3. 1주를 단위로 사용량이 가장적은 요일 새벽에 풀백업을 하고 그외 요일은 증분백업을 한다.

 - 장점 : 적은 용량으로 1주일 데이터를 저장할수 있다. 풀백업외에는 백업부하가 적다.

 - 단점 : 설정이 복잡해지고 관리가 귀찮다.

 

SystemV는 일반적인 3번방식을 설명하고자 한다. 사실 가장 장점없고 단점없는 그저그런 방식이랄까...;





LSN 


Log Sequence Number 의 약자로 MySQL 로그파일내에 해당 로그 레코드의 번호값이다. 번호? 순서? 위치? 주소? 암튼..


보통 시점복구나 증분백업등의 관리용으로 사용된다. 1트랜잭션 = 1LSN 은 아니다. 


여러개의 LSN들이 하나의 트랜잭션에 포함되는 구성이 되겠다.





증분백업


증분백업을 위해서는 반드시 이전백업데이터가 있어야 하므로 무조건 풀백업이 한번은 있어야 한다. 


주단위 백업을 설명하기로 했으므로 일요일에 풀백업을하고 그외는 증분백업을 한다고 가정하자.



[일요일] 풀백업


innobackupex --user root --password mysqlrootpw /Backup


풀백업 디렉토리에 xtrabackup_checkpoints 를 보면 풀백업에 대한 lsn 정보가 있다.


[root@localhost 2016-07-28_20-19-45]# cat xtrabackup_checkpoints 

backup_type = full-backuped

from_lsn = 0

to_lsn = 1951426944668

last_lsn = 1951426944668

compact = 0

recover_binlog_info = 0

 

이 풀백업은 0번(from_lsn)부터 1951426944668번(to_lsn)까지 백업된 데이터다.


풀백업이므로 당연히 from_lsn 은 0 이고 to_lsn 은 다음 증분백업의 from_lsn 이 될 것이다.



증분백업은 풀백업 실행문에 --incremental 를 추가해서 이 실행문이 '증분백업이다' 라고 선언해주고


incremental-lsn 에 이전백업(여기서는 풀백업)의 to_lsn 의 값을 할당해주면 된다.



[월요일] 1차증분백업 (풀백업에 대한 증분)

innobackupex --user root --password mysqlrootpw --incremental --incremental-lsn=1951426944668 /Backup



2차 증분백업은 1차증분백업에 대한 증분백업을 해야하므로 1차증분백업 디렉토리에 있는 xtrabackup_checkpoints 의 to_lsn을 이용한다.


[화요일] 2차증분백업 (1차증분백업에 대한 증분)

innobackupex --user root --password mysqlrootpw --incremental --incremental-lsn=2951426944668 /Backup



3차 역시 2차증분백업의 to_lsn을 이용한다.


[수요일] 3차증분백업 (2차증분백업에 대한 증분)

innobackupex --user root --password mysqlrootpw --incremental --incremental-lsn=3951426944668 /Backup

.

..

...

....


이렇게 토요일까지 진행하고 나서 일요일에는 동일한 방식으로 풀백업부터 다시 시작하면 된다.





to_lsn 찾기


grep to_lsn /이전백업의절대경로/xtrabackup_checkpoints | awk '{print $3}'



이게 번거로울 경우 직전백업의 디렉토리경로를 지정해주는 방법도 있다.


--incremental-lsn 옵션 대신에 --incremental-basedir 에 이전백업 디렉토리를 할당해 주면 된다.


innobackupex --user root --password mysqlrootpw --incremental --incremental-basedir=/이전백업의절대경로/ /Backup





증분백업 복구


증분백업의 복구도 풀백업과 동일하게 apply-log 로 로그반영 작업을 해주고 copy-back 으로 실제복구를 하게 된다.


다만 다른점이 있다면 apply-log 로 로그반영시에 --redo-only 옵션을 꼭 같이 써줘야 한다는거다. 



redo-only 


로그반영작업은 백업된 리두로그를 재실행 하면서 백업중에 발생된 트랜잭션에 대한 일관성을 맞추게 되는데 재실행을 마치고 


나서도 커밋되지 않은 트랜잭션이 존재한다면 그런 트랜잭션들은 모두 롤백시켜버린다. 



예를들어 1차 증분백업과 2차 증분백업 두개의 백업에 걸쳐진 트랜잭션은 1차증분백업 로그반영을 하면서 커밋이 안되어


롤백되버렸기 때문에 2차증분백업의 로그를 반영해봐야 해당 데이터는 날릴수 밖에 없다.



"커밋되지 않은 트랜잭션이 남아 있더라도 이후 증분백업의 로그반영 작업을 하면서 해당 트랜잭션이 커밋될 수 있으므로 


롤백작업은 하지마라" 라는 의미로 redo-only 옵션을 써주는 것이다. 



물론 가장 마지막 증분백업의 로그반영시에는 redo-only를 쓸 필요가 없다. 


이후의 백업이 없으므로 어차피 커밋될 여지가 없기 때문이다.




복구상황 가정


위 과정처럼 백업이 매일 새벽에 처리되고 있었으며 오늘이 만약 수요일 업무중인데 데이터가 망실됐다고 가정해보자.


가장 최근 백업데이터는 오늘 새벽 증분백업이다. 이번주 새벽에 풀백업이 있었으므로 일요일(풀백업), 월요일(증분), 화요일(증분), 수요일(증분)을 모두 합치면 오늘 새벽까지의 데이터를 모두 살릴수 있다.


apply-log 로 증분백업을 풀백업에 합쳐주고 copy-back으로 복구시켜보자.

 


apply-log 작업은 풀백업부터 시작해 오래된 데이터부터 진행한다.



1. 일요일 풀백업 로그반영 

innobackupex --apply-log --redo-only /Backup/풀백업디렉토리

이 다음에 증분백업 로그반영이 있으므로 반드시 --redo-only 를 써줘야 한다.



2. 월요일 증분 로그반영

innobackupex --apply-log --redo-only /Backup/풀백업디렉토리 --incremental-dir=/Backup/월요일증분백업디렉토리



3. 화요일 증분 로그반영

innobackupex --apply-log --redo-only /Backup/풀백업디렉토리 --incremental-dir=/Backup/화요일증분백업디렉토리



4. 수요일 증분 로그반영

innobackupex --apply-log /Backup/풀백업디렉토리 --incremental-dir=/Backup/수요일증분백업디렉토리

증분백업의 마지막 로그반영이므로 redo-only는 필요없다.



5. 마지막으로 일요일 풀백업 로그반영 한번더

innobackupex --apply-log /Backup/풀백업디렉토리



6. apply-log 작업으로 모든 증분데이터들이 풀백업에 병합되었으므로 풀백업으로 복구를 하면 된다.


innobackupex --copy-back /Backup/풀백업디렉토리



copy-back 이 끝나고 data_dir 의 소유권과 퍼미션을 맞춰주면 모든 복구작업이 완료된다.







XtraBackup을 이용한 InnoDB 증분백업과 복구하기 ( 2 ) 풀백업




Full Backup


기본 풀백업은 아래처럼 간단하게 할 수 있다.


[root@localhost ~]# innobackupex --user root --password mysqlrootpw /Backup

160609 16:46:54 innobackupex: Starting the backup operation


IMPORTANT: Please check that the backup run completes successfully.

           At the end of a successful backup run innobackupex

           prints "completed OK!".


160609 16:46:54  version_check Connecting to MySQL server with DSN 'dbi:mysql:;mysql_read_default_group=xtrabackup;port=3306;mysql_socket=/tmp/mysql.sock' as 'root'  (using password: YES).

160609 16:46:54  version_check Connected to MySQL server

160609 16:46:54  version_check Executing a version check against the server...

160609 16:46:54  version_check Done.

..

..

..

160609 16:47:41 [00] Writing backup-my.cnf

160609 16:47:41 [00]        ...done

160609 16:47:41 [00] Writing xtrabackup_info

160609 16:47:41 [00]        ...done

xtrabackup: Transaction log of lsn (1667732673) to (1667732673) was copied.

160609 16:47:41 completed OK!

[root@localhost ~]# 


가장 밑줄에 있는 completed OK! 가 떨어지면 백업이 정상 종료된거다.



내부적인 실행순서는 아래와 같다.


1. ibdata1 (시스템 테이블스페이스) 카피


2. InnoDB  파일 카피 (.ibd)


3. FLUSH NO_WRITE_TO_BINLOG TABLES 실행


4. FLUSH TABLES WITH READ LOCK 실행


5. non-InnoDB  파일카피 (.MYI, .MYD, .FRM)


6. UNLOCK TABLES 실행


7. backup-my.cnf 생성


8. xtrabackup_info 생성


9. 종료



/Backup 디렉토리 안에 현재 날짜/시간으로 디렉토리가 만들어지고 그 안에 아래와 같이 백업이 된다.


[root@localhost 2016-06-09_16-46-54]# ll

합계 1024060

-rw-r----- 1 root root        421 2016-06-09 16:47 backup-my.cnf

-rw-r----- 1 root root 1048576000 2016-06-09 16:47 ibdata1

drwxr-x--- 2 root root       4096 2016-06-09 16:47 mysql

drwxr-x--- 2 root root       4096 2016-06-09 16:47 performance_schema

-rw-r----- 1 root root        119 2016-06-09 16:47 xtrabackup_checkpoints

-rw-r----- 1 root root        435 2016-06-09 16:47 xtrabackup_info

-rw-r----- 1 root root       2560 2016-06-09 16:47 xtrabackup_logfile


backup-my.cnf : 백업&복구에 필요한 몇가지 옵션이 저장되어 있다. my.cnf자체를 백업한게 아니다.


xtrabackup_checkpoints : 아래와 같은 내용을 담고 있다. 백업타입과 lsn 정보등. 


backup_type = full-backuped

from_lsn = 0

to_lsn = 1667732673

last_lsn = 1667732673

compact = 0

recover_binlog_info = 0


xtrabackup_info : 백업 실행시의 각종 상태(백업시간,사용한 옵션,버전정보등등..)를 저장.




백업시 추가적으로 사용 할 수 있는 옵션들


--host : 원격 백업일때 디비서버 아이피를 적어주면 된다. 안쓰면 기본이 localhost


--port : 안쓰면 기본이 3306


--defaults-file : 안쓰면 기본이 /etc/my.cnf 


--backup : 안쓰면 기본이 --backup, --apply-log 나 --copy-back 등을 쓸수 있음.


--no-timestamp : 날짜/시간으로 된 디렉토리를 생성하지 않는다. 지정한 경로에 바로 백업파일을 생성한다.



그리고 성능 개선을 위해...


--parallel : .ibd 데이터 파일 복사시 병렬로 처리한다. --parallel=4

InnoDB가 아니거나 innodb_file_per_table 을 사용하지 않을때는 당연히 성능향상은 없다.

병렬처리 옵션을 줘도 MyISAM 이나 InnoDB의 .frm 파일은 병렬처리가 안된다.


--compress_threads : 압축백업시 압축수행하는 쓰레드 수 지정.





로그반영


이전글에서 설명했듯 백업만 완료된 데이터는 inconsistent 하기 때문에 이 데이터로는 복구를 할 수 없다.


그렇기 때문에 꼭 백업된 리두로그를 백업된 데이터파일에 반영해줘야한다.


로그반영은 아래처럼 --apply-log 옵션과 함께 백업된 디렉토리를 지정해주면 된다.


[root@localhost ~]# innobackupex --apply-log /Backup/2016-06-09_16-46-54

160609 21:06:30 innobackupex: Starting the apply-log operation


IMPORTANT: Please check that the apply-log run completes successfully.

           At the end of a successful apply-log run innobackupex

           prints "completed OK!".


innobackupex version 2.4.3 based on MySQL server 5.7.11 Linux (x86_64) (revision id: 6a46905)

xtrabackup: cd to /Backup/2016-06-09_16-46-54

xtrabackup: This target seems to be not prepared yet.

InnoDB: Number of pools: 1

xtrabackup: xtrabackup_logfile detected: size=8388608, start_lsn=(1667732763)

xtrabackup: using the following InnoDB configuration for recovery:

..

..

..

..

InnoDB: 96 redo rollback segment(s) found. 1 redo rollback segment(s) are active.

InnoDB: 32 non-redo rollback segment(s) are active.

InnoDB: page_cleaner: 1000ms intended loop took 5030ms. The settings might not be optimal. (flushed=0 and evicted=0, during the time.)

InnoDB: 5.7.11 started; log sequence number 1667736597

xtrabackup: starting shutdown with innodb_fast_shutdown = 1

InnoDB: FTS optimize thread exiting.

InnoDB: Starting shutdown...

InnoDB: Shutdown completed; log sequence number 1667738299

160609 21:06:39 completed OK!

[root@localhost ~]# 


백업때와 마찬가지로 가장 밑줄에 있는 completed OK! 가 떨어지면 로그반영로이 정상 종료된거다.



[root@localhost 2016-06-09_16-46-54]# ll

합계 1568824

-rw-r----- 1 root root        421 2016-06-09 20:27 backup-my.cnf

-rw-r----- 1 root root  134217728 2016-06-09 21:06 ib_logfile0

-rw-r----- 1 root root  134217728 2016-06-09 21:06 ib_logfile1

-rw-r----- 1 root root  134217728 2016-06-09 21:06 ib_logfile2

-rw-r----- 1 root root  134217728 2016-06-09 21:06 ib_logfile3

-rw-r----- 1 root root 1048576000 2016-06-09 21:06 ibdata1

-rw-r----- 1 root root   12582912 2016-06-09 21:06 ibtmp1

drwxr-x--- 2 root root       4096 2016-06-09 20:27 mysql

drwxr-x--- 2 root root       4096 2016-06-09 20:27 performance_schema

-rw-r----- 1 root root        119 2016-06-09 21:06 xtrabackup_checkpoints

-rw-r----- 1 root root        435 2016-06-09 20:27 xtrabackup_info

-rw-r----- 1 root root    8388608 2016-06-09 21:06 xtrabackup_logfile


이제 이 파일들은 완전히 consistent 한 데이터가 되었고 이 데이터들로 복구를 할 수 있게 되었다.



로그반영시 추가할수 있는 옵션


로그반영 작업을 좀 더 빠르게 하기위해 --use-memory 옵션을 사용할 수 있다.


지정하지 않으면 기본값이 100M 로 셋팅되는데 로그반영은 보통 복구 직전에 진행하기에 디비도 내려간 상태이므로


메모리 여유량이 충분할 것이다. 넉넉히 셋팅해주자. 


[root@localhost ~]# innobackup --apply-log --use-memory=4G /Backup/2016-06-09_16-46-54





복구


로그반영까지 완료된 상태에서 복구는 아주 간단하다. 실행옵션 3가지중 --copy-back 을 써주면 된다. 



다시 한번 알아보는 실행옵션 3가지


--backup      : 백업할때 사용. 생략가능

--apply-log  : 로그반영시 사용

--copy-back : 복구시 사용



복구시 주의사항


- 복구전에 datadir 디렉토리는 비어있어야 한다. --copy-back 은 기존파일을 덮어쓰지 못한다. 

  datadir 이 비어있지 않을때는 -force-non-empty-directories 옵션을 이용할 순 있지만 기존 파일을 덮어쓰는 무모한 도전은

  의미가 없다. mv 를 이용해 기존 datadir 이름을 바꾸고 mkdir 로 새로 생성해주자.


- partial backup을 임포팅하는 작업이 아니라면 반드시 디비는 내려간 상태여야 한다.


- 사실 로그반영이 완료된 데이터는 이미 consistent 하므로 --copy-back 을 이용하지 않고 백업디렉토리를 그대로 datadir 로 옮겨도 무방하다. 하지만 운영에 필요없는 파일들도 같이 들어가므로 특별한 이유가 아니라면 정석대로 --copy-back을 사용하도록 하자.



[root@localhost ~]# innobackupex --copy-back /Backup/2016-06-09_16-46-54



역시 위 작업들과 동일하게 innobackupex: completed OK! 가 떨어지면 정상종료 된것이다.



내부적인 복구 과정은 아래와 같다.


1. 데이터파일(.ibd)과 메타데이터(.frm) 카피


2. 시스템테이블 스페이스(iddata1) 카피


3. 언두테이블 스페이스 (따로 있지 않다면 생략)


4. 리두로그(ib_logfile0..) 카피



복구된 데이터의 퍼미션을 확인해보고 mysql 권한이 아니라면 반드시 수정하고 디비를 올려보자.


[root@localhost ~]# chown mysql. /app/mariadb/data -R


[root@localhost ~]# /app/mariadb/bin/mysqld_safe &

[1] 25206

[root@localhost ~]# 160610 17:21:07 mysqld_safe Logging to '/app/mariadb/data/error-log.err'.

/app/mariadb/data/mariaDB.pid

160620 17:21:07 mysqld_safe Starting mysqld daemon with databases from /app/mariadb/data


[root@localhost ~]# 



이상없이 데몬이 잘올라온것을 확인할 수 있다. 예상 못했던 문제가 있을수 있으므로 errorlog 를 꼭 확인하도록 한다.




풀백업정리



풀백업 


$ innobackupex /data/backups


/data/backups에 오늘날짜 디렉토리에 백업파일 생성



$ innobackupex --no-timestamp /data/backups


/data/backups에 백업파일 생성




로그반영


$ innobackupex --use-memory=4G --apply-log /data/backups/2016-03-01_01-00-00


메모리 4기가 할당해 /data/backups/2016-03-01_01-00-00 백업디렉토리에 대한 로그반영




복구


$ innobackupex --copy-back /data/backups/2016-03-01_01-00-00


백업데이터 /data/backups/2016-03-01_01-00-00 를 datadir 로 복구. datadir 경로는 당연히 my.cnf 참조


XtraBackup을 이용한 InnoDB 증분백업과 복구하기 ( 1 ) 설치




XtraBackup


XtraBackup은 percona사에서 만든 무료 백업 솔루션이다. Percona server, MySQL, MariaDB 등을


백업할 수 있으며 흔히 쓰는 mysqldump 와 다르게 무려! 증분백업이 된다.


XtraBackup의 장점은 너무 많다.


pausing 없이 핫백업이 되고, 증분백업이 되고, 로컬이 아닌 다른서버로 압축전송도 가능하고...등등...




XtraBackup 원리


XtraBackup은 InnoDB엔진의 자동복구 기능과 비슷한 원리다. 백업이 실행되면 데이터 파일들을 카피 하기 시작한다. 


우리가 이미 알고 있는 cp 와 크게 다르지 않은데 차이점은 카피가 시작된 이후부터 발생되는 변경사항을 별도의 파일에 


기록한다는 것이다. 이 파일을 백업된 리두로그 라고 한다.


카피작업이 끝나고 백업된 리두로그를 카피한 백업데이터에 반영해 consistent 한 데이터로 만들어주면 백업이 완료된다. 




설치


https://www.percona.com/downloads/XtraBackup/


Percona 홈페이지에서 원하는 OS와 버전을 선택해 바로 다운 받을수 있다.


테스트 서버가 CentOS 6.4 x64라서 percona-xtrabackup-24-2.4.3-1.el6.x86_64.rpm 파일을 받았다.


xtrabackup 설치시 libev 라이브러리가 필요하므로 먼저 설치해준다.


libev는 기본 repo에는 없고 epel에서 찾을수 있다.



[root@localhost ~]# yum install -y libev 


[root@localhost ~]# rpm -ivh percona-xtrabackup-24-2.4.3-1.el6.x86_64.rpm


[root@localhost ~]# rpm -ql percona-xtrabackup-24

/usr/bin/innobackupex

/usr/bin/xbcloud

/usr/bin/xbcloud_osenv

/usr/bin/xbcrypt

/usr/bin/xbstream

/usr/bin/xtrabackup

/usr/share/doc/percona-xtrabackup-24-2.4.3

/usr/share/doc/percona-xtrabackup-24-2.4.3/COPYING

/usr/share/man/man1/innobackupex.1.gz

/usr/share/man/man1/xbcrypt.1.gz

/usr/share/man/man1/xbstream.1.gz

/usr/share/man/man1/xtrabackup.1.gz


설치내역은 굉장히 단촐하다. 백업 및 복구에 있어 핵심파일은 /usr/bin/xtrabackup 이고


실제 작업시에는 innobackupex를 사용한다. 



inoobackupex는 C로 만들어진 xtrabackup를  내부적으로 호출하는 펄스크립트로


스트리밍이라던지 추가 기능들을 더 쉽게 사용할수 있게 해준다.


그런데 2.1 버전은 분명 perl 스크립트였는데 2.4 버전은 바이너리로 바뀌어 있더라...



암튼.. 그래서 이후로 모든 작업은 innobackupex 를 사용할 예정이고 xtrabackup 을 직접 실행하지 않을것이다.




to Top