aralıklı MySQL “Önemli hata: arabellek havuzu için bellek ayıramıyor” hatasıyla çöküyor


40

Düzenleme eklendi, 2013-05-29: Bu uzun bir soru ve tartışma olduğundan, soru ve çözümün kısa bir özeti. MySQL ve Apache'yi küçük bir Linux sunucusunda (1 GB bellek) çalıştırırken sorun yaşadım. Apache daha fazla hafıza talep etmeye devam etti ve bir sonuç olarak, OS her zaman hafızasını geri kazanmak için MySQL'i öldürdü. Çözüm , Apache'yi Lighttpd ile değiştirmekti. Bunu yaptıktan sonra, sunucudaki bellek kullanımı birkaç aydır tamamen stabildi ve hiçbir şekilde çökme olmadı. düzenlemenin sonu

Küçük bir sanal sunucu için acemi bir sistem yöneticisiyim. Sunucunun temel işlevi, PHP ile yazılmış açık kaynaklı Moodle kurs yönetim sistemi yazılımını çalıştırmaktır . Bu durumda bir veritabanına, bu durumda MySQL'e ve bir web sunucusuna, bu durumda Apache'ye güvenir.

Sunucu 64 bit CentOS yayın 5.8 (Final) ile çalışıyor ve 1 GB bellek ve 200 GB disk, 2.6.18-308.8.2.el5xen sürümüne sahip. MySQL sürümü, Verline 14.14 Distribüt 5.5.25'tir, Linux için (x86_64) readline 5.1'i kullanıyor.

Moodle yazılımının MySQL'in çok ağır bir kullanıcısı olduğunu sanmıyorum. Şu anda, sadece yaklaşık on öğretmen buna erişebiliyor ve bzip2 ile tüm veritabanını boşalttığımda ve sıkıştırdığımda, ortaya çıkan boşluğun boyutu 1 MB'tan az.

Sistemi birkaç ay önce kurdum. Apache sunucusu bu zamana kadar stabildi, fakat MySQL birkaç kez çöktü. Web'den optimum yapılandırma hakkında bilgi almaya çalıştım ve /etc/my.cnfdosyayı en son değiştirdiğimde, /usr/share/doc/mysql55-server-5.5.25/my-large.cnförnek olarak MySQL ile gelen dosyayı kullandım . Dosya 512 MB belleğe sahip sistemler için olduğunu söylüyor, bu yüzden bellekle ilgili yapılandırma parametrelerinin kullanılmasının bu sistem için güvenli olacağını düşündüm. (. Daha önce çok daha küçük sayılarla MySQL'ın bellek ilgili parametreleri konfigüre etmişti, ve bunu kazalara yol düşündüm çöker yine de oluşur ederken, sistem artık daha hızlı, en azından budur.) Bunlar şu anki içerikleri şunlardır /etc/my.cnf:

# /etc/my.cfg

# The main and only MySQL configuration file on [WEBSITE ADDRESS REDACTED].
# Last updated 2012-09-23 by Teemu Leisti.

# Most of the memory settings are set to be the same as the example setting file
# /usr/share/doc/mysql55-server-5.5.25/my-large.cnf, which is meant for systems
# with 512M of memory.  This server currently has twice that, i.e. 1G of memory,
# which should make these settings safe.


[client]
default_character_set           = utf8
port                            = 3306
socket                          = /var/lib/mysql/mysql.sock

[mysqld]
character_set_filesystem        = utf8
character_set_server            = utf8
datadir                         = /var/lib/mysql
innodb_additional_mem_pool_size = 20M
innodb_buffer_pool_size         = 256M # You can set .._buffer_pool_size up to
                                       # 50..80% of RAM, but beware of setting
                                       # memory usage too high
innodb_data_file_path           = ibdata1:10M:autoextend
innodb_data_home_dir            = /var/lib/mysql
innodb_flush_log_at_trx_commit  = 1
innodb_lock_wait_timeout        = 50
innodb_log_buffer_size          = 8M
innodb_log_file_size            = 64M # Set .._log_file_size to 25% of buffer
                                      # pool size
innodb_log_group_home_dir       = /var/lib/mysql
interactive_timeout             = 60
key_buffer_size                 = 256M
long_query_time                 = 10
max_allowed_packet              = 1M
max_connections                 = 30
port                            = 3306
query_cache_limit               = 2M # see http://emergent.urbanpug.com/?p=61
query_cache_size                = 16M
read_buffer_size                = 1M
read_rnd_buffer_size            = 4M
skip_networking                 # Only local processes need to use MySQL
skip_symbolic_links             # Disabling symbolic_links is recommended to
                                # prevent assorted security risks
slow_query_log_file             = /var/log/mysql-slow-queries.log
socket                          = /var/lib/mysql/mysql.sock
sort_buffer_size                = 1M
table_open_cache                = 256
thread_cache_size               = 8
thread_concurrency              = 2 #    = number of CPUs * 2
user                            = mysql
wait_timeout                    = 10

[mysqld_safe]
log_error                       = /var/log/mysqld.log
open_files_limit                = 4096
pid_file                        = /var/run/mysqld/mysqld.pid

[mysqldump]
quick
max_allowed_packet              = 16M

[mysql]
no-auto-rehash
# Remove the next comment character if you are not familiar with SQL
safe-updates

[myisamchk]
key_buffer_size                 = 128M
sort_buffer_size                = 128M
read_buffer                     = 2M
write_buffer                    = 2M

[mysqlhotcopy]
interactive-timeout

Yapılandırmada görebileceğiniz gibi, kurulum InnoDB motorunu kullanır ve yalnızca localhost'tan gelen isteklere hizmet eder. Sistem yöneticisinin dışında (ben), Moodle, MySQL'in tek kullanıcısıdır.

MySQL çöktüğünde, aşağıdakiler her zaman günlük dosyasına yazılır /var/log/mysqld.log(tabii ki zaman damgaları hariç):

120926 08:00:51 mysqld_safe Number of processes running now: 0
120926 08:00:51 mysqld_safe mysqld restarted
120926  8:00:53 [Note] Plugin 'FEDERATED' is disabled.
120926  8:00:53 InnoDB: The InnoDB memory heap is disabled
120926  8:00:53 InnoDB: Mutexes and rw_locks use GCC atomic builtins
120926  8:00:53 InnoDB: Compressed tables use zlib 1.2.3
120926  8:00:53 InnoDB: Using Linux native AIO
120926  8:00:53 InnoDB: Initializing buffer pool, size = 256.0M
InnoDB: mmap(274726912 bytes) failed; errno 12
120926  8:00:53 InnoDB: Completed initialization of buffer pool
120926  8:00:53 InnoDB: Fatal error: cannot allocate memory for the buffer pool
120926  8:00:53 [ERROR] Plugin 'InnoDB' init function returned error.
120926  8:00:53 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
120926  8:00:53 [ERROR] Unknown/unsupported storage engine: InnoDB
120926  8:00:53 [ERROR] Aborting

120926  8:00:53 [Note] /usr/libexec/mysqld: Shutdown complete

120926 08:00:53 mysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended

Bazen emriyle MySQL yeniden başlatabilirsiniz service mysqld restartkomut bu çıkışı ile başarısız bazen ama: mysqld dead but subsys locked. Bu gibi durumlarda, durumu düzeltmeyi düşünebildiğim tek şey sunucuyu yeniden başlatmak ve ardından MySQL'in yeniden başlatılmasını sağlamak. Bu durumlarda, çıktı şöyle görünür:

120926 11:43:48 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
120926 11:43:48 [Note] Plugin 'FEDERATED' is disabled.
120926 11:43:48 InnoDB: The InnoDB memory heap is disabled
120926 11:43:48 InnoDB: Mutexes and rw_locks use GCC atomic builtins
120926 11:43:48 InnoDB: Compressed tables use zlib 1.2.3
120926 11:43:48 InnoDB: Using Linux native AIO
120926 11:43:48 InnoDB: Initializing buffer pool, size = 256.0M
120926 11:43:48 InnoDB: Completed initialization of buffer pool
120926 11:43:48 InnoDB: highest supported file format is Barracuda.
InnoDB: The log sequence number in ibdata files does not match
InnoDB: the log sequence number in the ib_logfiles!
120926 11:43:48  InnoDB: Database was not shut down normally!
InnoDB: Starting crash recovery.
InnoDB: Reading tablespace information from the .ibd files...
InnoDB: Restoring possible half-written data pages from the doublewrite
InnoDB: buffer...
120926 11:43:51  InnoDB: Waiting for the background threads to start
120926 11:43:52 InnoDB: 1.1.8 started; log sequence number 466807107
120926 11:43:52 [Note] Event Scheduler: Loaded 0 events
120926 11:43:52 [Note] /usr/libexec/mysqld: ready for connections.
Version: '5.5.25'  socket: '/var/lib/mysql/mysql.sock'  port: 0  MySQL Community Server (GPL)

İşte komut free -mşu anda ne çıktı:

# free -m
             total       used       free     shared    buffers     cached
Mem:          1024        869        154          0         70        153
-/+ buffers/cache:        644        379
Swap:            0          0          0

Genellikle "boş" sütun 50 ila 100 MB arasındadır.

Komutun çıktısı ulimit -a:

# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 8192
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 8192
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

Bunun dışında Moodle'ın ayar veya kod dosyalarını değiştirmedim, bunun dışında /var/www/html/moodle/config.php(yer kazanmak için yorum satırları silindi):

<?php
unset($CFG);  // Ignore this line
global $CFG;  // This is necessary here for PHPUnit execution
$CFG = new stdClass();
$CFG->dbtype    = 'mysqli';           // 'pgsql', 'mysqli', 'mssql', 'sqlsrv' or 'oci'
$CFG->dblibrary = 'native';           // 'native' only at the moment
$CFG->dbhost    = 'localhost';        // eg 'localhost' or 'db.isp.com' or IP
$CFG->dbname    = 'moodle';           // database name, eg moodle
$CFG->dbuser    = 'moodleuser';       // your database username
$CFG->dbpass    = '[REDACTED]';       // your database password
$CFG->prefix    = 'moodle_';          // prefix to use for all table names
$CFG->dboptions = array(
    'dbpersist' => false,       // should persistent database connections be
                                //  used? set to 'false' for the most stable
                                //  setting, 'true' can improve performance
                                //  sometimes
    'dbsocket'  => true,        // should connection via UNIX socket be used?
                                //  if you set it to 'true' or custom path
                                //  here set dbhost to 'localhost',
                                //  (please note mysql is always using socket
                                //  if dbhost is 'localhost' - if you need
                                //  local port connection use '127.0.0.1')
    'dbport'    => '',          // the TCP port number to use when connecting
                                //  to the server. keep empty string for the
                                //  default port
);
$CFG->passwordsaltmain = '[REDACTED]';
$CFG->wwwroot   = 'http://[REDACTED]';
$CFG->dataroot  = '/var/moodledata';
$CFG->directorypermissions = 02777;
$CFG->admin = 'admin';
date_default_timezone_set('Europe/Helsinki');
$CFG->disableupdatenotifications = true;
require_once(dirname(__FILE__) . '/lib/setup.php'); // Do not edit

(Ancak, iki Moodle eklentisi, Seyirci modülü ve blok kurdum, ancak bu soruna nasıl dahil olabileceklerini anlamıyorum.)

/etc/my.cnfBir hafta önce şimdiki durumuna güncelledikten sonra bile , MySQL yukarıda belirtilen belirtilerle birkaç kez çöktü. Veri tabanı yönetiminde yeni bir başlangıç ​​yapmak ve bu sorunla ilgili çok fazla googling yaptıktan sonra ne yapacağımı kaybediyorum. Baska öneri? Daha fazla yapılandırma verisi göndermeli miyim?

Düzenlemeye ek olarak:

Dosyanın içeriği /var/log/messages.1:

Sep 23 04:02:18 [machine name] syslogd 1.4.1: restart.
Sep 26 08:00:51 [machine name] kernel: mysqld invoked oom-killer: gfp_mask=0x201d2, order=0, oomkilladj=0
Sep 26 08:00:51 [machine name] kernel:
Sep 26 08:00:51 [machine name] kernel: Call Trace:
Sep 26 08:00:51 [machine name] kernel:  [<ffffffff802c1bd5>] out_of_memory+0x8b/0x203
Sep 26 08:00:51 [machine name] kernel:  [<ffffffff8020fa49>] __alloc_pages+0x27f/0x308
Sep 26 08:00:51 [machine name] kernel:  [<ffffffff802139c9>] __do_page_cache_readahead+0xc8/0x1af
Sep 26 08:00:51 [machine name] kernel:  [<ffffffff8021423a>] filemap_nopage+0x14c/0x360
Sep 26 08:00:51 [machine name] kernel:  [<ffffffff80208e9d>] __handle_mm_fault+0x444/0x144f
Sep 26 08:00:51 [machine name] kernel:  [<ffffffff80263929>] _spin_lock_irqsave+0x9/0x14
Sep 26 08:00:51 [machine name] kernel:  [<ffffffff8023f468>] lock_timer_base+0x1b/0x3c
Sep 26 08:00:51 [machine name] kernel:  [<ffffffff80266d94>] do_page_fault+0xf72/0x131b
Sep 26 08:00:51 [machine name] kernel:  [<ffffffff802e5f4f>] sys_io_getevents+0x311/0x359
Sep 26 08:00:51 [machine name] kernel:  [<ffffffff802e4e56>] timeout_func+0x0/0x10
Sep 26 08:00:51 [machine name] kernel:  [<ffffffff8025f82b>] error_exit+0x0/0x6e
Sep 26 08:00:51 [machine name] kernel:
Sep 26 08:00:51 [machine name] kernel: Mem-info:
Sep 26 08:00:51 [machine name] kernel: DMA per-cpu:
Sep 26 08:00:51 [machine name] kernel: cpu 0 hot: high 0, batch 1 used:0
Sep 26 08:00:51 [machine name] kernel: cpu 0 cold: high 0, batch 1 used:0
Sep 26 08:00:51 [machine name] kernel: DMA32 per-cpu:
Sep 26 08:00:51 [machine name] kernel: cpu 0 hot: high 186, batch 31 used:117
Sep 26 08:00:51 [machine name] kernel: cpu 0 cold: high 62, batch 15 used:53
Sep 26 08:00:51 [machine name] kernel: Normal per-cpu: empty
Sep 26 08:00:51 [machine name] kernel: HighMem per-cpu: empty
Sep 26 08:00:51 [machine name] kernel: Free pages:        7256kB (0kB HighMem)
Sep 26 08:00:51 [machine name] kernel: Active:241649 inactive:0 dirty:0 writeback:0 unstable:0 free:1814 slab:4104 mapped-file:1153 mapped-anon:240592 pagetables:3298
Sep 26 08:00:51 [machine name] kernel: DMA free:3268kB min:32kB low:40kB high:48kB active:0kB inactive:0kB present:9068kB pages_scanned:0 all_unreclaimable? yes
Sep 26 08:00:51 [machine name] kernel: lowmem_reserve[]: 0 994 994 994
Sep 26 08:00:51 [machine name] kernel: DMA32 free:3988kB min:4016kB low:5020kB high:6024kB active:966596kB inactive:0kB present:1018080kB pages_scanned:6327262 all_unreclaimable? yes
Sep 26 08:00:52 [machine name] kernel: lowmem_reserve[]: 0 0 0 0
Sep 26 08:00:52 [machine name] kernel: Normal free:0kB min:0kB low:0kB high:0kB active:0kB inactive:0kB present:0kB pages_scanned:0 all_unreclaimable? no
Sep 26 08:00:52 [machine name] kernel: lowmem_reserve[]: 0 0 0 0
Sep 26 08:00:52 [machine name] kernel: HighMem free:0kB min:128kB low:128kB high:128kB active:0kB inactive:0kB present:0kB pages_scanned:0 all_unreclaimable? no
Sep 26 08:00:52 [machine name] kernel: lowmem_reserve[]: 0 0 0 0
Sep 26 08:00:52 [machine name] kernel: DMA: 1*4kB 2*8kB 1*16kB 1*32kB 2*64kB 2*128kB 1*256kB 1*512kB 2*1024kB 0*2048kB 0*4096kB = 3268kB
Sep 26 08:00:52 [machine name] kernel: DMA32: 17*4kB 2*8kB 2*16kB 1*32kB 0*64kB 0*128kB 1*256kB 1*512kB 1*1024kB 1*2048kB 0*4096kB = 3988kB
Sep 26 08:00:52 [machine name] kernel: Normal: empty
Sep 26 08:00:52 [machine name] kernel: HighMem: empty
Sep 26 08:00:52 [machine name] kernel: 1214 pagecache pages
Sep 26 08:00:52 [machine name] kernel: Swap cache: add 0, delete 0, find 0/0, race 0+0
Sep 26 08:00:52 [machine name] kernel: Free swap  = 0kB
Sep 26 08:00:52 [machine name] kernel: Total swap = 0kB
Sep 26 08:00:52 [machine name] kernel: Free swap:            0kB
Sep 26 08:00:52 [machine name] kernel: 262144 pages of RAM
Sep 26 08:00:52 [machine name] kernel: 8320 reserved pages
Sep 26 08:00:52 [machine name] kernel: 22510 pages shared
Sep 26 08:00:52 [machine name] kernel: 0 pages swap cached
Sep 26 08:00:52 [machine name] kernel: Out of memory: Killed process 1371, UID 27, (mysqld).

ve 11: 42'de yeniden başlatma ile ilgili çizgiler.

# 2 numaralı düzenlemeye ek olarak:

Michael'ın cevabı hakkında yorum yapmaya çalıştım, ancak yorum karakterinin sınırlarını aştım, bu yüzden burada cevap veriyorum.

Cevabınız için teşekkürler, Michael. Kaza anında makinenin sistem günlüğünün içeriğini içerecek şekilde sorumu değiştirdim. (CentOS sistem günlüğünü çağırıyor gibi görünüyor /var/log/messages.)

Evet, hem MySQL hem de sistem günlükleri, bağlantı kurduğunuz sorudakilerle neredeyse aynı görünüyor. Ve şimdi bahsettiğinize göre, mysql restartedmesajın MySQL'in zaten çökmüş olduğu anlamına geliyor. Sistem günlüğü oom_killer, sürecin ne olduğunu gösteriyor . Daha önceki cevabınızda şunu yazıyorsunuz: "İlk tahmin: apache alt süreçleri çalıştırılmıyor." Bana da Apache'nin burada da şüpheli olduğu sanıyor.

Daha önce, Kısım 1'de Düşük Bellek Kullanımı için MySQL ve Apache'yi Optimize Etme makalesini buldum . Apache'yi yapılandırmak için yazar şunları önerir: "İlk önce, Apache. İlk açıklamam, eğer kaçınabiliyorsanız deneyin. Lighttpd ve thttpd, hem web sunucuları hem de çok iyi değillerdir ve PHP ile lighttpd'yi çalıştırabilirsiniz. Yüksek hacimli bir site kullanıyorsanız, statik içeriği (genellikle resimler ve javascript dosyaları) Lighttpd gibi hafif, süper hızlı bir HTTPd sunucusuna geçirerek ciddi şekilde performans elde edebilirsiniz. "

Yazarın tavsiyesini almayı düşünüyorum ve müvekkilim ile bir sonraki hafta sonu Apache'yi sunucudaki Lighttpd ile değiştireceğim. Umarım bu sorunları çözer. İki sanal sunucu kullanmak büyük olasılıkla mümkün değildir.

Aynı makinede, makul miktarda belleğe sahip MySQL ve Apache gibi iki sağlam, açık kaynak sunucu kullanmanın, bu kadar sorunlu olacağını düşünmemiştim.

Yanıtlar:


36

Lütfen benim cevap için bu son soruya . Koşulların aynı olduğuna inanıyorum.

MySQL yapılandırmanızı bu noktada değiştirmeyin, çünkü MySQL sorun değildir - bu sadece sorunun belirtisidir ... ki bu, az miktarda bellek ve sıfır takas alanı olan bir sisteme sahip olduğunuzu gösterir.

Sunucunuz edilir değil çökmesini "çünkü" bellek tampon havuzu için tahsis edilemez. Sunucunuz kilitleniyor ... ve ardından sistem belleğinin mevcut olmaması nedeniyle daha sonra yeniden başlatılamıyor. InnoDB arabellek havuzu için yapılandırılan belleğin tamamı mysql başlangıcında sistemden isteniyor.

Bu günlük mesajını gördüğünüzde ...

120926 08:00:51 mysqld_safe Number of processes running now: 0

... sunucunuz çoktan öldü. Bundan önce hiçbir şey kaydetmediyse, ilk çökmeyle ilgili hiçbir şey kaydetmez. Sonraki kayıtlar, otomatik olarak yeniden başlatılmaya çalışılmasından sonradır.

Sistem günlüğünüzü kontrol edin ve aşırı bellek yetersizliği nedeniyle çekirdeğin öldürmek için işlem aradığı iletiler bulmalısınız.

Adım 1 muhtemelen bir miktar takas alanı eklemek ve / veya mümkünse RAM tahsis etmek olacaktır.

Bu mümkün değilse, aslında düşünebilirsiniz azalan Yapılandırmanızda innodb-tampon-havuzu boyutunu. (Aslında kendimi böyle söylerken duyacağımı hiç düşünmedim). Veritabanınız küçük ve trafiğiniz hafif olduğu sürece, büyük bir arabellek havuzuna ihtiyacınız olmayabilir ... ve InnoDB Buffer Pool belleğinin tümü başlangıçta gerekli olsun veya olmasın, tahsis edildiğinden, Sistemin talep ettiği başka bir şey için belleği. (Tampon havuzunun boyutlandırılması için% 75 ila% 80 arasında toplam RAM önerisi yalnızca, tüm sunucu MySQL'e tahsis edilmişse geçerlidir.)

Adım 2, Apache'nin forking modelini ve sunucunuzu ezmesini engellemek için yapılandırmada farklı şekilde yapmanız gerekebilecek olanı gözden geçirmek olacaktır. Apache alt işlemlerinin miktar ya da bellek gereksinimlerindeki kontrolsüz büyümenin bir dizi olay başlatması muhtemeldir, bu da çekirdeğin tüm sunucunun tamamen çökmesini önlemek için MySQL'i öldürmesine neden olur.

Ne kadar esnekliğinize bağlı olarak, Apache ve MySQL için iki ayrı sanal makine bile düşünebilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.