Дайте мне хорошую политику, и я вам дам хорошие финансы (А. Тюрго).

MySQL и память: история любви (часть 1)

7 мин для чтения
FavoriteLoadingДобавить в избранное
1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (1 оценок, среднее: 5,00 из 5)
Загрузка...
30 мая 2019
MySQL и память. История любви (часть 1)
Как вы, возможно, знаете, иногда MySQL может потребовать много памяти. Конечно, наличие данных в памяти всегда лучше, чем на диске… ОЗУ по-прежнему намного быстрее, чем на любом SSD-диск. По этой причине мы рекомендуем хранить как можно больше рабочих данных в памяти (мы предполагаем, что вы, конечно, используете InnoDB). Также по этой причине вы не хотите использовать Swap для MySQL, но не забывайте, что медленный MySQL всегда лучше, чем вообще никакой MySQL, поэтому не забудьте настроить раздел Swap, но старайтесь избегать его использования. Фактически, мы видели, как многие люди просто удаляли раздел подкачки … а затем OOM Killer сделал свою работу … и mysqld часто становится его первой жертвой. MySQL выделяет буферы и кэши для повышения производительности операций с базой данных. Этот процесс подробно описан в руководстве, В этой серии статей мы предоставляем вам некоторую информацию, чтобы проверить потребление памяти MySQL и какие настройки или действия конфигурации могут быть сделаны, чтобы понять и контролировать использование памяти MySQL. Мы начнем серию с операционной системы.

 

Операционная система

На уровне ОС есть несколько команд, которые мы можем использовать, чтобы понять использование памяти MySQL.

 

Использование памяти

Вы можете проверить mysqld использование памяти из командной строки:

# ps -eo size,pid,user,command --sort -size | grep [m]ysqld \ | awk '{ hr=$1/1024 ; printf("%13.2f Mb ",hr) } { for ( x=4 ; x<=NF ; x++ ) { printf("%s ",$x) } print "" }' \  |cut -d "" -f2 | cut -d "-" -f1
 

Вывод:

1841.10 Mb /usr/sbin/mysqld 
   0.46 Mb /bin/sh /usr/bin/mysqld_safe

 

top также может быть использован для проверки этого. Для top 3.2:

# top -ba -n1 -p $(pidof mysqld) | grep PID -A 1
 

Вывод:

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                
 1752 mysql     20   0 1943m 664m  15m S  0.0 11.1  19:55.13 mysqld                                                                                                                                 

# top -ba -n1 -m -p $(pidof mysqld) | grep PID -A 1
 

Вывод:

  PID USER      PR  NI  USED  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                
 1752 mysql     20   0  664m 664m  15m S  2.0 11.1  19:55.17 mysqld

 

Для более поздней вершины вы можете использовать top -b -o %MEM -n1 -p $(pidof mysqld) | grep PID -A 1 VIRT, представляющий общий объем виртуальной памяти, используемой mysql. Он включает в себя весь код, данные и общие библиотеки, а также страницы, которые в конечном итоге были заменены. USED сообщает сумму rss процесса (размер резидентного набора, часть памяти, занятую процессом, который содержится в оперативной памяти) и общее количество подкачки. Позже мы увидим, что мы можем проверить из клиента MySQL.

 

SWAP

Итак, мы видим, что это может в конечном итоге включать и измененные страницы. Давайте проверим, использует ли mysqld подкачку, и первое, что нужно сделать, это проверить, есть ли у машины некоторая информация в swap:

# free -m
 

Вывод:

             total       used       free     shared    buffers     cached
Mem:          5965       4433       1532        128        454       2359
-/+ buffers/cache:       1619       4346
Swap:         2045         30       2015

 

Мы видим, что используется небольшое количество подкачки (30 МБ), это MySQL? Давайте проверим:

# cat /proc/$(pidof mysqld)/status | grep Swap
 

Вывод:

VmSwap:       0 kB

 

Отлично, mysqld не используется. Если вы действительно хотите узнать, какие процессы поменялись местами, выполните следующую команду:

for i in $(ls -d /proc/[0-9]*) 
do  
   out=$(grep Swap $i/status 2>/dev/null)
   if [ "x$(echo $out | awk '{print $2}')" != "x0" ] && [ "x$(echo $out | awk '{print $2}')" != "x" ]
   then    
  echo "$(ps -p $(echo $i | cut -d'/' -f3) \
         | tail -n 1 | awk '{print $4'}): $(echo $out | awk '{print $2 $3}')" 
   fi
done

 

Конечно, страницы в разделе подкачки могли существовать уже давно и никогда не использовались, поскольку… конечно, мы рекомендуем использовать vmstat и проверять столбцы si и т. д. (Настоятельно рекомендуется использовать систему трендов):

# vmstat  1 10

 

Вывод:

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----                                                                              
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st                                                                              
 0  0      0 162280 120352 1344112    0    0  1035   197  584  637 19  5 75  1  1                                                                             
 0  0      0 162068 120484 1344256    0    0   136     4 1346  804  1  0 97  0  1                                                                             
 0  0      0 162180 120484 1344260    0    0     0     4 1572  733  0  1 98  0  1                                                                             
 2  0      0 148280 123580 1351640    0    0 10208     4 2553 2091 21  3 70  5  1                                                                             
 3  0      0 126864 125400 1363440    0    0 12164   316 3624 4652 54  9 24 11  3                                                                             
 0  0      0 135020 126188 1368308    0    0  4632   856 3407 4793 53 12 30  3  3                                                                             
 0  0      0 134740 126328 1368388    0    0   132    40 1514  849  1  0 98  0  1                                                                             
 1  0      0 107908 126388 1368360    0    0     4  2220 2093 1854 24  8 66  0  2                                                                             
 1  1      0 115552 126436 1368536    0    0   148   212 2074 1798 26  5 67  0  1                                                                             
 1  0      0 250776 126440 1368536    0    0    44     4 2202 1573 24 10 66  0  1

 

На этом сервере мы можем видеть, что mysqld подкачку не использует, но если бы это было так, и некоторое свободное ОЗУ оставалось доступным, что можно было бы сделать? Если это так, вы должны проверить 2 прямые причины:

  1. swappiness
  2. NUMA

 

Swappiness

Параметр swappiness контролирует стремление ядра перемещать процессы из физической памяти и помещать их в раздел подкачки. Как мы объяснили ранее, диски намного медленнее, чем ОЗУ, поэтому это приводит к более медленному времени отклика для системы и приложений, если процессы слишком агрессивно перемещаются из памяти. Высокое значение подкачки означает, что ядро будет более склонно к отмене сопоставления страниц. Низкое значение swappiness означает обратное, ядро будет менее склонно к распаковке отображенных страниц. Это означает, что чем выше значение swappiness, тем больше будет система подкачки! Значение по умолчанию (60) слишком велико для выделенного сервера MySQL и должно быть уменьшено. Обратите внимание, что с более старыми ядрами Linux (ранее 2.6.32), 0 означало, что ядро ​​должно избегать выгрузки процессов из физической памяти как можно дольше. Теперь это же значение полностью исключает использование swap. Мы рекомендуем установить его на 1 или 5.

# sysctl -w vn.swappinness=1

 

Numa

Для серверов, имеющих несколько ядер NUMA, рекомендуется установить режим чередования NUMA, который уравновешивает распределение памяти для всех узлов. MySQL 8.0 поддерживает NUMA для InnoDB. Вам просто нужно включить его в своей конфигурации: innodb_numa_interleave = 1 чтобы проверить, есть ли у вас несколько узлов NUMA, вы можете использовать numactl -H. Это два разных вывода:

# numactl -H
 

Вывод:

available: 1 nodes (0)
node 0 cpus: 0 1 2 3 4 5 6 7
node 0 size: 64379 MB
node 0 free: 2637 MB
node distances:
node 0 
0: 10
# numactl -H
 

Вывод:

available: 4 nodes (0-3)
node 0 cpus: 0 2 4 6
node 0 size: 8182 MB
node 0 free: 221 MB
node 1 cpus: 8 10 12 14
node 1 size: 8192 MB
node 1 free: 49 MB
node 2 cpus: 9 11 13 15
node 2 size: 8192 MB
node 2 free: 4234 MB
node 3 cpus: 1 3 5 7
node 3 size: 8192 MB
node 3 free: 5454 MB
node distances:
node 0 1 2 3 
0: 10 16 16 16 
1: 16 10 16 16 
2: 16 16 10 16 
3: 16 16 16 10

 

Мы можем видеть, что при наличии нескольких узлов NUMA (правый столбец) по умолчанию, память распределяется неравномерно между всеми этими узлами. Это может привести к большему обмену.

 

Кэш файловой системы

Еще один момент, который мы можем проверить из ОС – это кеш файловой системы. По умолчанию Linux будет использовать кэш файловой системы для всех входов/выходов (это одна из причин, по которой использование MyISAM не рекомендуется, так как этот механизм хранения опирается на кэш FS и может привести к потере данных, так как Linux синхронизирует эти записи. каждые 10 секунд). Конечно, поскольку вы используете InnoDB, с O_DIRECT as innodb_flush_method, MySQL будет обходить кеш файловой системы (InnoDB уже имеет достаточно оптимизированных кэшей в любом случае, и один дополнительный не нужен). InnoDB не будет использовать кэш-память FS для файлов данных (* .ibd). Но, конечно, есть и другие файлы, используемые в MySQL, которые все еще будут использовать кэш FS. Давайте проверим этот пример:

# ~fred/dbsake fincore binlog.000017

 

Вывод:

binlog.000017: total_pages=120841 cached=50556 percent=41.84

# ls -lh binlog.000017 

 

Вывод:

-rw-r----- 1 mysql mysql 473M May 30 22:56 binlog.000017

# free -m

 

Вывод:

             total       used       free     shared    buffers     cached
Mem:          5965       4608       1356        128        435       2456
-/+ buffers/cache:       1716       4249
Swap:         2045         30       2015

# ~fred/dbsake uncache binlog.000017 

 

Вывод:

Uncached binlog.000017
# free -m

 

Вывод:

             total       used       free     shared    buffers     cached
Mem:          5965       4413       1552        128        435       2259
-/+ buffers/cache:       1718       4247
Swap:         2045         30       2015

 

Несколько объяснений. Мы начали проверять, сколько двоичных журналов присутствовало в кеше файловой системы (используя dbsake fincore), и мы увидели, что 42% из 473M использовали оперативную память в качестве кеша FS. Затем мы принудительно распаковали эти страницы в кеше (используя fincore uncache) и, наконец, вы могли видеть, что мы освободили +/- 195 МБ ОЗУ. Вы можете быть удивлены, увидев, какие журналы или файлы данных используют кэш FS (например, для создания файла). Мы настоятельно рекомендуем вам проверить это.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Просмотров: 26

Если статья понравилась, то поделитесь ей в социальных сетях:

Отправить ответ

Войти с помощью: 
avatar
  Подписаться  
Уведомление о

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам:

Заполните форму и наш менеджер перезвонит Вам в самое ближайшее время!

badge
Обратный звонок 1
Отправить
galka

Спасибо! Ваша заявка принята

close
galka

Спасибо! Ваша заявка принята

close