InnoDB - I / O disk yang tinggi pada file ibdata1 dan ib_logfile0

8

Spesifikasi Server: VPS dengan info berikut

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

Kami menjalankan innodb_file_per_tableIP. Papan dari Invision Power Services, kami menggunakan dan telah memuat ulang database untuk mengurangi ukuran ibdata1. Namun, kami masih mendapat masalah CPU yang tinggi dan penggunaan I / O akhir-akhir ini meskipun ibdata1ukurannya berkurang .

Dari inspeksi saya, saya percaya itu disebabkan oleh penggunaan I / O yang tinggi ibdata1. Di bawah ini adalah data yang saya peroleh dengan menggunakan pt-ioprofile -cell sizes(di Percona ToolKit). Pada dasarnya, ini adalah jumlah total I / O yang dikumpulkan dalam periode 30 detik.

# 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)

Berlari iotopdan saya melihat DISK WRITE:naik dan turun di sekitar 2M/sdan200K/s

Pertanyaan saya adalah, mengapa kita memiliki tinggi I / O write pada ibdata1dan ib_logfileXsementara kita hanya memiliki sekitar 5-10 update kecil per detik ke dalam tabel sesi kami, yang juga MEMORYmeja (hanya sekitar 300K dalam ukuran)? Ini membingungkan saya karena juga tidak ada yang setara dengan penulisan I / O pada file tabel lainnya, yang menunjukkan bahwa penulisan I / O tidak disebabkan oleh UPDATE/INSERT/DELETE.

Perhatikan bahwa saya hanya seorang programmer yang kebetulan memiliki tugas untuk memelihara ini, jadi jangan ragu untuk meminta info lebih lanjut. Saya telah melakukan banyak hal pada server ini, tetapi tolong jangan berasumsi bahwa saya telah melakukan apa yang seharusnya sudah saya lakukan.

Informasi tambahan:

# 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

dan

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)

Dari @RolandoMySQLDBA: Silakan jalankan ini

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;

dan tunjukkan hasilnya. Ini akan memberi tahu Anda berapa banyak byte per jam ditulis ke ib_logfile0 / ib_logfile1 berdasarkan 5 menit berikutnya.

Di atas hasil kueri SQL (Pukul 8 pagi waktu setempat, sementara anggota daring sekitar 25% dari statistik pada siang hari):

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)
tia
sumber
Silakan jalankan yang berikut ini ls -l /var/lib/mysql/ib*Saya ingin melihat ukuran file. Saya juga perlu tahu versi MySQL apa yang Anda jalankan dan apakah semua data Anda adalah InnoDB.
RolandoMySQLDBA
Silakan jalankan ini: SHOW VARIABLES LIKE 'innodb%';dan tampilkan itu di pertanyaan Anda !!!
RolandoMySQLDBA
@RolandoMySQLDBA Terima kasih atas minat Anda. Pertanyaannya sekarang diperbarui dengan ukuran file dan variabel innodb.
tia
Berapa banyak RAM pada DB Server ???
RolandoMySQLDBA
@RolandoMySQLDBA Mendapat 2GB. Saya telah memperbarui pertanyaannya.
tia

Jawaban:

7

Berikut beberapa hal yang bisa Anda ubah

  • innodb_log_buffer_size : Anda memiliki 4 jt . Standarnya adalah 8M. Coba naikkan ke 8M.
  • innodb_log_file_size : Anda memiliki 128 juta . Diberikan info berikut yang Anda berikan
    • Anda menulis di rata-rata 93MB per jam ke file log innodb, berdasarkan 25% dari stat
    • waktu puncak adalah sekitar 372 MB per jam
    • setengahnya adalah 186 MB untuk 192MB
    • atur innodb_log_file_size ke 192M
  • innodb_io_capacity tampaknya sedikit tinggi, membuatnya 200 atau 300 (tergantung perangkat keras)
  • innodb_read_io_threads dan innodb_write_io_threads harus dimaksimalkan pada 64. Kadang-kadang, lebih sedikit lebih baik dalam lingkungan yang berat. Gunakan 8 atau 16 dalam kasus seperti itu.

Untuk mengubah innodb_log_file_size ke 192M, tambahkan ini ke /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

kemudian lakukan hal berikut

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

Uji ini selama masa-masa lambat dan lihat apakah ini meningkatkan keadaan

UPDATE 2012-10-19 12:31 EDT

Untuk menempatkan situasi Anda ke dalam perspektif, pikirkan tentang apa tujuan ibdata1 dan ib_logfile0 / 1. Daripada menulis ulang semuanya, baca posting terbaru saya tentang ibdata1 dan InnoDB Log Files: Apa sebenarnya file iblog di mysql

Setelah Anda membaca posting saya yang lain, sekarang pertimbangkan ini: Apa yang akan meningkatkan I / O pada file-file ini?

  • Memperbarui Indeks Sekunder dalam Penyangga Sisipan ibdata1
  • Membersihkan Segmen Rollback / Undo Space

IMHO saya akan meningkatkan Pool Buffer InnoDB dari 384M ke 1G.

Saya juga merekomendasikan untuk meningkatkan RAM ke 8G

RolandoMySQLDBA
sumber