[MDEV-14837] Duplicate primary keys are allowed after ADD COLUMN / UPDATE Created: 2018-01-01  Updated: 2018-01-15  Resolved: 2018-01-09

Status: Closed
Project: MariaDB Server
Component/s: Data Definition - Alter Table, Storage Engine - InnoDB
Affects Version/s: 10.3.2
Fix Version/s: 10.3.4

Type: Bug Priority: Critical
Reporter: Elena Stepanova Assignee: Marko Mäkelä
Resolution: Fixed Votes: 0
Labels: instant, regression

Issue Links:
Blocks
blocks MDEV-14840 Assertion `!log->same_pk' failed in r... Closed
Duplicate
is duplicated by MDEV-14473 Assertion `rec_get_trx_id(rec, clust_... Closed
is duplicated by MDEV-14897 After UPDATE of instant ADD COLUMN, P... Closed
Problem/Incident
is caused by MDEV-11369 Instant add column for InnoDB Closed
Relates
relates to MDEV-14068 Assertion `0' failed in row_sel_get_c... Closed

 Description   

--source include/have_innodb.inc
 
CREATE TABLE t1 (pk VARCHAR(3) PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 VALUES ('foo');
ALTER TABLE t1 ADD COLUMN f INT;
UPDATE t1 SET f = 1;
--error ER_DUP_ENTRY
INSERT INTO t1 VALUES ('foo',NULL);
 
# Cleanup
DROP TABLE t1;

The test fails on INSERT, because it actually succeeds instead of producing the expected ER_DUP_ENTRY.



 Comments   
Comment by Marko Mäkelä [ 2018-01-09 ]

The bug does not seem to affect ROW_FORMAT=REDUNDANT tables or PRIMARY KEY on fixed-length columns. VARCHAR(1) is the simplest key with which I reproduced the corruption.

Comment by Marko Mäkelä [ 2018-01-09 ]

The condition in the function row_ins_clust_index_entry_low() to check for duplicates fails to hold, because up_match=low_match=0:

	if (n_uniq
	    && (cursor->up_match >= n_uniq || cursor->low_match >= n_uniq)) {

The bug is that the length of the PRIMARY KEY column is being read from the wrong offset here:

	case REC_LEAF_COLUMNS_ADDED:
		/* We would have !index->is_instant() when rolling back
		an instant ADD COLUMN operation. */
		nulls -= REC_N_NEW_EXTRA_BYTES;
		if (rec_offs_n_fields(offsets) <= n_fields) {
			goto ordinary;
		}
		/* fall through */

If I manually set nulls-- then the correct length will be returned and the duplicate will be returned.
Due to the bug, we are reading the incorrect length 0 from the incorrect offset.

Generated at Thu Feb 08 08:16:40 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.