Skip to content

Commit 2ecabd6

Browse files
author
Ole John Aske
committed
Patch backported to cluster-7.6:
Bug#35450016 'ndb_log_update_minimal=ON' is not able to replicate primary key updates The minimal binlog format excluded all primary key columns from the 'after values' reflecting the updated row. The rational for this was a flawed assumption about the primary key being 'constant' when an UPDATE trigger is received. However, if the primary key contain character data type, an UPDATE trigger will also be received if character columns are updated to values being 'equal' by comparison rules of the collation set being used. E.g' 'xyz' -> XYZ'. In order to being able to replicate such changes, we need to include them in the after values as well. This patch midified Ndb_event_data::init_pk_bitmap() to set up a 'MY_BITMAP pk_nonchar_bitmap' in addition to the existing pk_bitmap. The 'nonchar_bitmap' contain only the PK columns not being of a character data type -> Will be 'constant' in an update trigger. Ndb_event_data::generate_minimal_bitmap() is modified to exclude only the nonchar_bitmap from the after values. Note, that ideally we could (in addition) have compared the before and after PK-values in DbtupTrigger, and included only those which changed to a (binary) different value. This was attempted in another version of a patch, but didn't succeed to make this work as intended. It would also have introduced upgrade issues which would had to be solved. Change-Id: I90281cc6ffec1f3495f2336593547ceb7972d907 (cherry picked from commit be4fff857b8ddabf1b0eecb1e06d914829ae2148)
1 parent db45ba7 commit 2ecabd6

File tree

4 files changed

+33
-18
lines changed

4 files changed

+33
-18
lines changed

mysql-test/suite/ndb_rpl/r/ndb_rpl_cmp_varchar_charset.result

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -516,9 +516,6 @@ select str from t1;
516516
str
517517
XYZ
518518
drop table t1;
519-
############################################################
520-
The two test cases below currently *fails* to replicate the
521-
changes due to Bug#35450016. The incorrect result is recorded.
522519
set global ndb_log_updated_only=0;
523520
set global ndb_log_update_as_write=0;
524521
set global ndb_log_update_minimal=1;
@@ -539,7 +536,7 @@ update t1 set str="one";
539536
Verify the replica update, no trailing spaces anymore!
540537
select concat("<<<",str,">>>") from t1;
541538
concat("<<<",str,">>>")
542-
<<<one >>>
539+
<<<one>>>
543540
drop table t1;
544541
#########################################
545542
############## Longvarchar ##############
@@ -550,7 +547,7 @@ update t1 set str="one";
550547
Verify the replica update, no trailing spaces anymore!
551548
select concat("<<<",str,">>>") from t1;
552549
concat("<<<",str,">>>")
553-
<<<one >>>
550+
<<<one>>>
554551
drop table t1;
555552
#####################################
556553
############ Varbinary ##############
@@ -580,7 +577,7 @@ update t1 set str="XYZ";
580577
Verify the replica updated varchar(32) to 'XYZ' as well
581578
select str from t1;
582579
str
583-
xyz
580+
XYZ
584581
drop table t1;
585582
##################################
586583
############## Char ##############
@@ -591,7 +588,7 @@ update t1 set str="XYZ";
591588
Verify the replica updated char(32) to 'XYZ' as well
592589
select str from t1;
593590
str
594-
xyz
591+
XYZ
595592
drop table t1;
596593
##################################
597594
############ Varbinary ###########
@@ -624,7 +621,7 @@ update t1 set str="one";
624621
Verify the replica update, no trailing spaces anymore!
625622
select concat("<<<",str,">>>") from t1;
626623
concat("<<<",str,">>>")
627-
<<<one >>>
624+
<<<one>>>
628625
drop table t1;
629626
#########################################
630627
############## Longvarchar ##############
@@ -635,7 +632,7 @@ update t1 set str="one";
635632
Verify the replica update, no trailing spaces anymore!
636633
select concat("<<<",str,">>>") from t1;
637634
concat("<<<",str,">>>")
638-
<<<one >>>
635+
<<<one>>>
639636
drop table t1;
640637
#####################################
641638
############ Varbinary ##############
@@ -665,7 +662,7 @@ update t1 set str="XYZ";
665662
Verify the replica updated varchar(32) to 'XYZ' as well
666663
select str from t1;
667664
str
668-
xyz
665+
XYZ
669666
drop table t1;
670667
##################################
671668
############## Char ##############
@@ -676,7 +673,7 @@ update t1 set str="XYZ";
676673
Verify the replica updated char(32) to 'XYZ' as well
677674
select str from t1;
678675
str
679-
xyz
676+
XYZ
680677
drop table t1;
681678
##################################
682679
############ Varbinary ###########

mysql-test/suite/ndb_rpl/t/ndb_rpl_cmp_varchar_charset.test

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,6 @@ set global ndb_log_update_as_write=1;
4444
set global ndb_log_update_minimal=1;
4545
--source ndb_rpl_cmp_varchar_charset.inc
4646

47-
--echo ############################################################
48-
--echo The two test cases below currently *fails* to replicate the
49-
--echo changes due to Bug#35450016. The incorrect result is recorded.
5047
set global ndb_log_updated_only=0;
5148
set global ndb_log_update_as_write=0;
5249
set global ndb_log_update_minimal=1;

sql/ndb_event_data.cc

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
Ndb_event_data::Ndb_event_data(NDB_SHARE *the_share) :
3131
shadow_table(NULL),
3232
share(the_share),
33-
pk_bitmap(NULL)
33+
pk_bitmap(NULL),
34+
pk_nonchar_bitmap(NULL)
3435
{
3536
ndb_value[0]= NULL;
3637
ndb_value[1]= NULL;
@@ -45,6 +46,8 @@ Ndb_event_data::~Ndb_event_data()
4546

4647
delete pk_bitmap;
4748
pk_bitmap = NULL;
49+
delete pk_nonchar_bitmap;
50+
pk_nonchar_bitmap = NULL;
4851

4952
free_root(&mem_root, MYF(0));
5053
share= NULL;
@@ -121,12 +124,21 @@ void Ndb_event_data::init_pk_bitmap()
121124
}
122125
pk_bitmap = new MY_BITMAP();
123126
ndb_bitmap_init(*pk_bitmap, pk_bitbuf, shadow_table->s->fields);
127+
pk_nonchar_bitmap = new MY_BITMAP();
128+
ndb_bitmap_init(*pk_nonchar_bitmap, pk_nonchar_bitbuf,
129+
shadow_table->s->fields);
124130
KEY* key = shadow_table->key_info + shadow_table->s->primary_key;
125131
KEY_PART_INFO* key_part_info = key->key_part;
126132
const uint key_parts = key->user_defined_key_parts;
127133
for (uint i = 0; i < key_parts; i++, key_part_info++)
128134
{
129135
bitmap_set_bit(pk_bitmap, key_part_info->fieldnr - 1);
136+
const bool is_char = key_part_info->type == HA_KEYTYPE_TEXT ||
137+
key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
138+
key_part_info->type == HA_KEYTYPE_VARTEXT2;
139+
if (!is_char) {
140+
bitmap_set_bit(pk_nonchar_bitmap, key_part_info->fieldnr - 1);
141+
}
130142
}
131143
assert(!bitmap_is_clear_all(pk_bitmap));
132144
}
@@ -150,8 +162,8 @@ void Ndb_event_data::generate_minimal_bitmap(MY_BITMAP *before, MY_BITMAP *after
150162
assert(!bitmap_is_clear_all(pk_bitmap));
151163
// set Before Image to contain only primary keys
152164
bitmap_copy(before, pk_bitmap);
153-
// remove primary keys from After Image
154-
bitmap_subtract(after, pk_bitmap);
165+
// remove non-character primary keys from After Image
166+
bitmap_subtract(after, pk_nonchar_bitmap);
155167
}
156168
else
157169
{

sql/ndb_event_data.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,21 @@ class Ndb_event_data
4545
struct TABLE *shadow_table;
4646
struct NDB_SHARE *share;
4747
union NdbValue *ndb_value[2];
48-
/* Bitmap with bit set for all primary key columns. */
48+
49+
// Bitmap with all primary key columns, used for "minimal bitmap"
4950
MY_BITMAP *pk_bitmap;
5051
my_bitmap_map pk_bitbuf[(NDB_MAX_ATTRIBUTES_IN_TABLE +
5152
8*sizeof(my_bitmap_map) - 1) /
5253
(8*sizeof(my_bitmap_map))];
5354

55+
// Bitmap with all primary key columns not being a character data type.
56+
// Note that char PK columns may compare-as-equal even if not being binary
57+
// identical. Thus they can not be eliminated from a "minimal bitmap".
58+
MY_BITMAP *pk_nonchar_bitmap;
59+
my_bitmap_map pk_nonchar_bitbuf[(NDB_MAX_ATTRIBUTES_IN_TABLE +
60+
8*sizeof(my_bitmap_map) - 1) /
61+
(8*sizeof(my_bitmap_map))];
62+
5463
void print(const char* where, FILE* file) const;
5564
void init_pk_bitmap();
5665
void generate_minimal_bitmap(MY_BITMAP *before, MY_BITMAP *after);

0 commit comments

Comments
 (0)