Skip to content

Commit c040fbb

Browse files
ref(db): Drop unused Group.logger indexes (#128334)
Drops the two indexes that `db_index=True` creates on `Group.logger`: - `sentry_groupedmessage_logger_993cb6d5`, a btree on `logger` - `sentry_groupedmessage_logger_993cb6d5_like`, a btree on `logger varchar_pattern_ops` that Django adds for `LIKE` lookups on `CharField`s This is a follow-up to #128156 (`level`) and #128165 (`times_seen`). ### Why - Nothing in `src/` filters, orders, or runs `LIKE` lookups on `Group.logger` in Postgres, so both indexes only add write overhead on `sentry_groupedmessage`. - Neither is unique or a constraint. ### How Same pattern as `1228`/`1229`: - Removed `db_index=True` from `Group.logger`. - Migration `1231_drop_group_logger_indexes` uses `SeparateDatabaseAndState`: - The database side runs `DROP INDEX CONCURRENTLY IF EXISTS` for both Django names, and for the South-era names `sentry_groupedmessage_logger` and `sentry_groupedmessage_logger_like`. Dropping by exact name keeps `AlterField` from introspecting and dropping other indexes. - The state side is an `AlterField` matching the model. - `use_statement_timeout=False`, because the concurrent drops wait for open transactions. - `is_post_deployment = True`. - Reversible: the reverse SQL recreates both indexes under their current names, including `varchar_pattern_ops` on the `_like` index. ### Notes for reviewers - `SafeRunSQL` needs sign-off from `owners-migrations`. - I couldn't run `makemigrations --check` or `sqlmigrate` locally, so please rely on CI and the migration SQL comment. <!-- junior-request-attribution:start --> via **michal**. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:local%3Aweb%3Ae4ce2a50461aaf3812f0494a --> -- [View Junior Session in Sentry](https://sentry.sentry.io/explore/conversations/local%3Aweb%3Ae4ce2a50461aaf3812f0494a/?project=4510944073809921) <!-- junior-session-footer:end --> Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com> Co-authored-by: michal <michal.kuffa@sentry.io>
1 parent 1e42114 commit c040fbb

3 files changed

Lines changed: 78 additions & 4 deletions

File tree

‎migrations_lockfile.txt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ replays: 0001_squashed_0007_organizationmember_replay_access
3535

3636
seer: 0038_add_workflow_config_scope
3737

38-
sentry: 1230_add_commit_new_repository_id_no_check
38+
sentry: 1231_drop_group_logger_indexes
3939

4040
social_auth: 0001_squashed_0003_social_auth_json_field
4141

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Generated by Django 5.2.17 on 2026-10-21 13:00
2+
3+
from django.db import migrations, models
4+
5+
from sentry.new_migrations.migrations import CheckedMigration
6+
from sentry.new_migrations.monkey.special import SafeRunSQL
7+
8+
# Created by `db_index=True` on `Group.logger`: a btree index plus a `varchar_pattern_ops` index
9+
# for `LIKE` lookups. Nothing queries `Group` by `logger` in Postgres.
10+
# `IF EXISTS` keeps these drops a no-op on any database where an index is absent.
11+
LOGGER_INDEX = "sentry_groupedmessage_logger_993cb6d5"
12+
LOGGER_LIKE_INDEX = "sentry_groupedmessage_logger_993cb6d5_like"
13+
# South-era names for the same indexes, which may still exist on databases created before Django
14+
# migrations.
15+
LEGACY_LOGGER_INDEX = "sentry_groupedmessage_logger"
16+
LEGACY_LOGGER_LIKE_INDEX = "sentry_groupedmessage_logger_like"
17+
18+
19+
def drop_index(name: str, reverse_sql: str) -> SafeRunSQL:
20+
return SafeRunSQL(
21+
f'DROP INDEX CONCURRENTLY IF EXISTS "{name}"',
22+
reverse_sql=reverse_sql,
23+
hints={"tables": ["sentry_groupedmessage"]},
24+
# The drop waits for open transactions on a hot table, which can outlast the statement
25+
# timeout.
26+
use_statement_timeout=False,
27+
)
28+
29+
30+
class Migration(CheckedMigration):
31+
# This flag is used to mark that a migration shouldn't be automatically run in production.
32+
# This should only be used for operations where it's safe to run the migration after your
33+
# code has deployed. So this should not be used for most operations that alter the schema
34+
# of a table.
35+
# Here are some things that make sense to mark as post deployment:
36+
# - Large data migrations. Typically we want these to be run manually so that they can be
37+
# monitored and not block the deploy for a long period of time while they run.
38+
# - Adding indexes to large tables. Since this can take a long time, we'd generally prefer to
39+
# run this outside deployments so that we don't block them. Note that while adding an index
40+
# is a schema change, it's completely safe to run the operation after the code has deployed.
41+
# Once deployed, run these manually via: https://develop.sentry.dev/database-migrations/#migration-deployment
42+
43+
is_post_deployment = True
44+
45+
dependencies = [
46+
("sentry", "1230_add_commit_new_repository_id_no_check"),
47+
]
48+
49+
operations = [
50+
migrations.SeparateDatabaseAndState(
51+
# Drop the indexes by their exact names rather than letting `AlterField` introspect
52+
# and drop every single-column index on `logger`.
53+
database_operations=[
54+
drop_index(
55+
LOGGER_INDEX,
56+
f'CREATE INDEX CONCURRENTLY IF NOT EXISTS "{LOGGER_INDEX}" '
57+
'ON "sentry_groupedmessage" ("logger")',
58+
),
59+
drop_index(
60+
LOGGER_LIKE_INDEX,
61+
f'CREATE INDEX CONCURRENTLY IF NOT EXISTS "{LOGGER_LIKE_INDEX}" '
62+
'ON "sentry_groupedmessage" ("logger" varchar_pattern_ops)',
63+
),
64+
# Reversing the drops above recreates the indexes under their current names.
65+
drop_index(LEGACY_LOGGER_INDEX, migrations.RunSQL.noop),
66+
drop_index(LEGACY_LOGGER_LIKE_INDEX, migrations.RunSQL.noop),
67+
],
68+
state_operations=[
69+
migrations.AlterField(
70+
model_name="group",
71+
name="logger",
72+
field=models.CharField(blank=True, default="", max_length=64),
73+
),
74+
],
75+
),
76+
]

‎src/sentry/models/group.py‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -864,9 +864,7 @@ class Group(Model):
864864
__relocation_scope__ = RelocationScope.Excluded
865865

866866
project = FlexibleForeignKey("sentry.Project")
867-
logger = models.CharField(
868-
max_length=64, blank=True, default=str(DEFAULT_LOGGER_NAME), db_index=True
869-
)
867+
logger = models.CharField(max_length=64, blank=True, default=str(DEFAULT_LOGGER_NAME))
870868
level = BoundedPositiveIntegerField(
871869
choices=[(key, str(val)) for key, val in sorted(LOG_LEVELS.items())],
872870
default=logging.ERROR,

0 commit comments

Comments
 (0)