Skip to content

Fix orphaned entity data - #1027

Open
tonyjamesstark wants to merge 2 commits into
PlayPro:masterfrom
tonyjamesstark:fix-orphaned-entity-data
Open

tonyjamesstark wants to merge 2 commits into
PlayPro:masterfrom
tonyjamesstark:fix-orphaned-entity-data

Conversation

@tonyjamesstark

Copy link
Copy Markdown

co_entity stores the entity state for each mob kill, and it is referenced by co_block.data where action = 3 and type <> 0. It has no world column, so r:#world purges delete the kill rows but never the co_entity rows. Those blobs become orphans that no later purge removes.

  • SQLite: the purge copies only co_entity rows that a retained kill row still references. This also removes orphans that earlier purges left.
  • MySQL and DuckDB: the purge deletes the co_entity rows of the purged kill rows, before co_block is purged. MySQL uses a multi-table DELETE ... JOIN. On MySQL 8, EXPLAIN shows it reads co_block through the wid index and deletes by primary key. Global purges keep the existing time-based delete.
  • MySQL with #optimize: the purge deletes every orphaned co_entity row through a temporary table of referenced ids. This needs the CREATE TEMPORARY TABLES privilege. A failure is reported the same way as the table loop, and the rest of the purge still runs.

Player kills (type = 0, data = user id) are never treated as co_entity references.

Removing orphaned rows now also means the v26 migration of SQLite and MySQL entity data converts fewer rows.

authored and verified with claude

co_entity has no world column, so /co purge r:#world deleted the kill
rows in co_block but kept every co_entity row. Those blobs became
orphans that no later purge removed.

- SQLite: copy only the co_entity rows that a retained kill row still
  references. This also drops orphans left by earlier purges.
- MySQL/DuckDB: delete the co_entity rows of the kill rows a world purge
  removes, before co_block is purged. MySQL uses a join so MariaDB and
  MySQL 5.7 do not run a dependent subquery. Global purges keep the
  cheaper time-based delete, which is equivalent. If MySQL stops between
  the two deletes, running the same purge again removes the remaining
  kill rows.

Player kills use the kill action with type 0 and a user id in data, so
they are never treated as co_entity references.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PdEuKbjcVoVinVQJq4te1f
MySQL deletes in place, so co_entity rows orphaned by earlier world
purges stay until something removes them. With #optimize, delete every
co_entity row that no kill row references, through a temporary table of
referenced ids (avoids an anti-join on the unindexed co_block.data), then
let OPTIMIZE reclaim the space. Failures are reported like the table
loop, so the entity_spawn link cleanup still runs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PdEuKbjcVoVinVQJq4te1f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants