From 4e9bd09d3934846e6303bc7f9f3770007530b21d Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 29 Jan 2023 16:33:23 -1000 Subject: [PATCH] Fix old indices not being removed in schema migration leading to slow MySQL queries (#86917) fixes #83787 --- .../components/recorder/db_schema.py | 2 +- .../components/recorder/migration.py | 25 +++++++++++-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/homeassistant/components/recorder/db_schema.py b/homeassistant/components/recorder/db_schema.py index 47b9658b053..1fef18573ea 100644 --- a/homeassistant/components/recorder/db_schema.py +++ b/homeassistant/components/recorder/db_schema.py @@ -55,7 +55,7 @@ from .models import StatisticData, StatisticMetaData, process_timestamp # pylint: disable=invalid-name Base = declarative_base() -SCHEMA_VERSION = 32 +SCHEMA_VERSION = 33 _StatisticsBaseSelfT = TypeVar("_StatisticsBaseSelfT", bound="StatisticsBase") diff --git a/homeassistant/components/recorder/migration.py b/homeassistant/components/recorder/migration.py index 8bd563fb6be..cf1a1f8b656 100644 --- a/homeassistant/components/recorder/migration.py +++ b/homeassistant/components/recorder/migration.py @@ -505,12 +505,12 @@ def _apply_update( # noqa: C901 timestamp_type = "FLOAT" if new_version == 1: - _create_index(session_maker, "events", "ix_events_time_fired") + # This used to create ix_events_time_fired, but it was removed in version 32 + pass elif new_version == 2: # Create compound start/end index for recorder_runs _create_index(session_maker, "recorder_runs", "ix_recorder_runs_start_end") - # Create indexes for states - _create_index(session_maker, "states", "ix_states_last_updated") + # This used to create ix_states_last_updated bit it was removed in version 32 elif new_version == 3: # There used to be a new index here, but it was removed in version 4. pass @@ -529,8 +529,7 @@ def _apply_update( # noqa: C901 _drop_index(session_maker, "states", "states__state_changes") _drop_index(session_maker, "states", "states__significant_changes") _drop_index(session_maker, "states", "ix_states_entity_id_created") - - _create_index(session_maker, "states", "ix_states_entity_id_last_updated") + # This used to create ix_states_entity_id_last_updated, but it was removed in version 32 elif new_version == 5: # Create supporting index for States.event_id foreign key _create_index(session_maker, "states", "ix_states_event_id") @@ -541,20 +540,21 @@ def _apply_update( # noqa: C901 ["context_id CHARACTER(36)", "context_user_id CHARACTER(36)"], ) _create_index(session_maker, "events", "ix_events_context_id") - _create_index(session_maker, "events", "ix_events_context_user_id") + # This used to create ix_events_context_user_id, but it was removed in version 28 _add_columns( session_maker, "states", ["context_id CHARACTER(36)", "context_user_id CHARACTER(36)"], ) _create_index(session_maker, "states", "ix_states_context_id") - _create_index(session_maker, "states", "ix_states_context_user_id") + # This used to create ix_states_context_user_id, but it was removed in version 28 elif new_version == 7: - _create_index(session_maker, "states", "ix_states_entity_id") + # There used to be a ix_states_entity_id index here, but it was removed in later schema + pass elif new_version == 8: _add_columns(session_maker, "events", ["context_parent_id CHARACTER(36)"]) _add_columns(session_maker, "states", ["old_state_id INTEGER"]) - _create_index(session_maker, "events", "ix_events_context_parent_id") + # This used to create ix_events_context_parent_id, but it was removed in version 28 elif new_version == 9: # We now get the context from events with a join # since its always there on state_changed events @@ -572,7 +572,7 @@ def _apply_update( # noqa: C901 # Redundant keys on composite index: # We already have ix_states_entity_id_last_updated _drop_index(session_maker, "states", "ix_states_entity_id") - _create_index(session_maker, "events", "ix_events_event_type_time_fired") + # This used to create ix_events_event_type_time_fired, but it was removed in version 32 _drop_index(session_maker, "events", "ix_events_event_type") elif new_version == 10: # Now done in step 11 @@ -859,6 +859,11 @@ def _apply_update( # noqa: C901 _drop_index(session_maker, "events", "ix_events_event_type_time_fired") _drop_index(session_maker, "states", "ix_states_last_updated") _drop_index(session_maker, "events", "ix_events_time_fired") + elif new_version == 33: + # This index is no longer used and can cause MySQL to use the wrong index + # when querying the states table. + # https://github.com/home-assistant/core/issues/83787 + _drop_index(session_maker, "states", "ix_states_entity_id") else: raise ValueError(f"No schema migration defined for version {new_version}")