Mysql từ từ sử dụng bộ nhớ cho đến khi nó bắt đầu sử dụng trao đổi


8

Tôi đang chạy một máy chủ cơ sở dữ liệu rackspace RAM 1gb. Vì một số lý do trong khoảng 2 ngày, việc sử dụng bộ nhớ chuyển từ sử dụng rất ít trao đổi, sang sử dụng 100mb. Nếu tôi không khởi động lại sql, nó sẽ tiếp tục sử dụng nhiều trao đổi hơn. (Tệp my.cnf của tôi được hiển thị bên dưới và sử dụng bộ nhớ được hiển thị bên dưới)

Một số nền tảng: Tôi có khoảng 50 cơ sở dữ liệu hoạt động có cùng lược đồ sử dụng INNODB cho các bảng. Tôi có một vài cơ sở dữ liệu với ít lưu lượng sử dụng MyISAM.

Trên các bảng INNODB tôi KHÔNG sử dụng các kết nối liên tục. Tôi cũng có một chức năng báo cáo tạo ra một bảng tạm thời. (Điều này có thể tốn nhiều tài nguyên, nhưng KHÔNG xảy ra thường xuyên)

Tôi đang sử dụng CENTOS 6.3 và mysql 5.5.28-log

Mặc dù tôi đang sử dụng trao đổi, hiệu suất vẫn khá tốt. Tôi chỉ sợ rằng nếu tôi không khởi động lại cứ sau vài ngày tôi sẽ gặp vấn đề.

Đây là nhật ký miễn phí của tôi trong khoảng 2 ngày: (Bản ghi đầu tiên là ngay sau khi khởi động lại mysql)

12/26 2:08 PM EST
             total       used       free     shared    buffers     cached
Mem:           992        697        295          0         74        362
-/+ buffers/cache:        260        732
Swap:          976         15        961

12/26 4:10 PM EST
[root@php-pos-db ~]# free -m
             total       used       free     shared    buffers     cached
Mem:           992        791        201          0         97        405
-/+ buffers/cache:        287        705
Swap:          976         14        961

12/27 2:52 PM EST
[root@php-pos-db ~]# free -m
             total       used       free     shared    buffers     cached
Mem:           992        947         45          0         55        169
-/+ buffers/cache:        722        270
Swap:          976         34        942

12/28 1:41 PM EST
             total       used       free     shared    buffers     cached
Mem:           992        963         29          0         45        119
-/+ buffers/cache:        797        195
Swap:          976         48        927

12/28 7:24 PM EST
[root@php-pos-db ~]# free -m
             total       used       free     shared    buffers     cached
Mem:           992        957         35          0         41        141
-/+ buffers/cache:        774        218
Swap:          976         90        886

12/28 8:33 PM EST
[root@php-pos-db ~]# free -m
             total       used       free     shared    buffers     cached
Mem:           992        948         44          0         48        130
-/+ buffers/cache:        768        224
Swap:          976         96        880

my.cnf

# The MySQL database server configuration file.
#
# You can copy this to one of:
# - "/etc/mysql/my.cnf" to set global options,
# - "~/.my.cnf" to set user-specific options.
# 
# One can use all long options that the program supports.
# Run program with --help to get a list of available options and with
# --print-defaults to see which it would actually understand and use.
#
# For explanations see
# http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html
#
# Take care to only add/remove/change a setting if you are comfortable
# doing so! For Rackspace customers, if you have any questions or
# concerns, please contact the MySQL Database Services Team. Be aware
# that some work performed by this team can involve additional billable
# fees.
#
# This file generated for host php-pos-db please modify
# variables if the server is resized from 1016636kB

[mysqld]

### General
user                = mysql
port                = 3306
datadir                         = /var/lib/mysql
tmpdir                          = /tmp
socket                          = /var/lib/mysql/mysql.sock
skip-external-locking           = 1
log_error                       = /var/log/mysqld.log

## This prevents using host-based authentication. That means users must be
## created using an ip-address (ie 'myuser'@'192.168.100.1') or must make
## use of the % wildcard (ie 'myuser'@'%'). The benefit to not using
## host-based authentication is that DNS will not impact MySQL performance.
#skip-name-resolve

## If open-files-limit is set very low, MySQL may increase on its own. Either
## way, increase this if MySQL gives 'too many open files' errors. Setting
## this above 65535 could be unwise (MySQL may crash).
open-files-limit                = 20000

### Cache
thread-cache-size               = 16
table-open-cache                = 4096
table-definition-cache          = 512

## Generally, it is unwise to set the query cache to be larger than 64-128M 
## as the costs associated with maintaining the cache outweigh the performance
## gains. A far superior solution would be to implement memcached, though this
## required modifying the application, among other things.
query-cache-type                = 1
query-cache-size                = 32M
query-cache-limit               = 1M

### Per-thread Buffers
sort-buffer-size                = 1M
read-buffer-size                = 1M
read-rnd-buffer-size            = 2M
join-buffer-size                = 1M

### Temp Tables
tmp-table-size                  = 64M 
max-heap-table-size             = 64M

### Networking
back-log                        = 100
max-connections                 = 50
max-connect-errors              = 10000
max-allowed-packet              = 16M
interactive-timeout             = 600
wait-timeout                    = 180
net_read_timeout        = 30
net_write_timeout       = 30
# This value is the size of the listen queue for incoming TCP/IP connections.
back_log            = 128

#### Storage Engines
## Set this to force MySQL to use a particular engine / table-type
## for new tables. This setting can still be overridden by specifying
## the engine explicitly in the CREATE TABLE statement.
default-storage-engine         = InnoDB

## Makes sure MySQL does not start if InnoDB fails to start. This helps
## prevent ugly silent failures.
innodb                          = FORCE

### MyISAM
## Not sure what to set this to?
## Try running a 'du -sch /var/lib/mysql/*/*.MYI'
## This will give you a good estimate on the size of all the MyISAM indexes.
## (The buffer may not need to set that high, however)
key-buffer-size                 = 2M
## This setting controls the size of the buffer that is allocated when 
## sorting MyISAM indexes during a REPAIR TABLE or when creating indexes 
## with CREATE INDEX or ALTER TABLE.
myisam-sort-buffer-size         = 2M

### InnoDB
## Note: While most settings in MySQL can be set at run-time, many InnoDB
## variables cannot be set at runtime as require restarting MySQL
###
## These settings control how much RAM InnoDB will use. Generally, when using
## mostly InnoDB tables, the innodb-buffer-pool-size should be as large as
## is possible without swapping or starving other processes of RAM. The other 
## two settings usually do not need to be changed, but can help for very large 
## datasets.
innodb-buffer-pool-size         = 285M
innodb-log-buffer-size          = 8M

## Be careful when changing these as they require re-generating the 
## ib-logfile* files, which must be done carefully. Do not change this unless 
## you are familiar with the procedure.
innodb-log-file-size           = 128M
innodb-log-files-in-group      = 2

## This will cause each table to create its own .ibd file
innodb-file-per-table           = 1

## Setting this to 2 will decrease disk I/O but can cause up to a second of
## queries to be lost during a hard outage (i.e. power failures)
# innodb-flush-log-at-trx-commit = 2

### Replication
## Set this to the Server's instance ID in replication environments
server-id                       = 1

#log-bin                        = /var/lib/mysql/bin-log
#relay-log                      = /var/lib/mysql/relay-log
#relay-log-space-limit          = 4G
#expire-logs-days               = 5

## This should be enabled on conventional MySQL slaves
#read-only                      = 1

## This will cause replicated statements on a slave to be written to the slave's binlog
## Enable this on the middle slave of M->S->S configs
#log-slave-updates              = 1

#binlog-format                  = STATEMENT

### Logging
## This option determines the destination for general query log and slow query log output.
## The option value can be given as one or more of the words TABLE, FILE, or NONE.
## NOTE: Table logging takes away 50% of performance and thus is not recommended
##       http://bugs.mysql.com/bug.php?id=30414
## In addition, you cannot backup the contents of these tables properly
## (mysqldump skips these tables by default since they cannot be locked)
#log-output                     = FILE
slow-query-log                 = 1
slow-query-log-file            = /var/lib/mysql/slow-log
long-query-time                = 2
log-queries-not-using-indexes  = 1

[mysqld-safe]
log-error                       = /var/log/mysqld.log

[mysqldump]
max-allowed-packet      = 16M

# * IMPORTANT: Additional settings that can override those from this file!
#   The files must end with '.cnf', otherwise they'll be ignored.
#
!includedir /etc/sysconfig/mysqld-config/

Câu trả lời:


5

MySQL có thói quen khó chịu là trao đổi hạnh phúc. Jeremy Cole đã giải quyết tốt nhất điều này trong blog của mình: http://blog.jcole.us/2012/04/16/a-brief-update-on-numa-and-mysql/ . Từ blog đó, bạn biết rằng có một số thứ bạn có thể làm: Thêm vào numactl --interleave=allbên trong /etc/init.d/mysql.

BỀN VỮNG

Nếu Máy chủ được dành riêng để chỉ thực hiện MySQL, vui lòng thay đổi các mục sau trong /etc/my.cnf:

[mysqld]
innodb_open_files=1000
innodb_flush_method=O_DIRECT
innodb_buffer_pool_size=768M
innodb_log_file_size=192M

Nếu máy chủ ít nhất là lõi kép, hãy thêm chúng

innodb_buffer_pool_instances=2
innodb_read_io_threads=16
innodb_write_io_threads=16
innodb_io_capacity=2000

Tiếp theo, đăng nhập vào mysql chạy SET GLOBAL innodb_fast_shutdown = 0;

Tiếp theo, chạy phần sau trong HĐH

cd /var/lib/mysql
service mysql stop
mv ib_logfile0 ib_logfile0.bak
mv ib_logfile1 ib_logfile1.bak
service mysql start

Hãy thử một lần !!!

CẬP NHẬT 2012-12-31 08:30 EDT

Từ bình luận cuối cùng của bạn

Nó ngừng leo khoảng 1 gb. Tôi đã xóa các cơ sở dữ liệu không sử dụng và có vẻ như mysql 5.5 lưu trữ rất nhiều dữ liệu trong bộ nhớ vì điều này đã không xảy ra trong 5.0. Có phải mysql thay đổi nhiều không?

Vâng, MySQL đã thay đổi rất nhiều. Trên thực tế, có nhiều trường hợp nâng cấp từ MySQL 5.0 lên MySQL 5.5 và dẫn đến suy giảm hiệu suất. InnoDB 5.5 hiện được trang bị để thực hiện siêu phân luồng và tham gia đa lõi.

Percona thực sự đã thử nghiệm điều này một lúc trước .

Xin vui lòng đọc cho tôi bài viết trước đây về chủ đề này

Tôi cũng đã viết về điều này trong ServerFault và StackOverflow


Tôi sẽ thử điều này: sự khác biệt giữa innodb_buffer_pool_size và innodb-buffer-pool-size
Chris Muench 30/12/12

innodb_buffer_pool_size768M có thể sẽ đẩy giới hạn trên một máy chỉ có 1 GB RAM. Chỉ còn lại 256M cho bất cứ điều gì đang diễn ra trong kernel và không gian người dùng bên ngoài MySQL, cộng với mọi thứ xảy ra trong MySQL bên ngoài nhóm bộ đệm InnoDB ... Bạn cần phải đặt nó thành thứ gì đó nhưng thật lòng tôi sẽ nhìn vào để có thêm bộ nhớ cũng.
James L

FWIW, NUMA không nên là một yếu tố ở đây: một máy 1 GB tại Rackspace chạy CentOS 6.3 sẽ là một VM chỉ có một nút NUMA được trình bày.
James L

@James vì ​​nó là VM nên bạn đúng. Điều chỉnh đa lõi là không cần thiết và 75% RAM trên 1GB là quá thấp. Anh ấy cần ít nhất 4GB.
RolandoMySQLDBA

Tôi đã nâng cấp lên máy chủ rackspace 2gb và việc sử dụng bộ nhớ vẫn đang tăng lên. Chúng tôi đang bối rối về những gì đang xảy ra. Điều này KHÔNG xảy ra trong mysql 5.0.96
Chris Muench

0

Ngoài những lời khuyên rất hay được Rolando đưa ra, về phía hệ thống, bạn có thể kích hoạt cài đặt không trao đổi bằng sysctl . Tôi thường đặt vm.swappiness=10trên máy MySQL trong /etc/sysctl.conf . Nó cho phép truy cập hạn chế vào trao đổi, nhưng cho phép nó nếu được yêu cầu.

Giá trị mặc định của vm.swappiness là 60, rất dễ cho phép.


0

Lưu ý : Tôi đã đăng câu trả lời này cho một câu hỏi liên quan trên stackoverflow. Giải pháp này dành riêng cho Linux và Systemd, nhưng trên thực tế, có thể được điều chỉnh phù hợp với bất kỳ hệ thống nào hỗ trợ đúng memlockcác cuộc gọi và cung cấp khả năng thực hiện điều đó cho các quy trình không được root.

Cập nhật : Thực tế, giải pháp này có thể không hoạt động tốt. Xem ghi chú ở cuối.

Có tồn tại một lớp các ứng dụng mà bạn không bao giờ muốn chúng trao đổi. Một lớp như vậy là một cơ sở dữ liệu. Cơ sở dữ liệu sẽ sử dụng bộ nhớ làm bộ nhớ cache và bộ đệm cho các vùng đĩa của chúng và hoàn toàn không có ý nghĩa rằng chúng được đặt để trao đổi. Bộ nhớ cụ thể có thể chứa một số dữ liệu liên quan không cần thiết trong một tuần cho đến một ngày khi khách hàng yêu cầu. Nếu không có bộ đệm / hoán đổi, cơ sở dữ liệu sẽ chỉ tìm thấy bản ghi có liên quan trên đĩa, sẽ khá nhanh; nhưng với việc hoán đổi, dịch vụ của bạn có thể đột nhiên mất nhiều thời gian để đáp ứng.

mysqldbao gồm mã để sử dụng cuộc gọi hệ điều hành / hệ thống memlock. Trên Linux, vì ít nhất 2.6.9, cuộc gọi hệ thống này sẽ hoạt động đối với các quy trình không root có CAP_IPC_LOCKkhả năng [1] . Khi sử dụng memlock(), quy trình vẫn phải hoạt động trong giới LimitMEMLOCKhạn. [2] . Một trong những (một vài) điều tốt systemdlà bạn có thể cấp cho mysqldquá trình những khả năng này mà không yêu cầu một chương trình đặc biệt. Nếu cũng có thể thiết lập các rlimits như bạn mong đợi ulimit. Đây là một overridetệp để mysqldthực hiện các bước cần thiết, bao gồm một số khác mà bạn có thể cần cho một quy trình, chẳng hạn như cơ sở dữ liệu:

[Service]
# Prevent mysql from swapping
CapabilityBoundingSet=CAP_IPC_LOCK

# Let mysqld lock all memory to core (don't swap)
LimitMEMLOCK=-1 

# do not kills this process if low on memory
OOMScoreAdjust=-900 

# Use higher io scheduling
IOSchedulingClass=realtime    

Type=simple    
ExecStart=
ExecStart=/usr/sbin/mysqld --memlock $MYSQLD_OPTS

Lưu ý Cộng đồng tiêu chuẩn mysql hiện có kèm theo Type=forking và thêm --daemonizetùy chọn cho dịch vụ ExecStarttrực tuyến. Điều này vốn đã kém ổn định hơn so với phương pháp trên.

Giới thiệu về ghi đè tệp trong systemd : Bạn tạo một thư mục /etc/systemd/system/được đặt tên mysqld.service.dvà đặt tệp mới (có nội dung trên) vào đó.

CẬP NHẬT Tôi không hài lòng 100% với giải pháp này. Sau nhiều ngày chạy, tôi nhận thấy quá trình này vẫn có lượng trao đổi khổng lồ! Kiểm tra /proc/XXXX/smaps, tôi lưu ý như sau:

  • Đóng góp lớn nhất của trao đổi là từ một phân khúc ngăn xếp! Lúc đầu điều này có vẻ không tệ lắm, nhưng sau vài ngày, nó đã đứng ở mức 437 MB và dao động. Điều này trình bày các vấn đề hiệu suất rõ ràng. Nó cũng chỉ ra rò rỉ bộ nhớ dựa trên ngăn xếp.
  • Không có trang bị khóa . Điều này cho thấy memlocktùy chọn trong MySQL (hoặc Linux) bị hỏng. Trong trường hợp này, nó sẽ không quan trọng lắm vì MySQL không thể khóa ngăn xếp.
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.