Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions doc/sql.extensions/README.set_transaction.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ commit fails. This option is mostly used by gfix.
LOCK TIMEOUT nonneg_short_integer: it's the time (measured in seconds) that a
transaction waits for a lock in a record before giving up and reporting an error.

AUTO RELEASE TEMP BLOBID: makes the transaction release temporary ID of user BLOB
just after its materialization. It's useful for massive insertions of records with
user-defined BLOBs because it eliminates the memory overhead caused by creating and
keeping temporary IDs until the transaction ends. This option is used during the
database restore.


Author:
Claudio Valderrama C.
Expand Down
5 changes: 4 additions & 1 deletion src/burp/BurpTasks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,8 @@ void RestoreRelationTask::initItem(BurpGlobals* tdgbl, Item& item)
tdgbl->verboseInterval = m_masterGbl->verboseInterval;
tdgbl->RESTORE_format = m_masterGbl->RESTORE_format;
tdgbl->runtimeODS = m_masterGbl->runtimeODS;
tdgbl->gbl_use_no_auto_undo = m_masterGbl->gbl_use_no_auto_undo;
tdgbl->gbl_use_auto_release_temp_blobid = m_masterGbl->gbl_use_auto_release_temp_blobid;

if (item.m_ownAttach)
{
Expand All @@ -893,11 +895,12 @@ void RestoreRelationTask::initItem(BurpGlobals* tdgbl, Item& item)
if (status->getState() & IStatus::STATE_ERRORS)
BURP_abort(&status);

// SET TRANSACTION NO_AUTO_UNDO, see at the end of get_data()
// SET TRANSACTION NO_AUTO_UNDO AUTO_RELEASE_TEMP_BLOBID, see at the end of get_data()

ClumpletWriter tpb(ClumpletReader::Tpb, 128, isc_tpb_version3);
tpb.insertTag(isc_tpb_concurrency);
tpb.insertTag(isc_tpb_no_auto_undo);
tpb.insertTag(isc_tpb_auto_release_temp_blobid);

item.m_tra = item.m_att->startTransaction(&status, tpb.getBufferLength(), tpb.getBuffer());

Expand Down
3 changes: 3 additions & 0 deletions src/burp/burp.h
Original file line number Diff line number Diff line change
Expand Up @@ -1227,6 +1227,9 @@ class BurpGlobals : public Firebird::ThreadData, public GblPool
bool gbl_stat_header; // true, if stats header was printed
bool gbl_stat_done; // true, if main process is done, stop to collect db-level stats
SINT64 gbl_stats[LAST_COUNTER];

bool gbl_use_no_auto_undo = true;
bool gbl_use_auto_release_temp_blobid = true;
};

// CVC: This aux routine declared here to not force inclusion of burp.h with burp_proto.h
Expand Down
97 changes: 64 additions & 33 deletions src/burp/restore.epp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ void update_ownership(BurpGlobals* tdgbl);
void update_view_dbkey_lengths(BurpGlobals* tdgbl);
void fix_missing_privileges(BurpGlobals* tdgbl);
void fix_system_generators(BurpGlobals* tdgbl);
void set_transaction(BurpGlobals* tdgbl);
void general_on_error();
#ifdef DEBUG
UCHAR debug_on = 0; // able to turn this on in the debugger
Expand Down Expand Up @@ -745,9 +746,7 @@ void add_files(BurpGlobals* tdgbl, const char* file_name)
END_ERROR;
END_ERROR;

EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
if (gds_status->hasData())
EXEC SQL SET TRANSACTION;
set_transaction(tdgbl);
}
}

Expand Down Expand Up @@ -3166,9 +3165,7 @@ static void commit_relation_data(BurpGlobals* tdgbl, burp_rel* relation)
} // end of while
END_ERROR;

EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
if (gds_status->hasData())
EXEC SQL SET TRANSACTION;
set_transaction(tdgbl);
}

// We have a corrupt backup, save the restore process from becoming useless.
Expand Down Expand Up @@ -7777,9 +7774,7 @@ bool get_relation(BurpGlobals* tdgbl, Coordinator* coord, RestoreRelationTask* t
general_on_error ();
END_ERROR;

EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
if (gds_status->hasData())
EXEC SQL SET TRANSACTION;
set_transaction(tdgbl);
}

// Pick up relation attributes
Expand Down Expand Up @@ -8004,9 +7999,8 @@ bool get_relation(BurpGlobals* tdgbl, Coordinator* coord, RestoreRelationTask* t
general_on_error ();
END_ERROR;
END_ERROR;
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
if (gds_status->hasData())
EXEC SQL SET TRANSACTION;

set_transaction(tdgbl);
}
return true;

Expand Down Expand Up @@ -8041,9 +8035,7 @@ bool get_relation(BurpGlobals* tdgbl, Coordinator* coord, RestoreRelationTask* t
general_on_error ();
END_ERROR;

EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
if (gds_status->hasData())
EXEC SQL SET TRANSACTION;
set_transaction(tdgbl);

// If we're only doing meta-data, ignore data records

Expand Down Expand Up @@ -9085,9 +9077,8 @@ bool get_trigger_old (BurpGlobals* tdgbl, burp_rel* relation)
general_on_error ();
END_ERROR;
END_ERROR;
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
if (gds_status->hasData())
EXEC SQL SET TRANSACTION;

set_transaction(tdgbl);
}

return true;
Expand Down Expand Up @@ -9441,9 +9432,8 @@ bool get_trigger(BurpGlobals* tdgbl)
general_on_error ();
END_ERROR;
END_ERROR;
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
if (gds_status->hasData())
EXEC SQL SET TRANSACTION;

set_transaction(tdgbl);
}

return true;
Expand Down Expand Up @@ -9537,9 +9527,8 @@ bool get_trigger_message(BurpGlobals* tdgbl)
general_on_error ();
END_ERROR;
END_ERROR;
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
if (gds_status->hasData())
EXEC SQL SET TRANSACTION;

set_transaction(tdgbl);
}

return true;
Expand Down Expand Up @@ -10391,9 +10380,7 @@ bool restore(BurpGlobals* tdgbl, Firebird::IProvider* provider, const TEXT* file

create_database(tdgbl, provider, database_name);

EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
if (gds_status->hasData())
EXEC SQL SET TRANSACTION;
set_transaction(tdgbl);

// For V4.0, start a read commited transaction. This will be used
// to create blobs for global fields and update the record in the
Expand Down Expand Up @@ -10751,9 +10738,8 @@ bool restore(BurpGlobals* tdgbl, Firebird::IProvider* provider, const TEXT* file
ON_ERROR
general_on_error ();
END_ERROR;
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
if (gds_status->hasData())
EXEC SQL SET TRANSACTION;

set_transaction(tdgbl);
flag = false;
}
if (!get_relation_data(tdgbl, &coord, &task))
Expand Down Expand Up @@ -10875,9 +10861,8 @@ bool restore(BurpGlobals* tdgbl, Firebird::IProvider* provider, const TEXT* file
ON_ERROR
general_on_error ();
END_ERROR;
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
if (gds_status->hasData())
EXEC SQL SET TRANSACTION;

set_transaction(tdgbl);
}

// put validation clauses for global fields
Expand Down Expand Up @@ -11625,6 +11610,52 @@ void fix_system_generators(BurpGlobals* tdgbl)
}
}

void set_transaction(BurpGlobals* tdgbl)
{
/**************************************
*
* s e t _ t r a n s a c t i o n
*
**************************************
*
* Functional description
* Start a transaction with options
* supported by the target server.
*
**************************************/

while (true)
{
if (tdgbl->gbl_use_auto_release_temp_blobid && tdgbl->gbl_use_no_auto_undo)
{
EXEC SQL SET TRANSACTION NO_AUTO_UNDO AUTO_RELEASE_TEMP_BLOBID;
if (gds_status->hasData())
{
// First try to disable AUTO_RELEASE_TEMP_BLOBID transaction
// option because it was implemented later than NO_AUTO_UNDO
tdgbl->gbl_use_auto_release_temp_blobid = false;
continue;
}
}
else if (tdgbl->gbl_use_no_auto_undo)
{
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
if (gds_status->hasData())
{
tdgbl->gbl_use_no_auto_undo = false;
continue;
}
}
else
{
fb_assert(!tdgbl->gbl_use_auto_release_temp_blobid);
EXEC SQL SET TRANSACTION;
}

break;
}
}

} // namespace

namespace Burp
Expand Down
2 changes: 2 additions & 0 deletions src/common/ParserTokens.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ PARSER_TOKEN(TOK_BINARY, "BINARY", false)
PARSER_TOKEN(TOK_BIND, "BIND", true)
PARSER_TOKEN(TOK_BIT_LENGTH, "BIT_LENGTH", false)
PARSER_TOKEN(TOK_BLOB, "BLOB", false)
PARSER_TOKEN(TOK_BLOBID, "BLOBID", true)
PARSER_TOKEN(TOK_BLOB_APPEND, "BLOB_APPEND", true)
PARSER_TOKEN(TOK_BLOCK, "BLOCK", true)
PARSER_TOKEN(TOK_BODY, "BODY", true)
Expand Down Expand Up @@ -491,6 +492,7 @@ PARSER_TOKEN(TOK_TAGS, "TAGS", true)
PARSER_TOKEN(TOK_TAN, "TAN", true)
PARSER_TOKEN(TOK_TANH, "TANH", true)
PARSER_TOKEN(TOK_TARGET, "TARGET", true)
PARSER_TOKEN(TOK_TEMP, "TEMP", true)
PARSER_TOKEN(TOK_TEMPORARY, "TEMPORARY", true)
PARSER_TOKEN(TOK_THEN, "THEN", false)
PARSER_TOKEN(TOK_TIES, "TIES", true)
Expand Down
3 changes: 3 additions & 0 deletions src/dsql/StmtNodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9720,6 +9720,9 @@ SetTransactionNode* SetTransactionNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
if (autoCommit.isAssigned())
dsqlScratch->appendUChar(isc_tpb_autocommit);

if (autoReleaseTempBlobID.isAssigned())
dsqlScratch->appendUChar(isc_tpb_auto_release_temp_blobid);

if (lockTimeout.has_value())
{
dsqlScratch->appendUChar(isc_tpb_lock_timeout);
Expand Down
2 changes: 2 additions & 0 deletions src/dsql/StmtNodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1607,6 +1607,7 @@ class SetTransactionNode : public TransactionNode
NODE_PRINT(printer, ignoreLimbo);
NODE_PRINT(printer, restartRequests);
NODE_PRINT(printer, autoCommit);
NODE_PRINT(printer, autoReleaseTempBlobID);
NODE_PRINT(printer, lockTimeout);
//// FIXME-PRINT: NODE_PRINT(printer, reserveList);
NODE_PRINT(printer, tpb);
Expand All @@ -1633,6 +1634,7 @@ class SetTransactionNode : public TransactionNode
Firebird::TriState ignoreLimbo;
Firebird::TriState restartRequests;
Firebird::TriState autoCommit;
Firebird::TriState autoReleaseTempBlobID;
};


Expand Down
6 changes: 6 additions & 0 deletions src/dsql/parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -343,10 +343,12 @@ using namespace Firebird;

%token <metaNamePtr> ACTION
%token <metaNamePtr> ADMIN
%token <metaNamePtr> BLOBID
%token <metaNamePtr> CASCADE
%token <metaNamePtr> FREE_IT // ISC SQL extension
%token <metaNamePtr> RESTRICT
%token <metaNamePtr> ROLE
%token <metaNamePtr> TEMP

// New tokens added v6.0

Expand Down Expand Up @@ -5938,6 +5940,8 @@ tran_option($setTransactionNode)
{ setClause($setTransactionNode->restartRequests, "RESTART REQUESTS", true); }
| AUTO COMMIT
{ setClause($setTransactionNode->autoCommit, "AUTO COMMIT", true); }
| AUTO RELEASE TEMP BLOBID
{ setClause($setTransactionNode->autoReleaseTempBlobID, "AUTO RELEASE TEMP BLOBID", true); }
// timeout
| LOCK TIMEOUT nonneg_short_integer
{ setClause($setTransactionNode->lockTimeout, "LOCK TIMEOUT", (USHORT) $3); }
Expand Down Expand Up @@ -9749,10 +9753,12 @@ non_reserved_word
// added in FB 4.0.2
| BLOB_APPEND
// added in FB 5.0
| BLOBID
| LOCKED
| OPTIMIZE
| QUARTER
| TARGET
| TEMP
| TIMEZONE_NAME
| UNICODE_CHAR
| UNICODE_VAL
Expand Down
2 changes: 2 additions & 0 deletions src/gpre/cmp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,8 @@ void CMP_t_start( gpre_tra* trans)
*text++ = isc_tpb_autocommit;
if (trans->tra_flags & TRA_no_auto_undo)
*text++ = isc_tpb_no_auto_undo;
if (trans->tra_flags & TRA_auto_release_temp_blobid)
*text++ = isc_tpb_auto_release_temp_blobid;
*text = 0;
const USHORT tpb_len = text - tpb_buffer;

Expand Down
3 changes: 2 additions & 1 deletion src/gpre/gpre.h
Original file line number Diff line number Diff line change
Expand Up @@ -1414,7 +1414,8 @@ enum tra_flags_vals {
TRA_read_committed = 32,
TRA_autocommit = 64,
TRA_rec_version = 128,
TRA_no_auto_undo = 256
TRA_no_auto_undo = 256,
TRA_auto_release_temp_blobid = 512
};

const int MAX_TRA_OPTIONS = 8;
Expand Down
1 change: 1 addition & 0 deletions src/gpre/hsh.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
{"AT", KW_AT},
{"AUTO", KW_AUTO},
{"AUTOCOMMIT", KW_AUTOCOMMIT},
{"AUTO_RELEASE_TEMP_BLOBID", KW_AUTO_RELEASE_TEMP_BLOBID},
{"AVERAGE", KW_AVERAGE},
{"AVG", KW_AVERAGE},
{"\\", KW_BACK_SLASH},
Expand Down
6 changes: 6 additions & 0 deletions src/gpre/sql.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4424,6 +4424,12 @@ static act* act_set_transaction()
continue;
}

if (MSC_match(KW_AUTO_RELEASE_TEMP_BLOBID))
{
trans->tra_flags |= TRA_auto_release_temp_blobid;
continue;
}

break;
}

Expand Down
1 change: 1 addition & 0 deletions src/gpre/words.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ enum kwwords_t {
KW_ASTERISK,
KW_AUTO,
KW_AUTOCOMMIT,
KW_AUTO_RELEASE_TEMP_BLOBID,
KW_AVERAGE,
KW_BASE_NAME,
KW_BETWEEN,
Expand Down
1 change: 1 addition & 0 deletions src/include/firebird/impl/consts_pub.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@
#define isc_tpb_lock_timeout 21
#define isc_tpb_read_consistency 22
#define isc_tpb_at_snapshot_number 23
#define isc_tpb_auto_release_temp_blobid 24


/************************/
Expand Down
1 change: 1 addition & 0 deletions src/include/gen/Firebird.pas
Original file line number Diff line number Diff line change
Expand Up @@ -4111,6 +4111,7 @@ IProfilerStatsImpl = class(IProfilerStats)
isc_tpb_lock_timeout = byte(21);
isc_tpb_read_consistency = byte(22);
isc_tpb_at_snapshot_number = byte(23);
isc_tpb_auto_release_temp_blobid = byte(24);
isc_bpb_version1 = byte(1);
isc_bpb_source_type = byte(1);
isc_bpb_target_type = byte(2);
Expand Down
3 changes: 3 additions & 0 deletions src/jrd/Monitoring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,9 @@ void Monitoring::putTransaction(SnapshotData::DumpRecord& record, const jrd_tra*
// statistics
const int stat_id = fb_utils::genUniqueId();
record.storeGlobalId(f_mon_tra_stat_id, getGlobalId(stat_id));
// auto release temp blobid flag
temp = (transaction->tra_flags & TRA_auto_release_temp_blobid) ? 1 : 0;
record.storeInteger(f_mon_tra_auto_release_temp_blobid, temp);

record.write();

Expand Down
Loading