@@ -305,6 +305,7 @@ type userTSDB struct {
305
305
stateMtx sync.RWMutex
306
306
state tsdbState
307
307
pushesInFlight sync.WaitGroup // Increased with stateMtx read lock held, only if state == active or activeShipping.
308
+ readInFlight sync.WaitGroup // Increased with stateMtx read lock held, only if state == active, activeShipping or forceCompacting.
308
309
309
310
// Used to detect idle TSDBs.
310
311
lastUpdate atomic.Int64
@@ -1508,6 +1509,29 @@ func (i *Ingester) Push(ctx context.Context, req *cortexpb.WriteRequest) (*corte
1508
1509
return & cortexpb.WriteResponse {}, nil
1509
1510
}
1510
1511
1512
+ func (u * userTSDB ) acquireReadLock () error {
1513
+ u .stateMtx .RLock ()
1514
+ defer u .stateMtx .RUnlock ()
1515
+
1516
+ switch u .state {
1517
+ case active :
1518
+ case activeShipping :
1519
+ case forceCompacting :
1520
+ // Read are allowed.
1521
+ case closing :
1522
+ return errors .New ("TSDB is closing" )
1523
+ default :
1524
+ return errors .New ("TSDB is not active" )
1525
+ }
1526
+
1527
+ u .readInFlight .Add (1 )
1528
+ return nil
1529
+ }
1530
+
1531
+ func (u * userTSDB ) releaseReadLock () {
1532
+ u .readInFlight .Done ()
1533
+ }
1534
+
1511
1535
func (u * userTSDB ) acquireAppendLock () error {
1512
1536
u .stateMtx .RLock ()
1513
1537
defer u .stateMtx .RUnlock ()
@@ -1555,6 +1579,11 @@ func (i *Ingester) QueryExemplars(ctx context.Context, req *client.ExemplarQuery
1555
1579
return & client.ExemplarQueryResponse {}, nil
1556
1580
}
1557
1581
1582
+ if err := db .acquireReadLock (); err != nil {
1583
+ return & client.ExemplarQueryResponse {}, nil
1584
+ }
1585
+ defer db .releaseReadLock ()
1586
+
1558
1587
q , err := db .ExemplarQuerier (ctx )
1559
1588
if err != nil {
1560
1589
return nil , err
@@ -1648,6 +1677,11 @@ func (i *Ingester) labelsValuesCommon(ctx context.Context, req *client.LabelValu
1648
1677
return & client.LabelValuesResponse {}, cleanup , nil
1649
1678
}
1650
1679
1680
+ if err := db .acquireReadLock (); err != nil {
1681
+ return & client.LabelValuesResponse {}, cleanup , nil
1682
+ }
1683
+ defer db .releaseReadLock ()
1684
+
1651
1685
mint , maxt , err := metadataQueryRange (startTimestampMs , endTimestampMs , db , i .cfg .QueryIngestersWithin )
1652
1686
if err != nil {
1653
1687
return nil , cleanup , err
@@ -1738,6 +1772,11 @@ func (i *Ingester) labelNamesCommon(ctx context.Context, req *client.LabelNamesR
1738
1772
return & client.LabelNamesResponse {}, cleanup , nil
1739
1773
}
1740
1774
1775
+ if err := db .acquireReadLock (); err != nil {
1776
+ return & client.LabelNamesResponse {}, cleanup , nil
1777
+ }
1778
+ defer db .releaseReadLock ()
1779
+
1741
1780
mint , maxt , err := metadataQueryRange (startTimestampMs , endTimestampMs , db , i .cfg .QueryIngestersWithin )
1742
1781
if err != nil {
1743
1782
return nil , cleanup , err
@@ -1836,6 +1875,11 @@ func (i *Ingester) metricsForLabelMatchersCommon(ctx context.Context, req *clien
1836
1875
return cleanup , nil
1837
1876
}
1838
1877
1878
+ if err := db .acquireReadLock (); err != nil {
1879
+ return cleanup , nil
1880
+ }
1881
+ defer db .releaseReadLock ()
1882
+
1839
1883
// Parse the request
1840
1884
_ , _ , limit , matchersSet , err := client .FromMetricsForLabelMatchersRequest (i .matchersCache , req )
1841
1885
if err != nil {
@@ -2070,6 +2114,11 @@ func (i *Ingester) QueryStream(req *client.QueryRequest, stream client.Ingester_
2070
2114
return nil
2071
2115
}
2072
2116
2117
+ if err := db .acquireReadLock (); err != nil {
2118
+ return nil
2119
+ }
2120
+ defer db .releaseReadLock ()
2121
+
2073
2122
numSamples := 0
2074
2123
numSeries := 0
2075
2124
totalDataBytes := 0
@@ -2857,8 +2906,9 @@ func (i *Ingester) closeAndDeleteUserTSDBIfIdle(userID string) tsdbCloseCheckRes
2857
2906
// If TSDB is fully closed, we will set state to 'closed', which will prevent this deferred closing -> active transition.
2858
2907
defer userDB .casState (closing , active )
2859
2908
2860
- // Make sure we don't ignore any possible inflight pushes .
2909
+ // Make sure we don't ignore any possible inflight requests .
2861
2910
userDB .pushesInFlight .Wait ()
2911
+ userDB .readInFlight .Wait ()
2862
2912
2863
2913
// Verify again, things may have changed during the checks and pushes.
2864
2914
tenantDeleted := false
0 commit comments