"치명적인 오류 : 버퍼 풀에 메모리를 할당 할 수 없습니다"오류와 함께 간헐적 인 MySQL 충돌


40

2013 년 5 월 29 일 편집에 추가됨 : 이것은 긴 질문과 토론이므로 질문과 솔루션에 대한 간단한 요약입니다. 작은 Linux 서버 (1GB의 메모리)에서 MySQL과 Apache를 실행하는 데 문제가있었습니다. 아파치는 계속해서 더 많은 메모리를 요구했고 결과적으로 OS는 메모리를 다시 확보하기 위해 MySQL을 죽였습니다. 해결책 은 Apache를 Lighttpd로 대체하는 것이 었습니다. 그렇게 한 후 서버의 메모리 사용은 몇 개월 동안 완전히 안정적이었고 어떤 충돌도 없었습니다. 편집 종료

소규모 가상 서버의 초보자 시스템 관리자입니다. 서버의 주요 기능은 PHP로 작성된 오픈 소스 무들 코스 관리 시스템 소프트웨어 를 실행하는 것입니다. 데이터베이스 (이 경우 MySQL)와 웹 서버 (이 경우 Apache)에 의존합니다.

서버에서 1GB의 메모리와 200GB의 디스크 (커널 버전 2.6.18-308.8.2.el5xen)가있는 64 비트 CentOS 릴리스 5.8 (최종)을 실행 중입니다. MySQL 버전은 readline 5.1을 사용하는 Linux (x86_64) 용 Ver 14.14 Distrib 5.5.25입니다.

Moodle 소프트웨어가 MySQL을 많이 사용한다고 생각하지 않습니다. 현재 약 10 명의 교사 만 액세스 할 수 있으며 전체 데이터베이스를 bzip2로 덤프하고 압축하면 결과 덤프의 크기는 1MB 미만입니다.

몇 달 전에 시스템을 설정했습니다. 아파치 서버는이 시간 동안 안정적이지만 MySQL은 여러 번 충돌했습니다. 웹에서 최적의 구성에 대해 배우려고 노력했으며 마지막으로 /etc/my.cnf파일을 변경했을 때 /usr/share/doc/mysql55-server-5.5.25/my-large.cnfMySQL과 함께 제공 되는 파일 을 예로 사용했습니다. 이 파일은 메모리가 512MB 인 시스템을위한 것이므로 메모리 관련 구성 매개 변수를 사용하는 것이이 시스템에 안전하다고 생각했습니다. (이전에 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의 요청 만 제공합니다. 시스템 관리자 (me) 외에, 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

때로는 service mysqld restart명령을 실행 하여 MySQL을 다시 시작할 수 있지만 때로는 다음 명령으로 해당 명령이 실패합니다 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-100MB입니다.

명령의 출력 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

/var/www/html/moodle/config.php다음과 같이 Moodle의 설정 또는 코드 파일을 변경하지 않았습니다 .

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

(그러나 출석 모듈과 블록이라는 두 가지 무들 플러그인을 설치 했지만이 문제와 어떻게 관련 될 수 있는지 알 수 없습니다.)

/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에 추가 :

나는 Michael의 대답에 대해 의견을 말하려고 시도했지만 의견의 글자 수 한도를 어 겼기 때문에 여기에 대답하고 있습니다.

대답 해 주셔서 감사합니다, 마이클 충돌 당시 컴퓨터의 시스템 로그 내용을 포함하도록 질문을 편집했습니다. (CentOS는 시스템 로그를 호출하는 것 같습니다 /var/log/messages.)

예, MySQL 및 시스템 로그는 모두 연결된 질문의 로그와 거의 동일하게 나타납니다. 그리고 지금 당신이 그것을 언급 mysql restarted했으므로 , 메시지는 MySQL이 이미 충돌했다는 것을 의미합니다. 시스템 로그는 oom_killer프로세스가 완료 되었음을 나타냅니다 . 이전 답변에서 "첫 번째 추측 : 아파치 하위 프로세스가 실행됩니다." 아파치도 여기에 의심의 여지가없는 것 같습니다.

이전에는 저용량 메모리 사용을 위해 MySQL 및 Apache 최적화, Part 1 기사를 찾았습니다 . 저자는 아파치를 구성 할 때 다음과 같이 권고한다. "아파치, 첫 번째 진술은 피할 수 없다면 시도해 보자. Lighttpd와 thttpd는 웹 서버를 잘 다루지 않으며 PHP로 lighttpd를 실행할 수있다. '대량 사이트를 운영하고 있다면 정적 컨텐츠 (일반적으로 이미지 및 자바 스크립트 파일)를 Lighttpd와 같은 초고속 HTTPd 서버로 전달하여 성능을 크게 향상시킬 수 있습니다. "

저자의 조언을 생각하고 다음 주말에 서버에서 Apache를 Lighttpd로 대체하겠다고 클라이언트와 동의했습니다. 문제가 해결되기를 바랍니다. 두 개의 가상 서버를 사용하는 것은 불가능합니다.

합리적인 양의 메모리를 가진 동일한 시스템에서 MySQL과 Apache와 같은 안정적이고 성숙한 오픈 소스 서버 두 개를 사용하는 것이이 번거로울 것이라고 생각하지 않았습니다.

답변:


36

이 최근 질문에 대한 나의 답변 을 검토하십시오 . 상황이 동일하다고 생각합니다.

MySQL은 문제가 아니기 때문에이 시점에서 MySQL 구성을 변경하지 마십시오. 문제의 증상 일뿐입니다. 적은 양의 메모리와 스왑 공간이없는 시스템이있는 것 같습니다.

귀하의 서버가되어 있지 충돌 "때문에" 메모리 버퍼 풀에 할당 할 수 없습니다. 서버가 충돌하고 시스템 메모리를 사용할 수 없어서 다시 시작할 수 없습니다. InnoDB 버퍼 풀에 대해 구성된 모든 메모리는 mysql 시작시 시스템에서 요청됩니다.

이 로그 메시지가 표시되면 ...

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

... 서버가 이미 죽었습니다. 이전에 아무 것도 기록하지 않은 경우 첫 번째 충돌에 대해서는 아무것도 기록하지 않습니다. 후속 로그는 자동 재시작 시도 후의 것입니다.

syslog를 확인하면 메모리 부족 상태로 인해 커널이 종료 할 프로세스를 찾는 메시지를 찾아야합니다.

1 단계는 가능하다면 스왑 공간을 추가하거나 RAM을 할당하는 것입니다.

이것이 가능하지 않으면 실제로 구성에서 innodb-buffer-pool 크기를 줄이는 것을 고려할 수 있습니다. (나는 실제로 내가 그렇게 말하는 것을들을 줄은 몰랐다). 데이터베이스가 작고 트래픽이 적 으면 큰 버퍼 풀이 필요하지 않을 수 있습니다. InnoDB 버퍼 풀 메모리는 시작시 필요에 관계없이 모두 할당되기 때문에 일부를 비울 수 있습니다. 다른 것을 요구하는 것에 대한 시스템의 메모리. (버퍼 풀 크기 조정에 대한 75 % ~ 80 %의 RAM 총 권장 사항은 전체 서버가 MySQL 전용 인 경우에만 해당됩니다.)

2 단계는 Apache의 포크 모델과 서버에서 서버를 압도하지 않도록 구성에서 다르게 수행해야 할 사항을 검토하는 것입니다. Apache 자식 프로세스의 제어되지 않은 수량 또는 메모리 요구 사항 증가가 일련의 이벤트를 시작하여 커널이 MySQL을 죽여서 전체 서버의 완전한 충돌을 피하려고 시도 할 가능성이 높습니다.

유연성이 어느 정도인지에 따라 Apache와 MySQL을위한 두 개의 개별 가상 머신을 고려할 수도 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.