ZFS 스냅 샷을 통한 MySQL 데이터베이스 백업


12

이 작업을 수행하는 것에 대해 이야기하는 여러 사이트를 찾았지만 중요한 세부 정보가 누락되었습니다. 일반적인 단계는

  • 운영 FLUSH TABLES WITH READ LOCK
  • ZFS 스냅 샷 생성
  • 운영 UNLOCK TABLES

다양한 소스에서 내가 사용하는 InnoDB가 실제로을 존중하지 않는다고보고합니다 FLUSH. MySQL 사용자 매뉴얼에는 FLUSH TABLES...FOR EXPORTInnoDB와 함께 사용할 수 있는 변형이 있지만 전체 데이터베이스를 백업하는 대신 각 테이블을 개별적으로 지정해야합니다. 테이블 목록이 실제로 존재하는 테이블과 동기화되지 않을 가능성이 높기 때문에 각 테이블을 개별적으로 지정하지 않는 것이 좋습니다.

내가 가진 다른 문제는 다음과 같은 일을 할 계획 mysql -h"$HOST" -u"$USERNAME" -p"$PASSWORD" --execute="FLUSH TABLES WITH READ LOCK"입니다. 그러나 세션 종료 후 즉시 잠금이 해제됩니다. 이것은 의미가 있지만 스냅 샷을 찍을 때 읽기 잠금을 잡아야하기 때문에 상당히 성가시다.

또 다른 아이디어는 Percona XtraBackup과 같은 도구를 사용하고 백업 스냅 샷을 생성하는 핫 백업을 수행하는 것이지만 스냅 샷을 위해 모든 데이터를 다른 위치에 쓰는 데 드는 비용을 지불하지 않는 것이 좋습니다.


정적 테이블 목록이 필요한 이유는 무엇입니까? 런타임에 반드시 목록을 동적으로 생성 할 수 있습니다.
EEAA

1
데이터베이스가 VM 또는 베어 메탈에 있습니까? 스토리지가 동일한 머신에도 있습니까?
Michael Hampton

EEAA, 충분히 공평합니다.
Andy Shulman

Michael, 데이터베이스 및 ZFS 상자는 서로 다른 시스템이지만 가상화되지는 않습니다.
Andy Shulman

@AndyShulman 레이아웃을 조금 더 잘 설명해야한다고 생각합니다. 이것은 말이되지 않습니다.
ewwhite

답변:


4

모든 테이블에 InnoDB 만 사용하고 다음 innodb_flush_log_at_trx_commit으로 설정 한 경우 :

  • 1 (InnoDB 로그 버퍼의 내용은 각 트랜잭션 커밋에서 로그 파일에 기록되고 로그 파일은 디스크로 플러시됩니다) 또는
  • 2 (InnoDB 로그 버퍼의 내용은 각 트랜잭션 커밋 후 로그 파일에 기록되고 로그 파일은 초당 약 1 회 디스크로 플러시됩니다),

그런 다음 스냅 샷을 수행하기 전에 FLUSH TABLES가 필요하지 않으며 ZFS 스냅 샷을 직접 실행하면됩니다. InnoDB는 데이터 손실없이 트랜잭션 커밋 로그에서 데이터를 복구 할 수 있습니다.

참조 : https://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit


으로 데이터가 사전 MySQL의 8 도입하더라도 DDL (스키마 변형) 연산은 현재 원자이다. 그 전에 파일 시스템 스냅 샷 중 DDL 조작은 부분적으로 커미트 된 (즉, 손상된) 결과를 제공 할 수 있습니다.
bernie

13

(대부분의) 데이터베이스를 일관되게 백업하려면 전체 데이터베이스 잠금이 필요합니다.

수동 https://dev.mysql.com/doc/refman/5.5/en/backup-methods.html는 말한다 READ LOCK과 같은 높이 테이블은 특히 ZFS 스냅 샷에 대한 올바른 것입니다.

파일 시스템 스냅 샷을 사용하여 백업하기

Veritas 파일 시스템을 사용하는 경우 다음과 같이 백업 할 수 있습니다.

  1. 클라이언트 프로그램에서을 실행하십시오 FLUSH TABLES WITH READ LOCK.
  2. 다른 쉘에서 마운트 vxfs스냅 샷을 실행하십시오 .
  3. 첫 번째 클라이언트에서를 실행하십시오 UNLOCK TABLES.
  4. 스냅 샷에서 파일을 복사하십시오.
  5. 스냅 샷을 마운트 해제하십시오.

유사 스냅 샷 기능은 LVM 또는 ZFS와 같은 다른 파일 시스템에 사용할 수 있습니다.

말도의 종류 그들은 당신이 필요로하는 사실 남겨 것을 FLUSH TABLES table_a, table_b, table_c FOR EXPORT위해 InnoDB의 이 지침에서합니다. 그런 식으로 각 테이블을 지정 해야하는 것도 바보입니다. 그러나 EEAA가 말했듯이 백업을 상당히 쉽게 시작할 때 테이블 목록을 생성 할 수 있습니다.

잠금을 유지하려면 스냅 샷을 수행하는 동안 DB 연결을 활성 상태로 유지해야합니다

일반적으로 Perl 또는 다른 프로그래밍 언어를 사용하여 연결할 수 있고 db를 잠그고 db 연결을 유지하면서 스냅 샷을 찍은 다음 잠금을 해제하고 연결을 끊습니다. 복잡하지 않습니다. 이미이 작업을 수행하는 도구가 있지만 작성하는 것은 쉽습니다.

몇 번이나 간단하고 복잡하지 않다고 말합니다. 기본 프로그래밍이나 스크립팅 기술이 좋다고 가정합니다.


나는 Bash에서 개념적으로 간단한 스크립트를 유지하기를 희망했지만 언어를 올바르게 전환하면 훨씬 쉽게 할 수 있습니다. 나는 당신의 응답을 잘못 읽을 수 있습니다,하지만 당신은 내가 모두를 실행해야 할 말을하는지 보이는 FLUSH TABLES WITH READ LOCK다음과 FLUSH TABLES...FOR EXPORTMySQL의 설명서의 내 독서는 하나가 필요합니다 말한다 반면,.
Andy Shulman

확실하지 않아서 죄송합니다. 나는 그냥 매뉴얼로 가고 있으며 두 가지 다른 말이 있습니다. 나는 당신이 정확하고 나중에 필요하다고 추측합니다. 그러나 모든 테이블은 하나의 명령으로 잠겨 야합니다.
Ryan Babchishin

1
설명서가 명확하지 않고 전체 데이터베이스를 잠 가야하며 스냅 샷을 만드는 동안 DB 연결을 유지해야하므로 DB를 종료하고 백업 한 후 다시 시작하는 것이 더 쉬워 보입니다. 그것.
Andrew Henle

2
@andrew sigh ... 이해합니다. 그러나 속도가 느려서 연결이 끊어 지거나 실패하고 데이터베이스가 제대로 백업되지 않는 것을 보았습니다 (자동화에 좋지 않습니다). mysql / Oracle에서 명확한 답변을 얻는 것이 좋습니다. 메일 링리스트가 있어야합니다.
Ryan Babchishin

7

나는 찢어 내가 다른 서버 오류에서 발견 배쉬에서 개념적으로 간단한 스크립트 적응 한 이후Tobia을 . 거기에 약 90 %의 도움이됩니다.

mysql_locked=/var/run/mysql_locked

# flush & lock MySQL, touch mysql_locked, and wait until it is removed
mysql -hhost -uuser -ppassword -NB <<-EOF &
    flush tables with read lock;
    delimiter ;;
    system touch $mysql_locked
    system while test -e $mysql_locked; do sleep 1; done
    exit
EOF

# wait for the preceding command to touch mysql_locked
while ! test -e $mysql_locked; do sleep 1; done

# take a snapshot of the filesystem, while MySQL is being held locked
zfs snapshot zpool/$dataset@$(date +"%Y-%m-%d_%H:%M")

# unlock MySQL
rm -f $mysql_locked

여기서 mysql사용 하는 명령은 백그라운드에서 실행되며 파일을 터치합니다. 종료하기 전에 파일이 사라질 때까지 백그라운드에서 대기하여 테이블을 잠금 해제합니다. 한편 메인 스크립트는 파일이 존재할 때까지 기다린 다음 스냅 샷을 생성하고 파일을 삭제합니다.

가 지적한 파일은 $mysql_locked두 머신 모두에 액세스 할 수 있어야하며, 공통 경로에 액세스 할 수 있기 때문에 쉽게 수행 할 수 있어야합니다 (다른 경로를 사용할 수도 있지만이를 고려해야합니다).


나는 MySQL 스크립팅을 모른다. 그래서 이것은 어리석은 아이디어 일지 모른다. 그러나 당신은 단지 system zfs snapshot...메인 스크립트 안에서 할 수 없었는가? 아니면 별도의 프로세스에서 스냅 샷 을 실행 해야 합니까?
TripeHound

@Tripehound 두 가지 상황이 어떻게 든 동시에 일어날 필요가있다
Ryan Babchishin

@RyanBabchishin 나는 그가 옳다고 생각합니다. 이 SYSTEM명령은 사물을 로컬로 실행합니다. FreeBSD 상자에서 mysql 클라이언트를 실행하고 실행 LOCK; SYSTEM zfs snapshot; UNLOCK하면 작동하는 것처럼 보입니다.
Andy Shulman

@ 앤디는 방금 병렬로 발생해야한다고 말했습니다. 어떻게 진행하든 상관 없습니다.
Ryan Babchishin

2

저널링이 아니므로 myisam에 대해 읽기 잠금이있는 FLUSH 테이블이 필요합니다.

INO는 저널링이기 때문에 실제로 innodb에는 아무것도 필요하지 않습니다. 어쨌든 일관성이 있습니다. 스냅 샷 원자 순간에 문제가 발생하면 저널을 자동으로 롤백하십시오.

응용 프로그램 수준의 일관성을 원하면 응용 프로그램에서 트랜잭션을 사용해야합니다. 응용 프로그램이 트랜잭션과 innodb를 사용하는 경우 모든 스냅 샷이 일관되게 응용 프로그램 수준까지 자동으로 요청합니다.


2

이것은 잠금을 유지하면서 ZFS 스냅 샷을 만드는 방법입니다.

mysql << EOF
    FLUSH TABLES WITH READ LOCK;
    system zfs snapshot data/db@snapname
    UNLOCK TABLES;
EOF
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.