카테고리 보관물: OS/시스템

OS, 서버, 시스템

MySQL 원격 증분 백업 – Percona XtraBackup

# Percona XtraBackup 소개

이미 예전에 XtraBackup을 간단하게 소개한 글을 썼었는데 그 글의 내용만으로는 XtraBackup을 실무에 쓰기에 턱없이 부족하다. 그래서 이번에는 XtraBackup을 제대로 쓸 수 있는 문서를 만들었다.

일반적으로 MySQL 백업으로 mysqldump를 사용하는데 매번 전체를 백업하는 방식이므로 데이터가 커질수록 백업에 걸리는 시간이 길어지고 부담이 커진다. 뿐만 아니라 백업된 데이터를 복구하는데도 무척 긴 시간을 필요로 한다. 하지만 XtraBackup을 사용하면 마지막 백업으로부터 변경된 사항만 이어서 백업하는 증분 백업이 가능하다.

XtraBackup은 MySQL의 데이터 디렉토리 자체를 복사하는 것과 같기에 복구에 걸리는 시간은 단지 파일을 복사하는데 걸리는 시간과 같으며 InnoDB 엔진을 적용한 테이블의 경우 MySQL이 실행중인 상태에서도 테이블 락을 걸지 않고 백업이 가능하다. MyISAM 엔진을 사용한 테이블은 락이 걸리므로 주의하자.(락을 걸지 않도록 하는 옵션이 있지만 모험을 하고 싶지는 않다.)

 

# 학습 순서

이 문서에서는 XtraBackup으로 MySQL 백업을 아래와 같은 단계로 학습하겠다.

  1. 로컬 전체 백업 및 복구
  2. 로컬 증분 백업 및 복구
  3. 원격 증분 백업 및 복구

단계가 올라갈수록 복잡도가 높아지며 이전 단계의 이해를 요구하므로 한단계씩 차근차근 진행하자.

 

# 설치

XtraBackup의 설치는 어렵지 않다. 패키지로 설치가 가능하며 우분투에서는 apt-get으로 설치하면 된다.

레드햇 계열은 yum으로 설치하면 된다. 요즘 배포판이라면 기본 저장소에 XtraBackup이 포함되어 있지만 그렇지 않다면 Percona에서 제공하는 XtraBackup 설치 가이드를 참고하자.

 

# 전체 백업

전체 백업은 무척 간단하다. innobackupex라는 명령을 사용하는데 xtrabackup을 좀 더 쓰기 쉽게 펄 스크립트로 구현해 놓은 것이다.

위와 같이 백업할 경우 ‘/전체백업/날짜’로 저장된다.
백업디렉토리를 명시적으로 지정하고 싶다면 –no-timestamp 옵션을 추가한다.

 

# 복원 준비

복원하기 위해서는 백업이 진행되는 동안 생성된 MySQL의 로그를 적용시켜야 한다.
로그 적용은 –apply-log 옵션을 사용하면 된다.

 

# 복원

복원 준비까지 마쳤다면 –copy-back 옵션으로 복원 할 수 있다.
복원은 백업 디렉토리를 MySQL 데이터 디렉토리에 복사하는 것과 동일하다.
때문에 MySQL의 동작을 중지시켜야 하며 데이터 디렉토리는 비어 있어야 한다.
우분투에서 MySQL의 기본 데이터 디렉토리는 /var/lib/mysql 이다.

마지막으로 MySQL 데이터 디렉토리의 소유자와 그룹을 재설정하고 MySQL을 다시 시작한다.

 

# 증분 백업

최초 증분 백업을 하기 위해서는 전체 백업을 해놓은 디렉토리가 준비되어 있어야 한다.
증분 백업이란 마지막 백업 이후로 변경된 사항만 이어서 백업하는 것이므로 기본적으로 전체 백업이 필요하다.

증분 백업은 –incremental 옵션으로 할 수 있다.
여기서 중요한건 어느 시점부터 백업을 시작할지 LSN(log sequence number)을 전달해야 한다.
LSN 전달 방법은 아래와 같은 방법이 있다.

  1. LSN(log sequence number) 값을 직접 명시하는 방법
    –incremental-lsn=LSN
  2. xtrabackup_checkpoints 파일이 있는 디렉토리를 지정하는 방법
    –incremental-basedir=DIR

두 방법 모두 백업 디렉토리 하위의 xtrabackup_checkpoints 파일의 to_lsn 값을 이용하는 것이다.

로컬 백업에는 2번 방법으로도 충분한데 원격 백업을 위해서는 1번 방법을 응용하는 것이 좋다.
이 문서에서는 1번 방법으로 계속 설명하겠다.

이후 진행을 편하게 하기 위해서 xtrabackup_checkpoints 파일에서 to_lsn 값을 가져오는 간단한 명령을 사용하자.

증분 백업도 전체 백업과 마찬가지로 –no-timestamp 옵션을 추가해서 백업 디렉토리를 명시적으로 지정할 수 있다.

그럼 위에서 설명한  –incremental, –incremental-lsn 옵션과 LSN 값을 가져오는 명령을 이용해서 증분 백업 명령을 내려보자.

LSN 값만 제대로 전달되면 증분 백업도 어렵지 않다.
이어서 새로운 증분 백업을 하려면 최근 백업한 디렉토리 하위의 xtrabackup_checkpoints 파일에서 to_lsn 값을 가져와서 처음 과정을 반복하면 된다.

이렇듯 증분백업은 전체 백업에 자동으로 합쳐지는 것이 아니라 별도의 디렉토리에 생성이 되며 복원을 위해서는 전체 백업에 합쳐야 한다.

전체 백업 + 증분 백업 1 + 증분 백업 2 + …

 

# 전체 백업에 증분 백업을 합치기

전체 백업에 증분 백업을 합치려면 일단 전체 백업 디렉토리에 –apply-log –redo-only 옵션을 적용한다.
그리고 증분 백업 디렉토리를 순서대로 –apply-log –redo-only 옵션과 함께 전체 백업에 적용한다.

전체 백업 디렉토리와 마지막 증분 백업 디렉토리 각각 하위의 xtrabackup_checkpoints 파일을 열어보면 to_lsn 값이 동일하다는 것을 확인 할 수 있다.

증분 백업을 전체 백업에 합치고 나면 증분 백업 디렉토리는 삭제해도 된다.

 

# 증분 백업 복원

전체 백업에 증분 백업을 모두 합쳤다면 이후 복원은 일반적인 전체 백업 복원과 동일하다.

 

# 증분 백업 팁

매번 증분 백업을 할때마다 디렉토리가 늘어나고 나중에 한번에 합치기가 불편하다면 증분 백업을 하자마자 바로 전체 백업에 합치면 된다.

위의 명령 이후 전체 백업을 제외한 3 ~ 6번 라인의 과정을 반복하면 한개의 디렉토리에 백업을 이어갈 수 있다.

 

# 원격 전체 백업

원격 백업이라고 하지만 원격 MySQL에 접속하여 백업하는 것은 불가능하고 로컬에서 백업한 것을 원격으로 전송하는 방식을 쓴다. 백업을 전달받을 원격 호스트는 –remote-host 옵션으로 지정한다.
원격 전송에는 scp가 사용되는데 –scpopt 옵션으로 scp 관련 옵션을 부여할 수 있고 기본 옵션은 ‘-Cp -c arcfour’ 이다.
–remote-host 옵션과 –scpopt 옵션을 제외하면 일반적인 전체 백업과 같다.

 

# 원격 증분 백업

증분 백업은 백업 데이터를 스트림으로 내보낼 수 있으며 –stream=xbstream 옵션을 사용하면 된다.
스트림으로 출력되는 데이터는 파이프를 통해 ssh 명령으로 원격 서버에 전송할 수 있으며 원격 서버에서는 xbstream 을 이용하여 전송된 데이터를 풀어 놓으면 된다. 때문에 원격 서버에도 XtraBackup이 설치되어 있어야 한다.

증분 백업 스트림 데이터를 ssh로 원격 서버에 전송하고 원격 서버에서는 xbstream으로 전송된 데이터를 풀어놓는 명령어은 아래와 같다.

명령이 복잡해 보이지만 차근차근 뜯어보면 어렵지 않다.

위 명령의 앞부분은 일반적인 증분 백업과 다를바 없다. 다만 백업 경로가 /tmp로 되어있는데 임시로 사용되는 경로일뿐 실제 데이터는 바로 스트림으로 전송된다.

명령의 뒷부분은 우리가 원하는 동작 순서 그대로 나열했을 뿐이다.

 

# 원격 증분 백업 스크립트

간단한 명령으로 자동화된 원격 백업을 할 수 있으면 좋겠지만 아쉽게도 그렇지 않다. XtraBackup의 다양한 명령을 조합하여 원격 백업을 구현해야 한다. 그러기 위해서는 서버의 ssh 설정과 권한 설정 등 추가적인 서버 운영 지식이 필요하다.

아래는 백업 서버에서 DB 서버로부터 MySQL의 데이터를 백업하는 스크립트 예제다. 각 코드에 대한 설명은 하지 않겠다. 서버별로 환경이 다양하므로 가져다 쓰기만 하면 되는 스크립트를 만들 수는 없다.

스크립트가 복잡해 보인다고 걱정하지 말자. 지금까지 설명한 XtraBackup의 사용법을 이해하고 있다면 아래 스크립트는 별 것 아닌 단순한 명령을 순서대로 나열한 것일 뿐이다.

완성된 스크립트를 cron에 등록하여 주기적으로 백업이 되도록 하면 된다.

내가 생각하기에 XtraBackup이 가장 가볍고 빠르게 동작할 수 있는 환경은 MySQL의 모든 테이블이 InnoDB 엔진을 사용하며 innodb_file_per_table 옵션이 활성화되어 있을 때인 것 같다.

이제는 실무에서 MySQL을 백업하는 도구로 mysqldump를 대신 XtraBackup을 사용하자. 물론 mysqldump가 필요한 경우도 있다. 하지만 분명한 건 전체를 백업하는 용도로는 mysqldump는 불편하다.

HA-LVS 구축하기 – Ubuntu 14.04 + Ipvsadm + Heartbeat

이 글에서는 우분투 14.04에서 Ipvsadm으로 LVS(Linux Virtual Server)를 구축하여 웹 서버 로드밸런싱을 구현하고 Heartbeat로 고가용성(HA, High Availability)을 유지하는 방법을 소개한다. LVS 구축 완료 후 HA를 적용할 것이므로 HA를 제외한 LVS만 구축하고 싶은 사람까지 고려되었다.

이 예제에서 사용되는 서버와 사용되는 IP는 아래와 같다.

[서버 종류: Hostname, IP]

  • LVS 서버 1: lvs1, 192.168.56.3
  • LVS 서버 2: lvs2, 192.168.56.4
  • (LVS 가상 IP: 192.168.56.10)
  • 웹 서버 1: web1, 192.168.56.11
  • 웹 서버 2: web2, 192.168.56.12

HA를 적용하지 않는다면 lvs2는 무시한다.

web1, web2 서버에는 Aapache, Nginx 같은 웹 서버 프로그램이 설치되어 있다.

LVS 서버(192.168.56.10)에 접속하면 web1(192.168.56.11), web2(192.168.56.12) 서버중 하나에 연결이 되도록 할 것이다.

LVS로 로드밸런싱 환경 구축하기

lvs1, lvs2 서버에 LVS 구축

-s 옵션은 스케쥴링 방식으로 4개의 방식이 있다.

  • rr: 라운드로빈
  • wrr: 가중치 라운드로빈
  • lc: 최소연결
  • wlc: 가중치 최소연결

-g 옵션은 패킷 포워딩 방식으로 다이렉트 라우팅(Direct Routing)을 뜻하며 -i(Tunneling), -m(NAT) 를 사용할 수도 있다. 하지만 각 상황에 따라 web1, web2에 요구되는 네트워크 설정이 달라지므로 이 예제에서는 -g(Direct Routing)를 사용한다.

패킷 포워딩 방식별 네트워크 설정 참고 자료: http://yoonperl.tistory.com/18

-w 옵션은 가중치로 서버별로 가중치를 다르게 하고 싶을때 사용하면 된다. 당연히 스케쥴링 방식중 wrr(가중치 라운드로빈), wlc(가중치 최소연결)에서 유효하다.

하지만 위 설정은 재부팅 하면 사라진다. ipvsadm-save 명령으로 출력되는 내용을 /etc/ipvsadm.rules 에 추가해야 한다.

위의 가상 IP 설정은 재부팅 하면 사라진다. /etc/network/interfaces 파일을 직접 수정하면 재부팅을 해도 설정이 유지된다.

 

web1, web2 서버 네트워크 설정

웹 서버도 LVS 서버와 마찬가지로 동일한 가상 IP를 추가해야 한다.

가상 IP를 추가하는 방법은 LVS 서버와 다르지 않다.

ARP(Address Resolution Protocol, 주소 결정 프로토콜) 기능을 끄는 설정을 반드시 추가해야 한다. 외부에서 가상 IP(192.168.56.10)로 접속시 ARP가 캐쉬 되면 로드밸런싱이 되지 않고 캐쉬된 맥주소의 장비로 바로 연결이 되버린다.

LVS 테스트 하기

lvs2 서버는 아직 사용하지 않으므로 전원을 꺼둔다.

외부 장비에서 가상 IP(192.168.56.10)로 웹 페이지(http://192.168.56.10) 접속을 시도한다. web1과 web2의 내용을 다르게 해서 web1과 web2가 번갈아가며 나오는지 확인한다. 단, web1과 web2가 정확하게 한번씩 번갈아가며 나오지는 않으므로 같은 페이지만 여러번 나온다고 해서 섣불리 오류라고 판단하지 말자.

여러번 접속과 시도를 한 후에 lvs1 서버에서 아래와 같이 상태를 확인하자.

CPS, InPPS 등의 숫자가 계속 오르고 내리며 변화하면 LVS 설정은 정상이다. 만약 숫자는 변하는데 웹 페이지가 뜨지 않는다면 웹 서버의 네트워크 설정을 다시 한번 확인해보자.

숫자가 변하지 않고 한쪽 웹서버의 웹 페이지만 뜬다면 LVS 설정이 잘못되었거나 외부 접속 테스트를 하는 컴퓨터의 ARP가 캐쉬되었을 수 있다. 만약 ARP 캐쉬가 되어버린 것 같다면 아래의 명령어로 캐쉬를 지울 수 있다.

여기까지 LVS를 이용한 로드밸런싱 환경 구축이 완료되었다.

 

Heartbeat로 LVS 서버에 고가용성(HA, High Availability) 유지하기

이제 lvs1 서버에 장애가 생기더라도 lvs2가 이어서 동작하는 고가용성을 적용해보자. lvs2는 lvs1과 LVS가 동일하게 구축되어 있어야 한다.

lvs1, lvs2 서버에 Heartbeat 설치하기

설치가 되었으면 /etc/ha.d/ 디렉토리 아래에 설정파일을 추가해야 한다. /usr/share/doc/heartbeat/ 디렉토리에 기본 설정파일이 준비되어 있다.

authkeys 파일의 권한은 반드시 600 이어야 오류가 발생하지 않는다.

authkeys 파일에서 설정들의 주석을 제거한다.

ha.cf 파일에서 아래 설정들의 주석을 제거한다.

lvs1, lvs2 서로가 IP를 알 수 있도록 hosts 파일에 추가한다.

우리의 목적은 lvs1 서버에 장애가 발생시 lvs2가 LVS 가상 IP를 이어 받아서 동작하게 만드는 것이다. 아래와 같이 haresources 파일을 편집한다.

여기서 한가지 중요한 것이 있는데 위에서 LVS를 구축하느라 추가한 가상 IP(192.168.56.10)를 LVS 서버에서는 제거해야 한다.

위의 LVS 구축 과정중 /etc/network/interfaces 파일에 가상 IP를 직접 추가했다면 파일을 열고 제거한다.

이제 설치 및 설정이 끝났다. Heartbeat를 실행해보자.

‘Bad nodename’이라는 오류가 발생하면 lvs1, lvs2 서버의 hostname이 각각 lvs1, lvs2가 맞는지 확인한다.

만약 hostname이 잘못되어서 변경해야 한다면 아래의 링크를 참고하여 hostname을 바꾼다.

http://www.subvs.co.uk/ubuntu_change_hostname_computer_name

Heartbeat 동작여부 확인하기

lvs1, lvs2 서버 각각 ifconfig를 입력한다. lvs1에는 eth0:0 장치가 있지만 lvs2에는 없다.

이때 lvs1을 종료시킨 후 lvs2에서 ifconfig를 입력하면 lvs2에 eth0:0이 생성되어 있을 것이다.

과정이 무척 길고 어려워 보이지만 네트워크 설정과 hostname만 실수하지 않으면 어렵지 않게 구축할 수 있을 것이다.

리눅스 명령어로 최근 파일만 남기고 지우기

서버를 관리하다 보면 주기적으로 로그를 남기거나 백업 등을 하게 되는데 시간이 지날수록 관련 파일이 쌓이게 된다. 보통 이럴때 find 명령으로 오래된 날짜의 파일을 찾아서 지우는 방법이 있다. 하지만 이 방법은 날짜를 기준으로 하다보니 예상치 못한 이유로 새로운 파일이 생성되지 않으면 결국에는 모든 파일이 지워진다. 우리는 언제나 일정한 개수의 최신 파일이 유지되기를 바란다.

그래서 원하는 개수만큼의 최근 파일만 남기는 간단한 리눅스 명령어 예제를 만들어봤다.

위 예제에 대한 설명은 아래와 같다.

3개의 파일을 1초 간격으로 만든다.

ls 명령으로 파일 목록을 시간 내림차순으로 출력한다.

tail 명령으로 파일 목록의 3번째 라인부터 출력한다.

출력되는 3번째부터 파일부터 rm 명령으로 삭제하면 최근 날짜의 파일 2개만 남는다.

이렇듯 단순히 명령을 조합하여 필요한 기능을 만들 수 있다는 것이 리눅스의 강점이다.