활성 읽기 및 쓰기로 라이브 시스템에서 mysqldump를 수행하는 가장 안전한 방법은 무엇입니까?


78

이것이 사실인지 확실하지 않지만 Linux에서 다음 명령을 실행하면 읽은 것을 기억합니다.

mysqldump -u username -p database_name > backup_db.sql

데이터베이스에 대한 읽기 및 쓰기 작업을 수행하는 동안 덤프에 오류가있을 수 있습니다.

mysqldump라이브 시스템에서 안전하게 수행 할 수 있도록 명령 에 특정 옵션 이 있습니까? 몇 초 동안 사용자에 대해 읽기 / 쓰기가 비활성화되어 있어도 괜찮습니다 (데이터베이스 <50MB)

답변:


82

모든 데이터는 InnoDB

이것은 데이터의 정확한 시점 스냅 샷을 제공합니다.

mysqldump -uuser -ppass --single-transaction --routines --triggers --all-databases > backup_db.sql

--single-transaction들어오는 변경 사항을 수신하면서 덤프가 검사 점 이전의 모든 데이터를 캡처 할 수있는 검사 점을 생성합니다. 들어오는 변경 사항은 덤프의 일부가되지 않습니다. 이렇게하면 모든 테이블에 대해 동일한 특정 시점이 보장됩니다.

--routines 모든 저장 프로 시저 및 저장 함수를 덤프합니다.

--triggers 각 테이블에 대한 모든 트리거를 덤프합니다.

모든 데이터는 MyISAM 또는 InnoDB / MyISAM의 혼합입니다

전역 읽기 잠금을 적용하고 mysqldump를 수행 한 후 글로벌 잠금을 해제해야합니다.

mysql -uuser -ppass -Ae"FLUSH TABLES WITH READ LOCK; SELECT SLEEP(86400)" &
sleep 5
mysql -uuser -ppass -ANe"SHOW PROCESSLIST" | grep "SELECT SLEEP(86400)" > /tmp/proclist.txt
SLEEP_ID=`cat /tmp/proclist.txt | awk '{print $1}'`
echo "KILL ${SLEEP_ID};" > /tmp/kill_sleep.sql
mysqldump -uuser -ppass --single-transaction --routines --triggers --all-databases > backup_db.sql
mysql -uuser -ppass -A < /tmp/kill_sleep.sql

시도 해봐 !!!

업데이트 2012-06-22 08:12 EDT

<50MB의 총 데이터가 있으므로 다른 옵션이 있습니다. 프로세스 ID를 얻고 외부를 종료하기 위해 86400 초 (24 시간) 동안 글로벌 읽기 잠금을 유지하기 위해 SLEEP 명령을 백그라운드로 실행하는 대신 OS가 아닌 mysql에서 5 초 시간 초과를 설정해 봅시다.

SLEEP_TIMEOUT=5
SQLSTMT="FLUSH TABLES WITH READ LOCK; SELECT SLEEP(${SLEEP_TIMEOUT})"
mysql -uuser -ppass -Ae"${SQLSTMT}" &
mysqldump -uuser -ppass --single-transaction --routines --triggers --all-databases > backup_db.sql

이것은 매우 작은 데이터베이스에 대해보다 깨끗하고 간단한 접근 방법입니다.


1
5 초는 예방 조치 일뿐입니다. 더 낮은 값을 시도 할 수 있습니다.
RolandoMySQLDBA

1
Rolando- ERROR 2013 (HY000) at line 1: Lost connection to MySQL server during query예상되는 오류 메시지입니까?
user784637

1
모든 MySQL 데이터가 mysqldump에서 나왔습니까?
RolandoMySQLDBA

1
오류 메시지가 확실하지 않습니다. 이것은 추측 일 뿐이지 만 두 번째 스크립트에서 언급 한 사용자 정의 SLEEP 함수 호출을 종료하는 한 줄 스크립트에서 비롯된 것일 수 있습니다.
RolandoMySQLDBA 2016 년

1
내 새로운 제안을 시도하고 잘 진행되는지 확인하십시오. 바라건대, 오류 메시지가 없을 것입니다.
RolandoMySQLDBA 2016 년


1

다운 타임없이 테이블을 잠그지 않고 MyISAM 또는 혼합 테이블에 대해이를 수행하려는 경우 슬레이브 데이터베이스를 설정하고 스냅 샷을 생성 할 수 있습니다. 불행히도 슬레이브 데이터베이스를 설정하면 가동 중지 시간이 발생하여 라이브 데이터베이스를 내보내지만 일단 실행되면 테이블을 잠그고 다른 방법을 사용하여 내보낼 수 있습니다. 이런 일이 발생하면 마스터보다 뒤쳐 지지만 마스터가 테이블을 업데이트하는 것을 막지 않으며 백업이 완료되는 즉시 따라 잡을 것입니다.


1

내가 한 방법은 다음과 같습니다. 사용하기 때문에 모든 경우에 작동합니다 FLUSH TABLES WITH READ LOCK.

#!/bin/bash

DB=example
DUMP_FILE=export.sql

# Lock the database and sleep in background task
mysql -uroot -proot $DB -e "FLUSH TABLES WITH READ LOCK; DO SLEEP(3600);" &
sleep 3

# Export the database while it is locked
mysqldump -uroot -proot --opt $DB > $DUMP_FILE

# When finished, kill the previous background task to unlock
kill $! 2>/dev/null
wait $! 2>/dev/null

echo "Finished export, and unlocked !"

sleep명령은 mysqldump가 시작되기 전에 mysql 잠금 명령을 실행하는 백그라운드 작업이 실행되도록하는 것입니다. 당신은 1 초로 줄일 수 있으며 여전히 괜찮을 것입니다. 30 초로 늘리고 30 초 동안 다른 클라이언트의 테이블에 값을 삽입하여 잠긴 것을 확인하십시오.

이 매뉴얼 배경 잠금을 사용하여 대신 사용하여 2 장점이 있습니다 mysqldump옵션 --single-transaction--lock-tables:

  1. MyISAM / InnoDB 테이블을 혼합 한 경우 모든 것이 잠 깁니다.
  2. mysqldump동일한 잠금 기간 동안 외에 다른 명령을 실행할 수 있습니다 . 예를 들어 마스터 노드에서 복제를 설정할 때 유용 SHOW MASTER STATUS;합니다. 데이터베이스를 잠금 해제하기 전에 생성 한 덤프의 정확한 상태에서 이진 로그 위치를 가져 와서 복제 슬레이브를 만들 수 있기 때문입니다.


0

MYISAM 테이블이 매우 커서 잠금없이 테이블을 덤프하고 서버로드를 많이 피해야하는 경우 다음 스크립트를 사용할 수 있습니다.

#!/bin/sh

my_user="user"
my_password="password"
my_db="vpn"
my_table="traffic"
my_step=100000

read -p "Dumping table ${my_db}.${my_table} to ${my_table}.sql?" yn
case $yn in
    [Yy]* ) break;;
    * ) echo "User cancel."; exit;;
esac

my_count=$(mysql $my_db -u $my_user -p$my_password -se "SELECT count(*) FROM $my_table")
my_count=$(($my_count + 0))

if [ ! $my_count ]
then
    echo "No records found"
    exit
fi

echo "Records in table ${my_db}.${my_table}: ${my_count}"

echo "" > $my_table.sql

max_progress=60

for (( limit=0; limit<=$my_count; limit+=$my_step )); do
    progress=$((max_progress * ( limit + my_step) / my_count))

    echo -ne "Dumping ["
    for ((i=0; i<$progress; i ++)); do
        echo -ne "#"
    done
    for ((; i<$max_progress; i ++)); do
        echo -ne "."
    done

    mysqldump -u $my_user -p$my_password --complete-insert --no-create-info --opt --where="1 limit $limit , $my_step" $my_db $my_table >> $my_table.sql
    echo "" >> $my_table.sql

    echo -ne "] $((100 * ( limit + my_step ) / my_count)) %"
    echo -ne "\r"

    sleep 1

done

echo -ne "\n"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.