code: func Init(ctx context.Context, cfg Config) (err error) {
  	tiPlugins := pluginGlobal.plugins()
  	if tiPlugins == nil {
  		return nil
  	}
  	for kind := range tiPlugins.plugins {
  		for i := range tiPlugins.plugins[kind] {
  			p := tiPlugins.plugins[kind][i]
  			if err = p.OnInit(ctx, p.Manifest); err != nil {
  				if cfg.SkipWhenFail {
  					logutil.Logger(ctx).Warn("call Plugin OnInit failure, err: %v",
  						zap.String("plugin", p.Name), zap.Error(err))
  					tiPlugins.plugins[kind][i].State = Disable
  					err = nil
  					continue
  				}
  				return
  			}
  			if p.OnFlush != nil && cfg.EtcdClient != nil {
  				const pluginWatchPrefix = "/tidb/plugins/"
  				ctx, cancel := context.WithCancel(context.Background())
  				watcher := &flushWatcher{
  					ctx:      ctx,
  					cancel:   cancel,
  					path:     pluginWatchPrefix + tiPlugins.plugins[kind][i].Name,
  					etcd:     cfg.EtcdClient,
  					manifest: tiPlugins.plugins[kind][i].Manifest,
  				}
  				tiPlugins.plugins[kind][i].flushWatcher = watcher
  				go util.WithRecovery(watcher.watchLoop, nil)
  			}
  			tiPlugins.plugins[kind][i].State = Ready
  		}
  	}
  	return
  }
docs: // Init initializes the loaded plugin by config param.
  // This method must be called after `Load` but before any other plugin method call, so it call got TiDB domain info.