简体   繁体   中英

What is the best and safest method to update/change the data type of a column in a MySQL table that has ~5.5 million rows (TINYINT to SMALLINT)?

Similar questions have been asked, but I have had issues in the past by using

ALTER TABLE tablename MODIFY columnname SMALLINT

I had a server crash and had to recover my table when I ran this the last time. Is it safe to use this command when there is that much data in the table? What if there are other queries that may be running on the table in parallel? Should I copy the table and run the query on the new table? Should I copy the column and move the data to the new column?

Please let me know if there are any best or "safest" practices when doing this.

Also, I know this depends on a lot of factors, but does anyone know how long the query should take on an InnoDB table with ~5.5 million rows (rough estimate)? The column in question is a TINYINT and has data in it. I want to upgrade to a SMALLINT to handle larger values.

Thanks!

This cannot be easily answered.

It depends on things like

  • Has the table its own file, or is it shared with others?
  • How big is the table in terms of bytes?

etc.

It can last from some minutes to, indeed, some hours and can involve copying over the whole content of the table, so you have quite big needs of disk space.

On a slow disk, and with lots of columns in the table, it could take hours to finish.

The ALTER is "safe" because it used to do the following:

  1. Lock the table
  2. Create a similar table, but with SMALLINT instead of TINYINT .
  3. Copy all the rows over to the new table.
  4. Rename the tables and drop the old one.
  5. Unlock

Step 3 is the slow part. The only vulnerability is in step 4, which is very fast.

A server crash during steps 1-3 should have left the old table intact, but possibly left behind a partially created tmp table named something like #sql... .

Percona's pt-online-schema-change has the advantage of being virtually lockless.

You can add a new SMALLINT column to the table:

ALTER TABLE tablename ADD columnname_new SMALLINT AFTER columnname;

then copy the data from old column to new one:

UPDATE tablename SET columnname_new = columnname WHERE columnname_new IS NULL LIMIT 100000

repeat above until all records done

then you can drop old column:

ALTER TABLE tablename DROP COLUMN columnname

and finally rename new column:

ALTER TABLE tablename CHANGE columnname_new columnname SMALLINT

you could do the copy of values from old column to new column in batch of 100000 rows, just to be sure not to have any issue

I would add a new column, change the code to check if a value exists in the new column and to read/write it if it does. Also change the code to read from the old column and write to the new column. At this point you can migrate the data at will, copying over values from the old column into the new column where a value does not exist in the new column.

Once all of the data has been migrated you can drop the old column.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM