Open dveeden opened 8 years ago
Yes, this will be a bit lengthier to handle; we may eventually also need to consider what happens when the alter statement changes a generated column into a non generated column. I need to wrap my head around this, but this sounds non-trivial.
Any thoughts on possible scenarios is appreciated!
Anecdotal virtual-column trick:
Yesterday, and mainly for fun, I used (a tweaked) pt-osc
to shrink and optimize a table in one run.
(the tweak was: an extra grep to keep the virtual column out of @common_columns)
To prepare the pt-osc
run, I first added a virtual column AS (IF(<condition>, NULL, id))
, and then added a UNIQUE
index on it. The condition
is true for rows that were old and no longer wanted.
I had to do that in 2 steps, to be able to use standard online-alters (LOCK=NONE, ALGORITHM=INPLACE
).
Adding the index takes a few seconds per 1M rows, and would pause single-threaded replication, so be careful there.
Then I used pt-osc
to alter the column to AS (IF(<condition>, 0, id))
, to make all no longer wanted rows collide on that zero (via the new restrictive UNIQUE
index).
Because pt-osc
uses INSERT IGNORE
to copy rows, only one of the (millions of) unwanted rows stays in the table. Don't forget to manually delete that one old row.
To finish, it needs 2 standard online alters again: one to drop the index, and then one to drop the virtual column.
If the old table has a generated column then
gh-ost
tries to insert on the generated column on the new table. It does not detect the error and tries to continue.The solution is:
Example table:
Example output