Issue Details (XML | Word | Printable)

Key: CORE-3468
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Vlad Khorsun
Reporter: Vlad Khorsun
Votes: 0
Watchers: 2
Operations

If you were logged in you would be able to see more operations.
Firebird Core

Attempt to read after the end of file when nbackup state is stalled

Created: 05/May/11 09:55 PM   Updated: 23/Apr/13 12:04 PM
Component/s: Engine
Affects Version/s: 2.1.0, 2.0.4, 2.1.1, 2.0.5, 2.1.2, 2.1.3, 2.0.6, 2.5.0, 2.1.4
Fix Version/s: 2.5.1, 2.1.5, 3.0 Alpha 1

Time Tracking:
Not Specified

Environment: SuperServer
Issue Links:
Relate
 

Planning Status: Unspecified


 Description  « Hide
When relation is extended new page is allocated (and faked) and passed into DPM\extend_relation() function.
Then it is released, and free slot on some pointer page is searched.
When free slot is found just allocated page is fetched again and linked into pointer page.

When nbackup state is stalled database file pre-allocation feature is disabled to left database file in consistent
state while it is copied for backup purpose. Therefore new pages could be allocated after end of database file.
As all new pages will be written into delta and later merged back into database file this is OK.

The issue is that new data page buffer could be evicted from page cache after it was released at the start of
extend_relation(). When page is fetched again it should be read from disk. In stalled state page first reads
from delta. Delta have preallocated space and read succeeds. As page was never written its image contains
zero's only. In this case attempt to read page from database file is performed.

Here we have IO read error : attempt to read after the end of file.


 All   Comments   Work Log   Change History   Version Control   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Vlad Khorsun added a comment - 05/May/11 10:01 PM
The simplest solution is to use CCH_fake instead of CCH_fetch when new allocated page is fetched second time.
CCH_fake doesn't reads page image from disk and there can't be any risk that this just allocated page is used by
someone else.

Another solution is to format page header before release. This will force page write in case of eviction and later
half-correct image will be read from delta. This is enough to not make attemp to read this page from database
and avoid potential IO read error.

I used first solution as it is simple and have no IO overhead.

Vlad Khorsun added a comment - 21/Mar/12 09:27 AM
> The issue is that new data page buffer could be evicted from page cache after it was released at the start of
> extend_relation(). When page is fetched again it should be read from disk. In stalled state page first reads
> from delta. Delta have preallocated space and read succeeds. As page was never written its image contains
> zero's only. In this case attempt to read page from database file is performed.

Actually, the code is diffrent in v3 and before.

Before v3 CCH_fetch_page() decides to re-read page from database if pag_checksum is zero. This is correct assumption as page checksum can't be zero.

In v3 we removed checksum's and check was changed : now it checks for pag_type and it really could be zero in the case above.

Therefore the patch is not necessary for v2.x and should be reworked for v3.

I'll undo patch for 2.5.2 and 2.1.5 (after additional testing) as it caused unexpected side effect - second call of CCH_fake writes the just allocated page to disk (see CORE-3792).

For v3 the patch will be undone and reworked.