8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 20:43:02 +01:00

Cleaning up

This commit is contained in:
tamlin 2001-12-29 10:09:02 +00:00
parent 9f2c51b4e3
commit c3312c5650

View File

@ -2356,7 +2356,6 @@ BOOLEAN VIO_sweep(TDBB tdbb, TRA transaction)
RPB rpb;
VEC vector;
USHORT i;
JMP_BUF env, *old_env;
SET_TDBB(tdbb);
dbb = tdbb->tdbb_database;
@ -2367,49 +2366,53 @@ BOOLEAN VIO_sweep(TDBB tdbb, TRA transaction)
transaction ? transaction->tra_number : 0);
#endif
if (transaction->tra_attachment->att_flags & ATT_NO_CLEANUP)
if (transaction->tra_attachment->att_flags & ATT_NO_CLEANUP) {
return FALSE;
}
DPM_scan_pages(tdbb);
rpb.rpb_record = NULL;
rpb.rpb_stream_flags = 0;
rpb.rpb_window.win_flags = WIN_large_scan;
old_env = (JMP_BUF *) tdbb->tdbb_setjmp;
tdbb->tdbb_setjmp = (UCHAR *) env;
try {
for (i = 1; (vector = dbb->dbb_relations) && i < vector->count(); i++)
if ((relation = (REL) (*vector)[i]) && relation->rel_pages &&
!(relation->rel_flags & (REL_deleted | REL_deleting))) {
rpb.rpb_relation = relation;
rpb.rpb_number = -1;
rpb.rpb_org_scans = relation->rel_scan_count++;
++relation->rel_sweep_count;
while (VIO_next_record
(tdbb, &rpb, NULL, transaction, 0, FALSE, FALSE)) {
CCH_RELEASE(tdbb, &rpb.rpb_window);
if (relation->rel_flags & REL_deleting)
break;
for (i = 1; (vector = dbb->dbb_relations) && i < vector->count(); i++)
{
if ((relation = (REL) (*vector)[i]) && relation->rel_pages &&
!(relation->rel_flags & (REL_deleted | REL_deleting)))
{
rpb.rpb_relation = relation;
rpb.rpb_number = -1;
rpb.rpb_org_scans = relation->rel_scan_count++;
++relation->rel_sweep_count;
while (VIO_next_record(tdbb,
&rpb,
NULL,
transaction,
0,
FALSE,
FALSE))
{
CCH_RELEASE(tdbb, &rpb.rpb_window);
if (relation->rel_flags & REL_deleting)
break;
#ifdef MULTI_THREAD
if (--tdbb->tdbb_quantum < 0 && !tdbb->tdbb_inhibit)
(void) JRD_reschedule(tdbb, SWEEP_QUANTUM, TRUE);
transaction->tra_oldest_active = dbb->dbb_oldest_snapshot;
if (--tdbb->tdbb_quantum < 0 && !tdbb->tdbb_inhibit) {
(void) JRD_reschedule(tdbb, SWEEP_QUANTUM, TRUE);
}
transaction->tra_oldest_active = dbb->dbb_oldest_snapshot;
#endif
}
--relation->rel_sweep_count;
--relation->rel_scan_count;
}
--relation->rel_sweep_count;
--relation->rel_scan_count;
}
tdbb->tdbb_setjmp = (UCHAR *) old_env;
if (rpb.rpb_record) {
delete rpb.rpb_record;
}
} // try
catch (...) {
tdbb->tdbb_setjmp = (UCHAR *) old_env;
delete rpb.rpb_record;
if (relation)
{
@ -3207,9 +3210,7 @@ static void THREAD_ROUTINE garbage_collector(DBB dbb)
REL relation;
TRA transaction;
RPB rpb;
VEC vector;
EVENT gc_event;
JMP_BUF env;
THREAD_ENTER;
CHECK_DBB(dbb);
@ -3230,7 +3231,6 @@ static void THREAD_ROUTINE garbage_collector(DBB dbb)
tdbb->tdbb_default = dbb->dbb_permanent;
tdbb->tdbb_status_vector = status_vector;
tdbb->tdbb_quantum = SWEEP_QUANTUM;
tdbb->tdbb_setjmp = (UCHAR *) env;
tdbb->tdbb_flags = TDBB_sweeper;
/* Surrender if resources to start up aren't available. */
@ -3278,17 +3278,21 @@ static void THREAD_ROUTINE garbage_collector(DBB dbb)
In particular, make worker threads perform their own
garbage collection so that errors are reported to users. */
if (dbb->dbb_flags & DBB_suspend_bgio) {
if (dbb->dbb_flags & DBB_suspend_bgio)
{
ATT attachment;
for (attachment = dbb->dbb_attachments;
attachment != 0; attachment = attachment->att_next)
{
if (attachment->att_flags & ATT_notify_gc) {
attachment->att_flags &= ~ATT_notify_gc;
attachment->att_flags |= ATT_disable_notify_gc;
}
}
while (dbb->dbb_flags & DBB_suspend_bgio) {
while (dbb->dbb_flags & DBB_suspend_bgio)
{
count = ISC_event_clear(gc_event);
THREAD_EXIT;
(void) ISC_event_wait(1, &gc_event, &count,
@ -3300,30 +3304,39 @@ static void THREAD_ROUTINE garbage_collector(DBB dbb)
for (attachment = dbb->dbb_attachments;
attachment != 0; attachment = attachment->att_next)
if (attachment->att_flags & ATT_disable_notify_gc) {
{
if (attachment->att_flags & ATT_disable_notify_gc)
{
attachment->att_flags &= ~ATT_disable_notify_gc;
attachment->att_flags |= ATT_notify_gc;
}
}
}
/* Scan relation garbage collection bitmaps for candidate data pages.
Express interest in the relation to prevent it from being deleted
out from under us while garbage collection is in-progress. */
for (id = 0; (vector = dbb->dbb_relations) && id < vector->count();
id++)
if ((relation = (REL) (*vector)[id])
&& relation->rel_gc_bitmap != 0
&& !(relation->rel_flags & (REL_deleted | REL_deleting))) {
VEC vector;
for (id = 0; (vector = dbb->dbb_relations) && id < vector->count(); ++id)
{
relation = (REL) (*vector)[id];
if (relation &&
relation->rel_gc_bitmap != 0 &&
!(relation->rel_flags & (REL_deleted | REL_deleting)))
{
++relation->rel_sweep_count;
dp_sequence = -1;
rpb.rpb_relation = relation;
while (SBM_next
(relation->rel_gc_bitmap, &dp_sequence,
RSE_get_forward)) {
while (SBM_next(relation->rel_gc_bitmap,
&dp_sequence,
RSE_get_forward))
{
(void) SBM_clear(relation->rel_gc_bitmap, dp_sequence);
if (!transaction) {
if (!transaction)
{
/* Start a "precommitted" transaction by using read-only,
read committed. Of particular note is the absence of a
transaction lock which means the transaction does not
@ -3331,7 +3344,7 @@ static void THREAD_ROUTINE garbage_collector(DBB dbb)
transaction =
TRA_start(tdbb, sizeof(gc_tpb),
const_cast < char *>(gc_tpb));
const_cast<char*>(gc_tpb));
tdbb->tdbb_transaction = transaction;
}
else {
@ -3349,8 +3362,14 @@ static void THREAD_ROUTINE garbage_collector(DBB dbb)
/* Attempt to garbage collect all records on the data page. */
while (VIO_next_record
(tdbb, &rpb, NULL, transaction, NULL, FALSE, TRUE)) {
while (VIO_next_record(tdbb,
&rpb,
NULL,
transaction,
NULL,
FALSE,
TRUE))
{
CCH_RELEASE(tdbb, &rpb.rpb_window);
if (!(dbb->dbb_flags & DBB_garbage_collector)) {
--relation->rel_sweep_count;
@ -3365,11 +3384,12 @@ static void THREAD_ROUTINE garbage_collector(DBB dbb)
}
}
rel_exit:
rel_exit:
dp_sequence = -1;
if (!SBM_next
(relation->rel_gc_bitmap, &dp_sequence,
RSE_get_forward)) {
if (!SBM_next(relation->rel_gc_bitmap,
&dp_sequence,
RSE_get_forward))
{
/* If the bitmap is empty then release it */
SBM_release(relation->rel_gc_bitmap);
@ -3378,19 +3398,26 @@ static void THREAD_ROUTINE garbage_collector(DBB dbb)
else {
/* Otherwise release bitmap segments that have been cleared. */
while (SBM_next
(relation->rel_gc_bitmap, &dp_sequence,
RSE_get_forward));
while (SBM_next(relation->rel_gc_bitmap,
&dp_sequence,
RSE_get_forward))
{
; // do nothing
}
}
--relation->rel_sweep_count;
}
}
/* If there's more work to do voluntarily ask to be rescheduled.
Otherwise, wait for event notification. */
if (found)
{
(void) JRD_reschedule(tdbb, SWEEP_QUANTUM, TRUE);
else {
}
else
{
dbb->dbb_flags &= ~DBB_gc_pending;
/* Make no mistake about it, garbage collection is our first
@ -3532,9 +3559,11 @@ static void list_staying(TDBB tdbb, RPB * rpb, LLS * staying)
if (temp.rpb_b_page != rpb->rpb_b_page ||
temp.rpb_b_line != rpb->rpb_b_line ||
temp.rpb_flags != rpb->rpb_flags) {
while (*staying)
temp.rpb_flags != rpb->rpb_flags)
{
while (*staying) {
delete LLS_POP(staying);
}
next_page = temp.rpb_page;
next_line = temp.rpb_line;
max_depth = 0;
@ -3547,7 +3576,8 @@ static void list_staying(TDBB tdbb, RPB * rpb, LLS * staying)
The while-loop finds this next older version. */
while (temp.rpb_b_page &&
!(temp.rpb_page == next_page && temp.rpb_line == next_line)) {
!(temp.rpb_page == next_page && temp.rpb_line == next_line))
{
temp.rpb_prior = (temp.rpb_flags & rpb_delta) ? data : NULL;
DPM_fetch_back(tdbb, &temp, LCK_read, 1);
depth++;
@ -3555,21 +3585,23 @@ static void list_staying(TDBB tdbb, RPB * rpb, LLS * staying)
/* Don't monopolize the server while chasing long
back version chains. */
if (--tdbb->tdbb_quantum < 0 && !tdbb->tdbb_inhibit)
if (--tdbb->tdbb_quantum < 0 && !tdbb->tdbb_inhibit) {
(void) JRD_reschedule(tdbb, 0, TRUE);
}
#endif
}
/* If there is a next older version, then process it: remember that
version's data in 'staying'. */
if (temp.rpb_page == next_page && temp.rpb_line == next_line) {
if (temp.rpb_page == next_page && temp.rpb_line == next_line)
{
next_page = temp.rpb_b_page;
next_line = temp.rpb_b_line;
temp.rpb_record = NULL;
if (temp.rpb_flags & rpb_deleted)
if (temp.rpb_flags & rpb_deleted) {
CCH_RELEASE(tdbb, &temp.rpb_window);
else {
} else {
VIO_data(tdbb, &temp,
reinterpret_cast < blk * >(tdbb->tdbb_default));
LLS_PUSH(temp.rpb_record, staying);
@ -3589,9 +3621,11 @@ static void list_staying(TDBB tdbb, RPB * rpb, LLS * staying)
of back versions that we saw in a previous iteration (max_depth), then
somebody else must have been garbage collecting also. Remove the entries
in 'staying' that have already been garbage collected. */
while (depth < max_depth--)
if (*staying)
while (depth < max_depth--) {
if (*staying) {
delete LLS_POP(staying);
}
}
}
@ -3612,13 +3646,9 @@ static void notify_garbage_collector(TDBB tdbb, RPB * rpb)
* which are candidates for garbage collection.
*
**************************************/
DBB dbb;
REL relation;
JrdMemoryPool *old_pool;
SLONG dp_sequence;
dbb = tdbb->tdbb_database;
relation = rpb->rpb_relation;
DBB dbb = tdbb->tdbb_database;
REL relation = rpb->rpb_relation;
/* If this is a large sequential scan then defer the release
of the data page to the LRU tail until the garbage collector
@ -3630,9 +3660,10 @@ static void notify_garbage_collector(TDBB tdbb, RPB * rpb)
/* A relation's garbage collect bitmap is allocated
from the database permanent pool. */
old_pool = tdbb->tdbb_default;
JrdMemoryPool* old_pool = tdbb->tdbb_default;
tdbb->tdbb_default = dbb->dbb_permanent;
dp_sequence = rpb->rpb_number / dbb->dbb_max_records;
SLONG dp_sequence = rpb->rpb_number / dbb->dbb_max_records;
SBM_set(tdbb, &relation->rel_gc_bitmap, dp_sequence);
tdbb->tdbb_default = old_pool;
@ -3640,17 +3671,20 @@ static void notify_garbage_collector(TDBB tdbb, RPB * rpb)
the event on which it sleeps to awaken it. */
dbb->dbb_flags |= DBB_gc_pending;
if (!(dbb->dbb_flags & DBB_gc_active))
if (!(dbb->dbb_flags & DBB_gc_active)) {
ISC_event_post(dbb->dbb_gc_event);
}
}
#endif
static void prepare_update(
TDBB tdbb,
TRA transaction,
SLONG commit_tid_read,
RPB * rpb, RPB * temp, RPB * new_rpb, LLS * stack)
static void prepare_update( TDBB tdbb,
TRA transaction,
SLONG commit_tid_read,
RPB* rpb,
RPB* temp,
RPB* new_rpb,
LLS* stack)
{
/**************************************
*
@ -3722,14 +3756,16 @@ static void prepare_update(
/* If it makes sense, store a differences record */
if (new_rpb) {
l = SQZ_differences(reinterpret_cast < char *>(new_rpb->rpb_address),
if (new_rpb)
{
l = SQZ_differences(reinterpret_cast<char*>(new_rpb->rpb_address),
new_rpb->rpb_length,
reinterpret_cast < char *>(temp->rpb_address),
reinterpret_cast<char*>(temp->rpb_address),
temp->rpb_length,
reinterpret_cast < char *>(differences),
reinterpret_cast<char*>(differences),
sizeof(differences));
if ((l < sizeof(differences)) && (l < temp->rpb_length)) {
if ((l < sizeof(differences)) && (l < temp->rpb_length))
{
temp->rpb_address = differences;
temp->rpb_length = l;
new_rpb->rpb_flags |= rpb_delta;
@ -3738,9 +3774,13 @@ static void prepare_update(
#ifdef VIO_DEBUG
if (debug_flag > DEBUG_WRITES_INFO)
{
if (new_rpb)
{
ib_printf(" new record is%sa delta \n",
(new_rpb->rpb_flags & rpb_delta) ? " " : " NOT ");
}
}
#endif
temp->rpb_number = rpb->rpb_number;
@ -3750,23 +3790,28 @@ static void prepare_update(
replacing it with a completely new version. Make sure it
was the same one we stored above. */
while (TRUE) {
while (TRUE)
{
org_rpb.rpb_flags = rpb->rpb_flags;
org_rpb.rpb_f_line = rpb->rpb_f_line;
org_rpb.rpb_f_page = rpb->rpb_f_page;
if (!DPM_get(tdbb, rpb, LCK_write)) {
if (!DPM_get(tdbb, rpb, LCK_write))
{
/* There is no reason why this record would disappear for a
snapshot transaction. */
if (!(transaction->tra_flags & TRA_read_committed))
{
BUGCHECK(186); /* msg 186 record disappeared */
}
else
{
/* A read-committed transaction, on the other hand, doesn't
insist on the presence of any version, so versions of records
and entire records it has already read might be garbage-collected. */
{
if (!DPM_fetch(tdbb, temp, LCK_write))
if (!DPM_fetch(tdbb, temp, LCK_write)) {
BUGCHECK(291); /* msg 291 cannot find record back version */
}
delete_(tdbb, temp, (SLONG) 0, 0);
ERR_post(isc_deadlock, isc_arg_gds, isc_update_conflict, 0);
}
@ -3782,6 +3827,7 @@ static void prepare_update(
reattempt the backout. */
if (rpb->rpb_flags & rpb_gc_active)
{
switch (state) {
case tra_committed:
state = tra_dead;
@ -3795,6 +3841,7 @@ static void prepare_update(
default:
break;
}
}
switch (state) {
case tra_committed:
@ -3973,13 +4020,14 @@ static void prepare_update(
THREAD_SLEEP(100); /* milliseconds */
THREAD_ENTER;
}
else
else {
VIO_backout(tdbb, rpb, transaction);
}
}
}
static BOOLEAN purge(TDBB tdbb, RPB * rpb)
static BOOLEAN purge(TDBB tdbb, RPB* rpb)
{
/**************************************
*