From ded2e7c976cbd66d58cccedd978e635b8a1392ab Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Sat, 26 Mar 2022 11:03:49 +0100 Subject: [PATCH] VStreamer: recompute table plan if a new table is encountered for the same id (#9978) * Recompute the plan for a table if a new table is encountered for the same id Signed-off-by: Rohit Nayak * Trigger rebuild Signed-off-by: Rohit Nayak * Trigger rebuild Signed-off-by: Rohit Nayak --- .../tabletserver/vstreamer/vstreamer.go | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go index 5a61041ba60..c5cbb18883d 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go @@ -514,14 +514,23 @@ func (vs *vstreamer) parseEvent(ev mysql.BinlogEvent) ([]*binlogdatapb.VEvent, e // will generate a new plan and FIELD event. id := ev.TableID(vs.format) - if _, ok := vs.plans[id]; ok { - return nil, nil - } - tm, err := ev.TableMap(vs.format) if err != nil { return nil, err } + + if plan, ok := vs.plans[id]; ok { + // When the underlying mysql server restarts the table map can change. + // Usually the vstreamer will also error out when this happens, and vstreamer re-initializes its table map. + // But if the vstreamer is not aware of the restart, we could get an id that matches one in the cache, but + // is for a different table. We then invalidate and recompute the plan for this id. + if plan == nil || plan.Table.Name == tm.Name { + return nil, nil + } + vs.plans[id] = nil + log.Infof("table map changed: id %d for %s has changed to %s", id, plan.Table.Name, tm.Name) + } + if tm.Database == "_vt" && tm.Name == "resharding_journal" { // A journal is a special case that generates a JOURNAL event. return nil, vs.buildJournalPlan(id, tm)