Wordpress / MySQL(InnoDB)表在优化表后瞬间变得片段化?

时间:2014-02-02 22:17:53

标签: mysql database wordpress innodb

所以我最初运行mysqltuner并且它一直说(在新的Wordpress安装上,使用Percona InnoDB和Wordpress帖子的随机虚拟数据),有碎片表。我不知道这是否是检查碎片表的正确方法:

SELECT TABLE_SCHEMA, TABLE_NAME, CONCAT(ROUND(data_length / ( 1024 * 1024 ), 2), 'MB')        DATA, CONCAT(ROUND(data_free / ( 1024 * 1024 ), 2), 'MB')FREE from information_schema.TABLES where TABLE_SCHEMA NOT IN ('information_schema','mysql') and Data_free > 0;

但是吐出来了:

+----------------+-------------+--------+--------+
| TABLE_SCHEMA   | TABLE_NAME  | DATA   | FREE   |
+----------------+-------------+--------+--------+
| db_wordpress   | wp_postmeta | 2.52MB | 4.00MB |
| db_wordpress   | wp_posts    | 1.52MB | 4.00MB |
+----------------+-------------+--------+--------+

所以我不确定这些表是否真正碎片化。我跑了:

ALTER TABLE wp_postmeta ENGINE='InnoDB';

这应该是“优化”InnoDB表的正确方法吗?然后,上面的查询显示:

+----------------+-------------+--------+--------+
| TABLE_SCHEMA   | TABLE_NAME  | DATA   | FREE   |
+----------------+-------------+--------+--------+
| db_wordpress   | wp_postmeta | 0.02MB | 4.00MB |
| db_wordpress   | wp_posts    | 1.52MB | 4.00MB |
+----------------+-------------+--------+--------+

现在,mysqltuner仍然说这两张表是碎片化的,所以我试过了:

OPTIMIZE TABLE wp_posts;

运行上述查询时,将“数据”列放回原来的2.52MB ...

所以我不确定到底发生了什么?更不用说为什么这些表格(特别是wp_postswp_postmeta)会被分割,因为我的理解(主要是?)删除是导致碎片化的主要原因?如果它也是插入,我会在Wordpress中制作的几乎所有新帖子上都存在碎片问题,因为这似乎导致表格首先被分割?

无论哪种方式,我只是不确定上面的查询是否是检查碎片的正确查询,如果是,那么ALTER TABLE wp_postmeta ENGINE='InnoDB'OPTIMIZE TABLE wp_posts是正确的查询来运行以优化表格和如果是这样,为什么查询仍然显示为碎片?

编辑:

Percona的配置向导给了我:

# MyISAM #
key-buffer-size                = 32M
myisam-recover                 = FORCE,BACKUP

# SAFETY #
max-allowed-packet             = 16M
max-connect-errors             = 1000000
skip-name-resolve
#sql-mode                       = STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ONLY_FULL_GROUP_BY # I disabled this due to problems with WP/Plugins
sysdate-is-now                 = 1
innodb                         = FORCE
#innodb-strict-mode             = 0 # I disabled this due to problems with WP/Plugins

# DATA STORAGE #
datadir                        = /var/lib/mysql/

# BINARY LOGGING #
log-bin                        = /var/lib/mysql/mysql-bin
expire-logs-days               = 14
sync-binlog                    = 1

# CACHES AND LIMITS #
tmp-table-size                 = 96M # I tweaked this due to mysqltuner recommendation
max-heap-table-size            = 96M # I tweaked this due to mysqltuner recommendation
query-cache-type               = 1 # I tweaked this due to mysqltuner recommendation
query-cache-size               = 96M # I tweaked this due to mysqltuner recommendation
max-connections                = 100
thread-cache-size              = 16
open-files-limit               = 65535
table-definition-cache         = 1024
table-open-cache               = 256

# INNODB #
innodb_stats_on_metadata = 0 # I added this when testing
innodb-flush-method            = O_DIRECT
innodb-log-files-in-group      = 2
innodb-log-file-size           = 64M
innodb-flush-log-at-trx-commit = 2
innodb-file-per-table          = 1
innodb-buffer-pool-size        = 400

2 个答案:

答案 0 :(得分:1)

我猜您将所有表存储在中央表空间ibdata1中,因为当您这样做时,所有表的data_free将被报告为金额整个ibdata1文件中未使用的空间。

换句话说,将data_lengthdata_free进行比较并不是衡量碎片的有效方法,除非您使用innodb_file_per_table=1

ALTER TABLE wp_postmeta ENGIN=InnoDB确实会进行表格重组并重建二级索引。有意义的是,页面将被更好地填充,因此您的2.52MB被重写为0.02MB(可能是一个或两个16KB数据页)。

在你正在使用的规模上,我根本不担心碎片。即使以碎片形式存储数据也只需要2个半MB,因此缓冲池仍然只是填充的一小部分。处理碎片的原因是当您尝试拉伸缓冲池以适应更多数据时。在你的情况下,它无论如何都适合。


重新发表您的评论和其他信息:

innodb-buffer-pool-size        = 400

这不是一个很好的设置值。此变量的单位是 bytes ,因此您请求了一个非常小的缓冲池。事实上,InnoDB将忽略您的配置,而是使用最小值5MB。如果您检查MySQL错误日志,您可能会看到:

[Note] InnoDB: Initializing buffer pool, size = 5.0M

这对于任何典型的生产网站来说都太小了。如果要获得良好的性能,缓冲池的大小是一个至关重要的调整参数。缓冲池应足够大,以容纳工作集,即应用程序最常使用的数据页面。请参阅MySQL Performance Blog's post "10 MySQL settings to tune after installation"

那就是说,你的数据库可能很小,只有5.0MB就足够了 - 现在。但请记住,MySQL 5.6中缓冲池的默认大小为128MB。

您已为密钥缓冲区分配了32MB,该密钥缓冲区仅用于MyISAM索引。在大多数情况下,I recommend against using MyISAM适用于任何表格。如果您没有MyISAM表,那么内存将更好地分配给您的InnoDB缓冲池。

您还为查询缓存分配了96MB。查询缓存有一些缺点 - 取决于您的网站的流量,它实际上可能伤害超过帮助。除非你从中获得大量收益,否则我会禁用它(query_cache_type=0 query_cache_size=0),并将该RAM用于缓冲池。有关详细信息,请参阅MySQL Performance Blog's post "MySQL Query Cache"


重新发表您的第二条评论:

不,innodb_buffer_pool_size不是MB,而是以字节为单位。只有在为数字添加“M”后缀时,才可以将其设为MB。

The MySQL 5.6 manual on innodb_buffer_pool_size说:

  

缓冲池的大小(以字节为单位),InnoDB缓存表和索引数据的内存区域。默认值为128MB。

我刚刚使用MySQL 5.5.36测试它 - 而不是Percona Server,只是存储MySQL社区版。我确认当我设置innodb_buffer_pool_size=400时,我得到的是5.0MB,这是记录的最小尺寸。

我还测试了MySQL 5.1.70,当我开始将缓冲池大小设置为400时,我在错误日志中看到了这一点:

140203  9:46:20 [Warning] option 'innodb-buffer-pool-size': signed value 400 adjusted to 1048576
140203  9:46:20  InnoDB: Initializing buffer pool, size = 1.0M

MySQL 5.1的最小缓冲池大小记录为1.0MB。

答案 1 :(得分:0)

嗯,非常有趣的比尔因为我的设置肯定是MB,因为mysqltuner显示使用的最大内存是~510MB,在1.1mb的100个连接+ 400mb缓冲池大小。此外,如果我调整它像900 MySQL错误启动error_log说明它不能分配900mb到innodb缓冲区。

那么Percona和MySQL肯定是不同的。