【问题标题】:Why MySQL InnoDB log files creates such big HDD load?为什么 MySQL InnoDB 日志文件会产生如此大的 HDD 负载?
【发布时间】:2014-11-20 04:51:25
【问题描述】:

我致力于 MySQL InnoDB 日志文件 (ib_logfile0, ib_logfile0) HDD - sda。并且 atopsar 显示此硬盘的负载很大

atopsar -d 60:

13:02:10 disk busy read/s KB/read writ/s KB/writ avque avserv _dsk 13:03:10 sda 59% 4.4 4.0 45.3 6.2 1.0 11.88 毫秒 13:04:10 sda 60% 4.5 4.0 45.6 6.1 1.0 11.98 毫秒 13:05:10 sda 58% 4.2 4.0 44.7 6.0 1.0 11.94 毫秒

dstat -tdD total,sda 60:

----系统---- -dsk/total----dsk/sda-- 时间 |读令:读令 24-09 13:11:24| 23k 912k:9689B 391k 24-09 13:12:24| 33k 971k:16k 270k 24-09 13:13:24| 16k 893k:14k 235k 24-09 13:14:24| 18k 963k:16k 254k

pt-ioprofile -cell sizes:

总 pread read pwrite write fsync open close lseek fcntl 文件名 905728 0 0 905728 0 0 0 0 0 0 /var/mysqllog/mysql/ib_logfile0

每秒 200-400Kb 似乎并不多。特别考虑到硬盘上唯一的文件是 MySQL InnoDB 日志文件和(来自InnoDB blog)。:

重做日志文件以循环方式使用。这意味着重做日志从第一个重做日志文件的开头到结尾写入,然后继续写入下一个日志文件,依此类推,直到到达最后一个重做日志文件。写入最后一个重做日志文件后,将再次从第一个重做日志文件写入重做日志。

问题是为什么 MySQL InnoDB 日志文件会产生如此大的 HDD 负载?

分片:

文件碎片 /var/mysqllog/mysql/ib_logfile0 /var/mysqllog/mysql/ib_logfile0: 找到 14 个范围,完美为 -1 个范围 文件碎片 /var/mysqllog/mysql/ib_logfile1 /var/mysqllog/mysql/ib_logfile1:找到 17 个范围,完美为 -1 个范围

对于 1Gb 的文件来说似乎没有太多碎片,所以应该几乎是顺序写入。

我尝试使用其他硬盘(不同制造商,不同尺寸),负载情况相同。所以原因不应该在硬盘上。

是否有机会调整 mysql 以提高性能?

会不会是mysql在多个线程中写入InnoDB日志,因此HDD的磁头每次都必须改变位置?如果是,是否可以强制 mysqld 在 1 个线程中写入 InnoDB 日志文件,或者至少不同时写入?

须藤 /etc/init.d/mysql 状态 主题:23 问题:11860661 慢查询:1 打开:2426 冲洗表:1 打开表:835 每秒平均查询数:74.015

InnoDB 变量:

+---------------------------------+------------ ------------+
|变量名 |价值 |
+---------------------------------+---------------- ---------+
| innodb_adaptive_flushing |开 |
| innodb_adaptive_hash_index |开 |
| innodb_additional_mem_pool_size | 8388608 |
| innodb_autoextend_increment | 8 |
| innodb_autoinc_lock_mode | 1 |
| innodb_buffer_pool_instances | 1 |
| innodb_buffer_pool_size | 3221225472 |
| innodb_change_buffering |全部 |
| innodb_checksums |开 |
| innodb_commit_concurrency | 0 |
| innodb_concurrency_tickets | 500 |
| innodb_data_file_path | ibdata1:10M:自动扩展 |
| innodb_data_home_dir | |
| innodb_doublewrite |开 |
| innodb_fast_shutdown | 1 |
| innodb_file_format |羚羊 |
| innodb_file_format_check |开 |
| innodb_file_format_max |羚羊 |
| innodb_file_per_table |开 |
| innodb_flush_log_at_trx_commit | 1 |
| innodb_flush_method | |
| innodb_force_load_corrupted |关闭 |
| innodb_force_recovery | 0 |
| innodb_io_capacity | 200 |
| innodb_large_prefix |关闭 |
| innodb_lock_wait_timeout | 50 |
| innodb_locks_unsafe_for_binlog |关闭 |
| innodb_log_buffer_size | 33554432 |
| innodb_log_file_size | 1073741824 |
| innodb_log_files_in_group | 2 |
| innodb_log_group_home_dir | /var/mysqllog/mysql |
| innodb_max_dirty_pages_pct | 75 |
| innodb_max_purge_lag | 0 |
| innodb_mirrored_log_groups | 1 |
| innodb_old_blocks_pct | 37 |
| innodb_old_blocks_time | 0 |
| innodb_open_files | 300 |
| innodb_print_all_deadlocks |关闭 |
| innodb_purge_batch_size | 20 |
| innodb_purge_threads | 1 |
| innodb_random_read_ahead |关闭 |
| innodb_read_ahead_threshold | 56 |
| innodb_read_io_threads | 16 |
| innodb_replication_delay | 0 |
| innodb_rollback_on_timeout |关闭 |
| innodb_rollback_segments | 128 |
| innodb_spin_wait_delay | 6 |
| innodb_stats_method | nulls_equal |
| innodb_stats_on_metadata |开 |
| innodb_stats_sample_pages | 8 |
| innodb_strict_mode |关闭 |
| innodb_support_xa |开 |
| innodb_sync_spin_loops | 30 |
| innodb_table_locks |开 |
| innodb_thread_concurrency | 0 |
| innodb_thread_sleep_delay | 10000 |
| innodb_use_native_aio |开 |
| innodb_use_sys_malloc |开 |
| innodb_version | 5.5.38 |
| innodb_write_io_threads | 16 |
+---------------------------------+---------------- ---------+

InnoDB 状态:

+----------------------------------------+--------- -----+ |变量名 |价值 | +----------------------------------------+--------- -----+ | Innodb_buffer_pool_pages_data | 189538 | | Innodb_buffer_pool_bytes_data | 3105390592 | | Innodb_buffer_pool_pages_dirty | 0 | | Innodb_buffer_pool_bytes_dirty | 0 | | Innodb_buffer_pool_pages_flushed | 15444830 | | Innodb_buffer_pool_pages_free | 3 | | Innodb_buffer_pool_pages_misc | 7066 | | Innodb_buffer_pool_pages_total | 196607 | | Innodb_buffer_pool_read_ahead_rnd | 0 | | Innodb_buffer_pool_read_ahead | 44261 | | Innodb_buffer_pool_read_ahead_evicted | 2063 | | Innodb_buffer_pool_read_requests | 7430686238 | | Innodb_buffer_pool_reads | 144665 | | Innodb_buffer_pool_wait_free | 0 | | Innodb_buffer_pool_write_requests | 276646158 | | Innodb_data_fsyncs | 9659307 | | Innodb_data_pending_fsyncs | 0 | | Innodb_data_pending_reads | 0 | | Innodb_data_pending_writes | 0 | | Innodb_data_read | 3131691008 | | Innodb_data_reads | 191406 | | Innodb_data_writes | 23908920 | | Innodb_data_written | 523765341184 | | Innodb_dblwr_pages_written | 15444830 | | Innodb_dblwr_writes | 209711 | | Innodb_have_atomic_builtins |开 | | Innodb_log_waits | 0 | | Innodb_log_write_requests | 29583143 | | Innodb_log_writes | 8042225 | | Innodb_os_log_fsyncs | 8136493 | | Innodb_os_log_pending_fsyncs | 0 | | Innodb_os_log_pending_writes | 0 | | Innodb_os_log_written | 17633602560 | | Innodb_page_size | 16384 | | Innodb_pages_created | 144810 | | Innodb_pages_read | 191009 | | Innodb_pages_written | 15444830 | | Innodb_row_lock_current_waits | 0 | | Innodb_row_lock_time | 3857 | | Innodb_row_lock_time_avg | 0 | | Innodb_row_lock_time_max | 218 | | Innodb_row_lock_waits | 8922 | | Innodb_rows_deleted | 1964207 | | Innodb_rows_inserted | 7013442 | | Innodb_rows_read | 16861336570 | | Innodb_rows_updated | 17193829 | | Innodb_truncated_status_writes | 0 | +----------------------------------------+--------- -----+

【问题讨论】:

  • 带宽很低,但您从未测量过使用了多少 I/O。数据库就像在单个 I/O 中刷新大量数据一样。我从提供的数据中得出的结论是,您有很多未分组在较大事务中的写入。
  • atopsar 表示平均每秒大约有 45 次写入(每个 6Kb)和 4 次读取(每个 4Kb)。所以我考虑了 IO 的数量。但它是否是顺序写入?似乎不像我认为的 HDD 缓存能够优化所有即将到来的小顺序写入。
  • 知道这玩意的人在dba.stackexchange.com
  • 这里长镜头 - 您是否有机会对查询中的主键做任何事情?此外,磁盘(如果是机械的)非常慢,这意味着您有 45-50 个查询,每个查询占用 6KB。我们无法衡量这是否是您驱动器的容量,但我也会好好看看您正在运行的查询实际做了什么。正如 Ollie 所说,这可能更适合 DBA 站点,有些人对此有很多经验。

标签: mysql performance innodb database-performance hard-drive


【解决方案1】:

您正在使用 innodb_flush_log_at_trx_commit=1 这意味着每个事务都写入磁盘。在这种情况下,每次提交都会导致 fsync(除非您有电池支持的 raid 控制器)无论如何都会进入磁盘。它专门用于防止系统故障时数据丢失(HDD 缓存因断电而易失)。

您没有提到磁盘设置或文件系统。单个旋转磁盘不能超过 150-200 IOPS(高端服务器磁盘),而普通用户级 HDD 大约为 60-80 IOPS。所以 45 并没有完全关闭。 http://en.wikipedia.org/wiki/IOPS#Examples

你可以尝试不同的东西。

a) 设置一个raid,这将使您的 IOPS 容量成倍增加。条带化 RAID 设置最有帮助。

b) 如果您可以忍受可能丢失一秒钟的数据,那么您可以将 innodb_flush_log_at_trx_commit 更改为 2,这只会每秒刷新一次磁盘。写入性能显着提升。

c) 如果您可以将应用程序中的写入分组到单个事务中,这将导致更少的 fsync / 秒。

d) 您还可以通过获取 SSD 或一些电池备份缓存 RAID 卡来升级您的设置。但它们都是相当昂贵的解决方案。

【讨论】:

    【解决方案2】:

    innodb_log_buffer_size 也会在这里发挥作用。大型日志缓冲区允许大型事务运行,而无需在事务提交之前将日志写入磁盘。但是缓冲区的当前值似乎很好。不过,你可以玩玩看看。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-02
      • 1970-01-01
      • 2015-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多