Description:
aggregate() advances m_cur_phase per stage with the pattern m_cur_phase < THIS_STAGE, but the
merge_sort and insert branches compare against the wrong enum value:
} else if (stage.first == &srv_stage_alter_table_merge_sort) {
if ((int)m_cur_phase < (int)NOT_STARTED) { m_cur_phase = SORT; } // < 0, never true
} else if (stage.first == &srv_stage_alter_table_insert) {
if ((int)m_cur_phase < (int)SORT) { m_cur_phase = INSERT; } // < SORT, wrong
}
Enum: NOT_STARTED=0, READ_PK=1, SORT=2, INSERT=3, FLUSH=4, LOG_INDEX=5, LOG_TABLE=6, END=7.
- merge_sort: < NOT_STARTED (i.e. < 0) is never true → dead branch, m_cur_phase never reaches SORT.
- insert: should be < INSERT; with the merge_sort fix, once m_cur_phase == SORT (2), < SORT is false
→ insert also skipped. The aggregated phase jumps straight to LOG_INDEX.
How to repeat:
performance_schema.events_stages_current may never report stage/innodb/alter table (merge sort) /
(insert) as the aggregated phase after sub-builders are aggregated; the phase label skips to log
apply index. Only the phase label is affected — WORK_COMPLETED/WORK_ESTIMATED are accumulated
independently and remain correct. No crash.
Suggested fix:
Compare against the stage being assigned in all four branches:
if ((int)m_cur_phase < (int)READ_PK) { m_cur_phase = READ_PK; ... }
if ((int)m_cur_phase < (int)SORT) { m_cur_phase = SORT; ... } // was < NOT_STARTED
if ((int)m_cur_phase < (int)INSERT) { m_cur_phase = INSERT; ... } // was < SORT
if ((int)m_cur_phase < (int)LOG_INDEX) { m_cur_phase = LOG_INDEX; ... }
Description: aggregate() advances m_cur_phase per stage with the pattern m_cur_phase < THIS_STAGE, but the merge_sort and insert branches compare against the wrong enum value: } else if (stage.first == &srv_stage_alter_table_merge_sort) { if ((int)m_cur_phase < (int)NOT_STARTED) { m_cur_phase = SORT; } // < 0, never true } else if (stage.first == &srv_stage_alter_table_insert) { if ((int)m_cur_phase < (int)SORT) { m_cur_phase = INSERT; } // < SORT, wrong } Enum: NOT_STARTED=0, READ_PK=1, SORT=2, INSERT=3, FLUSH=4, LOG_INDEX=5, LOG_TABLE=6, END=7. - merge_sort: < NOT_STARTED (i.e. < 0) is never true → dead branch, m_cur_phase never reaches SORT. - insert: should be < INSERT; with the merge_sort fix, once m_cur_phase == SORT (2), < SORT is false → insert also skipped. The aggregated phase jumps straight to LOG_INDEX. How to repeat: performance_schema.events_stages_current may never report stage/innodb/alter table (merge sort) / (insert) as the aggregated phase after sub-builders are aggregated; the phase label skips to log apply index. Only the phase label is affected — WORK_COMPLETED/WORK_ESTIMATED are accumulated independently and remain correct. No crash. Suggested fix: Compare against the stage being assigned in all four branches: if ((int)m_cur_phase < (int)READ_PK) { m_cur_phase = READ_PK; ... } if ((int)m_cur_phase < (int)SORT) { m_cur_phase = SORT; ... } // was < NOT_STARTED if ((int)m_cur_phase < (int)INSERT) { m_cur_phase = INSERT; ... } // was < SORT if ((int)m_cur_phase < (int)LOG_INDEX) { m_cur_phase = LOG_INDEX; ... }