// restore the main proxy data. func (m *MysqlProxy) InitMain() { pr, err := redis.ReadDB("MysqlProxy", "main") CheckError(err) if len(pr) == 0 { return } for _, proxy := range pr { proxy = proxy["main"].(map[string]interface{}) m.TableTotal = uint64(proxy["TableTotal"].(float64)) m.SizeTotal = uint64(proxy["SizeTotal"].(float64)) m.CurGId = uint64(proxy["CurGId"].(float64)) if ttableIds, isOk := proxy["TableIds"].([]interface{}); isOk && len(ttableIds) > 0 { m.TableIds = redis.RestorePrimaryId(ttableIds) } else { m.TableIds = []string{} } if dbIds, isOk := proxy["ShardDBIds"].([]interface{}); isOk && len(dbIds) > 0 { m.ShardDBIds = redis.RestorePrimaryId(dbIds) } else { m.ShardDBIds = []string{} } m.ShardDBCnt = int(proxy["ShardDBCnt"].(float64)) schema.ShardDBCnt = m.ShardDBCnt } // panic(fmt.Sprintf("%#v", m)) }
// get the shard db by ids. func (m *MysqlProxy) GetShardDbById(sid string) (*schema.MysqlShardDB, error) { if sid == "" { return nil, errors.New("Sorry, the shard db id connot is empty") } sdb, err := redis.ReadDB("MysqlShardDB", sid) if err != nil { return nil, err } if len(sdb) != 1 { return nil, errors.New("Load shard db wrong!") } tsdb := sdb[0][sid].(map[string]interface{}) groupId := tsdb["HostGroupId"].(string) curGroup, err := host.GetHostGroupById(groupId) if err != nil { return nil, err } shardDB := &schema.MysqlShardDB{ Id: tsdb["Id"].(string), Name: tsdb["Name"].(string), TableTotal: uint64(tsdb["TableTotal"].(float64)), SizeTotal: uint64(tsdb["SizeTotal"].(float64)), HostGroupId: groupId, Created: int64(tsdb["Created"].(float64)), HostGroup: curGroup, } schema.ShardDBCnt++ return shardDB, nil }
// to init or restore the table infomation. func (m *MysqlProxy) InitMysqlTable() { if len(m.TableIds) == 0 { return } // 分析数据,并恢复至MysqlProxy结构体中. tables := []*schema.MysqlTable{} for _, tid := range m.TableIds { tbs, err := redis.ReadDB("MysqlTable", tid) CheckError(err) if len(tbs) != 1 { panic("no found relation table for id: " + tid) } tb := tbs[0][tid].(map[string]interface{}) // panic(fmt.Sprintf("%#v", tbs)) shardTbIds := []string{} if std, isOk := tb["ShardIds"].([]interface{}); isOk && len(std) > 0 { shardTbIds = redis.RestorePrimaryId(std) } shardTb := []*schema.MysqlShardTable{} table := &schema.MysqlTable{ Id: tb["Id"].(string), Name: tb["Name"].(string), CurGId: uint64(tb["CurGId"].(float64)), RowTotal: uint64(tb["RowTotal"].(float64)), ShardIds: shardTbIds, Created: int64(tb["Created"].(float64)), Shards: shardTb, } if len(shardTbIds) > 0 { // create new shard table shardTb, err = m.GetShardTableByIds(shardTbIds) CheckError(err) table.Shards = shardTb err = table.RestoreColumnsByDB() CheckError(err) } // fmt.Printf("Init table `%s` done\n", table.Name) tables = append(tables, table) } m.Tables = tables schema.Tables = m.Tables }
// to get shard table info. func (m *MysqlProxy) GetShardTableByIds(ids []string) ([]*schema.MysqlShardTable, error) { if len(ids) == 0 { return nil, nil } tables := []*schema.MysqlShardTable{} for _, id := range ids { tbs, err := redis.ReadDB("MysqlShardTable", id) if err != nil { return nil, err } if len(tbs) != 1 { return nil, errors.New("no found the shard table for id: " + id) } tb := tbs[0][id].(map[string]interface{}) shardDbId := tb["ShardDBId"].(string) shardDb, err := m.GetShardDbById(shardDbId) if err != nil { return nil, err } shardTable := &schema.MysqlShardTable{ Id: tb["Id"].(string), Name: tb["Name"].(string), RowTotal: uint64(tb["RowTotal"].(float64)), ShardDBId: shardDbId, Created: int64(tb["Created"].(float64)), ShardDB: shardDb, } tables = append(tables, shardTable) } return tables, nil }
// get the current db cluster data infomations func (m *MysqlProxy) InitMysqlDB() { // panic(fmt.Sprintf("%#v, %#v", m.ShardDBIds, len(m.ShardDBIds))) if len(m.ShardDBIds) == 0 { // init the shard DB shardDBs := []*schema.MysqlShardDB{} shardDBIds := []string{} m.ShardDBCnt = 0 for _, group := range host.Groups { m.ShardDBCnt++ shardDb, err := m.BuildNewShardDB(&group, "shard"+strconv.Itoa(m.ShardDBCnt)) CheckError(err) shardDBs = append(shardDBs, shardDb) shardDBIds = append(shardDBIds, shardDb.Id) } m.ShardDBs = shardDBs m.ShardDBIds = shardDBIds // to prepare save new data. isUpdated = true // add shard dbs map. schema.Sdbs = shardDBs } else { // 分析数据,并恢复至MysqlProxy结构体中. shardDBs := []*schema.MysqlShardDB{} for _, sid := range m.ShardDBIds { dbs, err := redis.ReadDB("MysqlShardDB", sid) CheckError(err) if len(dbs) != 1 { panic("no found relation shard db for id:" + sid) } sdb := dbs[0][sid].(map[string]interface{}) groupId := sdb["HostGroupId"].(string) curGroup, err := host.GetHostGroupById(groupId) CheckError(err) shardDB := &schema.MysqlShardDB{ Id: sdb["Id"].(string), Name: sdb["Name"].(string), TableTotal: uint64(sdb["TableTotal"].(float64)), SizeTotal: uint64(sdb["SizeTotal"].(float64)), HostGroupId: groupId, Created: int64(sdb["Created"].(float64)), HostGroup: curGroup, } shardDBs = append(shardDBs, shardDB) } m.ShardDBs = shardDBs // add shard dbs map. schema.Sdbs = shardDBs } // listen the sharddb change status. locker := &sync.Mutex{} go func() { for { newShardDB := <-schema.NewShardDBCh locker.Lock() defer locker.Unlock() m.ShardDBIds = append(m.ShardDBIds, newShardDB.Id) m.ShardDBs = append(m.ShardDBs, newShardDB) schema.Sdbs = m.ShardDBs err := redis.UpdateDB("main", redis.EncodeData(m), "MysqlProxy") if err != nil { log.Printf("new shard db listener error:%s", err) } m.ShardDBCnt++ schema.ShardDBCnt = m.ShardDBCnt fmt.Printf("current shard total: %d\n", schema.ShardDBCnt) } }() // listen the table drop action. go func() { for { dropedTable := <-schema.DropedTableCh m.DeleteTable(dropedTable) } }() // panic(fmt.Sprintf("in init shard db: %#v, %#v", m)) }