Debian Jessie: Настройка mysql-server (MariaDB Server)

Это заметка из цикла стетей моего небольшого HowTo по Debian Jessie.

Для меня тюнинг mysql — это такой себе постоянный вялотекущий процесс который не имеет ни начала ни конца. Базы данных вцелом — это огромный кусок IT-индустрии в котором нужно вариться постоянно чтобы быть специалистом. Признаюсь честно, я не очень интересуюсь базами данных, поэтому настройку обычно свожу к соблюдению общих рекомендаций, не более …
Тут сделаю еще небольшую ремарку, особенно полезную новичкам. Настройка любой БД — это очень индивидуальный процесс, поэтому если вы видите на какомто ресурсе четкие рекомендации как и что нужно тюнить — не стоить этому верить. Разбираться нужно всеравно самому, анализировать конкретный сервер с конкретной нагрузкой на конкретном железе. Львиная доля оптимизации лежит также и на грамотной постройке самой базы, наличию правильных индексов и тд и тп Тут нам здорово помогает фича сбора статистики самим mysql-сервером, о ней чуть позже.

Поскольку я не просто БД-шный ламер но еще и лентяй с прокачанным скилом гугления — корректировку дефолнтного конфига mysql я делаю с помощью магического перл-скрипта mysqltuner.pl Это известный скрипт для тюнинга mysql, в некоторых дистрах он даже опакечен и есть в официальных репозитариях, но я не вижу смысла искать его там, так как знаю ссылку и могу скачать самую свежую версию из Интернет. В MySQL по-дефолту включен фича сбора различной статистики: операции, использование памяти, кэшей, конектов, открытых файлов и тд и тп Эти статистические данные + инфо о железе сервера использует скрипт для выдачи рекомендаций по настройке mysql-server. Из этого следует, что скрипт имеет смысл использовать после того как mysql поработал в продакшин режиме хотя бы сутки, а лучше больше … за это время у него набралось достаточное количество данных для анализа, иначе результат может получиться непредсказуемый.

Вот она, магическая команда закачки скрипта:

gw:~$ wget -c https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl

Даем скрипту права на запуск:

gw:~$ chmod +x mysqltuner.pl

Запускаем (в процессе скрипт спросит login/pass администратора mysql — вводите):

gw:~$ ./mysqltuner.pl

 >>  MySQLTuner 1.4.0 - Major Hayden <major@mhtx.net>
 >>  Bug reports, feature requests, and downloads at http://mysqltuner.com/
 >>  Run with '--help' for additional options and output filtering
Please enter your MySQL administrative login: root
Please enter your MySQL administrative password:
[!!] Currently running unsupported MySQL version 10.0.16-MariaDB-1
[OK] Operating on 64-bit architecture

-------- Storage Engine Statistics -------------------------------------------
[--] Status: +ARCHIVE +Aria +BLACKHOLE +CSV +FEDERATED +InnoDB +MRG_MyISAM
[--] Data in PERFORMANCE_SCHEMA tables: 0B (Tables: 52)
[--] Data in InnoDB tables: 99M (Tables: 231)
[--] Data in MEMORY tables: 124K (Tables: 4)
[--] Data in MyISAM tables: 47M (Tables: 188)
[!!] Total fragmented tables: 18

-------- Security Recommendations  -------------------------------------------
[OK] All database users have passwords assigned

-------- Performance Metrics -------------------------------------------------
[--] Up for: 13d 21h 3m 42s (1M q [1.288 qps], 58K conn, TX: 5B, RX: 277M)
[--] Reads / Writes: 94% / 6%
[--] Total buffers: 1.1G global + 2.8M per thread (500 max threads)
[OK] Maximum possible memory usage: 2.4G (63% of installed RAM)
[OK] Slow queries: 0% (0/1M)
[OK] Highest usage of available connections: 3% (18/500)
[OK] Key buffer size / total MyISAM indexes: 32.0M/2.6M
[OK] Key buffer hit rate: 96.0% (1K cached / 42 reads)
[!!] Query cache is disabled
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 392K sorts)
[!!] Joins performed without indexes: 9487
[!!] Temporary tables created on disk: 83% (120K on disk / 144K total)
[OK] Thread cache hit rate: 99% (18 created / 58K connections)
[!!] Table cache hit rate: 14% (452 open / 3K opened)
[OK] Open file limit used: 4% (431/10K)
[OK] Table locks acquired immediately: 100% (1M immediate / 1M locks)
[OK] InnoDB buffer pool / data size: 1000.0M/99.5M
[OK] InnoDB log waits: 0
-------- Recommendations -----------------------------------------------------
General recommendations:
    Run OPTIMIZE TABLE to defragment tables for better performance
    Adjust your join queries to always utilize indexes
    When making adjustments, make tmp_table_size/max_heap_table_size equal
    Reduce your SELECT DISTINCT queries without LIMIT clauses
    Increase table_open_cache gradually to avoid file descriptor limits
    Read this before increasing table_open_cache over 64: http://bit.ly/1mi7c4C
Variables to adjust:
    query_cache_size (>= 8M)
    join_buffer_size (> 128.0K, or always use indexes with joins)
    tmp_table_size (> 32M)
    max_heap_table_size (> 32M)
    table_open_cache (> 4096)

gw:~$

Сразу говорю что не буду розжевывать доп инфой параметры и их значения, просто описываю то что имею
Начнем по порядку выданных скриптом параметров для подстройки — Variables to adjust
query_cache_size (>= 8M)
Незнаю почему, могу ошибаться (обязательно на досуге поищу пруф) но в моей голове данный параметр ассоциируется с тремя параметрами которые нужно подстраивать вместе, а не врозь. Вот данная «троечка», а также мои текущие значения:

query-cache-type        = 1
query-cache-size        = 128M
query-cache-limit       = 2M

join_buffer_size (> 128.0K, or always use indexes with joins)
просто задал вот такое значение для sort/join буферов:

sort-buffer-size    = 4M
join-buffer-size    = 4M

table_open_cache (> 4096)
для начала задал необходимый минимум:

table-open-cache    = 4096

Что касается настройки tmp_table_size/max_heap_table_size хорошо описано тут Вот тут рекомендация уже по админской части — настроить отдельную директорию в tmpfs для операций которые требуют tmp
tmpfs это RAM, используется по мере необходимости, но ограничиваем размер 512MB
Для начала создаем директорию которая будет точкой монтирования:

gw:~$ sudo mkdir /var/lib/mysql/tmp

Исправляем владельца:

gw:~$ sudo chown mysql.mysql /var/lib/mysql/tmp

Определяем uid/gid пользователя mysql

gw:~$ sudo id mysql
uid=108(mysql) gid=113(mysql) groups=113(mysql)
gw:~$

Редактируем /etc/fstab, открываем:

gw:~$ sudo vim /etc/fstab

Добавляем туда вот что:

# MySQL tmp Partition
tmpfs /var/lib/mysql/tmp tmpfs rw,gid=113,uid=108,size=512M,nr_inodes=10k,mode=0700 0 0

Проверка, вот что получилось:

gw:~$ sudo mount -a
...
tmpfs on /var/lib/mysql/tmp type tmpfs (rw,relatime,size=524288k,nr_inodes=10240,mode=700,uid=108,gid=113)
...

Вот так проверяем что mysql имеет туда права для работы:

gw:~$ ls -l /var/lib/mysql
total 20
drwxr-xr-x 10 mysql mysql  4096 May 20 08:27 data
drwx------  2 root  root  16384 Apr 10 06:34 lost+found
drwx------  2 mysql mysql    40 May 21 08:59 tmp
gw:~$

Теперь подправим mysql конфиг, открываем:

gw:~$ sudo vim /etc/mysql/my.cnf

в секции [mysqld] должна быть такая опция

tmpdir          = /var/lib/mysql/tmp

а также параметры tmp нужно уменьшить:

tmp-table-size          = 1k
max-heap-table-size     = 1k

перезапускаем сервис mysql:

gw:~$ sudo systemctl restart mysql.service

Спустя какоето время опять обновляю скрипт (он достаточно активно развивается), даю ему права на выполнение и запускаю снова:

gw:~$ ./mysqltuner.pl
Please enter your MySQL administrative login: root
Please enter your MySQL administrative password:
 >>  MySQLTuner 1.6.1 - Major Hayden <major@mhtx.net>
 >>  Bug reports, feature requests, and downloads at http://mysqltuner.com/
 >>  Run with '--help' for additional options and output filtering
[--] Skipped version check for MySQLTuner script
[OK] Currently running supported MySQL version 10.0.18-MariaDB-0
[OK] Operating on 64-bit architecture

-------- Storage Engine Statistics -------------------------------------------
[--] Status: +ARCHIVE +Aria +BLACKHOLE +CSV +FEDERATED +InnoDB +MRG_MyISAM
[--] Data in MEMORY tables: 0B (Tables: 2)
[--] Data in InnoDB tables: 246M (Tables: 169)
[!!] Total fragmented tables: 22

-------- Security Recommendations  -------------------------------------------
[OK] There are no anonymous accounts for any database users
[OK] All database users have passwords assigned
[!!] There is no basic password file list !

-------- Performance Metrics -------------------------------------------------
[--] Up for: 23h 27m 0s (368K q [4.368 qps], 15K conn, TX: 908M, RX: 60M)
[--] Reads / Writes: 91% / 9%
[--] Binary logging is disabled
[--] Total buffers: 1.0G global + 8.7M per thread (50 max threads)
[OK] Maximum reached memory usage: 1.1G (28.72% of installed RAM)
[OK] Maximum possible memory usage: 1.5G (38.45% of installed RAM)
[OK] Slow queries: 0% (1K/368K)
[OK] Highest usage of available connections: 12% (6/50)
[OK] Aborted connections: 0.89%  (134/15122)
[OK] Query cache efficiency: 44.7% (201K cached / 449K selects)
[OK] Query cache prunes per day: 0
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 8K sorts)
[!!] Temporary tables created on disk: 95% (29K on disk / 30K total)
[OK] Thread cache hit rate: 99% (6 created / 15K connections)
[OK] Table cache hit rate: 116% (421 open / 360 opened)
[OK] Open file limit used: 0% (57/10K)
[OK] Table locks acquired immediately: 100% (80K immediate / 80K locks)

-------- MyISAM Metrics -----------------------------------------------------
[!!] Key buffer used: 18.3% (6M used / 33M cache)
[OK] Key buffer size / total MyISAM indexes: 32.0M/121.0K

-------- InnoDB Metrics -----------------------------------------------------
[--] InnoDB is enabled.
[OK] InnoDB buffer pool / data size: 768.0M/246.6M
[OK] InnoDB buffer pool instances: 1
[!!] InnoDB Used buffer: 23.86% (11729 used/ 49151 total)
[OK] InnoDB Read buffer efficiency: 99.99% (74534144 hits/ 74542487 total)
[!!] InnoDB Write buffer efficiency: 0.00% (0 hits/ 1 total)
[OK] InnoDB log waits: 0.00% (0 waits / 25172 writes)

-------- AriaDB Metrics -----------------------------------------------------
[--] AriaDB is disabled.

-------- Replication Metrics -------------------------------------------------
[--] No replication slave(s) for this server.
[--] This is a standalone server..

-------- Recommendations -----------------------------------------------------
General recommendations:
    Run OPTIMIZE TABLE to defragment tables for better performance
    MySQL started within last 24 hours - recommendations may be inaccurate
    When making adjustments, make tmp_table_size/max_heap_table_size equal
    Reduce your SELECT DISTINCT queries which have no LIMIT clause
Variables to adjust:
    tmp_table_size (> 1K)
    max_heap_table_size (> 16K)
gw:~$

Среди прочего видим ругать на tmp таблицы:
[!!] Temporary tables created on disk: 95% (29K on disk / 30K total)
это нормально, так как скрипт думает что используется директория tmp на диске, но мы то знаем что она в RAM 🙂

Вцелом на данный момент оставляю как есть, в дальнейшем еще буду копать эту тему и дописывать инетесности. Ниже приведу полный конфиг mysql-server /etc/mysql/my.cnf

[client]
port        = 3306
host        = 127.0.0.1

[mysqld_safe]
socket      = /var/run/mysqld/mysqld.sock
nice        = 0

[mysqld]
user        = mysql
pid-file    = /var/run/mysqld/mysqld.pid
socket      = /var/run/mysqld/mysqld.sock
port        = 3306
basedir     = /usr
datadir     = /var/lib/mysql/data
tmpdir      = /var/lib/mysql/tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
bind-address        = 127.0.0.1

key-buffer-size     = 32M
myisam-recover      = FORCE,BACKUP

max-heap-table-size = 10M
query-cache-type    = 1
query-cache-size    = 128M
query-cache-limit   = 2M
max-connections     = 50
thread-cache-size   = 50
open-files-limit    = 10000
table-definition-cache  = 4096
table-open-cache    = 4096
join-buffer-size    = 4M
sort-buffer-size    = 4M

tmp-table-size      = 1k
max-heap-table-size = 1k

innodb-flush-method     = O_DIRECT
innodb-log-files-in-group   = 2
innodb-log-file-size        = 128M
innodb-flush-log-at-trx-commit  = 1
innodb-file-per-table       = 1
innodb_buffer_pool_size     = 768M
innodb_buffer_pool_instances    = 1
innodb_io_capacity      = 500

log_queries_not_using_indexes
max_allowed_packet   = 16M
log_error            = /var/log/mysql/error.log
slow_query_log_file  = /var/log/mysql/mysql-slow.log
slow_query_log       = 1
long_query_time      = 2
expire_logs_days     = 7
max_binlog_size      = 64M

[mysqldump]
quick
quote-names
max_allowed_packet  = 16M

[mysql]

[isamchk]
key_buffer      = 16M

!includedir /etc/mysql/conf.d/

Хай щастить!

    • Константин
    • Октябрь 25th, 2016 7:34пп

    Добрый вечер, насколько я понял tmp-table-size — это размер превысисив какой данные временных таблиц записываются на диск. А у Вас выставлено 1k, то есть, получается все временные таблицы записываются на диск, смысл тогда от tmpfs?

    • admin
    • Ноябрь 9th, 2016 12:44пп

    @Константин
    tmpfs = RAM. В этом весь смысл.

  1. Трэкбэков пока нет.

Why ask?