InnoDB - высокая скорость записи на диск для файлов ibdata1 и ib_logfile0

8

Спецификация сервера: VPS со следующей информацией

model name  : Intel(R) Xeon(R) CPU           E5649  @ 2.53GHz
MemTotal:      2058776 kB
MemFree:        244436 kB

Мы используем IP.Board из Invision Power Services, мы используем innodb_file_per_tableи перезагрузили базу данных, чтобы уменьшить размер ibdata1. Однако в последнее время мы все еще сталкиваемся с проблемой высокой загрузки ЦП и В / В, несмотря на уменьшенный ibdata1размер.

Из моего осмотра я считаю, что это вызвано высоким использованием ввода-вывода ibdata1. Ниже приведены данные, полученные с помощью pt-ioprofile -cell sizes(в Percona ToolKit). По сути, это общая сумма ввода / вывода, собранная за период 30 секунд.

# pt-ioprofile -cell sizes
Fri Jul 20 10:22:23 ICT 2012
Tracing process ID 8581
     total      pread       read     pwrite      fsync       open      close   getdents      lseek      fcntl filename
   6995968          0          0    6995968          0          0          0          0          0          0 /db/mysql/ibdata1
   1019904          0          0    1019904          0          0          0          0          0          0 /db/mysql/ib_logfile0
    204800     204800          0          0          0          0          0          0          0          0 /db/mysql/admin_phpbb3forum/phpbb_posts.ibd
     49152      49152          0          0          0          0          0          0          0          0 /db/mysql/admin_ips/ips_reputation_cache.ibd
     32768      32768          0          0          0          0          0          0          0          0 /db/mysql/admin_ips/ips_reputation_totals.ibd
     29808          0          0          0          0          0          0      29808          0          0 /db/mysql/admin_ips/
... (other trivial I/O records truncated)

Бег iotopи я вижу, DISK WRITE:идет вверх и вниз 2M/sи200K/s

Мой вопрос, почему у нас есть запись с высоким I / O на ibdata1и в ib_logfileXто время как у нас есть только около 5-10 небольшого обновления в секунду в наши сессиях таблицы, которые также MEMORYтаблица (только около 300K в размерах)? Меня это озадачивает, потому что в любом другом табличном файле нет эквивалентного ввода-вывода записи, что указывает на то, что ввод-вывод записи не вызван UPDATE/INSERT/DELETE.

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

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

# ls -l /db/mysql/ib*
-rw-rw---- 1 mysql mysql  18874368 Jul 21 01:26 /db/mysql/ibdata1
-rw-rw---- 1 mysql mysql 134217728 Jul 21 01:26 /db/mysql/ib_logfile0
-rw-rw---- 1 mysql mysql 134217728 Jul 21 01:26 /db/mysql/ib_logfile1

а также

mysql> SHOW VARIABLES LIKE 'innodb%';
+-------------------------------------------+------------------------+
| Variable_name                             | Value                  |
+-------------------------------------------+------------------------+
| innodb_adaptive_flushing                  | ON                     |
| innodb_adaptive_flushing_method           | estimate               |
| innodb_adaptive_hash_index                | ON                     |
| innodb_adaptive_hash_index_partitions     | 1                      |
| innodb_additional_mem_pool_size           | 20971520               |
| innodb_autoextend_increment               | 8                      |
| innodb_autoinc_lock_mode                  | 1                      |
| innodb_blocking_buffer_pool_restore       | OFF                    |
| innodb_buffer_pool_instances              | 1                      |
| innodb_buffer_pool_restore_at_startup     | 0                      |
| innodb_buffer_pool_shm_checksum           | ON                     |
| innodb_buffer_pool_shm_key                | 0                      |
| innodb_buffer_pool_size                   | 402653184              |
| innodb_change_buffering                   | all                    |
| innodb_checkpoint_age_target              | 0                      |
| innodb_checksums                          | ON                     |
| innodb_commit_concurrency                 | 0                      |
| innodb_concurrency_tickets                | 500                    |
| innodb_corrupt_table_action               | assert                 |
| innodb_data_file_path                     | ibdata1:10M:autoextend |
| innodb_data_home_dir                      |                        |
| innodb_dict_size_limit                    | 0                      |
| innodb_doublewrite                        | ON                     |
| innodb_doublewrite_file                   |                        |
| innodb_fake_changes                       | OFF                    |
| innodb_fast_checksum                      | OFF                    |
| innodb_fast_shutdown                      | 1                      |
| innodb_file_format                        | Barracuda              |
| innodb_file_format_check                  | ON                     |
| innodb_file_format_max                    | Barracuda              |
| innodb_file_per_table                     | ON                     |
| innodb_flush_log_at_trx_commit            | 2                      |
| innodb_flush_method                       | O_DIRECT               |
| innodb_flush_neighbor_pages               | 0                      |
| innodb_force_load_corrupted               | OFF                    |
| innodb_force_recovery                     | 0                      |
| innodb_ibuf_accel_rate                    | 100                    |
| innodb_ibuf_active_contract               | 1                      |
| innodb_ibuf_max_size                      | 201310208              |
| innodb_import_table_from_xtrabackup       | 0                      |
| innodb_io_capacity                        | 4000                   |
| innodb_kill_idle_transaction              | 0                      |
| innodb_large_prefix                       | OFF                    |
| innodb_lazy_drop_table                    | 0                      |
| innodb_lock_wait_timeout                  | 50                     |
| innodb_locks_unsafe_for_binlog            | OFF                    |
| innodb_log_block_size                     | 4096                   |
| innodb_log_buffer_size                    | 4194304                |
| innodb_log_file_size                      | 134217728              |
| innodb_log_files_in_group                 | 2                      |
| innodb_log_group_home_dir                 | ./                     |
| 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_page_size                          | 16384                  |
| innodb_purge_batch_size                   | 20                     |
| innodb_purge_threads                      | 1                      |
| innodb_random_read_ahead                  | OFF                    |
| innodb_read_ahead                         | linear                 |
| innodb_read_ahead_threshold               | 56                     |
| innodb_read_io_threads                    | 24                     |
| innodb_recovery_stats                     | OFF                    |
| innodb_recovery_update_relay_log          | OFF                    |
| innodb_replication_delay                  | 0                      |
| innodb_rollback_on_timeout                | OFF                    |
| innodb_rollback_segments                  | 128                    |
| innodb_show_locks_held                    | 10                     |
| innodb_show_verbose_locks                 | 0                      |
| innodb_spin_wait_delay                    | 6                      |
| innodb_stats_auto_update                  | 0                      |
| innodb_stats_method                       | nulls_equal            |
| innodb_stats_on_metadata                  | OFF                    |
| innodb_stats_sample_pages                 | 8                      |
| innodb_stats_update_need_lock             | 1                      |
| innodb_strict_mode                        | OFF                    |
| innodb_support_xa                         | ON                     |
| innodb_sync_spin_loops                    | 30                     |
| innodb_table_locks                        | ON                     |
| innodb_thread_concurrency                 | 0                      |
| innodb_thread_concurrency_timer_based     | OFF                    |
| innodb_thread_sleep_delay                 | 10000                  |
| innodb_use_global_flush_log_at_trx_commit | ON                     |
| innodb_use_native_aio                     | ON                     |
| innodb_use_sys_malloc                     | ON                     |
| innodb_use_sys_stats_table                | OFF                    |
| innodb_version                            | 1.1.8-rel27.1          |
| innodb_write_io_threads                   | 24                     |
+-------------------------------------------+------------------------+
90 rows in set (0.00 sec)

От @RolandoMySQLDBA: Пожалуйста, запустите это

SET @TimeInterval = 300;
SELECT variable_value INTO @num1 FROM information_schema.global_status
WHERE variable_name = 'Innodb_os_log_written';
SELECT SLEEP(@TimeInterval);
SELECT variable_value INTO @num2 FROM information_schema.global_status
WHERE variable_name = 'Innodb_os_log_written';
SET @ByteWrittenToLog = @num2 - @num1;
SET @KB_WL = @ByteWrittenToLog / POWER(1024,1) * 3600 / @TimeInterval;
SET @MB_WL = @ByteWrittenToLog / POWER(1024,2) * 3600 / @TimeInterval;
SET @GB_WL = @ByteWrittenToLog / POWER(1024,3) * 3600 / @TimeInterval;
SELECT @KB_WL,@MB_WL,@GB_WL;

и показать вывод. Это скажет вам, сколько байтов в час записывается в ib_logfile0 / ib_logfile1 на основе следующих 5 минут.

Результат запроса выше SQL (в 8 утра по местному времени, когда члены онлайн составляют около 25% от статистики в течение дня):

mysql> SELECT @KB_WL,@MB_WL,@GB_WL;
+--------+----------+-------------------+
| @KB_WL | @MB_WL   | @GB_WL            |
+--------+----------+-------------------+
|  95328 | 93.09375 | 0.090911865234375 |
+--------+----------+-------------------+
1 row in set (0.00 sec)
ТИА
источник
Пожалуйста, запустите следующее, ls -l /var/lib/mysql/ib*я хочу увидеть размеры файлов. Мне также нужно знать, какую версию MySQL вы используете и есть ли у вас все данные InnoDB.
RolandoMySQLDBA
Пожалуйста, запустите это: SHOW VARIABLES LIKE 'innodb%';и отобразите это в своем вопросе !!!
RolandoMySQLDBA
@RolandoMySQLDBA Спасибо за ваш интерес. Теперь вопрос дополнен размерами файлов и переменными innodb.
TIA
Сколько оперативной памяти на сервере БД ???
RolandoMySQLDBA
@RolandoMySQLDBA Он получил 2 ГБ. Я обновил вопрос соответственно.
TIA

Ответы:

7

Вот несколько вещей, которые вы можете изменить

  • innodb_log_buffer_size : у вас есть 4M. По умолчанию это 8M. Попробуйте поднять его до 8М.
  • innodb_log_file_size : у вас 128M. Учитывая следующую информацию, которую вы предоставили
    • вы записываете средние 93 МБ в час в файлы журнала innodb, основываясь на 25% статистики
    • Пиковое время будет около 372 МБ в час
    • половина составляет 186 МБ, округляется до 192 МБ
    • установите innodb_log_file_size в 192M
  • innodb_io_capacity кажется немного большим, сделайте его 200 или 300 (в зависимости от оборудования)
  • innodb_read_io_threads и innodb_write_io_threads должны быть максимально увеличены до 64. Иногда чем меньше, тем лучше в среде с интенсивной записью. Используйте 8 или 16 в таких случаях.

Чтобы изменить innodb_log_file_size на 192M, добавьте это в /etc/my.cnf

[mysqld]
innodb_log_buffer_size=8M
innodb_log_file_size=192M
innodb_open_files=300
innodb_read_io_threads=64
innodb_write_io_threads=64

затем сделайте следующее

mysql -u... -p... -e"FLUSH TABLES;"
service mysql stop
mv /var/lib/mysql/ib_logfile0 /var/lib/mysql/ib_logfile0000
mv /var/lib/mysql/ib_logfile1 /var/lib/mysql/ib_logfile0001
service mysql start

Проверьте это в медленное время и посмотрите, улучшится ли это

ОБНОВЛЕНИЕ 2012-10-19 12:31 ПО ВОСТОЧНОМУ ВРЕМЕНИ

Чтобы представить ситуацию в перспективе, подумайте, каковы цели ibdata1 и ib_logfile0 / 1. Вместо того, чтобы переписывать все, прочтите мой последний пост о файлах журналов ibdata1 и InnoDB: что такое файлы iblog в mysql

После того, как вы прочитали мой другой пост, теперь подумайте: что может увеличить количество операций ввода-вывода для этих файлов?

  • Обновление вторичных индексов в буфере вставки ibdata1
  • Очистка сегментов отката / Отменить пробел

ИМХО я бы увеличил буферный пул InnoDB с 384М до 1G.

Я также рекомендовал бы обновить оперативную память до 8G

RolandoMySQLDBA
источник