本文整理汇总了Golang中github.com/youtube/vitess/go/vt/topo/topoproto.TabletAliasEqual函数的典型用法代码示例。如果您正苦于以下问题:Golang TabletAliasEqual函数的具体用法?Golang TabletAliasEqual怎么用?Golang TabletAliasEqual使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了TabletAliasEqual函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。
示例1: updateShardCellsAndMaster
// updateShardCellsAndMaster will update the 'Cells' and possibly
// MasterAlias records for the shard, if needed.
func (wr *Wrangler) updateShardCellsAndMaster(ctx context.Context, si *topo.ShardInfo, tabletAlias *topodatapb.TabletAlias, tabletType topodatapb.TabletType, allowMasterOverride bool) error {
// See if we need to update the Shard:
// - add the tablet's cell to the shard's Cells if needed
// - change the master if needed
shardUpdateRequired := false
if !si.HasCell(tabletAlias.Cell) {
shardUpdateRequired = true
}
if tabletType == topodatapb.TabletType_MASTER && !topoproto.TabletAliasEqual(si.MasterAlias, tabletAlias) {
shardUpdateRequired = true
}
if !shardUpdateRequired {
return nil
}
actionNode := actionnode.UpdateShard()
keyspace := si.Keyspace()
shard := si.ShardName()
lockPath, err := wr.lockShard(ctx, keyspace, shard, actionNode)
if err != nil {
return err
}
// re-read the shard with the lock
si, err = wr.ts.GetShard(ctx, keyspace, shard)
if err != nil {
return wr.unlockShard(ctx, keyspace, shard, actionNode, lockPath, err)
}
// update it
wasUpdated := false
if !si.HasCell(tabletAlias.Cell) {
si.Cells = append(si.Cells, tabletAlias.Cell)
wasUpdated = true
}
if tabletType == topodatapb.TabletType_MASTER && !topoproto.TabletAliasEqual(si.MasterAlias, tabletAlias) {
if si.HasMaster() && !allowMasterOverride {
return wr.unlockShard(ctx, keyspace, shard, actionNode, lockPath, fmt.Errorf("creating this tablet would override old master %v in shard %v/%v", topoproto.TabletAliasString(si.MasterAlias), keyspace, shard))
}
si.MasterAlias = tabletAlias
wasUpdated = true
}
if wasUpdated {
// write it back
if err := wr.ts.UpdateShard(ctx, si); err != nil {
return wr.unlockShard(ctx, keyspace, shard, actionNode, lockPath, err)
}
}
// and unlock
return wr.unlockShard(ctx, keyspace, shard, actionNode, lockPath, err)
}
开发者ID:BobbWu,项目名称:vitess,代码行数:55,代码来源:shard.go
示例2: updateShardCellsAndMaster
// updateShardCellsAndMaster will update the 'Cells' and possibly
// MasterAlias records for the shard, if needed.
func (wr *Wrangler) updateShardCellsAndMaster(ctx context.Context, si *topo.ShardInfo, tabletAlias *topodatapb.TabletAlias, tabletType topodatapb.TabletType, allowMasterOverride bool) error {
// See if we need to update the Shard:
// - add the tablet's cell to the shard's Cells if needed
// - change the master if needed
shardUpdateRequired := false
if !si.HasCell(tabletAlias.Cell) {
shardUpdateRequired = true
}
if tabletType == topodatapb.TabletType_MASTER && !topoproto.TabletAliasEqual(si.MasterAlias, tabletAlias) {
shardUpdateRequired = true
}
if !shardUpdateRequired {
return nil
}
// we do need to update the shard, lock it to not interfere with
// reparenting operations.
actionNode := actionnode.UpdateShard()
keyspace := si.Keyspace()
shard := si.ShardName()
lockPath, err := wr.lockShard(ctx, keyspace, shard, actionNode)
if err != nil {
return err
}
// run the update
_, err = wr.ts.UpdateShardFields(ctx, keyspace, shard, func(s *topodatapb.Shard) error {
wasUpdated := false
if !topoproto.ShardHasCell(s, tabletAlias.Cell) {
s.Cells = append(s.Cells, tabletAlias.Cell)
wasUpdated = true
}
if tabletType == topodatapb.TabletType_MASTER && !topoproto.TabletAliasEqual(s.MasterAlias, tabletAlias) {
if !topoproto.TabletAliasIsZero(s.MasterAlias) && !allowMasterOverride {
return fmt.Errorf("creating this tablet would override old master %v in shard %v/%v", topoproto.TabletAliasString(s.MasterAlias), keyspace, shard)
}
s.MasterAlias = tabletAlias
wasUpdated = true
}
if !wasUpdated {
return topo.ErrNoUpdateNeeded
}
return nil
})
return wr.unlockShard(ctx, keyspace, shard, actionNode, lockPath, err)
}
开发者ID:littleyang,项目名称:vitess,代码行数:50,代码来源:shard.go
示例3: Validate
// Validate makes sure a tablet is represented correctly in the topology server.
func Validate(ctx context.Context, ts Server, tabletAlias *topodatapb.TabletAlias) error {
// read the tablet record, make sure it parses
tablet, err := ts.GetTablet(ctx, tabletAlias)
if err != nil {
return err
}
if !topoproto.TabletAliasEqual(tablet.Alias, tabletAlias) {
return fmt.Errorf("bad tablet alias data for tablet %v: %#v", topoproto.TabletAliasString(tabletAlias), tablet.Alias)
}
// Validate the entry in the shard replication nodes
if err = ts.ValidateShard(ctx, tablet.Keyspace, tablet.Shard); err != nil {
return err
}
si, err := ts.GetShardReplication(ctx, tablet.Alias.Cell, tablet.Keyspace, tablet.Shard)
if err != nil {
return err
}
if _, err = si.GetShardReplicationNode(tabletAlias); err != nil {
return fmt.Errorf("tablet %v not found in cell %v shard replication: %v", tabletAlias, tablet.Alias.Cell, err)
}
return nil
}
开发者ID:BobbWu,项目名称:vitess,代码行数:27,代码来源:tablet.go
示例4: remove
// remove takes in an array and returns it with the specified element removed
// (leaves the array unchanged if element isn't in the array).
func remove(tablets []*discovery.TabletStats, tabletAlias *topodata.TabletAlias) []*discovery.TabletStats {
filteredTablets := tablets[:0]
for _, tablet := range tablets {
if !topoproto.TabletAliasEqual(tablet.Tablet.Alias, tabletAlias) {
filteredTablets = append(filteredTablets, tablet)
}
}
return filteredTablets
}
开发者ID:dumbunny,项目名称:vitess,代码行数:11,代码来源:tablet_stats_cache.go
示例5: ValidatePermissionsKeyspace
// ValidatePermissionsKeyspace validates all the permissions are the same
// in a keyspace
func (wr *Wrangler) ValidatePermissionsKeyspace(ctx context.Context, keyspace string) error {
// find all the shards
shards, err := wr.ts.GetShardNames(ctx, keyspace)
if err != nil {
return err
}
// corner cases
if len(shards) == 0 {
return fmt.Errorf("No shards in keyspace %v", keyspace)
}
sort.Strings(shards)
if len(shards) == 1 {
return wr.ValidatePermissionsShard(ctx, keyspace, shards[0])
}
// find the reference permissions using the first shard's master
si, err := wr.ts.GetShard(ctx, keyspace, shards[0])
if err != nil {
return err
}
if !si.HasMaster() {
return fmt.Errorf("No master in shard %v/%v", keyspace, shards[0])
}
referenceAlias := si.MasterAlias
log.Infof("Gathering permissions for reference master %v", topoproto.TabletAliasString(referenceAlias))
referencePermissions, err := wr.GetPermissions(ctx, si.MasterAlias)
if err != nil {
return err
}
// then diff with all tablets but master 0
er := concurrency.AllErrorRecorder{}
wg := sync.WaitGroup{}
for _, shard := range shards {
aliases, err := wr.ts.FindAllTabletAliasesInShard(ctx, keyspace, shard)
if err != nil {
er.RecordError(err)
continue
}
for _, alias := range aliases {
if topoproto.TabletAliasEqual(alias, si.MasterAlias) {
continue
}
wg.Add(1)
go wr.diffPermissions(ctx, referencePermissions, referenceAlias, alias, &wg, &er)
}
}
wg.Wait()
if er.HasErrors() {
return fmt.Errorf("Permissions diffs:\n%v", er.Error().Error())
}
return nil
}
开发者ID:c3p0hz,项目名称:vitess,代码行数:58,代码来源:permissions.go
示例6: InitTablet
// InitTablet creates or updates a tablet. If no parent is specified
// in the tablet, and the tablet has a slave type, we will find the
// appropriate parent. If createShardAndKeyspace is true and the
// parent keyspace or shard don't exist, they will be created. If
// allowUpdate is true, and a tablet with the same ID exists, just update it.
// If a tablet is created as master, and there is already a different
// master in the shard, allowMasterOverride must be set.
func (wr *Wrangler) InitTablet(ctx context.Context, tablet *topodatapb.Tablet, allowMasterOverride, createShardAndKeyspace, allowUpdate bool) error {
if err := topo.TabletComplete(tablet); err != nil {
return err
}
// get the shard, possibly creating it
var err error
var si *topo.ShardInfo
if createShardAndKeyspace {
// create the parent keyspace and shard if needed
si, err = wr.ts.GetOrCreateShard(ctx, tablet.Keyspace, tablet.Shard)
} else {
si, err = wr.ts.GetShard(ctx, tablet.Keyspace, tablet.Shard)
if err == topo.ErrNoNode {
return fmt.Errorf("missing parent shard, use -parent option to create it, or CreateKeyspace / CreateShard")
}
}
// get the shard, checks a couple things
if err != nil {
return fmt.Errorf("cannot get (or create) shard %v/%v: %v", tablet.Keyspace, tablet.Shard, err)
}
if !key.KeyRangeEqual(si.KeyRange, tablet.KeyRange) {
return fmt.Errorf("shard %v/%v has a different KeyRange: %v != %v", tablet.Keyspace, tablet.Shard, si.KeyRange, tablet.KeyRange)
}
if tablet.Type == topodatapb.TabletType_MASTER && si.HasMaster() && !topoproto.TabletAliasEqual(si.MasterAlias, tablet.Alias) && !allowMasterOverride {
return fmt.Errorf("creating this tablet would override old master %v in shard %v/%v, use allow_master_override flag", topoproto.TabletAliasString(si.MasterAlias), tablet.Keyspace, tablet.Shard)
}
// update the shard record if needed
if err := wr.updateShardCellsAndMaster(ctx, si, tablet.Alias, tablet.Type, allowMasterOverride); err != nil {
return err
}
err = wr.ts.CreateTablet(ctx, tablet)
if err == topo.ErrNodeExists && allowUpdate {
// Try to update then
oldTablet, err := wr.ts.GetTablet(ctx, tablet.Alias)
if err != nil {
return fmt.Errorf("failed reading existing tablet %v: %v", topoproto.TabletAliasString(tablet.Alias), err)
}
// Check we have the same keyspace / shard, and if not,
// require the allowDifferentShard flag.
if oldTablet.Keyspace != tablet.Keyspace || oldTablet.Shard != tablet.Shard {
return fmt.Errorf("old tablet has shard %v/%v. Cannot override with shard %v/%v. Delete and re-add tablet if you want to change the tablet's keyspace/shard", oldTablet.Keyspace, oldTablet.Shard, tablet.Keyspace, tablet.Shard)
}
*(oldTablet.Tablet) = *tablet
if err := wr.ts.UpdateTablet(ctx, oldTablet); err != nil {
return fmt.Errorf("failed updating tablet %v: %v", topoproto.TabletAliasString(tablet.Alias), err)
}
}
return nil
}
开发者ID:dumbunny,项目名称:vitess,代码行数:63,代码来源:tablet.go
示例7: startReplication
func (agent *ActionAgent) startReplication(ctx context.Context, pos replication.Position) error {
// Set the position at which to resume from the master.
cmds, err := agent.MysqlDaemon.SetSlavePositionCommands(pos)
if err != nil {
return err
}
if err := agent.MysqlDaemon.ExecuteSuperQueryList(ctx, cmds); err != nil {
return fmt.Errorf("failed to set slave position: %v", err)
}
// Read the shard to find the current master, and its location.
tablet := agent.Tablet()
si, err := agent.TopoServer.GetShard(ctx, tablet.Keyspace, tablet.Shard)
if err != nil {
return fmt.Errorf("can't read shard: %v", err)
}
if si.MasterAlias == nil {
// We've restored, but there's no master. This is fine, since we've
// already set the position at which to resume when we're later reparented.
// If we had instead considered this fatal, all tablets would crash-loop
// until a master appears, which would make it impossible to elect a master.
log.Warningf("Can't start replication after restore: shard %v/%v has no master.", tablet.Keyspace, tablet.Shard)
return nil
}
if topoproto.TabletAliasEqual(si.MasterAlias, tablet.Alias) {
// We used to be the master before we got restarted in an empty data dir,
// and no other master has been elected in the meantime.
// This shouldn't happen, so we'll let the operator decide which tablet
// should actually be promoted to master.
log.Warningf("Can't start replication after restore: master record still points to this tablet.")
return nil
}
ti, err := agent.TopoServer.GetTablet(ctx, si.MasterAlias)
if err != nil {
return fmt.Errorf("Cannot read master tablet %v: %v", si.MasterAlias, err)
}
// If using semi-sync, we need to enable it before connecting to master.
if *enableSemiSync {
if err := agent.enableSemiSync(false); err != nil {
return err
}
}
// Set master and start slave.
cmds, err = agent.MysqlDaemon.SetMasterCommands(ti.Hostname, int(ti.PortMap["mysql"]))
if err != nil {
return fmt.Errorf("MysqlDaemon.SetMasterCommands failed: %v", err)
}
cmds = append(cmds, "START SLAVE")
if err := agent.MysqlDaemon.ExecuteSuperQueryList(ctx, cmds); err != nil {
return fmt.Errorf("failed to start replication: %v", err)
}
return nil
}
开发者ID:xujianhai,项目名称:vitess,代码行数:56,代码来源:restore.go
示例8: DeleteTablet
// DeleteTablet removes a tablet from a shard.
// - if allowMaster is set, we can Delete a master tablet (and clear
// its record from the Shard record if it was the master).
// - if skipRebuild is set, we do not rebuild the serving graph.
func (wr *Wrangler) DeleteTablet(ctx context.Context, tabletAlias *topodatapb.TabletAlias, allowMaster, skipRebuild bool) error {
// load the tablet, see if we'll need to rebuild
ti, err := wr.ts.GetTablet(ctx, tabletAlias)
if err != nil {
return err
}
rebuildRequired := ti.IsInServingGraph()
wasMaster := ti.Type == topodatapb.TabletType_MASTER
if wasMaster && !allowMaster {
return fmt.Errorf("cannot delete tablet %v as it is a master, use allow_master flag", topoproto.TabletAliasString(tabletAlias))
}
// remove the record and its replication graph entry
if err := topotools.DeleteTablet(ctx, wr.ts, ti.Tablet); err != nil {
return err
}
// update the Shard object if the master was scrapped.
// we lock the shard to not conflict with reparent operations.
if wasMaster {
actionNode := actionnode.UpdateShard()
lockPath, err := wr.lockShard(ctx, ti.Keyspace, ti.Shard, actionNode)
if err != nil {
return err
}
// update the shard record's master
if _, err := wr.ts.UpdateShardFields(ctx, ti.Keyspace, ti.Shard, func(s *topodatapb.Shard) error {
if !topoproto.TabletAliasEqual(s.MasterAlias, tabletAlias) {
wr.Logger().Warningf("Deleting master %v from shard %v/%v but master in Shard object was %v", topoproto.TabletAliasString(tabletAlias), ti.Keyspace, ti.Shard, topoproto.TabletAliasString(s.MasterAlias))
return topo.ErrNoUpdateNeeded
}
s.MasterAlias = nil
return nil
}); err != nil {
return wr.unlockShard(ctx, ti.Keyspace, ti.Shard, actionNode, lockPath, err)
}
// and unlock
if err := wr.unlockShard(ctx, ti.Keyspace, ti.Shard, actionNode, lockPath, err); err != nil {
return err
}
}
// and rebuild the original shard if needed
if !rebuildRequired {
wr.Logger().Infof("Rebuild not required")
return nil
}
if skipRebuild {
wr.Logger().Warningf("Rebuild required, but skipping it")
return nil
}
_, err = wr.RebuildShardGraph(ctx, ti.Keyspace, ti.Shard, []string{ti.Alias.Cell})
return err
}
开发者ID:BobbWu,项目名称:vitess,代码行数:60,代码来源:tablet.go
示例9: validateShard
// FIXME(msolomon) This validate presumes the master is up and running.
// Even when that isn't true, there are validation processes that might be valuable.
func (wr *Wrangler) validateShard(ctx context.Context, keyspace, shard string, pingTablets bool, wg *sync.WaitGroup, results chan<- error) {
shardInfo, err := wr.ts.GetShard(ctx, keyspace, shard)
if err != nil {
results <- fmt.Errorf("TopologyServer.GetShard(%v, %v) failed: %v", keyspace, shard, err)
return
}
aliases, err := wr.ts.FindAllTabletAliasesInShard(ctx, keyspace, shard)
if err != nil {
results <- fmt.Errorf("TopologyServer.FindAllTabletAliasesInShard(%v, %v) failed: %v", keyspace, shard, err)
return
}
tabletMap, _ := wr.ts.GetTabletMap(ctx, aliases)
var masterAlias *pb.TabletAlias
for _, alias := range aliases {
tabletInfo, ok := tabletMap[*alias]
if !ok {
results <- fmt.Errorf("tablet %v not found in map", topoproto.TabletAliasString(alias))
continue
}
if tabletInfo.Type == pb.TabletType_MASTER {
if masterAlias != nil {
results <- fmt.Errorf("shard %v/%v already has master %v but found other master %v", keyspace, shard, topoproto.TabletAliasString(masterAlias), topoproto.TabletAliasString(alias))
} else {
masterAlias = alias
}
}
}
if masterAlias == nil {
results <- fmt.Errorf("no master for shard %v/%v", keyspace, shard)
} else if !topoproto.TabletAliasEqual(shardInfo.MasterAlias, masterAlias) {
results <- fmt.Errorf("master mismatch for shard %v/%v: found %v, expected %v", keyspace, shard, topoproto.TabletAliasString(masterAlias), topoproto.TabletAliasString(shardInfo.MasterAlias))
}
for _, alias := range aliases {
wg.Add(1)
go func(alias *pb.TabletAlias) {
defer wg.Done()
if err := topo.Validate(ctx, wr.ts, alias); err != nil {
results <- fmt.Errorf("Validate(%v) failed: %v", topoproto.TabletAliasString(alias), err)
} else {
wr.Logger().Infof("tablet %v is valid", topoproto.TabletAliasString(alias))
}
}(alias)
}
if pingTablets {
wr.validateReplication(ctx, shardInfo, tabletMap, results)
wr.pingTablets(ctx, tabletMap, wg, results)
}
return
}
开发者ID:richarwu,项目名称:vitess,代码行数:58,代码来源:validator.go
示例10: Validate
// Validate makes sure a tablet is represented correctly in the topology server.
func Validate(ctx context.Context, ts Server, tabletAlias *pb.TabletAlias) error {
// read the tablet record, make sure it parses
tablet, err := ts.GetTablet(ctx, tabletAlias)
if err != nil {
return err
}
if !topoproto.TabletAliasEqual(tablet.Alias, tabletAlias) {
return fmt.Errorf("bad tablet alias data for tablet %v: %#v", topoproto.TabletAliasString(tabletAlias), tablet.Alias)
}
// Some tablets have no information to generate valid replication paths.
// We have three cases to handle:
// - we are a tablet in the replication graph, and should have
// replication data (first case below)
// - we are in scrap mode but used to be assigned in the graph
// somewhere (second case below)
// Idle tablets are just not in any graph at all, we don't even know
// their keyspace / shard to know where to check.
if tablet.IsInReplicationGraph() {
if err = ts.ValidateShard(ctx, tablet.Keyspace, tablet.Shard); err != nil {
return err
}
si, err := ts.GetShardReplication(ctx, tablet.Alias.Cell, tablet.Keyspace, tablet.Shard)
if err != nil {
return err
}
_, err = si.GetShardReplicationNode(tabletAlias)
if err != nil {
return fmt.Errorf("tablet %v not found in cell %v shard replication: %v", tabletAlias, tablet.Alias.Cell, err)
}
} else if tablet.IsAssigned() {
// this case is to make sure a scrap node that used to be in
// a replication graph doesn't leave a node behind.
// However, while an action is running, there is some
// time where this might be inconsistent.
si, err := ts.GetShardReplication(ctx, tablet.Alias.Cell, tablet.Keyspace, tablet.Shard)
if err != nil {
return err
}
node, err := si.GetShardReplicationNode(tabletAlias)
if err != ErrNoNode {
return fmt.Errorf("unexpected replication data found(possible pending action?): %v (%v)", node, tablet.Type)
}
}
return nil
}
开发者ID:richarwu,项目名称:vitess,代码行数:52,代码来源:tablet.go
示例11: updateShardCellsAndMaster
// updateShardCellsAndMaster will update the 'Cells' and possibly
// MasterAlias records for the shard, if needed.
func (wr *Wrangler) updateShardCellsAndMaster(ctx context.Context, si *topo.ShardInfo, tabletAlias *topodatapb.TabletAlias, tabletType topodatapb.TabletType, allowMasterOverride bool) error {
// See if we need to update the Shard:
// - add the tablet's cell to the shard's Cells if needed
// - change the master if needed
shardUpdateRequired := false
if !si.HasCell(tabletAlias.Cell) {
shardUpdateRequired = true
}
if tabletType == topodatapb.TabletType_MASTER && !topoproto.TabletAliasEqual(si.MasterAlias, tabletAlias) {
shardUpdateRequired = true
}
if !shardUpdateRequired {
return nil
}
// run the update
_, err := wr.ts.UpdateShardFields(ctx, si.Keyspace(), si.ShardName(), func(s *topo.ShardInfo) error {
wasUpdated := false
if !s.HasCell(tabletAlias.Cell) {
s.Cells = append(s.Cells, tabletAlias.Cell)
wasUpdated = true
}
if tabletType == topodatapb.TabletType_MASTER && !topoproto.TabletAliasEqual(s.MasterAlias, tabletAlias) {
if !topoproto.TabletAliasIsZero(s.MasterAlias) && !allowMasterOverride {
return fmt.Errorf("creating this tablet would override old master %v in shard %v/%v", topoproto.TabletAliasString(s.MasterAlias), si.Keyspace(), si.ShardName())
}
s.MasterAlias = tabletAlias
wasUpdated = true
}
if !wasUpdated {
return topo.ErrNoUpdateNeeded
}
return nil
})
return err
}
开发者ID:dumbunny,项目名称:vitess,代码行数:40,代码来源:shard.go
示例12: TabletEquality
// TabletEquality returns true iff two Tablet are representing the same tablet
// process: same uid/cell, running on the same host / ports.
func TabletEquality(left, right *topodatapb.Tablet) bool {
if !topoproto.TabletAliasEqual(left.Alias, right.Alias) {
return false
}
if left.Hostname != right.Hostname {
return false
}
if len(left.PortMap) != len(right.PortMap) {
return false
}
for key, lvalue := range left.PortMap {
rvalue, ok := right.PortMap[key]
if !ok {
return false
}
if lvalue != rvalue {
return false
}
}
return true
}
开发者ID:CowLeo,项目名称:vitess,代码行数:23,代码来源:tablet.go
示例13: ValidateSchemaShard
// ValidateSchemaShard will diff the schema from all the tablets in the shard.
func (wr *Wrangler) ValidateSchemaShard(ctx context.Context, keyspace, shard string, excludeTables []string, includeViews bool) error {
si, err := wr.ts.GetShard(ctx, keyspace, shard)
if err != nil {
return err
}
// get schema from the master, or error
if !si.HasMaster() {
return fmt.Errorf("No master in shard %v/%v", keyspace, shard)
}
log.Infof("Gathering schema for master %v", topoproto.TabletAliasString(si.MasterAlias))
masterSchema, err := wr.GetSchema(ctx, si.MasterAlias, nil, excludeTables, includeViews)
if err != nil {
return err
}
// read all the aliases in the shard, that is all tablets that are
// replicating from the master
aliases, err := wr.ts.FindAllTabletAliasesInShard(ctx, keyspace, shard)
if err != nil {
return err
}
// then diff with all slaves
er := concurrency.AllErrorRecorder{}
wg := sync.WaitGroup{}
for _, alias := range aliases {
if topoproto.TabletAliasEqual(alias, si.MasterAlias) {
continue
}
wg.Add(1)
go wr.diffSchema(ctx, masterSchema, si.MasterAlias, alias, excludeTables, includeViews, &wg, &er)
}
wg.Wait()
if er.HasErrors() {
return fmt.Errorf("Schema diffs: %v", er.Error().Error())
}
return nil
}
开发者ID:erzel,项目名称:vitess,代码行数:41,代码来源:schema.go
示例14: DeleteTablet
// DeleteTablet removes a tablet from a shard.
// - if allowMaster is set, we can Delete a master tablet (and clear
// its record from the Shard record if it was the master).
func (wr *Wrangler) DeleteTablet(ctx context.Context, tabletAlias *topodatapb.TabletAlias, allowMaster bool) (err error) {
// load the tablet, see if we'll need to rebuild
ti, err := wr.ts.GetTablet(ctx, tabletAlias)
if err != nil {
return err
}
wasMaster := ti.Type == topodatapb.TabletType_MASTER
if wasMaster && !allowMaster {
return fmt.Errorf("cannot delete tablet %v as it is a master, use allow_master flag", topoproto.TabletAliasString(tabletAlias))
}
// remove the record and its replication graph entry
if err := topotools.DeleteTablet(ctx, wr.ts, ti.Tablet); err != nil {
return err
}
// update the Shard object if the master was scrapped.
if wasMaster {
// We lock the shard to not conflict with reparent operations.
ctx, unlock, lockErr := wr.ts.LockShard(ctx, ti.Keyspace, ti.Shard, fmt.Sprintf("DeleteTablet(%v)", topoproto.TabletAliasString(tabletAlias)))
if lockErr != nil {
return lockErr
}
defer unlock(&err)
// update the shard record's master
_, err = wr.ts.UpdateShardFields(ctx, ti.Keyspace, ti.Shard, func(si *topo.ShardInfo) error {
if !topoproto.TabletAliasEqual(si.MasterAlias, tabletAlias) {
wr.Logger().Warningf("Deleting master %v from shard %v/%v but master in Shard object was %v", topoproto.TabletAliasString(tabletAlias), ti.Keyspace, ti.Shard, topoproto.TabletAliasString(si.MasterAlias))
return topo.ErrNoUpdateNeeded
}
si.MasterAlias = nil
return nil
})
return err
}
return nil
}
开发者ID:dumbunny,项目名称:vitess,代码行数:42,代码来源:tablet.go
示例15: ValidatePermissionsShard
// ValidatePermissionsShard validates all the permissions are the same
// in a shard
func (wr *Wrangler) ValidatePermissionsShard(ctx context.Context, keyspace, shard string) error {
si, err := wr.ts.GetShard(ctx, keyspace, shard)
if err != nil {
return err
}
// get permissions from the master, or error
if !si.HasMaster() {
return fmt.Errorf("No master in shard %v/%v", keyspace, shard)
}
log.Infof("Gathering permissions for master %v", topoproto.TabletAliasString(si.MasterAlias))
masterPermissions, err := wr.GetPermissions(ctx, si.MasterAlias)
if err != nil {
return err
}
// read all the aliases in the shard, that is all tablets that are
// replicating from the master
aliases, err := wr.ts.FindAllTabletAliasesInShard(ctx, keyspace, shard)
if err != nil {
return err
}
// then diff all of them, except master
er := concurrency.AllErrorRecorder{}
wg := sync.WaitGroup{}
for _, alias := range aliases {
if topoproto.TabletAliasEqual(alias, si.MasterAlias) {
continue
}
wg.Add(1)
go wr.diffPermissions(ctx, masterPermissions, si.MasterAlias, alias, &wg, &er)
}
wg.Wait()
if er.HasErrors() {
return fmt.Errorf("Permissions diffs:\n%v", er.Error().Error())
}
return nil
}
开发者ID:c3p0hz,项目名称:vitess,代码行数:41,代码来源:permissions.go
示例16: chooseNewMaster
// chooseNewMaster finds a tablet that is going to become master after reparent. The criterias
// for the new master-elect are (preferably) to be in the same cell as the current master, and
// to be different from avoidMasterTabletAlias. The tablet with the largest replication
// position is chosen to minimize the time of catching up with the master. Note that the search
// for largest replication position will race with transactions being executed on the master at
// the same time, so when all tablets are roughly at the same position then the choice of the
// new master-elect will be somewhat unpredictable.
func (wr *Wrangler) chooseNewMaster(
ctx context.Context,
shardInfo *topo.ShardInfo,
tabletMap map[topodatapb.TabletAlias]*topo.TabletInfo,
avoidMasterTabletAlias *topodatapb.TabletAlias,
waitSlaveTimeout time.Duration) (*topodatapb.TabletAlias, error) {
if avoidMasterTabletAlias == nil {
return nil, fmt.Errorf("tablet to avoid for reparent is not provided, cannot choose new master")
}
var masterCell string
if shardInfo.MasterAlias != nil {
masterCell = shardInfo.MasterAlias.Cell
}
maxPosSearch := maxReplPosSearch{
wrangler: wr,
ctx: ctx,
waitSlaveTimeout: waitSlaveTimeout,
waitGroup: sync.WaitGroup{},
maxPosLock: sync.Mutex{},
}
for tabletAlias, tabletInfo := range tabletMap {
if (masterCell != "" && tabletAlias.Cell != masterCell) ||
topoproto.TabletAliasEqual(&tabletAlias, avoidMasterTabletAlias) {
continue
}
maxPosSearch.waitGroup.Add(1)
go maxPosSearch.processTablet(tabletInfo.Tablet)
}
maxPosSearch.waitGroup.Wait()
if maxPosSearch.maxPosTablet == nil {
return nil, nil
}
return maxPosSearch.maxPosTablet.Alias, nil
}
开发者ID:dumbunny,项目名称:vitess,代码行数:44,代码来源:reparent.go
示例17: plannedReparentShardLocked
func (wr *Wrangler) plannedReparentShardLocked(ctx context.Context, ev *events.Reparent, keyspace, shard string, masterElectTabletAlias *pb.TabletAlias, waitSlaveTimeout time.Duration) error {
shardInfo, err := wr.ts.GetShard(ctx, keyspace, shard)
if err != nil {
return err
}
ev.ShardInfo = *shardInfo
event.DispatchUpdate(ev, "reading tablet map")
tabletMap, err := wr.ts.GetTabletMapForShard(ctx, keyspace, shard)
if err != nil {
return err
}
// Check corner cases we're going to depend on
masterElectTabletInfo, ok := tabletMap[*masterElectTabletAlias]
if !ok {
return fmt.Errorf("master-elect tablet %v is not in the shard", topoproto.TabletAliasString(masterElectTabletAlias))
}
ev.NewMaster = *masterElectTabletInfo.Tablet
if topoproto.TabletAliasEqual(shardInfo.MasterAlias, masterElectTabletAlias) {
return fmt.Errorf("master-elect tablet %v is already the master", topoproto.TabletAliasString(masterElectTabletAlias))
}
oldMasterTabletInfo, ok := tabletMap[*shardInfo.MasterAlias]
if !ok {
return fmt.Errorf("old master tablet %v is not in the shard", topoproto.TabletAliasString(shardInfo.MasterAlias))
}
ev.OldMaster = *oldMasterTabletInfo.Tablet
// Demote the current master, get its replication position
wr.logger.Infof("demote current master %v", shardInfo.MasterAlias)
event.DispatchUpdate(ev, "demoting old master")
rp, err := wr.tmc.DemoteMaster(ctx, oldMasterTabletInfo)
if err != nil {
return fmt.Errorf("old master tablet %v DemoteMaster failed: %v", topoproto.TabletAliasString(shardInfo.MasterAlias), err)
}
// Wait on the master-elect tablet until it reaches that position,
// then promote it
wr.logger.Infof("promote slave %v", topoproto.TabletAliasString(masterElectTabletAlias))
event.DispatchUpdate(ev, "promoting slave")
rp, err = wr.tmc.PromoteSlaveWhenCaughtUp(ctx, masterElectTabletInfo, rp)
if err != nil {
return fmt.Errorf("master-elect tablet %v failed to catch up with replication or be upgraded to master: %v", topoproto.TabletAliasString(masterElectTabletAlias), err)
}
// Go through all the tablets:
// - new master: populate the reparent journal
// - everybody else: reparent to new master, wait for row
event.DispatchUpdate(ev, "reparenting all tablets")
now := time.Now().UnixNano()
wgMaster := sync.WaitGroup{}
wgSlaves := sync.WaitGroup{}
rec := concurrency.AllErrorRecorder{}
var masterErr error
for alias, tabletInfo := range tabletMap {
if topoproto.TabletAliasEqual(&alias, masterElectTabletAlias) {
wgMaster.Add(1)
go func(alias pb.TabletAlias, tabletInfo *topo.TabletInfo) {
defer wgMaster.Done()
wr.logger.Infof("populating reparent journal on new master %v", topoproto.TabletAliasString(&alias))
masterErr = wr.TabletManagerClient().PopulateReparentJournal(ctx, tabletInfo, now, plannedReparentShardOperation, &alias, rp)
}(alias, tabletInfo)
} else {
wgSlaves.Add(1)
go func(alias pb.TabletAlias, tabletInfo *topo.TabletInfo) {
defer wgSlaves.Done()
wr.logger.Infof("setting new master on slave %v", topoproto.TabletAliasString(&alias))
// also restart replication on old master
forceStartSlave := topoproto.TabletAliasEqual(&alias, oldMasterTabletInfo.Alias)
if err := wr.TabletManagerClient().SetMaster(ctx, tabletInfo, masterElectTabletAlias, now, forceStartSlave); err != nil {
rec.RecordError(fmt.Errorf("Tablet %v SetMaster failed: %v", topoproto.TabletAliasString(&alias), err))
return
}
}(alias, tabletInfo)
}
}
// After the master is done, we can update the shard record
// (note with semi-sync, it also means at least one slave is done)
wgMaster.Wait()
if masterErr != nil {
wgSlaves.Wait()
return fmt.Errorf("failed to PopulateReparentJournal on master: %v", masterErr)
}
wr.logger.Infof("updating shard record with new master %v", masterElectTabletAlias)
shardInfo.MasterAlias = masterElectTabletAlias
if err := wr.ts.UpdateShard(ctx, shardInfo); err != nil {
wgSlaves.Wait()
return fmt.Errorf("failed to update shard master record: %v", err)
}
// Wait for the slaves to complete. If some of them fail, we
// will rebuild the shard serving graph anyway
wgSlaves.Wait()
if err := rec.Error(); err != nil {
wr.Logger().Errorf("Some slaves failed to reparent: %v", err)
return err
}
// Then we rebuild the entire serving graph for the shard,
//.........这里部分代码省略.........
开发者ID:richarwu,项目名称:vitess,代码行数:101,代码来源:reparent.go
示例18: initShardMasterLocked
func (wr *Wrangler) initShardMasterLocked(ctx context.Context, ev *events.Reparent, keyspace, shard string, masterElectTabletAlias *pb.TabletAlias, force bool, waitSlaveTimeout time.Duration) error {
shardInfo, err := wr.ts.GetShard(ctx, keyspace, shard)
if err != nil {
return err
}
ev.ShardInfo = *shardInfo
event.DispatchUpdate(ev, "reading tablet map")
tabletMap, err := wr.ts.GetTabletMapForShard(ctx, keyspace, shard)
if err != nil {
return err
}
// Check the master elect is in tabletMap
masterElectTabletInfo, ok := tabletMap[*masterElectTabletAlias]
if !ok {
return fmt.Errorf("master-elect tablet %v is not in the shard", topoproto.TabletAliasString(masterElectTabletAlias))
}
ev.NewMaster = *masterElectTabletInfo.Tablet
// Check the master is the only master is the shard, or -force was used.
_, masterTabletMap := topotools.SortedTabletMap(tabletMap)
if !topoproto.TabletAliasEqual(shardInfo.MasterAlias, masterElectTabletAlias) {
if !force {
return fmt.Errorf("master-elect tablet %v is not the shard master, use -force to proceed anyway", topoproto.TabletAliasString(masterElectTabletAlias))
}
wr.logger.Warningf("master-elect tablet %v is not the shard master, proceeding anyway as -force was used", topoproto.TabletAliasString(masterElectTabletAlias))
}
if _, ok := masterTabletMap[*masterElectTabletAlias]; !ok {
if !force {
return fmt.Errorf("master-elect tablet %v is not a master in the shard, use -force to proceed anyway", topoproto.TabletAliasString(masterElectTabletAlias))
}
wr.logger.Warningf("master-elect tablet %v is not a master in the shard, proceeding anyway as -force was used", topoproto.TabletAliasString(masterElectTabletAlias))
}
haveOtherMaster := false
for alias, ti := range masterTabletMap {
if !topoproto.TabletAliasEqual(&alias, masterElectTabletAlias) && ti.Type != pb.TabletType_SCRAP {
haveOtherMaster = true
}
}
if haveOtherMaster {
if !force {
return fmt.Errorf("master-elect tablet %v is not the only master in the shard, use -force to proceed anyway", topoproto.TabletAliasString(masterElectTabletAlias))
}
wr.logger.Warningf("master-elect tablet %v is not the only master in the shard, proceeding anyway as -force was used", topoproto.TabletAliasString(masterElectTabletAlias))
}
// First phase: reset replication on all tablets. If anyone fails,
// we stop. It is probably because it is unreachable, and may leave
// an unstable database process in the mix, with a database daemon
// at a wrong replication spot.
event.DispatchUpdate(ev, "resetting replication on all tablets")
wg := sync.WaitGroup{}
rec := concurrency.AllErrorRecorder{}
for alias, tabletInfo := range tabletMap {
wg.Add(1)
go func(alias pb.TabletAlias, tabletInfo *topo.TabletInfo) {
defer wg.Done()
wr.logger.Infof("resetting replication on tablet %v", topoproto.TabletAliasString(&alias))
if err := wr.TabletManagerClient().ResetReplication(ctx, tabletInfo); err != nil {
rec.RecordError(fmt.Errorf("Tablet %v ResetReplication failed (either fix it, or Scrap it): %v", topoproto.TabletAliasString(&alias), err))
}
}(alias, tabletInfo)
}
wg.Wait()
if err := rec.Error(); err != nil {
return err
}
// Tell the new master to break its slaves, return its replication
// position
wr.logger.Infof("initializing master on %v", topoproto.TabletAliasString(masterElectTabletAlias))
event.DispatchUpdate(ev, "initializing master")
rp, err := wr.TabletManagerClient().InitMaster(ctx, masterElectTabletInfo)
if err != nil {
return err
}
// Now tell the new master to insert the reparent_journal row,
// and tell everybody else to become a slave of the new master,
// and wait for the row in the reparent_journal table.
// We start all these in parallel, to handle the semi-sync
// case: for the master to be able to commit its row in the
// reparent_journal table, it needs connected slaves.
event.DispatchUpdate(ev, "reparenting all tablets")
now := time.Now().UnixNano()
wgMaster := sync.WaitGroup{}
wgSlaves := sync.WaitGroup{}
var masterErr error
for alias, tabletInfo := range tabletMap {
if topoproto.TabletAliasEqual(&alias, masterElectTabletAlias) {
wgMaster.Add(1)
go func(alias pb.TabletAlias, tabletInfo *topo.TabletInfo) {
defer wgMaster.Done()
wr.logger.Infof("populating reparent journal on new master %v", topoproto.TabletAliasString(&alias))
masterErr = wr.TabletManagerClient().PopulateReparentJournal(ctx, tabletInfo, now, initShardMasterOperation, &alias, rp)
}(alias, tabletInfo)
} else {
wgSlaves.Add(1)
go func(alias pb.TabletAlias, tabletInfo *topo.TabletInfo) {
//.........这里部分代码省略.........
开发者ID:richarwu,项目名称:vitess,代码行数:101,代码来源:reparent.go
示例19: TestTabletExternallyReparented
func TestTabletExternallyReparented(t *testing.T) {
tabletmanager.SetReparentFlags(time.Minute /* finalizeTimeout */)
ctx := context.Background()
db := fakesqldb.Register()
ts := zktopo.NewTestServer(t, []string{"cell1", "cell2"})
wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient(), time.Second)
vp := NewVtctlPipe(t, ts)
defer vp.Close()
// Create an old master, a new master, two good slaves, one bad slave
oldMaster := NewFakeTablet(t, wr, "cell1", 0, pb.TabletType_MASTER, db)
newMaster := NewFakeTablet(t, wr, "cell1", 1, pb.TabletType_REPLICA, db)
goodSlave1 := NewFakeTablet(t, wr, "cell1", 2, pb.TabletType_REPLICA, db)
goodSlave2 := NewFakeTablet(t, wr, "cell2", 3, pb.TabletType_REPLICA, db)
badSlave := NewFakeTablet(t, wr, "cell1", 4, pb.TabletType_REPLICA, db)
// Add a new Cell to the Shard, that doesn't map to any read topo cell,
// to simulate a data center being unreachable.
si, err := ts.GetShard(ctx, "test_keyspace", "0")
if err != nil {
t.Fatalf("GetShard failed: %v", err)
}
si.Cells = append(si.Cells, "cell666")
if err := ts.UpdateShard(ctx, si); err != nil {
t.Fatalf("UpdateShard failed: %v", err)
}
// Slightly unrelated test: make sure we can find the tablets
// even with a datacenter being down.
tabletMap, err := ts.GetTabletMapForShardByCell(ctx, "test_keyspace", "0", []string{"cell1"})
if err != nil {
t.Fatalf("GetTabletMapForShardByCell should have worked but got: %v", err)
}
master, err := topotools.FindTabletByIPAddrAndPort(tabletMap, oldMaster.Tablet.Ip, "vt", o
|
请发表评论