Bug #69580 Renaming a column in Online DDL requires table copy for binary data types
Submitted: 26 Jun 2013 9:41 Modified: 15 Oct 2013 18:02
Reporter: Przemyslaw Malkowski Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: DDL Severity:S2 (Serious)
Version:5.6 OS:Any
Assigned to: CPU Architecture:Any
Tags: ONLINE DDL ALTER TABLE

[26 Jun 2013 9:41] Przemyslaw Malkowski
Description:
While testing Online DDL in MySQL 5.6 I noticed that changing column name involves table copy for certain type of column definitions.
I identified it happens for binary data types like BINARY and BLOB, but also for CHAR when binary collation is set. 
Surprisingly the same column rename for VARCHAR with binary collation works as expected.

How to repeat:
mysql [localhost] {msandbox} (test) > select @@version;
+-----------+
| @@version |
+-----------+
| 5.6.12    |
+-----------+
mysql [localhost] {msandbox} (test) > select @@old_alter_table;
+-------------------+
| @@old_alter_table |
+-------------------+
|                 0 |
+-------------------+

For a table table1 having these example columns:
`test_col3` blob,
`test_col4` char(10) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
`test_col6` binary(1) DEFAULT NULL,
`test_col7` char(20) CHARACTER SET utf8 COLLATE utf8_polish_ci DEFAULT NULL,
`test_col8` varchar(20) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,

mysql [localhost] {msandbox} (test) > ALTER TABLE table1 CHANGE COLUMN test_col3 test_col33 blob;
Query OK, 1479949 rows affected (2 min 17.36 sec)
Records: 1479949  Duplicates: 0  Warnings: 0

mysql [localhost] {msandbox} (test) > ALTER TABLE table1 CHANGE COLUMN test_col6 test_col66 binary(1) DEFAULT NULL;
Query OK, 1479949 rows affected (2 min 21.43 sec)
Records: 1479949  Duplicates: 0  Warnings: 0

mysql [localhost] {msandbox} (test) > ALTER TABLE table1 CHANGE COLUMN test_col4 test_col44 char(10) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL;
Query OK, 1479949 rows affected (1 min 37.26 sec)
Records: 1479949  Duplicates: 0  Warnings: 0

mysql [localhost] {msandbox} (test) > ALTER TABLE table1 CHANGE COLUMN test_col7 test_col77 char(20) CHARACTER SET utf8 COLLATE utf8_polish_ci DEFAULT NULL;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql [localhost] {msandbox} (test) > ALTER TABLE table1 CHANGE COLUMN test_col8 test_col88 varchar(20) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

When I tried to force ALGORITHM=INPLACE explicitly:

mysql [localhost] {msandbox} (test) > ALTER TABLE table1 CHANGE COLUMN test_col3 test_col33 blob, ALGORITHM=INPLACE;
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY.

Except I am not changing the data type, it's still blob as it was before...

I can't see this limitation about binary date types described in documentation.

Suggested fix:
Make online DDL work as expected for binary type columns.
[26 Jun 2013 12:55] Dmitry Lenev
Hello!

Thanks for reporting this issue!

While it might be not very obvious this bug has the same underlying cause as bug #67141 "In-place ALTER TABLE is impossible for BINARY columns". Because of this I am marking this bug as a duplicate of bug #67141. The latter bug was fixed in version 5.7.0.
[27 Jun 2013 16:03] Sinisa Milivojevic
Smaller part of the bug is a duplicate of the already stated bug, but the rest is a new and proper bug that needs to be addressed .
[1 Jul 2013 7:42] Przemyslaw Malkowski
I should also add that not only those column renames require table copy, but also are full blocking ones - any concurrent writes to a table are "Waiting for table metadata lock".
[6 Aug 2013 6:37] Marko Mäkelä
Side note: ALGORITHM=COPY blocking concurrent writes is by design. It is how MySQL worked before version 5.6. (Some earlier versions allowed renaming columns without involving the storage engine, but this caused trouble for InnoDB foreign key constraints. With version 5.6, column renaming will be communicated to the storage engine.)

ALGORITHM=COPY implies LOCK=SHARED (allowing concurrent reads). If you additionally specify LOCK=EXCLUSIVE, it will also block concurrent reads.

The keyword LOCK=NONE requires ALGORITHM=INPLACE. If the operation is refused by ALGORITHM=INPLACE, then LOCK=NONE will not work.

With LOCK=DEFAULT (the default), MySQL will choose the weakest possible locking for ALTER TABLE.
[15 Oct 2013 18:02] Paul Dubois
Noted in 5.6.15 changelog.

For an ALTER TABLE statement that renamed or changed the default
value of a BINARY column, the alteration was done using a table copy
and not in place.

(See also Bug#67141)