Bir veritabanını bir sunucudan diğerine nasıl taşıyabilirim?


136

MySQL tablolarını bir fiziksel sunucudan diğerine nasıl taşıyabilirim?

Bu tam senaryo gibi: Innodb tablosu kullanan ve yaklaşık 20GB boyutunda olan bir MySQL sunucum var.

Bunu yeni bir sunucuya taşımak istiyorum, bunu yapmanın en etkili yolu nedir?


4
Xtrabackup percona.com/docs/wiki/… 'i kullanırdım Çok kopyalamak gibi bir şey ancak sunucuyu çalışır durumda tutabilir ve esas olarak innodb tabloları kullandığınızı varsayabilir (ki, sahip olduğunuzu söyleyebilirsiniz), "sıcak" olarak kabul edebilirsiniz yanı sıra yedekleme.
Jonathan

Bu aracı kullanan diğer insanlardan faydalanmıyorum. Ücretsizdir ve açık kaynaklıdır ve bir şirket tarafından yapılmış olmasına rağmen, bu şirketten destek almayı düşünmenize gerek kalmayacak kadar kolaydır.
Jonathan

Yanıtlar:


80

En sevdiğim yol, bir sqldump komutunu bir sql komutuna yönlendirmektir. Tüm veritabanlarını veya belirli bir tane yapabilirsiniz. Yani, örneğin,

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

Tüm veritabanlarını ile yapabilirsiniz

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

Tek sorun, veritabanının çok büyük olması ve borunun çökmesidir. Bu durumda, tabloyu tablo veya aşağıda belirtilen diğer yöntemlerden herhangi birini kullanarak yapabilirsiniz.


4
İpucu: Hiçbir veritabanı uzak bağlantılara izin vermiyorsa, üzerinden geçin netcat.
Bart van Heukelom

1
Bunun benim için çalışması için uzak sunucuda aynı isimde boş bir veritabanı oluşturmalı ve ardından bu veritabanının adını komutun sonuna eklemeliydim.
Zugwalt

1
Bu zarif, ancak 20GB veritabanı için yeterince hızlı sıkıştırma olmadan.
Daddy32,

Bu çözüm yalnızca tamamen denetimli bir ağ için iyidir (eğer güvenli bir özel ağdaysa ve oku: interneti değil)! Ancak hızlı ve kolay çözüm!
tdaget

Bu yıldırım hızlı! Fakat @ Zugwalt'ın söylediği de benim için doğruydu. Veritabanını (boş) eklediğinize kadar komut çalışmadı, komutun sonuna veritabanı adını ekledi.
Skeets

65

Geçenlerde 30GB veri tabanını aşağıdaki zorlukla taşıdım:

Eski sunucu

  • MySQL sunucusunu durdur
  • Datadir içeriğini diskteki başka bir yere kopyala ( ~/mysqldata/*)
  • MySQL sunucusunu yeniden başlatın (aksama süresi 10-15 dakika idi)
  • verileri sıkıştır ( tar -czvf mysqldata.tar.gz ~/mysqldata)
  • sıkıştırılmış dosyayı yeni sunucuya kopyala

Yeni sunucu

  • mysql'i kurun (başlama)
  • sıkıştırılmış dosyayı aç ( tar -xzvf mysqldata.tar.gz)
  • için mysqldata içeriğini taşımak datadir
  • İnnodb_log_file_size dosyanızın yeni sunucuda aynı olduğundan emin olun, yoksa eski günlük dosyalarını kopyalamayın ( mysql bunları üretecektir )
  • MySQL'i Başlat

1
Sıkıştırma / açma işleminden sonra kopyayı atlayın. Ağ üzerinden ağ üzerinden ssh kullanarak akış yapın veya (yalnızca güvenli bir özel ağda okuyorsanız: interneti değil ) şifrelemenin genel giderinden kaçınmak için netcat kullanın. Ayrıca eğer yerel bir ağda gzipingi atlarsanız, hızlı bir ağ
borunuz varsa

Bu hem innodb hem de myisam için işe yarıyor mu? Ayrıca, mysql kullanıcıları da datadir içindedir.
giorgio79

2
@ giorgio79, siz de ibdata dosyalarını taşıdığınız sürece emin olun. Varsayılan olarak bunlar datadir içindedir. MySQL kullanıcıları, bir kullanıcı tablo alanındaki mysql klasöründe saklanır.
Derek Downey

2
Bu prosedür Windows'tan Linux'a geçmek için çalışacak mı?
ypercube

2
@ TypoCubeᵀᴹ cevap vermemiz iki yıldan fazla sürdüğü için üzgünüm, ancak birisinin kesin olarak "Evet, Windows'tan Linux'a çalışıyor" dediğini söylememe yardımcı olurdu. Benim durumumda, ben gittim , Windows Server 2012 R2 den üzere Cent OS (Red Hat 4.8.5-11) . Spesifik mysql versiyonu Maria DB 10.1 idi . Öngörüldüğü gibi, her iki mysql hizmetini durdurdum, veri dizinini yeniden başlattım ve yeni sunucudaki mysql hizmetini başlattıktan sonra, tüm veritabanları, veritabanı tabloları ve veritabanı kullanıcıları tamamen bozulmuştu.
WEBjuju

30

Göre MySQL 5.0 Belgelendirme Eğitim Kılavuzu , Bölüm 32 Bölüm 32.3.4, Sayfalar 456.457 tarif İkili Taşınabilirlik için şartlar dışarı şunları yanınızda:

Bir makinede yapılmış bir ikili yedekleme almak ve farklı bir mimariye sahip başka bir makinede kullanmak istiyorsanız, ikili taşınabilirlik önemlidir. Örneğin, ikili yedekleme kullanmak, veritabanlarını bir MySQL sunucusundan diğerine kopyalamanın bir yoludur.

MyISAM için, ikili taşınabilirlik, bir MyISAM tablosu için dosyaları doğrudan bir MySQL sunucusundan diğerine farklı bir makinede kopyalayabileceğiniz ve ikinci sunucunun da masaya erişebileceği anlamına gelir.

InnoDB için ikili taşınabilirlik, tablo alanı dosyalarını bir makinedeki MySQL sunucusundan başka bir makineye doğrudan başka bir sunucuya kopyalayabileceğiniz ve ikinci sunucunun tablo alanına erişebileceği anlamına gelir. Varsayılan olarak, bir sunucu tarafından yönetilen tüm InnoDB tabloları tablo alanında birlikte depolanır; bu nedenle tablo alanının taşınabilirliği, tüm bireysel InnoDB tablolarının taşınabilir olup olmadığının bir işlevidir. Bir tablo bile taşınabilir değilse, tablo alanı da değildir.

İki koşul karşılanırsa, MyISAM tabloları ve InnoDB tablo alanları, bir ana bilgisayardan diğerine ikili taşınabilir.

  • Her iki makine de ikiin tamamlayıcı tamsayı aritmetiğini kullanmalıdır
  • Her iki makinede de IEEE kayan nokta formatı kullanılmalı, aksi halde tablolarda kayan nokta sütunları (FLOAT veya DOUBLE) bulunmamalıdır

Uygulamada, bu iki koşul çok az kısıtlama getirmektedir. İkinin tamamlayıcı tamsayı aritmetiği ve IEEE kayan nokta formatı modern donanımdaki normlardır. InnoDB ikili taşınabilirliği için üçüncü bir koşul, tablolar ve veritabanları için küçük harfler kullanmanız gerektiğidir. Bunun nedeni InnoDB'nin bu adları dahili olarak (veri sözlüğünde) küçük harflerle Windows'ta saklamasıdır. Küçük harf adlarını kullanmak, küçük harf adlarını zorlamak için Windows ve Unix arasında ikili taşınabilirlik sağlar, bir seçenek dosyasına aşağıdaki satırları koyabilirsiniz:

[mysqld]
lower_case_table_names=1

InnoDB'yi tablo başına tablo alanı kullanacak şekilde yapılandırırsanız, ikili taşınabilirlik için koşullar InnoDB tabloları için .ibd dosyalarını içerecek şekilde genişletilir. (Paylaşılan tablo alanları için koşullar, tüm InnoDB tablolarıyla ilgili bilgileri depolayan veri sözlüğünü içerdiğinden hala geçerlidir.)

İkili taşınabilirlik için koşullar yerine getirilmezse, bazı metin formatlarını (örneğin, mysqldump ile) kullanarak ve bunları hedef sunucuya yeniden yükleyerek MyISAM veya InnoDB tablolarını bir sunucudan diğerine kopyalayabilirsiniz.

Tek tek tabloları taşımak için depolama motoruna dayanan iki ana yol vardır.

Verilen örnek için aşağıdakileri varsayalım:

  1. datadir / var / lib / mysql
  2. mydb adı verilen veritabanı
  3. mydb veritabanındaki tablo mytable denir .

MyISAM tabloları

Mydb.mytable, MyISAM depolama motorunu kullanıyorsa, tablo fiziksel olarak üç ayrı dosya olarak gösterilecektir.

  1. /var/lib/mysql/mydb/mytable.frm (.frm dosyası)
  2. /var/lib/mysql/mydb/mytable.MYD (.MYD dosyası)
  3. /var/lib/mysql/mydb/mytable.MYI (.MYI dosyası)


.Frm tablo yapısını içerir.. MYD tablo verilerini
içerir. .MYI tablo dizin sayfasını içerir

Bu dosyalar, tabloyu mysql'deki mantıksal bir noktadan temsil etmek için birbirine bağlı olarak kullanılır. Bu dosyaya başka bir mantıksal ilişkilendirme bağlanmadığından, bir tabloyu bir DB sunucusundan diğerine geçirme. Bunu bir Windows sunucusundan bir Linux Sunucusuna veya MacOS'a bile yapabilirsiniz. Tabii ki, mysql kapatma ve 3 tablo dosyalarını kopyalayabilirsiniz. Aşağıdakileri çalıştırabilirsiniz:

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

Bir ssh oturumunda tabloyu salt okunur şekilde tutmak ve kilidi 24 saat boyunca tutmak için. Bir saniye sonra, kopyayı başka bir ssh oturumunda gerçekleştirin. Sonra 24 saat kilidi ile MySQL oturumu öldür. 24 saat beklemene gerek yok.

InnoDB masaları

Sertifika kitabında belirtilen alıntıya dayanarak, belirli bir InnoDB tablosunun nasıl yedekleneceğini belirleyen birçok faktör vardır. Basitlik, açıklık ve kısalık adına, tablonun tam zamanında bir dökümü için - tek işlem parametrelerini kullanarak istenen tablonun bir miktarını doldurun. Sadece bir tablo istiyorsanız, InnoDB semantics ile kendinizi cnc işlemeye gerek yok. Bu boş dosyayı, seçtiğiniz herhangi bir MySQL sunucusuna yeniden yükleyebilirsiniz.

İki soru burada birleştirildiğinden beri (jcolebrand): EDIT

Bazı yavaş DB performanslarıyla yaşamaya istekli değilseniz, mysql hala SunucuA'da çalışırken bile eski sunucudan (SunucuA) yeni sunucuya (SunucuB) bir dizi rsync gerçekleştirebilirsiniz.

Adım 01) aynı mysql sürümünü ServerA'daki ServerB'ye kurun

Adım 02) SunucuA'da, SET GLOBAL innodb_max_dirty_pages_pct = 0;mysql ve yaklaşık 10 dakika çalıştırın (Bu, InnoDB Tampon Havuzundan kirli sayfaları temizler. Aynı zamanda mysql kapanmasını daha hızlı gerçekleştirmeye de yardımcı olur) Veritabanınız tamamen MyISAM ise, bu adımı atlayabilirsiniz.

Adım 03) rsync --archive --verbose --stats --partial --progress --human-readable ServerA:/var/lib/mysql ServerB:/var/lib/mysql

Adım 04) Bir rsync 1 dakikadan az sürene kadar 03 numaralı adımı tekrarlayın.

Adım 05) service mysql stopServerA'da

Adım 06) Bir rsync daha yapın

Adım 07) scp ServerA:/etc/my.cnf ServerB:/etc/

Adım 08) service mysql startSunucuB'de

Adım 08) service mysql startServerA'da (isteğe bağlı)

Bir şans ver !!!

UYARI

Böyle bir çoğaltma kölesi oluşturabilirsiniz. Sunucu kimliğinin master / etc/my.cnf dosyasında ve sunucu / id için de köle /etc/my.cnf dosyasında farklı bir sayı koyduğunu unutmayın.


29

Tüm bir veritabanı şemasını hareket ettiriyorsanız, mysqldump'a bile ihtiyacınız yoktur ve ilk veritabanını durdurmaya istekli olursunuz (yani aktarılırken tutarlı olur)

  1. Veritabanını durdur (veya kilitle)
  2. MySQL veri dosyalarının bulunduğu dizine gidin.
  3. Klasör (ve içeriği) üzerinden yeni sunucunun mysql veri dizinine aktarın
  4. Veritabanını yedeklemeye başla
  5. Yeni sunucuda 'veritabanı oluştur' komutunu verin.
  6. Kullanıcıları yeniden oluşturun ve izinleri verin.

Mysqldump kullanıcılarını ve izinleri, ya da sadece veri işleme eğer hatırlayamıyorum ... ama öyle olsa bile, bu yolu bir dökümü yapıyor ve onu çalıştıran daha hızlı. Bunu sadece bir mysql veri tabanını boşaltmak gerekirse, diğer bazı RDBMS'lere tekrar eklemek için kullanırsam, depolama seçeneklerini değiştirmem gerekirse (innodb vs. myisam) veya belki de mysql'nin ana versinlerini değiştiriyor olsaydım (ama Sanırım bunu 4-5 arasında yaptım.


Bu, özellikle de bir sysadmin / DBA ise daha verimlidir. BTW mysqldump kullanarak --all-databasesmysql şemasını döker. MySQL'in bir sonraki makinede başlatılması, veri klasörünü diğer makineye aynı büyük MySQL sürümüyle aktarmanız şartıyla izinleri getirir. (MySQL 5.5.x MySQL 5.5.x MySQL 5.1.x'ten MySQL 5.1.x MySQL 5.0.x MySQL 5.0.x)
RolandoMySQLDBA

4
@Joe, evet, şema mysqldumpiçerisinde depolandıkları için kullanıcıları ve izinleri ele alır mysql.
Shlomi Noach

Bu yaklaşım özellikle AWS gibi bulut barındırmada kullanışlıdır. MySQL'i durdurabilir, mevcut sunucudan ayırabilir ve çıkarabilirsiniz; takın ve yeni sunucuya bağlayın ve mysql'i başlatın. Aynı sunucu grubunda birimde kalırsa, ek yük yok.
LateralFractal

12

Sadece belirli bir tabloyu taşımak istiyorsanız şunu deneyin:

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

Aynı komutla, yukarıda daha fazla tablo adı belirleyebilirsiniz. Komut tamamlandıktan sonra, databasename.tablename.sql dosyasını diğer sunucuya taşıyın ve aşağıdakileri kullanarak geri yükleyin:

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

Geri .sql dosyasının mysqldump programı kullanılarak oluşturulduğunu ve geri yükleme işleminin doğrudan mysql'ye yapıldığını unutmayın .


7
  1. Eğer ssh erişiminiz varsa, komut satırından mysqldump kullanabilirsiniz.
  2. Eğer ssh erişiminiz yok, fakat phpMyAdmin erişiminiz varsa, onu almak / vermek için kullanabilirsiniz
  3. Eğer phpMyAdmin erişiminiz yoksa, boşaltıp içe aktaracak bazı kullanışlı php scriptleri var (ancak kendi tecrübelerime göre phpMyAdmin kadar güvenilir bir tane bulamadım).

Asıl veritabanı dosyalarını taşıdığınız yerde bu olasılık olabilir (kurulumum için / var / lib / mysql konumunda bulunurlar), ancak nasıl davranacağını / çalışacağını kesin olarak söyleyemem.


5

Bir kesinti yapmanız gerekecek. Ağ hızınızın ne olduğuna bağlı olarak biraz zaman alacaktır. Linux / Unix'te MySQL kullandığınızı varsayacağım. İşte kullandığım süreç:

  1. Kaynak ana bilgisayarda mysql arka planını durdurun.
  2. Dosyaları almak için hedef ana makinenizde bir tmp klasörü oluşturun.
  3. Ssh bağlantınız koparsa hayatta kalacak bir kabuk seansı yapmak için ekranı kullanın .
  4. Dosyaları ana bilgisayarlar arasında aktarmak için rsync kullanın . Gibi bir şey: rsync -avhP kaynak user @ targethost: / path / to / folder /
  5. Transferde hiçbir şey kaybetmediğinizden emin olmak için test vakalarınızı çalıştırın.

Ardından, yerel MySQL kurulumunu yaparken normal şekilde devam edin.

* Not: Aktarıma sağlama toplamı eklemek için -c parametresini rsync ile de kullanabilirsiniz, ancak bu işlem CPU hızına bağlı olarak değişmeyecektir.


4

DTest'in yönteminin ubuntu ve osx arasında kopyalama yapmak için de işe yaradığını onaylayabilirim.

Tüm veritabanlarını herhangi bir boşaltma veya benzeri işlem yapmak zorunda kalmadan kopyalamak için:

Temiz bir mysql mysql olduğundan emin olun (mysql http://cdn.mysql.com/Downloads/MySQL-5.1/mysql-5.1.63-osx10.6-x86_64.dmg adresinden indirilen dmg’yi kurun ), (VERY (ÖNEMLİ) hiç çalıştırılmadı.

/ Var / lib / mysql / folder içeriğini ubuntu makinesinden, mac'ta / usr / local / mysql / data / content dizinine kopyalayın. Ubuntu makinede klasör almak için erişim sudo kullanmak zorunda kaldı:

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

Klasörü scp kullanarak kopyaladım.

Başlamadan önce, hiçbir şeyi mahvetmediğinizden emin olmak için mac üzerindeki mysql klasörünün bir kopyasını alın.

Klasörü kopyaladıktan sonra, mac makinede aşağıdakileri yapın:

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 sunucusunu ilk kez başlatın (Sistem Tercihleri-> MySQL altındaki tercihler bölmesinden). Tüm kullanıcılar ve veritabanları şimdi doğru şekilde kurulmalıdır.

Bu, 64 bit 11.10 ubuntudaki mysql 5.1.61 ve osx aslanında (macbook pro) mysql 5.1.63 ile çalıştı.


4

Daha önceki cevapların hepsinin muhtemelen iyi çalıştığını düşünüyorum ancak aktarma sırasında bir veritabanı adı belirleme konusunu gerçekten ele alma.

İşte bu şekilde bash ile yaptım:

Sık sık kullanıyorsanız , dosyayı kullanmaktan rsyncdaha iyi bir şekilde kullanmaktan scpve dosyayı sıkıştırmamaktan daha iyi olabilir .

Kaynak sunucumda:

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

Hedef sunucumda:

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

İlerlemeyi görmek için her iki makinede:

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

Bunların hepsi , her iki makinedeki ana dizininizde MySQL yapılandırma dosyasına sahip olduğunuzu ve izinleri ayarladığınızı varsayar :

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

3

Başka bir mysql sunucusuna mı taşınıyorsunuz db? eğer öyleyse, üzerinde ihracat yap

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

Mysqldump? O zaman az miktarda veriyle mi uğraşıyorsunuz?
Oh Chin Boon

2
Bu günlerde küçük / büyük sanırım oldukça öznel. Sorunun başlığını gördüğümde, veritabanının "büyük" olarak kabul edilmek üzere 20 gb'den daha büyük olmasını bekliyordum ...
Aaron Bertrand

3

Genel linux yöntemi:

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

yeni konuma işaret etmek için hem mysqld hem de mysqld_safe (varsa) için datadir'i (ve soketi) düzenleyin, ardından

/etc/init.d/mysql start

Bunu gönderdim çünkü hiç kimse basitçe bunu yapmak için en az adım atılacak gibi görünmüyor ve bunun kişisel olarak en basit yol olduğunu düşünüyorum.


2

Belki de bunu yapmanın daha iyi bir yolu:

Sürüm 1 : veri dosyalarının kopyası (yalnızca MYISAM)

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

ssh server2 hizmeti mysql yeniden başlat

  • Veritabanı dosyalarınız salt okunursa sunucuyu durdurmayı atlayabilirsiniz.

Sürüm 2 : mysqldump

Pigz'i takın - modern Xeon veya Opteron işlemcilere, özellikle 2 veya daha fazla CPU'nuz olduğunda, gzip'ten çok daha hızlıdır.

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 ..

Sürüm 3 : ana / köle + mysqldump / dosya kopyalama

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

senaryo:

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

Not:

küçük tabloları kopyalamak için kullanın:

ssh server1 mysqldump şema tablosu | ssh server2 mysql şeması


2

Tüm veritabanını bir sunucudan diğerine aktarmak için iki basit adımı öneririm.

Adım 1 : mysqldump kullanarak kaynak sunucudaki veritabanlarının tam yedeğini alın .

Adım 2 : Tüm veritabanlarını hedef sunucuya aktarmak için rsync komutunu kullanabilirsiniz .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.