MySQL không liên tục gặp sự cố với lỗi Lỗi chết người: không thể phân bổ bộ nhớ cho nhóm bộ đệm


40

Đã thêm vào chỉnh sửa, 2013-05-29: Bởi vì đây là một câu hỏi và thảo luận dài, đây là một bản tóm tắt ngắn về câu hỏi và giải pháp. Tôi gặp vấn đề khi chạy MySQL và Apache trên một máy chủ Linux nhỏ (1 GB bộ nhớ). Apache liên tục đòi hỏi nhiều bộ nhớ hơn và như một sự thỏa mãn, HĐH luôn giết chết MySQL để lấy lại bộ nhớ. Giải pháp là thay thế Apache bằng Lighttpd. Sau khi tôi làm điều đó, việc sử dụng bộ nhớ trên máy chủ đã hoàn toàn ổn định trong vài tháng nay và tôi không gặp sự cố nào. kết thúc chỉnh sửa

Tôi là quản trị viên hệ thống mới bắt đầu cho một máy chủ ảo nhỏ. Chức năng chính của máy chủ là chạy phần mềm hệ thống quản lý khóa học Moodle mã nguồn mở , được viết bằng PHP. Nó dựa vào cơ sở dữ liệu, trong trường hợp này là MySQL và máy chủ web, trong trường hợp này là Apache.

Máy chủ đang chạy CentOS 64 bit phát hành 5,8 (Final) với bộ nhớ 1 GB và 200 GB đĩa, phiên bản kernel 2.6,18-308.8.2.el5xen. Phiên bản MySQL là Ver 14,14 Distrib 5.5.25, dành cho Linux (x86_64) sử dụng readline 5.1.

Tôi không nghĩ phần mềm Moodle là một người sử dụng MySQL nặng như vậy. Hiện tại, chỉ có khoảng mười giáo viên có quyền truy cập vào nó và khi tôi kết xuất và nén bằng bzip2 toàn bộ cơ sở dữ liệu, kích thước kết xuất của kết xuất nhỏ hơn 1 MB.

Tôi đã thiết lập hệ thống một vài tháng trước. Máy chủ Apache đã ổn định mọi lúc, nhưng MySQL đã bị sập nhiều lần. Tôi đã cố gắng tìm hiểu về cấu hình tối ưu từ web và lần cuối cùng tôi thay đổi /etc/my.cnftệp, tôi đã sử dụng tệp /usr/share/doc/mysql55-server-5.5.25/my-large.cnfđi kèm với MySQL làm ví dụ. Tệp nói rằng nó có nghĩa là cho các hệ thống có bộ nhớ 512 MB, vì vậy tôi nghĩ rằng việc sử dụng các tham số cấu hình liên quan đến bộ nhớ của nó sẽ an toàn cho hệ thống này. (. Tôi đã sớm cấu hình các thông số bộ nhớ liên quan đến MySQL với số nhỏ hơn nhiều, và tôi nghĩ rằng có thể đã dẫn đến các tai nạn Trong khi tai nạn vẫn xảy ra, hệ thống ít nhất là nhanh hơn bây giờ.) Đây là những nội dung hiện tại của /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

Như bạn có thể thấy trong cấu hình, thiết lập sử dụng công cụ InnoDB và nó chỉ phục vụ các yêu cầu từ localhost. Ngoài quản trị viên hệ thống (tôi), Moodle là người dùng duy nhất của MySQL.

Khi MySQL gặp sự cố, phần sau đây luôn được ghi vào tệp nhật ký /var/log/mysqld.log(ngoại trừ dấu thời gian, tất nhiên):

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

Đôi khi tôi có thể khởi động lại MySQL bằng cách ra lệnh service mysqld restart, nhưng đôi khi lệnh đó không thành công với đầu ra này : mysqld dead but subsys locked. Trong những trường hợp này, điều duy nhất tôi có thể nghĩ đến để phục hồi tình hình là khởi động lại máy chủ, sau đó MySQL có thể được khởi động lại. Trong những trường hợp này, đầu ra trông như thế này:

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)

Đây là những gì lệnh free -mhiện đang xuất:

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

Thông thường cột "miễn phí" nằm trong khoảng từ 50 đến 100 MB.

Đầu ra của lệnh 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

Tôi chưa thay đổi bất kỳ cài đặt hoặc tệp mã nào của Moodle, ngoại trừ /var/www/html/moodle/config.php, trông giống như thế này (các dòng bình luận đã bị xóa để tiết kiệm dung lượng):

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

(Tuy nhiên, tôi đã cài đặt hai plugin Moodle, mô-đun tham dự và chặn , nhưng tôi không thấy chúng có thể liên quan đến vấn đề này như thế nào.)

Ngay cả sau khi tôi cập nhật /etc/my.cnftrạng thái hiện tại một tuần trước, MySQL đã gặp sự cố một vài lần với các triệu chứng nêu trên. Là người mới bắt đầu quản trị cơ sở dữ liệu và sau khi làm nhiều việc về vấn đề này, tôi không biết phải làm gì tiếp theo. Bất kỳ đề xuất? Tôi có nên đăng thêm dữ liệu cấu hình?

Bổ sung về chỉnh sửa:

Nội dung của tập tin /var/log/messages.1là:

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

và sau đó các dòng liên quan đến khởi động lại lúc 11:42.

Bổ sung vào chỉnh sửa # 2:

Tôi đã cố gắng bình luận về câu trả lời của Michael, nhưng tôi đã chạy theo giới hạn nhận xét của nhân vật, vì vậy tôi đang trả lời ở đây.

Cảm ơn bạn đã trả lời, Michael. Tôi vừa chỉnh sửa câu hỏi của mình để bao gồm nội dung nhật ký hệ thống của máy tại thời điểm xảy ra sự cố. (CentOS dường như gọi nhật ký hệ thống của nó /var/log/messages.)

Có, cả bản ghi MySQL và hệ thống xuất hiện gần giống với bản ghi trong câu hỏi bạn liên kết đến. Và bây giờ khi bạn đề cập đến nó, rõ ràng là mysql restartedthông báo có nghĩa là MySQL đã bị sập. Nhật ký hệ thống chỉ ra rằng đó là oom_killernhững gì có quá trình. Trong câu trả lời trước đó của bạn, bạn viết: "Đầu tiên đoán: quá trình apache con chạy amok." Dường như với tôi rằng Apache cũng là nghi phạm rõ ràng ở đây.

Trước đó, tôi đã tìm thấy bài viết Tối ưu hóa MySQL và Apache để sử dụng bộ nhớ thấp, Phần 1 . Để cấu hình Apache, tác giả khuyến nghị: "Trước hết, Apache. Tuyên bố đầu tiên của tôi là, nếu bạn có thể tránh nó, hãy thử. Đang chạy một trang web có khối lượng lớn, bạn có thể đạt được hiệu suất một cách nghiêm túc bằng cách chuyển nội dung tĩnh (thường là hình ảnh và tệp javascript) sang máy chủ HTTPd siêu nhẹ, siêu nhanh như Lighttpd. "

Tôi đang nghĩ đến việc nghe lời khuyên của tác giả và đã đồng ý với khách hàng của tôi rằng vào cuối tuần tới, tôi sẽ thay thế Apache bằng Lighttpd trên máy chủ. Tôi hy vọng rằng sẽ giải quyết vấn đề. Sử dụng hai máy chủ ảo rất có thể là không thể.

Tôi đã không nghĩ rằng việc sử dụng hai máy chủ nguồn mở ổn định, trưởng thành như MySQL và Apache trên cùng một máy, với dung lượng bộ nhớ hợp lý, sẽ gây rắc rối.

Câu trả lời:


36

Vui lòng xem lại câu trả lời của tôi cho câu hỏi gần đây . Tôi tin rằng hoàn cảnh là giống hệt nhau.

Không thay đổi cấu hình MySQL của bạn tại thời điểm này, vì MySQL không phải là vấn đề - đó chỉ là một triệu chứng của vấn đề ... đó là bạn dường như có một hệ thống với một lượng bộ nhớ nhỏ và không gian hoán đổi bằng không.

Máy chủ của bạn không gặp sự cố "vì" bộ nhớ không thể được phân bổ cho nhóm bộ đệm. Máy chủ của bạn đang gặp sự cố ... và sau đó không thể khởi động lại do không có bộ nhớ hệ thống. Tất cả bộ nhớ được cấu hình cho nhóm bộ đệm InnoDB được yêu cầu từ hệ thống khi khởi động mysql.

Khi bạn thấy thông báo nhật ký này ...

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

... máy chủ của bạn đã chết. Nếu nó không ghi lại bất cứ điều gì trước đó, nó sẽ không ghi lại bất cứ điều gì về sự cố đầu tiên. Các bản ghi tiếp theo là từ sau khi cố gắng tự động khởi động lại.

Kiểm tra nhật ký hệ thống của bạn và bạn sẽ tìm thấy các thông báo trong đó kernel đã tìm kiếm các tiến trình để tiêu diệt do tình trạng hết bộ nhớ.

Bước 1 có thể là thêm một số dung lượng trao đổi và / hoặc phân bổ RAM nếu có thể.

Nếu điều đó là không thể, bạn thực sự có thể xem xét giảm kích thước nhóm bộ đệm innodb trong cấu hình của mình. (Tôi chưa bao giờ nghĩ rằng tôi thực sự nghe chính mình nói điều đó). Miễn là cơ sở dữ liệu của bạn nhỏ và lưu lượng truy cập của bạn nhẹ, bạn có thể không cần một vùng đệm lớn như vậy ... và vì bộ nhớ của Bộ đệm InnoDB được phân bổ khi khởi động cho dù có cần hay không, điều này sẽ giải phóng một số bộ nhớ của hệ thống cho bất cứ điều gì khác đang đòi hỏi nó. (Đề xuất 75% đến 80% tổng RAM cho kích thước vùng đệm chỉ đúng khi toàn bộ máy chủ được dành riêng cho MySQL.)

Bước 2 sẽ là xem xét mô hình giả mạo của Apache và những gì bạn có thể cần làm khác đi trong cấu hình để ngăn không cho nó áp đảo máy chủ của bạn. Rất có khả năng sự tăng trưởng không kiểm soát được về số lượng hoặc yêu cầu bộ nhớ của các tiến trình con Apache đang bắt đầu một loạt các sự kiện, dẫn đến việc kernel giết chết MySQL để cố gắng tránh sự cố hoàn toàn của toàn bộ máy chủ.

Tùy thuộc vào mức độ linh hoạt của bạn, bạn thậm chí có thể xem xét hai máy ảo riêng biệt cho Apache và MySQL.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.