переривчасті збої MySQL з помилкою "Фатальна помилка: не можна виділити пам'ять для буферного пулу"


40

Додано в редагуванні, 2013-05-29: Оскільки це довге питання та дискусія, ось короткий підсумок питання та рішення. У мене виникли проблеми із запуском MySQL та Apache на невеликому сервері Linux (1 Гб пам'яті). Apache продовжував вимагати більше пам’яті, і як сумління, ОС завжди вбивала MySQL, щоб відновити свою пам’ять. Рішенням було замінити Apache на Lighttpd. Після того, як я це зробив, використання пам'яті на сервері було стабільно вже кілька місяців, і у мене не було жодних збоїв. кінець редагування

Я початковий системний адміністратор невеликого віртуального сервера. Основна функція сервера полягає у запуску програмного забезпечення системи управління курсами Moodle з відкритим кодом , написаного на PHP. Він спирається на базу даних, в даному випадку MySQL, і веб-сервер, в даному випадку Apache.

На сервері працює 64-бітний випуск CentOS 5.8 (Final) з 1 ГБ пам'яті та 200 ГБ диска, версія ядра 2.6.18-308.8.2.el5xen. Версія MySQL - це версія Ver.14.14 Distrib 5.5.25, для Linux (x86_64) з використанням рядка 5.1.

Я не думаю, що програмне забезпечення Moodle є таким важким користувачем MySQL. В даний час доступ до нього мають лише близько десяти викладачів, і коли я скидаю і стискаю з bzip2 всю базу даних, розмір отриманого дампа становить менше 1 Мб.

Я створив систему кілька місяців тому. Сервер Apache був стабільним весь цей час, але MySQL кілька разів вийшов з ладу. Я спробував дізнатися про оптимальну конфігурацію з Інтернету, і востаннє, коли я змінив /etc/my.cnfфайл, я використав файл, /usr/share/doc/mysql55-server-5.5.25/my-large.cnfякий постачається разом із MySQL. У файлі йдеться про те, що він призначений для систем з 512 Мб пам'яті, тому я вважав, що використання його параметрів конфігурації, пов'язаних з пам'яттю, буде безпечним для цієї системи. (Раніше я налаштовував параметри пам'яті MySQL з набагато меншими числами, і я вважав, що це могло призвести до збоїв. Хоча збої все ще відбуваються, система принаймні швидша.) Це поточний вміст /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

Як ви бачите в конфігурації, налаштування використовує двигун InnoDB, і він обслуговує лише запити від localhost. Крім системного адміністратора (мене), Moodle є єдиним користувачем MySQL.

Коли збій MySQL, у файл журналу незмінно записується наступне /var/log/mysqld.log(за винятком часових позначок):

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

Іноді я можу запустити MySQL командирів service mysqld restart, але іноді , що команда не з цим виходом: mysqld dead but subsys locked. У цих випадках єдине, що мені вдалося придумати, щоб відновити ситуацію, - це перезапустити сервер, після чого MySQL можна перезапустити. У цих випадках результат виглядає так:

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)

Ось що команда free -mнаразі виводить:

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

Зазвичай стовпець "безкоштовно" становить від 50 до 100 Мб.

Вихід команди 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

Я не змінив жодного з параметрів або кодів Moodle, за винятком /var/www/html/moodle/config.php, який виглядає приблизно так (рядки коментарів видалені, щоб заощадити місце):

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

(Однак я встановив два плагіни Moodle, модуль Attendance та блок , але я не бачу, як вони могли бути пов'язані з цією проблемою.)

Навіть після того, як я /etc/my.cnfтиждень тому оновився до його поточного стану, MySQL впав кілька разів із симптомами, наведеними вище. Будучи початківцем у адмініструванні баз даних, і після того, як багато займаюся з цієї проблеми, я втрачаю, що робити далі. Будь-які пропозиції? Чи потрібно публікувати більше даних конфігурації?

Додаток при редагуванні:

Вміст файлу /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).

а потім рядки, пов’язані з перезавантаженням, о 11:42.

Додаток до редагування №2:

Я спробував прокоментувати відповідь Майкла, але я зіткнувся з обмеженням кількості коментарів, тому відповідаю тут.

Дякую за вашу відповідь, Майкл. Я щойно відредагував своє запитання, щоб включити вміст системного журналу машини під час аварії. (Схоже, CentOS називає свій системний журнал /var/log/messages.)

Так, і журнали MySQL, і системні журнали виглядають майже однаковими з тими, що містяться в питанні, з яким ви пов’язані. І тепер, коли ви це згадуєте, це очевидно, що mysql restartedповідомлення означає, що MySQL вже розбився. Системний журнал вказує, що саме oom_killerцей процес отримав. У своїй попередній відповіді ви пишете: "Спочатку здогадуйтесь: апачі дочірніх процесів запускаються на amok." Мені здається, що тут теж явний підозрюваний Апач.

Раніше я знайшов статтю Оптимізація MySQL та Apache для низького використання пам'яті, частина 1 . Для налаштування Apache автор рекомендує: "Перш за все, Apache. Моє перше твердження, якщо ви можете цього уникнути, спробуйте. Lighttpd і thttpd - це дуже добре, не надто вишукані веб-сервери, і ви можете запускати lighttpd з PHP. Навіть якщо ви На веб-сайті з великою гучністю ви можете серйозно отримати певну ефективність, передаючи статичний вміст (як правило, зображення та файли javascript) на легкий, надшвидкий сервер HTTPd, такий як Lighttpd. "

Я думаю скористатись авторською порадою і домовився зі своїм клієнтом, що наступні вихідні я заміню Apache на Lighttpd на сервері. Я сподіваюся, що це вирішить проблеми. Використання двох віртуальних серверів, швидше за все, неможливо.

Я не думав, що використання двох стабільних, зрілих серверів з відкритим кодом, таких як MySQL та Apache на одній машині, з достатньою кількістю пам'яті, буде цим клопітким.

Відповіді:


36

Перегляньте мою відповідь на це нещодавнє запитання . Я вважаю, що обставини однакові.

Не змінюйте конфігурацію MySQL на даний момент, оскільки MySQL не є проблемою - це лише симптом проблеми ... що полягає в тому, що у вас, мабуть, є система з невеликою кількістю пам'яті та нульовим місцем обміну.

Ваш сервер не виходить з ладу ", тому що" пам'ять не може бути виділена для буферного пулу. Ваш сервер виходить з ладу ... і потім не може згодом перезапустити через недоступність системної пам'яті. Вся пам'ять, налаштована для пулу буфера InnoDB, запитується від системи при запуску mysql.

Коли ви побачите це повідомлення журналу ...

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

... ваш сервер вже загинув. Якщо він до цього нічого не записав, він нічого не записуватиме про першу аварію. Подальші журнали починаються після автоматичної спроби перезапуску.

Перевірте свій системний журнал, і ви повинні знайти повідомлення, куди ядро ​​шукало процеси для вбивства через екстремальний стан поза пам'яттю.

Крок 1, ймовірно, буде додати трохи місця підкачки та / або виділити оперативну пам'ять, якщо це взагалі можливо.

Якщо це неможливо, ви можете реально розглянути можливість зменшення розміру пулу innodb-буфер у вашій конфігурації. (Я ніколи не думав, що насправді чую, як це кажу). Поки ваша база даних невелика, а ваш трафік легкий, можливо, вам не знадобиться такий великий буферний пул ... і оскільки пам'ять пулу InnoDB при виділенні повністю виділяється, потрібно чи ні, це звільнить частину вашої пам'ять системи для будь-якого іншого вимагає цього. (Рекомендація від 75% до 80% від загальної оперативної пам’яті щодо розміру буферного пулу справедлива лише в тому випадку, якщо весь сервер призначений для MySQL.)

Крок 2 полягає в перегляді моделі роздрібнення Apache і що вам може знадобитися зробити інакше в конфігурації, щоб запобігти перевантаженню вашого сервера. Цілком ймовірно, що неконтрольоване зростання кількості або пам’яті потреб дочірніх процесів Apache починає каскад подій, в результаті чого ядро ​​вбиває MySQL, щоб спробувати уникнути повного збою всього сервера.

Залежно від вашої гнучкості, ви навіть можете розглянути дві окремі віртуальні машини для Apache та MySQL.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.