สิ่งที่ max_allowed_packet มีขนาดใหญ่พอและทำไมฉันต้องเปลี่ยนมัน?


14

ฉันมี MySQL (5.5) ในการตั้งค่า master-slave และสร้างเซิร์ฟเวอร์ทาสอื่น

ฉันหยุดทาสต้นฉบับทิ้งข้อมูลคัดลอกและนำเข้าอีกครั้งและทำงานได้ดี ฉันสังเกตเห็น master_log pos ของสลาฟดั้งเดิมและใช้คำสั่งเหล่านี้เพื่อตั้งค่าสลาฟใหม่

CHANGE MASTER TO MASTER_HOST='<ipaddress>', 
MASTER_USER='<username>', MASTER_PASSWORD='<password>', 
MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000851', 
MASTER_LOG_POS=15824150, 
MASTER_CONNECT_RETRY=10;

เมื่อฉันเริ่มทาสใหม่ที่ฉันได้รับ

Last_IO_Error: มีข้อผิดพลาดร้ายแรง 1236 จากต้นแบบเมื่ออ่านข้อมูลจากบันทึกไบนารี: 'รายการบันทึกเหตุการณ์เกิน max_allowed_packet; เพิ่ม max_allowed_packet ในต้นแบบ '

อย่างไรก็ตามเมื่อฉันเริ่มต้นทาสดั้งเดิมมันก็ไม่เป็นไรและตอนนี้ก็กำลังซิงค์กันอยู่

ดังนั้นคำถาม:

  • ค่าปัจจุบันคือ 16M ฉันจะรู้ได้อย่างไรว่าใหญ่แค่ไหน (ฉันค่อนข้างจะหลีกเลี่ยงการลองผิดลองถูกกับเซิร์ฟเวอร์ที่ใช้งานจริง)

  • ทำไมฉันต้องเพิ่มมูลค่าให้กับนายเมื่อทาสดั้งเดิมถูกจัดการได้ดีปัญหาอาจจะเป็นกับทาสใหม่ได้หรือไม่

ปรับปรุง

ฉันเพิ่ม max_allowed_packet เป็น 1073741824 ตามที่ Rolando แนะนำไว้กับเจ้านายทาสเก่าและทาสใหม่และเริ่มต้นใหม่ ( SET GLOBAL max_allowed_packet = 1073741824;ด้วยเหตุผลบางอย่างดูเหมือนจะไม่เกิดขึ้น)

ตอนนี้ข้อผิดพลาด IO ครั้งสุดท้ายเหมือนเดิม แต่ตอนนี้ฉันเห็นแล้ว

Last_SQL_Error: การอ่านบันทึกการทำงานล้มเหลว: ไม่สามารถแยกวิเคราะห์รายการบันทึกการถ่ายทอด สาเหตุที่เป็นไปได้คือ: บันทึกไบนารีของต้นแบบเสียหาย (คุณสามารถตรวจสอบสิ่งนี้ได้โดยการเรียกใช้ 'mysqlbinlog' บนล็อกไฟล์ไบนารี) ล็อกบันทึกการถ่ายทอดของทาสทำงานเสียหาย (คุณสามารถตรวจสอบได้โดยใช้ 'mysqlbinlog' บนล็อกรีเลย์) ปัญหาเครือข่ายหรือข้อบกพร่องในรหัส MySQL ของเจ้านายหรือทาส หากคุณต้องการตรวจสอบบันทึกไบนารีของต้นแบบหรือบันทึกการถ่ายทอดของทาสคุณจะสามารถรู้ชื่อได้โดยการออก 'SHOW SLAVE STATUS' บนสลาฟนี้

ถ้าฉันทำ mysqlbinlog ในไฟล์ของอาจารย์มันจะเลื่อนผ่านไปด้วยคำสั่งที่ค่อนข้างมีความสุขสำหรับทุกเพศทุกวัย - ไฟล์คือ 722M - ถ้าฉันทำเช่นนั้นสำหรับบันทึกการถ่ายทอดทาสฉันได้รับ

ข้อผิดพลาด: ข้อผิดพลาดใน Log_event :: read_log_event (): 'การตรวจสอบสติไม่สำเร็จ', data_len: 38916267, event_type: 69

ข้อผิดพลาด: ไม่สามารถอ่านรายการที่ offset 253: ข้อผิดพลาดในรูปแบบบันทึกหรือข้อผิดพลาดในการอ่าน

ฉันตรวจสอบตัวแปรและการเปลี่ยนแปลงยังทำงานอยู่

mysql> แสดงตัวแปร LIKE '% max_allowed_packet%';

บนทาสคนใหม่ที่แสดงให้เห็นmax_allowed_packetและslave_max_allowed_packetที่เป็นหลักมันมีเพียงmax_allowed_packet

ดังนั้นฉันจึงตรวจสอบเวอร์ชันของต้นแบบ:

mysql> show variables LIKE '%version%';
+-------------------------+--------------------------------------+
| Variable_name           | Value                                |
+-------------------------+--------------------------------------+
| innodb_version          | 1.1.6                                |
| protocol_version        | 10                                   |
| slave_type_conversions  |                                      |
| version                 | 5.5.11-log                           |
| version_comment         | MySQL Community Server (GPL) by Remi |
| version_compile_machine | x86_64                               |
| version_compile_os      | Linux                                |
+-------------------------+--------------------------------------+

และทาสใหม่

mysql> show variables LIKE '%version%';
+-------------------------+--------------------------------------+
| Variable_name           | Value                                |
+-------------------------+--------------------------------------+
| innodb_version          | 5.5.32                               |
| protocol_version        | 10                                   |
| slave_type_conversions  |                                      |
| version                 | 5.5.32-log                           |
| version_comment         | MySQL Community Server (GPL) by Remi |
| version_compile_machine | x86_64                               |
| version_compile_os      | Linux                                |
+-------------------------+--------------------------------------+

รุ่นทั้งสองนี้อยู่ห่างกันมากเกินไปหรือไม่


มีบางสิ่งบางอย่างที่น่าสนใจคือที่นี่ หวังว่านี่จะเป็นประโยชน์
Sathish D

คำตอบ:


18

ตกลงเพื่อขยายสูงสุดmax_allowed_packet1G เมื่อใดก็ตามที่ MySQL Packet ถูกสร้างขึ้นมันจะไม่กระโดดไปที่ 1G ตั้งแต่เริ่มต้น ทำไม?

ก่อนอื่นคุณต้องรู้ว่า MySQL Packet คืออะไร หน้า 99 ของหนังสือ

ทำความเข้าใจกับ MySQL Internals

อธิบายไว้ในวรรค 1-3 ดังนี้

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

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

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

เปรียบเทียบกับเอกสาร MySQL บนmax_allowed_packet:

ขนาดสูงสุดของหนึ่งแพ็กเก็ตหรือสตริงที่สร้างขึ้น / ระดับกลางหรือพารามิเตอร์ใด ๆ ที่ส่งโดยฟังก์ชัน mysql_stmt_send_long_data () C API ค่าเริ่มต้นคือ 4MB จาก MySQL 5.6.6, 1MB ก่อนหน้านั้น

บัฟเฟอร์ข้อความแพ็คเก็ตถูกเตรียมใช้งานเป็นไบต์ net_buffer_length แต่สามารถโตได้ถึง max_allowed_packet ไบต์เมื่อจำเป็น ค่านี้โดยค่าเริ่มต้นมีขนาดเล็กเพื่อจับแพ็คเก็ตขนาดใหญ่ (อาจไม่ถูกต้อง)

คุณต้องเพิ่มค่านี้หากคุณใช้คอลัมน์ BLOB ขนาดใหญ่หรือสตริงที่ยาว มันควรจะใหญ่เท่ากับ BLOB ที่ใหญ่ที่สุดที่คุณต้องการใช้ ขีด จำกัด โปรโตคอลสำหรับ max_allowed_packet คือ 1GB ค่าควรเป็นจำนวนเต็ม 1024 nonmultiples ถูกปัดเศษลงเป็นพหุคูณที่ใกล้ที่สุด

เมื่อคุณเปลี่ยนขนาดบัฟเฟอร์ข้อความโดยการเปลี่ยนค่าของตัวแปร max_allowed_packet คุณควรเปลี่ยนขนาดบัฟเฟอร์ที่ฝั่งไคลเอ็นต์หากโปรแกรมไคลเอ็นต์ของคุณอนุญาต บนฝั่งไคลเอ็นต์ max_allowed_packet มีค่าเริ่มต้น 1GB บางโปรแกรมเช่น mysql และ mysqldump ช่วยให้คุณสามารถเปลี่ยนค่าฝั่งไคลเอ็นต์โดยการตั้งค่า max_allowed_packet บนบรรทัดคำสั่งหรือในไฟล์ตัวเลือก

จากข้อมูลนี้คุณควรดีใจที่ MySQL จะขยายและทำสัญญา MySQL Packet ตามต้องการ ดังนั้นไปข้างหน้าและ

  • ตั้งค่าmax_allowed_packetเป็น 1G ทั้ง Master และ Slave
  • ตั้งค่าnet_buffer_lengthสูงสุด 1M บนทั้ง Master และ Slave

Master และ Slave ควรจับคู่ในแง่ของผู้ที่ส่งข้อมูลโดยเฉพาะข้อมูล BLOB

อัพเดท 2013-07-04 07:03 EDT

จากข้อความของคุณเกี่ยวกับบันทึกการถ่ายทอดดูเหมือนว่าคุณมีสิ่งต่อไปนี้

  • บันทึกรีเลย์ที่เสียหาย
  • บันทึกหลักที่ดี

ข้อเสนอแนะ

SHOW SLAVE STATUS\G
STOP SLAVE;
CHANGE MASTER TO
MASTER_LOG_FILE='(Relay_Master_Log_File from SHOW SLAVE STATUS\G)',
MASTER_LOG_POS=(Exec_Master_Log_Pos from SHOW SLAVE STATUS\G);
START SLAVE;

การCHANGE MASTER TOล้างข้อมูลบันทึกการถ่ายทอดทั้งหมดและเริ่มต้นด้วยการบันทึกใหม่ คุณจะทำซ้ำจากเหตุการณ์ BinLog Master ครั้งสุดท้าย (BinLog, ตำแหน่ง) ที่ดำเนินการใน Slave

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


ขอบคุณเยี่ยมเลยที่ปลอดภัย แต่ฉันก็ยังไม่เข้าใจว่าทำไมฉันต้องเปลี่ยนมันเมื่อค่าปัจจุบันตรงกับต้นแบบและทาสตัวอื่นที่ทำงานได้อย่างสมบูรณ์
CodeMonkey

อย่างอื่นเกิดขึ้นฉันได้เพิ่มรายละเอียดเพิ่มเติม
CodeMonkey

1
สำหรับข้อมูลของคุณ: สิ่งนี้เกิดขึ้นฉันเมื่อฉันรีเซ็ตกระบวนการจำลองแบบและป้อนMASTER_LOG_FILEชื่อผิดโดยไม่ตั้งใจ เช่นใช้mysql-bin.000001เมื่อฉันควรจะใช้mysql-bin.000003จากในSHOW MASTER STATUS CHANGE MASTER TO
Mikko Ohtamaa

8

ค่อนข้างเปิ่นปัญหาคือชื่อไฟล์ที่ไม่ถูกต้องสำหรับบันทึกที่ก่อให้เกิดผลแปลก reimported กับชื่อไฟล์ที่ถูกต้องและทุกอย่างถูกปรับแฮงหัวในความอัปยศ


ขอบคุณมาก! คุณไม่ใช่คนเดียวที่ทำผิดนี้
Mikko Ohtamaa

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