Linux / mysql: ปลอดภัยไหมที่จะคัดลอกไฟล์ mysql db ด้วยคำสั่ง cp จากฐานข้อมูลหนึ่งไปยังอีกชุดหนึ่ง?


11

คู่มือส่วนใหญ่แนะนำ mysqldump และ SQL อย่างง่ายสำหรับการคัดลอกหนึ่งตารางไปยัง anoter db linux shell cp เป็นอย่างไร? ฉันสามารถทำได้

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

คำตอบ:


21

การคัดลอกนั้นง่ายมากสำหรับ MyISAM และมีความเสี่ยง 100% (ใกล้กับการฆ่าตัวตาย) ด้วย InnoDB

จากคำถามของคุณคุณนำมา

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

MyISAM

นี่เป็นสิ่งที่ต้องทำ อย่างไรก็ตามคุณไม่สามารถย้าย. frm คุณต้องย้ายส่วนประกอบทั้งหมด จากคำถามที่คุณถามมาลองตารางที่เรียกว่า db1.mytable ในการติดตั้งปกติตารางจะอยู่ใน / var / lib / mysql / db1 จะมีสามไฟล์ประกอบขึ้นเป็นตาราง

  • /var/lib/mysql/db1/mytable.frm
  • /var/lib/mysql/db1/mytable.MYD (ฐานข้อมูลตาราง)
  • /var/lib/mysql/db1/mytable.MYI (ดัชนีตาราง)

คุณต้องย้ายทั้งสามไฟล์เพื่อย้ายหนึ่งตาราง หากตารางทั้งหมดของคุณใช้เอนจิ้นการจัดเก็บ MyISAM คุณสามารถปิด mysql และคัดลอกออกไป หากคุณเพียงแค่ทำสำเนาของตารางและวางไว้ในฐานข้อมูลอื่นคุณควรใช้ SQL

ตัวอย่างเช่นหากคุณต้องการคัดลอก db1.mytable ไปยังฐานข้อมูล db2 ให้ทำสิ่งนี้:

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;

ตอนนี้ถ้าคุณเพิ่งย้ายตารางจาก db1 ไปยัง db2 คุณสามารถทำได้:

ALTER TABLE db1.mytable RENAME db2.mytable;

InnoDB

การคัดลอกนั้นอันตรายมากเนื่องจากโครงสร้างพื้นฐานที่ InnoDB ทำงาน โครงสร้างพื้นฐานพื้นฐานมีสองแบบ: 1) ปิดใช้งาน innodb_file_per_table และ 2) เปิดใช้งาน innodb_file_per_table

Achilles 'Heel of InnoDB เป็นไฟล์ tablespace ของระบบที่รู้จักกันในชื่อ ibdata1 (โดยปกติจะอยู่ใน / var / lib / mysql) สิ่งที่มีอยู่ในแฟ้มที่ ?

  • หน้าข้อมูลตาราง
  • หน้าดัชนีตาราง
  • ตาราง MetaData (รายการการจัดการรหัสพื้นที่ตาราง)
  • ข้อมูล MVCC (เพื่อสนับสนุนการแยกธุรกรรมและความสอดคล้องกับกรด )

InnoDB (innodb_file_per_table ถูกปิดใช้งาน)

เมื่อปิดใช้งาน innodb_file_per_table ข้อมูล InnoDB เหล่านี้ทั้งหมดจะเผยแพร่ภายใน ibdata1 การรวมตัวกันของตาราง InnoDB ใด ๆ ภายนอก ibdata1 คือไฟล์. frm ของตาราง InnoDB การคัดลอกข้อมูล InnoDB ทั้งหมดในครั้งเดียวจำเป็นต้องคัดลอกทั้งหมดของ / var / lib / mysql

การคัดลอกตาราง InnoDB แต่ละรายการเป็นไปไม่ได้ทั้งหมด คุณต้อง mysqldump เพื่อแยกการถ่ายโอนข้อมูลของตารางเป็นการแสดงตรรกะของข้อมูลและคำนิยามดัชนีที่สอดคล้องกัน จากนั้นคุณจะโหลดการถ่ายโอนข้อมูลนั้นไปยังฐานข้อมูลอื่นบนเซิร์ฟเวอร์เดียวกันหรือเซิร์ฟเวอร์อื่น

InnoDB (เปิดใช้งาน innodb_file_per_table)

เมื่อเปิดใช้งาน innodb_file_per_table ข้อมูลในตารางและดัชนีจะอยู่ในโฟลเดอร์ฐานข้อมูลถัดจากไฟล์. frm ตัวอย่างเช่นสำหรับตาราง db1.mytable การรวมตัวกันของตาราง InnoDB ภายนอก ibdata1 จะเป็น:

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

ข้อมูลเมตาทั้งหมดสำหรับ db1.mytable ยังคงอยู่ใน ibdata1 และไม่มีทางแก้ไข ทำซ้ำบันทึกและข้อมูล MVCC ยังคงอยู่กับ ibdata1

คำเตือน (หรืออันตรายเป็นหุ่นยนต์จะพูดในที่หายไปในอวกาศ )

หากคุณกำลังคิดที่จะคัดลอกไฟล์. frm และ. ibd คุณจะเข้าสู่โลกแห่งความเจ็บปวด การคัดลอกไฟล์. frm และ. ibd ของตาราง InnoDB จะทำได้ก็ต่อเมื่อคุณสามารถรับประกันได้ว่า tablespace id ของไฟล์. ibd ตรงกับรายการ tablespace id ใน metdata ของไฟล์ ibdata1 ทุกประการ

ฉันเขียนสองโพสต์ใน DBA StackExchange เกี่ยวกับแนวคิด id tablespace นี้

นี่คือการเชื่อมโยงที่ดีเกี่ยวกับวิธีการใส่กลับเข้าไปและไฟล์ .ibd เพื่อ ibdata1 ในกรณีของรหัส tablespace ไม่ตรงกัน: http://www.chriscalender.com/?tag=innodb-error-tablespace-id-in-file หลังจากอ่านบทความนี้แล้วคุณควรจะเห็นว่าทำไมฉันถึงพูดถึงการฆ่าตัวตาย

สำหรับ InnoDB คุณจะต้องทำสิ่งนี้เท่านั้น

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

เพื่อสร้างสำเนาของตาราง InnoDB หากคุณย้ายข้อมูลไปยังเซิร์ฟเวอร์ฐานข้อมูลอื่นให้ใช้ mysqldump


4
คำตอบอื่น ๆ บอกว่านี่อาจจะเป็น "ไปโดยไม่บอก" แต่ก็เป็นเรื่องดีที่จะกล่าวต่อไป: InnoDB ยังคงเขียนไปยังไฟล์แม้ว่าฐานข้อมูลไม่ได้ใช้งานอยู่ดังนั้นการคัดลอกไฟล์ในขณะที่ MySQL กำลังทำงานอยู่ คุณสามารถปิดตัวเองถ่ายภาพระบบไฟล์หรือใช้ Percona XtraBackup เพื่อแก้ไขปัญหานี้
บารอน Schwartz

1
คำตอบที่ยอดเยี่ยมเช่นเคย @Rolando! คำถามใหญ่เพียงข้อเดียวที่ฉันมี: ทำไมมีคนต้องการทำเช่นนี้แทนที่จะทำ MySQL dump & import แบบตรง? ฉันถือว่าขนาดฐานข้อมูลที่แท้จริง แต่รู้สึกว่าควรจะนำขึ้น
JakeGould

1
@ JakeGould การโหลดสคริปต์ mysqldump ลงใน mysql นั้นจำเป็นต้องทำการประมวลผล SQL จำนวนมากในแต่ละครั้งโดยใช้หลาย ๆ แถวโดยใช้รอบการทำงานของ CPU, cranking out อธิบายแผนการสร้างดัชนีใหม่ (การแทรก BTree, การแยกโหนดโหนด -unique to build) เพียงเพื่อสร้างตารางเดียวกัน ในกรณีของ MyISAM ทำไมต้องคิดค้นล้อใหม่ เพียงคัดลอกของ.frm, และ.MYD .MYI
RolandoMySQLDBA

@ JakeGould ในกรณีของ InnoDB ฉันได้คัดลอกฐานข้อมูลสดที่ใช้งาน InnoDB ทั้งหมดพร้อม rsync หลังจากคัดลอกโดยใช้ rsync ฉันได้ทำการปิด mysql, ทำ rsync สุดท้ายและเริ่ม mysql ใหม่โดยไม่มีปัญหา ฉันเขียนโพสต์ก่อนหน้านี้: serverfault.com/questions/288140/…
RolandoMySQLDBA

8

การคัดลอกฐานข้อมูล MySQL ทั้งหมดเป็นเทคนิคที่ใช้งานได้จริงสมมติว่าบริการ MySQL หยุดทำงานและคุณต้องการคัดลอกเซิร์ฟเวอร์ฐานข้อมูลทั้งหมด

นี่เป็นเทคนิคที่มีประโยชน์สำหรับการย้ายฐานข้อมูลที่มีดัชนีขนาดใหญ่และการถ่ายโอนข้อมูล mysql จะไม่รวมดัชนีซึ่งจะต้องมีการสร้างใหม่ในเวลานำเข้า ฉันพบเทคนิคนี้มีประโยชน์เมื่อตั้งค่า MySQL ทาส

การคัดลอกแต่ละไฟล์จะขึ้นอยู่กับสคีมาที่ใช้งานอยู่ แต่ในสถานการณ์ส่วนใหญ่ไม่ใช่วิธีแก้ปัญหาที่เหมาะสม


2
ในการอธิบาย: คุณไม่จำเป็นต้องหยุดบริการตามลำดับหากระบบไฟล์ของคุณมีความสามารถคุณสามารถทำการถ่ายภาพแบบ LVM และสำรองข้อมูลนั้นได้ หรือหยุดระบบไฟล์เอง
thinice

ตราบใดที่ส่วนบุคคลสามารถกินการหยุดทำงานนี่เป็นวิธีที่ง่ายที่สุด +1 !!!
RolandoMySQLDBA

2

ใช้xtrabackup w / ow w / o wrapper innobackupex และคุณจะใช้ได้ทั้งบนฐานข้อมูล myisam และ innodb หมายเหตุการกู้คืนฐานข้อมูล innodb ไม่เพียง แต่คัดลอกไฟล์กลับแม้ว่าคุณจะใช้ xtrabackup บอกถ้าคุณต้องการข้อมูลเพิ่มเติม


1

ไม่คุณควรสำรองข้อมูลด้วย mysqdump และกู้คืนด้วยยูทิลิตี้ mysql cli คัดลอกไฟล์ frm ที่คุณกำลังคัดลอกเฉพาะโครงสร้างตารางและไม่ใช่ข้อมูลที่อยู่ภายในและหากคุณอยู่ใน innodb ก็อปปี้ไฟล์โดยตรงไม่สามารถทำได้

วิธีที่ดีที่สุดคือถ่ายโอนข้อมูลและเรียกคืนตาราง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.