MySQL 고급

Point-In-Time

Point-in-Time?

  • 의도하지 않은 명령이 실행됐을 때 이를 배제하고 복구
  • 원본을 그대로 복원할 수 있다는 장점이 있다.
  • 바이너리 로그를 유지해야 한다.
  • 어렵다.

mysqlbinlog

mysql의 바이너리 로그를 열람하는 도구

grep

  • 데이터에서 특정 문자를 찾는 도구
  • -i : 옵션, 대소문자 구분 안함
  • -B : 옵션, 검색된 결과를 기준으로 앞에 몇줄을 더 보여줄 것인가를 지정
  • -A : 옵션, 검색된 결과를 기준으로 뒤에 몇줄을 더 보여줄 것인가를 지정
mysqlbinlog mysql-bin.000010 | grep -i -B 8 -A 3 DROP

zmanda binary log parser

mysql-zrm --action parse-binlogs --backup-set=f --source-directory=/var/lib/mysql-zrm/backupSet1/20060912140720

mysql-zrm

  • --bin-logs : 특정 백업 세트 중 특정 로그만을 복원할 경우 사용
  • --stop-position : 복원 시에 지정된 바이너리 로그 제외 좌표 전까지를 복원
  • --start-position : 복원시에 지정된 바이너리 로그  포함 좌표 후의 데이터를 복원
  • --bin-logs 옵션에 복수의 바이너리 로그를 지정한 경우 --stop-position은 첫번째 바이너리 로그의 좌표를 의미하고, --start-position은 마지막 파일의 좌표를 의미한다.
mysql-zrm --action restore --backup-set backup --source-directory /var/lib/mysql-zrm/backup/20060830020843 
  --start-position 4 --stop-position 22
mysql-zrm --action restore --bin-logs "/var/lib/mysql-zrm/backupset1/20060818121532/mysql-bin.[0-9]* /var/lib/mysql-zrm/backupset1/20060819121532/mysql-bin.[0-9]*" --start-position=100

보강 - 동적인 데이터의 경우 PIT는 어떻게 동작하는가?

아래는 기존의 데이터를 기준으로 추가되는 데이터의 값이 변화되는 경우 PIT는 어떻게 동작하는가에 대해서 테스트한 영상이다.

아래는 위의 테스트를 수행하기 위해서 사용된 명령어들의 리스트다. 

SELECT * FROM movie;
truncate movie;

CREATE TABLE `movie` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `sum` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

INSERT INTO `movie` (title,sum) SELECT '전체백업', sum(s.id) from movie as s;
INSERT INTO `movie` (title,sum) SELECT '전체백업', sum(s.id) from movie as s;

전체백업 실행
mysql-zrm-scheduler --now --backup-set common --backup-level 0

INSERT INTO `movie` (title,sum) SELECT '증분백업-삭제전', sum(s.id) from movie as s;
INSERT INTO `movie` (title,sum) SELECT '증분백업-삭제전', sum(s.id) from movie as s;

DELETE FROM movie;

INSERT INTO `movie` (title,sum) SELECT '증분백업-삭제후', sum(s.id) from movie as s;
INSERT INTO `movie` (title,sum) SELECT '증분백업-삭제후', sum(s.id) from movie as s;

증분백업 실행
mysql-zrm-scheduler --now --backup-set common --backup-level 1

백업상황 파악
mysql-zrm-reporter --show restore-info

전체백업 복원
mysql-zrm --action restore --backup-set common --source-directory /var/lib/mysql-zrm/common/20130416124901

bin 로그 테스트
mysqlbinlog mysql-bin.000010 | grep -i -B 8 -A 3 delete

mysql-zrm --action restore --backup-set common --source-directory /var/lib/mysql-zrm/common/20130416125205 --stop-position 732
mysql-zrm --action restore --backup-set common --source-directory /var/lib/mysql-zrm/common/20130416125205 --start-position 813

 

댓글

댓글 본문
  1. koyulka
    아래 내용에 대한 상세한 질문과 답변들은 생활코딩 페이스북에 있습니다.~https://www.facebook.com/group...
  2. egoing
    안녕하세요. 제가 질문을 정확하게 이해하지 못했습니다. 위에서 data 2개 입력이라고 언급하신 부분 아래의 12는 삽입되는 행의 amout값이 12가 되야 한다는 말씀인가요? data 2개 입력은 어떤 데이터를 입력했다는 말씀인지 설명 부탁드립니다.
    그리고 PIT는 전체백업을 한 시점을 복원 한 후에 그 이후의 바이너리로그를 delete from Accout까지 순차적으로 실행한 후에 delete From Account만을 건너뛰고, 나머지 Insert를 실행하는 것인데요. 그렇다면 아래와 같은 결과가 나오지 않을까요?
    3612244896
    피드백 부탁드립니다.
    대화보기
    • koyulka
      늘 잘 보고 있습니다. 궁금한 점이 있습니다. 예제에서의 data는 단순한 data이기 때문에 이런 복원이 가능하지만 만약, data가 php 소스에서 가공되어져서 입력되는 거라면 잘못된 명령을 내리기 전까지만 복원을 하는게 정답일까요? 동영상과 비슷한 예를 들어보겠습니다.
      ----------------------------------예)table: Account, column : amountphp 로직 : Account 테이블의 amount 의 합계를 가져온다음 (합계+3) 한다음 amount에 다시 insert
      Account.column--------------------------36---> 전체백업--->data 2개 입력1224---> data 모두 삭제delete from Account;--->data 2개 입력3 insert into Account values(3);6 insert into Account values(6);
      point-in-time으로 복구시 다음과 같이 복구됨36122436
      정상적으로 데이타가 입력된다면 마지막 두 row가 48, 96 이어야 함. 이럴때 point-in-time 복원으로 정상적인 data가 들어갈 수 있도록 할 수 있는 방법이요? 아니면 delete 명령을 내리기 전까지만 복원을 하고 그 시점에서 서비스를 다시 하는게 최선일까요?
    버전 관리
    egoing
    현재 버전
    선택 버전
    graphittie 자세히 보기