แพ็คเกจการสื่อสารเพื่ออ่านข้อผิดพลาดของ MySQL


42

ในบันทึกข้อผิดพลาด MySQL ฉันเห็นคำเตือนเล็กน้อยเหล่านี้:

120611 16:12:30 [Warning] Aborted connection 2619503 to db: 'db_name' user: 'user_name' host: 'webapp_hostname' (Got an error reading communication packets)

ไม่ได้สังเกตเห็นการสูญเสียข้อมูลใด ๆ ต่อฉันดังนั้นฉันสงสัยว่าคำเตือนนี้หมายถึงอะไรหรือสิ่งที่ทำให้มันและถ้าใครอาจแก้ไขปัญหาที่ก่อให้เกิดเหล่านี้ นี่คือ RHEL 6.1 และ MySQL Enterprise 5.5

คำตอบ:


50

หนึ่งในนักฆ่าเงียบ ๆ ของการเชื่อมต่อของ MySQL คือ MySQL Packet

อันดับแรกเรามาดูกันว่า MySQL Packet คืออะไร

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

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

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

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

การรู้สิ่งนี้เกี่ยวกับ MySQL Packets ช่วยให้ Developer / DBA เพิ่มขนาดให้รองรับหลาย BLOBs ภายในแพ็คเก็ตเดียวแม้ว่ามันจะใหญ่เกินไป แพ็กเก็ตขนาดเล็กเกินไปจะทำให้เกิดปัญหาสำหรับการเชื่อมต่อแบบเปิดในส่วนนี้

ตามเอกสาร MySQL

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

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

คำแนะนำ

ลองเพิ่มmax_allowed_packetเป็นจำนวนที่มากกว่าเนื่องจากค่าเริ่มต้นคือ 1M ฉันจะแนะนำประมาณ 10 เท่าของฟิลด์ TEXT หรือ BLOB ที่ใหญ่ที่สุดที่คุณมีในชุดข้อมูลปัจจุบันของคุณ

หากต้องการตั้งค่า max_allowed_packet เป็น 256M คุณสามารถเพิ่มลงใน /etc/my.cnf หรือ my.ini

[mysqld]
max_allowed_packet=256M

เพื่อให้ครอบคลุมการเริ่มต้นใหม่ในอนาคตของ mysqld หากต้องการติดตั้งค่าทันทีบนเซิร์ฟเวอร์กรุณาเรียกใช้สิ่งนี้:

SET GLOBAL max_allowed_packet = 1024 * 1024 * 256;

ให้มันลอง !!!


คำอธิบายที่ดีมาก
Vasilis Lourdas

4

ส่วนใหญ่โดยค่าเริ่มต้น max_connections จะเป็น 100 ลองเพิ่มพารามิเตอร์การตั้งค่า

max_connections = 400 หลังจากตั้งค่าใน my.cnf รีบูทเซิร์ฟเวอร์หรือตั้งค่าแบบไดนามิก:

    set @@global.max_connections = 400;

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


2

ฉันพบปัญหานี้เมื่อเร็ว ๆ นี้หลังจากย้ายจาก MySQL Enterprise 5.1.xเป็น5.7.xโดยไม่ต้องมีการเปลี่ยนแปลงรหัสที่สำคัญใด ๆ ในแอปพลิเคชัน ' โน้ต ' เริ่มปรากฏขึ้น

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


0

บรรทัด my.ini นี้แก้ไขปัญหาของฉันได้:

log_error_verbosity=1

อ้างอิงลิงค์นี้


16
ฉันไม่คิดว่าคุณได้แก้ไขปัญหาพื้นฐานแล้ว แต่หยุดเพียงแค่บันทึกไว้
user19292

1
ฉันมีข้อความเดียวกันรายงานว่าเป็น "หมายเหตุ" ใช้ log_error_verbosity = 2 แก้ปัญหา "จริง ๆ " (แต่ควรมีการ "เตือน" ไม่ควรเพิกเฉย)
xtian
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.