Skip to content

Conversation

TreeHunter9
Copy link
Contributor

  • This should eliminate double writes of pages when file is extended.
  • If fallocate is not supported by filesystem fallback to the old method of writing zeroes to the file.

Restore gets the biggest performance boost from this patch. I tested restore on a database with one table CREATE TABLE TAB1(V1 VARCHAR(25), V2 VARCHAR(25), V3 VARCHAR(25), V4 VARCHAR(25)), with a file size of about 16 GB. The testing was done on two different PCs with the same OS (Ubuntu 24.04):
Intel Core i5-10400 + WD Red SN700 1000 GB (111150WD): +10% speedup with -par 8;
Ryzen 7 7700 + KINGSTON SKC3000S1024G (EIFK31.6): +18% speedup with -par 8;
On Windows, the performance improvement is small (about 3-5%), so the real target of this patch is Linux.

…file

- This should eliminate double writes of pages when file is extended.
- If fallocate is not supported by filesystem fallback to the old method of writing zeroes to the file.
return std::nullopt;

// File was extended, reset cached value
maxPageNumber = 0;
Copy link
Member

Choose a reason for hiding this comment

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

I know this was the original code, but still wondering -- why we cannot do maxPageNumber += reqPages, given we know the file was extended successfully?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The only reason I found is that if our page size is less than OS page size, we may get different value from PIO_get_number_of_pages() because it uses fstat(), but in all other cases we should get the same value. And as I can see in current code we cannot call PageSpace::extend() from multiple threads due to fetching PIP with write lock before calling PageSpace::extend().

Copy link
Member

Choose a reason for hiding this comment

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

Couldn't it be called from BackupManager::endBackup() and ensureDiskSpace() simultaneously? If not, please add a comment near the increment explaining why it's safe. If there are any doubts, better leave it being reset to zero.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If I understand correctly, calls to extendDatabase() inside endBackup() happens when backup_state is hdr_nbak_stalled, so calls to ensureDiskSpace() will not result in the file being extended. Also there is BackupManager::StateReadGuard stateGuard(tdbb); in ensureDiskSpace() which provides even more protection against races from nbakup.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But it is very bug-prone in future, if this logic will be changed, so I believe it is better to reset the cached value to zero (and we shouldn't see a significant performance improvement, the additional call to fstat() to obtain the file size should be fast anyway, as it only uses information from inode (I hope it's fast)).

@dyemanov dyemanov merged commit d3ef1f0 into FirebirdSQL:master Oct 8, 2025
23 checks passed
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.

4 participants