
|
If you were logged in you would be able to see more operations.
|
|
|
| Planning Status: |
Unspecified
|
|
When some relation is extended by the few attachments simultaneously bugcheck could occurs.
Reproduced with SS but it is independent on engine architecture.
Test executed 20 threads insering data in the same table. Bugcheck happens after few hours of work, so it is rare and hard to reproduce.
|
|
Description
|
When some relation is extended by the few attachments simultaneously bugcheck could occurs.
Reproduced with SS but it is independent on engine architecture.
Test executed 20 threads insering data in the same table. Bugcheck happens after few hours of work, so it is rare and hard to reproduce. |
Show » |
|
To link newly allocated data page into relation we need to find a free slot on some pointer page.
If there is no free slots we allocate and link new pointer page.
for (pp_sequence = relPages->rel_slot_space;; pp_sequence++) {
if (!(ppage = get_pointer_page(tdbb, relation, relPages, &pp_window,
pp_sequence, LCK_write)))
{
BUGCHECK(253); /* msg 253 pointer page vanished from extend_relation */
}
SLONG* slots = ppage->ppg_page;
...
if (ppage->ppg_header.pag_flags & ppg_eof) {
-- here we allocate new PP
ppage = (pointer_page*) DPM_allocate(tdbb, &new_pp_window);
ppage->ppg_header.pag_type = pag_pointer;
ppage->ppg_header.pag_flags |= ppg_eof;
ppage->ppg_relation = relation->rel_id;
ppage->ppg_sequence = ++pp_sequence;
slot = 0;
CCH_must_write(&new_pp_window);
CCH_RELEASE(tdbb, &new_pp_window);
-- here we store new PP number at in-memory array of PPs
vcl* vector = relPages->rel_pages =
vcl::newVector(*dbb->dbb_permanent, relPages->rel_pages, pp_sequence + 1);
(*vector)[pp_sequence] = new_pp_window.win_page.getPageNum();
-- after this point concurrent attachments in the same SS process could see new PP
-- but we didn't release sheduler still so they can't
// hvlad: temporary tables don't save their pointer pages in RDB$PAGES
if (relation->rel_id && (relPages->rel_instance_id == 0))
{
-- here we store new PP number in RDB$PAGES
DPM_pages(tdbb, relation->rel_id, pag_pointer,
(SLONG) pp_sequence, new_pp_window.win_page.getPageNum());
-- after this point any concurrent attachments could see new PP
-- and we of course released sheduler inside DPM_pages
}
relPages->rel_slot_space = pp_sequence;
ppage = (pointer_page*) pp_window.win_buffer;
CCH_MARK(tdbb, &pp_window);
ppage->ppg_header.pag_flags &= ~ppg_eof;
ppage->ppg_next = new_pp_window.win_page.getPageNum();
-- BUG : at this point slot 0 could be filled by some other attachment
- ppage = (pointer_page*) CCH_HANDOFF(tdbb, &pp_window, new_pp_window.win_page.getPageNum(),
- LCK_write, pag_pointer);
- break;
-- FIX : therefore release PP and go to the loop again, searching for free slot
+ --pp_sequence;
}
CCH_RELEASE(tdbb, &pp_window);
}
/* We've found a slot. Stick in the pointer to the data page */
if (ppage->ppg_page[slot])
{
-- another BUG : pointer page was not released so engine is in bad shape and can't report error correclty
+ CCH_RELEASE(tdbb, &pp_window);
CORRUPT(258); /* msg 258 page slot not empty */
}