MySQL е обширен и има много области за оптимизиране и настройка за желаната производителност. Някои промени могат да се извършват динамично, други изискват рестартиране на сървъра. Доста обичайно е да намерите инсталация на MySQL с конфигурация по подразбиране, въпреки че последната може да не е подходяща сама по себе си от вашето работно натоварване и настройка.
Ето ключовите области в MySQL, които взех от различни експертни източници в света на MySQL, както и нашия собствен опит тук в Severalnines. Този блог ще послужи като вашата измама, за да настроите производителността и да направите MySQL отново страхотен :-)
Нека да ги разгледаме, като очертаем ключовите области в MySQL.
Системни променливи
MySQL има много променливи, които можете да помислите за промяна. Някои променливи са динамични, което означава, че могат да бъдат зададени с помощта на оператора SET. Други изискват рестартиране на сървъра, след като са зададени в конфигурационния файл (напр. /etc/my.cnf и т.н./mysql/my.cnf). Въпреки това ще разгледам често срещаните неща, които са доста често срещани за настройка, за да направя сървъра оптимизиран.
sort_buffer_size
Тази променлива контролира колко голям е вашият буфер за сортиране на файлове, което означава, че всеки път, когато заявка трябва да сортира редовете, стойността на тази променлива се използва за ограничаване на размера, който трябва да бъде разпределен. Обърнете внимание, че тази променлива е на база на заявка, която се обработва (или на връзка), което означава, че ще бъде гладна за памет, когато зададете това по-високо и ако имате множество връзки, което изисква сортиране на вашите редове. Можете обаче да наблюдавате нуждите си, като проверите глобалната променлива на състоянието Sort_merge_passes. Ако тази стойност е голяма, трябва да помислите за увеличаване на стойността на системната променлива sort_buffer_size. В противен случай го вземете до умерената граница, от която се нуждаете. Ако зададете това твърде ниско или ако имате големи заявки за обработка, ефектът от сортирането на вашите редове може да бъде по-бавен от очакваното, тъй като данните се извличат на случаен принцип при гмуркания на диска. Това може да доведе до влошаване на производителността. Въпреки това, най-добре е да коригирате вашите запитвания. В противен случай, ако приложението ви е проектирано да изтегля големи заявки и изисква сортиране, тогава е ефективно да използвате инструменти, които обработват кеширането на заявки като Redis. По подразбиране в MySQL 8.0 текущата зададена стойност е 256 KiB. Задайте това съответно само когато имате заявки, които силно използват или извикват сортиране.
размер_на_буфера за четене
Документацията на MySQL споменава, че за всяка заявка, която извършва последователно сканиране на таблица, тя разпределя буфер за четене. Системната променлива read_buffer_size определя размера на буфера. Също така е полезно за MyISAM, но тази променлива засяга и всички системи за съхранение. За таблици MEMORY се използва за определяне на размера на блок памет.
По принцип всяка нишка, която извършва последователно сканиране за MyISAM таблица, заделя буфер с този размер (в байтове) за всяка таблица, която сканира. Прилага се и за всички машини за съхранение (което включва InnoDB), така че е полезно за заявки, които сортират редове с помощта на ORDER BY и кешират неговите индекси във временен файл. Ако правите много последователни сканирания, групово вмъкване в таблици на дялове, кеширане на резултати от вложени заявки, тогава помислете за увеличаване на стойността му. Стойността на тази променлива трябва да бъде кратна на 4KB. Ако е зададена на стойност, която не е кратна на 4KB, стойността му ще бъде закръглена надолу до най-близкото кратно на 4KB. Имайте предвид, че задаване на това на по-висока стойност ще консумира голяма част от паметта на вашия сървър. Предлагам да не използвате това без подходящ сравнителен анализ и наблюдение на вашата среда.
read_rnd_buffer_size
Тази променлива се занимава с четене на редове от MyISAM таблица в сортиран ред след операция за сортиране по ключ, редовете се четат през този буфер, за да се избегне търсенето на диск. Документацията казва, че при четене на редове в произволна последователност или от таблица MyISAM в сортиран ред след операция за сортиране по ключ, редовете се четат през този буфер (и се определят чрез този размер на буфера), за да се избегне търсенето на диск. Задаването на променливата на голяма стойност може да подобри производителността на ORDER BY доста. Това обаче е буфер, разпределен за всеки клиент, така че не трябва да задавате глобалната променлива на голяма стойност. Вместо това променете променливата на сесията само от тези клиенти, които трябва да изпълняват големи заявки. Трябва обаче да имате предвид, че това не се отнася за MariaDB, особено когато се възползвате от MRR. MariaDB използва mrr_buffer_size, докато MySQL използва read_buffer_size read_rnd_buffer_size.
размер_на_буфера за присъединяване
По подразбиране стойността е 256K. Минималният размер на буфера, който се използва за сканиране на обикновени индекси, сканиране на индекс на диапазон и обединения, които не използват индекси и по този начин извършват пълно сканиране на таблицата. Използва се и от BKA оптимизацията (която е деактивирана по подразбиране). Увеличете стойността му, за да получите по-бързи пълни присъединявания, когато добавянето на индекси не е възможно. Предупреждение обаче може да има проблеми с паметта, ако зададете това твърде високо. Не забравяйте, че един буфер за свързване се разпределя за всяко пълно свързване между две таблици. За сложно свързване между няколко таблици, за които не се използват индекси, може да са необходими множество буфери за свързване. Най-добре е да се остави ниско глобално и да се зададе високо в сесиите (чрез използване на синтаксис SET SESSION), които изискват големи пълни присъединявания. При 64-битови платформи Windows съкращава стойности над 4GB до 4GB-1 с предупреждение.
max_heap_table_size
Това е максималният размер в байтове за създадените от потребителя таблици MEMORY, които могат да нарастват. Това е полезно, когато приложението ви се занимава с таблици на механизма за съхранение на ПАМЕТ. Задаването на променливата, докато сървърът е активен, няма ефект върху съществуващите таблици, освен ако не са пресъздадени или променени. По-малката от max_heap_table_size и tmp_table_size също ограничава вътрешните таблици в паметта. Тази променлива също е във връзка с tmp_table_size, за да ограничи размера на вътрешните таблици в паметта (това се различава от таблиците, създадени изрично като Engine=MEMORY, тъй като прилага само max_heap_table_size), което от двете е по-малко се прилага между двете.
tmp_table_size
Най-големият размер за временни таблици в паметта (не таблици MEMORY), въпреки че ако max_heap_table_size е по-малък, ще се приложи долната граница. Ако временна таблица в паметта надхвърли ограничението, MySQL автоматично я преобразува във временна таблица на диска. Увеличете стойността на tmp_table_size (и max_heap_table_size, ако е необходимо), ако изпълнявате много разширени заявки GROUP BY и имате голямо налично пространство в паметта. Можете да сравните броя на създадените вътрешни временни таблици на диска с общия брой създадени вътрешни временни таблици, като сравните стойностите на променливите Created_tmp_disk_tables и Created_tmp_tables. В ClusterControl можете да наблюдавате това чрез Dashboard -> Temporary Objects graph.
отворен_кеш_на_таблица
Можете да увеличите стойността на тази променлива, ако имате голям брой таблици, които са често достъпни във вашия набор от данни. Ще се прилага за всички нишки, което означава за основа на свързване. Стойността показва максималния брой таблици, които сървърът може да държи отворени във всеки един кеш екземпляр. Въпреки че увеличаването на тази стойност увеличава броя на файловите дескриптори, които mysqld изисква, така че можете също да помислите да проверите стойността на open_files_limit или да проверите колко голямо е ограничението SOFT и HARD, зададено във вашата *nix операционна система. Можете да наблюдавате това дали трябва да увеличите кеша на таблицата, като проверите променливата за състояние Opened_tables. Ако стойността на Opened_tables е голяма и не използвате FLUSH TABLES често (което просто принуждава всички таблици да бъдат затворени и отворени отново), тогава трябва да увеличите стойността на променливата table_open_cache. Ако имате малка стойност за table_open_cache и голям брой таблици са често достъпни, това може да повлияе на производителността на вашия сървър. Ако забележите много записи в списъка с процеси на MySQL със статус „Отваряне на таблици“ или „Затваряне на таблици“, тогава е време да коригирате стойността на тази променлива, но вземете под внимание предупреждението, споменато по-рано. В ClusterControl можете да проверите това под Табла за управление -> Състояние на отворения кеш на таблицата или Табла за управление -> Отворени таблици. Можете да го проверите тук за повече информация.
table_open_cache_instances
Задаването на тази променлива би помогнало за подобряване на мащабируемостта и, разбира се, на производителността, което би намалило споровете между сесиите. Стойността, която задавате тук, ограничава броя на екземплярите на отворените таблици. Кешът на отворените таблици може да бъде разделен на няколко по-малки кеш екземпляра с размер table_open_cache/table_open_cache_instances. Една сесия трябва да заключи само един екземпляр, за да има достъп до него за DML изрази. Това сегментира достъпа до кеша между екземпляри, позволявайки по-висока производителност за операции, които използват кеша, когато има много сесии с достъп до таблици. (DDL изразите все още изискват заключване на целия кеш, но такива изрази са много по-рядко от DML изразите.) Стойност от 8 или 16 се препоръчва за системи, които рутинно използват 16 или повече ядра.
кеш_на_дефиниция на таблица
Дефинициите на кеш таблици, т.е. това е мястото, където CREATE TABLE се кешират, за да се ускори отварянето на таблици и само един запис на таблица. Би било разумно да увеличите стойността, ако имате голям брой таблици. Кешът на дефинициите на таблицата заема по-малко място и не използва файлови дескриптори, за разлика от нормалния кеш на таблицата. Петър Зайцев от Percona предлага, ако можете да опитате настройката на формулата по-долу,
The number of user-defined tables + 10% unless 50K+ tables
Но имайте предвид, че стойността по подразбиране се основава на следната формула, ограничена до лимит от 2000.
MIN(400 + table_open_cache / 2, 2000)
Така че, в случай че имате по-голям брой таблици в сравнение с по подразбиране, тогава е разумно да увеличите стойността му. Имайте предвид, че с InnoDB тази променлива се използва като мека граница на броя на екземплярите на отворена таблица за кеша на речника на данните. Той ще приложи механизма LRU, след като надвиши текущата стойност на тази променлива. Ограничението помага за справяне със ситуации, при които значителни количества памет биха били използвани за кеширане на рядко използвани екземпляри на таблица до следващото рестартиране на сървъра. Следователно, екземпляри на родителска и дъщерна таблица с връзки с външни ключове не се поставят в списъка с LRU и могат да наложат по-висока от границата, дефинирана от table_definition_cache, и не подлежат на изгонване в паметта по време на LRU. Освен това table_definition_cache дефинира меко ограничение за броя на пространствата за таблици InnoDB файл на таблица, които могат да бъдат отворени наведнъж, което също се контролира от innodb_open_files и всъщност се използва най-високата настройка между тези променливи, ако и двете са зададени . Ако нито една променлива не е зададена, се използва table_definition_cache, която има по-висока стойност по подразбиране. Ако броят на манипулаторите на файловете на отвореното пространство на таблици надвишава ограничението, дефинирано от table_definition_cache или innodb_open_files, LRU механизмът търси в списъка LRU файла на пространството за таблици за файлове, които са напълно изчистени и в момента не се разширяват. Този процес се извършва всеки път, когато се отвори ново пространство за таблици. Ако няма „неактивни“ пространства за таблици, няма затворени файлове. Така че имайте предвид това.
max_allowed_packet
Това е максималният размер за връзка на върната SQL заявка или ред. За последно стойността е увеличена в MySQL 5.6. Въпреки това в MySQL 8.0 (поне на 8.0.3) текущата стойност по подразбиране е 64 MiB. Може да помислите да коригирате това, ако имате големи BLOB редове, които трябва да бъдат изтеглени (или прочетени), в противен случай можете да оставите тези настройки по подразбиране с 8.0, но в по-старите версии по подразбиране е 4 MiB, така че може да се погрижите за това, в случай че среща грешка ER_NET_PACKET_TOO_LARGE. Най-големият възможен пакет, който може да бъде предаден към или от MySQL 8.0 сървър или клиент, е 1 GB.
skip_name_resolve MySQL сървърът обработва входящите връзки чрез разделителна способност на името на хоста. По подразбиране MySQL не деактивира никакво разделяне на имена на хостове, което означава, че ще извършва DNS търсене и случайно, ако DNS е бавен, това може да е причина за ужасна производителност на вашата база данни. Помислете да включите това, ако не се нуждаете от DNS резолюция и се възползвайте от подобряването на вашата MySQL производителност, когато това търсене на DNS е деактивирано. Имайте предвид, че тази променлива не е динамична, следователно е необходимо рестартиране на сървъра, ако зададете това във вашия MySQL конфигурационен файл. Можете по желание да стартирате mysqld демон, като подадете опцията --skip-name-resolve, за да активирате това.max_connections
Това е броят на разрешените връзки за вашия MySQL сървър. Ако откриете грешката в MySQL „Твърде много връзки“, може да помислите да я зададете по-високо. По подразбиране стойността на 151 не е достатъчна, особено в производствена база данни и като се има предвид, че имате по-големи ресурси на сървъра (не губете ресурсите на сървъра си, особено ако това е специален MySQL сървър). Въпреки това, трябва да имате достатъчно файлови дескриптори, в противен случай ще ги изчерпите. В такъв случай помислете за коригиране на вашите SOFT и HARD лимита на вашите *nix операционни системи и задайте по-висока стойност на open_files_limit в MySQL (5000 е ограничението по подразбиране). Имайте предвид, че много често приложението не затваря връзките към базата данни правилно и задаване на високо max_connections може да доведе до неотговаряне или голямо натоварване на вашия сървър. Използването на пул за връзки на ниво приложение може да помогне за разрешаването на проблема тук.
thread_cache_size
Това е кеш за предотвратяване на прекомерно създаване на нишки. Когато клиентът прекъсне връзката, нишките на клиента се поставят в кеша, ако там има по-малко от thread_cache_size нишки. Заявките за нишки се удовлетворяват чрез повторно използване на нишки, взети от кеша, ако е възможно, и само когато кешът е празен, се създава нова нишка. Тази променлива може да бъде увеличена, за да се подобри производителността, ако имате много нови връзки. Обикновено това не осигурява значително подобрение на производителността, ако имате добра реализация на нишката. Въпреки това, ако вашият сървър вижда стотици връзки в секунда, обикновено трябва да зададете thread_cache_size достатъчно високо, така че повечето нови връзки да използват кеширани нишки. Като изследвате разликата между променливите на състоянието Connections и Threads_created, можете да видите колко ефективен е кешът на нишката. С помощта на формулата, посочена в документацията, 8 + (max_connections / 100) е достатъчно добро.
query_cache_size
За някои настройки тази променлива е най-големият им враг. За някои системи, които изпитват голямо натоварване и са заети с високи показания, тази променлива ще ви забие. Има сравнителни показатели, които бяха добре и тествани от например Percona. Тази променлива трябва да бъде настроена на 0 заедно с query_cache_type =0, за да я изключите. Добрата новина в MySQL 8.0 е, че екипът на MySQL спря да поддържа това, тъй като тази променлива наистина може да причини проблеми с производителността. Трябва да се съглася с техния блог, че е малко вероятно да подобри предвидимостта на представянето. Ако сте ангажирани да използвате кеширане на заявки, предлагам да използвате Redis или ProxySQL.
Storage Engine - InnoDB
InnoDB е ACID-съвместим двигател за съхранение с различни функции, които да предлага заедно с поддръжка на чужд ключ (Декларативна референтна цялост). Тук има много неща за казване, но някои променливи, които трябва да имате предвид за настройка:
innodb_buffer_pool_size
Тази променлива действа като ключов буфер на MyISAM, но има много неща за предлагане. Тъй като InnoDB разчита в голяма степен на буферния пул, бихте помислили да зададете тази стойност обикновено на 70% -80% от паметта на вашия сървър. Благоприятно е също така да имате по-голямо пространство в паметта от вашия набор от данни и да зададете по-висока стойност за вашия буферен пул, но не твърде много. В ClusterControl това може да се наблюдава с помощта на нашите Табла за управление -> InnoDB Metrics -> InnoDB Buffer Pool Pages графика. Можете също да наблюдавате това с ПОКАЗВАНЕ НА ГЛОБАЛЕН СТАТУС, като използвате променливите Innodb_buffer_pool_pages*.
innodb_buffer_pool_instances
За вашето работно натоварване за едновременност, настройката на тази променлива може да подобри паралелността и да намали конкуренцията като различни нишки за четене/запис в кеширани страници. Минимумът innodb_buffer_pool_instances трябва да е между 1 (минимум) и 64 (максимум). Всяка страница, която се съхранява в или чете от буферния пул, се присвоява на един от екземплярите на буферния пул на случаен принцип, като се използва хешираща функция. Всеки буферен пул управлява свои собствени безплатни списъци, списъци за изтриване, LRU и всички други структури от данни, свързани към буферен пул, и е защитен от собствен мютекс на буферния пул. Обърнете внимание, че тази опция влиза в сила само когато innodb_buffer_pool_size>=1GiB и размерът му е разделен между екземплярите на буферния пул.
innodb_log_file_size
Тази променлива е регистрационният файл в лог група. Комбинираният размер на регистрационните файлове (innodb_log_file_size * innodb_log_files_in_group) не може да надвишава максимална стойност, която е малко по-малка от 512 GB. Според Вадим по-големият размер на регистрационния файл е по-добър за производителност, но има недостатък (съществен), за който трябва да се притеснявате:времето за възстановяване след срив. Трябва да балансирате времето за възстановяване в редкия случай на възстановяване при срив срещу максимизиране на пропускателната способност по време на пикови операции. Това ограничение може да доведе до 20 пъти по-дълъг процес на възстановяване при срив!
За да го уточним, по-голяма стойност би била добра за регистрационните файлове на транзакциите на InnoDB и е от решаващо значение за добрата и стабилна производителност на запис. Колкото по-голяма е стойността, толкова по-малко активност за прочистване на контролните точки се изисква в буферния пул, спестявайки дисков вход/изход. Въпреки това процесът на възстановяване е доста бавен, след като вашата база данни е била изключена необичайно (срив или убит, OOM или случайно). В идеалния случай можете да имате 1-2GiB в производство, но разбира се можете да коригирате това. Сравнителен анализ на тези промени може да бъде голямо предимство, за да видите как се представят, особено след срив.
innodb_log_buffer_size
За да запази дисков вход/изход, InnoDB записва данните за промяната в буфера на журнала на lt и използва стойността на innodb_log_buffer_size със стойност по подразбиране от 8MiB. Това е от полза особено за големи транзакции, тъй като не е необходимо да записва дневника с промените на диска преди извършване на транзакцията. Ако трафикът ви за запис е твърде висок (вмъква, изтрива, актуализира), увеличаването на буфера спестява вход/изход на диска.
innodb_flush_log_at_trx_commit
Когато innodb_flush_log_at_trx_commit е настроен на 1, буферът на журнала се изтрива при всяка транзакция, записвайки се в регистрационния файл на диска и осигурява максимална цялост на данните, но също така оказва влияние върху производителността. Задаването му на 2 означава, че буферът на журнала се измива в кеша на файловете на ОС при всяка транзакция. Значението на 2 е оптимално и подобрява производителността, ако можете да намалите изискванията си за ACID и можете да си позволите да загубите транзакции за последните секунди или две в случай на сривове на ОС.
innodb_thread_concurrency
С подобренията на двигателя InnoDB се препоръчва да се позволи на машината да контролира едновременността, като се запази стойността по подразбиране (която е нула). Ако видите проблеми с едновременността, можете да настроите тази променлива. Препоръчителната стойност е 2 пъти броя на процесорите плюс броя на дисковете. Това е динамична променлива означава, че може да се задава без рестартиране на MySQL сървъра.
innodb_flush_method
Тази променлива обаче трябва да бъде изпробвана и тествана на кой хардуер ви пасва най-добре. Ако използвате RAID с кеш памет, поддържана от батерия, DIRECT_IO помага за облекчаване на I/O налягането. Директният I/O не се кешира, така че избягва двойно буфериране с буферен пул и кеш на файловата система. Ако дискът ви се съхранява в SAN, O_DSYNC може да е по-бърз за натоварено с четене работно натоварване с предимно оператори SELECT.
innodb_file_per_table
innodb_file_per_table е ВКЛЮЧЕНО по подразбиране от MySQL 5.6. Това обикновено се препоръчва, тъй като се избягва наличието на огромно споделено пространство за таблици и тъй като ви позволява да възстановите място, когато пуснете или съкратите таблица. Отделното пространство за таблици също е от полза за схемата за частично архивиране на Xtrabackup.
innodb_stats_on_metadata
Това се опитва да държи процента мръсни страници под контрол, а преди плъгина Innodb това наистина беше единственият начин да се настрои прочистването на мръсния буфер. Виждал съм обаче сървъри с 3% мръсни буфери и те достигат максималната си възраст за контролни точки. Начинът, по който това увеличава прочистването на мръсния буфер, също не се мащабира добре при подсистеми с високо ниво на io, той ефективно просто удвоява замърсяването на мръсния буфер в секунда, когато % мръсни страници надвиши това количество.
innodb_io_capacity
Тази настройка, въпреки всичките ни големи надежди, че ще позволи на Innodb да използва по-добре нашия IO във всички операции, просто контролира количеството промиване на мръсни страници в секунда (и други фонови задачи като четене напред). Направете това по-голямо, промивате повече в секунда. Това не се адаптира, просто прави толкова много IOP всяка секунда, ако има мръсни буфери за промиване. Това ефективно ще елиминира всякаква оптимизация на консолидацията на IO, ако имате достатъчно ниско работно натоварване при писане (тоест, мръсните страници се изтриват почти веднага, може би е по-добре без регистър на транзакциите в този случай). Той също така може бързо да изтощи четенето и записването на данни в регистъра на транзакциите, ако зададете това твърде високо.
innodb_write_io_threads
Контролира колко нишки ще имат текущи записи на диска. Не съм сигурен защо това все още е полезно, ако можете да използвате роден AIO за Linux. Те също могат да бъдат направени безполезни от файлови системи, които не позволяват паралелно записване в един и същ файл от повече от една нишка (особено ако имате сравнително малко таблици и/или използвате глобалните пространства за таблици)
innodb_adaptive_flushing
Указва дали да се регулира динамично скоростта на промиване на мръсни страници в буферния пул на InnoDB въз основа на работното натоварване. Динамичното регулиране на скоростта на промиване има за цел да избегне изблици на I/O активност. Обикновено това е активирано по подразбиране. Тази променлива, когато е активирана, се опитва да бъде по-интелигентна за по-агресивно промиване въз основа на броя мръсни страници и скоростта на нарастване на регистрационния файл на транзакциите.
innodb_dedicated_server
Тази променлива е нова в MySQL 8.0, която се прилага глобално и изисква рестартиране на MySQL, тъй като не е динамична променлива. Въпреки това, тъй като в документацията се посочва, че тази променлива е желателно да бъде активирана само ако вашият MySQL работи на специален сървър. В противен случай не позволявайте това на споделен хост или споделяйте системни ресурси с други приложения. Когато това е активирано, InnoDB ще направи автоматична конфигурация за количеството памет, открито за променливи innodb_buffer_pool_size, innodb_log_file_size, innodb_flush_method. Недостатъкът е само, че не можете да приложите желаните стойности към споменатите открити променливи.
MyISAM
размер_на_буфера
InnoDB е машината за съхранение по подразбиране сега на MySQL, стойността по подразбиране за key_buffer_size вероятно може да бъде намалена, освен ако не използвате MyISAM продуктивно като част от вашето приложение (но кой използва MyISAM в производството сега?). Бих предложил тук да зададете може би 1% RAM или 256 MiB при стартиране, ако имате по-голяма памет и да отделите останалата памет за кеша на ОС и буферния пул на InnoDB.
Други разпоредби за изпълнение
slow_query_log
Разбира се, тази променлива не помага за повишаване на вашия MySQL сървър. Тази променлива обаче може да ви помогне да анализирате бавно изпълняващи се заявки. Стойността може да бъде зададена на 0 или OFF, за да деактивирате регистрирането. Задайте го на 1 или ON, за да активирате това. Стойността по подразбиране зависи от това дали е дадена опцията --slow_query_log. Дестинацията за изход на журнал се контролира от системната променлива log_output; ако тази стойност е NONE, не се записват записи в дневника, дори ако дневникът е активиран. Можете да зададете името на файла или дестинацията на регистрационния файл на заявката, като зададете променливата slow_query_log_file.
long_query_time
Ако една заявка отнема повече от тези секунди, сървърът увеличава променливата на състоянието Slow_queries. Ако регистрационният файл с бавни заявки е активиран, заявката се записва в регистрационния файл с бавни заявки. Тази стойност се измерва в реално време, а не в процесорно време, така че заявка, която е под прага на слабо натоварена система, може да бъде над прага на силно натоварена. Минималните и стойностите по подразбиране на long_query_time са съответно 0 и 10. Обърнете внимание също, че ако променливата min_examined_row_limit е зададена> 0, тя няма да регистрира заявки, дори ако отнема твърде много време, ако броят на върнатите редове е по-малък от стойността, зададена в min_examined_row_limit.
За повече информация относно настройката на бавното регистриране на заявки вижте документацията тук.
sync_binlog
Тази променлива контролира колко често MySQL ще синхронизира binlogs с диска. По подразбиране (>=5.7.7) това е зададено на 1, което означава, че ще се синхронизира с диска, преди транзакциите да бъдат ангажирани. Това обаче оказва отрицателно въздействие върху производителността поради увеличения брой записвания. Но това е най-безопасната настройка, ако искате стриктно съвместим с ACID заедно с вашите подчинени. Като алтернатива можете да зададете това на 0, ако искате да деактивирате синхронизирането на диска и просто да разчитате на ОС да изтрива двоичния дневник на диск от време на време. Задаването му на по-високо от 1 означава, че binlog се синхронизира с диск, след като са събрани N групи за записване на двоични регистрационни файлове, където N е> 1.
Изхвърляне/възстановяване на буферен пул
Доста често срещано е, че вашата производствена база данни трябва да се затопли от студен старт/рестартиране. Чрез изхвърляне на текущия буферен пул преди рестартиране, той ще запази съдържанието от буферния пул и след като се включи, ще зареди съдържанието обратно в буферния пул. По този начин се избягва необходимостта от загряване на вашата база данни обратно до кеша. Обърнете внимание, че тази версия беше въведена в 5.6, но Percona Server 5.5 вече я има, само в случай, че се чудите. За да активирате тази функция, задайте и двете променливи innodb_buffer_pool_dump_at_shutdown =ON и innodb_buffer_pool_load_at_startup =ON.
Хардуер
Сега сме през 2019 г., има много нови подобрения в хардуера. Обикновено няма твърдо изискване MySQL да изисква специфичен хардуер, но това зависи от това какво трябва да прави базата данни. Очаквам, че не четете този блог, защото правите тест дали работи на Intel Pentium 200 MHz.
За CPU по-бързите процесори с множество ядра ще бъдат оптимални за MySQL в най-новите версии поне от 5.6. Процесорите Xeon/Itanium на Intel могат да бъдат скъпи, но тествани за мащабируеми и надеждни изчислителни платформи. Amazon доставя своите EC2 екземпляри, работещи на ARM архитектура. Въпреки че аз лично не съм опитвал да стартирам или да си спомням да изпълнявам MySQL на ARM архитектура, има еталонни показатели, направени преди години. Съвременните процесори могат да мащабират своите честоти нагоре и надолу въз основа на температурата, натоварването и политиките за пестене на енергия на операционната система. Въпреки това, има вероятност настройките на вашия процесор във вашата Linux OS да са настроени на различен управител. Можете да проверите това или да зададете с „управител на производителност“, като направите следното:
echo performance | sudo tee /sys/devices/system/cpu/cpu[0-9]*/cpufreq/scaling_governor
За паметта е много важно паметта ви да е голяма и да може да изравни размера на вашия набор от данни. Уверете се, че имате swappiness =1. Можете да го проверите, като проверите sysctl или проверите файла в procfs. Това се постига, като се направи следното:
$ sysctl -e vm.swappiness
vm.swappiness = 1
Или да го зададете на стойност 1, както следва
$ sudo sysctl vm.swappiness=1
vm.swappiness = 1
Друго страхотно нещо, което трябва да имате предвид за управлението на паметта си, е да обмислите изключване на THP (Transparrent Huge Pages). В миналото си спомням, че сме срещали някои странни проблеми с използването на процесора и смятахме, че се дължи на дисков I/O. Оказа се, че проблемът е с нишката khugepaged на ядрото, която разпределя памет динамично по време на изпълнение. Не само това, по време на дефрагментиране на ядрото, паметта ви ще бъде бързо разпределена, докато я предава на THP. Стандартната памет на HugePages е предварително разпределена при стартиране и не се променя по време на изпълнение. Можете да потвърдите и деактивирате това, като направите следното:
$ cat /sys/kernel/mm/transparent_hugepage/enabled
$ echo "never" > /sys/kernel/mm/transparent_hugepage/enabled
За Disk е важно да имате добра пропускателна способност. Използването на RAID10 е най-добрата настройка за база данни с резервна батерия. С появата на флаш устройства, които предлагат висока пропускателна способност на диска и висок I/O диск за четене/запис, е важно то да може да управлява високото използване на диска и дисковия I/O.
Операционна система
Повечето производствени системи, работещи на MySQL, работят на Linux. Това е така, защото MySQL е тестван и бенчмаркиран на Linux и звучи, че това е де факто стандартът за инсталация на MySQL. Въпреки това, разбира се, нищо не ви пречи да го използвате на Unix или Windows платформа. Би било по-лесно, ако вашата платформа е тествана и има широка общност, която да ви помогне, в случай че срещнете проблеми. Повечето настройки работят на системи RHEL/Centos/Fedora и Debian/Ubuntu. В AWS Amazon има своя Amazon Linux, който според мен също се използва в производството от някои.
Най-важното, което трябва да вземете предвид при вашата настройка, е, че вашата файлова система използва или XFS, или Ext4. Със сигурност има плюсове и минуси между тези две файлови системи, но няма да навлизам в подробностите тук. Някои казват, че XFS превъзхожда Ext4, но има и съобщения, че Ext4 превъзхожда XFS. ZFS също излиза от картината като добър кандидат за алтернативна файлова система. Jervin Real (от Percona) има страхотен ресурс за това, можете да проверите тази презентация по време на конференцията на ZFS.
Външни връзки
https://developer.okta.com/blog/2015/05/22/tcmalloc
https://www.percona.com/blog/2012/07/05/impact-of-memory-allocators-on-mysql-performance/
https://www.percona.com/live/18/sessions/benchmark-noise-reduction-how-to-configure-your-machines-for-stable-results
https://zfs.datto.com/2018_slides/real.pdf
https://docs.oracle.com/en/database/oracle/oracle-database/12.2/ladbi/disabling-transparent-hugepages.html#GUID-02E9147D-D565-4AF8-B12A-8E6E9F74BEEA