Skip to main content

memory-db-sql

Write and manage SQL queries against an exported Unity memory-snapshot database (DuckDB/SQLite), and keep the schema, views, version, and docs consistent. Use when writing/editing queries over native_objects, native_allocations, native_roots, memory_regions, system_memory_regions, etc.; investigating memory regions; adding or changing tables/views/macros; or checking database version compatibility.

来源信息

仓库
Unity-Technologies/MemorySnapshotDataTools
最近来源活动
2026年6月3日 19:19
检测到的 SKILL.md 语言
英语
星标
11
分支
1

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
memory-db-sql
description
Write and manage SQL queries against an exported Unity memory-snapshot database (DuckDB/SQLite), and keep the schema, views, version, and docs consistent. Use when writing/editing queries over native_objects, native_allocations, native_roots, memory_regions, system_memory_regions, etc.; investigating memory regions; adding or changing tables/views/macros; or checking database version compatibility.
# Memory snapshot database SQL Use this when working with the database the tool exports from a `.snap` (the `export` command), as opposed to running the export/report pipeline itself (use `memory-snapshot-report` for that). **Canonical schema reference:** [`docs/database-schema.md`](../../../docs/database-schema.md). It lists every table, column, view, macro, join key, and the version policy. Read it before writing non-trivial queries — this skill is the workflow; that doc is the source of truth. ## Before you query: check the schema version The database stamps a **major.minor** version in `schema_meta`: ```sql SELECT schema_version_major, schema_version_minor, msdt_version FROM schema_meta; ``` - **No `schema_meta` table** → a pre-versioning export (treated as 0.0): re-export the `.snap`. - **major < `DatabaseSchemaInfo.SchemaMajor`** → table/column structure changed; **re-export required** (`MemorySnapshotDataTools export "<snap>" "<db>"`). - **same major, minor < `DatabaseSchemaInfo.SchemaMinor`** → only views/indexes changed; **upgrade in place** with `MemorySnapshotDataTools upgrade "<db>"` (no re-export). - In code, classify with `DatabaseSchemaInfo.Evaluate(major, minor)` → `SchemaAction` (`None`/`UpgradeInPlace`/`ReExport`/`ToolOutdated`); the CLI `SchemaGate` already does this before `report`/`summary`/`validate`, and `DatabaseMaintenance.{Inspect,UpgradeInPlace}` are the entry points (see [`Core/Models/DatabaseSchemaInfo.cs`](../../../Core/Models/DatabaseSchemaInfo.cs)). ## Querying: the things that bite These are spelled out in the schema doc, but the high-frequency traps: - **Two region tables, no FK between them.** `memory_regions` = Unity allocator buckets (`native_allocations.memory_region_index` points here). `system_memory_regions` = OS/VM regions (the RAM truth). Bridge an allocation to its OS region **by address range**, not a key. - **Prefer the views/macros** over rebuilding joins: `v_allocation_enriched` (allocation + Unity region + OS region + root + object), `v_system_region_summary` (committed/resident/Unity-tracked per OS region), `v_region_owner_breakdown`, `v_connection_edges` (reference graph with both endpoints typed — filter it, don't `SELECT *`), `v_assetbundle_utilization` (per-bundle: does it reference other loaded assets, and how much). DuckDB also has `region_allocations(name)` and `region_page_density(name)` (SQLite has the views only). - **Connections: don't hand-count "own" edges with magic numbers.** A native object's outbound edges include its self-reference and its managed wrappers (`native_gc_handle_bridge`/`native_connection` to managed). For "references to *other* loaded objects," count `native_object→native_object` `native_connection` edges where `to_index <> from_index` — exactly what `v_assetbundle_utilization` does. - **`native_object_address` ≠ `native_allocations.address`** — bridge objects and allocations through a shared `root_reference_id` → `native_roots.root_id`, never by address. - **Don't divide by `memory_regions.address_size`** (0 for `ALLOC_DEFAULT` et al.). - **`system_memory_regions.type` is uniformly 0 on iOS** — group by `name`. - **Resident data and `page_size` require `snap_format_version` ≥ 17** (else NULL). - `region_page_density` is for **small-allocation zones** (NANO/TINY/SMALL); `avg_fill_pct` > 100% means the region holds page-spanning allocations and the metric doesn't apply. ## Writing query code safely This repo's first-class rule is SQL safety — see [`CLAUDE.md`](../../../CLAUDE.md) and [`docs/sql-safety.md`](../../../docs/sql-safety.md): - **Parameterize every value.** DuckDB: positional `?`. SQLite: named `$name`. - **Identifiers can't be parameters** — validate against the catalog (`information_schema.columns` for DuckDB, `pragma_table_info($t)` for SQLite); see the `HasColumn` helpers. - **Open read-only** for analysis (`ACCESS_MODE=READ_ONLY` / `Mode=ReadOnly`). - The report `ExecuteQuery(string)` sink takes only internally-constructed SQL (constants in `ReportSql`); never pass it external input. Ad-hoc CLI querying (no SQL command exists in the tool): use the `duckdb` CLI on a `.duckdb` file (open with `-readonly`; if a lock error mentions DataGrip, ask the user to close that connection). ## Upkeep: when you change the schema A schema change is not done until **all** of these are consistent: 1. **Both backends** — mirror the change in [`DuckDbExportDestination.cs`](../../../Core/ExportDestination/DuckDbExportDestination.cs) **and** [`SqliteWriter.cs`](../../../Core/ExportDestination/SqliteWriter.cs) (tables, indexes, and the `CreateViewsScript`). Remember: DuckDB has `ASOF` joins and table macros; SQLite does not (use a correlated subquery; macros are DuckDB-only). Keep index/view DDL **re-runnable** (`CREATE INDEX IF NOT EXISTS`, DuckDB `CREATE OR REPLACE VIEW` / SQLite drop-then-create) so `UpgradeSchema` works. 2. **The doc** — update [`docs/database-schema.md`](../../../docs/database-schema.md): table/column tables, view/macro list, join keys, and the version table. New tables, views, columns, and identifiers must appear here. 3. **The version** — in [`Core/Models/DatabaseSchemaInfo.cs`](../../../Core/Models/DatabaseSchemaInfo.cs): - **View/index change only** (add/change a view or index): bump **`SchemaMinor`**. Existing databases can be upgraded in place (`MemorySnapshotDataTools upgrade`), so no re-export. - **Table/column change** (add/rename/remove a table or column, or change a column's meaning/units): bump **`SchemaMajor`** and reset `SchemaMinor` to 0. Old databases require a re-export. Make sure both writers' table DDL and `schema_meta` insert stay in sync. - Add a row to the doc's version table either way. 4. **Readers** — `snapshot_info` is read with `SELECT *` by column name (`SummaryReportRunner.ReadSnapshotInfo`), so new columns are safe; if you add a column some reader needs, wire it there. 5. **Tests** — extend `DatabaseSchemaInfoTests` and the export round-trip tests so the new schema/view/version is asserted. ## See also - `memory-snapshot-report` skill — export a `.snap` to a database and generate reports. - [`docs/database-schema.md`](../../../docs/database-schema.md) — canonical schema.
在 GitHub 查看