func (cnf *ZkConfig) DataDir() string { baseDir := env.VtDataRoot() if cnf.Global { return fmt.Sprintf("%v/zk_global_%03d", baseDir, cnf.ServerId) } return fmt.Sprintf("%v/zk_%03d", baseDir, cnf.ServerId) }
// HttpHandleSnapshots handles the serving of files from the local tablet func HttpHandleSnapshots(mycnf *mysqlctl.Mycnf, uid uint32) { // make a list of paths we can serve HTTP traffic from. // we don't resolve them here to real paths, as they might not exits yet snapshotDir := mysqlctl.SnapshotDir(uid) allowedPaths := []string{ path.Join(vtenv.VtDataRoot(), "data"), mysqlctl.TabletDir(uid), mysqlctl.SnapshotDir(uid), mycnf.DataDir, mycnf.InnodbDataHomeDir, mycnf.InnodbLogGroupHomeDir, } // NOTE: trailing slash in pattern means we handle all paths with this prefix http.Handle(mysqlctl.SnapshotURLPath+"/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { handleSnapshot(w, r, snapshotDir, allowedPaths) })) }
// createTopDir creates a top level directory under TabletDir. // However, if a directory of the same name already exists under // vtenv.VtDataRoot(), it creates a directory named after the tablet // id under that directory, and then creates a symlink under TabletDir // that points to the newly created directory. For example, if // /vt/data is present, it will create the following structure: // /vt/data/vt_xxxx /vt/vt_xxxx/data -> /vt/data/vt_xxxx func (mysqld *Mysqld) createTopDir(dir string) error { vtname := path.Base(mysqld.TabletDir) target := path.Join(vtenv.VtDataRoot(), dir) _, err := os.Lstat(target) if err != nil { if os.IsNotExist(err) { topdir := path.Join(mysqld.TabletDir, dir) log.Infof("creating directory %s", topdir) return os.MkdirAll(topdir, os.ModePerm) } return err } linkto := path.Join(target, vtname) source := path.Join(mysqld.TabletDir, dir) log.Infof("creating directory %s", linkto) err = os.MkdirAll(linkto, os.ModePerm) if err != nil { return err } log.Infof("creating symlink %s -> %s", source, linkto) return os.Symlink(linkto, source) }
func SnapshotDir(uid uint32) string { return fmt.Sprintf("%s/%s/vt_%010d", env.VtDataRoot(), snapshotDir, uid) }
func TabletDir(uid uint32) string { return fmt.Sprintf("%s/vt_%010d", env.VtDataRoot(), uid) }
func main() { dbConfigsFile, dbCredentialsFile := dbconfigs.RegisterCommonFlags() flag.Parse() if err := servenv.Init("vttablet"); err != nil { relog.Fatal("Error in servenv.Init: %s", err) } tabletAlias := tabletParamToTabletAlias(*tabletPath) mycnf := readMycnf(tabletAlias.Uid) dbcfgs, err := dbconfigs.Init(mycnf.SocketFile, *dbConfigsFile, *dbCredentialsFile) if err != nil { relog.Warning("%s", err) } dbcfgs.App.Memcache = *rowcache if err := jscfg.ReadJson(*overridesFile, &schemaOverrides); err != nil { relog.Warning("%s", err) } else { data, _ := json.MarshalIndent(schemaOverrides, "", " ") relog.Info("schemaOverrides: %s\n", data) } initQueryService(dbcfgs) initUpdateStreamService(mycnf) ts.RegisterCacheInvalidator() // depends on both query and updateStream err = initAgent(tabletAlias, dbcfgs, mycnf, *dbConfigsFile, *dbCredentialsFile) // depends on both query and updateStream if err != nil { relog.Fatal("%s", err) } rpc.HandleHTTP() // NOTE(szopa): Changing credentials requires a server // restart. if *authConfig != "" { if err := auth.LoadCredentials(*authConfig); err != nil { relog.Error("could not load authentication credentials, not starting rpc servers: %v", err) } serveAuthRPC() } serveRPC() // make a list of paths we can serve HTTP traffic from. // we don't resolve them here to real paths, as they might not exits yet snapshotDir := mysqlctl.SnapshotDir(tabletAlias.Uid) allowedPaths := []string{ path.Join(vtenv.VtDataRoot(), "data"), mysqlctl.TabletDir(tabletAlias.Uid), snapshotDir, mycnf.DataDir, mycnf.InnodbDataHomeDir, mycnf.InnodbLogGroupHomeDir, } // NOTE: trailing slash in pattern means we handle all paths with this prefix http.Handle(mysqlctl.SnapshotURLPath+"/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { handleSnapshot(w, r, snapshotDir, allowedPaths) })) // we delegate out startup to the micromanagement server so these actions // will occur after we have obtained our socket. umgmt.SetLameDuckPeriod(float32(*lameDuckPeriod)) umgmt.SetRebindDelay(float32(*rebindDelay)) umgmt.AddStartupCallback(func() { umgmt.StartHttpServer(fmt.Sprintf(":%v", *port)) if *securePort != 0 { relog.Info("listening on secure port %v", *securePort) umgmt.StartHttpsServer(fmt.Sprintf(":%v", *securePort), *cert, *key, *caCert) } }) umgmt.AddStartupCallback(func() { c := make(chan os.Signal, 1) signal.Notify(c, syscall.SIGTERM) go func() { for sig := range c { umgmt.SigTermHandler(sig) } }() }) relog.Info("started vttablet %v", *port) umgmtSocket := fmt.Sprintf("/tmp/vttablet-%08x-umgmt.sock", *port) if umgmtErr := umgmt.ListenAndServe(umgmtSocket); umgmtErr != nil { relog.Error("umgmt.ListenAndServe err: %v", umgmtErr) } relog.Info("done") }