Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix "xapian audit creates a bogus directory with no entries" bug #5014

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

brong
Copy link
Member

@brong brong commented Sep 1, 2024

This caused real production issues at Fastmail. We have a weekly cronjob running squatter -A to audit indexes. This creates a zero-record database, which when you later try to open it causes issues!

The fix is to check that we got all the expected Xapian glass files before considering a database to be "real", and so we don't include databases without terms.

This really is a multi-stage bug! Stage 1:

[72048] =====> Instance::_fork_command[1969] Running: "/usr/cyrus/bin/squatter" "-C" "/run/cass/0959120101/conf/imapd.conf" "-A"

C: 8 search fuzzy subject xyzzy
S: * SEARCH 1
S: 8 OK Completed (1 msgs in 0.000 secs)

Still works - but then we use compact_dbs to compact that empty database, and it produces a broken database!

But then we compact that one down, and:

[72048] =====> Instance::_fork_command[1969] Running: "/usr/cyrus/bin/squatter" "-C" "/run/cass/0959120101/conf/imapd.conf" "-z" "t2" "-t" "t1"

C: 9 search fuzzy subject xyzzy
S: * SEARCH
S: 9 OK Completed (0 msgs in 0.000 secs)

and in syslog:

Sep 01 20:03:46.836820 elg 1003450101/imap[72211]: command: 9 Search
Sep 01 20:03:46.837198 elg 1003450101/imap[72211]: xapian_wrapper: invalid db version in /run/cass/1003450101/search2/user/uuid/4/9/4942a15e-d3da-4845-bcc2-24967d476c5e/xapian.1

@brong brong requested a review from rsto September 1, 2024 10:04
Copy link
Member

@rsto rsto left a comment

Choose a reason for hiding this comment

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

Ouch.. looks good to me with one nit.

};

for (i = 0; known_files[i]; i++) {
char *fname = strconcat(path, "/", known_files[i], (char *)NULL);
Copy link
Member

Choose a reason for hiding this comment

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

Given that we expect the majority of users to have all these files the cost of calling malloc/free five times looks unnecessary expensive, given that we could achieve the same by using a single struct buf for the building the file names in the loop.

But since the cost of calling stat is likely to make the cost of malloc/free look small in comparison, there's no big need for this optimization.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I don't think that it's anywhere near important compared to all the other costs. Not only stat but the locking cost per user - we have only a few files per user.

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