GotoKnow
  • เข้าระบบ
  • สมัครสมาชิก
  • แผงจัดการ
  • ออกจากระบบ
GotoKnow

Out of Memory [ MySQL ]

พอดีมาแก้ปัญหาเกี่ยวกับ Out of Memory ของ MySQL  ที่รันบนลินุกซ์ Fedora Core 2 นะครับ ซึ่งดูลอกไฟล์ที่ /var/log/message ได้ผลดังนี้ครับ

Out of Memory: Killed process 10085 (mysqld).
oom-killer: gfp_mask=0xd0
Mem-info:
DMA per-cpu:
cpu 0 hot: low 2, high 6, batch 1
cpu 0 cold: low 0, high 2, batch 1
cpu 1 hot: low 2, high 6, batch 1
cpu 1 cold: low 0, high 2, batch 1
Normal per-cpu:
cpu 0 hot: low 32, high 96, batch 16
cpu 0 cold: low 0, high 32, batch 16
cpu 1 hot: low 32, high 96, batch 16
cpu 1 cold: low 0, high 32, batch 16
HighMem per-cpu:
cpu 0 hot: low 32, high 96, batch 16
cpu 0 cold: low 0, high 32, batch 16
cpu 1 hot: low 32, high 96, batch 16
cpu 1 cold: low 0, high 32, batch 16

ซึ่งเครื่องนี้มีแรมขนาด 2 GB กับ Swap อีก 4 GB ( 2 GB (Partition) + 2 GB (File) ) ครับ ก่อนหน้านี้แรมหมดเกลี้ยงเลยนะ

# free -m
             total       used       free     shared    buffers     cached
Mem:          2026        999       1027          0          8        612
-/+ buffers/cache:        377       1648
Swap:         3992          0       3991

สำหรับความเร็วของซีพียูนะครับ ดูจากคำสั่ง  cat /proc/cpuinfo

processor       : 0
vendor_id       : GenuineIntel
cpu family      : 15
model           : 2
model name      : Intel(R) Xeon(TM) CPU 3.06GHz
stepping        : 9
cpu MHz         : 3061.967
cache size      : 512 KB
physical id     : 0
siblings        : 2
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 2
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe cid xtpr
bogomips        : 6062.08

สำหรับวิธีการแก้ปัญหาของผมนะ ก็ปรับแต่งค่าพารามิเตอร์ต่างๆ ที่อยู่ในไฟล์ /etc/my.cnf นะครับ โดยทีแรกสุดนั้น ค่าต่างๆ เป็นค่าโดยปริยายของระบบ ซึ่งทำให้มีการใช้งานที่หนักเกินไป ผมก็เลยลองเปลี่ยนเป็นค่าอื่นๆ ตามเอกสารของ mysql ดูครับ ซึ่งจะมีตัวอย่างไฟล์อยู่ที่ /usr/share/doc/mysql-*/my-*.cnf ครับ ซึ่ง my-*.cnf จะมีทั้ง my-huge.cnf , my-large.cnf , my-medium.cnf , my-small.cnf ซึ่งจะมีโหลดของการทำงานที่แตกต่างกันครับ ผมลองปรับค่าเดิมที่มีอยู่ ให้เป็นแบบ my-medium.cnf ก็ปรากฏว่า อาการดีขึ้นมาครับ จากเดิมที่ใช้ cpu 99.9% มาเป็น ไม่เกิน 60% แล้วครับ

บันทึกนี้เขียนที่ GotoKnow โดย 

คำสำคัญ (keywords): serverlinux
หมายเลขบันทึก: 79888
เขียน:
แก้ไข:
ความเห็น: 4
อ่าน:
สัญญาอนุญาต: สงวนสิทธิ์ทุกประการ

ความเห็น (4)

แวะเข้ามา share ครับ 

บางทีการแก้ปัญหาแบบนี้ เป็นการแก้ที่ปลายเหตุนะครับ
บางครั้งมีสาเหตุอื่นๆ อีก เช่น ปัญหาที่เกิดจาก Database ไม่ได้มีการสร้าง Index  แล้วมีการ query ข้อมูลขนาดใหญ่ (แล้ว resource ที่จองไว้ให้ MySQL น้อยเกินไป)  ทำให้ MySQL ต้องทำงานหนักมาก

 โดยเฉพาะการใช้ฐานข้อมูลแบบ  MyISAM จะก่อให้เกิดปัญหา dead lock เนื่องจาก MyISAM จะ lock ในระดับ Table  โดยเฉพาะอย่างยิ่งการใช้ คำสั่งในการ join หรือ update ดังนั้นเมื่อ sql command  มีอาการค้างเกิดขึ้น  จะทำให้ sql command ที่เข้ามาทีหลัง ไม่สามารถทำงานได้  และจะหยุดรอจนกว่า อันแรกจะหยุด  เมื่อ server มี sql command เข้ามาอีกเรื่อยๆอีก  จะทำให้ connection ที่จองไว้เต็ม  ทำให้ไม่สามารถ remote เข้าไป MySQL  เพื่อ เข้าไปจัดการแก้ไข (แม้แต่ mysql's root ก็ตาม)

 หากว่าเป็นปัญหาที่ database จริง  ถึงแม้ว่าการเพิ่ม resource ให้กับ MySQL จะช่วยให้ทำงานต่อไปได้  แต่เมื่อถึงจุดๆ หนึ่ง  เราก็ต้องเพิ่ม resource ให้กับ MySQL เพิ่มอีก จน Server รับไม่ไหว

 

วิธีการที่จะรู้ว่า มี sql command ที่ทำงานช้าอยู่หรือไม่นั้น  ดูได้จาก mysql slow log นั่นเอง  ซึ่ง log นี้จะบันทึก คำสั่ง sql ที่ทำงานช้า ซึ่งจะนำไป วิเคราะห์ การทำงานได้ในภายหลัง

 

แล้วตัว Server เป็น Windows 2003 จะมีวิธีแก้เหมือนกันหรือเปล่าครับ.. วิธีการแก้ไขที่ดีคืออะไรครับ จากที่อ่าน หมายความว่า เราต้องแก้ไข โค้ด SQL command ของเราใหม่ ใช่หรือเปล่าครับ...

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

 วิธีการที่ผมเขียนไว้ข้างบน พอดีผมไม่สามารถแตะต้องซอร์สโค้ดได้ ได้แต่แนะนำทางผู้เขียนโปรแกรมขึ้นมา ให้ตรวจสอบซอร์สโค้ดครับ

:-) 

ถูกต้องแล้วต้องแก้ที่ต้นเหตุคือ Query และ ไม่ควรใช้ select * นะครับ

สำหรับ 2005 Views ที่มี order by เอาออกให้หมดนะครับ

แล้วมาใส่ตอน query แทน