Skip to content

Commit 4b61da0

Browse files
committed
Merge branch 'mysql-5.7-cluster-7.5' into mysql-5.7-cluster-7.6
Change-Id: Ifd0e1f4469b9c4167349e549d6158e17644e4754
2 parents c3746ac + 141a06c commit 4b61da0

File tree

3 files changed

+148
-12
lines changed

3 files changed

+148
-12
lines changed

mysql-test/suite/ndb/r/ndb_index_stat.result

+40
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,46 @@ select * from information_schema.tables;
662662
Pattern "\[NdbApi\] ERROR -- ndb_index_stat key\/value has different length than expected" found
663663
#cleanup
664664
drop table t1;
665+
CREATE TABLE t1 (
666+
a INT PRIMARY KEY,
667+
b INT,
668+
c INT,
669+
UNIQUE(c)
670+
) ENGINE NDB PARTITION BY KEY(a);
671+
Insert 100 rows
672+
ANALYZE TABLE t1;
673+
Table Op Msg_type Msg_text
674+
test.t1 analyze status OK
675+
SELECT CASE COUNT(*) > 0
676+
WHEN 1 THEN 'YES' ELSE 'NO' END
677+
AS stats_metadata_present FROM mysql.ndb_index_stat_head;
678+
stats_metadata_present
679+
YES
680+
SELECT COUNT(*) INTO @samples_pre_alter FROM mysql.ndb_index_stat_sample;
681+
ALTER TABLE t1 COMMENT="NDB_TABLE=READ_BACKUP=1";
682+
ANALYZE TABLE t1;
683+
Table Op Msg_type Msg_text
684+
test.t1 analyze status OK
685+
SELECT COUNT(index_id)
686+
FROM mysql.ndb_index_stat_head
687+
GROUP BY index_id
688+
HAVING COUNT(index_id) > 1;
689+
COUNT(index_id)
690+
2
691+
2
692+
Sample count is the same as before the ALTER
693+
EXPLAIN is the same both pre- and post-ALTER
694+
DROP TABLE t1;
695+
SELECT CASE COUNT(*) > 0
696+
WHEN 1 THEN 'YES' ELSE 'NO' END
697+
AS stats_metadata_present FROM mysql.ndb_index_stat_head;
698+
stats_metadata_present
699+
YES
700+
SELECT CASE COUNT(*) = 0
701+
WHEN 1 THEN 'YES' ELSE 'NO' END
702+
AS stats_samples_cleaned_up FROM mysql.ndb_index_stat_sample;
703+
stats_samples_cleaned_up
704+
YES
665705
set @is_enable = @is_enable_default;
666706
set @is_enable = NULL;
667707
# is_enable_on=0 is_enable_off=0

mysql-test/suite/ndb/t/ndb_index_stat.test

+87
Original file line numberDiff line numberDiff line change
@@ -526,5 +526,92 @@ select * from information_schema.tables;
526526
--echo #cleanup
527527
drop table t1;
528528

529+
# Bug#29611297 NDB: INDEX STAT HAS ISSUES WITH ONLINE ALTER TABLE TO/FROM
530+
# READBACKUP. Online ALTER TABLE statements that resulted in the index
531+
# version being bumped up left behind orphaned index stats corresponding
532+
# to the previous index version.
533+
CREATE TABLE t1 (
534+
a INT PRIMARY KEY,
535+
b INT,
536+
c INT,
537+
UNIQUE(c)
538+
) ENGINE NDB PARTITION BY KEY(a);
539+
540+
--echo Insert 100 rows
541+
--disable_query_log
542+
let $i = 100;
543+
while ($i)
544+
{
545+
dec $i;
546+
eval INSERT INTO t1 VALUES($i, $i % 100, $i);
547+
}
548+
--enable_query_log
549+
550+
# Trigger index stats creation which creates 1 metadata entry
551+
# in the head table (exposed to users via the ndbinfo.index_stats
552+
# table) and n sample table entries per index
553+
ANALYZE TABLE t1;
554+
# Uncomment below to check details
555+
#SELECT * FROM mysql.ndb_index_stat_head;
556+
SELECT CASE COUNT(*) > 0
557+
WHEN 1 THEN 'YES' ELSE 'NO' END
558+
AS stats_metadata_present FROM mysql.ndb_index_stat_head;
559+
# Record the number of samples created. This seems to vary across platforms
560+
SELECT COUNT(*) INTO @samples_pre_alter FROM mysql.ndb_index_stat_sample;
561+
562+
# Record the value of 'rows' in the EXPLAIN output for a later check
563+
--let $query=SELECT * FROM t1 WHERE c > 50
564+
--let $explain_rows_pre_alter=query_get_value(EXPLAIN $query, rows, 1)
565+
566+
# Online ALTER that creates indexes with new versions
567+
ALTER TABLE t1 COMMENT="NDB_TABLE=READ_BACKUP=1";
568+
569+
# Trigger index stats creation. The ANALYZE below will clean up
570+
# samples corresponding to the old index version in the
571+
# ndb_index_stat_sample table and create new samples for the
572+
# new index version.
573+
ANALYZE TABLE t1;
574+
# Uncomment below to check details
575+
#SELECT * FROM mysql.ndb_index_stat_head;
576+
# Check for duplicates
577+
SELECT COUNT(index_id)
578+
FROM mysql.ndb_index_stat_head
579+
GROUP BY index_id
580+
HAVING COUNT(index_id) > 1;
581+
# Should still be 21/26 samples. Was 42/52 (21/26 created with
582+
# <index_id, old index_version> as the key and 21/26 more
583+
# with <index_id, new index version>) before the bug fix
584+
if (`SELECT COUNT(*) <> @samples_pre_alter FROM mysql.ndb_index_stat_sample`)
585+
{
586+
--die "Extra samples found"
587+
}
588+
--echo Sample count is the same as before the ALTER
589+
590+
# Execute the same EXPLAIN as earlier. The expectation is that the 'rows'
591+
# output is the same from before the ALTER
592+
--let $explain_rows_post_alter=query_get_value(EXPLAIN $query, rows, 1)
593+
#--expr $explain_rows_change = $explain_rows_post_alter - $explain_rows_pre_alter
594+
if ($explain_rows_post_alter == $explain_rows_pre_alter)
595+
{
596+
--echo EXPLAIN is the same both pre- and post-ALTER
597+
}
598+
if ($explain_rows_post_alter != $explain_rows_pre_alter)
599+
{
600+
--die EXPLAIN has changed. Pre-ALTER: $explain_rows_pre_alter and post-ALTER: $explain_rows_post_alter
601+
}
602+
603+
DROP TABLE t1;
604+
605+
# We expect 0 entries in the sample table but "stale" metadata
606+
# info is still present in the head table
607+
# Uncomment below to check details
608+
#SELECT * FROM mysql.ndb_index_stat_head;
609+
SELECT CASE COUNT(*) > 0
610+
WHEN 1 THEN 'YES' ELSE 'NO' END
611+
AS stats_metadata_present FROM mysql.ndb_index_stat_head;
612+
SELECT CASE COUNT(*) = 0
613+
WHEN 1 THEN 'YES' ELSE 'NO' END
614+
AS stats_samples_cleaned_up FROM mysql.ndb_index_stat_sample;
615+
529616
set @is_enable = @is_enable_default;
530617
source ndb_index_stat_enable.inc;

storage/ndb/src/kernel/blocks/trix/Trix.cpp

+21-12
Original file line numberDiff line numberDiff line change
@@ -2678,35 +2678,44 @@ Trix::statCleanPrepare(Signal* signal, StatOp& stat)
26782678
ndbrequire(ao_buf.isEmpty());
26792679
ao_buf.append(ao_list, ao_size);
26802680

2681-
// create TUX bounds
2682-
clean.m_bound[0] = TuxBoundInfo::BoundEQ;
2683-
clean.m_bound[1] = AttributeHeader(0, 4).m_value;
2684-
clean.m_bound[2] = data.m_indexId;
2685-
clean.m_bound[3] = TuxBoundInfo::BoundEQ;
2686-
clean.m_bound[4] = AttributeHeader(1, 4).m_value;
2687-
clean.m_bound[5] = data.m_indexVersion;
2688-
Uint32 boundCount;
2681+
Uint32 boundCount = 0;
26892682
switch (stat.m_requestType) {
26902683
case IndexStatReq::RT_CLEAN_NEW:
26912684
D("statCleanPrepare delete sample versions > " << data.m_sampleVersion);
2685+
clean.m_bound[0] = TuxBoundInfo::BoundEQ;
2686+
clean.m_bound[1] = AttributeHeader(0, 4).m_value;
2687+
clean.m_bound[2] = data.m_indexId;
2688+
clean.m_bound[3] = TuxBoundInfo::BoundEQ;
2689+
clean.m_bound[4] = AttributeHeader(1, 4).m_value;
2690+
clean.m_bound[5] = data.m_indexVersion;
26922691
clean.m_bound[6] = TuxBoundInfo::BoundLT;
26932692
clean.m_bound[7] = AttributeHeader(2, 4).m_value;
26942693
clean.m_bound[8] = data.m_sampleVersion;
26952694
boundCount = 3;
26962695
break;
26972696
case IndexStatReq::RT_CLEAN_OLD:
26982697
D("statCleanPrepare delete sample versions < " << data.m_sampleVersion);
2698+
clean.m_bound[0] = TuxBoundInfo::BoundEQ;
2699+
clean.m_bound[1] = AttributeHeader(0, 4).m_value;
2700+
clean.m_bound[2] = data.m_indexId;
2701+
clean.m_bound[3] = TuxBoundInfo::BoundEQ;
2702+
clean.m_bound[4] = AttributeHeader(1, 4).m_value;
2703+
clean.m_bound[5] = data.m_indexVersion;
26992704
clean.m_bound[6] = TuxBoundInfo::BoundGT;
27002705
clean.m_bound[7] = AttributeHeader(2, 4).m_value;
27012706
clean.m_bound[8] = data.m_sampleVersion;
27022707
boundCount = 3;
27032708
break;
27042709
case IndexStatReq::RT_CLEAN_ALL:
2705-
D("statCleanPrepare delete all sample versions");
2706-
boundCount = 2;
2710+
D("statCleanPrepare delete all sample versions and index versions");
2711+
// Delete all entries corresponding to the index id. This handles
2712+
// scenarios involving index versions bumps as well
2713+
clean.m_bound[0] = TuxBoundInfo::BoundEQ;
2714+
clean.m_bound[1] = AttributeHeader(0, 4).m_value;
2715+
clean.m_bound[2] = data.m_indexId;
2716+
boundCount = 1;
27072717
break;
27082718
default:
2709-
boundCount = 0; /* Silence compiler warning */
27102719
ndbrequire(false);
27112720
return; /* Silence compiler warning */
27122721
break;
@@ -2755,7 +2764,7 @@ Trix::statCleanExecute(Signal* signal, StatOp& stat)
27552764
ndbrequire(ptr1.sz <= avmax);
27562765
::copy(av, ptr1);
27572766
ndbrequire(data.m_indexId == av[0]);
2758-
ndbrequire(data.m_indexVersion == av[1]);
2767+
data.m_indexVersion = av[1];
27592768
data.m_sampleVersion = av[2];
27602769
data.m_statKey = &av[3];
27612770
const unsigned char* kp = (const unsigned char*)data.m_statKey;

0 commit comments

Comments
 (0)