zeitweise auftretende MySQL-Abstürze mit dem Fehler "Schwerwiegender Fehler: Speicher für den Pufferpool kann nicht zugewiesen werden"

40

Hinzugefügt am 29.05.2013: Da dies eine lange Frage und Diskussion ist , folgt hier eine kurze Zusammenfassung der Frage und der Lösung. Ich hatte Probleme, MySQL und Apache auf einem kleinen Linux-Server (1 GB Speicher) auszuführen. Apache forderte immer mehr Speicherplatz und als Folge davon hat das Betriebssystem immer MySQL beendet, um seinen Speicher wiederzugewinnen. Die Lösung bestand darin, Apache durch Lighttpd zu ersetzen. Nachdem ich das getan habe, ist die Speichernutzung auf dem Server seit einigen Monaten vollständig stabil und ich hatte keinerlei Abstürze. Ende der Bearbeitung

Ich bin ein Anfänger-Systemadministrator für einen kleinen virtuellen Server. Die Hauptfunktion des Servers besteht darin, das Open-Source- Moodle auszuführen , die in PHP geschriebene auszuführen. Es basiert auf einer Datenbank, in diesem Fall MySQL, und einem Webserver, in diesem Fall Apache.

Auf dem Server wird die 64-Bit-Version von CentOS 5.8 (Final) mit 1 GB Arbeitsspeicher und 200 GB Festplatte ausgeführt (Kernel-Version 2.6.18-308.8.2.el5xen). Die MySQL-Version ist Ver 14.14 Distrib 5.5.25 für Linux (x86_64) mit readline 5.1.

Ich glaube nicht, dass die Moodle-Software so viele MySQL-Benutzer hat. Derzeit haben nur etwa zehn Lehrer Zugriff darauf, und wenn ich die gesamte Datenbank mit bzip2 kopiere und komprimiere, beträgt die Größe des resultierenden Dumps weniger als 1 MB.

Ich habe das System vor ein paar Monaten eingerichtet. Der Apache-Server war die ganze Zeit stabil, aber MySQL ist mehrmals abgestürzt. Ich habe versucht, die optimale Konfiguration aus dem Internet zu ermitteln, und als ich die /etc/my.cnfDatei das letzte Mal geändert habe , habe ich die /usr/share/doc/mysql55-server-5.5.25/my-large.cnfmit MySQL gelieferte Datei als Beispiel verwendet. Die Datei besagt, dass sie für Systeme mit 512 MB Arbeitsspeicher gedacht ist. Daher dachte ich, dass die Verwendung der speicherbezogenen Konfigurationsparameter für dieses System sicher wäre. (Ich hatte zuvor die speicherbezogenen Parameter von MySQL mit viel kleineren Zahlen konfiguriert und dachte, dies hätte zu Abstürzen geführt. Obwohl die Abstürze immer noch auftreten, ist das System jetzt zumindest schneller.) Dies sind die aktuellen Inhalte von /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

Wie Sie in der Konfiguration sehen können, verwendet das Setup die InnoDB-Engine und verarbeitet nur Anforderungen von localhost. Neben dem Systemadministrator (mir) ist Moodle der einzige Benutzer von MySQL.

Wenn MySQL abstürzt, wird ausnahmslos Folgendes in die Protokolldatei geschrieben /var/log/mysqld.log(natürlich mit Ausnahme der Zeitstempel):

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

Manchmal kann ich MySQL neu starten , indem befehlen service mysqld restart, aber manchmal , dass Befehl mit diesem Ausgang nicht: mysqld dead but subsys locked. In diesen Fällen konnte ich nur daran denken, die Situation wiederherzustellen, indem ich den Server neu startete, wonach MySQL neu gestartet werden kann. In diesen Fällen sieht die Ausgabe folgendermaßen aus:

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)

Folgendes gibt der Befehl free -mderzeit aus:

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

Normalerweise liegt die "freie" Spalte zwischen 50 und 100 MB.

Die Ausgabe des Befehls 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

Ich habe keine Einstellungen oder Codedateien von Moodle geändert, mit Ausnahme der folgenden Ausnahmen /var/www/html/moodle/config.php(Kommentarzeilen wurden aus Platzgründen gelöscht):

<?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

(Ich habe jedoch zwei Moodle-Plugins installiert, das Anwesenheitsmodul und den Block , aber ich sehe nicht, wie sie mit diesem Problem in Verbindung gebracht werden könnten.)

Selbst nachdem ich vor /etc/my.cnfeiner Woche auf den aktuellen Stand gebracht habe, ist MySQL ein paar Mal mit den oben angegebenen Symptomen abgestürzt. Als Anfänger in der Datenbankadministration und nachdem ich viel über dieses Problem gegoogelt habe, weiß ich nicht, was ich als Nächstes tun soll. Irgendwelche Vorschläge? Soll ich weitere Konfigurationsdaten posten?

Zusatz bei Bearbeitung:

Der Inhalt der Datei /var/log/messages.1ist:

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).

und dann Zeilen zum Neustart um 11:42.

Zusatz zum Edit # 2:

Ich habe versucht, Michaels Antwort zu kommentieren, aber ich habe die Zeichenbegrenzung der Kommentare verletzt, also antworte ich hier.

Danke für deine Antwort, Michael. Ich habe meine Frage soeben bearbeitet, dass sie den Inhalt des Systemprotokolls des Computers zum Zeitpunkt des Absturzes enthält. (CentOS scheint sein Systemprotokoll aufzurufen /var/log/messages.)

Ja, sowohl das MySQL- als auch das Systemprotokoll stimmen nahezu mit den Protokollen in der Frage überein, mit der Sie verknüpft sind. Und jetzt, wo Sie es erwähnen, ist es offensichtlich, dass die mysql restartedMeldung bedeutet, dass MySQL bereits abgestürzt ist. Das Systemprotokoll zeigt an, dass dies oom_killerder Prozess ist. In Ihrer früheren Antwort schreiben Sie: "Erste Vermutung: Apache-Child-Prozesse führen Amok aus." Mir scheint, dass Apache auch hier der offensichtliche Verdächtige ist.

Zuvor fand ich den Artikel Optimieren von MySQL und Apache für eine geringe Speichernutzung, Teil 1 . Für die Konfiguration von Apache empfiehlt der Autor: "Zuallererst Apache. Meine erste Aussage ist, wenn Sie dies vermeiden können, versuchen Sie es. Lighttpd und thttpd sind beide sehr gute, schnörkellose Webserver, und Sie können lighttpd mit PHP ausführen. Selbst wenn Sie Wenn Sie eine hochvolumige Site betreiben, können Sie ernsthaft an Leistung gewinnen, indem Sie statischen Inhalt (normalerweise Bilder und Javascript-Dateien) an einen schlanken, superschnellen HTTPd-Server wie Lighttpd weitergeben. "

Ich denke darüber nach, den Rat des Autors zu befolgen, und habe mit meinem Kunden vereinbart, dass ich am kommenden Wochenende Apache durch Lighttpd auf dem Server ersetzen werde. Ich hoffe das löst die Probleme. Die Verwendung von zwei virtuellen Servern ist höchstwahrscheinlich nicht möglich.

Ich hätte nicht gedacht, dass die Verwendung von zwei stabilen, ausgereiften Open-Source-Servern wie MySQL und Apache auf demselben Computer mit einer angemessenen Speicherkapazität so mühsam wäre.

Teemu Leisti
quelle

Antworten:

36

Bitte überprüfen Sie meine Antwort auf diese aktuelle Frage . Ich glaube, die Umstände sind identisch.

Ändern Sie Ihre MySQL-Konfiguration zum jetzigen Zeitpunkt nicht, da MySQL nicht das Problem ist - es ist nur ein Symptom des Problems ... anscheinend haben Sie ein System mit wenig Arbeitsspeicher und null Swap-Speicherplatz.

Ihr Server stürzt nicht ab , weil dem Pufferpool kein Speicher zugewiesen werden kann. Ihr Server stürzt ab ... und kann anschließend nicht neu gestartet werden, da der Systemspeicher nicht verfügbar ist. Der gesamte für den InnoDB-Pufferpool konfigurierte Speicher wird beim Start von mysql vom System angefordert.

Wenn Sie diese Protokollmeldung sehen ...

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

... Ihr Server ist bereits gestorben. Wenn es vorher nichts protokolliert hat, wird es nichts über den ersten Absturz protokollieren. Die nachfolgenden Protokolle stammen aus dem automatischen Neustartversuch.

Überprüfen Sie Ihr Syslog und finden Sie Nachrichten, bei denen der Kernel nach Prozessen gesucht hat, die aufgrund eines extremen Speichermangels abgebrochen werden können.

Schritt 1 wäre wahrscheinlich, etwas Auslagerungsspeicher hinzuzufügen und / oder RAM zuzuweisen, wenn dies überhaupt möglich ist.

Ist dies nicht möglich, können Sie die Größe des Innodb-Buffer-Pools in Ihrer Konfiguration verringern . (Ich hätte nie gedacht, dass ich mich das sagen hören würde). Solange Ihre Datenbank klein ist und Ihr Datenverkehr gering ist, benötigen Sie möglicherweise keinen so großen Pufferpool. Da der InnoDB-Pufferpool-Speicher beim Start zugewiesen wird, unabhängig davon, ob er benötigt wird oder nicht, wird ein Teil Ihres Pufferspeichers freigegeben Systemspeicher für alles, was es sonst noch verlangt. (Die Empfehlung von 75% bis 80% des gesamten Arbeitsspeichers für die Größe des Pufferpools gilt nur, wenn der gesamte Server für MySQL reserviert ist.)

Schritt 2 besteht darin, das Forking-Modell von Apache zu überprüfen und zu prüfen, was Sie möglicherweise in der Konfiguration anders machen müssen, um zu verhindern, dass der Server überlastet wird. Es ist ziemlich wahrscheinlich, dass ein unkontrolliertes Anwachsen der Menge oder des Speicherbedarfs der untergeordneten Apache-Prozesse eine Kaskade von Ereignissen auslöst, was dazu führt, dass der Kernel MySQL beendet, um einen vollständigen Absturz des gesamten Servers zu vermeiden.

Abhängig von Ihrer Flexibilität können Sie sogar zwei separate virtuelle Maschinen für Apache und MySQL in Betracht ziehen.

Michael - sqlbot
quelle