หนึ่งในนักฆ่าเงียบของการเชื่อมต่อ 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 จึงถูกดำเนินการทีละตัว ข้อเสียที่สำคัญคือ
- mysqldump นั้นใหญ่กว่ามาก
- การโหลดซ้ำการถ่ายโอนข้อมูลใช้เวลานานกว่ามาก
วิธีที่ # 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 ของฉัน