Skip to content

Commit

Permalink
Fix deadlock in Index.ForEachMeasurementTagKey
Browse files Browse the repository at this point in the history
Index.ForEachMeasurementTagKey held an RLock while call the fn,
if the fn made another call into the index which acquired an RLock
and after another goroutine tried to acquire a Lock, it would deadlock.
  • Loading branch information
jwilder committed May 4, 2017
1 parent b4ea523 commit 7371f10
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 9 deletions.
12 changes: 7 additions & 5 deletions tsdb/index/inmem/inmem.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,10 +263,13 @@ func (i *Index) MeasurementTagKeysByExpr(name []byte, expr influxql.Expr) (map[s

// ForEachMeasurementTagKey iterates over all tag keys for a measurement.
func (i *Index) ForEachMeasurementTagKey(name []byte, fn func(key []byte) error) error {
// Ensure we do not hold a lock on the index while fn executes in case fn tries
// to acquire a lock on the index again. If another goroutine has Lock, this will
// deadlock.
i.mu.RLock()
defer i.mu.RUnlock()

mm := i.measurements[string(name)]
i.mu.RUnlock()

if mm == nil {
return nil
}
Expand Down Expand Up @@ -537,9 +540,9 @@ func (i *Index) DropSeries(key []byte) error {
// ForEachMeasurementSeriesByExpr iterates over all series in a measurement filtered by an expression.
func (i *Index) ForEachMeasurementSeriesByExpr(name []byte, expr influxql.Expr, fn func(tags models.Tags) error) error {
i.mu.RLock()
defer i.mu.RUnlock()

mm := i.measurements[string(name)]
i.mu.RUnlock()

if mm == nil {
return nil
}
Expand Down Expand Up @@ -731,7 +734,6 @@ type ShardIndex struct {

// CreateSeriesListIfNotExists creates a list of series if they doesn't exist in bulk.
func (idx *ShardIndex) CreateSeriesListIfNotExists(keys, names [][]byte, tagsSlice []models.Tags) error {

keys, names, tagsSlice = idx.assignExistingSeries(idx.id, keys, names, tagsSlice)
if len(keys) == 0 {
return nil
Expand Down
5 changes: 1 addition & 4 deletions tsdb/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,12 +287,9 @@ func (m *Measurement) ForEachSeriesByExpr(condition influxql.Expr, fn func(tags
return err
}

m.mu.RLock()
defer m.mu.RUnlock()

// Iterate over each series.
for _, id := range ids {
s := m.seriesByID[id]
s := m.SeriesByID(id)
if err := fn(s.Tags()); err != nil {
return err
}
Expand Down

0 comments on commit 7371f10

Please sign in to comment.