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

Postfix for CORE-3908: Engine leaks memory and crashes when lot of autonomous transactions have been started and finished

This commit is contained in:
alexpeshkoff 2013-02-28 16:23:56 +00:00
parent 3f2477e8f5
commit 97b4b8c2c2
4 changed files with 45 additions and 12 deletions

View File

@ -259,6 +259,8 @@ blb* blb::create2(thread_db* tdbb,
* Basically blb::create() with BPB structure.
*
**************************************/
transaction = transaction->getOuter();
SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase();
CHECK_DBB(dbb);
@ -273,6 +275,7 @@ blb* blb::create2(thread_db* tdbb,
reinterpret_cast<USHORT*>(&from_charset), // safe - alignment not changed
reinterpret_cast<USHORT*>(&to_charset), // safe - alignment not changed
NULL, NULL, NULL, NULL);
blb* blob = allocate_blob(tdbb, transaction);
if (type & isc_bpb_type_stream)
@ -529,6 +532,8 @@ blb* blb::get_array(thread_db* tdbb, jrd_tra* transaction, const bid* blob_id,
* Get array blob and array descriptor.
*
**************************************/
transaction = transaction->getOuter();
SET_TDBB(tdbb);
blb* blob = open2(tdbb, transaction, blob_id, 0, 0);
@ -808,6 +813,8 @@ SLONG blb::get_slice(thread_db* tdbb,
* Fetch a slice of an array.
*
**************************************/
transaction = transaction->getOuter();
SET_TDBB(tdbb);
//Database* database = GET_DBB();
Jrd::ContextPoolHolder context(tdbb, transaction->tra_pool);
@ -1056,6 +1063,7 @@ void blb::move(thread_db* tdbb, dsc* from_desc, dsc* to_desc, const ValueExprNod
CLEAR_NULL(record, id);
jrd_tra* transaction = request->req_transaction;
transaction = transaction->getOuter();
// If the target is a view, this must be from a view update trigger.
// Just pass the blob id thru.
@ -1255,6 +1263,8 @@ blb* blb::open2(thread_db* tdbb,
* Basically blb::open() with BPB structure.
*
**************************************/
transaction = transaction->getOuter();
SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase();
@ -1642,6 +1652,8 @@ void blb::put_slice(thread_db* tdbb,
* Put a slice of an array.
*
**************************************/
transaction = transaction->getOuter();
SET_TDBB(tdbb);
Jrd::ContextPoolHolder context(tdbb, transaction->tra_pool);
@ -1811,6 +1823,7 @@ void blb::scalar(thread_db* tdbb,
* Functional description
*
**************************************/
transaction = transaction->getOuter();
SLONG stuff[IAD_LEN(16) / 4];
@ -1859,6 +1872,7 @@ static ArrayField* alloc_array(jrd_tra* transaction, Ods::InternalArrayDesc* pro
* Allocate an array block based on a prototype array descriptor.
*
**************************************/
fb_assert(!transaction->tra_outer);
// Compute size and allocate block
@ -1896,14 +1910,11 @@ blb* blb::allocate_blob(thread_db* tdbb, jrd_tra* transaction)
* Create a shiney, new, empty blob.
*
**************************************/
fb_assert(!transaction->tra_outer);
SET_TDBB(tdbb);
Database* dbb = tdbb->getDatabase();
// If we are in an autonomous transaction, link the blob on the transaction started by the user.
while (transaction->tra_outer)
transaction = transaction->tra_outer;
// Create a blob large enough to hold a single data page.
blb* blob = FB_NEW(*transaction->tra_pool) blb(*transaction->tra_pool, dbb->dbb_page_size);
@ -1956,7 +1967,11 @@ static ISC_STATUS blob_filter(USHORT action, BlobControl* control)
thread_db* tdbb = JRD_get_thread_data();
jrd_tra* const transaction = reinterpret_cast<jrd_tra*>(control->ctl_internal[1]);
jrd_tra* transaction = reinterpret_cast<jrd_tra*>(control->ctl_internal[1]);
if (transaction)
{
transaction = transaction->getOuter();
}
bid* blob_id = reinterpret_cast<bid*>(control->ctl_internal[2]);
#ifdef DEV_BUILD
@ -2208,6 +2223,7 @@ static ArrayField* find_array(jrd_tra* transaction, const bid* blob_id)
* Find array from temporary blob id.
*
**************************************/
fb_assert(!transaction->tra_outer);
ArrayField* array = transaction->tra_arrays;
for (; array; array = array->arr_next)
@ -2489,6 +2505,7 @@ static void move_from_string(thread_db* tdbb, const dsc* from_desc, dsc* to_desc
jrd_req* request = tdbb->getRequest();
jrd_tra* transaction = request ? request->req_transaction : tdbb->getTransaction();
transaction = transaction->getOuter();
UCharBuffer bpb;
BLB_gen_bpb_from_descs(from_desc, to_desc, bpb);
@ -2595,6 +2612,7 @@ static void move_to_string(thread_db* tdbb, dsc* fromDesc, dsc* toDesc)
jrd_req* request = tdbb->getRequest();
jrd_tra* transaction = request ? request->req_transaction : tdbb->getTransaction();
transaction = transaction->getOuter();
UCharBuffer bpb;
BLB_gen_bpb_from_descs(fromDesc, &blobAsText, bpb);

View File

@ -1636,6 +1636,7 @@ static void release_blobs(thread_db* tdbb, jrd_req* request)
if (transaction)
{
DEV_BLKCHK(transaction, type_tra);
transaction = transaction->getOuter();
// Release blobs bound to this request

View File

@ -3263,6 +3263,10 @@ jrd_tra::~jrd_tra()
{
delete tra_blob_space;
}
else
{
fb_assert(!tra_arrays);
}
DFW_delete_deferred(this, -1);
@ -3309,6 +3313,19 @@ UserManagement* jrd_tra::getUserManagement()
}
jrd_tra* jrd_tra::getOuter()
{
jrd_tra* tra = this;
while (tra->tra_outer)
{
tra = tra->tra_outer;
}
return tra;
}
MemoryPool* jrd_tra::getAutonomousPool()
{
if (!tra_autonomous_pool)

View File

@ -155,7 +155,8 @@ public:
tra_pool(p),
tra_memory_stats(parent_stats),
tra_blobs_tree(p),
tra_blobs(&tra_blobs_tree),
tra_blobs(outer ? outer->tra_blobs : &tra_blobs_tree),
tra_arrays(NULL),
tra_deferred_job(NULL),
tra_resources(*p),
tra_context_vars(*p),
@ -176,12 +177,6 @@ public:
tra_autonomous_pool(NULL),
tra_autonomous_cnt(0)
{
if (outer)
{
tra_arrays = outer->tra_arrays;
tra_blobs = outer->tra_blobs;
}
tra_transactions.resize(length);
}
@ -297,6 +292,7 @@ private:
public:
MemoryPool* getAutonomousPool();
void releaseAutonomousPool(MemoryPool* toRelease);
jrd_tra* getOuter();
SSHORT getLockWait() const
{
@ -310,6 +306,7 @@ public:
if (!tra_blob_space)
{
fb_assert(!tra_outer);
tra_blob_space = FB_NEW(*tra_pool) TempSpace(*tra_pool, TRA_BLOB_SPACE);
}