Alter table column in production I want to alter a table column from CHAR(2) utf8mb4 to CHAR(2) latin1 (so it will use 2 bytes instead of 8, utf8 is not needed because they are country codes so there are only latin characters).

This table receives about 50 new rows per second.

There are about 125 million rows, total table size 5GB, so the alter will take a wile.

How can I alter the table without locking the writes?
Issue 1 - How to do the ALTER without blocking everything too badly.  Answer:  use pt-online-schema-change.

Issue 2 - Storage for char-like datatypes.

In the past, CHAR(n) always reserved n*c bytes, where c is the maximum size based on the CHARACTER SET: 1 for latin1, 3 for utf8, 4 for utf8mb4.  This was sometimes handy for Engine=MyISAM with FIXED sized rows.

In certain ROW_FORMATs of InnoDB in new enough versions (sorry, I don't have the specifics), CHAR(n) will occupy between n and n*c bytes, depending on the actual characters needed.  With InnoDB, there is no concept of fixed sized rows.

A complex SELECT that needs a temp table (say for ORDER BY), will try to use a MEMORY table for such.  In that case, the length of CHAR(n) and VARCHAR(n) will always be n*c.  This sometimes leads to an inefficiency.  Or it might use MyISAM for the tmp table.  Version 8.0 will be moving toward using InnoDB for tmp tables, so this paragraph will eventually be moot.

Converting CHAR to VARCHAR and/or converting the column from one CHARACTER SET to another requires a heavy-duty ALTER (not INPLACE).  See https://dev.mysql.com/doc/refman/5.6/en/innodb-create-index-overview.html  That link is for 5.6; there have been changes; pick the page for your version.

VARCHAR has 1 or 2 bytes for the length, plus only the number of bytes needed for the actual characters.  So it is 1+n*c for short max len.