0

I am using MySQL 5.6 and I want to modify the default encoding of one table (from latin1 to utf8) WITHOUT modifying the existing columns and rows. Based on documentation I have tried the following command:

ALTER TABLE mytable DEFAULT CHARACTER SET utf8;

It modified the default character set encoding of my table and did NOT modify the collation of the columns, as expected, BUT I was really surprised to see:

Query OK, 32141 rows affected (6.31 sec)
Records: 32141 Duplicates: 0  Warnings: 0

Except "32141 rows affected", the results are as expected as you can see below:

MySQL> select count(*) from mytable;
+----------+
| count(*) |
+----------+
|    32141 |
+----------+
1 row in set (0.01 sec)
MySQL> show table status like 'mytable';
+-----------------------+--------+---------+------------+-------+----------------+-------------+-----------------+--------------+-----------+----------------+-------------+-------------+------------+-----------------+----------+----------------+---------+
| Name                  | Engine | Version | Row_format | Rows  | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation       | Checksum | Create_options | Comment |
+-----------------------+--------+---------+------------+-------+----------------+-------------+-----------------+--------------+-----------+----------------+-------------+-------------+------------+-----------------+----------+----------------+---------+
| mytable               | InnoDB |      10 | Compact    | 16723 |          20798 |   347815936 |               0 |     21561344 |  15728640 |           NULL | NULL        | NULL        | NULL       | utf8_general_ci |     NULL | partitioned    |         |
+-----------------------+--------+---------+------------+-------+----------------+-------------+-----------------+--------------+-----------+----------------+-------------+-------------+------------+-----------------+----------+----------------+---------+

MySQL> show create table mytable;
CREATE TABLE `mytable` (
  `ID` varchar(255) NOT NULL,
  `COL1` double DEFAULT NULL,
  `COL2` longtext CHARACTER SET latin1,
  `COL3` datetime DEFAULT NULL,
  `COL4` varchar(255) CHARACTER SET latin1 DEFAULT NULL,
  `COL5` int(11) DEFAULT NULL,
  `COL6` datetime DEFAULT NULL,
  `COL7` varchar(255) CHARACTER SET latin1 DEFAULT NULL,
  `COL8` datetime(3) NOT NULL,
  `COL9` int(11) NOT NULL DEFAULT '-1',
  `COL10` int(11) DEFAULT '0',
  `COL11` double DEFAULT '0',
  PRIMARY KEY (`ID`,`COL9`),
  KEY `idx1` (`COL7`,`COL3`,`COL6`),
  KEY `idx2` (`COL1`,`COL4`,`COL3`,`COL6`),
  KEY `idx3` (`ID`,`COL3`,`COL6`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (`COL9`)
(PARTITION p0 VALUES LESS THAN (1) ENGINE = InnoDB,
 PARTITION p1 VALUES LESS THAN (2) ENGINE = InnoDB,
 PARTITION p2 VALUES LESS THAN (3) ENGINE = InnoDB,
 PARTITION p3 VALUES LESS THAN (4) ENGINE = InnoDB,
 PARTITION p4 VALUES LESS THAN (5) ENGINE = InnoDB,
 PARTITION p5 VALUES LESS THAN (6) ENGINE = InnoDB,
 PARTITION p6 VALUES LESS THAN (7) ENGINE = InnoDB,
 PARTITION p7 VALUES LESS THAN (8) ENGINE = InnoDB,
 PARTITION p8 VALUES LESS THAN (9) ENGINE = InnoDB,
 PARTITION p9 VALUES LESS THAN (10) ENGINE = InnoDB,
 PARTITION p10 VALUES LESS THAN (11) ENGINE = InnoDB,
 PARTITION p11 VALUES LESS THAN (100) ENGINE = InnoDB,
 PARTITION p12 VALUES LESS THAN (101) ENGINE = InnoDB,
 PARTITION p13 VALUES LESS THAN (102) ENGINE = InnoDB,
 PARTITION p14 VALUES LESS THAN (103) ENGINE = InnoDB,
 PARTITION p15 VALUES LESS THAN (104) ENGINE = InnoDB,
 PARTITION p16 VALUES LESS THAN (105) ENGINE = InnoDB,
 PARTITION p17 VALUES LESS THAN (106) ENGINE = InnoDB,
 PARTITION p18 VALUES LESS THAN (107) ENGINE = InnoDB,
 PARTITION p19 VALUES LESS THAN (108) ENGINE = InnoDB,
 PARTITION p20 VALUES LESS THAN (109) ENGINE = InnoDB,
 PARTITION p21 VALUES LESS THAN (110) ENGINE = InnoDB,
 PARTITION p22 VALUES LESS THAN (111) ENGINE = InnoDB,
 PARTITION p23 VALUES LESS THAN (200) ENGINE = InnoDB,
 PARTITION p24 VALUES LESS THAN (201) ENGINE = InnoDB,
 PARTITION p25 VALUES LESS THAN (202) ENGINE = InnoDB,
 PARTITION p26 VALUES LESS THAN (203) ENGINE = InnoDB,
 PARTITION p27 VALUES LESS THAN (204) ENGINE = InnoDB,
 PARTITION p28 VALUES LESS THAN (205) ENGINE = InnoDB,
 PARTITION p29 VALUES LESS THAN (206) ENGINE = InnoDB,
 PARTITION p30 VALUES LESS THAN (207) ENGINE = InnoDB,
 PARTITION p31 VALUES LESS THAN (208) ENGINE = InnoDB,
 PARTITION p32 VALUES LESS THAN (209) ENGINE = InnoDB,
 PARTITION p33 VALUES LESS THAN (210) ENGINE = InnoDB,
 PARTITION p34 VALUES LESS THAN (211) ENGINE = InnoDB,
 PARTITION p35 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
MySQL> show full columns from mytable;
+--------------------------+--------------+-------------------+------+-----+---------+-------+---------------------------------+---------+
| Field                    | Type         | Collation         | Null | Key | Default | Extra | Privileges                      | Comment |
+--------------------------+--------------+-------------------+------+-----+---------+-------+---------------------------------+---------+
| ID                       | varchar(255) | latin1_swedish_ci | NO   | PRI | NULL    |       | select,insert,update,references |         |
| COL1                     | double       | NULL              | YES  | MUL | NULL    |       | select,insert,update,references |         |
| COL2                     | longtext     | latin1_swedish_ci | YES  |     | NULL    |       | select,insert,update,references |         |
| COL3                     | datetime     | NULL              | YES  |     | NULL    |       | select,insert,update,references |         |
| COL4                     | varchar(255) | latin1_swedish_ci | YES  |     | NULL    |       | select,insert,update,references |         |
| COL5                     | int(11)      | NULL              | YES  |     | NULL    |       | select,insert,update,references |         |
| COL6                     | datetime     | NULL              | YES  |     | NULL    |       | select,insert,update,references |         |
| COL7                     | varchar(255) | latin1_swedish_ci | YES  | MUL | NULL    |       | select,insert,update,references |         |
| COL8                     | datetime(3)  | NULL              | NO   |     | NULL    |       | select,insert,update,references |         |
| COL9                     | int(11)      | NULL              | NO   | PRI | -1      |       | select,insert,update,references |         |
| COL10                    | int(11)      | NULL              | YES  |     | 0       |       | select,insert,update,references |         |
| COL11                    | double       | NULL              | YES  |     | 0       |       | select,insert,update,references |         |
+--------------------------+--------------+-------------------+------+-----+---------+-------+---------------------------------+---------+

My connection parameters are as follows:

MySQL> show variables where variable_name like '%char%' or variable_name like '%collation%';
+--------------------------+--------------------------------------------------+
| Variable_name            | Value                                            |
+--------------------------+--------------------------------------------------+
| character_set_client     | utf8mb4                                          |
| character_set_connection | utf8mb4                                          |
| character_set_database   | utf8mb4                                          |
| character_set_filesystem | binary                                           |
| character_set_results    | utf8mb4                                          |
| character_set_server     | utf8mb4                                          |
| character_set_system     | utf8                                             |
| collation_connection     | utf8mb4_general_ci                               |
| collation_database       | utf8mb4_general_ci                               |
| collation_server         | utf8mb4_general_ci                               |
+--------------------------+--------------------------------------------------+

Note that:

  • data was created from a java application
  • at the time of data creation, the connection parameters were set to utf8
  • there are no FK linked with this table

When I try to reproduce with some newly created tables, it seems that the rows are not modified. See below "0 rows affected":

MySQL> select count(*) from mytesttable;
+----------+
| count(*) |
+----------+
|        3 |
+----------+
3 row in set (0.10 sec)
MySQL> alter table mytesttable character set utf8;
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

I tried to changed my connection parameters back to latin1 during the data creation but it didn't change the result: still "0 rows affected".

So my questions:

  1. Is my understanding of the command correct? (that it shouldn't modify the rows)
  2. What could explain that the rows are affected in the 1st case?

EDIT

I have just found out that the problem doesn't happen if I remove the partition.

  1. With partition I get "XXX affected rows"
  2. Without partition I get "0 affected rows"

Is it expected?

EDIT 2 with SUMMARY

Initially:

  1. The table was using latin1 as default encoding (same for the columns)
  2. The connection was declared as utf8

What works:

  1. Before any ALTER TABLE command, characters like "é" seem to be latin1 encoded (E9)
  2. Running command ALTER TABLE mytable CHARACTER SET utf8mb4; does not modify the data (hex command still shows E9) The column is still declared latin1.
  3. Running command ALTER TABLE mytable MODIFY COL2 LONGTEXT CHARACTER SET utf8mb4 changes the column to utf8mb4 (C3A9)

So far so good.

Remaining questions:

  1. How to make sure that all data present in the table is latin1? I have tried SELECT COL2 FROM mytable WHERE LENGTH(COL2) != CHAR_LENGTH(COL2) LIMIT 1 and I got 0 results. Is it enough?
  2. Why the command ALTER TABLE mytable CHARACTER SET utf8mb4; shows "32141 rows affected" when it seems that the data is not modified? (it happens when the table has partitions and index on the same column)
  3. Following the previous point, is it safe (needed?) to also change the default encoding of the table? Or shall I just stick to the modification of the columns?

Thanks a lot for your help

D3nsk
  • 131
  • 2
  • 13
  • Does the data actually appear to be changed? – deceze Jul 05 '19 at 08:00
  • Hi @deceze and thanks for taking the time. It doesn't seem to be changed but I'm not sure I tried the good commands. I tried `select * from mytable limit 1;` and `select hex(COL1), hex(COL2)... from mytable limit 1;` on both the backup and the modified tables and I got the same result on both. I also tried the command mentioned [here](https://stackoverflow.com/questions/9304485/how-to-detect-utf-8-characters-in-a-latin1-encoded-column-mysql) but it gives me no result – D3nsk Jul 05 '19 at 08:48
  • In `mytesttable`, were any of the columns `CHAR` or `TEXT`? What did `SHOW CREATE TABLE mytesttable` say _before_ the `ALTER`? – Rick James Jul 05 '19 at 18:52
  • Do you perceive any benefit from `PARTITIONing`? (I doubt it.) – Rick James Jul 05 '19 at 18:53
  • Let's see the `HEX()` for one cell with accented letters. You may have "double encoding" and not realize it. – Rick James Jul 05 '19 at 18:56
  • Hi @RickJames and thanks for taking the time. `mytesttable` has the same structure as the previous one. For the partitioning, this is not an option, I need to keep it. When I try with accents ("éléments") the hex value is not modified after the `alter table mytable character set utf8;` but it is modified after `alter table mytable modify COL2 longtext character set utf8;` As far as I understand this is expected. But then I still don't know why mysql is telling me "1 row modified" after the 1st command – D3nsk Jul 08 '19 at 02:06
  • @D3nsk - `é` in latin1 is `E9`; in utf8/utf8mb4: `C3A9`; "double encoded" `C383C2A9`. Which hex do you see? – Rick James Jul 08 '19 at 03:41
  • @RickJames before `alter ... modify` command I see the utf8/utf8mb4 encoding (`C3A9`) and after the command I see the "double encoded" `C383C2A9`. Before: `C3A96CC3A96D656E7473` After: `C383C2A96CC383C2A96D656E7473` – D3nsk Jul 08 '19 at 03:45
  • @RickJames why is it initially already encoded as utf8/utf8mb4? My table has default charset latin1 and I have set `set NAMES latin1;`. Is it because of the `character_set_system = utf8`? – D3nsk Jul 08 '19 at 04:15
  • @D3nsk - I edited your "What works" section; please verify that what I said agrees with what you see. – Rick James Jul 08 '19 at 14:06
  • @RickJames yes that's correct, the data doesn't seem modified at step 2 but is modified at step 3 as expected. That's why I don't understand why mysql is showing "32141 rows affected" at step 2, during `ALTER TABLE mytable CHARACTER SET utf8mb4;`. Not sure if it is just a wrong output. – D3nsk Jul 09 '19 at 01:27

1 Answers1

2

You had a mess, and the ALTER made the mess worse.

To start with, the table columns were declared latin1 and the connection declared that the client was using latin1 (via SET NAMES latin1). That would have been fine if é had actually been hex E9 in the client. But the data in the client was UTF-8. So é was the two bytes C3A9 was sent to the database as 2 latin1 characters. The damage was not noticeable, because it was reversed when you SELECTed.

The later step messed things up by treating each of those bytes as latin1 and converting them to utf8, hence "double" encoding.

See "Mojibake" and "double encoding" in Trouble with UTF-8 characters; what I see is not what I stored . If you want to try to recover the data, see the appropriate case in http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases

Well, apparently ALTER TABLE mytable DEFAULT CHARACTER SET utf8; was not just changing the default, but was copying the table over, and in doing so, introducing the double encoding.

I have been chasing MySQL charset problems for over a decade. This is a new wrinkle that I had not yet observed.

I'm pretty sure that character_set_system is not involved in your problem. (But I could be wrong!)

Wrong SET NAMES

Test case:

CREATE TABLE mytest ( MYDATA longtext ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
SET NAMES latin1;
INSERT INTO mytest VALUES ( "é" );
SELECT MYDATA, HEX(MYDATA) FROM mytest;

Running that test case:

mysql> SET NAMES latin1;

mysql> SHOW CREATE TABLE mytest\G
*************************** 1. row ***************************
       Table: mytest
Create Table: CREATE TABLE `mytest` (
  `MYDATA` longtext
) ENGINE=InnoDB DEFAULT CHARSET=latin1

mysql> INSERT INTO mytest VALUES ( "é" );

mysql> SELECT MYDATA, HEX(MYDATA), LENGTH(MYDATA),
              CHAR_LENGTH(MYDATA) FROM mytest;
+--------+-------------+----------------+---------------------+
| MYDATA | HEX(MYDATA) | LENGTH(MYDATA) | CHAR_LENGTH(MYDATA) |
+--------+-------------+----------------+---------------------+
| é      | C3A9        |              2 |                   2 |
+--------+-------------+----------------+---------------------+

The character looks fine. But the HEX looks like UTF-8, not latin1. And the CHAR_LENGTH is "wrong".

The case is: CHARACTER SET latin1, but utf8 bytes are in it. To leave bytes alone while fixing charset:

Then to convert the column without changing the bytes:

ALTER TABLE tbl MODIFY COLUMN MYDATA LONGBLOB;
ALTER TABLE tbl MODIFY COLUMN MYDATA LONGTEXT CHARACTER SET utf8mb4;

(Be sure to have all the attributes that you originally had, such as NOT NULL.)

This is the "2-step ALTER", as discussed in http://mysql.rjweb.org/doc.php/charcoll .) (Be sure to keep the other specifications the same - VARCHAR, NOT NULL, etc.)

Partition Test case:

DROP TABLE IF EXISTS ptest;
CREATE TABLE ptest (
        nn INT NOT NULL,
        ee LONGTEXT
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1
    PARTITION BY RANGE (nn)
        (PARTITION p0 VALUES LESS THAN (1),
         PARTITION p1 VALUES LESS THAN MAXVALUE);
SET NAMES latin1;
INSERT INTO ptest (nn, ee)  VALUES ( 0, "é" ), ( 1, "ü" );
SELECT nn, ee, HEX(ee), LENGTH(ee), CHAR_LENGTH(ee) FROM ptest;
ALTER TABLE ptest
    DEFAULT CHARSET utf8;
SELECT nn, ee, HEX(ee), LENGTH(ee), CHAR_LENGTH(ee) FROM ptest;
SELECT @@version;
SHOW CREATE TABLE ptest\G

Partition results:

mysql>     DROP TABLE IF EXISTS ptest;
Query OK, 0 rows affected (0.02 sec)

mysql>     CREATE TABLE ptest (
    ->             nn INT NOT NULL,
    ->             ee LONGTEXT
    ->         ) ENGINE=InnoDB DEFAULT CHARSET=latin1
    ->         PARTITION BY RANGE (nn)
    ->             (PARTITION p0 VALUES LESS THAN (1),
    ->              PARTITION p1 VALUES LESS THAN MAXVALUE);
Query OK, 0 rows affected (0.03 sec)

mysql>     SET NAMES latin1;
Query OK, 0 rows affected (0.00 sec)

mysql>     INSERT INTO ptest (nn, ee)  VALUES ( 0, "é" ), ( 1, "ü" );
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql>     SELECT nn, ee, HEX(ee), LENGTH(ee), CHAR_LENGTH(ee) FROM ptest;
+----+------+---------+------------+-----------------+
| nn | ee   | HEX(ee) | LENGTH(ee) | CHAR_LENGTH(ee) |
+----+------+---------+------------+-----------------+
|  0 | é    | C3A9    |          2 |               2 |
|  1 | ü    | C3BC    |          2 |               2 |
+----+------+---------+------------+-----------------+
2 rows in set (0.00 sec)

mysql>     ALTER TABLE ptest
    ->         DEFAULT CHARSET utf8;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql>     SELECT nn, ee, HEX(ee), LENGTH(ee), CHAR_LENGTH(ee) FROM ptest;
+----+------+---------+------------+-----------------+
| nn | ee   | HEX(ee) | LENGTH(ee) | CHAR_LENGTH(ee) |
+----+------+---------+------------+-----------------+
|  0 | é    | C3A9    |          2 |               2 |
|  1 | ü    | C3BC    |          2 |               2 |
+----+------+---------+------------+-----------------+
2 rows in set (0.00 sec)

mysql>     SELECT @@version;
+-----------------+
| @@version       |
+-----------------+
| 5.6.22-71.0-log |
+-----------------+
1 row in set (0.00 sec)

mysql>     SHOW CREATE TABLE ptest\G
*************************** 1. row ***************************
       Table: ptest
Create Table: CREATE TABLE `ptest` (
  `nn` int(11) NOT NULL,
  `ee` longtext CHARACTER SET latin1
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (nn)
(PARTITION p0 VALUES LESS THAN (1) ENGINE = InnoDB,
 PARTITION p1 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
1 row in set (0.00 sec)

Hmmm... I don't see the ALTER problem. What version are you using? Do you see the problem with this test case?

Rick James
  • 135,179
  • 13
  • 127
  • 222
  • the `ALTER TABLE mytable DEFAULT CHARACTER SET utf8;` doesn't change the hex value. This is the `ALTER TABLE ... MODIFY COL2 ...` that changed the hex value. I have tried one more time with `set NAMES utf8` first. In this case I get: `E96CE96D656E7473` (latin1) before any `ALTER` command, still `E96CE96D656E7473` (latin1) after the `ALTER TABLE mytable DEFAULT CHARACTER SET utf8;` and `C3A96CC3A96D656E7473` (utf8) after the `ALTER TABLE mytable MODIFY COL2 LONGTEXT CHARACTER SET utf8;` – D3nsk Jul 08 '19 at 07:10
  • I have edited the main post to summarize the current situation and ask the remaining questions – D3nsk Jul 08 '19 at 08:32
  • @D3nsk - The important thing to check is whether the encoding (E9 vs C3A9) agrees with the character set of the _column_ (latin1 vs utf8/utf8mb4). I sensed that they were getting out of sync, but your Comment implies that they are not. – Rick James Jul 08 '19 at 14:14
  • @D3nsk - Could you build a 1-row table with all the create table, sets, select hex, alters, etc, to demonstrate the problem? That would make it easier for me to test out theories. And, assuming there is a real bug lurking somewhere, it would provide proof for submitting a bug report. – Rick James Jul 08 '19 at 14:17
  • The encoding seems to be in line with the column for now. They were not in sync when I performed the following operations: `set NAMES latin1;` then `INSERT INTO ... "éléments"...` then `ALTER TABLE mytable MODIFY COL2 LONGTEXT CHARACTER SET utf8;`. But in my initial use case, the connection encoding was declared as utf8 not latin1 (sorry I made things confusing in my previous post). – D3nsk Jul 08 '19 at 14:37
  • @D3nsk - can you provide the exact list of `CREATE TABLE; SET NAMES; INSERT; SELECT HEX; ALTER; SELECT HEX` that demonstrates the "not in sync". – Rick James Jul 08 '19 at 14:40
  • 1) `set NAMES latin1;` 2) `show variables like 'character_set%';` (character_set_client=latin1, character_set_connection=latin1, character_set_database=latin1, character_set_filesystem=binary, character_set_results=latin1, character_set_server=utf8mb4, character_set_system=utf8) 3) `create table mytest ( MYDATA longtext default null ) engine=InnoDB default character set=latin1;` 4) `insert into mytest ( "é" );` 5) `select hex(MYDATA) from mytest;` shows `C3A9` (utf8 instead of latin1) – D3nsk Jul 08 '19 at 15:25
  • @D3nsk - This is the trap that people get into. The problem is that "é" in your _client_ is utf8 (C3A9). However, you _said_ that the _client_ is latin1 via `SET NAMES latin1;`. `SET NAMES` _must_ match the encoding in the client, but there is _no_ obvious error until much farther down the road. – Rick James Jul 08 '19 at 15:49
  • (That does not get to the ALTER problem, but it is a problem that needs addressing.) – Rick James Jul 08 '19 at 15:51
  • Okay I understand the first part, thank you. My client is _actually_ sending utf8 encoded characters. But because I _declare_ the encoding of the client as latin1, mysql takes the received characters as latin1 characters and simply insert them in db. – D3nsk Jul 08 '19 at 15:56
  • Now for the `ALTER TABLE mytable DEFAULT CHARACTER SET utf8;` it is still not clear what is happening. Based on the tests you asked me to perform, it seems that the data is not modified. Yet mysql shows "32141 rows affected". This only happens when the table has partitions. Do you have any idea? – D3nsk Jul 08 '19 at 15:59
  • @D3nsk - I added the test case into my Answer, plus a reference to my blog. Tweaking the test to have minimal `PARTITIONing` could allow for your bug to show? – Rick James Jul 08 '19 at 16:09
  • I was able to reproduce by creating an index on "nn": `CREATE TABLE ptest ( nn int NOT NULL, ee longtext, KEY idx1 (nn) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 PARTITION BY RANGE (nn) (PARTITION p0 VALUES LESS THAN (1), PARTITION p1 VALUES LESS THAN MAXVALUE ENGINE = InnoDB);` (need both the partition and the index/primary key). In this case, `ALTER TABLE ptest DEFAULT CHARSET utf8;` shows "2 rows affected". Yet the result of `SELECT nn, ee, HEX(ee), LENGTH(ee), CHAR_LENGTH(ee) FROM ptest;` remains the same. `select @@version;` returns `5.6.10-log`. `set NAMES xxx` doesn't seem to matter here – D3nsk Jul 09 '19 at 01:13
  • @D3nsk - So, the original problem and this 'simple' test case have something different that is leading to different results? Tweak one toward the other until you isolate what is causing the problem. – Rick James Jul 09 '19 at 22:43
  • The difference between what you wrote and my test is the index. I added an index on "nn". The rest is the same. With this I could get the weird behavior of the `alter table ptest default charset utf8;` command (showing "affected rows") – D3nsk Jul 10 '19 at 01:46
  • Without the index or without the partition I don't experience the problem. I need both to see the issue – D3nsk Jul 10 '19 at 01:53
  • @D3nsk - I tested on 5.6.22 and did not see rows affected=2. Your 5.6.10 dates back to early 2013; it is time to upgrade. I did not spot anything in the changelogs that looked like a fix. – Rick James Jul 10 '19 at 03:35
  • Thanks a lot for your time and effort. I agree 5.6.10 is an old version. I upvote your answer because it was really helpful. I keep the ticket open in case someone knows why mysql 5.6.10 is showing "affected rows" in this case. – D3nsk Jul 11 '19 at 06:50