#mysql #mariadb #mariadb-10.4
#mysql #mariadb #mariadb-10.4
Вопрос:
У меня есть сервер с такими параметрами:
OS: Ubuntu 18.04.4 LTS x86_64
Kernel: 4.15.0-112-generic
CPU: Intel Xeon Silver 4214 (48 Cores) @ 2.201GHz
Memory: 96Gb
SSD SAMSUNG MZQLB960HAJR-00007 894.3Gb x 2
С установленным 5.5.5-10.4.12-MariaDB-1:10.4.12 maria~bionic
. У меня есть написанный на PHP проект с довольно большим количеством запросов к БД (~ 400-500 выборок в секунду ~ 200-300 обновлений в секунду). Проблема в том, что база данных работает довольно медленно при большой активности пользователей, но нормально в любое другое время. Мой my.cfg
файл находится ниже:
# this is read by the standalone daemon and embedded servers
[server]
# this is only for the mysqld standalone daemon
[mysqld]
#
# * Basic Settings
#
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
skip-name-resolve
max_connections = 1000000
bind-address = 0.0.0.0
#
# * Fine Tuning
#
key_buffer_size = 96M
max_allowed_packet = 16M
thread_stack = 192K
thread_cache_size = 32
# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
myisam-recover = BACKUP
lock_wait_timeout = 10
interactive_timeout = 10
wait_timeout = 3
#
# * Query Cache Configuration
#
query_cache_type = 0
query_cache_limit = 0
query_cache_size = 0
open-files-limit = 320000
thread_cache_size = 64
#
# * Logging and Replication
#
log_error = /var/log/mysql/error.log
expire_logs_days = 10
max_binlog_size = 100M
#
# * InnoDB
#
innodb_buffer_pool_size = 10000M
innodb_buffer_pool_instances = 128
max_heap_table_size = 1000M
tmp_table_size = 1000M
sort_buffer_size = 96M
innodb_sort_buffer_size = 96M
read_buffer_size = 96M
#
# * Character sets
#
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
# this is only for embedded server
[embedded]
[mariadb]
max_statement_time = 15
thread_handling = pool-of-threads
thread_pool_size = 48
Недавно я изменил thread_handling = pool-of-threads
и wait_timeout = 3
: это дало некоторый прирост производительности, но не решило проблему в целом. Я буду благодарен за любые идеи, как ускорить это или устранить некоторые «узкие места».
Обновить:
Используйте InnoDB, а не MyISAM
Это уже так.
Включите slowlog, чтобы найти самые медленные запросы.
Ну, все мои SELECTs вызывают только одну таблицу (~ 500 тыс. записей, без объединений и / или подзапросов), и большинство из них имеют ОГРАНИЧЕНИЕ 1, поэтому не такой большой объем данных.
Давайте посмотрим, как показать ТАБЛИЦУ СОЗДАНИЯ.
Хорошо, вот SHOW CREATE TABLE
для этой основной таблицы:
CREATE TABLE `orders` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`order_created_datetime` timestamp NULL DEFAULT current_timestamp(),
`order_updated_datetime` timestamp NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE current_timestamp(),
`order_last_perform_datetime` timestamp NULL DEFAULT '0000-00-00 00:00:00',
`order_category_id` tinyint(4) DEFAULT NULL,
`order_url` text CHARACTER SET utf8 DEFAULT NULL,
`order_social_shortcode` varchar(128) CHARACTER SET utf8 DEFAULT NULL,
`order_social_id` varchar(128) DEFAULT NULL,
`order_title` text DEFAULT NULL,
`order_preview_pic` text DEFAULT NULL,
`order_custom_data` text DEFAULT NULL,
`order_price_usd` decimal(13,6) DEFAULT 0.000000,
`order_daily_limit` int(11) DEFAULT 0,
`order_hourly_limit` int(11) DEFAULT 0,
`order_minute_limit` int(11) DEFAULT 0,
`order_overall_limit` int(11) DEFAULT 0,
`order_initial_social_counter` int(11) DEFAULT 0,
`order_daily_counter` int(11) DEFAULT 0,
`order_hourly_counter` int(11) DEFAULT 0,
`order_minute_counter` int(11) DEFAULT 0,
`order_overall_counter` int(11) DEFAULT 0,
`order_allowed_countries` text CHARACTER SET utf8 DEFAULT NULL,
`order_forbidden_countries` text CHARACTER SET utf8 DEFAULT NULL,
`order_api` tinyint(4) DEFAULT 0,
`order_reported` tinyint(4) DEFAULT 0,
`order_active` tinyint(4) DEFAULT 1,
`order_deleted` tinyint(4) DEFAULT 0,
`order_deleted_datetime` timestamp NULL DEFAULT '0000-00-00 00:00:00',
`order_deleted_user_id` int(11) DEFAULT NULL,
`users_log_actions` longtext CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
`users_log_hidden` longtext CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
KEY `index_user_id` (`user_id`) USING BTREE,
KEY `index_order_category_id` (`order_category_id`) USING BTREE,
KEY `index_order_deleted` (`order_deleted`) USING BTREE,
KEY `index_order_active` (`order_active`) USING BTREE,
KEY `index_order_social_id` (`order_social_id`) USING BTREE,
KEY `index_users_log_actions` (`users_log_actions`(1024)) USING BTREE,
KEY `index_users_log_hidden` (`users_log_hidden`(1024)) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=461811 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC
innodb_buffer_pool_size может быть слишком маленьким — Сколько у вас данных? Сколько оперативной памяти доступно для MariaDB?
Ну, MariaDB запускается на автономном сервере, без какого-либо другого программного обеспечения (PHP, Apache и т.д.). Итак, у меня есть 96 ГБ оперативной памяти на этом сервере, и все это может использоваться MariaDB.
innodb_buffer_pool_instances слишком велик; он должен быть — buffer_pool_size/1G
Не могли бы вы, пожалуйста, прояснить это? В моем случае это должно быть buffer_pool_size/ 96Gb, или? Я думаю, что buffer_pool_size
в моей конфигурации есть значение по умолчанию.
Какое значение будет, если innodb_flush_log_at_trx_commit?
Это 1
, но я пытался 2
без результата.
Комментарии:
1. Пожалуйста, опубликуйте свой медленный запрос и последние 400 строк вашего журнала МЕДЛЕННЫХ ЗАПРОСОВ, если таковые имеются.
2. Запрос дополнительной информации. С вашего хост-сервера MySQL. Опубликовать на pastebin.com и поделитесь ссылками. Из вашего корня для входа в систему SSH текстовые результаты: B) ПОКАЗЫВАЮТ ГЛОБАЛЬНЫЙ СТАТУС; после минимального времени безотказной работы 24 часа C) ПОКАЗЫВАЮТ ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ; D) ПОКАЗЫВАЮТ ПОЛНЫЙ СПИСОК ПРОЦЕССОВ; E) полный отчет MySQLTuner И дополнительную очень полезную информацию, если таковая имеется, включает — htop ИЛИ top для большинства активных приложений, ulimit -a для списка ограничений Linux / Unix, iostat -xm 5 3 для IOPS по устройствам и количеству ядер / cpu, для анализа настройки рабочей нагрузки сервера для предоставления предложений.
3. Пожалуйста, рассмотрите возможность публикации дополнительной информации, запрошенной 16 сентября в 20:26, для предложений по улучшению использования доступной оперативной памяти в my.cnf.
Ответ №1:
Поскольку вы используете innodb, сначала необходимо настроить несколько параметров innodb.
innodb_buffer_pool_size слишком мал, поскольку у вас 96 ГБ оперативной памяти. Может дать по крайней мере 50% этим переменным и также уменьшить innodb_buffer_pool_instances.
Если вы можете позволить себе потерю данных на 1-2 секунды, тогда установите значение innodb_flush_log_at_trx_commit равным 2.
Установите max_allowed_packet равным 256 M
Уменьшите max_connections до 1000
Установите для tmp_table_size значение 256M
Установите для sql_binlog и innodb_doublewrite значение 0
ПРИМЕЧАНИЕ: ВЫБЕРИТЕ ( @@key_buffer_size @@query_cache_size @@innodb_buffer_pool_size @@innodb_log_buffer_size @@max_connections * ( @@read_buffer_size @@read_rnd_buffer_size @@sort_buffer_size @@join_buffer_size @@binlog_cache_size @@thread_stack @@tmp_table_size — таблица размеров )) / (1024 * 1024 * 1024) КАК MAX_MEMORY_GB; должно составлять менее 80% от общего объема оперативной памяти.
Комментарии:
1.Я изменил эти переменные, как вы предложили, и по какой-то причине этот запрос показывает 504 ГБ.
key_buffer_size=100663296
query_cache_size=0
innodb_buffer_pool_size=68719476736
innodb_log_buffer_size=16777216
max_connections=1000
read_buffer_size=100663296
read_rnd_buffer_size=262144
sort_buffer_size=100663296
join_buffer_size=262144
binlog_cache_size=32768
thread_stack=196608
tmp_table_size=268435456
2. Кстати, у меня нет никаких проблем с памятью, но процессоры почти всегда перегружены.
3. если у нас недостаточно памяти, запросы будут считываться с диска, а если диск работает плохо, то для ожидания ввода-вывода будет достаточно. Также рекомендуется фиксировать медленные запросы.
4. @VickyPopovic Пожалуйста, опубликуйте дополнительную информацию, запрошенную 16.9/2020 в 20:08.