2012-03-29 40 views
10

Me he dado cuenta de una importante ganancia de rendimiento si vuelvo a empaquetar una tabla (ALTER TABLE foo ENGINE = INNODB) después de un período de tiempo, o muchos después de un gran volumen de INSERT/UPDATE/DELETE. No sé si esto se debe a que se reconstruyen indices, etc., o se compacta el espacio de la tabla, o algo más.Optimización de tabla InnoDB sin tabla de bloqueo

Se me ocurre que hacer algo como ALTER MOTOR TABLA foo = INNODB debe ser una parte del mantenimiento tabla de rutina, sin embargo el uso de optimizar o ALTER bloquea la tabla que es inaceptable, es que hay una buena manera de hacerlo con la un servidor de base de datos (lo que significa que no se puede pasar a otra instancia) sin bloquear toda la tabla?

Actualización: Usando Percona 5.5.17-55

Actualización: VER variables como '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

¿Qué versión de MySQL estás usando ??? – RolandoMySQLDBA

+0

Pregunta actualizada para incluir la versión – Jeremy

+0

de MySQL Agregue esto a su pregunta: 'MOSTRAR VARIABLES COMO 'innodb%';' – RolandoMySQLDBA

Respuesta

24

no se puede modificar u optimizar una mesa sin bloquearlo. Sin embargo, con la herramienta pt-online-schema-change de Percona Toolkit (exención de responsabilidad: mi empleador), puede hacerlo y funciona bastante bien. Para optimizar la tabla, basta con utilizar algo como esto:

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

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

+0

Actualicé la pregunta para mayor claridad. Analizaré pt-online-schema-change, gracias. – Jeremy

+0

Exactamente lo que estaba buscando, gracias. – Jeremy

+0

Al leer la documentación, no usaré esta herramienta en mis tablas InnoDB (todas con claves foráneas). Compruebe http://www.percona.com/doc/percona-toolkit/2.1/pt-online-schema-change.html#cmdoption-pt-online-schema-change--alter-foreign-keys-method –

1

Básicamente, usted está haciendo un OPTIMIZE en la tabla. Para tablas InnoDB, OPTIMIZE está mapeado a ALTER TABLE. Citando el manual de MySQL:

Para tablas InnoDB, optimizar la TABLA se asigna a ALTER TABLE, que reconstruye la tabla para actualizar las estadísticas de índice y el espacio no utilizado libre en el índice agrupado.

Al eliminar 1/2 una tabla, una OPTIMIZE después es una muy buena idea.

Haría una sugerencia para mejorar el rendimiento. Al ver que admite en su configuración el nuevo formato de archivo BARRACUDA, debe usarlo. Lo que le es muy fácil, sólo tiene que añadir en su my.cnf:

innodb_file​_format=Barracuda 

Reiniciar el servidor y luego altera su mesa para utilizar la nueva disposición ROW_FORMAT = COMPRESSED:

ALTER TABLE x ROW_FORMAT=COMPRESSED; 

Por experiencia personal, cuando se utiliza la fila comprimido formato, el tamaño de la tabla se ha reducido a la mitad y tiene un impacto positivo significativo en el rendimiento también.

Para más detalles intentar ir 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

¿Hay inconvenientes en el uso del nuevo formato de archivo o la compresión de filas? – Jeremy

+0

Debe haber un pequeño aumento en el uso de la CPU, pero todas las pruebas que he visto indican que no hay inconvenientes. El antiguo formato "Antelope" se mantiene como predeterminado principalmente para la compatibilidad con versiones anteriores de MySQL. El nuevo formato de archivo Barracuda probablemente se convertirá en el predeterminado en la próxima versión principal de MySQL. – capi

+0

En mi experiencia, habilitar el formato de fila comprimida solo tiene sentido si la longitud de fila promedio es lo suficientemente grande (use 'MOSTRAR ESTADO DE MESA COMO 'nombre_tabla'' para verificar) y tiene al menos un campo de texto con un contenido largo. –

10

Desde MySQL 5.6.17, MySQL soporta optimizar la línea de tablas InnoDB por defecto.

Cuestiones relacionadas