A partitioned table in MySQL has its data separated into different tablespaces while still being viewed as a single table. Partitioning can be a useful approach in some cases when handling huge sets of data. Deleting huge data sets could be quickened up in a partitioned table, but if not handled properly, it can misplace your data in the table. In this blog, I will share how to check and fix the data in such a table with minimal disruption to the table.

In this example, we use a table partitioned based on a date range.

If we query an arbitrary data set, MySQL returns it quickly and without any issue.    

But once the data is misplaced, it does not return any rows.  

At first glance, it looks like the data has been deleted; even EXPLAIN plan returns no result.

But, the data still exists in the table; it’s just misplaced in a different partition.

 

How to check if there are more misplaced rows?

To check for more misplaced rows in the table, we could execute the CHECK command to find any more misplaced rows.

 

How can rows be misplaced?

The above observation does raise one question: how can MySQL allow this to happen, and how can it be fixed? The answer to the former is that MySQL allows users to exchange a partition with a separate table; as explained in my previous blog Quick Data Archival in MySQL Using Partitions, by default, it checks every row before inserting data into the table. 

In the above query, salaries_p15 is an empty table with the same structure as salaries, except having no partitions in it. 

After exchanging the partition, partition p15 is empty, and salaries_p15 has data of partition p15.

MySQL allows exchanging partitions without checking every row so that exchanging data can be sped up.

The above query will exchange the data in salaries_p15 quickly with an empty partition p08, assuming that the data is correct. In this case, it will result in misplaced rows in the wrong partition.

 

How to fix it

There are two ways to fix it – first, run the MySQL recommended REPAIR TABLE command, or second recreate the table by running an empty alter.

When the REPAIR TABLE is executed, the misplaced rows are arranged to their proper positions by analyzing all the rows, but it acquires a SYSTEM LOCK on the table. 

The other way is to run an empty alter that will recreate the table.

One can run a direct alter on the table that will recreate the table and lock it until the alter is completed.

One can also use pt-online schema change to recreate the table, which will not lock the table and have other benefits (Using Percona Toolkit to Alter Database Tables Online: A Controlled Approach) as well.

 

Conclusion

It is always recommended to be extra cautious while working with partitions and avoid using WITHOUT VALIDATION in the production environment to avoid any misplaced data.

Percona Distribution for MySQL is the most complete, stable, scalable, and secure open-source MySQL solution available, delivering enterprise-grade database environments for your most critical business applications… and it’s free to use!

Try Percona Distribution for MySQL today!

Subscribe
Notify of
guest

4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
lee

I’d like to recreate the missing partition issue, so can I know how to configure the test data?

lee

May I know what kind of situations might cause this problem?

lee

Can you let me know if there is a case where this happened during the actual operation