Schrödinger's Paradox in MySQL
Tags: mysql, database, performance, webdev
Published: 2022-11-12 03:30:00

<!-- wp:paragraph -->
<p>If you have ever dived deeper into physics and quantum mechanics in particular, you have probably heard of this weird phenomena called the Schrödinger's cat. In a nutshell, a Schrödinger's cat is a thought experiment performed by an Austrian-Irish physicist Erwin Schrödinger in 1935 in a discussion with Albert Einstein: the experiment illustrates a hypothetical cat that may simultaneously be considered both alive and dead as a result of being linked to a random subatomic event that may or may not occur.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>The Schrödinger's Paradox in MySQL</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>As already mentioned above, the Schrödinger's paradox illustrates something that is simultaneously considered both alive and dead, so one might wonder how might this experiment be relevant to MySQL? In general, everything is pretty simple: such an issue might appear when the power is interrupted in the middle of an operation performed by MySQL: for example, in the middle of an import operation. While relying on ACID properties might help, they might not be of much help after all: these sets of properties are indeed intended to guarantee data validity despite errors, power failures and other mishaps, but if after the failed operation you perform some sort of operations on the table in question and they fail, ACID might not be at fault here. You may be faced with a different problem: the Schrödinger's paradox in MySQL.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>In order to confirm you're dealing with a Schrödinger's table in MySQL, perform these steps:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li>Issue a <code>SHOW TABLES;</code> statement on your MySQL instance, look for your table - the table should not be in the list.</li><li>Try to create the table in question (use the same name) - run a <code>CREATE TABLE</code> statement. MySQL should return an error that the table already exists:<br><code>ERROR 1050 (42S01): Table 'demo_table' already exists</code></li><li>Try to drop the table in question - run a <code>DROP TABLE</code> statement. MySQL should return an error that the table does not exist:<br><code>ERROR 1146 (42S02): Table 'demo_table' doesn't exist</code></li></ol>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>If you cannot create the table, dropping it doesn't work either, but you are able to see the files in the <code>/var/lib/mysql</code> directory, you are probably dealing with a Schrödinger's table in MySQL.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>That might be the case because the data file is missing in the data directory, but the table format (also called definition) <code>.frm</code> file exists or vice-versa. In a nutshell, it seems like InnoDB still has an entry for such a table in the tablespace (the <code>ibdata1</code> file).</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Getting Rid of Schrödinger's Tables in MySQL</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Now that you have confirmed that you're dealing with a Schrödinger's table, it's time to get rid of it. In order to do so, perform these steps:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li>Create a table with the same name on another MySQL instance.</li><li>Copy the <code>.frm</code> file of the table to the database directory on the server where you're facing the Schrödinger's table issue. Make sure the file ownership and permissions are correct.</li><li>Issue a <code>SHOW TABLES</code> statement in MySQL: you should now see the Schrödinger's table. All operations should now work as normal (i.e you can drop the table if you wish).</li></ol>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>Bear in mind that simply deleting the <code>.ibd</code> files that are present in the directory will not work because MySQL will simply recreate the files.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Another way to fix the issue would be as follows (make sure you have backups of your data before performing these steps though):</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li>Delete all of your databases excluding <code>mysql</code>.</li><li>Shut down MySQL.</li><li>Delete the <code>ibdata1</code> and <code>ib_logfile*</code> files.</li><li>Restart MySQL. The tablespace and logs should be recreated.</li><li>Restore your database.</li></ol>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>In order to ensure that you no longer have to deal with Schrödinger's tables in MySQL, make sure the power doesn't get interrupted when any MySQL operations are running.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Summary</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Schrödinger's tables in MySQL can be a really frustrating problem. The issue is generally caused by power interruptions when certain operations are running - this way the data file is missing from the data directory, but the table definition files - <code>.frm</code> - exist or vice-versa. Thankfully, these issues are pretty easy to fix and prevent from happening again.</p>
<!-- /wp:paragraph -->