[MDEV-15821] Row format replication from LONGBLOB COMPRESSED to LONGBLOB does not work Created: 2018-04-09  Updated: 2018-04-10  Resolved: 2018-04-10

Status: Closed
Project: MariaDB Server
Component/s: Data types, Replication
Affects Version/s: 10.3
Fix Version/s: 10.3.6

Type: Bug Priority: Major
Reporter: Alexander Barkov Assignee: Alexander Barkov
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to MDEV-15833 Row format replication between LONGBL... Closed

 Description   

I create a test file with this content:

-- source include/have_binlog_format_row.inc
-- source include/master-slave.inc
 
connection master;
 
let mst=LONGBLOB COMPRESSED;
let slv=MEDIUMBLOB;
let cnv='ALL_LOSSY';
 
# This is to make sure that the compressed data is longer than 64K
SET column_compression_threshold=16*256*256;
 
--eval CREATE TABLE t1 (a $mst);
 
sync_slave_with_master;
connection slave;
SET @tmp=@@GLOBAL.SLAVE_TYPE_CONVERSIONS;
eval SET GLOBAL SLAVE_TYPE_CONVERSIONS = $cnv;
--eval ALTER TABLE t1 MODIFY a $slv;
 
connection master;
INSERT INTO t1 (a) VALUES (REPEAT('a',256*256));
SELECT LENGTH(a) FROM t1;
 
sync_slave_with_master;
SHOW CREATE TABLE t1;
SELECT LENGTH(a) FROM t1;
 
connection master;
DROP TABLE t1;
 
sync_slave_with_master;
connection slave;
SET GLOBAL SLAVE_TYPE_CONVERSIONS=@tmp;
 
--source include/rpl_end.inc

It creates a wrong output:

--------------------------------------------------------------------------
 
worker[1] Using MTR_BUILD_THREAD 300, with reserved ports 16000..16019
include/master-slave.inc
[connection master]
connection master;
SET column_compression_threshold=16*256*256;
CREATE TABLE t1 (a LONGBLOB COMPRESSED);;
connection slave;
connection slave;
SET @tmp=@@GLOBAL.SLAVE_TYPE_CONVERSIONS;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = 'ALL_LOSSY';
ALTER TABLE t1 MODIFY a MEDIUMBLOB;;
connection master;
INSERT INTO t1 (a) VALUES (REPEAT('a',256*256));
SELECT LENGTH(a) FROM t1;
LENGTH(a)
65536
connection slave;
SHOW CREATE TABLE t1;
Table	Create Table
t1	CREATE TABLE `t1` (
  `a` mediumblob DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT LENGTH(a) FROM t1;
LENGTH(a)
0
connection master;
DROP TABLE t1;
connection slave;
connection slave;
SET GLOBAL SLAVE_TYPE_CONVERSIONS=@tmp;
include/rpl_end.inc
compat/oracle.AAA2 'row'                 [ pass ]   1035
--------------------------------------------------------------------------

Notice, LENGTH(a) is 65536 on the master side, while 0 on the slave side.

Note, if I change REPEAT('a',256*255) to REPEAT('a',256*250) to make length fit into two bytes, it start to work fine and return 64000 both on master and slave side.

The problem most likely resides in this piece of the code:

Field *Type_handler_blob_compressed::make_conversion_table_field(TABLE *table,
                                                      uint metadata,
                                                      const Field *target)
                                                      const
{
  return new(table->in_use->mem_root)
         Field_blob_compressed(Record_addr(true), Field::NONE,
                               &empty_clex_str,
                               table->s, 2, target->charset(),
                               zlib_compression_method);
}

Notice, it always creates a field with packlength=2. It should pass 1, 2, 3 or 4 depending on the exact BLOB type on the master side (TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB).
The exact data type can be read from metadata.



 Comments   
Comment by Alexander Barkov [ 2018-04-09 ]

The same problem is actually repeatable with non-compressed LONGBLOB to non-compressed MEDIUMBLOB.

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