Skip to content

Commit

Permalink
Backport fix for bug CORE-2616 : page 1530262 is of wrong type (expec…
Browse files Browse the repository at this point in the history
…ted 7, found 5)
  • Loading branch information
hvlad committed Sep 24, 2009
1 parent 76b52bb commit 17afb2b
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 72 deletions.
107 changes: 46 additions & 61 deletions src/jrd/btr.cpp
Expand Up @@ -42,7 +42,6 @@
#include "gen/iberror.h"
#include "../jrd/common.h"
#include "../jrd/lck.h"
#include "../jrd/LocksCache.h"
#include "../jrd/GlobalRWLock.h"
#include "../jrd/cch.h"
#include "../jrd/sort.h"
Expand Down Expand Up @@ -221,8 +220,6 @@ static void checkForLowerKeySkip(bool&, const bool, const IndexNode&, const temp
const index_desc&, const IndexRetrieval*);


typedef LocksCache<CachedLock> BtrPageLocks;

void Database::destroyBtrLocks()
{
BtrPageLocks *locks = reinterpret_cast<BtrPageLocks*> (dbb_btr_page_locks);
Expand All @@ -231,82 +228,70 @@ void Database::destroyBtrLocks()
}


class Jrd::BtrPageGCLock
BtrPageGCLock::~BtrPageGCLock()
{
public:
explicit BtrPageGCLock(thread_db* tdbb)
{
m_lock = NULL;
}
fb_assert(!m_lock);

~BtrPageGCLock()
{
fb_assert(!m_lock);

if (m_lock) {
enablePageGC(JRD_get_thread_data());
}
if (m_lock) {
enablePageGC(JRD_get_thread_data());
}
}

static BtrPageLocks* getLocksCache(thread_db* tdbb)
BtrPageLocks* BtrPageGCLock::getLocksCache(thread_db* tdbb)
{
Database *dbb = tdbb->getDatabase();
BtrPageLocks* locks = reinterpret_cast<BtrPageLocks*> (dbb->dbb_btr_page_locks);
if (!locks)
{
Database *dbb = tdbb->getDatabase();
BtrPageLocks* locks = reinterpret_cast<BtrPageLocks*> (dbb->dbb_btr_page_locks);
if (!locks)
{
locks = FB_NEW (*dbb->dbb_permanent)
BtrPageLocks(tdbb, LCK_btr_dont_gc, PageNumber::getLockLen(), 128);
dbb->dbb_btr_page_locks = locks;
}

return locks;
locks = FB_NEW (*dbb->dbb_permanent)
BtrPageLocks(tdbb, LCK_btr_dont_gc, PageNumber::getLockLen(), 128);
dbb->dbb_btr_page_locks = locks;
}

void disablePageGC(thread_db* tdbb, const PageNumber &page)
{
fb_assert(!m_lock);

UCHAR key[8];
page.getLockStr(key);
return locks;
}

BtrPageLocks* locks = getLocksCache(tdbb);
m_lock = locks->get(tdbb, key);
m_lock->lock(tdbb, LCK_read, LCK_WAIT);
}
void BtrPageGCLock::disablePageGC(thread_db* tdbb, const PageNumber &page)
{
fb_assert(!m_lock);

void enablePageGC(thread_db* tdbb)
{
fb_assert(m_lock);
m_lock->unlock(tdbb, LCK_read);
m_lock = NULL;
}
UCHAR key[8];
page.getLockStr(key);

static bool isPageGCAllowed(thread_db* tdbb, const PageNumber& page)
{
UCHAR key[8];
page.getLockStr(key);
BtrPageLocks* locks = getLocksCache(tdbb);
m_lock = locks->get(tdbb, key);
m_lock->lock(tdbb, LCK_read, LCK_WAIT);
}

BtrPageLocks* locks = getLocksCache(tdbb);
GlobalRWLock *lock = locks->get(tdbb, key);
void BtrPageGCLock::enablePageGC(thread_db* tdbb)
{
fb_assert(m_lock);
m_lock->unlock(tdbb, LCK_read);
m_lock = NULL;
}

ISC_STATUS_ARRAY temp_status;
ISC_STATUS* const org_status = tdbb->tdbb_status_vector;
tdbb->tdbb_status_vector = temp_status;
bool BtrPageGCLock::isPageGCAllowed(thread_db* tdbb, const PageNumber& page)
{
UCHAR key[8];
page.getLockStr(key);

const bool res = lock->lock(tdbb, LCK_write, LCK_NO_WAIT);
BtrPageLocks* locks = getLocksCache(tdbb);
GlobalRWLock *lock = locks->get(tdbb, key);

if (res) {
lock->unlock(tdbb, LCK_write);
}
ISC_STATUS_ARRAY temp_status;
ISC_STATUS* const org_status = tdbb->tdbb_status_vector;
tdbb->tdbb_status_vector = temp_status;

tdbb->tdbb_status_vector = org_status;
const bool res = lock->lock(tdbb, LCK_write, LCK_NO_WAIT);

return res;
if (res) {
lock->unlock(tdbb, LCK_write);
}

private:
GlobalRWLock *m_lock;
};
tdbb->tdbb_status_vector = org_status;

return res;
}


USHORT BTR_all(thread_db* tdbb,
Expand Down
23 changes: 23 additions & 0 deletions src/jrd/btr.h
Expand Up @@ -35,6 +35,7 @@
#include "../jrd/err_proto.h" /* Index error types */
#include "../jrd/RecordNumber.h"
#include "../jrd/sbm.h"
#include "../jrd/LocksCache.h"

/* 64 turns out not to be enough indexes */
/* #define MAX_IDX 64 */ /* that should be plenty of indexes */
Expand Down Expand Up @@ -225,6 +226,28 @@ const int irb_exclude_upper = 64; // exclude upper bound keys while scanning i

typedef Firebird::HalfStaticArray<float, 4> SelectivityList;

class GlobalRWLock;
typedef LocksCache<CachedLock> BtrPageLocks;

class BtrPageGCLock
{
public:
explicit BtrPageGCLock(Jrd::thread_db* tdbb)
{
m_lock = NULL;
}

~BtrPageGCLock();

static BtrPageLocks* getLocksCache(thread_db* tdbb);
void disablePageGC(thread_db* tdbb, const PageNumber &page);
void enablePageGC(thread_db* tdbb);
static bool isPageGCAllowed(thread_db* tdbb, const PageNumber &page);

private:
GlobalRWLock *m_lock;
};

} //namespace Jrd

#endif /* JRD_BTR_H */
Expand Down
43 changes: 38 additions & 5 deletions src/jrd/nav.cpp
Expand Up @@ -66,6 +66,7 @@ static UCHAR* get_position(thread_db*, RecordSource*, IRSB_NAV, WIN *, RSE_GET_M
static bool get_record(RecordSource*, IRSB_NAV, record_param*, temporary_key*, bool);
static void init_fetch(IRSB_NAV);
static UCHAR* nav_open(thread_db*, RecordSource*, IRSB_NAV, WIN *, RSE_GET_MODE, btree_exp**);
static void set_page(IRSB_NAV impure, WIN* window);
static void set_position(IRSB_NAV, record_param*, WIN*, const UCHAR*, btree_exp*, const UCHAR*, USHORT);
static bool setup_bitmaps(RecordSource*, IRSB_NAV);

Expand Down Expand Up @@ -969,7 +970,7 @@ static void init_fetch(IRSB_NAV impure)
**************************************/
if (impure->irsb_flags & irsb_first) {
impure->irsb_flags &= ~irsb_first;
impure->irsb_nav_page = 0;
set_page(impure, NULL);
}
}

Expand All @@ -996,7 +997,7 @@ static UCHAR* nav_open(
if (!setup_bitmaps(rsb, impure))
return NULL;

impure->irsb_nav_page = 0;
set_page(impure, NULL);
impure->irsb_nav_length = 0;

#ifdef SCROLLABLE_CURSORS
Expand All @@ -1021,8 +1022,7 @@ static UCHAR* nav_open(
Ods::btree_page* page = BTR_find_page(tdbb, retrieval, window, idx, &lower,
&upper, false);
#endif
impure->irsb_nav_page = window->win_page.getPageNum();

set_page(impure, window);

#ifdef SCROLLABLE_CURSORS
// store the upper and lower bounds for the search in the impure area for the rsb
Expand Down Expand Up @@ -1136,6 +1136,39 @@ static UCHAR* nav_open(
}


static void set_page(IRSB_NAV impure, WIN* window)
{
/**************************************
*
* s e t _ p a g e
*
**************************************
*
* Functional description
* Take a LCK_btr_dont_gc lock on walked index page to prevent its
* removal from index while page lock is not taken
*
**************************************/
const SLONG newPage = window ? window->win_page.getPageNum() : 0;

if (impure->irsb_nav_page != newPage)
{
thread_db *tdbb = JRD_get_thread_data();

if (impure->irsb_nav_page)
impure->irsb_nav_btr_gc_lock->enablePageGC(tdbb);

if (newPage)
{
if (!impure->irsb_nav_btr_gc_lock)
impure->irsb_nav_btr_gc_lock = FB_NEW(*tdbb->getDefaultPool()) BtrPageGCLock(tdbb);
impure->irsb_nav_btr_gc_lock->disablePageGC(tdbb, window->win_page);
}
impure->irsb_nav_page = newPage;
}
}


static void set_position(IRSB_NAV impure, record_param* rpb, WIN* window,
const UCHAR* pointer, btree_exp* expanded_node,
const UCHAR* key_data, USHORT length)
Expand All @@ -1156,7 +1189,7 @@ static void set_position(IRSB_NAV impure, record_param* rpb, WIN* window,
// We can actually set position without having a data page
// fetched; if not, just set the incarnation to the lowest possible
impure->irsb_nav_incarnation = CCH_get_incarnation(window);
impure->irsb_nav_page = window->win_page.getPageNum();
set_page(impure, window);
impure->irsb_nav_number = rpb->rpb_number;

// save the current key value if it hasn't already been saved
Expand Down
20 changes: 14 additions & 6 deletions src/jrd/rse.cpp
Expand Up @@ -170,17 +170,25 @@ void RSE_close(thread_db* tdbb, RecordSource* rsb)
return;

case rsb_navigate:
if (bFreeAll)
{
irsb_nav* imp_nav = (irsb_nav*) impure;
if (imp_nav->irsb_nav_bitmap)
if (bFreeAll)
{
delete (*imp_nav->irsb_nav_bitmap);
*imp_nav->irsb_nav_bitmap = NULL;
if (imp_nav->irsb_nav_bitmap)
{
delete (*imp_nav->irsb_nav_bitmap);
*imp_nav->irsb_nav_bitmap = NULL;
}

delete imp_nav->irsb_nav_records_visited;
imp_nav->irsb_nav_records_visited = NULL;
}

delete imp_nav->irsb_nav_records_visited;
imp_nav->irsb_nav_records_visited = NULL;
if (imp_nav->irsb_nav_page)
{
imp_nav->irsb_nav_btr_gc_lock->enablePageGC(tdbb);
imp_nav->irsb_nav_page = 0;
}
}
return;

Expand Down
2 changes: 2 additions & 0 deletions src/jrd/rse.h
Expand Up @@ -54,6 +54,7 @@ class CompilerScratch;
class jrd_prc;
class Format;
class VaryingStr;
class BtrPageGCLock;

// Record source block (RSB) types

Expand Down Expand Up @@ -267,6 +268,7 @@ struct irsb_nav {
ULONG irsb_nav_count; // record count of last record returned
RecordBitmap** irsb_nav_bitmap; // bitmap for inversion tree
RecordBitmap* irsb_nav_records_visited; // bitmap of records already retrieved
BtrPageGCLock* irsb_nav_btr_gc_lock; // lock to prevent removal of currently walked index page
USHORT irsb_nav_offset; // page offset of current index node
USHORT irsb_nav_lower_length; // length of lower key value
USHORT irsb_nav_upper_length; // length of upper key value
Expand Down

0 comments on commit 17afb2b

Please sign in to comment.