1

I have a large table hosted on Aurora at Amazon using MySql 5.7

2 days ago, I ran this command:

     insert IGNORE into archiveDataNEW
         (`DateTime-UNIX`,`pkl_PPLT_00-PIndex`,`DataValue`)
         SELECT `DateTime-UNIX`,`pkl_PPLT_00-PIndex`,`DataValue`
             FROM offlineData 
             order by id 
             limit  600000000,  200000000

Yesterday afternoon, my computer crashed so the connection to mysql was severed.

sometime last night the status of the query was "query end"

today the status of the query is still "query end"

Questions: Can I stop this process - or with that only make things worse?

Does MySQL innodb unwind a query when the connection to the server drops? Is there any way to tell it to proceed instead?

will I need to re-run the command when it finally completes the query end process ?

Here is the table I am loading data into, any thoughts or suggestions will be appreciated.

CREATE TABLE `archiveDataNEW` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `DateTime-UNIX` bigint(20) NOT NULL DEFAULT '0',
  `pkl_PPLT_00-PIndex` int(11) NOT NULL DEFAULT '0',
  `DataValue` decimal(14,4) NOT NULL DEFAULT '0.0000',
  PRIMARY KEY (`id`,`DateTime-UNIX`),
  UNIQUE KEY `Unique2` (`pkl_PPLT_00-PIndex`,`DateTime-UNIX`) USING BTREE,
  KEY `DateTime` (`DateTime-UNIX`) USING BTREE,
  KEY `pIndex` (`pkl_PPLT_00-PIndex`) USING BTREE,
  KEY `DataIndex` (`DataValue`),
  KEY `pIndex-Data` (`pkl_PPLT_00-PIndex`,`DataValue`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=736142506 DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (`DateTime-UNIX`)
(PARTITION p2016 VALUES LESS THAN (1483246800) ENGINE = InnoDB,
 PARTITION p2017 VALUES LESS THAN (1514782800) ENGINE = InnoDB,
 PARTITION p2018 VALUES LESS THAN (1546318800) ENGINE = InnoDB,
 PARTITION p2019 VALUES LESS THAN (1577854800) ENGINE = InnoDB,
 PARTITION p2020 VALUES LESS THAN (1609477200) ENGINE = InnoDB,
 PARTITION p2021 VALUES LESS THAN (1641013200) ENGINE = InnoDB,
 PARTITION p2022 VALUES LESS THAN (1672549200) ENGINE = InnoDB,
 PARTITION p2023 VALUES LESS THAN (1704085200) ENGINE = InnoDB,
 PARTITION pMAX VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */;```

Rick James
  • 135,179
  • 13
  • 127
  • 222
iewebguy
  • 316
  • 3
  • 16
  • UPDATE: It took at least 12 hours for the killed process in the "query end" state to disappear after I issued the CALL mysql.rds_kill(xx); command. – iewebguy Apr 17 '21 at 14:35

2 Answers2

2

There's no way to complete that statement and commit the row it inserted.

This is apparently a bug in MySQL 5.7 code, discussed here: https://bugs.mysql.com/bug.php?id=91078

The symptom is that a query is stuck in "query end" state and there's no way to kill it or finish it except by restarting the MySQL Server. But this is not possible on AWS Aurora, right?

There's some back and forth in that bug log about whether it's caused by the query cache. The query cache is deprecated, but in Aurora they have reenabled it and changed its implementation. They are convinced that their query cache code solves the disadvantages of MySQL's query cache implementation, so they leave it on in Aurora (this is one of many reasons you should think of Aurora as a fork of MySQL, not necessarily compatible with MySQL itself).

Bill Karwin
  • 538,548
  • 86
  • 673
  • 828
  • I am attempting to kill it now... there is a special command: CALL mysql.rds_kill(xx); Last time I restarted the server it did not go well... It got stuck in a restart loop and AWS tech support had to fix it. I'll give the kill command a day or so to finish. – iewebguy Apr 16 '21 at 18:26
1

Kill it, if you can. It is either busy committing (which will take a long time) or busy undoing (which will take even longer). If it won't kill, you are stuck with waiting it out.

A better way.

Using OFFSET in limit 600000000, 200000000 will only get slower and slower as you do the chunks. This is because it must step over the 600M rows.

Also, INSERTing 200M rows at a time is quite inefficient. The system must prepare to UNDO the action in case of crash.

So, it is better to "remember where you left off". Or do it in explicit chunks like WHERE id BETWEEN 12345000 AND 12345999. Also, do only 1K rows at a time.

But, what are your trying to do?

If you are adding Partitioning, let's discuss whether there will be any benefit. It looks like you are adding yearly partitioning. Possibly the only advantage is when you need to DROP PARTITION to get rid of "old" data. It is unlikely that any queries will run any faster.

Likely optimizations:

Shrink:

`DateTime-UNIX` bigint(20)

This seems to be a unix timestamp, that fits nicely in a 4-byte INT or a 5-byte TIMESTAMP; why use an 8-byte BIGINT? TIMESTAMP has the advantage of allowing lots of datetime functions. A 5-byte DATETIME or a 3-byte DATE will last until the end of the year 9999. We are 17 years from overflow of TIMESTAMP; what computer systems do you know of that have been around since 2004 (today - 17 years)? Caveat: There will be timezone issues to address (or ignore) if you switch from TIMESTAMP. (If you need the time part, do not split a DATETIME into two columns; it is likely to add complexity.)

Drop KEY pIndex (pkl_PPLT_00-PIndex) USING BTREE, it is redundant with two other indexes.

Do not pre-build future partitions; it hurts performance (a small amount). At the end of the current year, build the next year's partition with REORGANIZE. Details here: http://mysql.rjweb.org/doc.php/partitionmaint

This will improve performance in multiple ways:

PRIMARY KEY (`id`,`DateTime-UNIX`),
UNIQUE KEY `Unique2` (`pkl_PPLT_00-PIndex`,`DateTime-UNIX`) USING BTREE,

-->

PRIMARY KEY(`pkl_PPLT_00-PIndex`,`DateTime-UNIX`),
INDEX(id)   -- sufficient for AUTO_INCREMENT

It may run faster if you leave off the non-UNIQUE indexes until the table is loaded. Then do ALTER(s) to add them.

Rick James
  • 135,179
  • 13
  • 127
  • 222
  • Rick, I am loading 1.3 billion records, so 1000 at a time is going to present a challenge. I am attempting to kill it now.- (thanks for formatting my post) – iewebguy Apr 16 '21 at 18:33
  • I thought the TIMESTAMP datatype was limited to 2038 ? I am attempting to avoid the 2038 problem at the same time not break the application that uses this database – iewebguy Apr 16 '21 at 18:45
  • 1K (or 10K) at a time is not necessarily slower than 200M at a time. The "undo" logging, etc, is more efficient if it involves less space than innodb_log_file_size. When it exceeds that, it must write to the actual table, leading to extra block spits and fragmentation. – Rick James Apr 16 '21 at 20:38
  • And I augmented my Answer to discuss `TIMESTAMP`. – Rick James Apr 16 '21 at 20:44
  • Rick, Thank you so much for your insight. I am going to change the KEY setup as you suggest. Our application is monitoring the energy usage of many buildings for the life of the building, so 17 years is quite short for us. I don't want to be the guy they call to fix this when the database has a projected 50 billion records in 17 years! ;) Enjoy the Latte! – iewebguy Apr 16 '21 at 21:24
  • 1
    @iewebguy - Interesting application. Thanks for the latte. For the time being, the system can grow the disk space easily, thanks to being in the cloud. 5.7 will be EOL in a year or two; AWS may take care of moving you up to 8.0. In the long run, AWS may go out of business or be replaced. – Rick James Apr 16 '21 at 22:53