2012-03-29 17 views
10

Ho notato un notevole aumento di prestazioni se reimballaggio una tabella (ALTER TABLE foo ENGINE = INNODB) dopo un certo periodo di tempo, o molti dopo un volume pesante di INSERT/UPDATE/DELETE. Non so se questo è dovuto al fatto che gli indirizzi ecc vengono ricostruiti, o comprimendo il tablespace, o qualcos'altro?Ottimizzazione tabella InnoDB senza tabella di bloccaggio

Mi colpisce che fare qualcosa di come ALTER TABLE foo ENGINE = InnoDB dovrebbe essere una parte della routine di manutenzione tavolo, tuttavia utilizzando ottimizzare o ALTER blocca il tavolo che è inaccettabile, è che c'è un buon modo a che fare con con un server di database (che significa non aver superato un'altra istanza) senza bloccare l'intera tabella?

Aggiornamento: Usando Percona 5.5.17-55

Aggiornamento: SHOW VARIABLES LIKE 'InnoDB%';

+----------------------------------------+------------------------+ 
| Variable_name       | Value     | 
+----------------------------------------+------------------------+ 
| innodb_adaptive_checkpoint    | estimate    | 
| innodb_adaptive_flushing    | OFF     | 
| innodb_adaptive_hash_index    | ON      | 
| innodb_additional_mem_pool_size  | 8388608    | 
| innodb_auto_lru_dump     | 120     | 
| innodb_autoextend_increment   | 8      | 
| innodb_autoinc_lock_mode    | 1      | 
| innodb_buffer_pool_shm_checksum  | ON      | 
| innodb_buffer_pool_shm_key    | 0      | 
| innodb_buffer_pool_size    | 30064771072   | 
| innodb_change_buffering    | inserts    | 
| innodb_checkpoint_age_target   | 0      | 
| innodb_checksums      | ON      | 
| innodb_commit_concurrency    | 0      | 
| innodb_concurrency_tickets    | 500     | 
| innodb_data_file_path     | ibdata1:10M:autoextend | 
| innodb_data_home_dir     |      | 
| innodb_dict_size_limit     | 0      | 
| innodb_doublewrite      | ON      | 
| innodb_doublewrite_file    |      | 
| innodb_enable_unsafe_group_commit  | 0      | 
| innodb_expand_import     | 0      | 
| innodb_extra_rsegments     | 0      | 
| innodb_extra_undoslots     | OFF     | 
| innodb_fast_checksum     | OFF     | 
| innodb_fast_recovery     | OFF     | 
| innodb_fast_shutdown     | 1      | 
| innodb_file_format      | Antelope    | 
| innodb_file_format_check    | Barracuda    | 
| innodb_file_per_table     | ON      | 
| innodb_flush_log_at_trx_commit   | 0      | 
| innodb_flush_log_at_trx_commit_session | 3      | 
| innodb_flush_method     | O_DIRECT    | 
| innodb_flush_neighbor_pages   | 1      | 
| innodb_force_recovery     | 0      | 
| innodb_ibuf_accel_rate     | 100     | 
| innodb_ibuf_active_contract   | 1      | 
| innodb_ibuf_max_size     | 15032369152   | 
| innodb_io_capacity      | 200     | 
| innodb_lazy_drop_table     | 0      | 
| innodb_lock_wait_timeout    | 50      | 
| innodb_locks_unsafe_for_binlog   | OFF     | 
| innodb_log_block_size     | 512     | 
| innodb_log_buffer_size     | 67108864    | 
| innodb_log_file_size     | 402653184    | 
| 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_overwrite_relay_log_info  | OFF     | 
| innodb_page_size      | 16384     | 
| innodb_pass_corrupt_table    | 0      | 
| innodb_read_ahead      | linear     | 
| innodb_read_ahead_threshold   | 56      | 
| innodb_read_io_threads     | 4      | 
| innodb_recovery_stats     | OFF     | 
| innodb_replication_delay    | 0      | 
| innodb_rollback_on_timeout    | OFF     | 
| innodb_show_locks_held     | 10      | 
| innodb_show_verbose_locks    | 0      | 
| innodb_spin_wait_delay     | 6      | 
| innodb_stats_auto_update    | 1      | 
| innodb_stats_method     | nulls_equal   | 
| innodb_stats_on_metadata    | ON      | 
| 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    | 8      | 
| innodb_thread_concurrency_timer_based | OFF     | 
| innodb_thread_sleep_delay    | 10000     | 
| innodb_use_purge_thread    | 1      | 
| innodb_use_sys_malloc     | ON      | 
| innodb_use_sys_stats_table    | OFF     | 
| innodb_version       | 1.0.16-12.8   | 
| innodb_write_io_threads    | 4      | 
+----------------------------------------+------------------------+ 
+0

Quale versione di MySQL stai usando ??? – RolandoMySQLDBA

+0

Domanda aggiornata per includere la versione di MySQL – Jeremy

+0

Si prega di aggiungere questo alla tua domanda: 'Mostra variabili come 'innodb%';' – RolandoMySQLDBA

risposta

24

Non è possibile modificare o ottimizzare un tavolo senza bloccarlo. Tuttavia, con lo strumento pt-online-schema-change di Percona Toolkit (disclaimer: il mio datore di lavoro), puoi farlo e funziona abbastanza bene. Per ottimizzare la tabella, è sufficiente utilizzare qualcosa di simile:

pt-online-schema-change <options> --alter='ENGINE=InnoDB' 

http://www.percona.com/doc/percona-toolkit/2.1/pt-online-schema-change.html

+0

Ho aggiornato la domanda per chiarezza. Guarderò in pt-online-schema-change, grazie. – Jeremy

+0

Esattamente quello che stavo cercando, grazie. – Jeremy

+0

Leggendo la documentazione, non userò questo strumento nelle mie tabelle InnoDB (tutte con chiavi esterne). Controllare http://www.percona.com/doc/percona-toolkit/2.1/pt-online-schema-change.html#cmdoption-pt-online-schema-change--alter-foreign-keys-method –

1

Fondamentalmente, si sta facendo un OPTIMIZE sul tavolo. Per le tabelle InnoDB, viene mappato su ALTER TABLE. Citando dal manuale Mysql:

Per le tabelle InnoDB, OPTIMIZE TABLE viene mappato ALTER TABLE, che ricostruisce la tabella per aggiornare le statistiche indice e lo spazio inutilizzato nell'indice cluster.

Quando si elimina 1/2 un tavolo, un OPTIMIZE dopo è davvero una buona idea.

Vorrei fare un suggerimento per migliorare le prestazioni. Vedendo che supporti nella configurazione il nuovo formato di file BARRACUDA dovresti usarlo. L'attivazione è molto semplice, è sufficiente aggiungere nella vostra my.cnf:

innodb_file​_format=Barracuda 

Riavviare il server e quindi modificare il vostro tavolo per utilizzare la nuova disposizione ROW_FORMAT = COMPRESSED:

ALTER TABLE x ROW_FORMAT=COMPRESSED; 

Per esperienza personale, quando si utilizza la riga compressa formato, la dimensione della tabella è ridotta alla metà e ha un impatto positivo significativo anche sulle prestazioni.

Per maggiori dettagli provare ad andare throug:

http://dev.mysql.com/doc/refman/5.5/en/innodb-compression-usage.html

http://www.mysqlperformanceblog.com/2008/04/23/testing-innodb-barracuda-format-with-compression/

+0

Ci sono degli svantaggi nell'usare il nuovo formato di file o la compressione delle righe? – Jeremy

+0

Ci dovrebbe essere un lieve aumento nell'uso della CPU, ma tutti i test che ho visto indicano che non c'è alcun svantaggio. Il vecchio formato "Antelope" viene mantenuto come predefinito principalmente per la compatibilità con le versioni precedenti di MySQL. Il nuovo formato di file Barracuda molto probabilmente diventerà il default nella prossima versione di MySQL. – capi

+0

Nella mia esperienza l'abilitazione del formato di righe compresse ha senso solo se la lunghezza della riga media è abbastanza grande (usare 'MOSTRA TABELLA STATO COME 'nome_tabella' per controllare) e si ha almeno un campo di testo con un contenuto lungo. –

10

da MySQL 5.6.17, MySQL supporta ottimizzare online le tabelle di InnoDB per impostazione predefinita.

Problemi correlati