한 서버에서 다른 서버로 데이터베이스를 어떻게 이동합니까?


136

한 물리적 서버에서 다른 물리적 서버로 MySQL 테이블을 어떻게 이동할 수 있습니까?

이 정확한 시나리오 : innodb 테이블을 사용하고 크기가 약 20GB 인 MySQL 서버가 있습니다.

새 서버로 옮기고 싶습니다. 가장 효율적인 방법은 무엇입니까?


4
xtrabackup percona.com/docs/wiki/를 사용 하고 싶습니다. 복사하는 것과 매우 비슷하지만 서버를 계속 실행하고 주로 innodb 테이블을 사용한다고 가정하면 "핫"이라고 간주 할 수 있습니다. 백업도.
조나단

이 도구를 사용하는 다른 사람들에게는 도움이되지 않습니다. 무료 / 오픈 소스이며 회사에서 만든 것이더라도 해당 회사의 지원 구매를 고려할 필요가 없을 정도로 사용하기 쉽습니다.
조나단

답변:


80

내가 가장 좋아하는 방법은 sqldump 명령을 sql 명령으로 파이프하는 것입니다. 모든 데이터베이스 또는 특정 데이터베이스를 수행 할 수 있습니다. 예를 들어

mysqldump -uuser -ppassword myDatabase | mysql -hremoteserver -uremoteuser -premoteserverpassword 

당신은 모든 데이터베이스를 할 수 있습니다

mysqldump --all-databases -uuser -ppassword | mysql -hremoteserver -uremoteuser -premoteserver 

유일한 문제는 데이터베이스가 너무 커서 파이프가 붕괴되는 경우입니다. 이 경우 테이블별로 또는 아래 언급 된 다른 방법 중 하나를 수행 할 수 있습니다.


4
팁 : 데이터베이스가 원격 연결을 허용하지 않으면을 통해 파이프하십시오 netcat.
바트 반 Heukelom

1
이를 위해 원격 서버에서 동일한 이름으로 빈 데이터베이스를 만든 다음 해당 데이터베이스 이름을 명령 끝에 추가해야했습니다.
Zugwalt

1
이것은 우아하지만 20GB 데이터베이스에는 압축 속도가 빠르지 않습니다.
Daddy32

이 솔루션은 완전히 제어 된 네트워크에만 적합합니다 (보안 개인 네트워크에있는 경우에만 인터넷을 읽지 마십시오)! 그러나 빠르고 쉬운 솔루션!
tdaget

번개가 빨리옵니다! 그러나 @ Zugwalt가 말한 것은 나에게도 사실이었습니다. 데이터베이스를 만들 때까지 명령이 작동하지 않았습니다 (빈) add 명령을 수행 할 때 데이터베이스 이름을 추가했습니다.
스키트

65

최근에 다음과 같은 전략으로 30GB 데이터베이스를 옮겼습니다.

이전 서버

  • MySQL 서버 중지
  • datadir의 내용 을 디스크의 다른 위치 ( ~/mysqldata/*) 에 복사
  • MySQL 서버를 다시 시작하십시오 (가동 중지 시간은 10-15 분이었습니다)
  • 데이터 압축 ( tar -czvf mysqldata.tar.gz ~/mysqldata)
  • 압축 파일을 새 서버로 복사

새로운 서버

  • mysql을 설치하십시오 (시작하지 마십시오)
  • 압축 파일 압축 해제 ( tar -xzvf mysqldata.tar.gz)
  • mysqldata의 내용을 datadir 로 이동
  • innodb_log_file_size가 새 서버에서 동일한 지 확인하거나 그렇지 않은 경우 이전 로그 파일을 복사하지 마십시오 ( mysql이 생성합니다 )
  • mysql 시작

1
압축 / 압축 해제 후 복사를 건너 뜁니다. ssh를 사용하여 네트워크를 통해 타르를 스트리밍하거나 암호화 되지 않은 오버 헤드를 피하기 위해 netcat을 사용하십시오 (인터넷이 아닌 안전한 개인 네트워크에있는 경우에만 ). 또한 로컬 네트워크에서 gzipping을 건너 뛰는 경우 빠른 네트워크 파이프를 사용하는 경우 압축을 수행하는 페그 코어 회전에서 전송 병목 현상이 발생합니다.
atxdba

이것은 innodb와 myisam 모두에서 작동합니까? 또한 mysql 사용자도 datadir에 있습니까?
giorgio79

2
ibdata 파일을 이동하는 한 반드시 @ giorgio79로 이동하십시오. 기본적으로 이들은 datadir에 있습니다. MySQL 사용자는 사용자 테이블 스페이스의 mysql 폴더에 저장됩니다.
데릭 다우니

2
이 절차가 Windows에서 Linux로 이동하는 데 효과적입니까?
ypercubeᵀᴹ

2
@ TypoCubeᵀᴹ 응답하는 데 2 ​​년 이상이 걸렸지 만 죄송합니다. "예, Windows에서 Linux로 작동합니다." 필자의 경우 Windows Server 2012 R2 에서 Cent OS (Red Hat 4.8.5-11)로갔습니다 . 특정 mysql 버전은 Maria DB 10.1 입니다. 규정에 따라 mysql 서비스를 모두 중지하고 데이터 디렉토리를 재 동기화하고 새 서버에서 mysql 서비스를 시작할 때 모든 데이터베이스, 데이터베이스 테이블 및 데이터베이스 사용자가 완전히 손상되지 않았습니다.
WEBjuju

30

에 따르면 5.0 인증 학습 가이드 , 장 32 절 32.3.4, 페이지 456457은 설명 바이너리 이식성을위한 조건 밖으로 다음 가지고 :

이진 이식성은 한 시스템에서 작성된 이진 백업을 가져 와서 다른 아키텍처를 가진 다른 시스템에서 사용하려는 경우에 중요합니다. 예를 들어, 바이너리 백업을 사용하면 한 MySQL 서버에서 다른 MySQL 서버로 데이터베이스를 복사 할 수 있습니다.

MyISAM의 경우 이진 이식성은 MyISAM 테이블의 파일을 한 MySQL 서버에서 다른 컴퓨터의 다른 서버로 직접 복사 할 수 있고 두 번째 서버가 테이블에 액세스 할 수 있음을 의미합니다.

InnoDB의 경우 바이너리 이식성은 한 머신의 MySQL 서버에서 다른 머신의 다른 서버로 테이블 스페이스 파일을 직접 복사 할 수 있고 두 번째 서버가 테이블 스페이스에 액세스 할 수 있음을 의미합니다. 기본적으로 서버가 관리하는 모든 InnoDB 테이블은 테이블 스페이스에 함께 저장되므로 테이블 스페이스의 이식성은 모든 개별 InnoDB 테이블이 이식 가능한지 여부의 함수입니다. 하나의 테이블도 이식 가능하지 않으면 테이블 공간도 마찬가지입니다.

MyISAM 테이블과 InnoDB 테이블 스페이스는 두 가지 조건이 충족되면 한 호스트에서 다른 호스트로 이진 이식 가능합니다.

  • 두 기계 모두 2의 보수 정수 산술을 사용해야합니다
  • 두 머신 모두 IEEE 부동 소수점 형식을 사용해야합니다. 그렇지 않으면 테이블에 부동 소수점 열이 없어야합니다 (FLOAT 또는 DOUBLE)

실제로이 두 조건은 거의 제한이 없습니다. 2의 보수 정수 산술 및 IEEE 부동 소수점 형식은 현대 하드웨어의 표준입니다. InnoDB 바이너리 이식성의 세 번째 조건은 테이블과 데이터베이스에 소문자 이름을 사용해야한다는 것입니다. InnoDB는 이러한 이름을 Windows에서 내부적으로 (데이터 사전에) 소문자로 저장하기 때문입니다. 소문자 이름을 사용하면 Windows와 Unix 간의 이진 이식성이 가능하므로 소문자 이름을 사용하도록 옵션 파일에 다음 줄을 넣을 수 있습니다.

[mysqld]
lower_case_table_names=1

테이블 단위 테이블 스페이스를 사용하도록 InnoDB를 구성하면 이진 이식성 조건이 확장되어 InnoDB 테이블의 .ibd 파일도 포함됩니다. (공유 테이블 스페이스의 조건은 모든 InnoDB 테이블에 대한 정보를 저장하는 데이터 사전을 포함하므로 여전히 적용됩니다.)

이진 이식성 조건이 충족되지 않으면 MyISAM 또는 InnoDB 테이블을 일부 텍스트 형식 (예 : mysqldump로)을 사용하여 덤프 한 다음 대상 서버로 다시로드하여 한 서버에서 다른 서버로 복사 할 수 있습니다.

스토리지 엔진을 기반으로 개별 테이블을 이동하는 두 가지 주요 방법이 있습니다.

주어진 예에서 다음을 가정합니다.

  1. datadir은 / var / lib / mysql입니다.
  2. mydb 라는 데이터베이스
  3. 테이블 MYDB의 데이터베이스라는 MYTABLE .

MyISAM 테이블

mydb.mytable이 MyISAM 스토리지 엔진을 사용하는 경우 테이블은 물리적으로 세 개의 별도 파일로 나타납니다.

  1. /var/lib/mysql/mydb/mytable.frm(.frm 파일)
  2. /var/lib/mysql/mydb/mytable.MYD(.MYD 파일)
  3. /var/lib/mysql/mydb/mytable.MYI(.MYI 파일)

.frm은 테이블 구조를 포함합니다
. .MYD는 테이블 데이터를
포함합니다. .MYI는 테이블 인덱스 페이지를 포함합니다

이 파일들은 mysql의 논리적 관점에서 테이블을 나타 내기 위해 상호 의존적으로 사용됩니다. 이 파일에는 더 이상 논리적 연관 첨부가 없으므로 한 DB 서버에서 다른 DB 서버로 테이블을 마이그레이션합니다. Windows 서버에서 Linux 서버 또는 MacOS로이 작업을 수행 할 수도 있습니다. 물론 mysql을 종료하고 3 개의 테이블 파일을 복사 할 수 있습니다. 다음을 실행할 수 있습니다.

LOCK TABLES mydb.mytable READ;
SELECT SLEEP(86400);
UNLOCK TABLES;

하나의 ssh 세션에서 테이블을 읽기 전용으로 유지하고 24 시간 동안 잠금을 유지하십시오. 1 초 후에 다른 ssh 세션에서 복사를 수행하십시오. 그런 다음 24 시간 잠금으로 mysql 세션을 종료하십시오. 24 시간을 기다리지 않아도됩니다.

InnoDB 테이블

앞서 언급 한 인증 책에서 인용 한 내용을 바탕으로 특정 InnoDB 테이블을 백업하는 방법을 결정하는 많은 요소가 있습니다. 단순성, 명확성 및 간결성을 위해 --single-transaction 매개 변수를 사용하여 원하는 테이블의 mysqldump를 수행하여 테이블의 완벽한 시점 덤프를 수행하십시오. 하나의 테이블 만 원한다면 InnoDB 시맨틱을 사용하지 않아도됩니다. 선택한 덤프 서버에 해당 덤프 파일을 다시로드 할 수 있습니다.

두 개의 질문이 여기에 합쳐진 이후 (jcolebrand) : EDIT

DB 성능이 약간 저하되는 것을 원한다면 mysql이 여전히 ServerA에서 실행되는 동안에도 이전 서버 (ServerA)에서 새 서버 (ServerB)로 일련의 rsync를 수행 할 수 있습니다.

단계 01) ServerA와 동일한 버전의 mysql을 ServerB에 설치

단계 02) ServerA SET GLOBAL innodb_max_dirty_pages_pct = 0;에서 mysql과 약 10 분 동안 실행합니다 (이것은 InnoDB 버퍼 풀에서 더티 페이지를 제거합니다. 또한 mysql 종료를 더 빠르게 수행하는 데 도움이됩니다). 데이터베이스가 모두 MyISAM이면이 단계를 건너 뛸 수 있습니다.

단계 03) rsync --archive --verbose --stats --partial --progress --human-readable ServerA:/var/lib/mysql ServerB:/var/lib/mysql

단계 04) rsync가 1 분 미만이 될 때까지 단계 03을 반복하십시오.

service mysql stopServerA의 05 단계)

단계 06) 하나 더 rsync 수행

07 단계) scp ServerA:/etc/my.cnf ServerB:/etc/

service mysql startServerB의 08 단계)

service mysql startServerA의 08 단계) (선택 사항)

시도 해봐 !!!

경고

이와 같이 복제 슬레이브를 만들 수 있습니다. 마스터 /etc/my.cnf에 server-id를 명시 적으로 설정하고 슬레이브 /etc/my.cnf에 server-id에 다른 번호를 설정해야합니다.


29

전체 데이터베이스 스키마를 이동하고 첫 번째 데이터베이스를 기꺼이 중단하려는 경우 mysqldump가 필요하지 않으므로 전송시 일관성이 유지됩니다.

  1. 데이터베이스를 중지하거나 잠그십시오.
  2. mysql 데이터 파일이있는 디렉토리로 이동하십시오.
  3. 폴더 및 내용을 새 서버의 mysql 데이터 디렉토리로 전송하십시오.
  4. 데이터베이스 백업을 시작하십시오
  5. 새 서버에서 '데이터베이스 작성'명령을 발행하십시오.
  6. 사용자를 다시 작성하고 권한을 부여하십시오.

mysqldump는 사용자 및 사용 권한, 또는 단지 데이터를 처리하는 경우 기억이 없습니다 ...하지만이 경우에도,이는 방식으로 덤프를하고 & 그것을 실행하는 것보다 더 빨리. 스토리지 옵션 (innodb vs. myisam)을 변경 해야하는 경우 또는 mysql의 주요 버전을 변경하려는 경우 mysql 데이터베이스를 덤프 한 다음 다른 RDBMS에 다시 삽입 해야하는 경우에만 사용합니다 (그러나 그래도 4 ~ 5 사이 에이 작업을 수행했다고 생각합니다)


특히 sysadmin / DBA 인 경우 더욱 효율적입니다. BTW mysqldump를 사용 --all-databases하여 mysql 스키마 를 덤프합니다. 다음 머신에서 mysql을 시작하면 동일한 주요 MySQL 릴리스를 사용하여 데이터 폴더를 다른 머신으로 전송 한 경우 권한이 표시됩니다. (MySQL 5.5.x-MySQL 5.5.x, MySQL 5.1.x-MySQL 5.1.x, MySQL 5.0.x-MySQL 5.0.x)
RolandoMySQLDBA

4
@Joe mysqldump는 사용자와 권한이 mysql스키마 내에 저장되므로 사용자와 권한을 처리합니다 .
Shlomi Noach

이 접근 방식은 AWS와 같은 클라우드 호스팅에 특히 유용합니다. mysql을 중지하고 현재 서버에서 마운트 해제 및 분리 할 수 ​​있습니다. 새 서버에 연결하고 마운트하고 mysql을 시작하십시오. 볼륨이 동일한 서버 팜에 남아 있으면 복사 오버 헤드가 없습니다.
LateralFractal

12

특정 테이블을 이동하려면 다음을 시도하십시오.

mysqldump -u username -ppassword databasename tablename > databasename.tablename.sql

동일한 명령에서 더 많은 테이블 이름을 지정할 수 있습니다. 명령이 완료되면 databasename.tablename.sql 파일을 다른 서버로 이동 한 후 다음을 사용하여 복원하십시오.

mysql -u username -ppassword databasename < databasename.tablename.sql

back .sql 파일은 mysqldump 프로그램을 사용하여 작성 되며 복원은 mysql 로 직접 수행됩니다 .


7
  1. ssh 액세스 권한이 있으면 명령 행에서 mysqldump를 사용할 수 있습니다
  2. ssh 액세스 권한은 없지만 phpMyAdmin 액세스 권한이 있으면이를 사용하여 내보내기 / 가져 오기
  3. phpMyAdmin 액세스 권한이 없으면 덤프 및 가져올 편리한 PHP 스크립트가 있습니다 (그러나 내 경험으로는 phpMyAdmin만큼 신뢰할 수있는 스크립트를 찾지 못했습니다).

실제 데이터베이스 파일을 옮기는 가능성이있을 수 있지만 (내 설치의 경우 / var / lib / mysql에 있습니다) 실제로 어떻게 작동 / 작동하는지 확실하지 않습니다.


5

가동 중지 시간이 필요합니다. 네트워크 속도에 따라 다소 시간이 걸립니다. Linux / Unix에서 MySQL을 실행한다고 가정하겠습니다. 내가 사용하는 프로세스는 다음과 같습니다.

  1. 소스 호스트에서 mysql 데몬을 중지하십시오.
  2. 대상 호스트에서 tmp 폴더를 만들어 파일을 수신하십시오.
  3. 사용 화면을 사용자의 SSH 연결이 끊어 가야 살아남을 것입니다 쉘 세션을 만들 수 있습니다.
  4. rsync 를 사용 하여 호스트간에 파일을 전송하십시오. 뭔가 같은 : rsync를 -avhP 소스 사용자 @의 targethost : / 경로 /로 / 폴더 /
  5. 테스트 케이스를 실행하여 전송에서 아무것도 잃지 않았는지 확인하십시오.

그런 다음 평소와 같이 로컬 MySQL 설정을 진행하십시오.

* 참고 : rsync와 함께 -c 매개 변수를 사용하여 전송에 체크섬을 추가 할 수도 있지만 CPU 속도에 따라 sloooow가됩니다.


4

DTest의 방법이 우분투와 osx 사이의 복사에도 작동한다는 것을 확인할 수 있습니다.

덤프 또는 이와 유사한 작업을 수행하지 않고 모든 데이터베이스를 복사하려면

당신은 MySQL의 깨끗한 MySQL의이 있는지 확인 (MySQL의에서 다운로드 한 DMG 설치 http://cdn.mysql.com/Downloads/MySQL-5.1/mysql-5.1.63-osx10.6-x86_64.dmg 것을, () 아주 중요) 실행 한 적이 없습니다.

Mac의 / usr / local / mysql / data / 내용 위에있는 우분투 시스템에서 / var / lib / mysql / 폴더 내용을 복사하십시오. 우분투 컴퓨터에서 폴더를 가져 오려면 sudo를 사용해야했습니다.

sudo cp /var/lib/mysql /home/foouser/mysql_data_folder
sudo chown -R foouser /home/foouser/mysql_data_folder

scp를 사용하여 폴더를 복사했습니다.

시작하기 전에 Mac에서 mysql 폴더의 복사본을 만들어 아무것도 엉망이되지 않도록하십시오.

폴더를 복사 한 후 Mac 컴퓨터에서 다음을 수행하십시오.

sudo chown -R _mysql /usr/local/mysql/data/
sudo chgrp -R wheel /usr/local/mysql/data/
sudo chmod -R g+rx /usr/local/mysql/data/

시스템 환경 설정-> mysql의 환경 설정 창에서 mysql 서버를 처음 시작하십시오. 모든 사용자 및 데이터베이스가 이제 올바르게 설정되었습니다.

이것은 우분투 64 비트 11.10의 mysql 5.1.61 및 osx lion (macbook pro)의 mysql 5.1.63에서 작동했습니다.


4

이전의 모든 답변이 제대로 작동한다고 생각하지만 전송 중에 데이터베이스 이름을 설정하는 문제를 실제로 다루지는 않습니다.

이것이 내가 bash로 방금 한 방법입니다.

rsync보다 scp자주 사용하고 파일을 자주 압축하지 않으면 파일을 압축하지 않는 것이 좋습니다 .

내 소스 서버에서 :

me@web:~$ d=members
me@web:~$ mysqldump $d | gzip > $d.sql.gz
me@web:~$ scp -i .ssh/yourkeynamehere $d.sql.gz $sbox:$d.sql.gz

내 대상 서버에서 :

me@sandbox:~$ d1=members
me@sandbox:~$ d2=members_sb
me@sandbox:~$ mysqladmin create $d2
me@sandbox:~$ cat $d1.sql.gz | gunzip |  mysql $d2

진행 상황을 보려면 두 머신 중 하나에서 :

me@sandbox:~$ ls *.gz 
me@sandbox:~$ cat $d.sql.gz | gunzip |  less

이것은 모두 두 머신의 홈 디렉토리에 MySQL 구성 파일이 있고 권한을 설정 했다고 가정합니다 .

$ echo "
[client]
user=drupal6
password=metoknow
host=ord-mysql-001-sn.bananas.com
[mysql]
database=nz_drupal" > .my.cnf
$ chmod 0600 ~/.my.cnf

3

다른 mysql 서버 db로 옮기고 있습니까? 사용하는 경우 내보내기를 수행하십시오.

# mysqldump -u username -ppassword database_name > FILE.sql

mysqldump? 적은 양의 데이터를 처리 할 때입니까?
오 친 분

2
요즘에는 작고 큰 것이 주관적이라고 생각합니다. 질문의 제목을 보았을 때 데이터베이스가 "큰"것으로 간주되기 위해 20GB보다 훨씬 더 클 것으로 예상했습니다.
Aaron Bertrand

3

일반적인 리눅스 방법 :

/etc/init.d/mysqld stop
rsync -avz source_files destination
vi /etc/my.cnf

새 위치를 가리 키도록 mysqld 및 mysqld_safe (해당되는 경우)에 대한 datadir (및 소켓)을 편집 한 다음

/etc/init.d/mysql start

나는이 작업을 수행하는 데 필요한 최소한의 단계를 나열하지 않았기 때문에 개인적으로 가장 간단한 방법이라고 생각했기 때문에 이것을 게시했습니다.


2

아마도 이것이 더 좋은 방법 일 것입니다.

버전 1 : 데이터 파일 사본 (MYISAM 만 해당)

ssh server1
service mysql stop
cd $mysql-data-dir
rsync -avz dirs-or-files server2:$mysql-data-dir
service mysql start

ssh server2 서비스 재시작 mysql

  • 데이터베이스 파일이 읽기 전용 인 경우 서버 중지를 건너 뛸 수 있습니다.

버전 2 : mysqldump

최신 Xeon 또는 Opteron 프로세서에 pigz를 설치하십시오. 특히 2 개 이상의 CPU가있는 경우 gzip보다 훨씬 빠릅니다.

ssh server1 
mysqldump ... | pigz > backup-YYMDD.sql.gz
rsync backup-YYMDD.sql.gz server:location

ssh server2
pigz -dc location/backup-YYMDD.sql.gz | mysql ..

버전 3 : 마스터 / 슬레이브 + mysqldump / 파일 복사

In HA environment you should use the following trick:
setup slave server & do all backups from it
before backups - do "slave stop"; 
then do version 1 or version 2

스크립트:

touch full.start
mysqladmin -h slave-db stop-slave
echo "show slave status \G" | mysql -h slave-db > FULL/comfi-$NOW.master-position
/usr/bin/mysqldump -h slave-db --default-character-set=utf8 -A --opt --skip-lock-tables | pigz > "FULL/XXXX-$NOW.sql.gz"
mysqladmin -h slave-db start-slave
touch full.end

ln -fs "FULL/XXXX-$NOW.sql.gz" FULL.sql.gz

추신:

작은 테이블을 복사하려면 다음을 사용하십시오.

ssh server1 mysqldump 스키마 테이블 | ssh server2 mysql 스키마


2

한 서버에서 다른 서버로 전체 데이터베이스를 전송하는 두 가지 간단한 단계를 제안합니다.

1 단계 : mysqldump를 사용하여 소스 서버에서 데이터베이스의 전체 백업을 수행하십시오 .

2 단계 : rsync 명령을 사용 하여 전체 데이터베이스를 대상 서버로 전송할 수 있습니다 .

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