func (do *Domain) getAllSchemasWithTablesFromMeta(m *meta.Meta) ([]*model.DBInfo, error) { schemas, err := m.ListDatabases() if err != nil { return nil, errors.Trace(err) } for _, di := range schemas { if di.State != model.StatePublic { // schema is not public, can't be used outside. continue } tables, err1 := m.ListTables(di.ID) if err1 != nil { err = err1 return nil, errors.Trace(err1) } di.Tables = make([]*model.TableInfo, 0, len(tables)) for _, tbl := range tables { if tbl.State != model.StatePublic { // schema is not public, can't be used outside. continue } di.Tables = append(di.Tables, tbl) } } return schemas, nil }
func (d *ddl) delReorgSchema(t *meta.Meta, job *model.Job) error { dbInfo := &model.DBInfo{} if err := job.DecodeArgs(dbInfo); err != nil { // arg error, cancel this job. job.State = model.JobCancelled return errors.Trace(err) } tables, err := t.ListTables(dbInfo.ID) if terror.ErrorEqual(meta.ErrDBNotExists, err) { job.State = model.JobDone return nil } if err != nil { return errors.Trace(err) } if err = d.dropSchemaData(dbInfo, tables); err != nil { return errors.Trace(err) } // finish this background job job.SchemaState = model.StateNone job.State = model.JobDone return nil }
func (d *ddl) onCreateTable(t *meta.Meta, job *model.Job) error { schemaID := job.SchemaID tbInfo := &model.TableInfo{} if err := job.DecodeArgs(tbInfo); err != nil { // arg error, cancel this job. job.State = model.JobCancelled return errors.Trace(err) } tbInfo.State = model.StateNone tables, err := t.ListTables(schemaID) if terror.ErrorEqual(err, meta.ErrDBNotExists) { job.State = model.JobCancelled return errors.Trace(infoschema.ErrDatabaseNotExists) } else if err != nil { return errors.Trace(err) } for _, tbl := range tables { if tbl.Name.L == tbInfo.Name.L { if tbl.ID != tbInfo.ID { // table exists, can't create, we should cancel this job now. job.State = model.JobCancelled return errors.Trace(infoschema.ErrTableExists) } tbInfo = tbl } } ver, err := updateSchemaVersion(t, job) if err != nil { return errors.Trace(err) } switch tbInfo.State { case model.StateNone: // none -> public job.SchemaState = model.StatePublic tbInfo.State = model.StatePublic err = t.CreateTable(schemaID, tbInfo) if err != nil { return errors.Trace(err) } // finish this job job.State = model.JobDone addTableHistoryInfo(job, ver, tbInfo) return nil default: return ErrInvalidTableState.Gen("invalid table state %v", tbInfo.State) } }
func (d *ddl) onDropSchema(t *meta.Meta, job *model.Job) error { dbInfo, err := t.GetDatabase(job.SchemaID) if err != nil { return errors.Trace(err) } if dbInfo == nil { job.State = model.JobCancelled return errors.Trace(infoschema.ErrDatabaseDropExists) } ver, err := updateSchemaVersion(t, job) if err != nil { return errors.Trace(err) } switch dbInfo.State { case model.StatePublic: // public -> write only job.SchemaState = model.StateWriteOnly dbInfo.State = model.StateWriteOnly err = t.UpdateDatabase(dbInfo) case model.StateWriteOnly: // write only -> delete only job.SchemaState = model.StateDeleteOnly dbInfo.State = model.StateDeleteOnly err = t.UpdateDatabase(dbInfo) case model.StateDeleteOnly: dbInfo.State = model.StateNone tables, err := t.ListTables(job.SchemaID) if err != nil { return errors.Trace(err) } err = t.UpdateDatabase(dbInfo) if err = t.DropDatabase(dbInfo.ID); err != nil { break } // finish this job addDBHistoryInfo(job, ver, dbInfo) if len(tables) > 0 { job.Args = append(job.Args, getIDs(tables)) } job.State = model.JobDone job.SchemaState = model.StateNone default: // we can't enter here. err = errors.Errorf("invalid db state %v", dbInfo.State) } return errors.Trace(err) }
func (do *Domain) fetchSchemasWithTables(schemas []*model.DBInfo, m *meta.Meta, done chan error) { for _, di := range schemas { if di.State != model.StatePublic { // schema is not public, can't be used outside. continue } tables, err := m.ListTables(di.ID) if err != nil { done <- err return } di.Tables = make([]*model.TableInfo, 0, len(tables)) for _, tbl := range tables { if tbl.State != model.StatePublic { // schema is not public, can't be used outside. continue } di.Tables = append(di.Tables, tbl) } } done <- nil }
func (d *ddl) onDropSchema(t *meta.Meta, job *model.Job) error { dbInfo, err := t.GetDatabase(job.SchemaID) if err != nil { return errors.Trace(err) } if dbInfo == nil { job.State = model.JobCancelled return errors.Trace(ErrNotExists) } _, err = t.GenSchemaVersion() if err != nil { return errors.Trace(err) } switch dbInfo.State { case model.StatePublic: // public -> write only job.SchemaState = model.StateWriteOnly dbInfo.State = model.StateWriteOnly err = t.UpdateDatabase(dbInfo) return errors.Trace(err) case model.StateWriteOnly: // write only -> delete only job.SchemaState = model.StateDeleteOnly dbInfo.State = model.StateDeleteOnly err = t.UpdateDatabase(dbInfo) return errors.Trace(err) case model.StateDeleteOnly: // delete only -> reorganization job.SchemaState = model.StateDeleteReorganization dbInfo.State = model.StateDeleteReorganization err = t.UpdateDatabase(dbInfo) return errors.Trace(err) case model.StateDeleteReorganization: // wait reorganization jobs done and drop meta. var tables []*model.TableInfo tables, err = t.ListTables(dbInfo.ID) if err != nil { return errors.Trace(err) } err = d.runReorgJob(func() error { return d.dropSchemaData(dbInfo, tables) }) if terror.ErrorEqual(err, errWaitReorgTimeout) { // if timeout, we should return, check for the owner and re-wait job done. return nil } if err != nil { return errors.Trace(err) } // all reorganization jobs done, drop this database if err = t.DropDatabase(dbInfo.ID); err != nil { return errors.Trace(err) } // finish this job job.State = model.JobDone job.SchemaState = model.StateNone return nil default: // we can't enter here. return errors.Errorf("invalid db state %v", dbInfo.State) } }
func (d *ddl) onCreateTable(t *meta.Meta, job *model.Job) error { schemaID := job.SchemaID tbInfo := &model.TableInfo{} if err := job.DecodeArgs(tbInfo); err != nil { // arg error, cancel this job. job.State = model.JobCancelled return errors.Trace(err) } tbInfo.State = model.StateNone tables, err := t.ListTables(schemaID) if terror.ErrorEqual(err, meta.ErrDBNotExists) { job.State = model.JobCancelled return errors.Trace(terror.DatabaseNotExists) } else if err != nil { return errors.Trace(err) } for _, tbl := range tables { if tbl.Name.L == tbInfo.Name.L { if tbl.ID != tbInfo.ID { // table exists, can't create, we should cancel this job now. job.State = model.JobCancelled return errors.Trace(ErrExists) } tbInfo = tbl } } _, err = t.GenSchemaVersion() if err != nil { return errors.Trace(err) } switch tbInfo.State { case model.StateNone: // none -> delete only job.SchemaState = model.StateDeleteOnly tbInfo.State = model.StateDeleteOnly err = t.CreateTable(schemaID, tbInfo) return errors.Trace(err) case model.StateDeleteOnly: // delete only -> write only job.SchemaState = model.StateWriteOnly tbInfo.State = model.StateWriteOnly err = t.UpdateTable(schemaID, tbInfo) return errors.Trace(err) case model.StateWriteOnly: // write only -> public job.SchemaState = model.StatePublic tbInfo.State = model.StatePublic err = t.UpdateTable(schemaID, tbInfo) if err != nil { return errors.Trace(err) } // finish this job job.State = model.JobDone return nil default: return errors.Errorf("invalid table state %v", tbInfo.State) } }