func (s *Shard) Open() error {
	if err := func() error {
		s.mu.Lock()
		defer s.mu.Unlock()
		if s._engine != nil {
			return nil
		}
		seriesIDSet := NewSeriesIDSet()
		ipath := filepath.Join(s.path, "index")
		idx, err := NewIndex(s.id, s.database, ipath, seriesIDSet, s.sfile, s.options)
		if err != nil {
			return err
		}
		if err := idx.Open(); err != nil {
			return err
		}
		s.index = idx
		idx.WithLogger(s.baseLogger)
		e, err := NewEngine(s.id, idx, s.database, s.path, s.walPath, s.sfile, s.options)
		if err != nil {
			return err
		}
		e.WithLogger(s.baseLogger)
		e.SetEnabled(false)
		if err := e.Open(); err != nil {
			return err
		}
		if err := e.LoadMetadataIndex(s.id, s.index); err != nil {
			return err
		}
		s._engine = e
		return nil
	}(); err != nil {
		s.close()
		return NewShardError(s.id, err)
	}
	if s.EnableOnOpen {
		s.SetEnabled(true)
	}
	return nil
}
Open initializes and opens the shard's store.
package tsdb
import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"runtime"
	"sort"
	"strings"
	"sync"
	"sync/atomic"
	"time"
	"github.com/gogo/protobuf/proto"
	"github.com/influxdata/influxdb/models"
	"github.com/influxdata/influxdb/pkg/bytesutil"
	"github.com/influxdata/influxdb/pkg/estimator"
	"github.com/influxdata/influxdb/pkg/file"
	"github.com/influxdata/influxdb/pkg/limiter"
	"github.com/influxdata/influxdb/query"
	internal "github.com/influxdata/influxdb/tsdb/internal"
	"github.com/influxdata/influxql"
	"go.uber.org/zap"
)
const (
	statWriteReq           = "writeReq"
	statWriteReqOK         = "writeReqOk"
	statWriteReqErr        = "writeReqErr"
	statSeriesCreate       = "seriesCreate"
	statFieldsCreate       = "fieldsCreate"
	statWritePointsErr     = "writePointsErr"
	statWritePointsDropped = "writePointsDropped"
	statWritePointsOK      = "writePointsOk"
	statWriteBytes         = "writeBytes"
	statDiskBytes          = "diskBytes"
)
var (
	ErrFieldOverflow = errors.New("field overflow")
	ErrFieldTypeConflict = errors.New("field type conflict")
	ErrFieldNotFound = errors.New("field not found")
	ErrFieldUnmappedID = errors.New("field ID not mapped")
	ErrEngineClosed = errors.New("engine is closed")
	ErrShardDisabled = errors.New("shard is disabled")
	ErrUnknownFieldsFormat = errors.New("unknown field index format")
	ErrShardNotIdle = errors.New("shard not idle")
	fieldsIndexMagicNumber = []byte{0, 6, 1, 3}
)
var (
	timeBytes = []byte("time")
)
type ShardError struct {
	id  uint64
	Err error
}
func NewShardError(id uint64, err error) error {
	if err == nil {
		return nil
	}
	return ShardError{id: id, Err: err}
}
func (e ShardError) Error() string {
	return fmt.Sprintf("[shard %d] %s", e.id, e.Err)
}
type PartialWriteError struct {
	Reason  string
	Dropped int
	DroppedKeys [][]byte
}
func (e PartialWriteError) Error() string {
	return fmt.Sprintf("partial write: %s dropped=%d", e.Reason, e.Dropped)
}
type Shard struct {
	path    string
	walPath string
	id      uint64
	database        string
	retentionPolicy string
	sfile   *SeriesFile
	options EngineOptions
	mu      sync.RWMutex
	_engine Engine
	index   Index
	enabled bool
	stats       *ShardStatistics
	defaultTags models.StatisticTags
	baseLogger *zap.Logger
	logger     *zap.Logger
	EnableOnOpen bool
}
func NewShard(id uint64, path string, walPath string, sfile *SeriesFile, opt EngineOptions) *Shard {
	db, rp := decodeStorePath(path)
	logger := zap.NewNop()
	s := &Shard{
		id:      id,
		path:    path,
		walPath: walPath,
		sfile:   sfile,
		options: opt,
		stats: &ShardStatistics{},
		defaultTags: models.StatisticTags{
			"path":            path,
			"walPath":         walPath,
			"id":              fmt.Sprintf("%d", id),
			"database":        db,
			"retentionPolicy": rp,
			"engine":          opt.EngineVersion,
		},
		database:        db,
		retentionPolicy: rp,
		logger:       logger,
		baseLogger:   logger,
		EnableOnOpen: true,
	}
	return s
}
func (s *Shard) WithLogger(log *zap.Logger) {
	s.baseLogger = log
	engine, err := s.engine()
	if err == nil {
		engine.WithLogger(s.baseLogger)
		s.index.WithLogger(s.baseLogger)
	}
	s.logger = s.baseLogger.With(zap.String("service", "shard"))
}
func (s *Shard) SetEnabled(enabled bool) {
	s.mu.Lock()
	s.enabled = enabled
	if s._engine != nil {
		s._engine.SetEnabled(enabled)
	}
	s.mu.Unlock()
}
func (s *Shard) ScheduleFullCompaction() error {
	engine, err := s.engine()
	if err != nil {
		return err
	}
	return engine.ScheduleFullCompaction()
}
func (s *Shard) ID() uint64 {
	return s.id
}
func (s *Shard) Database() string {
	return s.database
}
func (s *Shard) RetentionPolicy() string {
	return s.retentionPolicy
}
type ShardStatistics struct {
	WriteReq           int64
	WriteReqOK         int64
	WriteReqErr        int64
	FieldsCreated      int64
	WritePointsErr     int64
	WritePointsDropped int64
	WritePointsOK      int64
	BytesWritten       int64
	DiskBytes          int64
}
func (s *Shard) Statistics(tags map[string]string) []models.Statistic {
	engine, err := s.engine()
	if err != nil {
		return nil
	}
	if _, err := s.DiskSize(); err != nil {
		return nil
	}
	seriesN := engine.SeriesN()
	tags = s.defaultTags.Merge(tags)
	statistics := []models.Statistic{{
		Name: "shard",
		Tags: tags,
		Values: map[string]interface{}{
			statWriteReq:           atomic.LoadInt64(&s.stats.WriteReq),
			statWriteReqOK:         atomic.LoadInt64(&s.stats.WriteReqOK),
			statWriteReqErr:        atomic.LoadInt64(&s.stats.WriteReqErr),
			statSeriesCreate:       seriesN,
			statFieldsCreate:       atomic.LoadInt64(&s.stats.FieldsCreated),
			statWritePointsErr:     atomic.LoadInt64(&s.stats.WritePointsErr),
			statWritePointsDropped: atomic.LoadInt64(&s.stats.WritePointsDropped),
			statWritePointsOK:      atomic.LoadInt64(&s.stats.WritePointsOK),
			statWriteBytes:         atomic.LoadInt64(&s.stats.BytesWritten),
			statDiskBytes:          atomic.LoadInt64(&s.stats.DiskBytes),
		},
	}}
	statistics = append(statistics, engine.Statistics(tags)...)
	return statistics
}
func (s *Shard) Path() string { return s.path }