我们有一个使用MySQL存储信息的XMPP应用程序。到目前为止,我们没有遇到任何特定的负载问题,但我正在努力为最坏的情况做好准备(或者就用户来说最好;)。
安装此MySQL服务器的主机是具有2GB RAM的Slicehost片。
昨天,我激活了慢查询日志记录,以确保我们实际上没有什么缓慢的。不幸的是,似乎实际上发现了很多慢查询:
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
我做了一个EXPLAIN:
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如此缓慢的任何想法?
[摘要]总结各种答案:
答案 0 :(得分:3)
看看平均值&amp;如果速度慢,那么VM主机就有问题(不幸的是,这不受你的控制)。
对于那些指出内存/磁盘I / O的人来说,这些数字太大了。磁盘应该在100毫秒内返回,而不是几秒钟。
答案 1 :(得分:1)
如果id是主键,为什么要添加LIMIT子句?
您是否尝试过指定所需的列名而不是使用*?
另外,你的Id列是int吗?通过指定“1”而不是1,您可能没有使用索引。
尝试
SELECT * FROM Feeds WHERE id = 1
而不是
SELECT * FROM Feeds WHERE id = '1'
修改评论
在我看来,最好明确指定列名,因为您可能需要在将来向您的应用添加不需要的列。此时,您开始提取的数据超出了所需数据。
答案 2 :(得分:1)
您的查询非常简单,并且鉴于id是主键,在正常情况下,即使在巨大的表上也不会花费那么长时间。这里只是一个猜测,但也许服务器是问题?根据我的理解(从查看他们的主页30秒),Slicehost为您提供了一个功能更强大的服务器的“切片”。可能是同一服务器上的其他片段偶尔会进行大量磁盘读取,暂时窃取所有资源?或者,当管理员为其他用户从机器创建/删除切片时,可能会发生这种情况。
这种情况经常发生吗?
答案 3 :(得分:1)
不幸的是,在过去的一年里,我已经获得了很多这方面的经验。
我同意其他人可能是CPU /磁盘延迟问题(由于虚拟主机)。是否有某种方法可以从主机获取磁盘延迟数?也许有尖峰。
我也同意在查询limit子句和引用索引时查询有点奇怪。 SELECT *位我完全可以理解。
我猜InnoDB没有足够的内存,但只有很少的行并且给InnoDB 1 gig,那不是它。
我猜这个查询错了。我以前见过MySQL做过这种事情。某些查询需要太长时间或导致其他查询开始堆叠。但是你看到的查询花费的时间太长,是一些简单的小事,不应该花很长时间。
我有几点建议:
有时候查看完整的流程列表,这可能是最有帮助的。
当我们去年遇到这种情况时,它正在观看最终发现真正问题的进程列表。
答案 4 :(得分:1)
我之前见过这个问题。
您的索引位于整数字段,而您的where子句键是字符串。您导致类型转换的事实会使您的索引失败。在where子句中取消引用您的密钥。
我非常惊讶mysql的行为方式,令人非常失望的是它无法检测到何时发生这种情况。
答案 5 :(得分:0)
如果表大于内存缓存中可以保存的表,那么可能是某些查询需要在某些不幸的时刻触摸光盘而其他东西对它们施加了很大的负担?
MySQL调优有时候是一种黑色艺术。高密钥缓冲区高速缓存争用也会导致显着的减速。
您也可以尝试在mysql performance blog中搜索线索和似是而非的理论。
答案 6 :(得分:0)
这可能是由于名称解析延迟造成的,具体取决于您的设置。您可以使用以下命令测试服务器的DNS查找速度:
nslookup www.domain.com
如果您的回复速度很慢,请尝试在/etc/my.cnf
文件中设置以下内容:
skip-name-resolve
# and/or:
skip-networking
最好绑定IP地址和端口号以消除对连接路径的疑虑:
bind-address=127.0.0.1
port=3306
否则我会查看表锁定并从那里进行故障排除。
答案 7 :(得分:-1)
如果您正在使用MyISAM,则可能会遇到并发问题。