เซิร์ฟเวอร์ MySQL หายไปจากการขัดขวางการนำเข้าของทิ้งขนาดใหญ่


14

ฉันพยายามนำเข้า sql dump ขนาดใหญ่ (2GB) ไปยัง mysql ในเครื่องของฉันบน mac ฉันสามารถทำสิ่งนี้ได้ในอดีต (ฉันใช้ MAMP) แต่ตอนนี้ฉันได้รับ ERROR 2006 (HY000) ที่บรรทัด 7758: เซิร์ฟเวอร์ MySQL หายไปทุกครั้งที่ฉันพยายามนำเข้าดัมพ์ ฐานข้อมูลมีตาราง innodb

ฉันพยายามคัดลอกไฟล์ my-innodb-heavy-4G.cnf ไปยัง my.cnf ของฉันเพื่อดูว่าการตั้งค่าเหล่านั้นจะช่วยได้หรือไม่ แต่โชคไม่ดี

ความคิดใด ๆ เกี่ยวกับสิ่งที่จะปรับแต่ง?

ฉันใช้ "Mac OS X เวอร์ชั่น 10.6 (x86, 64- บิต), DMG Archive" จากที่นี่: http://dev.mysql.com/downloads/mysql/

คำตอบ:


15

หนึ่งในนักฆ่าเงียบของการเชื่อมต่อ MySQL คือ MySQL Packet แม้แต่ I / O Thread ของ MySQL Replication ก็สามารถตกเป็นเหยื่อได้ด้วยสิ่งนี้

ตามเอกสาร MySQL

  • คุณสามารถรับข้อผิดพลาดเหล่านี้ได้หากคุณส่งแบบสอบถามไปยังเซิร์ฟเวอร์ที่ไม่ถูกต้องหรือใหญ่เกินไป หาก mysqld ได้รับแพ็คเก็ตที่ใหญ่เกินไปหรือไม่เรียบร้อยก็จะถือว่ามีบางอย่างผิดปกติกับไคลเอนต์และปิดการเชื่อมต่อ หากคุณต้องการคิวรีขนาดใหญ่ (ตัวอย่างเช่นหากคุณทำงานกับคอลัมน์ BLOB ขนาดใหญ่) คุณสามารถเพิ่มขีด จำกัด คิวรีได้โดยการตั้งค่าตัวแปร max_allowed_packet ของเซิร์ฟเวอร์ซึ่งมีค่าเริ่มต้น 1MB คุณอาจต้องเพิ่มขนาดแพ็กเก็ตสูงสุดที่ส่วนท้ายของไคลเอ็นต์ ข้อมูลเพิ่มเติมเกี่ยวกับการตั้งค่าขนาดแพ็คเก็ตได้รับในส่วน C.5.2.10“ แพ็คเก็ตใหญ่เกินไป”

  • คำสั่ง INSERT หรือ REPLACE ที่แทรกแถวจำนวนมากออกไปสามารถทำให้เกิดข้อผิดพลาดได้ ข้อความใดข้อความหนึ่งเหล่านี้ส่งคำขอเดียวไปยังเซิร์ฟเวอร์โดยไม่คำนึงถึงจำนวนแถวที่จะแทรก ดังนั้นคุณมักจะสามารถหลีกเลี่ยงข้อผิดพลาดได้โดยลดจำนวนแถวที่ส่งต่อ INSERT หรือ REPLACE

อย่างน้อยที่สุดคุณต้องตรวจสอบขนาดแพ็คเก็ตสำหรับทั้งเครื่องที่คุณใช้งานและเครื่องที่คุณโหลดเหมือนกัน

อาจมีสองวิธีที่คุณสามารถทำได้:

วิธีที่ # 1: ดำเนินการ mysqldump โดยใช้ --skip-extended-insert

สิ่งนี้จะทำให้แน่ใจได้ว่า MySQL Packet ไม่ได้ถูกน้ำท่วมด้วยหลาย BLOBs, TEXT field ด้วยเหตุนี้ SQL INSERT จึงถูกดำเนินการทีละตัว ข้อเสียที่สำคัญคือ

  1. mysqldump นั้นใหญ่กว่ามาก
  2. การโหลดซ้ำการถ่ายโอนข้อมูลใช้เวลานานกว่ามาก

วิธีที่ # 2: เพิ่มmax_allowed_packet

นี่อาจเป็นวิธีที่แนะนำเนื่องจากการใช้งานนี้เป็นเพียงการรีสตาร์ท mysql การทำความเข้าใจกับสิ่งที่ MySQL Packet อาจชี้แจงนี้

ตามหน้า 99 ของ "การทำความเข้าใจกับ MySQL ภายใน" (ไอ 0-596-00957-7) ต่อไปนี้คือย่อหน้าที่ 1-3 ที่อธิบาย:

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

รหัสที่สนใจในความสัมพันธ์กับตัวเลือกนี้จะพบใน SQL / net_serv.cc ลองดูที่my_net_read ()จากนั้นทำตามการเรียกร้องให้my_real_read ()และให้ความสนใจเป็นพิเศษกับ net_realloc ()

ตัวแปรนี้ยังจำกัดความยาวของผลลัพธ์ของฟังก์ชั่นสตริงจำนวนมาก ดูSQL / field.ccและ SQL / intem_strfunc.ccสำหรับรายละเอียด

จากคำอธิบายนี้การสร้าง INSERT จำนวนมากจะทำการโหลด / ยกเลิกการโหลด MySQL Packet ค่อนข้างเร็ว โดยเฉพาะอย่างยิ่งเมื่อ max_allowed_packet มีขนาดเล็กเกินไปสำหรับการโหลดข้อมูลที่กำหนดมา

สรุปผลการศึกษา

ในการติดตั้ง MySQL ส่วนใหญ่ฉันมักจะตั้งค่านี้เป็น 256M หรือ 512M คุณควรพบกับค่าที่มากกว่าเมื่อโหลดข้อมูลสร้างข้อผิดพลาด "MySQL หายไป"


ฉันพยายามที่จะตั้งค่า max_allowed_packetให้ 900M และฉันใช้--skip-extended-insert(และคุณถูก - ที่ทำให้ huuuge db-dumps) แต่ก็ยังล้มเหลว ฉันสงสัยว่ามีบางบรรทัดในดัมพ์ตอนนี้ซึ่งฉันสามารถแก้ไขได้ แต่มันก็ยังแปลกอยู่ - ดัมพ์สามารถอิมพอร์ตได้ดีบนเซิร์ฟเวอร์ CentOS ของฉัน
naxoc

ฉันลงเอยด้วยการลบส่วนแทรกออกจาก sql dump ซึ่งเป็นเส้นที่ยาวมาก ๆ แก้ไขแล้ว (และไม่จำเป็นต้องใช้สาย)
naxoc

BTW โปรดตรวจสอบให้แน่ใจว่าอักขระเริ่มต้นสำหรับการถ่ายโอนข้อมูลสามารถรองรับได้ในระบบปฏิบัติการ MacOSX และใน MySQL
RolandoMySQLDBA

@naxov - ฉันแค่อยากรู้เกี่ยวกับหนึ่งบรรทัดที่คุณสงสัยในการถ่ายโอนข้อมูล มีฟิลด์ TEXT หรือ BLOB ที่เกี่ยวข้องหรือไม่?
RolandoMySQLDBA

ใช่ฟิลด์ข้อความยาวมาก
naxoc

2

ระยะเวลานี้นานเท่าไหร่ก่อนหมดเวลา? ขั้นตอนแรกจะวางเดิมพันเพื่อตรวจสอบwait_timeoutและinteractive_timeoutตั้งค่าเพื่อให้แน่ใจว่ามีขนาดใหญ่พอสำหรับการนำเข้าของคุณ:

SHOW VARIABLES LIKE '%_timeout';
SET SESSION wait_timeout=28800;

ค่าเริ่มต้นคือ 8 ชั่วโมง (28800) ดังนั้นจึงไม่มีปัญหา ตัวชี้วัดอื่น ๆ ของปัญหานี้สามารถพบได้ที่นี่ หนึ่งที่โดดเด่นคือ:

แอปพลิเคชันไคลเอนต์ที่ทำงานบนโฮสต์อื่นไม่มีสิทธิ์ที่จำเป็นในการเชื่อมต่อกับเซิร์ฟเวอร์ MySQL จากโฮสต์นั้น

ตรวจสอบสิทธิ์ก่อนจากนั้นทำตามรายการปัญหาที่อาจเกิดขึ้น


มันอยู่บน localhost ดังนั้นฉันไม่เข้าใจว่าคุณหมายถึงอะไรหรือไม่ใช่ปัญหา คุณหมายถึงการอนุญาตตามสิทธิ์ใน mysql หรือไม่
naxoc

2

ใช่มักจะเล่นกับ wait_timeout และ max_allowed_packets ช่วยให้ฉันได้รับข้อความแสดงข้อผิดพลาดเช่นกัน


นั่นไม่ได้ผลสำหรับฉัน ฉันต้องแก้ไข sql ในไฟล์ดัมพ์และลบบรรทัดที่ยาวมากซึ่งทำให้เกิดปัญหา
naxoc

หนึ่งไม่ควรเล่นกับพารามิเตอร์บางอย่างที่เขาไม่เข้าใจ
Jeredepp

2

มันอาจไม่ใช่สิ่งที่ "ถูกต้อง" ที่ต้องทำ แต่อาจใช้งานได้ (เสร็จสิ้นแล้วใช่ไหม):

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

ฉันค่อนข้างอยากรู้อยากเห็นถ้าจำนวน RAM ที่คุณมีในกล่องของคุณสามารถทำอะไรกับมันได้ MySQL โหลดดัมพ์ทั้งหมดลงในหน่วยความจำหรือไม่เมื่อเรียกใช้ ฉันไม่รู้ ... แต่ถ้าคุณมี RAM เพียง 2GB และบางตัวกำลังใช้งานระบบปฏิบัติการของคุณและแอพอื่น ๆ นี่อาจเป็นปัญหา


2

ผู้ที่ยังไม่ประสบความสำเร็จกับข้อเสนอแนะอื่น ๆ อาจพิจารณาการดูที่ BigDump PHP เซ MySQL การถ่ายโอนข้อมูลสคริปต์ผู้นำเข้า

เป็นวิธีแก้ปัญหาสำหรับการนำเข้าฐานข้อมูลขนาดใหญ่ทิ้งลงใน MySQL ฉันใช้มันสำเร็จแล้วในการนำเข้าการถ่ายโอนข้อมูล MySQL ขนาดใหญ่ในสภาพแวดล้อมการพัฒนาท้องถิ่นของฉัน (ฉันใช้ MAMP ในกรณีนี้)

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