Bir MySQL tablosundan aynı veritabanının başka bir MySQL tablosuna kopyalama


15

Bir MySQL tablosunda yaklaşık 40 milyon satır var ve bu tabloyu aynı veritabanındaki başka bir tabloya kopyalamak istiyorum. Bunu yapmanın en etkili yolu nedir? Ne kadar zaman alacak (yaklaşık)?


Masanızın Motoru nedir?
Abdul Manaf

InnoDB Engine ..
Devashish Dixit

Yanıtlar:


23

Sahip olduğunuzu mydb.mytbve oluşturmak istediğinizi varsayalımmydb.mytbcopy

Bu kopyayı yapmak için beş (5) yaklaşımım var

YAKLAŞIM # 1

Gelen mysqlmüşteri, aşağıdaki çalıştırmak

USE mydb
CREATE TABLE mytbcopy LIKE mytb;
INSERT INTO mytbcopy SELECT * FROM mytb;

YAKLAŞIM # 2

MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
mysql ${MYSQL_CONN} -ANe"CREATE DATABASE IF NOT EXISTS test"
mysqldump ${MYSQL_CONN} mydb mytb | mysql ${MYSQL_CONN} -Dtest
mysql ${MYSQL_CONN} -ANe"ALTER TABLE test.mytb RENAME mydb.mytbcopy"

YAKLAŞIM # 3

DUMPFILE=/some/path/tabledata.sql
MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
mysql ${MYSQL_CONN} -ANe"CREATE DATABASE IF NOT EXISTS test"
mysqldump ${MYSQL_CONN} mydb mytb > ${DUMPFILE}
mysql ${MYSQL_CONN} -Dtest < ${DUMPFILE}
rm -f ${DUMPFILE}
mysql ${MYSQL_CONN} -ANe"ALTER TABLE test.mytb RENAME mydb.mytbcopy"

YAKLAŞIM # 4

MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
mysqldump ${MYSQL_CONN} mydb mytb | sed 's/mytb/mytbcopy' | mysql ${MYSQL_CONN} -Dmydb

YAKLAŞIM # 5

DUMPFILE=/some/path/tabledata.sql
MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
mysqldump ${MYSQL_CONN} mydb mytb | sed 's/mytb/mytbcopy' > ${DUMPFILE}
mysql ${MYSQL_CONN} -Dmydb < ${DUMPFILE}
rm -f ${DUMPFILE}

ANALİZ

  • YAKLAŞIM # 1 , adımlar açısından en kolay olanıdır, ancak 40 milyon satırı tek bir işleme itmeyi gerektirir. Bu InnoDB Depolama Motorundaki en fazla vergi olacaktır.
  • Diğer yaklaşımlar için, mysqldump binlerce satırlık mandrenlerde 40 milyon satır gönderecek
    • YAKLAŞIM # 2 ve YAKLAŞIM # 3 tabloyu test veritabanına mysqldump koyacaktır. Test veritabanında tablo oluşturulduktan sonra, daha sonra yeniden adlandırılır ve özgün veritabanına taşınır
    • APPROACH # 4 ve APPROACH # 5 INSERT komutlarını yansıtırken mysqldump'tan gelen akıma karşı sed kullanarak tabloyu yeniden adlandırdı
    • APPROACH # 2 ve APPROACH # 4 çıktı dosyası yerine boru kullanıyor
    • APPROACH # 3 ve APPROACH # 5 daha sonra yeniden yüklemek için bir outpuit dosyası kullanıyor

mydb.mytbZaten var olan bir tabloya kopyalamak istiyorsanız mydb.mytbcopyve iki tablonun özdeş yapıları vardır:

YAKLAŞIM # 6

INSERT INTO mytbcopy SELECT * FROM mytb;

Gibi #APPROACH 1 , #APPROACH 6 40000000 satır tek bir işlem olurdu

YAKLAŞIM # 7

MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
mysqldump ${MYSQL_CONN} -t mydb mytb | sed 's/mytb/mytbcopy' | mysql ${MYSQL_CONN} -Dmydb

Bu yaklaşımlar masayı düşürmez. Yalnızca INSERT'leri oluşturur

SONSÖZ

DB Server, tablo yapısı, dizin düzeni ve bunun gibi şeyler bilmiyorum çünkü size bir zaman tahmini veremem.

BİR ŞANS VER !!!


0

InnoDB tabloları, MyISAM * 'dan farklı olarak, veri sözlüğünün bir parçası olarak (ve birleştirme arabelleği gibi tablonun bağlı olduğu diğer yapılar) bellekte (sunucu çalışıyorsa) ve ortak / ana tablo alanı, diğer adı verilen büyük dosya ibdata1.

Percona Server> = 5.1 veya MySQL> = 5.6 kullanıyorsanız, tabloları doğrudan dosya sisteminden dışa ve içe aktarmanıza izin veren taşınabilir tablo alanları desteği vardır. İşte MySQL ve Percona için yöntem . Her iki durumda da, innodb_file_per_tableseçeneği içeren bir tablo oluşturmuş olmanız DISCARD TABLESPACE/IMPORT TABLESPACEve / veya Percona Xtrabakup'ın kullanımını içermeniz gerekir (dışa aktarmanın çevrimiçi olarak yapılmasını istiyorsanız). Percona Server veya Xtrabakup'un Windows için mevcut olmadığını lütfen unutmayın.

Bu yöntem, genel olarak, dosya sistemi komutlarını (cp, rsync) kullanarak dosyayı kopyalamak kadar hızlı olacaktır .

Geri yükleme için MySQL <5.6 (hacky bir şekilde) 'de çalışabileceği bazı durumlar olsa da, bir tablo kopyası için çalışmayacaktır. Bu durumlarda, bunu yapmanın bir yolu SQL kullanmaktır :

CREATE TABLE new_table LIKE old_table;
INSERT INTO new_table SELECT * FROM old_table;

Bu, InnoDB'nin yürütebileceği kadar hızlı Handler_read_rnd_nextve Handler_writeher satırda bir kez olacaktır. Bu yöntemi kullanırsanız, dayanıklılık seçeneklerini en azından geçici olarak devre dışı bıraktığınızdan ve büyük bir arabellek havuzunuz ve işlem günlüğünüz olduğundan emin olun. Bu koşullar altında, içe aktarma süresini azaltabilir, ancak kesinlikle belleğe tam olarak sığmaz, bu yüzden çok zaman bekleyin. Ayrıca, tek bir işlemde 40M satırları almaya çalışıyorsunuz, bu da sorunlara yol açabilir.

Gerçek tavsiyem, bu ikinci durumda, az önce bahsettiğim gibi bir işlem gerçekleştireceğinden, pt-archiver gibi bir şey kullanmak olacaktır, ancak işlem yükünü önleyerek "parçalar" halinde yapılacaktır ( daha hızlı olmamalı, ancak bir hata durumunda, tüm masayı geri almaya çalışmayacak, sonsuza dek sürecek). Bahsettiğiniz veri boyutları için bu muhtemelen en iyi yoldur.

Son seçenek, SELV INF OUTFILE / mysqldump ve LOAD DATA / mysqlimport kombinasyonu ile CSV (veya TSV) biçimini kullanarak dışa ve içe aktarmak olacaktır . Mysql'nin bazı eski sürümlerinde eşzamanlılık gerekiyorsa bu çok yaygın bir seçimdi, çünkü sql kullanmak daha büyük kilitler oluşturdu (doğru yapılırsa artık doğru değil). Mysqldump / import sadece serileştirilmiş bir şekilde çalıştığından, paralelleştirmek için seçenekleri araştırmanızı öneririm, büyük tablolar için çok yararlı.

Her durumda, çok sayıda farklı sorgu yürütmeniz (tek tek yürütülmesi, ayrıştırılması ve optimize edilmesi gerekir) en önemli darboğazınız olacağından, birden çok SQL cümlesinden kaçınmaya çalışın.


* MyISAM yapıları sıcak bir şekilde kopyalanamaz, ancak bunları geçici olarak diske senkronize etmek çok kolaydır FTWRL.


0

şemadaki verileri bir tablodan diğerine taşıma

create table your_table_name select * from old_schema_table;

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.