I'm currently running a schema migration on a table containing ~23 million rows. The rows have a normal primary index and we're running MySQL 5.5.
The migration, to add a couple of columns, started quickly. At a rapid rate, it copied the first 3 million in about 3 minutes. The next 3 took about 20 minutes. Overnight, it did another 9 million in about 8 hours.
Other than modifying the replica lag I'm willing to accept, I've not modified the defaults - so it's obeying the chunk time and aiming to get each copy in the ~0.5 second range.
As I'm running the tool with PTDEBUG on so I can see detailed output, and it would appear the operations are correctly in that range - but I don't understand why they're getting slower and slower. At peak it was around 7000 rows a second, and it's slowly dropping further and further, we're down to ~470 now and still have ~15million rows to go.
I have several assumptions, but I'm not sure which is correct, or how to diagnose it.
Are any of my assumptions correct, and how would I identify which?
- It's the index on the original table - the query itself is taking too long. I'm assuming it's not this, as the
SELECT
is off the primary key. - It's something to do with the insertion process. The larger the table, the more "thinking" has to be done about the
INSERT
and so that process is taking longer. - There's a hardware limitation somewhere. We're running on RDS with 3 replicas, by the way. Monitoring doesn't suggest we're hitting a bottleneck at the moment.
Here's the CREATE TABLE statement anonymised:
CREATE TABLE `user_offer` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`CreatedDate` datetime NOT NULL,
`A` int(11) NOT NULL,
`B` int(11) NOT NULL,
`C` int(11) NOT NULL,
`D` datetime DEFAULT NULL,
`E` datetime DEFAULT NULL,
`F` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`G` int(11) DEFAULT NULL,
`H` int(11) DEFAULT NULL,
`I` int(11) NOT NULL,
`J` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`K` tinyint(1) NOT NULL,
`L` tinyint(1) NOT NULL,
`M` tinyint(1) NOT NULL,
`N` tinyint(1) NOT NULL,
`O` int(11) NOT NULL,
`P` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`Q` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`R` tinyint(1) NOT NULL,
`S` tinyint(1) NOT NULL,
`T` int(11) DEFAULT NULL,
`U` tinyint(1) NOT NULL,
`V` int(11) DEFAULT NULL,
`W` datetime DEFAULT NULL,
`X` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`Y` tinyint(1) NOT NULL,
`Z` tinyint(1) DEFAULT NULL,
`AA` int(11) DEFAULT NULL,
`AB` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `IDX_CB147C66AAB016B8` (`I`),
KEY `IDX_CB147C6668D3EA09` (`J`),
KEY `L_idx` (`L`),
KEY `H_idx` (`H`),
KEY `IDX_CB147C6632A90D98` (`T`),
KEY `IDX_CB147C66F6CB3049` (`V`),
KEY `createdDate_idx` (`CreatedDate`),
KEY `consentedDate_idx` (`W`),
CONSTRAINT `FK_CB147C6632A90D98` FOREIGN KEY (`T`) REFERENCES `table_1` (`id`),
CONSTRAINT `FK_CB147C6668D3EA09` FOREIGN KEY (`H`) REFERENCES `table_2` (`id`),
CONSTRAINT `FK_CB147C66AAB016B8` FOREIGN KEY (`I`) REFERENCES `table_3` (`id`),
CONSTRAINT `FK_CB147C66F6CB3049` FOREIGN KEY (`V`) REFERENCES `table_2` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23448523 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
The alter statement is: ADD AC VARCHAR(5)
plus adding indexes on AC, P and Q.
Innodb_buffer_pool_read_requests
vsInnodb_buffer_pool_reads
to confirm/reject the hypothesis.SELECT
look like as it works its way through the data? (That may give us some clues of what it is working "too hard" on.)