วิธีฆ่า MySQL อย่างถูกต้อง?


28

ฉันมี CentOS 64 บิตพร้อมติดตั้ง CPanel และฉันใช้:

service mysql stop

มันแค่ทำให้ช่วงเวลาฟ้องร้องและดูเหมือนว่ามันจะไม่หยุด ในบันทึกมันเพิ่งโพสต์เป็นจำนวนมาก:

130303 17:42:38 [Warning] /usr/sbin/mysqld: Forcing close of thread

ในerr.logไฟล์ฉันเห็นสิ่งเหล่านี้มากมาย:

[Warning] /usr/sbin/mysqld: Forcing close of thread

มันเคยเป็นแบบทันที ความคิดใด ๆ ว่าทำไมถึงเป็นเช่นนั้นและจะแก้ไขอย่างไร

ตอนนี้ฉันต้องทำkillall -9 mysqlแต่จะมีวิธีที่ดีกว่า

เซิร์ฟเวอร์ใช้งานได้ดีมาก

นี่เป็นปัญหาการกำหนดค่าหรือไม่ ฉันมีการตั้งค่า memroy สูงเกินไปหรือไม่

[mysqld]
default-storage-engine=MyISAM
local-infile=0
symbolic-links=0
skip-networking
max_connections = 500
max_user_connections = 20
key_buffer = 512M
myisam_sort_buffer_size = 64M
join_buffer_size = 64M
read_buffer_size = 12M
sort_buffer_size = 12M
read_rnd_buffer_size = 12M
table_cache = 2048
thread_cache_size = 16K
wait_timeout = 30
connect_timeout = 15
tmp_table_size = 64M
max_heap_table_size = 64M
max_allowed_packet = 64M
max_connect_errors = 10
query_cache_limit = 1M
query_cache_size = 64M
query_cache_type = 1
low_priority_updates=1
concurrent_insert=ALWAYS
log-error=/var/log/mysql/error.log
tmpdir=/home/mysqltmp
myisam_repair_threads=4
[mysqld_safe]
open_files_limit = 8192
log-error=/var/log/mysql/error.log

[mysqldump]
quick
max_allowed_packet = 512M

[myisamchk]
key_buffer = 64M
sort_buffer = 64M
read_buffer = 16M
write_buffer = 16M

คำตอบ:


37

วิธีที่ลื่นที่สุดในการปิด mysql เมื่อทำเช่นนั้นคือการเรียกใช้

mysqladmin -uroot -p -h127.0.0.1 --protocol=tcp shutdown

นี่คือเหตุผล:

ไฟล์บริการ mysql ( /etc/init.d/mysql) ขึ้นอยู่กับการมีอยู่ของไฟล์ซ็อกเก็ต เมื่อพูดไปแล้วกลับไปสู่ ​​MySQL 4.0 ไฟล์ซ็อกเก็ตบางครั้งก็หายไปอย่างลึกลับ นี่เป็นมาตรฐานในservice mysql stopการทำงาน

มันไม่เพียงพอที่จะพูด

mysqladmin -uroot -p -h127.0.0.1 shutdown

เพราะ mysqld ประสงค์เส้นทางที่ผู้ใช้เข้ามาในฐานะroot@127.0.0.1ที่จะroot@localhostถ้า TCP / IP ไม่ได้เปิดใช้อย่างชัดเจน โดยค่าเริ่มต้น mysqld จะเลือกเส้นทางที่น้อยที่สุดของความต้านทานและเชื่อมต่อroot@127.0.0.1ไปroot@localhostผ่านทางไฟล์ซ็อกเก็ต แต่ถ้าไม่มีไฟล์ซ็อกเก็ตroot@localhostจะไม่เชื่อมต่อ

แม้แต่เอกสาร MySQL บน mysqladmin ก็บอกว่า:

หากคุณเรียกใช้ mysqladmin เมื่อปิดการเชื่อมต่อกับเซิร์ฟเวอร์ภายในโดยใช้ไฟล์ซ็อกเก็ต Unix mysqladmin จะรอจนกว่าไฟล์ ID กระบวนการของเซิร์ฟเวอร์จะถูกลบออกเพื่อให้แน่ใจว่าเซิร์ฟเวอร์หยุดทำงานอย่างถูกต้อง

นี่คือสาเหตุที่จำเป็นต้องเปิดใช้งาน TCP / IP:

mysqladmin -uroot -p -h127.0.0.1 --protocol=tcp shutdown

ย้อนกลับไปเมื่อวันที่ 30 กันยายน 2011 ฉันเขียนสคริปต์เวอร์ชันที่ฉันmysqld_multiเรียกmysqlservice(ดูโพสต์ของฉัน: เรียกใช้อินสแตนซ์หลายรายการบนโฮสต์เดียวกัน ) มันทำหน้าที่เป็นเสมือนเครื่องมือสำหรับเชื่อมต่อกับ mysqld จากพอร์ตที่แตกต่างกัน คุณเพียงแค่ต้องนำmy.cnfพารามิเตอร์ของคุณเองมาเอง ในสคริปต์นั้นฉันออกการปิดระบบเช่นนี้:

stop() {
  ${ECHO} -n $"Stopping ${PROGNAME}"
  ${MYSQLD_STOP}
  ATTEMPTS=0
  STOPPING_MYSQLD=1
  MINUTES_TO_TRY=10
  (( TICKS_TO_TRY = MINUTES_TO_TRY*240 ))
  while [ ${STOPPING_MYSQLD} -eq 1 ]
  do
    ${ECHO} -n "."
    ${SLEEP} 0.25
    MYSQLD_HAS_BEEN_SHUTDOWN=`${TAIL} ${MYSQL_ERROR_LOG} | ${GREP} -c "Shutdown complete$"`
    (( ATTEMPTS++ ))
    if [ ${ATTEMPTS} -eq ${TICKS_TO_TRY}   ] ; then STOPPING_MYSQLD=0 ; fi
    if [ ${MYSQLD_HAS_BEEN_SHUTDOWN} -eq 1 ] ; then STOPPING_MYSQLD=2 ; fi
  done
  ${ECHO}
  if [ ${STOPPING_MYSQLD} -eq 2 ]
  then
    ${ECHO} "Stopped ${PROGNAME}"
  else
    ${TAIL} -30 ${MYSQL_ERROR_LOG}
  fi
}

แต่สิ่งที่เป็น${MYSQLD_STOP}?

MYSQL_CONN="-uroot -p<rootpassword> -P${MYSQLD_PORT} -h127.0.0.1 --protocol=tcp"
MYSQLD_STOP="${MYSQLADMIN} ${MYSQL_CONN} shutdown"

โปรดสังเกตว่าฉันใช้127.0.0.1และพอร์ตที่ชัดเจน ด้วยวิธีนี้ฉันไม่ได้ใช้ไฟล์ซ็อกเก็ต

ฉันมักจะใช้mysqladmin --protocol=tcp shtudownเป็นทางเลือกที่เหมาะสมในการปิด mysql ถ้าservice mysql stopแฮงค์ ทำkill -9บนmysqldและmysqld_safeควรสุดท้ายของสุดท้ายของรีสอร์ทที่ผ่านมา (ใช่ฉันพูดไปสามครั้งแล้ว)

หลายครั้ง mysqld ได้ลบ mysql.sock โดยไม่มีการเตือนล่วงหน้า คนอื่นมีปัญหานี้เช่นกันในช่วงหลายปีที่ผ่านมา:

บทส่งท้าย

ความลับอยู่เช่นเดียวกับผมระบุ: เชื่อมต่อกับ MySQL ใช้mysqladminผ่าน TCP / IP ( --protocol=tcp) shutdownและปัญหา สิ่งนี้ต้องใช้งานได้เนื่องจากสิทธิ์การปิดเครื่องนั้นมีไว้mysql.userเพื่อวัตถุประสงค์เฉพาะของการปิดระบบที่ผ่านการตรวจสอบความถูกต้องแล้ว สิ่งนี้ได้บันทึกวันทำงานของฉันสองสามครั้งเมื่อฉันสามารถออกการปิดระยะไกลจากเครื่อง Windows ของฉันเมื่อปิด mysqld บนเซิร์ฟเวอร์ Linux

อัพเดท 2013-03-06 22:48 EST

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

คำแนะนำ # 1

หากคุณมีหน้าสกปรกจำนวนมากคุณสามารถลดinnodb_max_dirty_pages_pctเป็น 0:

SET GLOBAL innodb_max_dirty_pages_pct = 0;

ตั้งค่านี้ประมาณ 15-30 นาทีก่อนปิดเครื่อง นี้จะให้ mysqld จำนวนหน้าสกปรกน้อยที่สุดที่เป็นไปได้ในการเขียนไปยังดิสก์

คำแนะนำ # 2

โดยค่าเริ่มต้นinnodb_fast_shutdownคือ 1 มีสามค่าสำหรับตัวเลือกนี้

  • 0: InnoDB ทำการปิดระบบช้าการล้างข้อมูลแบบเต็มและการแทรกบัฟเฟอร์แบบผสานก่อนที่จะปิดเครื่อง
  • 1: InnoDB ข้ามการดำเนินการเหล่านี้เมื่อปิดระบบซึ่งเป็นกระบวนการที่เรียกว่าการปิดระบบอย่างรวดเร็ว
  • 2: InnoDB จะล้างบันทึกและปิดการทำงานของความเย็นราวกับว่า MySQL ขัดข้อง ไม่มีการทำธุรกรรมที่มุ่งมั่นจะหายไป แต่การดำเนินการกู้คืนความผิดพลาดทำให้การเริ่มต้นครั้งต่อไปใช้เวลานานขึ้น

เอกสารอธิบายเพิ่มเติมว่า:

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

ใช้ innodb_fast_shutdown = 2 ในสถานการณ์ฉุกเฉินหรือการแก้ไขปัญหาเพื่อให้ได้การปิดระบบที่รวดเร็วที่สุดหากข้อมูลมีความเสี่ยงต่อความเสียหาย

ค่าเริ่มต้นสำหรับ innodb_max_dirty_pages_pct และ innodb_fast_shutdown น่าจะใช้ได้ในกรณีส่วนใหญ่


2
ไฟล์ซ็อกเก็ตจะหายไปใน Red Hat อนุพันธ์เพราะtmpwatchลบมันรวมถึงทุกอย่างใน/tmpที่มีเวลาเก่ากว่าเกณฑ์ที่กำหนดไว้
Michael - sqlbot

ขอบคุณ @ Michael-sqlbot ฉันต้องการได้ยินจากใครบางคนในที่สุด ฉันคิดว่านั่นเป็นสาเหตุที่ใครบางคนที่ MySQL AB (pre-Oracle, pre-Sun) ตัดสินใจที่จะเพิ่มสิทธิ์ SHUTDOWN mysql.userเพื่อหลีกเลี่ยงอาการปวดหัวแบบนี้
RolandoMySQLDBA

บน Debian หรือ Ubuntu ให้ใช้mysqladmin --defaults-file=/etc/mysql/debian.cnf shutdown... ไฟล์นั้นมีข้อมูลรับรองสำหรับบัญชี MySQL แบบรูท
0xC0000022L

ตามปกติ @RolandoMySQLDBA คุณเป็นหนึ่งในแหล่งข้อมูล DBA ที่ดีที่สุดในไซต์ Stack Exchange ผลงานยอดเยี่ยมที่นี่ช่วยฉันในอีก 6 ปีต่อมา
JakeGould

5

ดูเหมือนว่าคำถามของคุณเกี่ยวกับ "วิธีการ" ปิด MySQL น้อยลงและเพิ่มเติมเกี่ยวกับสาเหตุที่ทำให้คุณปิดตัวลงอย่างช้าๆ

ในคำตอบของฉันคำถามที่คล้ายกันผมนำเสนอข้อเสนอแนะบางอย่างสำหรับการเริ่มต้นใหม่ได้อย่างราบรื่นซึ่งความช่วยเหลือโดยการลดจำนวนของกิจกรรมที่มีจะเกิดขึ้นหลังจากที่คุณขอให้ MySQL เริ่มต้นการปิดระบบ

หากคุณไม่ใช่ผู้ใช้ประจำของSHOW FULL PROCESSLIST;รายการนั้น # 1 เพราะคุณจำเป็นต้องรู้ว่าเกิดอะไรขึ้นในเซิร์ฟเวอร์ของคุณซึ่งทำให้การปิดระบบช้าลง KILL <thread-id>หากมียาวทำงานคำสั่งที่มีความปลอดภัยที่จะขัดขวางคุณสามารถฆ่าพวกเขาด้วย

Recapping คำแนะนำอื่น ๆ :

การตั้งค่าตัวแปรส่วนกลางinnodb_fast_shutdown = 1(ค่าเริ่มต้น) จะช่วยเร่งการปิดระบบของ InnoDB อย่างไรก็ตามนี่จะปลอดภัยเท่านั้นหากคุณปิดเซิร์ฟเวอร์ด้วยเหตุผลที่ไม่เกี่ยวข้องกับการอัปเกรด หากคุณกำลังปิดตัวเพื่ออัปเกรดต้องตั้งค่าเป็น 0

การใช้FLUSH TABLES;ปิดตารางที่เปิดอยู่ทั้งหมดอย่างงดงาม พวกเขาจะถูกเปิดอีกครั้งหากมีการอ้างอิงโดยการสืบค้นที่ตามมา แต่การกระทำนี้ควรจะลดเวลาที่ผ่านไประหว่างเวลาที่คุณขอให้ปิดเครื่องและเวลาที่การปิดระบบเสร็จสมบูรณ์ในที่สุด สำหรับขั้นตอนสุดท้าย ...

FLUSH TABLES WITH READ LOCK;ปิดตารางที่เปิดอยู่ทั้งหมดและรับการล็อคแบบเอกสิทธิ์เฉพาะบุคคลจากการเชื่อมต่อไคลเอนต์ปัจจุบันของคุณซึ่งป้องกันการเชื่อมต่ออื่น ๆ จากการเขียนไปยังตารางใด ๆ บนเซิร์ฟเวอร์ทั้งหมด คุณจะไม่ได้รับmysql>พรอมต์จนกว่าคุณจะเป็นเจ้าของล็อคซึ่ง ณ จุดนี้คุณสามารถออกคำขอปิดระบบได้ แต่อย่าตัดการเชื่อมต่อจากเซสชันนี้

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


2

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

นี่คือสิ่งที่ต้องดู: ปิด mysql ในหน้าต่างเทอร์มินัลหนึ่งขณะที่ดูบันทึกข้อผิดพลาด (tail -f [yourerror.log]) ในหน้าต่างเทอร์มินัลอื่น บันทึกข้อผิดพลาดจะแสดงให้คุณเห็นว่า MySQL กำลังทำอะไรอยู่


1

ฉันขอโทษที่ได้ยินเกี่ยวกับประสบการณ์ของคุณและหวังว่าประสบการณ์ของฉันกับสถานการณ์ MySQL ที่เหลวไหลเช่นนี้จะช่วยคุณได้

แทนที่จะพยายามหาวิธีกำจัดบริการ MySQL จากเซิร์ฟเวอร์ในบางกรณีคุณจะต้องตรวจสอบสถานะของระบบของคุณผ่านทางต่อไปนี้เพื่อตรวจสอบว่ามีการใช้บริการที่ไม่เหมาะสมหรือไม่ สภาพแวดล้อม CentOS / RHEL ):

 /usr/bin/iostat
 /usr/bin/uptime
 top -c

ใช้ข้อมูลต่อไปนี้เพื่อระบุภาระของระบบโดยเฉลี่ยและทรัพยากรที่ใช้มากที่สุดภายในระบบ

คุณจะต้องติดตั้งmytopเพื่อรับมุมมองโดยรวมเกี่ยวกับคำสั่ง SQL ที่กำลังถูกประมวลผลโดยระบบ

ในการติดตั้งmytopเพียงดำเนินการดังนี้:

 cd /root
 wget http://jeremy.zawodny.com/mysql/mytop/mytop-1.6.tar.gz
 tar -zxvf /root/mytop-1.6.tar.gz
 cd /root/mytop-1.6
 perl Makefile.pl
 make
 make install
 chmod 644 /usr/local/bin/mytop
 vi /usr/local/bin/mytop 

(ใช้โปรแกรมแก้ไขข้อความใด ๆ ที่คุณต้องการ)

ค้นหา"long|!" => \$config{long_nums},

แสดงความคิดเห็นออกเป็น#"long|!" => \$config{long_nums},

chmod 555 /usr/local/bin/mytop

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

การปฏิบัติตามคำแนะนำข้างต้นจะช่วยให้คุณมีความสามารถดังต่อไปนี้:

  • การวินิจฉัยสถานะ / สุขภาพของเซิร์ฟเวอร์ของคุณ
  • การวินิจฉัยสาเหตุของปัญหาคอขวดของคุณ

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

หมายเหตุ: mytopโบราณและไร้สี คุณควรใช้innotopกับระบบที่ทันสมัย


0

การใช้งานมาตรฐานของสคริปต์เริ่มต้นของ MySQL ส่งสัญญาณ MySQL ด้วย SIGTERM และรอเป็นระยะเวลาหนึ่งที่ MySQL จะปิดตัวลง

MySQL หลังจากที่ได้รับ SIGTERM จะหยุดรับการเชื่อมต่อใหม่ก่อนจากนั้นจึงดำเนินการสืบค้นใด ๆ ที่ยังค้างอยู่ (ซึ่งอาจใช้เวลาสักครู่ขึ้นอยู่กับปริมาณงานและจำนวนไคลเอนต์ที่ทำงานพร้อมกัน) จากนั้นเริ่มล้างข้อมูลลงดิสก์ เป็นเวลานานขึ้นอยู่กับปริมาณงานการกำหนดค่าหน่วยความจำที่มีอยู่และตัวเลือกเครื่องมือจัดเก็บข้อมูลของคุณ) หลังจากล้างข้อมูลเสร็จสิ้นแล้ว MySQL จะทำการจัดสรรคืนหน่วยความจำที่จัดสรรไว้ในระหว่างขั้นตอนการเริ่มต้น (ซึ่งอาจใช้เวลาสักครู่ขึ้นอยู่กับจำนวนหน่วยความจำที่จัดสรรโดย MySQL) ปิดการจัดการไฟล์ทั้งหมดที่ยังคงเปิดอยู่ "ทางออก (0)"

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

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

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