From 97b4b8c2c262ab430fbb8c2db397a191b3f3157a Mon Sep 17 00:00:00 2001 From: alexpeshkoff Date: Thu, 28 Feb 2013 16:23:56 +0000 Subject: [PATCH] Postfix for CORE-3908: Engine leaks memory and crashes when lot of autonomous transactions have been started and finished --- src/jrd/blb.cpp | 28 +++++++++++++++++++++++----- src/jrd/exe.cpp | 1 + src/jrd/tra.cpp | 17 +++++++++++++++++ src/jrd/tra.h | 11 ++++------- 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/jrd/blb.cpp b/src/jrd/blb.cpp index 295d20f4cb..9e7fa8e38c 100644 --- a/src/jrd/blb.cpp +++ b/src/jrd/blb.cpp @@ -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(&from_charset), // safe - alignment not changed reinterpret_cast(&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(control->ctl_internal[1]); + jrd_tra* transaction = reinterpret_cast(control->ctl_internal[1]); + if (transaction) + { + transaction = transaction->getOuter(); + } bid* blob_id = reinterpret_cast(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); diff --git a/src/jrd/exe.cpp b/src/jrd/exe.cpp index 4d49abe87d..2491db93d3 100644 --- a/src/jrd/exe.cpp +++ b/src/jrd/exe.cpp @@ -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 diff --git a/src/jrd/tra.cpp b/src/jrd/tra.cpp index 25aeeb29f3..744a24e727 100644 --- a/src/jrd/tra.cpp +++ b/src/jrd/tra.cpp @@ -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) diff --git a/src/jrd/tra.h b/src/jrd/tra.h index 40f37eb268..c49f0e7261 100644 --- a/src/jrd/tra.h +++ b/src/jrd/tra.h @@ -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); }