Bagaimana cara membunuh MySQL dengan benar?

28

Saya memiliki CentOS 64bit dengan CPanel diinstal dan saya menggunakan:

service mysql stop

Itu terus berdetak periode dan sepertinya tidak pernah berhenti. Dalam log itu hanya memposting banyak:

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

Dalam err.logfile tersebut, saya melihat banyak dari ini:

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

Dulu instan. Adakah yang tahu mengapa ia melakukan itu dan bagaimana cara memperbaikinya?

Sekarang saya harus melakukan killall -9 mysqltetapi apakah ada cara yang lebih baik?

Servernya juga sangat sangat aktif.

Apakah ini masalah konfigurasi? Apakah saya memiliki pengaturan memroy terlalu tinggi?

[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
Paul White mengatakan GoFundMonica
sumber

Jawaban:

37

Cara paling licin untuk mematikan mysql saat itu adalah menjalankannya

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

Inilah alasannya:

File layanan mysql ( /etc/init.d/mysql) bergantung pada keberadaan file socket. Secara historis, akan kembali ke MySQL 4.0, file socket kadang-kadang menghilang secara tidak dapat dijelaskan. Ini menghambat standar service mysql stopuntuk bekerja.

Itu tidak cukup untuk mengatakan

mysqladmin -uroot -p -h127.0.0.1 shutdown

karena mysqld akan rute pengguna yang datang sebagai [email protected]untuk root@localhostjika TCP / IP tidak secara eksplisit diaktifkan. Secara default, mysqld akan memilih jalur paling perlawanan dan terhubung [email protected]ke root@localhostmelalui file socket. Namun, jika tidak ada file socket, root@localhosttidak akan pernah terhubung.

Bahkan Dokumentasi MySQL di mysqladmin mengatakan ini:

Jika Anda mengeksekusi shutdown mysqladmin ketika menghubungkan ke server lokal menggunakan file socket Unix, mysqladmin menunggu sampai file ID proses server telah dihapus, untuk memastikan bahwa server telah berhenti dengan benar.

Itulah mengapa sangat penting untuk mengaktifkan TCP / IP:

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

Kembali pada 30 September 2011, saya menulis versi saya sendiri yang mysqld_multidisebut mysqlservice(Lihat posting saya: Menjalankan beberapa instance pada host yang sama ). Ini berfungsi sebagai mesin virtual untuk menghubungkan ke mysqld dari port yang berbeda. Anda hanya perlu membawa my.cnfparameter Anda sendiri dengan parameter khusus. Dalam skrip itu, saya mengeluarkan shutdown seperti ini:

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
}

Tapi apa itu ${MYSQLD_STOP}?

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

Harap perhatikan saya menggunakan 127.0.0.1dan port eksplisit. Dengan begitu, saya tidak mengandalkan file socket.

Saya selalu menggunakan mysqladmin --protocol=tcp shtudownsebagai alternatif yang tepat untuk mematikan mysql jika service mysql stophang. Melakukan kill -9pada mysqlddan mysqld_safeharus yang terakhir yang terakhir resor terakhir. (Ya, saya katakan tiga kali terakhir).

Banyak kali, mysqld telah menghapus mysql.sock tanpa peringatan. Orang lain juga mengalami masalah ini selama bertahun-tahun:

EPILOG

Rahasianya sama seperti yang saya nyatakan: Hubungkan ke mysql menggunakan mysqladmin melalui TCP / IP ( --protocol=tcp) dan masalah shutdown. Ini harus berfungsi karena hak istimewa shutdown adalah mysql.useruntuk tujuan eksklusif shutdown terotentikasi. Ini telah menyelamatkan hari kerja saya beberapa kali ketika saya dapat mengeluarkan shutdown jarak jauh dari mesin Windows saya ketika mematikan mysqld pada server Linux.

UPDATE 2013-03-06 22:48 EST

Jika Anda khawatir tentang apa yang terjadi selama shutdown, ada cara untuk memanipulasi waktu shutdown dan cara data dibilas ke disk, terutama jika Anda memiliki banyak data InnoDB di Buffer Pool

SARAN # 1

Jika Anda memiliki banyak halaman kotor, Anda dapat menurunkan innodb_max_dirty_pages_pct menjadi 0:

SET GLOBAL innodb_max_dirty_pages_pct = 0;

Atur ini sekitar 15-30 menit sebelum dimatikan. Ini akan memberikan mysqld jumlah halaman kotor paling tidak mungkin untuk ditulis ke disk.

SARAN # 2

Secara default, innodb_fast_shutdown adalah 1. Ada tiga nilai untuk opsi ini

  • 0: InnoDB melakukan shutdown yang lambat, pembersihan penuh, dan penyangga buffer bergabung sebelum dimatikan.
  • 1: InnoDB melewatkan operasi ini pada saat shutdown, sebuah proses yang dikenal sebagai shutdown cepat.
  • 2: InnoDB membersihkan log-nya dan mati dingin, seolah-olah MySQL telah crash; tidak ada transaksi berkomitmen yang hilang, tetapi operasi pemulihan kerusakan membuat startup berikutnya lebih lama.

Dokumentasi lebih lanjut mengatakan ini:

Shutdown yang lambat bisa memakan waktu beberapa menit, atau bahkan berjam-jam dalam kasus ekstrim di mana sejumlah besar data masih buffer. Gunakan teknik shutdown lambat sebelum memutakhirkan atau menurunkan versi antara rilis utama MySQL, sehingga semua file data dipersiapkan sepenuhnya jika proses upgrade memperbarui format file.

Gunakan innodb_fast_shutdown = 2 dalam situasi darurat atau pemecahan masalah, untuk mendapatkan shutdown tercepat mutlak jika data beresiko korupsi.

Default untuk innodb_max_dirty_pages_pct dan innodb_fast_shutdown seharusnya baik-baik saja dalam kebanyakan kasus.

RolandoMySQLDBA
sumber
2
File soket menghilang pada turunan Red Hat karena tmpwatchmenghapusnya, bersama dengan segala sesuatu /tmpyang memiliki atime lebih lama dari ambang yang dikonfigurasi.
Michael - sqlbot
Terima kasih, @ Michael-sqlbot saya perlu mendengarnya dari seseorang, akhirnya. Saya kira itu sebabnya seseorang di MySQL AB (pra-Oracle, pre-Sun) memutuskan untuk menambahkan hak istimewa SHUTDOWN mysql.useruntuk mengatasi sakit kepala seperti ini.
RolandoMySQLDBA
Pada penggunaan Debian atau Ubuntu mysqladmin --defaults-file=/etc/mysql/debian.cnf shutdown... file itu berisi kredensial untuk akun MySQL seperti root.
0xC0000022L
Seperti biasa, @RolandoMySQLDBA Anda adalah salah satu sumber daya DBA terbaik di situs Stack Exchange. Kerja bagus di sini yang membantu saya 6+ tahun kemudian.
JakeGould
5

Kedengarannya pertanyaan Anda kurang tentang "bagaimana" mematikan MySQL dan lebih banyak tentang mengapa Anda dimatikan dengan sangat lambat.

Dalam jawaban saya untuk pertanyaan serupa , saya menawarkan beberapa saran untuk memulai kembali dengan lancar, yang membantu dengan mengurangi jumlah aktivitas yang harus terjadi setelah Anda meminta agar MySQL memulai proses penutupan .

Jika Anda bukan pengguna yang sering SHOW FULL PROCESSLIST;menggunakan item # 1 itu, karena Anda perlu mengetahui apa yang terjadi di server Anda, ini membuat shutdown menjadi sangat lambat. Jika ada permintaan yang berjalan lama yang aman untuk diinterupsi, Anda dapat membunuhnya KILL <thread-id>.

Mengembalikan saran lainnya:

Mengatur variabel global innodb_fast_shutdown = 1(default) akan mempercepat bagian InnoDB dari shutdown. Ini hanya aman, namun, jika Anda mematikan server karena alasan yang tidak terkait dengan melakukan peningkatan. Jika Anda dimatikan untuk peningkatan, ini harus diatur ke 0.

Menggunakan dengan FLUSH TABLES;anggun menutup semua tabel terbuka. Mereka akan dibuka kembali jika direferensikan oleh pertanyaan berikutnya, tetapi tindakan ini harus tetap pada akhirnya mengurangi waktu yang berlalu antara saat Anda meminta shutdown dan waktu shutdown selesai, karena melakukan beberapa pembersihan awal dan lebih penting lagi mengatur panggung untuk langkah terakhir ...

FLUSH TABLES WITH READ LOCK;menutup semua tabel terbuka dan mendapatkan kunci eksklusif yang dimiliki oleh koneksi klien Anda saat ini yang mencegah koneksi lain dari menulis ke tabel apa pun di seluruh server. Anda tidak akan mendapatkan mysql>konfirmasi kembali sampai Anda memiliki kunci ini, pada titik mana Anda dapat mengeluarkan permintaan penutupan - tetapi jangan terputus dari sesi ini.

Pada server yang sibuk, langkah-langkah ini harus mengurangi tingkat aktivitas di server, harus membuat segalanya lebih tenang, dan harus membantu membuat shutdown atau restart berjalan lebih lancar.

Michael - sqlbot
sumber
2

Kemungkinan MySQL tidak dikunci sepenuhnya, tetapi sedang melakukan aktivitas pembersihan (rollbacks, dll.) Saat dimatikan. Jika Anda tidak membiarkannya melakukan semua itu saat mematikan, seringkali Anda harus menunggu saat memulai.

Berikut ini sesuatu untuk dilihat: Matikan mysql di satu jendela terminal sambil menonton log kesalahan (tail -f [yourerror.log]) di jendela terminal lain. Log kesalahan akan menunjukkan kepada Anda apa yang sedang dilakukan MySQL.

Valerie Parham-Thompson
sumber
1

Saya menyesal mendengar tentang pengalaman Anda dan berharap pengalaman saya dengan skenario MySQL yang konyol, mirip dengan ini, dapat membantu Anda.

Alih-alih mencoba mencari cara untuk mematikan layanan MySQL dari server, dalam beberapa kasus, Anda perlu memeriksa kesehatan sistem Anda melalui yang berikut untuk menentukan apakah ada penyalahgunaan layanan ( asumsi didasarkan pada gagasan untuk Lingkungan CentOS / RHEL ):

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

Gunakan yang berikut ini untuk mengidentifikasi beban sistem rata-rata dan sumber daya yang paling banyak dikonsumsi dalam sistem.

Anda juga perlu menginstal mytopuntuk mendapatkan tampilan keseluruhan pada pernyataan SQL yang sedang diproses oleh sistem.

Untuk menginstal mytop, cukup lakukan hal berikut:

 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 

(gunakan editor teks apa saja yang Anda sukai)

Cari untuk "long|!" => \$config{long_nums},

Komentari sebagai #"long|!" => \$config{long_nums},

chmod 555 /usr/local/bin/mytop

Dan Anda baik untuk pergi dengan mytop . Gunakan untuk memeriksa pernyataan MySQL yang memonopoli layanan MySQL Anda dan menghentikannya.

Eksekusi instruksi di atas akan memberi Anda kemampuan berikut:

  • Diagnosis status / kesehatan server Anda
  • Diagnosis Anda adalah penyebab kemacetan

Setelah Anda menghilangkan penyebab kemacetan, Anda harus memiliki hari yang lebih mudah ketika Anda mencoba untuk me-restart layanan MySQL. Saya harap Anda akan menemukan informasi di atas bermanfaat.

Catatan: mytop kuno dan tidak terawat. Anda mungkin harus menggunakan innotopsistem modern.

Michael Feng
sumber
0

Implementasi standar dari init-script MySQL memberi sinyal MySQL dengan SIGTERM dan menunggu sejumlah waktu untuk MySQL dimatikan.

MySQL, setelah menerima SIGTERM, pertama-tama akan berhenti menerima koneksi baru, kemudian menyelesaikan mengeksekusi permintaan apa pun yang masih tertunda (ini bisa memakan waktu cukup lama, tergantung pada beban kerja Anda dan jumlah klien bersamaan), kemudian mulai menyiram data ke disk (ini dapat mengambil waktu yang lama, sekali lagi tergantung pada beban kerja Anda, konfigurasi, memori yang tersedia, dan pilihan mesin penyimpanan). Setelah semua pembilasan data dilakukan, MySQL kemudian akan membatalkan alokasi memori apa pun yang dialokasikan selama tahap inisialisasi (ini juga dapat memakan waktu cukup lama, tergantung pada jumlah memori yang dialokasikan oleh MySQL), tutup semua pegangan file yang masih terbuka, lalu panggil "keluar (0)".

Jika setelah permintaan Anda untuk mematikan MySQL membutuhkan waktu lama untuk dimatikan, sangat mungkin bahwa satu atau lebih tahapan ini membutuhkan waktu lama untuk diselesaikan. Jika Anda punya waktu, saya sangat menyarankan menunggu proses untuk menyelesaikan (ini akan menghindari kehilangan data atau proses pemulihan yang lama ketika Anda memulai contoh database Anda lagi).

Sayangnya tidak ada informasi yang cukup dalam pertanyaan Anda untuk memungkinkan saya menyarankan solusi yang tepat untuk masalah Anda. Saya harap ini membantu memahami masalah ini.

LMC
sumber