Bug #83045 Unique index allows duplicates without null values

Submitted: 20 Sep 2016 7:11 Modified: 20 Sep 2016 8:55
Reporter: peter kim Email Updates:
Status: Duplicate Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S2 (Serious)
Version:5.6.17 OS:CentOS (6.5)
Assigned to: CPU Architecture:Any
Tags: duplicates, unique

[20 Sep 2016 7:11] peter kim
Description:
I experienced a situation that a compound unique index allowed duplicates without null values.  

The situation is like the following description. 

## isolation-level
- read-committed

## the related table 

CREATE TABLE `coupon_use_log` (
   `coupon_use_log_seq` bigint(20) NOT NULL AUTO_INCREMENT ,
   `coupon_type` varchar(1) NOT NULL ,
   `coupon_id` varchar(100) NOT NULL ,
   `use_cnt` int(11) NOT NULL ,
   `promotion_seq` int(11) NOT NULL ,
   `event_seq` int(11) NOT NULL ,
   `print_seq` int(11) NOT NULL ,
   `game_ssn` int(11) NOT NULL ,
   `game_world` varchar(100) NOT NULL,
   `game_usn` varchar(30) NOT NULL ,
   `platform_type` int(11) NOT NULL DEFAULT '0',
   `platform_usn` varchar(50) NOT NULL,
   `reg_date` datetime NOT NULL ,
   PRIMARY KEY (`coupon_use_log_seq`),
   UNIQUE KEY `idx_COUPON_USE_LOG_01` (`coupon_id`,`use_cnt`,`event_seq`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

## three transactions on the same unique key record of the same table 

1) An administrator's transaction to modify a column value of a record.  

start at : 160917 12:17:17
end   at : 160917 12:17:34

### UPDATE `coupondb`.`coupon_use_log`
### WHERE
###   @1=739218 /* LONGINT meta=0 nullable=0 is_null=0 */
### SET
###   @4=26547 /* INT meta=0 nullable=0 is_null=0 */

2) service transaction 1 ( insert to same table at 1) )

start at : 160917 12:17:25
end   at : 160917 12:17:34

INSERT INTO `coupondb`.`coupon_use_log` ( coupon_use_log_seq = 745661 )

## binlog 

#160917 12:17:25 server id 2801  end_log_pos 452822143 CRC32 0xca82151b         Write_rows: table id 224 flags: STMT_END_F

BINLOG '
xbXcVxPxCgAAVQAAABSE/RoAAOAAAAAAAAEACGNvdXBvbmRiAA5jb3Vwb25fdXNlX2xvZwANCA8P
AwMDAwMPDwMPEgsDACwBLAFaAJYAAAAAlUJATg==
xbXcVx7xCgAAawAAAH+E/RoAAOAAAAAAAAEAAgAN/x8A4L1gCwAAAAAAAVMQAGp1c3Rvbmx5MW1z
bDA5MDe0ZwAApwEAAAQEAAABAAAA7gMAAAEAMQYxOTMxMTgEAAAAATCZmmLEWBsVgso=
'/*!*/;
### INSERT INTO `coupondb`.`coupon_use_log`
### SET
###   @1=745661 /* LONGINT meta=0 nullable=0 is_null=0 */
###   @2='S' /* VARSTRING(3) meta=3 nullable=0 is_null=0 */
###   @3='abcd0907' /* VARSTRING(300) meta=300 nullable=0 is_null=0 */
###   @4=26548 /* INT meta=0 nullable=0 is_null=0 */
###   @5=423 /* INT meta=0 nullable=0 is_null=0 */
###   @6=1028 /* INT meta=0 nullable=0 is_null=0 */
###   @7=1 /* INT meta=0 nullable=0 is_null=0 */
###   @8=1006 /* INT meta=0 nullable=0 is_null=0 */
###   @9='1' /* VARSTRING(300) meta=300 nullable=0 is_null=0 */
###   @10='193118' /* VARSTRING(90) meta=90 nullable=0 is_null=0 */
###   @11=4 /* INT meta=0 nullable=0 is_null=0 */
###   @12='0' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
###   @13='2016-09-17 12:17:24' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
# at 452822143
#160917 12:17:34 server id 2801  end_log_pos 452822174 CRC32 0x553d9dbc         Xid = 2001479752
COMMIT/*!*/;

3) service transaction 2 ( insert to same table at 1) and 2) )

start at : 160917 12:17:34
end   at : 160917 12:17:34

INSERT INTO `coupondb`.`coupon_use_log` ( coupon_use_log_seq = 745663 ) 

## binlog 

#160917 12:17:34 server id 2801  end_log_pos 452822575 CRC32 0xc1c78e2e         Write_rows: table id 224 flags: STMT_END_F

BINLOG '
zrXcVxPxCgAAVQAAAMOF/RoAAOAAAAAAAAEACGNvdXBvbmRiAA5jb3Vwb25fdXNlX2xvZwANCA8P
AwMDAwMPDwMPEgsDACwBLAFaAJYAAAAAsizyzQ==
zrXcVx7xCgAAbAAAAC+G/RoAAOAAAAAAAAEAAgAN/x8A4L9gCwAAAAAAAVMQAGp1c3Rvbmx5MW1z
bDA5MDe0ZwAApwEAAAQEAAABAAAA7gMAAAEAMQcxNDA3OTc1BwAAAAEwmZpixGEujsfB
'/*!*/;
### INSERT INTO `coupondb`.`coupon_use_log`
### SET
###   @1=745663 /* LONGINT meta=0 nullable=0 is_null=0 */
###   @2='S' /* VARSTRING(3) meta=3 nullable=0 is_null=0 */
###   @3='abcd0907' /* VARSTRING(300) meta=300 nullable=0 is_null=0 */
###   @4=26548 /* INT meta=0 nullable=0 is_null=0 */
###   @5=423 /* INT meta=0 nullable=0 is_null=0 */
###   @6=1028 /* INT meta=0 nullable=0 is_null=0 */
###   @7=1 /* INT meta=0 nullable=0 is_null=0 */
###   @8=1006 /* INT meta=0 nullable=0 is_null=0 */
###   @9='1' /* VARSTRING(300) meta=300 nullable=0 is_null=0 */
###   @10='1407975' /* VARSTRING(90) meta=90 nullable=0 is_null=0 */
###   @11=7 /* INT meta=0 nullable=0 is_null=0 */
###   @12='0' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
###   @13='2016-09-17 12:17:33' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
# at 452822575
#160917 12:17:34 server id 2801  end_log_pos 452822606 CRC32 0x05b83287         Xid = 2001482217
COMMIT/*!*/;

## Detail description for the above situation

1) transaction was started earlier than 2) and 3) and tried to update a record of the table coupon_use_log
update coupon_use_log set use_cnd = 26547   
where  coupon_id = 'abcd0907' and use_cnt=26548 and event_seq=1028;

(`coupon_id`,`use_cnt`,`event_seq`) is a unique key of the table coupon_use_log

before the first transaction was committed. the second transaction was started to insert a row into a table coupon_use_log with following values for unique index columns => coupon_id = 'abcd0907' , use_cnt=26548, event_seq=1028;
( you can see the complete insert statment by above binlog ) 
this transaction had to wait to get the lock that the first transaction was holding exclusive for update.

when the first transaction was committed ( the second transaction is automatically committed right after the first is done ), at the same time the third transaction was started to insert a row into a table coupon_use_log with following values for unique index columns => coupon_id = 'abcd0907' , use_cnt=26548, event_seq=1028;
( you can see the complete insert statment by above binlog ) 

In normal situation, the third transaction must fail because it tried insert statement with same unique key values with transaction 2 insert statement. 

but the transaction 2) and 3) were successfully done. 
And the slave was stopped with an unique key duplicate error.  

it must not happen in any situation. :(
 

How to repeat:
I can't repeat.
[20 Sep 2016 8:55] MySQL Verification Team
Hello peter kim,

Thank you for the report.
This is most likely duplicate of Bug #73170, Please see Bug #73170

Thanks,
Umesh

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.051 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.