사례 12. 셸 다 중 스 레 드 백업 데이터베이스

셸 스 크 립 트 다 중 스 레 드 는 이름 파 이 프 를 통 해 이 루어 졌 기 때문에 이해 하기 어렵 습 니 다.다 중 스 레 드 란 원래 한 프로 세 스 가 완 성 했 던 일 을 지금 은 여러 스 레 드 로 완성 하 는 것 이다.만약 프로 세 스 가 10 시간 이 걸 리 는 일 을 지금 10 개의 스 레 드 를 배정 하여 그들 에 게 분업 을 한 다음 에 이 일 을 동시에 하면 최종 적 으로 1 시간 이 걸 릴 것 이다.
본 사례 의 구체 적 인 수 요 는 다음 과 같다.
1) 회사 의 업 무량 이 비교적 많 고 100 개의 데이터 베 이 스 는 전량 백업 이 필요 하 며 모든 데이터 베 이 스 는 수 십 GB 에 달한다. (주의, 모든 라 이브 러 리 는 하나의 독립 된 실례, 즉 독립 된 IP: port 가 있다.)
2) 각 라 이브 러 리 의 백업 시간 을 30 분 정도 로 예측한다.
3) 5 시간 내 에 백업 을 완료 해 야 합 니 다.
알림: 5 시간 안에 100 개의 데이터 베 이 스 를 백업 하려 면 셸 스 크 립 트 의 다 중 스 레 드 기능 을 사용 하여 10 개의 스 레 드 를 한꺼번에 열 고 10 개의 데이터 베 이 스 를 동시에 백업 해 야 합 니 다.
지식 포인트 1: xtrabackup 을 사용 하여 MySQL 데이터 베 이 스 를 백업 합 니 다.
my sqldump 는 G 의 데이터베이스 나 시 계 를 내 보 내 는 데 좋 습 니 다.데이터 양 이 수 십 수백 G 에 이 르 면 원 라 이브 러 리 에 대한 압력 이 든 내 보 내 는 성능 이 든 my sqldump 는 그다지 좋 지 않다.Percona - Xtrabackup 백업 도 구 는 MySQL 온라인 열 준비 작업 의 두 가지 선택 을 실현 하고 전체 양, 증분, 단일 표 백업 과 복원 을 할 수 있 습 니 다.
xtrabackup 명령 은 InnoDB 와 XtraDB 저장 엔진 의 데이터 베 이 스 를 차단 하지 않 고 백업 할 수 있 으 며, innobackupex 는 Perl 을 통 해 xtrabackup 을 패키지 하여 Myisam 의 백업 은 표 읽 기 자 물 쇠 를 통 해 이 루어 집 니 다.
CentOS 7 에 Percona - Xtrabackup 을 이렇게 설치 합 니 다.
# rpm -ivh https://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm  //  yum 
# yum install -y percona-xtrabackup-24  //yum  2.4  

xtrabackup 으로 전체 백업 명령 은:
# innobackupex --default-file=/etc/my.cnf --host=10.100.100.100 --port=3333 --user=bakuser --password=your_pass /data/backup/mysql

설명: 이 백업 작업 을 수행 하기 전에 사용자 bakuser (사용자 이름 사용자 정의) 를 만 들 고 reload, lock tables, replication client, process, super 등 권한 을 부여 해 야 합 니 다.백업 데 이 터 는/data/backup/mysql 디 렉 터 리 에 넣 고 현재 날짜, 시간 을 이름 으로 하 는 디 렉 터 리 를 자동 으로 생 성 합 니 다. 예 를 들 어 2019 - 08 - 1009_56_12.
지식 포인트 2: 파일 설명자
파일 설명자 (줄 임 말 fd) 는 형식적 으로 마이너스 정수 가 아 닙 니 다.실제로, 이것 은 모든 프로 세 스 가 유지 하고 있 는 프로 세 스 를 가리 키 는 색인 값 입 니 다. 파일 의 기록 표를 엽 니 다.프로그램 이 기 존 파일 을 열 거나 새 파일 을 만 들 때 커 널 은 프로 세 스 에 파일 설명 자 를 되 돌려 줍 니 다.모든 유 닉 스 프로 세 스 는 세 가지 다른 흐름 에 대응 하 는 세 가지 표준 파일 설명 자 를 가지 고 있 습 니 다.
               
0                   
1                     
2                     

위의 세 개의 표준 설명 자 를 제외 하고 프로 세 스 에서 다른 숫자 를 파일 설명자 로 정의 할 수 있 습 니 다.모든 파일 설명 자 는 파일 을 열 어야 하 며, 서로 다른 파일 설명자 도 같은 파일 을 열 수 있 습 니 다.같은 파일 은 다른 프로 세 스에 의 해 열 릴 수도 있 고, 같은 프로 세 스에 의 해 여러 번 열 릴 수도 있다.
테스트 스 크 립 트 를 작성 합 니 다./tmp/test. sh, 내용:
#!/bin/bash
echo "    pid $$"
exec 1>/tmp/test.log 2>&1
ls -l /proc/$$/fd/

이 스 크 립 트 를 실행 하고/tmp/test. log 를 봅 니 다.
# cat test.log
    0
lrwx------. 1 root root 64 8   10 10:24 0 -> /dev/pts/1
l-wx------. 1 root root 64 8   10 10:24 1 -> /tmp/test.log
l-wx------. 1 root root 64 8   10 10:24 2 -> /tmp/test.log
lr-x------. 1 root root 64 8   10 10:24 255 -> /tmp/test.sh

설명: exec 는 스 크 립 트 후속 명령 의 정확 함 과 오류 출력 을/tmp/test. log 로 바 꾸 었 기 때문에 이 파일 을 볼 때 상기 내용 을 볼 수 있 습 니 다.exec 명령 에 대해 직관 적 인 예 를 보십시오.
[root@wbs 12.sh]# exec > /tmp/test
[root@wbs 12.sh]# echo "123123"
[root@wbs 12.sh]# echo $PWD
[root@wbs 12.sh]# lalala
-bash: lalala:      
[root@wbs 12.sh]# exec > /dev/tty
[root@wbs 12.sh]# cat /tmp/test
123123
/root/20shell/12.sh

설명: 위의 예 를 통 해 알 수 있 듯 이 exec 를 실행 한 후에 그 뒤의 명령 의 표준 출력 은 모두/tmp/test 파일 에 기록 되 었 고 잘못된 것 은 현재 터미널 에 표 시 됩 니 다. 이 설정 을 종료 하려 면 exec 의 표준 출력 을/dev/tty 로 다시 정의 해 야 합 니 다.
지식 포인트 3: 명명 파이프
앞에서 셸 스 크 립 트 에서 파이프 기 호 를 여러 번 사용 한 적 이 있 습 니 다. 이것 은 익명 파이프 라 고 합 니 다. 여기 서 언급 한 파 이 프 는 이름 파이프 라 고 합 니 다. 기능 은 익명 파이프 와 대체적으로 같 습 니 다.
파이프 이름, 영어 이름 First In First Out, 약칭 FIFO.이름 파이프 특징:
1) 파일 시스템 에서 FIFO 는 이름 을 가지 고 있 으 며 장치 의 특수 파일 형식 으로 존재 한다.
2) 모든 프로 세 스 가 FIFO 를 통 해 데 이 터 를 공유 할 수 있 습 니 다.
3) FIFO 양 끝 에 읽 기와 쓰기 프로 세 스 가 동시에 있 지 않 으 면 FIFO 의 데이터 유통 이 막 힐 수 있 습 니 다.
4) 익명 파 이 프 는 셸 이 자동 으로 만 들 고 커 널 에 존재 하 며 FIFO 는 프로그램 이 만 든 (예 를 들 어 mkfifo 명령) 으로 파일 시스템 에 존재 합 니 다.
5) 익명 파 이 프 는 단 방향 바이트 흐름 이 고 FIFO 는 양 방향 바이트 흐름 이다.
mkfifo 명령 으로 이름 파 이 프 를 만 듭 니 다:
# screen
# mkfifo 123.fifo
# echo "121212" > 123.fifo  //     ,               ,            。
ctrl+a d  //   screen
# cat 123.fifo  //      121212  ,     screen     echo         。

이름 파이프 와 파일 설명 자 를 결합 할 수 있 습 니 다:
[root@wbs ~]# mkfifo test.fifo
[root@wbs ~]# exec 10<>test.fifo  //     fd10         test.fifo 
[root@wbs ~]# ls -l /dev/fd/10  //    fd10      /root/test.fifo
lrwx------. 1 root root 64 8   10 11:41 /dev/fd/10 -> /root/test.fifo

지식 포인트 4: read 명령
셸 스 크 립 트 에서 read 명령 을 많이 사용 합 니 다. 가장 전형 적 인 용법 은 사용자 와 상호작용 하 는 것 입 니 다. 다음 과 같 습 니 다.
# read -p "Please input a number:" n
Please input a number:3
# echo $n
3

- p 옵션 을 사용 하지 않 으 면 이렇게 사용 할 수 있 습 니 다.
# read name
1234
# echo $name
1234

read 의 - u 옵션 뒤에 fd 를 따라 갈 수 있 습 니 다. 다음 과 같 습 니 다.
# read -u 10 a  //    fd 10         a

여기 fd 10 은 앞에서 정 의 된 test. fifo 입 니 다. fd 10 에 아무런 내용 도 기록 되 지 않 으 면 위 명령 을 실행 하면 걸 리 지 않 습 니 다.fd 10 은 이름 이 붙 은 파이프 파일 이기 때문에 기록 한 것 만 읽 을 수 있 습 니 다. 그렇지 않 으 면 계속 끊 겨 서 기록 내용 을 기다 리 고 있 습 니 다.물론 이 이름 의 파이프 파일 은 여러 줄 에 쓸 수 있 습 니 다. 먼저 저장 한 다음 에 read 가 읽 기 를 기다 리 고 있 습 니 다.
# echo "123" >& 10
# echo "456" >& 10  //   fd10       
# read -u 10 a  //     fd10     
# echo $a
123
# read -u 10 a  //     fd10     
# echo $a
456

지식 포인트 5: wait 명령
wait 명령: 기다 리 는 것 은 완료 되 지 않 은 작업 (주로 배경 작업) 을 기다 리 는 것 입 니 다. 모든 작업 이 완 료 된 후에 야 wait 이후 의 명령 을 계속 수행 할 수 있 습 니 다. 셸 스 크 립 트 에 자주 사 용 됩 니 다.다음은 wait 명령 에 대한 예제 입 니 다.
# sleep 5 &
# wait   //       ,            ,     。

지식 점 6: 명명 파이프 와 read 를 결합 하여 다 중 스 레 드 실현
명명 파 이 프 는 두 가지 뚜렷 한 특징 이 있다.
1) 먼저 나 간다. 예 를 들 어 상례 에서 우 리 는 fd 10 에 두 줄 의 내용 을 썼 는데 첫 번 째 read 첫 번 째 줄, 두 번 째 read 두 번 째 줄 이다.
2) 내용 read 가 있 으 면 실행 하고, 없 으 면 차단 합 니 다. 예 를 들 어 상례 에서 read 가 두 번 끝 난 후에, 만약 당신 이 read 를 다시 실행 한다 면, 그것 은 우리 가 다시 새로운 내용 을 쓸 때 까지 계속 끊 길 것 입 니 다.
이 두 가지 특징 을 이용 하면 셸 의 다 중 스 레 드 를 실현 할 수 있 습 니 다. 먼저 예 를 들 어 보 겠 습 니 다.
#!/bin/bash
#      123.fifo  
mkfifo 123.fifo
#     123.fifo      1000  , fd1000        123.fifo 
exec 1000<>123.fifo

#   fd1000       
echo >&1000
echo >&1000

#  10 
for i in `seq 1 10`
do
    #     ,   fd1000    ,   ,       ,    { }    
    #              ,  1 ,     fd1000     ,     read     
    #read        ,        , { }   ,        
    read -u1000
    {
        date +%T
        echo $i
        sleep 1
        echo >&1000
    } &  //     ,  10       ,             。         fd1000        ,  read        。
done
#            
wait
#  fd1000
exec 1000>&-
#      
rm -f 123.fifo

실행 결과:
08:54:11
1
08:54:11
2
08:54:12
3
08:54:12
4
08:54:13
5
08:54:13
6
08:54:14
08:54:14
7
8
08:54:15
9
08:54:15
10

10 초 만 에 완성 해 야 했 던 일 을 지금 5 초 만 에 완성 한 것 을 볼 수 있 습 니 다. 이 는 병발 량 이 2, 즉 두 스 레 드 가 동시에 임 무 를 수행 하고 5 개의 스 레 드 를 원한 다 면 처음에 fd 1000 에 5 개의 빈 줄 을 직접 기록 하면 됩 니 다.
본 사례 참조 스 크 립 트
#!/bin/bash
#        
#  :
#  :
#  :v1.0

##  100     、host、port                ,     /tmp/databases.list
##  :db1 10.10.10.2 3308 /data/mysql/db1/my.cnf
##       xtrabackup(     myisam,   inoobackupex)

exec &> /tmp/mysql_bak.log

if ! which innobackupex &>/dev/nll
then
    echo "  xtrabackup  "
    rpm -ivh http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm  && \ 
    yum install -y percona-xtrabackup-24
    if [ $? -ne 0 ]
    then
        echo "  xtrabackup    ,   。"
        exit 1
    fi
fi

bakdir=/data/backup/mysql
bakuser=vyNctM
bakpass=99omeaBHh

function bak_data {
    db_name=$1
    db_host=$2
    db_port=$3
    cnf=$4
    [ -d $bakdir/$db_name ] || mkdir -p $bakdir/$db_name
    innobackupex --defaults-file=$4  --host=$2  --port=$3 --user=$bakuser --password=$bakpass  $bakdir/$1
        if [ $? -ne 0 ]
        then
            echo "     $1    。"
        fi
}

fifofile=/tmp/$$
mkfifo $fifofile
exec 1000<>$fifofile


thread=10
for ((i=0;i&1000
done

cat /tmp/databases.list | while read line
do
    read -u1000
    {
        bak_data `echo $line`
        echo >&1000
    } &
done

wait
exec 1000>&-
rm -f $fifofile

좋은 웹페이지 즐겨찾기