Skip to content

Commit

Permalink
VReplication VPlayer: set foreign_key_checks on initialization (#14013)
Browse files Browse the repository at this point in the history
Signed-off-by: Rohit Nayak <[email protected]>
  • Loading branch information
rohit-nayak-ps authored Sep 19, 2023
1 parent 757333e commit a8f601d
Showing 1 changed file with 32 additions and 14 deletions.
46 changes: 32 additions & 14 deletions go/vt/vttablet/tabletmanager/vreplication/vplayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,19 @@ type vplayer struct {

throttlerAppName string

foreignKeyCheck bool
// See updateFKCheck for more details on how the two fields below are used.

// foreignKeyChecksEnabled is the current state of the foreign key checks for the current session.
// It reflects what we have set the @@session.foreign_key_checks session variable to.
foreignKeyChecksEnabled bool

// foreignKeyChecksStateInitialized is set to true once we have initialized the foreignKeyChecksEnabled.
// The initialization is done on the first row event that this vplayer sees.
foreignKeyChecksStateInitialized bool
}

// NoForeignKeyCheckFlagBitmask is the bitmask for the 2nd bit (least significant) of the flags in a binlog row event.
// This bit is set if foreign key checks are disabled.
const NoForeignKeyCheckFlagBitmask uint32 = 1 << 1

// newVPlayer creates a new vplayer. Parameters:
Expand Down Expand Up @@ -105,7 +115,6 @@ func newVPlayer(vr *vreplicator, settings binlogplayer.VRSettings, copyState map
tablePlans: make(map[string]*TablePlan),
phase: phase,
throttlerAppName: throttlerapp.VCopierName.ConcatenateString(vr.throttlerAppName()),
foreignKeyCheck: false,
}
}

Expand Down Expand Up @@ -138,23 +147,32 @@ func (vp *vplayer) play(ctx context.Context) error {
return vp.fetchAndApply(ctx)
}

// updateFKCheck will check if the fk checks value has changed from what it is currently set to and update it if it has.
// This is done to avoid setting the fk checks value for every row event. vplayer starts with fk checks off.
// updateFKCheck updates the @@session.foreign_key_checks variable based on the binlog row event flags.
// The function only does it if it has changed to avoid redundant updates, using the cached vplayer.foreignKeyChecksEnabled
// The foreign_key_checks value for a transaction is determined by the 2nd bit (least significant) of the flags:
// - If set (1), foreign key checks are disabled.
// - If unset (0), foreign key checks are enabled.
// updateFKCheck also updates the state for the first row event that this vplayer and hence the connection sees.
func (vp *vplayer) updateFKCheck(ctx context.Context, flags2 uint32) error {
// The 2nd bit (least significant) of the flags attribute of the binlog row event
// is set to 1 if foreign key checks are disabled.
enableFK := true
dbForeignKeyChecksEnabled := true
if flags2&NoForeignKeyCheckFlagBitmask == NoForeignKeyCheckFlagBitmask {
enableFK = false
dbForeignKeyChecksEnabled = false
}
if vp.foreignKeyCheck == enableFK {
// if not changed, return

if vp.foreignKeyChecksStateInitialized /* already set earlier */ &&
dbForeignKeyChecksEnabled == vp.foreignKeyChecksEnabled /* no change in the state, no need to update */ {
return nil
}
vp.foreignKeyCheck = enableFK
log.Infof("Setting foreign_key_checks to %v", enableFK)
_, err := vp.vr.dbClient.ExecuteWithRetry(ctx, "set @@session.foreign_key_checks="+strconv.FormatBool(enableFK))
return err
log.Infof("Setting this session's foreign_key_checks to %s", strconv.FormatBool(dbForeignKeyChecksEnabled))
if _, err := vp.vr.dbClient.ExecuteWithRetry(ctx, "set @@session.foreign_key_checks="+strconv.FormatBool(dbForeignKeyChecksEnabled)); err != nil {
return fmt.Errorf("failed to set session foreign_key_checks: %w", err)
}
vp.foreignKeyChecksEnabled = dbForeignKeyChecksEnabled
if !vp.foreignKeyChecksStateInitialized {
log.Infof("First foreign_key_checks update to: %s", strconv.FormatBool(dbForeignKeyChecksEnabled))
vp.foreignKeyChecksStateInitialized = true
}
return nil
}

// fetchAndApply performs the fetching and application of the binlogs.
Expand Down

0 comments on commit a8f601d

Please sign in to comment.