2017-01-20 2 views
4

У меня есть эта простая таблицаMysql плохой производительности

CREATE TABLE `user_did_something` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `something_id` int(11) NOT NULL, 
    `user_id` int(11) NOT NULL, 
    `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    `active` int(1) NOT NULL DEFAULT '1' 
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 

-- Indexes for table `user_did something` 
ALTER TABLE `user_did_something` 
    ADD PRIMARY KEY (`id`); 

и когда я пытаюсь вставить с

INSERT INTO user_did_something (something_id, user_id) VALUES (1,11) 

, время для выполнения составляет ~ 70ms.

Тестирование той же структуры на разных машинах, время выполнения ~ 3 мс.

Дополнительная информация:

  • версия 10.0.28-MariaDB-0ubuntu0.16.04

  • таблица не имеет ни одной строки

  • только индекс для столбца id, который является основным.

Я понятия не имею, как отладить это. Прочитайте некоторые вещи в Интернете, перезагрузите все, все тот же результат.

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

+0

Ваш 'CREATE TABLE' не говорит, что у вас есть' ПЕРВИЧНЫЙ КЛЮЧ (id) '; снова запустите 'SHOW CREATE TABLE'. –

+0

Какие еще вопросы могли касаться одной и той же таблицы одновременно? Был ли 70 мс сразу после перезапуска сервера, и в этом случае таблица еще не была открыта, а также другие вещи, которые еще не были кэшированы. –

+0

@RickJames Я редактировал вопрос. Сервер для тестирования, и ничто не касается таблицы во время выполнения запросов. Протестируйте его после 2 дней работы без перезагрузки, также протестировали его после перезапуска. Каждый раз, когда запрос занимает около 70-120 мс. В большинстве случаев это занимает около 70 мс. –

ответ

0

У меня была такая же проблема и решить эту проблему путем перезапуска MySQL. но, как вы сказали, вы пробовали это раньше. Я рекомендую:

Проверьте брандмауэр, если у вас на вашем Ubuntu.

Проверьте размер кэша и проверить, если он включен:

SHOW VARIABLES LIKE have_query_cache; 
SHOW VARIABLES LIKE query_cache_size; 

Проверьте, что процесс работает, и, возможно, замедляя:

SHOW PROCESSLIST; 

Проверьте, стоимость запроса вам больше по х $ statement_analysis:

SELECT * FROM sys.`x$statement_analysis` 

Проверьте глобальный статус. Вы можете найти полезную информацию там, как Threads_connected:

SHOW GLOBAL STATUS 
2

Я ищу рекомендации о том, как отлаживать такие вещи, как это без необходимости переустановки сервера MySQL на моей машине.

Я постараюсь ответить на эту часть вашего вопроса. Таким образом, вы хотите заглянуть под капот какого-то процесса и посмотреть, что он делает. Вы не хотите перекомпилировать его, переустановить или перезапустить, и вы не хотите ограничиваться трассировкой, поставляемой с готовым.

Это хорошая возможность использовать DTrace! Он позволяет вам смотреть, что делают ваши процессы (и muchmore).

DTrace доступен, по крайней мере, для Solaris, Mac OS X * и FreeBSD и I hear a port exists for Linux.В противном случае вы можете проследить аналогичную информацию с помощью другой утилиты (BPF tracing got merged into Linux 4.9-rc1 recently).

* Mac пользователи OS X потребуется explicitly permit DTrace to run, исключив его из защиты системы Integrity

Вы можете смотреть mysqld в режиме реального времени, как он входит и возвращается из функций:

dtrace -p $(pgrep -x mysqld) -F -n 'pid$target:mysqld::entry{} pid$target:mysqld::return{}' 

В качестве примера некоторого выхода ... InnoDB довольно чат, даже когда он работает:

2 -> sync_arr_wake_threads_if_sema_free  
6 -> os_event_reset       
2 -> os_mutex_enter      
6 <- os_event_reset       
2 <- os_mutex_enter      
6 -> pfs_mutex_exit_func     
6 <- pfs_mutex_exit_func     
2 -> os_mutex_exit      
6 -> os_event_reset       
2 <- os_mutex_exit      
6 <- os_event_reset       

Вы можете смотреть запросы, входящие в диспетчер MySQL!

dtrace -p $(pgrep -x mysqld) -F -n 'pid$target:mysqld:*dispatch_command*:entry{printf("Query: %s\n", copyinstr(arg2));}' 

Пример вывода:

CPU FUNCTION         
0 -> dispatch_command(enum_server_command, THD*, char*, unsigned int) Query: SHOW VARIABLES LIKE 'pid_file' 

Я считаю, что это также в пределах возможностей DTrace для прослушивания вызовов функций, которые происходят в то время как конкретный запрос выполняется. Например: вы можете сделать mysqld:*dispatch_command*:entry инициализировать поточно-локальную переменную, если запрос соответствует некоторым критериям, и сделать только pid$target:mysqld::entry|return, пока эта переменная определена. Соответствующий mysqld:*dispatch_command*:exit или аналогичный может затем определить эту переменную. Конечно, вы можете использовать глобальные переменные, если вы ожидаете, что работа будет происходить в отдельном потоке.

Извините, что не написал конкретный пример вышеизложенного; мой собственный MySQL закрыт, и моя книга DTrace находится в офисе.

Brendan Gregg, автор DTraceToolkit предоставляет множество типовых сценариев, которые могут быть полезны для мониторинга вашего заблудшего процесса, в том числе some one-liners для просмотра процесс наталкивается ли ошибки страницы, насколько велики его чтения и записи, что системные вызовы это делает и т. д. Но вы можете сделать гораздо лучше, чем однострочные, если вы более подробно узнаете DTrace.


Сценарии I, представленные здесь, основаны на те, что представлены в статье Бена ROCKWOOD в, Examining MySQL in real time using DTrace. Требуется бесплатная регистрация для чтения.

Я узнал об этом инструменте из статей Брендана Грегга и узнал больше о DTrace от Брендана DTrace book. Я очень рекомендую эту книгу, если вы хотите увидеть, как глубоко проходит кроличья дыра.

Смежные вопросы