mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-31 10:56:12 +01:00 
			
		
		
		
	 5f206259e5
			
		
	
	
	5f206259e5
	
	
	
		
			
			The bug is inherent for row-based replication as well. To reproduce, a virtual (not stored) field of a blob type computed from another field of a different blob type is required. The following happens during an update or delete row event: 1. A row is unpacked. 2. Virtual fields are updated. Field b1 stores the pointer in Field_blob::value and references it in table->record[0]. 3. record[0] is stored to record[1] in Rows_log_event::find_row. 4. A new record is fetched from handler. (e.g. ha_rnd_next) 5. Virtual columns are updated (only non-stored). 6. Field b1 receives new value. Old value is deallocated (Field_blob::val_str). 7. record_compare is called. record[0] and record[1] are compared. 8. record[1] contains a reference to a freed value. record_compare is used in replication to find a matching record for update or delete. Virtual columns that are not stored should be definitely skipped both for correctness, and for this bug fix. STORED virtual columns, on the other hand, may be required and shouldn't be skipped. Stored columns are not affected, since they are not updated after handler's fetch.
		
			
				
	
	
		
			178 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			178 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| include/master-slave.inc
 | |
| [connection master]
 | |
| connection master;
 | |
| DROP TABLE IF EXISTS test.t1;
 | |
| DROP TABLE IF EXISTS test.t2;
 | |
| *****  Table Create Section ****
 | |
| 
 | |
| CREATE TABLE test.t1 (c1 int not null auto_increment, 
 | |
| data LONGBLOB, PRIMARY KEY(c1))ENGINE=#;
 | |
| 
 | |
| **** Data Insert Section test.t1 *****
 | |
| 
 | |
| INSERT INTO test.t1 VALUES (NULL, NULL);
 | |
| INSERT INTO test.t1 VALUES (NULL, repeat('a',1*1024));
 | |
| INSERT INTO test.t1 VALUES (NULL, repeat('b',16*1024));
 | |
| 
 | |
| **** Data Insert Validation Master Section test.t1 ****
 | |
| 
 | |
| SELECT LENGTH(data) FROM test.t1 WHERE c1 = 1;
 | |
| LENGTH(data)
 | |
| NULL
 | |
| SELECT LENGTH(data) FROM test.t1 WHERE c1 = 2;
 | |
| LENGTH(data)
 | |
| 1024
 | |
| SELECT LENGTH(data) FROM test.t1 WHERE c1 = 3;
 | |
| LENGTH(data)
 | |
| 16384
 | |
| connection slave;
 | |
| 
 | |
| **** Data Insert Validation Slave Section test.t1 ****
 | |
| 
 | |
| SELECT LENGTH(data) FROM test.t1 WHERE c1 = 1;
 | |
| LENGTH(data)
 | |
| NULL
 | |
| SELECT LENGTH(data) FROM test.t1 WHERE c1 = 2;
 | |
| LENGTH(data)
 | |
| 1024
 | |
| SELECT LENGTH(data) FROM test.t1 WHERE c1 = 3;
 | |
| LENGTH(data)
 | |
| 16384
 | |
| connection master;
 | |
| 
 | |
| **** Data Update Section test.t1 ****
 | |
| 
 | |
| UPDATE test.t1 set data=repeat('a',18*1024) where c1 = 1;
 | |
| UPDATE t1 set data=repeat('c',17*1024) where c1 = 2;
 | |
| 
 | |
| **** Data Update Validation Master Section test.t1 ****
 | |
| 
 | |
| SELECT LENGTH(data) FROM test.t1 WHERE c1 = 1;
 | |
| LENGTH(data)
 | |
| 18432
 | |
| SELECT LENGTH(data) FROM test.t1 WHERE c1 = 2;
 | |
| LENGTH(data)
 | |
| 17408
 | |
| connection slave;
 | |
| 
 | |
| **** Data Update Validation Slave Section test.t1 ****
 | |
| 
 | |
| SELECT LENGTH(data) FROM test.t1 WHERE c1 = 1;
 | |
| LENGTH(data)
 | |
| 18432
 | |
| SELECT LENGTH(data) FROM test.t1 WHERE c1 = 2;
 | |
| LENGTH(data)
 | |
| 17408
 | |
| connection master;
 | |
| 
 | |
| **** End Test Section test.t1 ****
 | |
| 
 | |
| **** Create Table test.t2 ****
 | |
| 
 | |
| CREATE TABLE test.t2 (
 | |
| c1 INT NOT NULL PRIMARY KEY,
 | |
| c2 TEXT,
 | |
| c3 INT,
 | |
| c4 LONGBLOB,
 | |
| KEY(c3))ENGINE=#;
 | |
| 
 | |
| *** Setup Values For test.t2 ***
 | |
| set @x0 = '01234567012345670123456701234567';
 | |
| set @x0 = concat(@x0,@x0,@x0,@x0,@x0,@x0,@x0,@x0);
 | |
| set @b1 = 'b1';
 | |
| set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1);
 | |
| set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1);
 | |
| set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1);
 | |
| set @b1 = concat(@b1,@x0);
 | |
| set @d1 = 'dd1';
 | |
| set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1);
 | |
| set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1);
 | |
| set @d1 = concat(@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1,@d1);
 | |
| set @b2 = 'b2';
 | |
| set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2);
 | |
| set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2);
 | |
| set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2);
 | |
| set @b2 = concat(@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2,@b2);
 | |
| set @d2 = 'dd2';
 | |
| set @d2 = concat(@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2);
 | |
| set @d2 = concat(@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2);
 | |
| set @d2 = concat(@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2);
 | |
| set @d2 = concat(@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2,@d2);
 | |
| 
 | |
| **** Data Insert Section test.t2 *****
 | |
| 
 | |
| INSERT INTO test.t2 VALUES(1,@b1,111,@d1);
 | |
| INSERT INTO test.t2 VALUES(2,@b2,222,@d2);
 | |
| 
 | |
| **** Data Insert Validation Master Section test.t2 ****
 | |
| 
 | |
| SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3)
 | |
| FROM test.t2 WHERE c1=1;
 | |
| c1	LENGTH(c2)	SUBSTR(c2,1+2*900,2)	LENGTH(c4)	SUBSTR(c4,1+3*900,3)
 | |
| 1	2256	b1	3000	dd1
 | |
| SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3)
 | |
| FROM test.t2 WHERE c1=2;
 | |
| c1	LENGTH(c2)	SUBSTR(c2,1+2*900,2)	LENGTH(c4)	SUBSTR(c4,1+3*900,3)
 | |
| 2	20000	b2	30000	dd2
 | |
| connection slave;
 | |
| 
 | |
| **** Data Insert Validation Slave Section test.t2 ****
 | |
| 
 | |
| SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3)
 | |
| FROM test.t2 WHERE c1=1;
 | |
| c1	LENGTH(c2)	SUBSTR(c2,1+2*900,2)	LENGTH(c4)	SUBSTR(c4,1+3*900,3)
 | |
| 1	2256	b1	3000	dd1
 | |
| SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3)
 | |
| FROM test.t2 WHERE c1=2;
 | |
| c1	LENGTH(c2)	SUBSTR(c2,1+2*900,2)	LENGTH(c4)	SUBSTR(c4,1+3*900,3)
 | |
| 2	20000	b2	30000	dd2
 | |
| connection master;
 | |
| 
 | |
| **** Data Update Section test.t2 ****
 | |
| 
 | |
| UPDATE test.t2 SET c2=@b2, c4=@d2 WHERE c1=1;
 | |
| UPDATE test.t2 SET c2=@b1, c4=@d1 WHERE c1=2;
 | |
| 
 | |
| **** Data Update Validation Master Section test.t2 ****
 | |
| 
 | |
| SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3)
 | |
| FROM test.t2 WHERE c1=1;
 | |
| c1	LENGTH(c2)	SUBSTR(c2,1+2*900,2)	LENGTH(c4)	SUBSTR(c4,1+3*900,3)
 | |
| 1	20000	b2	30000	dd2
 | |
| SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3)
 | |
| FROM test.t2 WHERE c1=2;
 | |
| c1	LENGTH(c2)	SUBSTR(c2,1+2*900,2)	LENGTH(c4)	SUBSTR(c4,1+3*900,3)
 | |
| 2	2256	b1	3000	dd1
 | |
| connection slave;
 | |
| 
 | |
| **** Data Update Validation Slave Section test.t2 ****
 | |
| 
 | |
| SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3)
 | |
| FROM test.t2 WHERE c1=1;
 | |
| c1	LENGTH(c2)	SUBSTR(c2,1+2*900,2)	LENGTH(c4)	SUBSTR(c4,1+3*900,3)
 | |
| 1	20000	b2	30000	dd2
 | |
| SELECT c1, LENGTH(c2), SUBSTR(c2,1+2*900,2), LENGTH(c4), SUBSTR(c4,1+3*900,3)
 | |
| FROM test.t2 WHERE c1=2;
 | |
| c1	LENGTH(c2)	SUBSTR(c2,1+2*900,2)	LENGTH(c4)	SUBSTR(c4,1+3*900,3)
 | |
| 2	2256	b1	3000	dd1
 | |
| connection master;
 | |
| 
 | |
| DROP TABLE IF EXISTS test.t1;
 | |
| DROP TABLE IF EXISTS test.t2;
 | |
| connection slave;
 | |
| #
 | |
| # MDEV-30985 Replica stops with error on ALTER ONLINE with Geometry Types
 | |
| #
 | |
| connection master;
 | |
| CREATE TABLE t(txt TEXT DEFAULT '111111111', blb LONGBLOB AS (txt));
 | |
| INSERT INTO t () VALUES (),(),();
 | |
| DELETE FROM t;
 | |
| DROP TABLE t;
 | |
| connection slave;
 | |
| connection master;
 | |
| CREATE TABLE t(txt TEXT DEFAULT '111111111', blb LONGBLOB AS (txt) STORED);
 | |
| INSERT INTO t () VALUES (),(),();
 | |
| DELETE FROM t;
 | |
| DROP TABLE t;
 | |
| connection slave;
 | |
| include/rpl_end.inc
 |