|
|
這篇是資料庫的完整處置。
假設你已經確認「慢」的原因是資料庫(怎麼確認在 tid=271,一句話版本是:執行 recorder.disable 之後明顯變順)。接下來要做的是:看懂 recorder 在做什麼、用 SQL 找出到底是誰在吃空間、把設定調對、必要時換引擎。

先算一次,你就知道為什麼會變這麼大
HA 預設把每一個實體的每一次狀態變化寫進資料庫。聽起來合理,直到你算一下:
- 一個功率感測器,每 10 秒回報一次
- 一天 8,640 筆
- 一個月 259,200 筆
- 五個這種感測器
- 一個月 130 萬筆
- 再加上每一筆的「屬性」(單位、圖示、裝置類別、friendly_name…)
- 以及每個 Zigbee 裝置的 LQI、電量、訊號強度
- 以及所有自動化與腳本的觸發事件
複製代碼
結果就是幾 GB 的資料庫、開機要好幾分鐘、歷史頁面卡住、SD 卡被寫爆。
---
步驟 1:先看清楚你的資料庫現在的狀態
怎麼看整體大小
設定 → 系統 → 修復 → 右上三個點 → 系統資訊,往下找 Recorder 區塊。
你會看到什麼:
- Recorder
- 資料庫引擎 sqlite
- 資料庫版本 3.45.x
- 預估資料庫大小 1842.31 MiB
- 目前執行中 是
- 最舊的執行起始時間 2026-09-15T04:12:00+08:00
複製代碼
直接看檔案更準(裝 Terminal & SSH 附加元件,或 Container 版直接 SSH 進主機),到設定目錄:
- ls -lh home-assistant_v2.db*
複製代碼
你會看到什麼:
- -rw-r--r-- 1 root root 1.8G Sep 25 14:02 home-assistant_v2.db
- -rw-r--r-- 1 root root 32K Sep 25 14:02 home-assistant_v2.db-shm
- -rw-r--r-- 1 root root 412M Sep 25 14:02 home-assistant_v2.db-wal
複製代碼
⚠ 三個檔案都要算。-wal 是「預寫日誌」,忙碌的系統上可能幾百 MB,只看主檔會低估。
判準:
- 500MB 以下 —— 正常
- 1 到 2GB —— 該整理了
- 3GB 以上 —— 一定有問題
- -wal 超過主檔的 20% —— 寫入壓力很大,優先處理步驟 3
做一個「資料庫大小」感測器,讓它自己盯著
到設定 → 裝置與服務 → 新增整合,搜尋 SQL,加入。
它會問幾個欄位,SQLite 的話這樣填:
- 資料庫網址:留空(留空就是用 HA 自己的那個)
- 名稱:資料庫大小
- 查詢:
- SELECT ROUND(page_count * page_size / 1024.0 / 1024.0, 1) AS size
- FROM pragma_page_count(), pragma_page_size();
複製代碼
MariaDB 的話查詢要換成:
- SELECT ROUND(SUM(data_length + index_length) / 1048576, 1) AS size
- FROM information_schema.tables
- WHERE table_schema = 'homeassistant';
複製代碼
你會看到什麼:新增成功後出現 sensor.資料庫大小,值是一個數字。
顯示 unknown 或 unavailable → 查詢語法錯了,或是資料欄名稱跟查詢輸出的欄位名不符(兩邊都要是 size)。
順便做一個超標提醒,放在 automations.yaml:
- - id: db_too_big_alert
- alias: 資料庫超過 2GB 提醒
- triggers:
- - trigger: numeric_state
- entity_id: sensor.zi_liao_ku_da_xiao
- above: 2000
- for:
- hours: 6
- conditions: []
- actions:
- - action: persistent_notification.create
- data:
- title: 資料庫超過 2GB
- message: >
- 目前 {{ states('sensor.zi_liao_ku_da_xiao') }} MB,該檢查 recorder 設定了
複製代碼
⚠ entity_id 要用實際的。中文名稱會被轉成拼音,到開發者工具 → 狀態搜尋「資料庫」看它實際叫什麼,複製過來。for: hours: 6 是為了避免 purge 期間數字跳動造成重複通知。
---
步驟 2:用 SQL 找出到底是誰在吃空間(這一步最關鍵)
不做這一步的話,後面的 exclude 清單都是猜的。
用 Terminal & SSH 附加元件,到設定目錄。
查詢 A:哪些實體的筆數最多
- sqlite3 home-assistant_v2.db "
- SELECT m.entity_id, COUNT(*) AS 筆數
- FROM states s
- JOIN states_meta m ON m.metadata_id = s.metadata_id
- GROUP BY m.entity_id
- ORDER BY 筆數 DESC
- LIMIT 25;
- "
複製代碼
你會看到什麼:
- sensor.power_meter_power|1284391
- sensor.router_download_speed|982104
- sensor.router_upload_speed|981887
- device_tracker.my_phone|412039
- sensor.cpu_temperature|298112
- sensor.zigbee_bulb_linkquality|187432
- sensor.living_room_temperature|41208
- sensor.outdoor_humidity|38901
- ...
複製代碼
怎麼讀:拿第一筆跟第十筆比。差一個數量級以上就是異常(128 萬 vs 4 萬)。
查詢 B:哪些實體佔最多空間(比筆數更準)
筆數多不等於佔空間多 —— 一個狀態值很長、屬性很多的實體,一筆就抵別人十筆。
- sqlite3 home-assistant_v2.db "
- SELECT m.entity_id,
- COUNT(*) AS 筆數,
- ROUND(SUM(LENGTH(COALESCE(s.state,'')) +
- LENGTH(COALESCE(sa.shared_attrs,''))) / 1048576.0, 2) AS 約MB
- FROM states s
- JOIN states_meta m ON m.metadata_id = s.metadata_id
- LEFT JOIN state_attributes sa ON sa.attributes_id = s.attributes_id
- GROUP BY m.entity_id
- ORDER BY 約MB DESC
- LIMIT 25;
- "
複製代碼
你會看到什麼:
- sensor.power_meter_power|1284391|284.31
- sensor.weather_forecast|8412|196.04
- sensor.router_download_speed|982104|142.88
- camera.front_door|41200|98.12
- ...
複製代碼
|
|