Skip to content
This repository was archived by the owner on Apr 2, 2024. It is now read-only.

Commit 1b0ade6

Browse files
committed
Take stronger lock before creating a series partition
Stupidly create table ... partition of X first takes an access share lock and then an access exclusive lock. Such an upgrade can, and does, cause deadlocks. Taking the stronger lock beforehand prevents such deadlocks.
1 parent f353cbb commit 1b0ade6

File tree

3 files changed

+33
-14
lines changed

3 files changed

+33
-14
lines changed

pkg/pgmodel/end_to_end_tests/concurrent_sql_test.go

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -167,11 +167,11 @@ func TestConcurrentSQL(t *testing.T) {
167167
})
168168
}
169169

170-
func testConcurrentInsertSimple(t testing.TB, db *pgxpool.Pool) {
170+
func testConcurrentInsertSimple(t testing.TB, db *pgxpool.Pool, metric string) {
171171
metrics := []prompb.TimeSeries{
172172
{
173173
Labels: []prompb.Label{
174-
{Name: MetricNameLabelName, Value: "cpu_usage"},
174+
{Name: MetricNameLabelName, Value: metric},
175175
},
176176
Samples: []prompb.Sample{
177177
{Timestamp: 10, Value: 0.5},
@@ -250,16 +250,29 @@ func TestConcurrentInsert(t *testing.T) {
250250

251251
withDB(t, *testDatabase, func(db *pgxpool.Pool, t testing.TB) {
252252
var wg sync.WaitGroup
253-
wg.Add(2)
254-
go func() {
255-
defer wg.Done()
256-
testConcurrentInsertSimple(t, db)
257-
}()
258-
go func() {
259-
defer wg.Done()
260-
testConcurrentInsertSimple(t, db)
261-
}()
262-
wg.Wait()
253+
for i := 0; i < 10; i++ {
254+
wg.Add(2)
255+
go func() {
256+
defer wg.Done()
257+
testConcurrentInsertSimple(t, db, fmt.Sprintf("metric_%d", i))
258+
}()
259+
go func() {
260+
defer wg.Done()
261+
testConcurrentInsertSimple(t, db, fmt.Sprintf("metric_%d", i))
262+
}()
263+
wg.Wait()
264+
265+
wg.Add(2)
266+
go func() {
267+
defer wg.Done()
268+
testConcurrentInsertSimple(t, db, fmt.Sprintf("metric_1_%d", i))
269+
}()
270+
go func() {
271+
defer wg.Done()
272+
testConcurrentInsertSimple(t, db, fmt.Sprintf("metric_2_%d", i))
273+
}()
274+
wg.Wait()
275+
}
263276

264277
wg.Add(2)
265278
go func() {

pkg/pgmodel/migrations/migration_files_generated.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/pgmodel/migrations/sql/1_base_schema.up.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,12 @@ BEGIN
193193
SELECT SCHEMA_CATALOG.get_or_create_label_id('__name__', NEW.metric_name)
194194
INTO STRICT label_id;
195195

196+
197+
-- stupidly create table ... partition of X first takes an access share lock
198+
-- and then an access exclusive lock. Such an upgrade can, and does, cause
199+
-- deadlocks. Taking the stronger lock beforehand prevents such deadlocks.
200+
LOCK TABLE _prom_catalog.series in ACCESS EXCLUSIVE mode;
201+
196202
--note that because labels[1] is unique across partitions and UNIQUE(labels) inside partition, labels are guaranteed globally unique
197203
EXECUTE format($$
198204
CREATE TABLE SCHEMA_DATA_SERIES.%1$I PARTITION OF SCHEMA_CATALOG.series (

0 commit comments

Comments
 (0)