【发布时间】:2017-09-01 13:20:53
【问题描述】:
我将从 MySQL Online DDL Limitations 页面中的一些内容开始:
没有机制可以暂停在线 DDL 操作或限制在线 DDL 操作的 I/O 或 CPU 使用率。
但是,我仍然对可能错过的解决方案感兴趣。
情况:索引越来越大,而且它们变得越来越大,以至于没有足够的内存来处理所使用的查询,导致磁盘 I/O 猛增,一切都陷入了彻底的混乱.已创建较小的新复合索引,但问题是在运行 ALTER TABLE 时不会破坏任何内容。
事实如下:
- 这是一个 InnoDB 表。
- 该表没有主键或唯一索引。
- 列组合不适合用作主键或唯一索引。
- 该表没有外键。
- 该表每月分区(当前为 50 个)。
- 该表必须始终接受写入。
- 最新的 3-6 个分区必须接受读取。
- 有一个
id列,但这不是唯一的。 - 该表由大约 20 亿行组成。
- 当前月份的分区是唯一接收写入的分区。
- 提前 1 个月进行分区;总是有一个空分区。
SHOW CREATE TABLE(我没有包括所有分区):
CREATE TABLE `my_wonky_table` (
`id` bigint(20) unsigned NOT NULL,
`login` varchar(127) DEFAULT NULL,
`timestamp` int(10) unsigned NOT NULL,
`ip` varchar(32) CHARACTER SET ascii DEFAULT NULL,
`val_1` int(10) unsigned DEFAULT NULL,
`val_2` varchar(127) DEFAULT NULL,
`val_3` varchar(255) DEFAULT NULL,
`val_4` varchar(127) DEFAULT NULL,
`val_5` int(10) unsigned DEFAULT NULL,
KEY `my_wonky_table_id_idx` (`id`),
KEY `my_wonky_table_timestamp_idx` (`timestamp`),
KEY `my_wonky_table_val_1_idx` (`val_1`,`id`),
KEY `my_wonky_table_val_2_idx` (`val_2`,`id`),
KEY `my_wonky_table_val_4_idx` (`val_4`,`id`),
KEY `my_wonky_table_val_5_idx` (`val_5`,`id`),
KEY `my_wonky_table_ip_idx` (`ip`,`id`),
KEY `my_wonky_table_login_idx` (`login`,`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (`id`)
(PARTITION pdefault VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
关于查询:在id 上始终是SELECT,其他所有内容都用于过滤。
我想避免的:
- 关闭数据库实例。
- 100% 的磁盘 I/O
我曾想过使用pt-online-schema-change 工具进行节流,但遇到了无主键墙。一个不同的解决方案是在代码中执行此操作,有效地将触发器移动到代码库,并使用有些奇怪的块(例如,使用时间戳列的一个小时的数据块)缓慢复制数据,因为没有唯一索引。
是否有其他可用的解决方案和/或工具?
【问题讨论】:
-
你有那个表的外键吗?此外,您是否需要能够始终读取整个数据(和/或您是否可以例如在维护期间调整您的应用程序以访问不同的表),因为您只指定您必须始终能够写入?此外,该特定表本身的 I/O 是否会出现问题,或者服务器上的 I/O 通常会出现问题(因为它可能会减慢服务器的其余部分)
-
好问题!我更新了事实清单。此外,I/O 与整个服务器有关。当磁盘利用率达到 100% 时,奇怪的事情开始发生。
-
请提供
SHOW CREATE TABLE;我需要查看更多信息。多少个分区?典型的查询是什么?你在表演什么ALTERs?同时,关于分区的更多信息:mariadb.com/kb/en/mariadb/partition-maintenance -
是否有必要将所有这些数据保存在一个表中?
-
添加了额外信息。
ALTER是专门将几个索引组合成更少的复合索引,因为它们总是在一起。数据必须保留在此表中,是的。
标签: mysql database indexing alter-table