ฉันจะย้ายตาราง MySQL จากเซิร์ฟเวอร์จริงหนึ่งไปยังอีกเซิร์ฟเวอร์หนึ่งได้อย่างไร
เช่นสถานการณ์ที่แน่นอน: ฉันมีเซิร์ฟเวอร์ MySQL ที่ใช้ตาราง innodb และมีขนาดประมาณ 20GB
ฉันต้องการย้ายไปยังเซิร์ฟเวอร์ใหม่วิธีที่มีประสิทธิภาพที่สุดในการทำเช่นนี้คืออะไร
ฉันจะย้ายตาราง MySQL จากเซิร์ฟเวอร์จริงหนึ่งไปยังอีกเซิร์ฟเวอร์หนึ่งได้อย่างไร
เช่นสถานการณ์ที่แน่นอน: ฉันมีเซิร์ฟเวอร์ MySQL ที่ใช้ตาราง innodb และมีขนาดประมาณ 20GB
ฉันต้องการย้ายไปยังเซิร์ฟเวอร์ใหม่วิธีที่มีประสิทธิภาพที่สุดในการทำเช่นนี้คืออะไร
คำตอบ:
วิธีที่ฉันชอบคือไพพ์คำสั่ง sqldump ไปยังคำสั่ง sql คุณสามารถทำฐานข้อมูลทั้งหมดหรือเฉพาะ ตัวอย่างเช่น
mysqldump -uuser -ppassword myDatabase | mysql -hremoteserver -uremoteuser -premoteserverpassword
คุณสามารถทำฐานข้อมูลทั้งหมดด้วย
mysqldump --all-databases -uuser -ppassword | mysql -hremoteserver -uremoteuser -premoteserver
ปัญหาเดียวคือเมื่อฐานข้อมูลมีขนาดใหญ่เกินไปและไพพ์ยุบ ในกรณีนั้นคุณสามารถทำแบบตารางต่อตารางหรือวิธีการอื่น ๆ ที่กล่าวถึงด้านล่าง
netcat
ถ้าฐานข้อมูลไม่อนุญาตให้เชื่อมต่อระยะไกลท่อผ่าน
ฉันเพิ่งย้ายฐานข้อมูล 30GB ด้วย stragegy ต่อไปนี้:
~/mysqldata/*
)tar -czvf mysqldata.tar.gz ~/mysqldata
)tar -xzvf mysqldata.tar.gz
)ตามคู่มือการศึกษาใบรับรอง MySQL 5.0บทที่ 32 มาตรา 32.3.4, หน้า 456,457 อธิบายถึงเงื่อนไขสำหรับความสะดวกในการพกพาไบนารีซึ่งนำออกมาดังต่อไปนี้:
การพกพาแบบไบนารี่มีความสำคัญหากคุณต้องการทำการสำรองข้อมูลแบบไบนารี่ที่ทำกับเครื่องหนึ่งและใช้กับเครื่องอื่นที่มีสถาปัตยกรรมที่แตกต่างกัน ตัวอย่างเช่นการใช้การสำรองข้อมูลแบบไบนารีเป็นวิธีหนึ่งในการคัดลอกฐานข้อมูลจากเซิร์ฟเวอร์ MySQL เครื่องหนึ่งไปยังอีกเครื่องหนึ่ง
สำหรับ MyISAM ความสามารถในการพกพาแบบไบนารี่หมายความว่าคุณสามารถคัดลอกไฟล์สำหรับตาราง MyISAM โดยตรงจากเซิร์ฟเวอร์ MySQL เครื่องหนึ่งไปยังอีกเครื่องหนึ่งในเครื่องอื่นและเซิร์ฟเวอร์ตัวที่สองจะสามารถเข้าถึงตารางได้
สำหรับ InnoDB ความสามารถในการพกพาแบบไบนารี่หมายความว่าคุณสามารถคัดลอกไฟล์ tablespace โดยตรงจากเซิร์ฟเวอร์ MySQL บนเครื่องหนึ่งไปยังเซิร์ฟเวอร์อื่นบนเครื่องอื่นและเซิร์ฟเวอร์ตัวที่สองจะสามารถเข้าถึงพื้นที่ตารางได้ โดยค่าเริ่มต้นตาราง InnoDB ทั้งหมดที่จัดการโดยเซิร์ฟเวอร์จะถูกเก็บไว้ใน tablespace ดังนั้นความสะดวกในการพกพาของ tablespace จึงเป็นฟังก์ชั่นว่าตาราง InnoDB ทั้งหมดเป็นแบบพกพาหรือไม่ หากแม้แต่ตารางเดียวไม่สามารถพกพาได้ก็จะไม่มีพื้นที่ตาราง
ตาราง MyISAM และพื้นที่ตาราง InnoDB เป็นไบนารีแบบพกพาจากโฮสต์หนึ่งไปอีกโฮสต์หนึ่งหากตรงตามเงื่อนไขสองข้อ:
- เครื่องทั้งสองต้องใช้เลขคณิตเลขจำนวนเต็มสองส่วน
- เครื่องทั้งสองต้องใช้รูปแบบทศนิยมของ IEEE ไม่เช่นนั้นตารางจะต้องไม่มีคอลัมน์จุดลอยตัว (FLOAT หรือ DOUBLE)
ในทางปฏิบัติทั้งสองเงื่อนไขมีข้อ จำกัด เล็กน้อย เลขจำนวนเต็มสองส่วนที่เติมเต็มและรูปแบบจุดลอยตัว IEEE เป็นบรรทัดฐานของฮาร์ดแวร์ที่ทันสมัย เงื่อนไขที่สามสำหรับการพกพาแบบไบนารีของ InnoDB คือคุณควรใช้ชื่อตัวพิมพ์เล็กสำหรับตารางและฐานข้อมูล นี่เป็นเพราะ InnoDB เก็บชื่อเหล่านี้ไว้ภายใน (ในพจนานุกรมข้อมูล) ในตัวพิมพ์เล็กบน Windows การใช้ชื่อตัวพิมพ์เล็กอนุญาตให้ไบนารีพกพาระหว่าง Windows และ Unix เพื่อบังคับให้ใช้ชื่อตัวพิมพ์เล็กคุณสามารถใส่บรรทัดต่อไปนี้ในไฟล์ตัวเลือก:
[mysqld]
lower_case_table_names=1
หากคุณกำหนดค่า InnoDB เพื่อใช้พื้นที่ตารางต่อตารางเงื่อนไขสำหรับการพกพาไบนารีจะถูกขยายเพื่อรวมไฟล์. ibd สำหรับตาราง InnoDB เช่นกัน (เงื่อนไขสำหรับพื้นที่ตารางที่ใช้ร่วมกันยังคงใช้ได้เนื่องจากมีพจนานุกรมข้อมูลที่เก็บข้อมูลเกี่ยวกับตาราง InnoDB ทั้งหมด)
หากเงื่อนไขสำหรับความสะดวกในการพกพาแบบไบนารี่ไม่เป็นที่พอใจคุณสามารถคัดลอกตาราง MyISAM หรือ InnoDB จากเซิร์ฟเวอร์หนึ่งไปยังอีกเซิร์ฟเวอร์หนึ่งโดยการเททิ้งโดยใช้รูปแบบข้อความบางอย่าง (ตัวอย่างเช่นพร้อม mysqldump) และโหลดซ้ำลงในเซิร์ฟเวอร์ปลายทาง
มีสองวิธีที่สำคัญบนพื้นฐานของเอ็นจิ้นการจัดเก็บเพื่อย้ายแต่ละตาราง
สำหรับตัวอย่างที่กำหนดเราจะสมมติต่อไปนี้:
ตาราง MyISAM
หาก mydb.mytable ใช้เครื่องมือจัดเก็บ MyISAM ตารางจะแสดงเป็นไฟล์แยกกันสามไฟล์
. frm มีโครงสร้างตาราง
. MYD มีข้อมูลตาราง
. MYI มีหน้าดัชนีตาราง
ไฟล์เหล่านี้ถูกใช้ซึ่งกันและกันเพื่อแสดงตารางจากจุดยืนเชิงตรรกะใน mysql เนื่องจากไฟล์เหล่านี้ไม่มีการเชื่อมโยงแบบโลจิคัลเพิ่มเติมให้ย้ายตารางจากเซิร์ฟเวอร์ DB หนึ่งไปยังเซิร์ฟเวอร์อื่น คุณสามารถทำได้แม้กระทั่งจากเซิร์ฟเวอร์ Windows ไปยัง Linux Server หรือ MacOS แน่นอนคุณสามารถปิด mysql และคัดลอกไฟล์ตาราง 3 คุณสามารถเรียกใช้ต่อไปนี้:
LOCK TABLES mydb.mytable READ;
SELECT SLEEP(86400);
UNLOCK TABLES;
ในหนึ่งเซสชันเพื่อเก็บตารางเป็นแบบอ่านอย่างเดียวและล็อคเป็นเวลา 24 ชั่วโมง หนึ่งวินาทีต่อมาดำเนินการคัดลอกในเซสชั่นอื่น ssh จากนั้นฆ่าเซสชัน mysql ด้วยการล็อค 24 ชั่วโมง คุณไม่จำเป็นต้องรอ 24 ชั่วโมง
ตาราง InnoDB
ขึ้นอยู่กับคำพูดที่กล่าวถึงข้างต้นจากหนังสือรับรองมีหลายปัจจัยที่ควบคุมวิธีการสำรองข้อมูลตาราง InnoDB ที่เฉพาะเจาะจง เพื่อความเรียบง่ายความชัดเจนและความกะทัดรัดเพียงใช้ mysqldump ของตารางที่ต้องการโดยใช้พารามิเตอร์ - ธุรกรรมเดี่ยวเพื่อให้มีการถ่ายโอนข้อมูล ณ จุดเวลาที่สมบูรณ์แบบของตาราง ไม่จำเป็นต้องใช้ความหมายของตัวเองด้วยความหมายของ InnoDB หากคุณต้องการเพียงหนึ่งตาราง คุณสามารถโหลด dumpfile นั้นไปยังเซิร์ฟเวอร์ MySQL ที่คุณเลือกได้
เนื่องจากคำถามสองข้อถูกรวมที่นี่ (jcolebrand): EDIT
หากคุณเต็มใจที่จะอยู่กับประสิทธิภาพของฐานข้อมูลช้าคุณสามารถดำเนินการชุด rsyncs จากเซิร์ฟเวอร์เก่า (ServerA) ไปยังเซิร์ฟเวอร์ใหม่ (ServerB) แม้ในขณะที่ mysql ยังคงทำงานบน ServerA
ขั้นตอนที่ 01) ติดตั้ง mysql รุ่นเดียวกันบน ServerB ที่ ServerA มี
ขั้นตอนที่ 02) ใน ServerA ให้เรียกใช้SET GLOBAL innodb_max_dirty_pages_pct = 0;
จาก mysql และประมาณ 10 นาที (นี่จะล้างหน้าที่สกปรกจาก InnoDB Buffer Pool นอกจากนี้ยังช่วยให้ทำการปิด mysql ได้เร็วขึ้น) หากฐานข้อมูลของคุณคือ MyISAM ทั้งหมดคุณสามารถข้ามขั้นตอนนี้ได้
ขั้นตอนที่ 03) rsync --archive --verbose --stats --partial --progress --human-readable ServerA:/var/lib/mysql ServerB:/var/lib/mysql
ขั้นตอนที่ 04) ทำซ้ำขั้นตอนที่ 03 จนกระทั่ง rsync ใช้เวลาน้อยกว่า 1 นาที
ขั้นตอนที่ 05) service mysql stop
ใน ServerA
ขั้นตอนที่ 06) ดำเนินการ rsync อีกหนึ่งรายการ
ขั้นตอนที่ 07) scp ServerA:/etc/my.cnf ServerB:/etc/
ขั้นตอนที่ 08) service mysql start
ใน ServerB
ขั้นตอน 08) service mysql start
บน ServerA (ไม่บังคับ)
ให้มันลอง !!!
ข้อแม้
คุณสามารถสร้างทาสการจำลองเช่นนี้ เพียงจำไว้ว่าต้องตั้งค่าเซิร์ฟเวอร์ - รหัสอย่างชัดเจนใน master / etc / my.cnf และหมายเลขอื่นสำหรับ server-id ใน slave /etc/my.cnf
คุณไม่จำเป็นต้องใช้ mysqldump ถ้าคุณย้ายสกีมาฐานข้อมูลทั้งหมดและคุณยินดีที่จะหยุดฐานข้อมูลแรก (ดังนั้นจึงสอดคล้องกันเมื่อมีการถ่ายโอน)
ฉันจำไม่ได้ว่า mysqldump จัดการกับผู้ใช้และการอนุญาตหรือเพียงแค่ข้อมูล ... แต่แม้ว่ามันจะเป็นเช่นนั้นนี่เป็นวิธีที่เร็วกว่าการถ่ายโอนข้อมูลและการเรียกใช้ ฉันจะใช้เฉพาะที่ถ้าฉันต้องการถ่ายโอนฐานข้อมูล mysql แล้วใส่กลับเข้าไปใน RDBMS อื่น ๆ ถ้าฉันต้องการเปลี่ยนตัวเลือกการจัดเก็บ (innodb vs. myisam) หรือบางทีถ้าฉันกำลังเปลี่ยนข้อสำคัญของ mysql (แต่ ฉันคิดว่าฉันทำสิ่งนี้ระหว่าง 4 และ 5)
--all-databases
ดัมพ์ mysql schema การเริ่มต้นใช้งาน 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)
mysqldump
จัดการกับผู้ใช้และการอนุญาตเนื่องจากสิ่งเหล่านี้ถูกเก็บไว้ภายในmysql
schema
หากคุณต้องการย้ายตารางเฉพาะลอง:
mysqldump -u username -ppassword databasename tablename > databasename.tablename.sql
คุณสามารถระบุชื่อตารางเพิ่มเติมได้ในคำสั่งเดียวกัน เมื่อคำสั่งเสร็จสิ้นให้ย้ายไฟล์ databasename.tablename.sql ไปยังเซิร์ฟเวอร์อื่นจากนั้นกู้คืนโดยใช้:
mysql -u username -ppassword databasename < databasename.tablename.sql
โปรดทราบว่าไฟล์ .sql กลับถูกสร้างขึ้นโดยใช้mysqldumpโปรแกรมและเรียกคืนจะทำโดยตรงในMySQL
อาจมีความเป็นไปได้ที่คุณย้ายไฟล์ฐานข้อมูลจริง (สำหรับการติดตั้งของฉันจะอยู่ที่ / var / lib / mysql) แต่ฉันไม่แน่ใจว่ามันจะทำงานออกมาได้อย่างไร
คุณจะต้องหยุดทำงาน อาจต้องใช้เวลาสักครู่ขึ้นอยู่กับความเร็วเครือข่ายของคุณ ฉันจะสมมติว่าคุณใช้งาน MySQL บน Linux / Unix นี่คือกระบวนการที่ฉันใช้:
จากนั้นดำเนินการตามปกติเมื่อทำการติดตั้ง MySQL ในเครื่อง
* หมายเหตุ: คุณยังสามารถใช้พารามิเตอร์ -c พร้อม rsync เพื่อเพิ่มการตรวจสอบการถ่ายโอนได้อย่างไรก็ตามการดำเนินการนี้จะช้ามากขึ้นอยู่กับความเร็วของ CPU
ฉันสามารถยืนยันได้ว่าวิธีการของ DTest นั้นใช้ได้สำหรับการคัดลอกระหว่าง ubuntu และ osx
ในการคัดลอกฐานข้อมูลทั้งหมดโดยไม่ต้องทำการดัมพ์หรือที่คล้ายกัน:
ตรวจสอบให้แน่ใจว่าคุณมี mysql ที่สะอาดของ mysql (ติดตั้ง dmg ที่ดาวน์โหลดจาก mysql http://cdn.mysql.com/Downloads/MySQL-5.1/mysql-5.1.63-osx10.6-x86_64.dmg ), (มาก สำคัญ) ไม่เคยถูกเรียกใช้
คัดลอกเนื้อหา / var / lib / mysql / folder จากเครื่อง ubuntu ที่ด้านบนของ / usr / local / mysql / data / content บน mac ในการเข้าถึงโฟลเดอร์บนเครื่องอูบุนตูฉันต้องใช้ sudo เช่น:
sudo cp /var/lib/mysql /home/foouser/mysql_data_folder
sudo chown -R foouser /home/foouser/mysql_data_folder
ฉันคัดลอกโฟลเดอร์โดยใช้ scp
ก่อนที่คุณจะเริ่มคัดลอกโฟลเดอร์ mysql บน mac เพื่อให้แน่ใจว่าคุณจะไม่ทำอะไรผิดพลาด
หลังจากคัดลอกโฟลเดอร์แล้วให้ทำสิ่งต่อไปนี้บนเครื่อง 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 เป็นครั้งแรก (จากบานหน้าต่างการตั้งค่าภายใต้ System Preferences-> mysql) ผู้ใช้และฐานข้อมูลทั้งหมดควรได้รับการตั้งค่าอย่างถูกต้อง
สิ่งนี้ทำงานกับ mysql 5.1.61 บน Ubuntu 64 บิต 11.10 และ mysql 5.1.63 บน osx lion (macbook pro)
ฉันคิดว่าคำตอบก่อนหน้านี้ทั้งหมดอาจใช้ได้ดี แต่ไม่ได้แก้ไขปัญหาของการตั้งชื่อฐานข้อมูลระหว่างการถ่ายโอน
นี่คือวิธีที่ฉันทำกับ 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
คุณย้ายไปยังเซิร์ฟเวอร์ mysql อื่นหรือไม่ ถ้าเป็นเช่นนั้นใช้ส่งออกมัน
# mysqldump -u username -ppassword database_name > FILE.sql
วิธีลินุกซ์ทั่วไป:
/etc/init.d/mysqld stop
rsync -avz source_files destination
vi /etc/my.cnf
แก้ไข datadir (และซ็อกเก็ต) สำหรับทั้ง mysqld และ mysqld_safe (ถ้ามี) เพื่อชี้ไปที่ตำแหน่งใหม่จากนั้น
/etc/init.d/mysql start
ฉันโพสต์สิ่งนี้เพราะไม่มีใครดูเหมือนจะทำรายการขั้นตอนจำนวนน้อยที่สุดในการทำสิ่งนี้และฉันรู้สึกว่ามันเป็นวิธีที่ง่ายที่สุดโดยส่วนตัว
บางทีนี่อาจเป็นวิธีที่ดีกว่าในการทำ:
รุ่น 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
ติดตั้ง pigz - บนโปรเซสเซอร์ Xeon หรือ Opteron รุ่นใหม่โดยเฉพาะเมื่อคุณมี CPU 2 ตัวขึ้นไปมันเร็วกว่า 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 : master / slave + mysqldump / file-copy
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
PS:
เพื่อคัดลอกตารางขนาดเล็กใช้:
ssh server1 ตาราง mysqldump schema ssh server2 mysql schema
ฉันขอแนะนำสองขั้นตอนง่าย ๆ ในการถ่ายโอนฐานข้อมูลทั้งหมดจากเซิร์ฟเวอร์หนึ่งไปยังอีกเซิร์ฟเวอร์หนึ่ง
ขั้นตอนที่ 1 : ทำเต็มรูปแบบในการสำรองข้อมูลของฐานข้อมูลในเซิร์ฟเวอร์ต้นทางโดยใช้mysqldump
ขั้นตอนที่ 2 : คุณสามารถใช้คำสั่งrsyncเพื่อถ่ายโอนฐานข้อมูลทั้งหมดไปยังเซิร์ฟเวอร์ปลายทาง