При изобилии датчиков и различных других умных устройств, подключенных к Home Assistant, особенно если эти устройства часто отправляют в систему свои данные, база данных умного дома, в которой хранится вся история изменений состояний умных устройств, может существенно вырасти в размерах, что в свою очередь может негативно отразиться на быстродействии системы в целом. А также большой размер БД влияет на размер резервных копий системы, что может привести с использованию значительного дискового или облачного пространства хранения данных.
В Home Assistant есть инструмент регулирования объёма хранимых в БД данных - это встроенная интеграция recorder:
Эта интеграция включена по умолчанию и занимается записью истории изменений в системе в базу данных. По умолчанию recorder пишет в БД всё подряд без разбора. Любые изменения любых сущностей попадают в это хранилище, постепенно увеличивая занимаемый им объём.
По умолчанию время хранения истории в БД составляет всего 10 дней. Но это касается только непосредственно истории изменений состояний объектов. В терминологии Home Assistant это называется краткосрочной статистикой. Но есть в Home Assistant есть также и функционал долгосрочной статистики:
Это усреднённые в пределах часа данные, и для каждой сущности в сутки создаётся только 24 записи, независимо от частоты отправляемых ими данных. Долгосрочная статистика хранится в БД вечно и никогда не очищается автоматически.
Настройка recorder
Но долгосрочная статистика - это неточные данные. А часто бывает нужно хранить именно точные, исходные данные с датчиков в течение длительного времени. И время их хранения пользователь может изменить по своему усмотрению. Для этого нужно внести некоторые изменения в файл configuration.yaml. Для его редактирования удобно использовать дополнение File Editor, о котором я рассказывал здесь:
Добавив в него две строчки мы увеличим время хранения краткосрочной статистики в данном случае до 90 дней:
К сожалению, в Home Assistant нет возможности задавать время хранения данных отдельно для каждой сущности, только для всех сразу. Но зато можно полностью исключить запись истории отдельных сущностей или даже целых доменов, если их история не нужна и она занимает много места.
Это делается с помощью переменной exclude. Можно указать какие домены исключить из записи помощью переменной domains. Можно указать шаблоны исключаемых имён сущностей с применением подстановочных символов с помощью переменной entity_globs. Можно перечислить конкретные имена сущностей с помощью переменной entities. Можно указать типы событий, которые нужно исключить из записи в БД, с помощью переменной event_types:
Можно также пойти от обратного, и исключить всё, кроме указанного. Это делается с помощью переменной include. Можно также комбинировать include и exclude, чтобы, например, включить домен, но исключить из него некоторые сущности. Подробности - в описании интеграции recorder.
Таким образом можно существенно снизить нагрузку на БД, не теряя при этом в функциональности.
Поиск объектов-спамеров в базе данных
Но как же определить, какие именно сущности наносят ущерб БД своими часто изменяющимися данными? Для того, чтобы это выяснить, нам нужно проанализировать записи в БД. Но делать это с БД по умолчанию, с котором поставляется Home Assistant "из коробки" крайне неудобно. Поэтому для начала стоит перейти на другой тип БД - MariaDB. О том, как это сделать, я рассказывал здесь:
При использовании MySQL-совместимой базы данных MariaDB у нас появляется возможность пользоваться удобным инструментом для анализа содержимого БД - phpMyAdmin. О том, как установить это дополнение и пользоваться им, я рассказывал здесь:
И теперь у нас есть всё для того, чтобы оценить объекты Home Assistant на предмет заспамливания ими базы данных.
В аддоне phpMyAdmin мы можем сделать SQL-запрос к таблице states, который выведет таблицу всех имён сущностей с указанием общего числа записей для каждой из них. Вот этот запрос:
SELECT states.metadata_id AS metadata_id, states_meta.entity_id AS entity_id, COUNT(*) as count
FROM states
INNER JOIN states_meta ON states.metadata_id = states_meta.metadata_id
GROUP BY states.metadata_id
ORDER BY count DESC
И вот результат работы этого запроса:
Здесь видно, что у меня, например, самые прожорливые сущности - это данные с измерителя тока, у каждой сущности по два-три миллиона записей в БД. Это ожидаемо, данный датчик у меня отсылает данные ежесекундно, мне это нужно для быстрого срабатывания реле максимального тока. Однако писать все эти данные в БД вряд ли нужно. Но у меня проблем с быстродействием Home Assistant нет, поэтому оставил так.
Аналогичный запрос к таблице events, чтобы узнать кто спамит больше всего по событиям:
SELECT events.event_type_id AS event_type_id, event_types.event_type AS event_type_id, COUNT(*) as count
FROM events
INNER JOIN event_types ON events.event_type_id = event_types.event_type_id
GROUP BY events.event_type_id
ORDER BY count DESC
Результатом будет аналогичная таблица, но с количеством сгенерированных событий каждой сущности:
Таким образом мы можем определить, кто именно и сколько записей вносит в базу данных. Самых "незатыкающихся" сущностей добавляем в исключения в рекордере, и всё.
Как узнать размер базы данных
Узнать текущий размер базы данных можно с помощью вот такого SQL-запроса:
SELECT table_schema AS 'db_name', ROUND(SUM( data_length + index_length ) / 1024 / 1024, 2)
AS 'size_mb'
FROM information_schema.TABLES
WHERE table_schema='homeassistant'
Результатом работы этого запроса будет число - размер базы данных, выраженный в мегабайтах:
Размер моей БД почти 8 Гб.
Датчик размера базы данных
На основе этого SQL-запроса можно сделать программный датчик, и отображать текущий размер базы данных прямо на панели интерфейса Home Assistant, не залезая каждый раз в phpMyAdmin и не делая SQL-запросов вручную.
Для этого воспользуемся интеграцией SQL. Установим её как обычно, из меню "Настройки" -> "Устройства и службы. Интеграции..." -> "Добавить интеграцию" -> "SQL":
Заполняем настройки интеграции:
Адрес БД:
mysql://homeassistant:homeassistant@core-mariadb/homeassistant?charset=utf8
Столбец:
size_mb
Запрос:
SELECT table_schema AS 'db_name', ROUND(SUM( data_length + index_length ) / 1024 / 1024, 2) AS 'size_mb' FROM information_schema.TABLES WHERE table_schema='homeassistant'
Нажимаем "Подтвердить", через несколько секунд запись будет создана:
И у нас появится вот такой сенсор в системе:
Однако я не очень понял, с какой частотой он обновляется и можно ли эту частоту изменить. У меня это происходит крайне редко, раз в несколько дней.
Подробнее об интеграции SQL можно почитать в официальной документации: