fix: Try workaround for bad index choice when updating execution logs (#64328)

Under high contention, the updating of execution logs query:

```
UPDATE
  lsif_indexes
SET
  execution_logs = execution_logs || $1::json
WHERE
  id = $2
  AND worker_hostname = $3
  AND state = $4 RETURNING ARRAY_LENGTH(execution_logs, $5)
```

Was taking multiple seconds due to lock contention on the
lsif_indexes_state index.

![image](https://github.com/user-attachments/assets/be58bc97-0995-4909-a032-69084ad995c5)

Running `EXPLAIN ANALYZE` on Sourcegraph.com under lower contention uses
the primary key index on id, so we don't have an easy way to test the
high contention scenario. Try this alternate query form to see if that fixes the issue.
This commit is contained in:
Varun Gandhi 2024-08-07 19:22:15 +08:00 committed by GitHub
parent 4d6e8949e8
commit 93818e0d9b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -791,14 +791,14 @@ func (s *store[T]) AddExecutionLogEntry(ctx context.Context, id int, entry execu
}})
defer endObservation(1, observation.Args{})
conds := []*sqlf.Query{
s.formatQuery("{id} = %s", id),
}
conds := []*sqlf.Query{sqlf.Sprintf("%s", true)}
conds = append(conds, options.ToSQLConds(s.formatQuery)...)
entryID, ok, err := basestore.ScanFirstInt(s.Query(ctx, s.formatQuery(
addExecutionLogEntryQuery,
quote(s.options.TableName),
id,
quote(s.options.TableName),
entry,
sqlf.Join(conds, "AND"),
)))
@ -825,11 +825,15 @@ func (s *store[T]) AddExecutionLogEntry(ctx context.Context, id int, entry execu
}
const addExecutionLogEntryQuery = `
UPDATE
%s
WITH candidate AS (
-- Directly using id = blah in WHERE clause would sometimes
-- trigger use of the state index under high contention, so
-- try forcing the use of pkey on id
SELECT id FROM %s WHERE id = %s FOR UPDATE
)
UPDATE %s
SET {execution_logs} = {execution_logs} || %s::json
WHERE
%s
WHERE id IN (SELECT id FROM candidate) AND %s
RETURNING array_length({execution_logs}, 1)
`