Skip to content

fix(archive): Finish forced archive when the database directory has leftover files - #625

Open
regdocs wants to merge 1 commit into
developfrom
fix/archive-site-leftover-database-directory
Open

regdocs wants to merge 1 commit into
developfrom
fix/archive-site-leftover-database-directory

Conversation

@regdocs

@regdocs regdocs commented Oct 10, 2026

Copy link
Copy Markdown
Member

Problem

A forced Archive Site job can fail at the database drop:

pymysql.err.OperationalError: (1010, 'Error dropping database (can't rmdir './_xxxxxxxx', errno: 39 "Directory not empty")')

DROP DATABASE only removes files MariaDB recognises as table files. Any other file in the schema directory stops the final rmdir. One example is a MyISAM auto-recovery backup (__global_search.MYD-<timestamp>.BAK), which database servers write under myisam-recover-options = BACKUP. bench drop-site --force only tolerates a failed backup, so it stops at this point. The site's database user is never dropped, the site directory never moves to archived, and the job fails. If this happens in the archive step of a Site Migration, the whole migration fails after the site has already been restored on the destination.

Change

In Bench.bench_archive_site, when force is set and drop-site fails with this error (1010 / errno 39 on the site's own schema directory):

  • every table is already dropped, so the error is treated as non-fatal;
  • every account named after the site's database user is dropped (mysql.user lookup), as drop-site would have done;
  • the site directory moves to sites/archived/<site>, using drop-site's numeric suffix when a site with that name was archived before.

Without force, or for any other drop-site error, the archive fails as before.

Trade-off

The emptied schema directory, holding only the stray files, stays on the database server, and the schema still appears in SHOW DATABASES. Removing it needs access to the database host, which the app server's agent doesn't have.

Tests

Added to agent/tests/test_site.py:

  • forced archive with the leftover-directory error drops the users and archives the site (including the name-collision suffix);
  • the same error without force still fails;
  • other drop-site errors with force still fail.

🤖 Generated with Claude Code

…eftover files

DROP DATABASE removes only the table files MariaDB knows about. A stray
file in the schema directory, such as a MyISAM auto-recovery backup
(<table>.MYD-<timestamp>.BAK written under myisam-recover-options=BACKUP),
makes the final rmdir fail with error 1010 / errno 39. drop-site then
aborts before dropping the site's database user and moving the site to
archived, so the archive job fails even with force.

At that point every table is already gone. With force, treat this error
as non-fatal: drop the site's database users and move the site directory
to sites/archived the same way drop-site would. Without force, or for any
other drop-site error, the archive still fails as before.

The emptied schema directory is left on the database server.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@regdocs regdocs self-assigned this Oct 10, 2026
@mergify

mergify Bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

This pull request does not currently match the merge queue conditions, so it cannot be queued from here. The box comes back if it matches again.

@greptile-apps

greptile-apps Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 4/5

[High impact] Adds fallback logic to complete site archival when database cleanup fails.

Fix cleanup for sites with a separate db_user before merging.

Reviews (1) · Last reviewed commit: "fix(archive): Finish forced archive when..." · Reviewed by Greptile

Comment thread agent/bench.py
Comment on lines +466 to +468
hosts = self.execute(f"{mysql} -N -B -e \"SELECT Host FROM mysql.user WHERE User = '{database}'\"")
for host in hosts["output"].split():
self.execute(f"{mysql} -e \"DROP USER IF EXISTS '{database}'@'{host}'\"")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Archived site's user remains

When db_user differs from db_name, the fallback drops accounts named after the database instead of the site's actual user. It then archives the site and reports success while leaving that user behind. Pass Site.user separately and use it for both account queries.

Prompt To Fix With AI
This is a comment left during a code review.
Path: agent/bench.py
Line: 466-468

Comment:
**Archived site's user remains**

When `db_user` differs from `db_name`, the fallback drops accounts named after the database instead of the site's actual user. It then archives the site and reports success while leaving that user behind. Pass `Site.user` separately and use it for both account queries.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant