LINUX.ORG.RU
ФорумAdmin

Блин, вот как воевать со свопом?

 , swappiness


2

12

MySQL занимает 25Гб VIRT. Из них только 16Гб в RSS. При этом 9.6Гб в буферах и кешах + 2Гб свободно. Большие MySQL-запросы по базе безбожно тормозят с уходом в IO по причине доставания данных из свопа.

swappines = 1

Что ещё можно подкрутить, чтобы заставить MySQL реже уходить в своп (но не отключая своп — всё в мои 32Гб оперативки не влезет)?

★★★★★

Ответ на: комментарий от router

механизм своппинга решил, что выгрузить нужно именно страницы mysql

И теперь смотрим, какой я задал вопрос в топикстарте: «Что ещё можно подкрутить, чтобы заставить MySQL реже уходить в своп?».

KRoN73 ★★★★★
() автор топика
Ответ на: комментарий от KRoN73

myisam_sort_buffer_size = 500M

sort_buffer_size (и myisam_sort_buffer_size) выделяются на каждый поток. Чисто теоретически у вас могут возникать ситуации, в которых такое значение приведёт к неистовому жору памяти с закономерным вытеснением в своп.

Да и с учётом

Нет, все запросы выдёргивают короткие результаты. Это чистый Web.
Индексы на каждый чих, explain выдаёт разумное число строк

Не понятно нафига тут аж 500M?

NeOlip ★★
()

Переходи постгрес, он использует page cache операционной системы вместо своего велосипедного кэша, а ОС при пиквом росте потребления памяти в приложении проще выкинуть старые страницы из кэша чем что-то свопить

annulen ★★★★★
()
Последнее исправление: annulen (всего исправлений: 1)
Ответ на: комментарий от NeOlip

sort_buffer_size выделяются на каждый поток. Чисто теоретически у вас могут возникать ситуации, в которых такое значение приведёт к неистовому жору памяти с закономерным вытеснением в своп.

sort_buffer_size у меня = 8M

(и myisam_sort_buffer_size)

Хм? Я такое читал много лет подряд:

# myisam_sort_buffer_size — размер буфера, выделяемого MyISAM для сортировки
# индексов при REPAIR TABLE или для создания индексов при
# CREATE INDEX, ALTER TABLE. Значение по умолчанию 8 МБ, его стоит увеличить
# вплоть до 30-40% ОЗУ. Выигрыш в производительности соответственно будет
# только при выполнении вышеупомянутых запросов.

KRoN73 ★★★★★
() автор топика
Ответ на: комментарий от Valman_new

Я полагаю, все должно влезть. У лора БД на 48Гб живет

$ du -hs /var/lib/mysql
30G	/var/lib/mysql



И кроме MySQL у меня на машине с 32Гб много кто живёт :)

KRoN73 ★★★★★
() автор топика
Ответ на: комментарий от KRoN73

Я с подобной проблемой успешно справился вот как.

Мой кейс: на машине с десяток виртуалок, делались регулярно большие бэкапы снапшотов их дисков. Во время бэкапов память совершенно ненужно заполнялась буфферами - что далее приводило к частичного вытеснения памяти виртуалок в своп, что конечно нежелательно.

Эксперименты со swappiness ни к чему не привели (даже если = 0).

Проблема решилась ограничиванием физической памяти процесса бэкапа в 200Мb (и то много, но ладно) - через cgroups - вследствие чего он не занимал гигабайты памяти буфферами. С тех пор, свап на этой машине всегда по нулям.

Так что может стоит подойти с обратной стороны - узнать что за процесс съедает только буфферов - и ограничить его через cgroups.

Или просто, для всех основных пожирателей памяти - самому решить, кому сколько физической памяти нужно - и ограничить их соответно через cgroups политик.

manul91
()

Что ещё можно подкрутить, чтобы заставить MySQL реже уходить в своп (но не отключая своп — всё в мои 32Гб оперативки не влезет)?

Памяти докупить вестимо. 64Гб хватит всем!

А если серьёзно, то ведь все индексы в памяти хранятся и запросы только по индексам?

WARNING ★★★★
()
Ответ на: комментарий от manul91

Так что может стоит подойти с обратной стороны - узнать что за процесс съедает только буфферов

Хм. Как?

KRoN73 ★★★★★
() автор топика

Перейти на ZVOL в качестве хранилища БД.

iZEN ★★★★★
()
Ответ на: комментарий от KRoN73

Хм. Как?

1) Мониторингом за buffers, cache memory / slabtop (/proc/meminfo), экспериментом.

2) Можно попытаться экспериментировать с vm.vfs_cache_pressure как описано здесь http://unix.stackexchange.com/questions/253816/restrict-size-of-buffer-cache-... (у меня это помогло в некоторой степени но не полностью, как хотелось бы; вопрос решился только cgroups)

3) Если у тебя такие запросы, то ты точно знаешь сколько RAМ тебе хотелось бы держать свободной для MySQL, и сколько для *всего остального* - допустим 26GB/6GB. Можно настроить cgroups подобным образом через демон на 6GB для «всего остального», см. например https://www.digitalocean.com/community/tutorials/how-to-limit-resources-using... в дебиане демон cgred находится в пакет cgroup-tools (либо через systemd наверное, но как в нем точно я не знаю) (тебе нужно ограничить memory.limit_in_bytes для «всего остального» - все остальное вкл. его буфера не будет занимать более чем 6GB)

Таким способом 3) - ты добьешься желаемого, но нужно включать и здравый разум - вполне возможно что «решая проблему» для mysql ты создадишь проблемы для всего остального (остальное будет свапится намного сильнее).

Так что лучше подход 1 или 2 - когда ограничиваешь конкретно то, для чего знаешь что заполняет buffer cache лишним (а не mysql vs «все остальное»). Если buffered у тебя большой - это возможно операция копирования cp/rsync много данных (гигабайтами), если cached - возможно разное десктопное говно (если это десктоп) типа okular, firefox и т.д.

manul91
()
Ответ на: комментарий от KRoN73

P.S. vm.vfs_cache_pressure поможет только если твое «9-10GB в кеше и буфферах» - это в основном буфферы. Нужно смотреть детально сколько кеш и сколько буффер кеш (/proc/meminfo в помощь).

manul91
()
10 июля 2017 г.

Что-то у меня MySQL (точнее, MariadDB) по сабжу совсем в разнос пошёл. В конфигах ничего не менялось. Сам сервер обновлялся.

Сейчас:

VIRT = 24.8G
RSS = 3.7G (!!)
SWAP = 0 (!!!)

В системе свободно в кеше и буферах 23Гб оперативки. Своп занят только на 1.5Гб при свободных 32Гб.

При этом MySQL постоянно грузит данные с диска, всё жутко тормозит.

Что за фигня? o_O

KRoN73 ★★★★★
() автор топика
Ответ на: комментарий от KRoN73

Сейчас:

Чем цифры кажутся странными?

При этом MySQL постоянно грузит данные с диска, всё жутко тормозит.

Либо какие-то лимиты по памяти в настройках mariadb, либо план запросов такой, что требует не жрать память

router ★★★★★
()
Ответ на: комментарий от anonymous

Осиль уже zram

Блин. Как раз в нём проблема и была :) После топикстарта я эксперименторовал с zram, он так и остался включенным. А 11 дней назад я сервер перезагружал. И что-то с zram пошло не так :)

Сейчас отключил своп в zram и использование RSS начало понемногу расти.

KRoN73 ★★★★★
() автор топика
Ответ на: комментарий от router

Чем цифры кажутся странными?

Тем, что RSS в 3Гб при размере базы 28Гб и innodb_buffer_pool_size=20G — это реально странно :)

...

К счастью с последней проблемой разобрался, стоило вырубить zram и производительность начала понемногу, по мере перехода VIRT в RSS восстанавливаться.

Однако, топикстартовую проблему я так всё равно и не решил. При наличии 5-10Гб свободной памяти MySQL всё равно занимает в RSS по 13-15Гб максимум. И при работе по всей базе тормозит на дисковых операциях, при загрузке базы с диска.

KRoN73 ★★★★★
() автор топика
Ответ на: комментарий от KRoN73

Рано начал радоваться. За 20 минут работы всё замеательно, RSS вырос до 6.5Гб, всё летало... И, вдруг, ВЖУХ, RSS занят на 3Гб, LA подскочил с кошерных 3 до 22, всё начало тормозить, а сейчас снова начинает приходить в норму o_O

Какого чёрта MySQL высвобождает RSS при 20+ Гб свободной памяти?

KRoN73 ★★★★★
() автор топика
Ответ на: комментарий от KRoN73

Ага, это сработал oom-killer. Только почему?

[Пн июл 10 12:33:23 2017] Out of memory: Kill process 6116 (mysqld) score 143 or sacrifice child
[Пн июл 10 12:33:23 2017] Killed process 6116 (mysqld) total-vm:25994852kB, anon-rss:6995204kB, file-rss:15716kB


Это при

KiB Mem : 32806336 total,  1672328 free,  9045356 used, 22088652 buff/cache
KiB Swap: 16768892 total, 16568452 free,   200440 used. 21163940 avail Mem 

KRoN73 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.