// loadInfoSchema loads infoschema at startTS into handle, usedSchemaVersion is the currently used // infoschema version, if it is the same as the schema version at startTS, we don't need to reload again. func (do *Domain) loadInfoSchema(handle *infoschema.Handle, usedSchemaVersion int64, startTS uint64) error { snapshot, err := do.store.GetSnapshot(kv.NewVersion(startTS)) if err != nil { return errors.Trace(err) } m := meta.NewSnapshotMeta(snapshot) latestSchemaVersion, err := m.GetSchemaVersion() if err != nil { return errors.Trace(err) } if usedSchemaVersion != 0 && usedSchemaVersion == latestSchemaVersion { log.Debugf("[ddl] schema version is still %d, no need reload", usedSchemaVersion) return nil } ok, err := do.tryLoadSchemaDiffs(m, usedSchemaVersion, latestSchemaVersion) if err != nil { // We can fall back to full load, don't need to return the error. log.Errorf("[ddl] failed to load schema diff %v", err) } if ok { log.Infof("[ddl] diff load InfoSchema from version %d to %d", usedSchemaVersion, latestSchemaVersion) return nil } schemas, err := do.getAllSchemasWithTablesFromMeta(m) if err != nil { return errors.Trace(err) } newISBuilder, err := infoschema.NewBuilder(handle).InitWithDBInfos(schemas, latestSchemaVersion) if err != nil { return errors.Trace(err) } log.Infof("[ddl] full load InfoSchema from version %d to %d", usedSchemaVersion, latestSchemaVersion) return newISBuilder.Build() }
func (s *testSuite) TestSnapshot(c *C) { defer testleak.AfterTest(c)() driver := localstore.Driver{Driver: goleveldb.MemoryDriver{}} store, err := driver.Open("memory") c.Assert(err, IsNil) defer store.Close() txn, _ := store.Begin() m := meta.NewMeta(txn) m.GenGlobalID() n, _ := m.GetGlobalID() c.Assert(n, Equals, int64(1)) txn.Commit() ver1, _ := store.CurrentVersion() time.Sleep(time.Millisecond) txn, _ = store.Begin() m = meta.NewMeta(txn) m.GenGlobalID() n, _ = m.GetGlobalID() c.Assert(n, Equals, int64(2)) txn.Commit() snapshot, _ := store.GetSnapshot(ver1) snapMeta := meta.NewSnapshotMeta(snapshot) n, _ = snapMeta.GetGlobalID() c.Assert(n, Equals, int64(1)) _, err = snapMeta.GenGlobalID() c.Assert(err, NotNil) }
// loadInfoSchema loads infoschema at startTS into handle, usedSchemaVersion is the currently used // infoschema version, if it is the same as the schema version at startTS, we don't need to reload again. // It returns the latest schema version and an error. func (do *Domain) loadInfoSchema(handle *infoschema.Handle, usedSchemaVersion int64, startTS uint64) (int64, error) { snapshot, err := do.store.GetSnapshot(kv.NewVersion(startTS)) if err != nil { return 0, errors.Trace(err) } m := meta.NewSnapshotMeta(snapshot) latestSchemaVersion, err := m.GetSchemaVersion() if err != nil { return 0, errors.Trace(err) } if usedSchemaVersion != 0 && usedSchemaVersion == latestSchemaVersion { return latestSchemaVersion, nil } startTime := time.Now() ok, err := do.tryLoadSchemaDiffs(m, usedSchemaVersion, latestSchemaVersion) if err != nil { // We can fall back to full load, don't need to return the error. log.Errorf("[ddl] failed to load schema diff err %v", err) } if ok { log.Infof("[ddl] diff load InfoSchema from version %d to %d, in %v", usedSchemaVersion, latestSchemaVersion, time.Since(startTime)) return latestSchemaVersion, nil } schemas, err := do.fetchAllSchemasWithTables(m) if err != nil { return 0, errors.Trace(err) } newISBuilder, err := infoschema.NewBuilder(handle).InitWithDBInfos(schemas, latestSchemaVersion) if err != nil { return 0, errors.Trace(err) } log.Infof("[ddl] full load InfoSchema from version %d to %d, in %v", usedSchemaVersion, latestSchemaVersion, time.Since(startTime)) newISBuilder.Build() return latestSchemaVersion, nil }