我正在mysql服务器(8.0)上实现数据分区。
作为“分区的必备要求”,我必须将分区键添加为主键,即我表中的
created_at
。例如:
alter table notifications drop primary key, add primary key(`id`, `created_at`);
在上面的查询中,
id
是一个自增主键。我的表中有超过 10M 的条目。
Mysql 不允许实时更新模式;当我运行 alter
命令时,它会锁定表。
同时,我可以为这个过程休息一段时间。请指导进行此直播的最佳方法。
我尝试使用“Faker”库在本地生成相同数量的数据,同时对其运行更改查询。我观察到这个过程花费了 2 个多小时。
Schema
CREATE TABLE `data` (
`seq_id` int NOT NULL AUTO_INCREMENT,
`id` varchar(100) NOT NULL,
`doc_id` varchar(100) NOT NULL,
`page_no` int DEFAULT '1',
`file_store` varchar(100) DEFAULT NULL,
`s_id` varchar(100) NOT NULL,
`s_f_id` varchar(100) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`f_store` varchar(100) DEFAULT 'GCP',
`purged` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`seq_id`),
UNIQUE KEY `id` (`id`),
KEY `doc_id` (`doc_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `data `
PARTITION BY RANGE (UNIX_TIMESTAMP(created_at))
(
PARTITION `partition_2020` VALUES LESS THAN (UNIX_TIMESTAMP('2020-01-01 00:00:00')),
PARTITION `partition_2021` VALUES LESS THAN (UNIX_TIMESTAMP('2021-01-01 00:00:00')),
PARTITION `partition_2022` VALUES LESS THAN (UNIX_TIMESTAMP('2022-01-01 00:00:00')),
PARTITION `partition_2022` VALUES LESS THAN (UNIX_TIMESTAMP('2023-05-31 00:00:00')),
PARTITION `partition_future` VALUES LESS THAN (MAXVALUE)
);
如果你非常关心锁定时间,那么我建议你使用主从复制。基本上就是一个主从切换时间,很短。
更改 PK 和添加
PARTITIONing
都需要数据的完整副本和重新索引。这会很慢。但是...让我们谈谈分区是否会提供任何好处。请提供 SHOW CREATE TABLE
- 当前和添加分区之后。另请参阅分区
另一方面,如果您认为确实需要分区,并且表正在增长,那么您越早执行分区,所需的时间就越少。
如果您在进行转换时要清除一些旧数据,那么我建议一次完成所有操作:
CREATE TABLE new_t (
... ); -- with new PK and partitioning.
INSERT INTO new_t
SELECT * FROM t
WHERE date >= ...; -- to purge old data by not copying it over
但即使在这样做之前,让我们看看创建,可能会有更多建议折叠到副本中。
另请注意,分区不允许使用
UNIQUE
键,也不允许使用 FOREIGN KEYs
。我们可以在看到CREATE
后进一步讨论。
还有——你有“天生”的PK吗?也就是说,你能摆脱
id
吗?
更多
更改PK时,可以简单地删除
seq_id
(auto_inc)列吗?或者您出于其他原因需要它?