简体   繁体   English

无锁表的InnoDB表优化

[英]InnoDB table optimization w/o locking table

I've noticed a significant amount of performance gain if I repack a table (ALTER TABLE foo ENGINE = INNODB) after some period of time, or after heavy volume of INSERT/UPDATE/DELETEs. 如果在一段时间后或在执行大量的INSERT / UPDATE / DELETE之后重新打包表(ALTER TABLE foo ENGINE = INNODB),我已经注意到了可观的性能提升。 I don't know if this is because indicies etc are rebuilt, or compacting the table space, or something else? 我不知道这是因为重新构建了索引等,还是压缩了表空间或其他原因?

It strikes me that doing something like ALTER TABLE foo ENGINE = INNODB should be a part of routine table maintenance, however using OPTIMIZE or ALTER locks the table which is unacceptable, is there is a good way to do with with one database server (meaning no failing over to another instance) w/o locking the entire table? 令我惊讶的是,执行ALTER TABLE foo ENGINE = INNODB之类的事情应该成为例行表维护的一部分,但是使用OPTIMIZE或ALTER会锁定该表,这是不可接受的,是否有一种与一台数据库服务器一起使用的好方法(这意味着没有故障转移到另一个实例)不锁定整个表?

Update: Using Percona 5.5.17-55 更新:使用Percona 5.5.17-55

Update: SHOW VARIABLES LIKE 'innodb%'; 更新:显示变量,如“ 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                      |
+----------------------------------------+------------------------+

You cannot ALTER or OPTIMIZE a table without locking it. 如果不锁定表,则不能更改或优化表。 However, with the pt-online-schema-change tool from Percona Toolkit (disclaimer: my employer), you can do that, and it works quite well. 但是,使用Percona Toolkit中的pt-online-schema-change工具(免责声明:我的雇主),您可以做到这一点,并且效果很好。 To OPTIMIZE the table, simply use something like this: 要优化表,只需使用如下代码:

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

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

从MySQL 5.6.17开始,MySQL默认情况下支持InnoDB表的在线优化。

Basically, you are doing an OPTIMIZE on the table. 基本上,您正在对表进行OPTIMIZE For InnoDB tables, OPTIMIZE is mapped to ALTER TABLE . 对于InnoDB表, OPTIMIZE映射到ALTER TABLE Quoting from the Mysql manual : 引用Mysql手册:

For InnoDB tables, OPTIMIZE TABLE is mapped to ALTER TABLE, which rebuilds the table to update index statistics and free unused space in the clustered index. 对于InnoDB表,OPTIMIZE TABLE映射到ALTER TABLE,ALTER TABLE重建表以更新索引统计信息并释放聚簇索引中未使用的空间。

When deleting 1/2 a table, an OPTIMIZE after is a really good idea. 当删除1/2个表时,在OPTIMIZE之后是一个好主意。

I would make a suggestion for improving performance. 我会提出改善性能的建议。 Seeing that you support in your configuration the new file format BARRACUDA you should use it. 看到您的配置支持新文件格式BARRACUDA ,则应使用它。 Enabling it is really easy, just add in your my.cnf : 启用它非常容易,只需添加my.cnf

innodb_file​_format=Barracuda

Restart the server and then alter your table to use the new available ROW_FORMAT = COMPRESSED : 重新启动服务器,然后更改表以使用新的可用ROW_FORMAT = COMPRESSED

ALTER TABLE x ROW_FORMAT=COMPRESSED;

From personal experience, when using the compressed row format, table size has reduced to half and it a significant positive impact on performance as well. 根据个人经验,使用压缩的行格式时,表的大小已减小到一半,并且对性能也产生了积极的影响。

For more details try going throug : 有关更多详细信息,请尝试通过:

http://dev.mysql.com/doc/refman/5.5/en/innodb-compression-usage.html 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/ http://www.mysqlperformanceblog.com/2008/04/23/testing-innodb-barracuda-format-with-compression/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM