firebird
firebird copied to clipboard
Index is corrupted after multiple record updates
How to reproduce on FB3: I've created a database which can show the problem: DB_FB_3_0.zip
It has a table T1 with non-unique index and a procedure update_from_log which updates records of the table.
execute procedure update_from_log(0, 8082); -- Multiple updates. Index is still OK.
execute procedure update_from_log(8082, 1); -- 1 more update. Index is corrupted.
commit;
Result of gfix -v -full:
DESKTOP-75ILNSS Wed Dec 8 12:39:15 2021
Database: Z:\DB_FB_3_0.FDB
Validation started
DESKTOP-75ILNSS Wed Dec 8 12:39:15 2021
Database: Z:\DB_FB_3_0.FDB
Warning: Index 2 misses node on page 4754 level 1 at offset 39 in table T1 (128)
DESKTOP-75ILNSS Wed Dec 8 12:39:15 2021
Database: Z:\DB_FB_3_0.FDB
Warning: Index 2 has inconsistent left sibling pointer, page 4754 level 1 at offset 43 in table T1 (128)
DESKTOP-75ILNSS Wed Dec 8 12:39:15 2021
Database: Z:\DB_FB_3_0.FDB
Warning: Index 2 misses node on page 4754 level 1 at offset 43 in table T1 (128)
DESKTOP-75ILNSS Wed Dec 8 12:39:15 2021
Database: Z:\DB_FB_3_0.FDB
Warning: Index 2 has inconsistent left sibling pointer, page 4754 level 1 at offset 1050 in table T1 (128)
DESKTOP-75ILNSS Wed Dec 8 12:39:15 2021
Database: Z:\DB_FB_3_0.FDB
Warning: Index 2 has orphan child page at page 4754 in table T1 (128)
DESKTOP-75ILNSS Wed Dec 8 12:39:15 2021
Database: Z:\DB_FB_3_0.FDB
Validation finished: 0 errors, 5 warnings, 0 fixed
What happens on the last update: Page 4754 is the root of the index (1-level). 240 and 4711 are 0-level pages. Page 4711 splits. 4752 is the new 0-level page and its number should be inserted at the level above (page 4754). The problem is 4711 and 4752 have the same key and record number, and according to the code
if (!validateDuplicates)
{
// if recordnumber is higher we need to insert before it.
if (newRecordNumber <= beforeInsertNode.recordNumber) {
break;
}
}
4752 is inserted before 4711. The correct order of pages is violated.