MySQL запрос случайным образом принимает «навсегда» - PullRequest
4 голосов
/ 10 июня 2009

У нас есть приложение XMPP, которое использует MySQL для хранения информации. Пока что у нас нет особых проблем с нагрузкой, но я стараюсь быть готовым к худшему (или лучшему с точки зрения пользователей;)).

Хост, на котором установлен этот сервер MySQL, является слайсом Slicehost с 2 ГБ ОЗУ.

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

Reading mysql slow query log from /var/log/mysql/mysql-slow.log
Count: 109  Time=25.57s (2787s)  Lock=0.00s (0s)  Rows=1.0 (109), xxxxx[xxxxx]@[172.21.xxx.xxx]
  SELECT * FROM `feeds` WHERE (`id` = 'S') LIMIT N

Это действительно странно для меня, поскольку id на самом деле является первичным ключом ... Стол InnoDB

Я сделал ОБЪЯСНЕНИЕ:

mysql> EXPLAIN SELECT * FROM `feeds` WHERE (`id` = '2650') LIMIT 1;

 +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
 | id | select_type | table | type  | possible_keys | key     | key_len | ref   | rows | Extra |
 +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
 |  1 | SIMPLE      | feeds | const | PRIMARY       | PRIMARY | 4       | const |    1 |       |
 +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
 1 row in set (0.00 sec)

Должна быть еще одна причина, почему это происходит. И в нашем журнале действительно много подобных медленных запросов (запросов, использующих первичные ключи).

Я думаю, что имеет смысл опубликовать настройки MySQL здесь:

mysql> SHOW VARIABLES;
+---------------------------------+-----------------------------+
| Variable_name                   | Value                       |
+---------------------------------+-----------------------------+
| auto_increment_increment        | 1                           | 
| auto_increment_offset           | 1                           | 
| automatic_sp_privileges         | ON                          | 
| back_log                        | 50                          | 
| basedir                         | /usr/                       | 
| binlog_cache_size               | 32768                       | 
| bulk_insert_buffer_size         | 8388608                     | 
| character_set_client            | latin1                      | 
| character_set_connection        | latin1                      | 
| character_set_database          | latin1                      | 
| character_set_filesystem        | binary                      | 
| character_set_results           | latin1                      | 
| character_set_server            | latin1                      | 
| character_set_system            | utf8                        | 
| character_sets_dir              | /usr/share/mysql/charsets/  | 
| collation_connection            | latin1_swedish_ci           | 
| collation_database              | latin1_swedish_ci           | 
| collation_server                | latin1_swedish_ci           | 
| completion_type                 | 0                           | 
| concurrent_insert               | 1                           | 
| connect_timeout                 | 10                          | 
| datadir                         | /var/lib/mysql/             | 
| date_format                     | %Y-%m-%d                    | 
| datetime_format                 | %Y-%m-%d %H:%i:%s           | 
| default_week_format             | 0                           | 
| delay_key_write                 | ON                          | 
| delayed_insert_limit            | 100                         | 
| delayed_insert_timeout          | 300                         | 
| delayed_queue_size              | 1000                        | 
| div_precision_increment         | 4                           | 
| keep_files_on_create            | OFF                         | 
| engine_condition_pushdown       | OFF                         | 
| expire_logs_days                | 10                          | 
| flush                           | OFF                         | 
| flush_time                      | 0                           | 
| ft_boolean_syntax               | + -><()~*:""&|              | 
| ft_max_word_len                 | 84                          | 
| ft_min_word_len                 | 4                           | 
| ft_query_expansion_limit        | 20                          | 
| ft_stopword_file                | (built-in)                  | 
| group_concat_max_len            | 1024                        | 
| have_archive                    | YES                         | 
| have_bdb                        | NO                          | 
| have_blackhole_engine           | YES                         | 
| have_compress                   | YES                         | 
| have_crypt                      | YES                         | 
| have_csv                        | YES                         | 
| have_dynamic_loading            | YES                         | 
| have_example_engine             | NO                          | 
| have_federated_engine           | DISABLED                    | 
| have_geometry                   | YES                         | 
| have_innodb                     | YES                         | 
| have_isam                       | NO                          | 
| have_merge_engine               | YES                         | 
| have_ndbcluster                 | DISABLED                    | 
| have_openssl                    | DISABLED                    | 
| have_ssl                        | DISABLED                    | 
| have_query_cache                | YES                         | 
| have_raid                       | NO                          | 
| have_rtree_keys                 | YES                         | 
| have_symlink                    | YES                         | 
| hostname                        | SuperfeedrDatabase          | 
| init_connect                    |                             | 
| init_file                       |                             | 
| init_slave                      |                             | 
| innodb_additional_mem_pool_size | 1048576                     | 
| innodb_autoextend_increment     | 8                           | 
| innodb_buffer_pool_awe_mem_mb   | 0                           | 
| innodb_buffer_pool_size         | 1073741824                  | 
| innodb_checksums                | ON                          | 
| innodb_commit_concurrency       | 0                           | 
| innodb_concurrency_tickets      | 500                         | 
| innodb_data_file_path           | ibdata1:10M:autoextend      | 
| innodb_data_home_dir            |                             | 
| innodb_adaptive_hash_index      | ON                          | 
| innodb_doublewrite              | ON                          | 
| innodb_fast_shutdown            | 1                           | 
| innodb_file_io_threads          | 4                           | 
| innodb_file_per_table           | ON                          | 
| innodb_flush_log_at_trx_commit  | 2                           | 
| innodb_flush_method             | O_DIRECT                    | 
| innodb_force_recovery           | 0                           | 
| innodb_lock_wait_timeout        | 50                          | 
| innodb_locks_unsafe_for_binlog  | OFF                         | 
| innodb_log_arch_dir             |                             | 
| innodb_log_archive              | OFF                         | 
| innodb_log_buffer_size          | 4194304                     | 
| innodb_log_file_size            | 5242880                     | 
| innodb_log_files_in_group       | 2                           | 
| innodb_log_group_home_dir       | ./                          | 
| innodb_max_dirty_pages_pct      | 90                          | 
| innodb_max_purge_lag            | 0                           | 
| innodb_mirrored_log_groups      | 1                           | 
| innodb_open_files               | 300                         | 
| innodb_rollback_on_timeout      | OFF                         | 
| innodb_support_xa               | ON                          | 
| innodb_sync_spin_loops          | 20                          | 
| innodb_table_locks              | ON                          | 
| innodb_thread_concurrency       | 8                           | 
| innodb_thread_sleep_delay       | 10000                       | 
| interactive_timeout             | 28800                       | 
| join_buffer_size                | 131072                      | 
| key_buffer_size                 | 16777216                    | 
| key_cache_age_threshold         | 300                         | 
| key_cache_block_size            | 1024                        | 
| key_cache_division_limit        | 100                         | 
| language                        | /usr/share/mysql/english/   | 
| large_files_support             | ON                          | 
| large_page_size                 | 0                           | 
| large_pages                     | OFF                         | 
| lc_time_names                   | en_US                       | 
| license                         | GPL                         | 
| local_infile                    | ON                          | 
| locked_in_memory                | OFF                         | 
| log                             | OFF                         | 
| log_bin                         | OFF                         | 
| log_bin_trust_function_creators | OFF                         | 
| log_error                       |                             | 
| log_queries_not_using_indexes   | ON                          | 
| log_slave_updates               | OFF                         | 
| log_slow_queries                | ON                          | 
| log_warnings                    | 1                           | 
| long_query_time                 | 3                           | 
| low_priority_updates            | OFF                         | 
| lower_case_file_system          | OFF                         | 
| lower_case_table_names          | 0                           | 
| max_allowed_packet              | 16777216                    | 
| max_binlog_cache_size           | 18446744073709547520        | 
| max_binlog_size                 | 104857600                   | 
| max_connect_errors              | 10                          | 
| max_connections                 | 2000                        | 
| max_delayed_threads             | 20                          | 
| max_error_count                 | 64                          | 
| max_heap_table_size             | 16777216                    | 
| max_insert_delayed_threads      | 20                          | 
| max_join_size                   | 18446744073709551615        | 
| max_length_for_sort_data        | 1024                        | 
| max_prepared_stmt_count         | 16382                       | 
| max_relay_log_size              | 0                           | 
| max_seeks_for_key               | 18446744073709551615        | 
| max_sort_length                 | 1024                        | 
| max_sp_recursion_depth          | 0                           | 
| max_tmp_tables                  | 32                          | 
| max_user_connections            | 0                           | 
| max_write_lock_count            | 18446744073709551615        | 
| multi_range_count               | 256                         | 
| myisam_data_pointer_size        | 6                           | 
| myisam_max_sort_file_size       | 9223372036853727232         | 
| myisam_recover_options          | BACKUP                      | 
| myisam_repair_threads           | 1                           | 
| myisam_sort_buffer_size         | 8388608                     | 
| myisam_stats_method             | nulls_unequal               | 
| ndb_autoincrement_prefetch_sz   | 1                           | 
| ndb_force_send                  | ON                          | 
| ndb_use_exact_count             | ON                          | 
| ndb_use_transactions            | ON                          | 
| ndb_cache_check_time            | 0                           | 
| ndb_connectstring               |                             | 
| net_buffer_length               | 16384                       | 
| net_read_timeout                | 30                          | 
| net_retry_count                 | 10                          | 
| net_write_timeout               | 60                          | 
| new                             | OFF                         | 
| old_passwords                   | OFF                         | 
| open_files_limit                | 10000                       | 
| optimizer_prune_level           | 1                           | 
| optimizer_search_depth          | 62                          | 
| pid_file                        | /var/run/mysqld/mysqld.pid  | 
| plugin_dir                      |                             | 
| port                            | 3306                        | 
| preload_buffer_size             | 32768                       | 
| profiling                       | OFF                         | 
| profiling_history_size          | 15                          | 
| protocol_version                | 10                          | 
| query_alloc_block_size          | 8192                        | 
| query_cache_limit               | 1048576                     | 
| query_cache_min_res_unit        | 4096                        | 
| query_cache_size                | 16777216                    | 
| query_cache_type                | ON                          | 
| query_cache_wlock_invalidate    | OFF                         | 
| query_prealloc_size             | 8192                        | 
| range_alloc_block_size          | 4096                        | 
| read_buffer_size                | 131072                      | 
| read_only                       | OFF                         | 
| read_rnd_buffer_size            | 262144                      | 
| relay_log                       |                             | 
| relay_log_index                 |                             | 
| relay_log_info_file             | relay-log.info              | 
| relay_log_purge                 | ON                          | 
| relay_log_space_limit           | 0                           | 
| rpl_recovery_rank               | 0                           | 
| secure_auth                     | OFF                         | 
| secure_file_priv                |                             | 
| server_id                       | 0                           | 
| skip_external_locking           | ON                          | 
| skip_networking                 | OFF                         | 
| skip_show_database              | OFF                         | 
| slave_compressed_protocol       | OFF                         | 
| slave_load_tmpdir               | /tmp/                       | 
| slave_net_timeout               | 3600                        | 
| slave_skip_errors               | OFF                         | 
| slave_transaction_retries       | 10                          | 
| slow_launch_time                | 2                           | 
| socket                          | /var/run/mysqld/mysqld.sock | 
| sort_buffer_size                | 2097144                     | 
| sql_big_selects                 | ON                          | 
| sql_mode                        |                             | 
| sql_notes                       | ON                          | 
| sql_warnings                    | OFF                         | 
| ssl_ca                          |                             | 
| ssl_capath                      |                             | 
| ssl_cert                        |                             | 
| ssl_cipher                      |                             | 
| ssl_key                         |                             | 
| storage_engine                  | MyISAM                      | 
| sync_binlog                     | 0                           | 
| sync_frm                        | ON                          | 
| system_time_zone                | UTC                         | 
| table_cache                     | 64                          | 
| table_lock_wait_timeout         | 50                          | 
| table_type                      | MyISAM                      | 
| thread_cache_size               | 8                           | 
| thread_stack                    | 131072                      | 
| time_format                     | %H:%i:%s                    | 
| time_zone                       | SYSTEM                      | 
| timed_mutexes                   | OFF                         | 
| tmp_table_size                  | 33554432                    | 
| tmpdir                          | /tmp                        | 
| transaction_alloc_block_size    | 8192                        | 
| transaction_prealloc_size       | 4096                        | 
| tx_isolation                    | READ-COMMITTED              | 
| updatable_views_with_limit      | YES                         | 
| version                         | 5.0.67-0ubuntu6-log         | 
| version_comment                 | (Ubuntu)                    | 
| version_compile_machine         | x86_64                      | 
| version_compile_os              | debian-linux-gnu            | 
| wait_timeout                    | 28800                       | 
+---------------------------------+-----------------------------+
237 rows in set (0.00 sec)

Большинство наших запросов являются «базовыми», однако нам нужна огромная скорость!

Есть мысли о том, что может сделать MySQL таким медленным?

[ РЕЗЮМЕ ] Подводя итог различным ответам:

  • Удалить "LIMIT", изменить WHERE id = "X" в ГДЕ id = X
  • Убедитесь, что у меня нет скрипт (резервный или другой), который запускается из время от времени это будет потреблять много ресурсов
  • Убедитесь, что «хост» на самом деле не виновник.

Ответы [ 8 ]

3 голосов
/ 10 июня 2009

Если посмотреть на среднее значение и дисперсию замедлений, у вас возникла проблема с хост-машиной VM (к сожалению, она не находится под вашим контролем).

Для тех из вас, кто указывает на память / дисковый ввод / вывод, эти цифры слишком велики для этого. Диск должен вернуться через 100 мс, а не за несколько секунд.

1 голос
/ 10 июня 2009

Я видел эту проблему раньше.

Ваш индекс находится в поле integer , а ключом предложения where является строка . Ваш индекс побежден тем фактом, что вы вызываете преобразование типов. Не используйте кавычки в предложении where.

Я был очень удивлен, что mysql ведет себя таким образом, очень разочаровывает, что он не может обнаружить, когда это происходит.

1 голос
/ 10 июня 2009

К сожалению, за последний год я получил большой опыт в подобных вещах.

Я согласен с другими, это может быть проблема задержки процессора / диска (из-за виртуального хостинга). Есть ли какой-нибудь способ, которым вы можете получить номера задержки диска от хоста? Может быть, есть шипы.

Я также согласен с тем, что запрос немного странный, в определении предложения limit и цитировании индекса. Бит SELECT *, который я полностью понимаю.

Я бы предположил, что InnoDB не хватает памяти, но с таким небольшим количеством строк и предоставлением InnoDB 1 гига, это не так.

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

У меня есть несколько предложений для вас:

  • Существует ли какое-либо автоматическое резервное копирование, которое может блокировать таблицу?
  • Это происходит на каком-либо регулярном или предсказуемом интервале?
  • Вы когда-нибудь входили в систему и видели полный список процессов, когда это происходит?
  • Совпадает ли это с чем-то конкретным (каждый раз, когда люди запускают определенный отчет и т. Д.)?
  • Есть ли у вас очень большие таблицы, которые могут занимать всю вашу память, пока они работают над запросами, предотвращая вход этой таблицы (маловероятно)?
  • Это всегда было так? Это началось недавно? Изменилась ли версия MySQL? Можете ли вы попробовать другую сборку MySQL (более новая версия, сборка Percona Performance и т. Д.)?

Иногда бывает полезно просмотреть полный список процессов во время этого процесса.

Когда мы сталкивались с подобными вещами в прошлом году, именно просмотр списка процессов наконец выявил реальную проблему.

1 голос
/ 10 июня 2009

Ваш запрос очень прост, и, учитывая, что id является первичным ключом, это не значит, что это займет много времени даже для огромной таблицы в нормальных условиях. Просто предположение здесь, но, возможно, проблема с сервером? Насколько я понимаю (из 30 секунд просмотра их домашней страницы), Slicehost предлагает вам виртуальный компьютер «срез» более мощного сервера. Может ли быть так, что другие фрагменты на одном и том же сервере время от времени выполняют чтение с жесткого диска, временно крадя все ваши ресурсы? Или, может быть, это происходит, когда администраторы создают / удаляют фрагменты с компьютера для других пользователей.

Это случается очень часто?

1 голос
/ 10 июня 2009

Если id является первичным ключом, почему вы добавляете предложение LIMIT?

Вы пытались указать имена столбцов, которые хотите вместо использования *?

Кроме того, ваш столбец идентификатора int? Указав «1» вместо «1», вы, возможно, не используете индекс.

Попробуйте

SELECT * FROM Feeds WHERE id = 1

вместо

SELECT * FROM Feeds WHERE id = '1'

Редактировать для комментария

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

0 голосов
/ 21 июня 2017

Это может быть вызвано задержкой разрешения имен, в зависимости от настроек. Вы можете проверить скорость поиска DNS с сервера с помощью:

nslookup www.domain.com

Если вы получаете медленный ответ, попробуйте установить в файле /etc/my.cnf следующее:

skip-name-resolve
# and/or:
skip-networking

Также рекомендуется связать IP-адрес и номер порта, чтобы устранить сомнения относительно пути подключения:

bind-address=127.0.0.1
port=3306

В противном случае я бы посмотрел на блокировку таблицы и устранял бы оттуда проблемы.

0 голосов
/ 10 июня 2009

Если таблица больше, чем та, которую можно хранить в кэшах памяти, то может случиться так, что некоторые из этих запросов должны были коснуться диска в некоторые неудачные моменты, когда что-то еще оказывало на них большую нагрузку?

Настройка MySQL иногда является черным искусством. Высокая конкуренция в кеше и буфере ключей также может привести к заметному замедлению работы.

Вы также можете попробовать поискать в блоге производительности mysql , чтобы найти подсказки и вероятные теории.

0 голосов
/ 10 июня 2009

Если вы используете MyISAM, возможно, у вас проблемы с параллелизмом.

...