Linux / mysql: apakah aman untuk menyalin file mysql db dengan perintah cp dari satu db ke yang lain?

11

Sebagian besar panduan merekomendasikan mysqldump dan SQL sederhana untuk menyalin satu tabel ke anoter db. Bagaimana dengan linux shell cp? Bisakah saya lakukan begitu saja

cp /db1/mytable.frm /db2/mytable.frm

giorgio79
sumber

Jawaban:

21

Menyalin sangat sederhana untuk MyISAM dan sepenuhnya 100% berisiko (hampir bunuh diri) dengan InnoDB.

Dari pertanyaan Anda, Anda dibesarkan

cp /db1/mytable.frm /db2/mytable.frm

MyISAM

Ini boleh saja dilakukan. Namun, Anda tidak bisa hanya memindahkan .frm. Anda harus memindahkan semua komponen. Dari pertanyaan Anda, mari kita ambil tabel bernama db1.mytable. Dalam instalasi normal, tabel terletak di / var / lib / mysql / db1. Akan ada tiga file yang menyusun tabel.

  • /var/lib/mysql/db1/mytable.frm
  • /var/lib/mysql/db1/mytable.MYD (Tabel Database)
  • /var/lib/mysql/db1/mytable.MYI (Tabel Indeks)

Anda harus memindahkan ketiga file untuk memindahkan satu tabel. Jika semua tabel Anda menggunakan mesin penyimpanan MyISAM, Anda dapat mematikan mysql dan menyalinnya. Jika Anda hanya membuat salinan tabel dan menempatkannya di database lain, Anda harus melakukannya menggunakan SQL.

Misalnya, jika Anda ingin menyalin db1.mytable ke database db2, lakukan ini:

CREATE TABLE db2.mytable LIKE db1.mytable;
ALTER TABLE db2.mytable DISABLE KEYS;
INSERT INTO db2.mytable SELECT * FROM db1.mytable;
ALTER TABLE db2.mytable ENABLE KEYS;

Sekarang jika Anda hanya memindahkan tabel dari db1 ke db2, Anda dapat melakukan ini:

ALTER TABLE db1.mytable RENAME db2.mytable;

InnoDB

Menyalin sangat berbahaya karena infrastruktur tempat InnoDB bekerja. Ada dua infrastruktur dasar: 1) innodb_file_per_table dinonaktifkan dan 2) innodb_file_per_table diaktifkan

The Achilles 'Heel of InnoDB adalah file tablespace sistem yang dikenal sebagai ibdata1 (biasanya terletak di / var / lib / mysql). Apa yang terkandung dalam file itu ?

  • Halaman Data Tabel
  • Halaman Indeks Tabel
  • Tabel MetaData (daftar manajemen id tablespace)
  • Data MVCC (untuk mendukung Isolasi Transaksi dan Kepatuhan ACID )

InnoDB (innodb_file_per_table dinonaktifkan)

Dengan innodb_file_per_table dinonaktifkan, semua jenis info InnoDB ini tinggal di dalam ibdata1. Satu-satunya manifestasi dari setiap tabel InnoDB di luar ibdata1 adalah file .frm dari tabel InnoDB. Menyalin semua data InnoDB sekaligus membutuhkan menyalin semua / var / lib / mysql.

Menyalin tabel InnoDB individu tidak mungkin. Anda harus mysqldump untuk mengekstrak dump tabel sebagai representasi logis dari data dan definisi indeks yang sesuai. Anda kemudian akan memuat dump itu ke database lain di server yang sama atau server lain.

InnoDB (innodb_file_per_table diaktifkan)

Dengan innodb_file_per_table diaktifkan, data tabel dan indeksnya tinggal di folder database di sebelah file .frm. Misalnya, untuk tabel db1.mytable, manifestasi dari tabel InnoDB di luar ibdata1 adalah:

  • /var/lib/mysql/db1/mytable.frm
  • /var/lib/mysql/db1/mytable.ibd

Semua metadata untuk db1.mytable masih berada di ibdata1 dan sama sekali tidak ada jalan lain untuk itu . Redo log dan data MVCC juga masih hidup dengan ibdata1.

PERINGATAN (atau BAHAYA Robot akan berkata dalam Lost in Space )

Jika Anda berpikir untuk hanya menyalin file .frm dan .ibd, Anda berada di jalur untuk dunia yang terluka. Menyalin file .frm dan .ibd dari tabel InnoDB hanya baik jika Anda dapat menjamin bahwa id tablespace dari file .ibd cocok dengan entri id tablespace dalam metdata file ibdata1.

Saya menulis dua posting di DBA StackExchange tentang konsep id tablespace ini

Berikut ini adalah tautan yang sangat bagus tentang cara memasang kembali dan file .ibd ke ibdata1 jika id tablespace tidak cocok: http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file . Setelah membaca ini, Anda harus dapat melihat mengapa saya berkata hampir bunuh diri.

Untuk InnoDB Anda hanya perlu ini

CREATE TABLE db2.mytable LIKE db1.mytable;
INSERT INTO db2.mytable SELECT * FROM db1.mytable;

untuk membuat salinan tabel InnoDB. Jika Anda memigrasikannya ke server DB lain, gunakan mysqldump.

RolandoMySQLDBA
sumber
4
Respons lain mengatakan ini, jadi mungkin itu "tak perlu dikatakan," tapi tetap bagus untuk mengatakan: InnoDB terus menulis ke file bahkan jika database tidak digunakan, jadi menyalin file-file saat MySQL sedang berjalan hampir pasti menyebabkan korupsi! Anda dapat mematikan, mengambil snapshot sistem file, atau menggunakan Percona XtraBackup untuk mengatasi ini.
Baron Schwartz
1
Jawaban sempurna seperti biasa, @Rando! Satu-satunya pertanyaan besar yang saya miliki: Mengapa seseorang ingin melakukan ini sebagai lawan dari melakukan dump & import MySQL langsung? Saya mengasumsikan ukuran database semata, tetapi merasa itu harus dibesarkan.
JakeGould
1
@JakeGould Memuat skrip mysqldump ke mysql membutuhkan pemrosesan banyak SQL, memasukkan ribuan baris sekaligus, menggunakan siklus CPU, menguraikan rencana menjelaskan, membangun kembali indeks, memasukkan BTree, Leaf Node Splits, menyeimbangkan Kunci, memindai tabel untuk setiap non -unik untuk membangun) hanya untuk menghasilkan tabel yang sama. Dalam kasus MyISAM, mengapa menemukan kembali roda? Salin saja .frm, .MYDdan .MYI.
RolandoMySQLDBA
@JakeGould Dalam kasus InnoDB, saya telah menyalin database langsung yang menggunakan semua InnoDB dengan rsync. Setelah menyalin menggunakan rsync, saya menjalankan shutdown mysql, melakukan rsync terakhir, dan me-restart mysql tanpa masalah. Saya menulis posting seperti sebelumnya: serverfault.com/questions/288140/…
RolandoMySQLDBA
8

Menyalin seluruh data MySQL adalah teknik praktis, dengan anggapan layanan MySQL dihentikan dan Anda ingin seluruh server basis data disalin.

Ini adalah teknik yang berguna untuk memindahkan basis data dengan indeks besar, dan dump mysql tidak akan menyertakan indeks, yang perlu diregenerasi pada waktu impor. Saya menemukan teknik ini berguna ketika mengatur budak MySQL.

Menyalin file individual akan tergantung pada skema tabel yang digunakan, tetapi dalam kebanyakan situasi bukan solusi yang cocok.

Koperasi
sumber
2
Untuk menjelaskan: Anda tidak harus menghentikan layanan itu sendiri, jika sistem file Anda mampu, Anda bisa melakukan snapshot LVM dan membuat cadangannya; atau membekukan sistem file itu sendiri.
thinice
Selama seorang pribadi dapat makan downtime, ini adalah cara termudah. +1 !!!
RolandoMySQLDBA
2

Gunakan xtrabackup tanpa menggunakan pembungkus innobackupex dan Anda akan baik-baik saja pada basis data myisam dan innodb. Catatan, bahwa memulihkan basis data innodb tidak hanya menyalin kembali file bahkan jika Anda menggunakan xtrabackup. Katakan apakah Anda memerlukan info lebih lanjut

Gabor Vincze
sumber
1

Tidak, Anda harus mem-backup dengan mysqdump dan memulihkan dengan utilitas mysql cli, menyalin file frm Anda hanya menyalin struktur tabel dan bukan data di dalamnya, dan jika Anda menggunakan innodb, salin file secara langsung tidak mungkin.

Cara terbaik adalah membuang dan mengembalikan tabel.

aleroot
sumber