本文整理汇总了Golang中github.com/youtube/vitess/go/vt/topo.CreateShard函数的典型用法代码示例。如果您正苦于以下问题:Golang CreateShard函数的具体用法?Golang CreateShard怎么用?Golang CreateShard使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了CreateShard函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: createTestAgent
func createTestAgent(ctx context.Context, t *testing.T) *ActionAgent {
ts := zktopo.NewTestServer(t, []string{cell})
if err := ts.CreateKeyspace(ctx, keyspace, &pb.Keyspace{}); err != nil {
t.Fatalf("CreateKeyspace failed: %v", err)
}
if err := topo.CreateShard(ctx, ts, keyspace, shard); err != nil {
t.Fatalf("CreateShard failed: %v", err)
}
port := 1234
tablet := &topo.Tablet{
Alias: tabletAlias,
Hostname: "host",
Portmap: map[string]int{
"vt": port,
},
IPAddr: "1.0.0.1",
Keyspace: keyspace,
Shard: shard,
Type: topo.TYPE_SPARE,
}
if err := topo.CreateTablet(ctx, ts, tablet); err != nil {
t.Fatalf("CreateTablet failed: %v", err)
}
mysqlDaemon := &mysqlctl.FakeMysqlDaemon{MysqlPort: 3306}
agent := NewTestActionAgent(ctx, ts, tabletAlias, port, 0, mysqlDaemon)
agent.BinlogPlayerMap = NewBinlogPlayerMap(ts, nil, nil)
agent.HealthReporter = &fakeHealthCheck{}
return agent
}
示例2: GetOrCreateShard
// GetOrCreateShard will return the shard object, or create one if it doesn't
// already exist. Note the shard creation is protected by a keyspace Lock.
func GetOrCreateShard(ctx context.Context, ts topo.Server, keyspace, shard string) (*topo.ShardInfo, error) {
si, finalErr := ts.GetShard(ctx, keyspace, shard)
if finalErr == topo.ErrNoNode {
// create the keyspace, maybe it already exists
if err := ts.CreateKeyspace(ctx, keyspace, &topo.Keyspace{}); err != nil && err != topo.ErrNodeExists {
return nil, fmt.Errorf("CreateKeyspace(%v) failed: %v", keyspace, err)
}
// now we can lock the keyspace
node := actionnode.KeyspaceCreateShard()
lockPath, err := node.LockKeyspace(ctx, ts, keyspace)
if err != nil {
return nil, fmt.Errorf("LockKeyspace failed: %v", err)
}
// now try to create within the lock, may already exist
if err := topo.CreateShard(ctx, ts, keyspace, shard); err != nil && err != topo.ErrNodeExists {
return nil, node.UnlockKeyspace(ctx, ts, keyspace, lockPath, fmt.Errorf("CreateShard(%v/%v) failed: %v", keyspace, shard, err))
}
// try to read the shard again, maybe someone created it
// in between the original GetShard and the LockKeyspace
si, finalErr = ts.GetShard(ctx, keyspace, shard)
// and unlock
if err := node.UnlockKeyspace(ctx, ts, keyspace, lockPath, finalErr); err != nil {
return nil, fmt.Errorf("UnlockKeyspace failed: %v", err)
}
}
return si, finalErr
}
示例3: CopyShards
// CopyShards will create the shards in the destination topo
func CopyShards(fromTS, toTS topo.Server, deleteKeyspaceShards bool) {
keyspaces, err := fromTS.GetKeyspaces()
if err != nil {
log.Fatalf("fromTS.GetKeyspaces: %v", err)
}
wg := sync.WaitGroup{}
rec := concurrency.AllErrorRecorder{}
for _, keyspace := range keyspaces {
wg.Add(1)
go func(keyspace string) {
defer wg.Done()
shards, err := fromTS.GetShardNames(keyspace)
if err != nil {
rec.RecordError(fmt.Errorf("GetShardNames(%v): %v", keyspace, err))
return
}
if deleteKeyspaceShards {
if err := toTS.DeleteKeyspaceShards(keyspace); err != nil {
rec.RecordError(fmt.Errorf("DeleteKeyspaceShards(%v): %v", keyspace, err))
return
}
}
for _, shard := range shards {
wg.Add(1)
go func(keyspace, shard string) {
defer wg.Done()
if err := topo.CreateShard(toTS, keyspace, shard); err != nil {
if err == topo.ErrNodeExists {
log.Warningf("shard %v/%v already exists", keyspace, shard)
} else {
rec.RecordError(fmt.Errorf("CreateShard(%v, %v): %v", keyspace, shard, err))
return
}
}
si, err := fromTS.GetShard(keyspace, shard)
if err != nil {
rec.RecordError(fmt.Errorf("GetShard(%v, %v): %v", keyspace, shard, err))
return
}
if err := toTS.UpdateShard(si); err != nil {
rec.RecordError(fmt.Errorf("UpdateShard(%v, %v): %v", keyspace, shard, err))
}
}(keyspace, shard)
}
}(keyspace)
}
wg.Wait()
if rec.HasErrors() {
log.Fatalf("copyShards failed: %v", rec.Error())
}
}
示例4: CheckShardLock
// CheckShardLock checks we can take a shard lock
func CheckShardLock(ctx context.Context, t *testing.T, ts topo.Server) {
if err := ts.CreateKeyspace(ctx, "test_keyspace", &pb.Keyspace{}); err != nil {
t.Fatalf("CreateKeyspace: %v", err)
}
if err := topo.CreateShard(ctx, ts, "test_keyspace", "10-20"); err != nil {
t.Fatalf("CreateShard: %v", err)
}
checkShardLockTimeout(ctx, t, ts)
checkShardLockMissing(ctx, t, ts)
checkShardLockUnblocks(ctx, t, ts)
}
示例5: CreateShard
// CreateShard will create the shard, while holding the keyspace lock
func CreateShard(ctx context.Context, ts topo.Server, keyspace, shard string) error {
// Lock the keyspace
node := actionnode.KeyspaceCreateShard()
lockPath, err := node.LockKeyspace(ctx, ts, keyspace)
if err != nil {
return fmt.Errorf("LockKeyspace failed: %v", err)
}
// now try to create within the lock, may already exist
err = topo.CreateShard(ctx, ts, keyspace, shard)
// and unlock and return
return node.UnlockKeyspace(ctx, ts, keyspace, lockPath, err)
}
示例6: TestReparentTablet
func TestReparentTablet(t *testing.T) {
ctx := context.Background()
ts := zktopo.NewTestServer(t, []string{"cell1", "cell2"})
wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient(), time.Second)
// create shard and tablets
if err := topo.CreateShard(ctx, ts, "test_keyspace", "0"); err != nil {
t.Fatalf("CreateShard failed: %v", err)
}
master := NewFakeTablet(t, wr, "cell1", 1, pb.TabletType_MASTER)
slave := NewFakeTablet(t, wr, "cell1", 2, pb.TabletType_REPLICA)
// mark the master inside the shard
si, err := ts.GetShard(ctx, "test_keyspace", "0")
if err != nil {
t.Fatalf("GetShard failed: %v", err)
}
si.MasterAlias = master.Tablet.Alias
if err := topo.UpdateShard(ctx, ts, si); err != nil {
t.Fatalf("UpdateShard failed: %v", err)
}
// master action loop (to initialize host and port)
master.StartActionLoop(t, wr)
defer master.StopActionLoop(t)
// slave loop
slave.FakeMysqlDaemon.SetMasterCommandsInput = fmt.Sprintf("%v:%v", master.Tablet.Hostname, master.Tablet.PortMap["mysql"])
slave.FakeMysqlDaemon.SetMasterCommandsResult = []string{"set master cmd 1"}
slave.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{
"set master cmd 1",
}
slave.StartActionLoop(t, wr)
defer slave.StopActionLoop(t)
// run ReparentTablet
if err := wr.ReparentTablet(ctx, slave.Tablet.Alias); err != nil {
t.Fatalf("ReparentTablet failed: %v", err)
}
// check what was run
if err := slave.FakeMysqlDaemon.CheckSuperQueryList(); err != nil {
t.Fatalf("slave.FakeMysqlDaemon.CheckSuperQueryList failed: %v", err)
}
}
示例7: CheckShardLock
func CheckShardLock(t *testing.T, ts topo.Server) {
if err := ts.CreateKeyspace("test_keyspace", &topo.Keyspace{}); err != nil {
t.Fatalf("CreateKeyspace: %v", err)
}
if err := topo.CreateShard(ts, "test_keyspace", "10-20"); err != nil {
t.Fatalf("CreateShard: %v", err)
}
interrupted := make(chan struct{}, 1)
lockPath, err := ts.LockShardForAction("test_keyspace", "10-20", "fake-content", 5*time.Second, interrupted)
if err != nil {
t.Fatalf("LockShardForAction: %v", err)
}
// test we can't take the lock again
if _, err := ts.LockShardForAction("test_keyspace", "10-20", "unused-fake-content", time.Second/2, interrupted); err != topo.ErrTimeout {
t.Errorf("LockShardForAction(again): %v", err)
}
// test we can interrupt taking the lock
go func() {
time.Sleep(time.Second / 2)
close(interrupted)
}()
if _, err := ts.LockShardForAction("test_keyspace", "10-20", "unused-fake-content", 5*time.Second, interrupted); err != topo.ErrInterrupted {
t.Errorf("LockShardForAction(interrupted): %v", err)
}
if err := ts.UnlockShardForAction("test_keyspace", "10-20", lockPath, "fake-results"); err != nil {
t.Errorf("UnlockShardForAction(): %v", err)
}
// test we can't unlock again
if err := ts.UnlockShardForAction("test_keyspace", "10-20", lockPath, "fake-results"); err == nil {
t.Error("UnlockShardForAction(again) worked")
}
// test we can't lock a non-existing shard
interrupted = make(chan struct{}, 1)
if _, err := ts.LockShardForAction("test_keyspace", "20-30", "fake-content", 5*time.Second, interrupted); err == nil {
t.Fatalf("LockShardForAction(test_keyspace/20-30) worked for non-existing shard")
}
}
示例8: CheckShard
func CheckShard(t *testing.T, ts topo.Server) {
if err := ts.CreateKeyspace("test_keyspace", &topo.Keyspace{}); err != nil {
t.Fatalf("CreateKeyspace: %v", err)
}
if err := topo.CreateShard(ts, "test_keyspace", "b0-c0"); err != nil {
t.Fatalf("CreateShard: %v", err)
}
if err := topo.CreateShard(ts, "test_keyspace", "b0-c0"); err != topo.ErrNodeExists {
t.Errorf("CreateShard called second time, got: %v", err)
}
if _, err := ts.GetShard("test_keyspace", "666"); err != topo.ErrNoNode {
t.Errorf("GetShard(666): %v", err)
}
shardInfo, err := ts.GetShard("test_keyspace", "b0-c0")
if err != nil {
t.Errorf("GetShard: %v", err)
}
if want := newKeyRange("b0-c0"); shardInfo.KeyRange != want {
t.Errorf("shardInfo.KeyRange: want %v, got %v", want, shardInfo.KeyRange)
}
master := topo.TabletAlias{Cell: "ny", Uid: 1}
shardInfo.MasterAlias = master
shardInfo.KeyRange = newKeyRange("b0-c0")
shardInfo.ServedTypes = []topo.TabletType{topo.TYPE_MASTER, topo.TYPE_REPLICA, topo.TYPE_RDONLY}
shardInfo.SourceShards = []topo.SourceShard{
topo.SourceShard{
Uid: 1,
Keyspace: "source_ks",
Shard: "b8-c0",
KeyRange: newKeyRange("b8-c0"),
Tables: []string{"table1", "table2"},
},
}
if err := topo.UpdateShard(ts, shardInfo); err != nil {
t.Errorf("UpdateShard: %v", err)
}
shardInfo, err = ts.GetShard("test_keyspace", "b0-c0")
if err != nil {
t.Errorf("GetShard: %v", err)
}
if shardInfo.MasterAlias != master {
t.Errorf("after UpdateShard: shardInfo.MasterAlias got %v", shardInfo.MasterAlias)
}
if shardInfo.KeyRange != newKeyRange("b0-c0") {
t.Errorf("after UpdateShard: shardInfo.KeyRange got %v", shardInfo.KeyRange)
}
if len(shardInfo.ServedTypes) != 3 || shardInfo.ServedTypes[0] != topo.TYPE_MASTER || shardInfo.ServedTypes[1] != topo.TYPE_REPLICA || shardInfo.ServedTypes[2] != topo.TYPE_RDONLY {
t.Errorf("after UpdateShard: shardInfo.ServedTypes got %v", shardInfo.ServedTypes)
}
if len(shardInfo.SourceShards) != 1 ||
shardInfo.SourceShards[0].Uid != 1 ||
shardInfo.SourceShards[0].Keyspace != "source_ks" ||
shardInfo.SourceShards[0].Shard != "b8-c0" ||
shardInfo.SourceShards[0].KeyRange != newKeyRange("b8-c0") ||
len(shardInfo.SourceShards[0].Tables) != 2 ||
shardInfo.SourceShards[0].Tables[0] != "table1" ||
shardInfo.SourceShards[0].Tables[1] != "table2" {
t.Errorf("after UpdateShard: shardInfo.SourceShards got %v", shardInfo.SourceShards)
}
shards, err := ts.GetShardNames("test_keyspace")
if err != nil {
t.Errorf("GetShardNames: %v", err)
}
if len(shards) != 1 || shards[0] != "b0-c0" {
t.Errorf(`GetShardNames: want [ "b0-c0" ], got %v`, shards)
}
if _, err := ts.GetShardNames("test_keyspace666"); err != topo.ErrNoNode {
t.Errorf("GetShardNames(666): %v", err)
}
}
示例9: TestSplitDiff
func TestSplitDiff(t *testing.T) {
ts := zktopo.NewTestServer(t, []string{"cell1", "cell2"})
// We need to use FakeTabletManagerClient because we don't have a good way to fake the binlog player yet,
// which is necessary for synchronizing replication.
wr := wrangler.New(logutil.NewConsoleLogger(), ts, faketmclient.NewFakeTabletManagerClient(), time.Second)
ctx := context.Background()
sourceMaster := testlib.NewFakeTablet(t, wr, "cell1", 0,
topo.TYPE_MASTER, testlib.TabletKeyspaceShard(t, "ks", "-80"))
sourceRdonly1 := testlib.NewFakeTablet(t, wr, "cell1", 1,
topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "-80"))
sourceRdonly2 := testlib.NewFakeTablet(t, wr, "cell1", 2,
topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "-80"))
leftMaster := testlib.NewFakeTablet(t, wr, "cell1", 10,
topo.TYPE_MASTER, testlib.TabletKeyspaceShard(t, "ks", "-40"))
leftRdonly1 := testlib.NewFakeTablet(t, wr, "cell1", 11,
topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "-40"))
leftRdonly2 := testlib.NewFakeTablet(t, wr, "cell1", 12,
topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "-40"))
for _, ft := range []*testlib.FakeTablet{sourceMaster, sourceRdonly1, sourceRdonly2, leftMaster, leftRdonly1, leftRdonly2} {
ft.StartActionLoop(t, wr)
defer ft.StopActionLoop(t)
}
// add the topo and schema data we'll need
if err := topo.CreateShard(ctx, ts, "ks", "80-"); err != nil {
t.Fatalf("CreateShard(\"-80\") failed: %v", err)
}
wr.SetSourceShards(ctx, "ks", "-40", []topo.TabletAlias{sourceRdonly1.Tablet.Alias}, nil)
if err := wr.SetKeyspaceShardingInfo(ctx, "ks", "keyspace_id", pbt.KeyspaceIdType_UINT64, 4, false); err != nil {
t.Fatalf("SetKeyspaceShardingInfo failed: %v", err)
}
if err := wr.RebuildKeyspaceGraph(ctx, "ks", nil, true); err != nil {
t.Fatalf("RebuildKeyspaceGraph failed: %v", err)
}
excludedTable := "excludedTable1"
gwrk := NewSplitDiffWorker(wr, "cell1", "ks", "-40", []string{excludedTable})
wrk := gwrk.(*SplitDiffWorker)
for _, rdonly := range []*testlib.FakeTablet{sourceRdonly1, sourceRdonly2, leftRdonly1, leftRdonly2} {
// In reality, the destinations *shouldn't* have identical data to the source - instead, we should see
// the data split into left and right. However, if we do that in this test, we would really just be
// testing our fake SQL logic, since we do the data filtering in SQL.
// To simplify things, just assume that both sides have identical data.
rdonly.FakeMysqlDaemon.Schema = &myproto.SchemaDefinition{
DatabaseSchema: "",
TableDefinitions: []*myproto.TableDefinition{
&myproto.TableDefinition{
Name: "table1",
Columns: []string{"id", "msg", "keyspace_id"},
PrimaryKeyColumns: []string{"id"},
Type: myproto.TableBaseTable,
},
&myproto.TableDefinition{
Name: excludedTable,
Columns: []string{"id", "msg", "keyspace_id"},
PrimaryKeyColumns: []string{"id"},
Type: myproto.TableBaseTable,
},
&myproto.TableDefinition{
Name: "view1",
Type: myproto.TableView,
},
},
}
}
grpcqueryservice.RegisterForTest(leftRdonly1.RPCServer, &destinationSqlQuery{t: t, excludedTable: excludedTable})
grpcqueryservice.RegisterForTest(leftRdonly2.RPCServer, &destinationSqlQuery{t: t, excludedTable: excludedTable})
grpcqueryservice.RegisterForTest(sourceRdonly1.RPCServer, &sourceSqlQuery{t: t, excludedTable: excludedTable})
grpcqueryservice.RegisterForTest(sourceRdonly2.RPCServer, &sourceSqlQuery{t: t, excludedTable: excludedTable})
err := wrk.Run(ctx)
status := wrk.StatusAsText()
t.Logf("Got status: %v", status)
if err != nil || wrk.State != WorkerStateDone {
t.Errorf("Worker run failed")
}
}
示例10: 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
// update is true, and a tablet with the same ID exists, update it.
// If Force is true, and a tablet with the same ID already exists, it
// will be scrapped and deleted, and then recreated.
func (wr *Wrangler) InitTablet(tablet *topo.Tablet, force, createShardAndKeyspace, update bool) error {
if err := tablet.Complete(); err != nil {
return err
}
if tablet.IsInReplicationGraph() {
// create the parent keyspace and shard if needed
if createShardAndKeyspace {
if err := wr.ts.CreateKeyspace(tablet.Keyspace); err != nil && err != topo.ErrNodeExists {
return err
}
if err := topo.CreateShard(wr.ts, tablet.Keyspace, tablet.Shard); err != nil && err != topo.ErrNodeExists {
return err
}
}
// get the shard, checks a couple things
si, err := wr.ts.GetShard(tablet.Keyspace, tablet.Shard)
if err != nil {
return fmt.Errorf("missing parent shard, use -parent option to create it, or CreateKeyspace / CreateShard")
}
if 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 == topo.TYPE_MASTER && !si.MasterAlias.IsZero() && si.MasterAlias != tablet.Alias() && !force {
return fmt.Errorf("creating this tablet would override old master %v in shard %v/%v", si.MasterAlias, tablet.Keyspace, tablet.Shard)
}
// see if we specified a parent, otherwise get it from the shard
if tablet.Parent.IsZero() && tablet.Type.IsSlaveType() {
if si.MasterAlias.IsZero() {
return fmt.Errorf("trying to create tablet %v in shard %v/%v without a master", tablet.Alias(), tablet.Keyspace, tablet.Shard)
}
tablet.Parent = si.MasterAlias
}
// 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(tablet.Cell) {
shardUpdateRequired = true
}
if tablet.Type == topo.TYPE_MASTER && si.MasterAlias != tablet.Alias() {
shardUpdateRequired = true
}
if shardUpdateRequired {
actionNode := wr.ai.UpdateShard()
lockPath, err := wr.lockShard(tablet.Keyspace, tablet.Shard, actionNode)
if err != nil {
return err
}
// re-read the shard with the lock
si, err = wr.ts.GetShard(tablet.Keyspace, tablet.Shard)
if err != nil {
return wr.unlockShard(tablet.Keyspace, tablet.Shard, actionNode, lockPath, err)
}
// update it
wasUpdated := false
if !si.HasCell(tablet.Cell) {
si.Cells = append(si.Cells, tablet.Cell)
wasUpdated = true
}
if tablet.Type == topo.TYPE_MASTER && si.MasterAlias != tablet.Alias() {
if !si.MasterAlias.IsZero() && !force {
return wr.unlockShard(tablet.Keyspace, tablet.Shard, actionNode, lockPath, fmt.Errorf("creating this tablet would override old master %v in shard %v/%v", si.MasterAlias, tablet.Keyspace, tablet.Shard))
}
si.MasterAlias = tablet.Alias()
wasUpdated = true
}
if wasUpdated {
// write it back
if err := wr.ts.UpdateShard(si); err != nil {
return wr.unlockShard(tablet.Keyspace, tablet.Shard, actionNode, lockPath, err)
}
}
// and unlock
if err := wr.unlockShard(tablet.Keyspace, tablet.Shard, actionNode, lockPath, err); err != nil {
return err
}
// also create the cell's ShardReplication
if err := wr.ts.CreateShardReplication(tablet.Cell, tablet.Keyspace, tablet.Shard, &topo.ShardReplication{}); err != nil && err != topo.ErrNodeExists {
return err
}
}
}
//.........这里部分代码省略.........
示例11: CheckShard
func CheckShard(t *testing.T, ts topo.Server) {
if err := ts.CreateKeyspace("test_keyspace", &topo.Keyspace{}); err != nil {
t.Fatalf("CreateKeyspace: %v", err)
}
if err := topo.CreateShard(ts, "test_keyspace", "b0-c0"); err != nil {
t.Fatalf("CreateShard: %v", err)
}
if err := topo.CreateShard(ts, "test_keyspace", "b0-c0"); err != topo.ErrNodeExists {
t.Errorf("CreateShard called second time, got: %v", err)
}
if _, err := ts.GetShard("test_keyspace", "666"); err != topo.ErrNoNode {
t.Errorf("GetShard(666): %v", err)
}
shardInfo, err := ts.GetShard("test_keyspace", "b0-c0")
if err != nil {
t.Errorf("GetShard: %v", err)
}
if want := newKeyRange("b0-c0"); shardInfo.KeyRange != want {
t.Errorf("shardInfo.KeyRange: want %v, got %v", want, shardInfo.KeyRange)
}
master := topo.TabletAlias{Cell: "ny", Uid: 1}
shardInfo.MasterAlias = master
shardInfo.KeyRange = newKeyRange("b0-c0")
shardInfo.ServedTypes = []topo.TabletType{topo.TYPE_MASTER, topo.TYPE_REPLICA, topo.TYPE_RDONLY}
shardInfo.SourceShards = []topo.SourceShard{
topo.SourceShard{
Uid: 1,
Keyspace: "source_ks",
Shard: "b8-c0",
KeyRange: newKeyRange("b8-c0"),
Tables: []string{"table1", "table2"},
},
}
shardInfo.BlacklistedTablesMap = map[topo.TabletType][]string{
topo.TYPE_MASTER: []string{"black1", "black2"},
topo.TYPE_REPLICA: []string{"black3", "black4"},
}
if err := topo.UpdateShard(ts, shardInfo); err != nil {
t.Errorf("UpdateShard: %v", err)
}
updatedShardInfo, err := ts.GetShard("test_keyspace", "b0-c0")
if err != nil {
t.Fatalf("GetShard: %v", err)
}
if eq, err := shardEqual(shardInfo.Shard, updatedShardInfo.Shard); err != nil {
t.Errorf("cannot compare shards: %v", err)
} else if !eq {
t.Errorf("put and got shards are not identical:\n%#v\n%#v", shardInfo.Shard, updatedShardInfo.Shard)
}
// test GetShardNames
shards, err := ts.GetShardNames("test_keyspace")
if err != nil {
t.Errorf("GetShardNames: %v", err)
}
if len(shards) != 1 || shards[0] != "b0-c0" {
t.Errorf(`GetShardNames: want [ "b0-c0" ], got %v`, shards)
}
if _, err := ts.GetShardNames("test_keyspace666"); err != topo.ErrNoNode {
t.Errorf("GetShardNames(666): %v", err)
}
}
示例12: RebuildReplicationGraph
// This is a quick and dirty tool to resurrect the TopologyServer data from the
// canonical data stored in the tablet nodes.
//
// cells: local vt cells to scan for all tablets
// keyspaces: list of keyspaces to rebuild
func (wr *Wrangler) RebuildReplicationGraph(cells []string, keyspaces []string) error {
if cells == nil || len(cells) == 0 {
return fmt.Errorf("must specify cells to rebuild replication graph")
}
if keyspaces == nil || len(keyspaces) == 0 {
return fmt.Errorf("must specify keyspaces to rebuild replication graph")
}
allTablets := make([]*topo.TabletInfo, 0, 1024)
for _, cell := range cells {
tablets, err := GetAllTablets(wr.ts, cell)
if err != nil {
return err
}
allTablets = append(allTablets, tablets...)
}
for _, keyspace := range keyspaces {
log.V(6).Infof("delete keyspace shards: %v", keyspace)
if err := wr.ts.DeleteKeyspaceShards(keyspace); err != nil {
return err
}
}
keyspacesToRebuild := make(map[string]bool)
shardsCreated := make(map[string]bool)
hasErr := false
mu := sync.Mutex{}
wg := sync.WaitGroup{}
for _, ti := range allTablets {
wg.Add(1)
go func(ti *topo.TabletInfo) {
defer wg.Done()
if !ti.IsInReplicationGraph() {
return
}
if !strInList(keyspaces, ti.Keyspace) {
return
}
mu.Lock()
keyspacesToRebuild[ti.Keyspace] = true
shardPath := ti.Keyspace + "/" + ti.Shard
if !shardsCreated[shardPath] {
if err := topo.CreateShard(wr.ts, ti.Keyspace, ti.Shard); err != nil && err != topo.ErrNodeExists {
log.Warningf("failed re-creating shard %v: %v", shardPath, err)
hasErr = true
} else {
shardsCreated[shardPath] = true
}
}
mu.Unlock()
err := topo.CreateTabletReplicationData(wr.ts, ti.Tablet)
if err != nil {
mu.Lock()
hasErr = true
mu.Unlock()
log.Warningf("failed creating replication path: %v", err)
}
}(ti)
}
wg.Wait()
for keyspace := range keyspacesToRebuild {
wg.Add(1)
go func(keyspace string) {
defer wg.Done()
if err := wr.RebuildKeyspaceGraph(keyspace, nil); err != nil {
mu.Lock()
hasErr = true
mu.Unlock()
log.Warningf("RebuildKeyspaceGraph(%v) failed: %v", keyspace, err)
return
}
}(keyspace)
}
wg.Wait()
if hasErr {
return fmt.Errorf("some errors occurred rebuilding replication graph, consult log")
}
return nil
}
示例13: 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
// update is true, and a tablet with the same ID exists, update it.
// If Force is true, and a tablet with the same ID already exists, it
// will be scrapped and deleted, and then recreated.
func (wr *Wrangler) InitTablet(tablet *topo.Tablet, force, createShardAndKeyspace, update bool) error {
if err := tablet.Complete(); err != nil {
return err
}
if tablet.Parent.IsZero() && tablet.Type.IsSlaveType() {
parentAlias, err := wr.getMasterAlias(tablet.Keyspace, tablet.Shard)
if err != nil {
return err
}
tablet.Parent = parentAlias
}
if tablet.IsInReplicationGraph() {
// create the parent keyspace and shard if needed
if createShardAndKeyspace {
if err := wr.ts.CreateKeyspace(tablet.Keyspace); err != nil && err != topo.ErrNodeExists {
return err
}
if err := topo.CreateShard(wr.ts, tablet.Keyspace, tablet.Shard); err != nil && err != topo.ErrNodeExists {
return err
}
}
// get the shard, checks KeyRange is the same
si, err := wr.ts.GetShard(tablet.Keyspace, tablet.Shard)
if err != nil {
return fmt.Errorf("Missing parent shard, use -parent option to create it, or CreateKeyspace / CreateShard")
}
if si.KeyRange != tablet.KeyRange {
return fmt.Errorf("Shard %v/%v has a different KeyRange: %v != %v", tablet.Keyspace, tablet.Shard, si.KeyRange, tablet.KeyRange)
}
}
err := topo.CreateTablet(wr.ts, tablet)
if err != nil && err == topo.ErrNodeExists {
// Try to update nicely, but if it fails fall back to force behavior.
if update {
oldTablet, err := wr.ts.GetTablet(tablet.Alias())
if err != nil {
relog.Warning("failed reading tablet %v: %v", tablet.Alias(), err)
} else {
if oldTablet.Keyspace == tablet.Keyspace && oldTablet.Shard == tablet.Shard {
*(oldTablet.Tablet) = *tablet
err := topo.UpdateTablet(wr.ts, oldTablet)
if err != nil {
relog.Warning("failed updating tablet %v: %v", tablet.Alias(), err)
} else {
return nil
}
}
}
}
if force {
if _, err = wr.Scrap(tablet.Alias(), force, false); err != nil {
relog.Error("failed scrapping tablet %v: %v", tablet.Alias(), err)
return err
}
if err := wr.ts.DeleteTablet(tablet.Alias()); err != nil {
// we ignore this
relog.Error("failed deleting tablet %v: %v", tablet.Alias(), err)
}
return topo.CreateTablet(wr.ts, tablet)
}
}
return err
}
示例14: TestSplitClone
func TestSplitClone(t *testing.T) {
ts := zktopo.NewTestServer(t, []string{"cell1", "cell2"})
wr := wrangler.New(logutil.NewConsoleLogger(), ts, time.Minute, time.Second)
sourceMaster := testlib.NewFakeTablet(t, wr, "cell1", 0,
topo.TYPE_MASTER, testlib.TabletKeyspaceShard(t, "ks", "-80"))
sourceRdonly := testlib.NewFakeTablet(t, wr, "cell1", 1,
topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "-80"),
testlib.TabletParent(sourceMaster.Tablet.Alias))
leftMaster := testlib.NewFakeTablet(t, wr, "cell1", 10,
topo.TYPE_MASTER, testlib.TabletKeyspaceShard(t, "ks", "-40"))
leftRdonly := testlib.NewFakeTablet(t, wr, "cell1", 11,
topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "-40"),
testlib.TabletParent(leftMaster.Tablet.Alias))
rightMaster := testlib.NewFakeTablet(t, wr, "cell1", 20,
topo.TYPE_MASTER, testlib.TabletKeyspaceShard(t, "ks", "40-80"))
rightRdonly := testlib.NewFakeTablet(t, wr, "cell1", 21,
topo.TYPE_RDONLY, testlib.TabletKeyspaceShard(t, "ks", "40-80"),
testlib.TabletParent(rightMaster.Tablet.Alias))
for _, ft := range []*testlib.FakeTablet{sourceMaster, sourceRdonly, leftMaster, leftRdonly, rightMaster, rightRdonly} {
ft.StartActionLoop(t, wr)
defer ft.StopActionLoop(t)
}
// add the topo and schema data we'll need
if err := topo.CreateShard(ts, "ks", "80-"); err != nil {
t.Fatalf("CreateShard(\"-80\") failed: %v", err)
}
if err := wr.SetKeyspaceShardingInfo("ks", "keyspace_id", key.KIT_UINT64, 4, false); err != nil {
t.Fatalf("SetKeyspaceShardingInfo failed: %v", err)
}
if err := wr.RebuildKeyspaceGraph("ks", nil); err != nil {
t.Fatalf("RebuildKeyspaceGraph failed: %v", err)
}
sourceRdonly.FakeMysqlDaemon.Schema = &myproto.SchemaDefinition{
DatabaseSchema: "CREATE DATABASE `{{.DatabaseName}}` /*!40100 DEFAULT CHARACTER SET utf8 */",
TableDefinitions: []*myproto.TableDefinition{
&myproto.TableDefinition{
Name: "table1",
Schema: "CREATE TABLE `resharding1` (\n `id` bigint(20) NOT NULL AUTO_INCREMENT,\n `msg` varchar(64) DEFAULT NULL,\n `keyspace_id` bigint(20) unsigned NOT NULL,\n PRIMARY KEY (`id`),\n KEY `by_msg` (`msg`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8",
Columns: []string{"id", "msg", "keyspace_id"},
PrimaryKeyColumns: []string{"id"},
Type: myproto.TABLE_BASE_TABLE,
DataLength: 2048,
RowCount: 100,
},
},
Version: "unused",
}
sourceRdonly.FakeMysqlDaemon.DbaConnectionFactory = SourceRdonlyFactory(t)
sourceRdonly.FakeMysqlDaemon.CurrentSlaveStatus = &myproto.ReplicationStatus{
Position: myproto.ReplicationPosition{
GTIDSet: myproto.MariadbGTID{Domain: 12, Server: 34, Sequence: 5678},
},
}
sourceRdonly.RpcServer.Register(&SqlQuery{t: t})
leftMaster.FakeMysqlDaemon.DbaConnectionFactory = DestinationsFactory(t, 50)
leftRdonly.FakeMysqlDaemon.DbaConnectionFactory = DestinationsFactory(t, 50)
rightMaster.FakeMysqlDaemon.DbaConnectionFactory = DestinationsFactory(t, 50)
rightRdonly.FakeMysqlDaemon.DbaConnectionFactory = DestinationsFactory(t, 50)
wrk := NewSplitCloneWorker(wr, "cell1", "ks", "-80", nil, "populateBlpCheckpoint", 10, 1, 10).(*SplitCloneWorker)
wrk.Run()
status := wrk.StatusAsText()
t.Logf("Got status: %v", status)
if wrk.err != nil || wrk.state != stateSCDone {
t.Errorf("Worker run failed")
}
}
示例15: 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
// update is true, and a tablet with the same ID exists, update it.
// If Force is true, and a tablet with the same ID already exists, it
// will be scrapped and deleted, and then recreated.
func (wr *Wrangler) InitTablet(tablet *topo.Tablet, force, createShardAndKeyspace, update bool) error {
if err := tablet.Complete(); err != nil {
return err
}
if tablet.Parent.IsZero() && tablet.Type.IsSlaveType() {
parentAlias, err := wr.getMasterAlias(tablet.Keyspace, tablet.Shard)
if err != nil {
return err
}
tablet.Parent = parentAlias
}
if tablet.IsInReplicationGraph() {
// create the parent keyspace and shard if needed
if createShardAndKeyspace {
if err := wr.ts.CreateKeyspace(tablet.Keyspace); err != nil && err != topo.ErrNodeExists {
return err
}
if err := topo.CreateShard(wr.ts, tablet.Keyspace, tablet.Shard); err != nil && err != topo.ErrNodeExists {
return err
}
}
// get the shard, checks KeyRange is the same
si, err := wr.ts.GetShard(tablet.Keyspace, tablet.Shard)
if err != nil {
return fmt.Errorf("Missing parent shard, use -parent option to create it, or CreateKeyspace / CreateShard")
}
if si.KeyRange != tablet.KeyRange {
return fmt.Errorf("Shard %v/%v has a different KeyRange: %v != %v", tablet.Keyspace, tablet.Shard, si.KeyRange, tablet.KeyRange)
}
// add the tablet's cell to the shard cell if needed
if !si.HasCell(tablet.Cell) {
actionNode := wr.ai.UpdateShard()
lockPath, err := wr.lockShard(tablet.Keyspace, tablet.Shard, actionNode)
if err != nil {
return err
}
// re-read the shard with the lock
si, err = wr.ts.GetShard(tablet.Keyspace, tablet.Shard)
if err != nil {
return wr.unlockShard(tablet.Keyspace, tablet.Shard, actionNode, lockPath, err)
}
// update it
if !si.HasCell(tablet.Cell) {
si.Cells = append(si.Cells, tablet.Cell)
// write it back
if err := wr.ts.UpdateShard(si); err != nil {
return wr.unlockShard(tablet.Keyspace, tablet.Shard, actionNode, lockPath, err)
}
}
// and unlock
if err := wr.unlockShard(tablet.Keyspace, tablet.Shard, actionNode, lockPath, err); err != nil {
return err
}
// also create the cell's ShardReplication
if err := wr.ts.CreateShardReplication(tablet.Cell, tablet.Keyspace, tablet.Shard, &topo.ShardReplication{}); err != nil && err != topo.ErrNodeExists {
return err
}
}
}
err := topo.CreateTablet(wr.ts, tablet)
if err != nil && err == topo.ErrNodeExists {
// Try to update nicely, but if it fails fall back to force behavior.
if update {
oldTablet, err := wr.ts.GetTablet(tablet.Alias())
if err != nil {
log.Warningf("failed reading tablet %v: %v", tablet.Alias(), err)
} else {
if oldTablet.Keyspace == tablet.Keyspace && oldTablet.Shard == tablet.Shard {
*(oldTablet.Tablet) = *tablet
err := topo.UpdateTablet(wr.ts, oldTablet)
if err != nil {
log.Warningf("failed updating tablet %v: %v", tablet.Alias(), err)
} else {
return nil
}
}
}
}
if force {
if _, err = wr.Scrap(tablet.Alias(), force, false); err != nil {
log.Errorf("failed scrapping tablet %v: %v", tablet.Alias(), err)
return err
}
//.........这里部分代码省略.........