Skip to content

Commit babd741

Browse files
authored
Add AUTO RELEASE TEMP BLOBID transaction option (#8323)
* Add AUTO RELEASE TEMP BLOBID transaction option It 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. * Place tokens in the correct sections * Avoid repeated attempts to start a transaction with options that are not supported by the target server * Correct AUTO RELEASE TEMP BLOBID description * Check bad_tpb_form error for more reliable detection of unsupported transaction options * Do not use unsupported options for transactions of parallel workers performing RestoreRelationTask
1 parent 933ac7b commit babd741

File tree

22 files changed

+128
-38
lines changed

22 files changed

+128
-38
lines changed

doc/sql.extensions/README.set_transaction.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ commit fails. This option is mostly used by gfix.
2727
LOCK TIMEOUT nonneg_short_integer: it's the time (measured in seconds) that a
2828
transaction waits for a lock in a record before giving up and reporting an error.
2929

30+
AUTO RELEASE TEMP BLOBID: makes the transaction release a temporary ID of a user
31+
BLOB just after its materialization. It's useful for massive insertions of records
32+
with user-defined BLOBs because it eliminates the memory overhead caused by creating
33+
and keeping temporary IDs until the transaction ends. This option should be used
34+
with care and only if there is no need to access a materialized BLOB via a temporary
35+
ID obtained after its creation. It's used during the database restore.
36+
3037

3138
Author:
3239
Claudio Valderrama C.

src/burp/BurpTasks.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,8 @@ void RestoreRelationTask::initItem(BurpGlobals* tdgbl, Item& item)
869869
tdgbl->verboseInterval = m_masterGbl->verboseInterval;
870870
tdgbl->RESTORE_format = m_masterGbl->RESTORE_format;
871871
tdgbl->runtimeODS = m_masterGbl->runtimeODS;
872+
tdgbl->gbl_use_no_auto_undo = m_masterGbl->gbl_use_no_auto_undo;
873+
tdgbl->gbl_use_auto_release_temp_blobid = m_masterGbl->gbl_use_auto_release_temp_blobid;
872874

873875
if (item.m_ownAttach)
874876
{
@@ -893,11 +895,16 @@ void RestoreRelationTask::initItem(BurpGlobals* tdgbl, Item& item)
893895
if (status->getState() & IStatus::STATE_ERRORS)
894896
BURP_abort(&status);
895897

896-
// SET TRANSACTION NO_AUTO_UNDO, see at the end of get_data()
898+
// SET TRANSACTION NO_AUTO_UNDO AUTO_RELEASE_TEMP_BLOBID, see at the end of get_data()
897899

898900
ClumpletWriter tpb(ClumpletReader::Tpb, 128, isc_tpb_version3);
899901
tpb.insertTag(isc_tpb_concurrency);
900-
tpb.insertTag(isc_tpb_no_auto_undo);
902+
903+
if (tdgbl->gbl_use_no_auto_undo)
904+
tpb.insertTag(isc_tpb_no_auto_undo);
905+
906+
if (tdgbl->gbl_use_auto_release_temp_blobid)
907+
tpb.insertTag(isc_tpb_auto_release_temp_blobid);
901908

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

src/burp/burp.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,6 +1227,9 @@ class BurpGlobals : public Firebird::ThreadData, public GblPool
12271227
bool gbl_stat_header; // true, if stats header was printed
12281228
bool gbl_stat_done; // true, if main process is done, stop to collect db-level stats
12291229
SINT64 gbl_stats[LAST_COUNTER];
1230+
1231+
bool gbl_use_no_auto_undo = true;
1232+
bool gbl_use_auto_release_temp_blobid = true;
12301233
};
12311234

12321235
// CVC: This aux routine declared here to not force inclusion of burp.h with burp_proto.h

src/burp/restore.epp

Lines changed: 64 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ void update_ownership(BurpGlobals* tdgbl);
183183
void update_view_dbkey_lengths(BurpGlobals* tdgbl);
184184
void fix_missing_privileges(BurpGlobals* tdgbl);
185185
void fix_system_generators(BurpGlobals* tdgbl);
186+
void set_transaction(BurpGlobals* tdgbl);
186187
void general_on_error();
187188
#ifdef DEBUG
188189
UCHAR debug_on = 0; // able to turn this on in the debugger
@@ -745,9 +746,7 @@ void add_files(BurpGlobals* tdgbl, const char* file_name)
745746
END_ERROR;
746747
END_ERROR;
747748

748-
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
749-
if (gds_status->hasData())
750-
EXEC SQL SET TRANSACTION;
749+
set_transaction(tdgbl);
751750
}
752751
}
753752

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

3169-
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
3170-
if (gds_status->hasData())
3171-
EXEC SQL SET TRANSACTION;
3168+
set_transaction(tdgbl);
31723169
}
31733170

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

7780-
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
7781-
if (gds_status->hasData())
7782-
EXEC SQL SET TRANSACTION;
7777+
set_transaction(tdgbl);
77837778
}
77847779

77857780
// Pick up relation attributes
@@ -8004,9 +7999,8 @@ bool get_relation(BurpGlobals* tdgbl, Coordinator* coord, RestoreRelationTask* t
80047999
general_on_error ();
80058000
END_ERROR;
80068001
END_ERROR;
8007-
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
8008-
if (gds_status->hasData())
8009-
EXEC SQL SET TRANSACTION;
8002+
8003+
set_transaction(tdgbl);
80108004
}
80118005
return true;
80128006

@@ -8041,9 +8035,7 @@ bool get_relation(BurpGlobals* tdgbl, Coordinator* coord, RestoreRelationTask* t
80418035
general_on_error ();
80428036
END_ERROR;
80438037

8044-
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
8045-
if (gds_status->hasData())
8046-
EXEC SQL SET TRANSACTION;
8038+
set_transaction(tdgbl);
80478039

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

@@ -9085,9 +9077,8 @@ bool get_trigger_old (BurpGlobals* tdgbl, burp_rel* relation)
90859077
general_on_error ();
90869078
END_ERROR;
90879079
END_ERROR;
9088-
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
9089-
if (gds_status->hasData())
9090-
EXEC SQL SET TRANSACTION;
9080+
9081+
set_transaction(tdgbl);
90919082
}
90929083

90939084
return true;
@@ -9441,9 +9432,8 @@ bool get_trigger(BurpGlobals* tdgbl)
94419432
general_on_error ();
94429433
END_ERROR;
94439434
END_ERROR;
9444-
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
9445-
if (gds_status->hasData())
9446-
EXEC SQL SET TRANSACTION;
9435+
9436+
set_transaction(tdgbl);
94479437
}
94489438

94499439
return true;
@@ -9537,9 +9527,8 @@ bool get_trigger_message(BurpGlobals* tdgbl)
95379527
general_on_error ();
95389528
END_ERROR;
95399529
END_ERROR;
9540-
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
9541-
if (gds_status->hasData())
9542-
EXEC SQL SET TRANSACTION;
9530+
9531+
set_transaction(tdgbl);
95439532
}
95449533

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

1039210381
create_database(tdgbl, provider, database_name);
1039310382

10394-
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
10395-
if (gds_status->hasData())
10396-
EXEC SQL SET TRANSACTION;
10383+
set_transaction(tdgbl);
1039710384

1039810385
// For V4.0, start a read commited transaction. This will be used
1039910386
// to create blobs for global fields and update the record in the
@@ -10751,9 +10738,8 @@ bool restore(BurpGlobals* tdgbl, Firebird::IProvider* provider, const TEXT* file
1075110738
ON_ERROR
1075210739
general_on_error ();
1075310740
END_ERROR;
10754-
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
10755-
if (gds_status->hasData())
10756-
EXEC SQL SET TRANSACTION;
10741+
10742+
set_transaction(tdgbl);
1075710743
flag = false;
1075810744
}
1075910745
if (!get_relation_data(tdgbl, &coord, &task))
@@ -10875,9 +10861,8 @@ bool restore(BurpGlobals* tdgbl, Firebird::IProvider* provider, const TEXT* file
1087510861
ON_ERROR
1087610862
general_on_error ();
1087710863
END_ERROR;
10878-
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
10879-
if (gds_status->hasData())
10880-
EXEC SQL SET TRANSACTION;
10864+
10865+
set_transaction(tdgbl);
1088110866
}
1088210867

1088310868
// put validation clauses for global fields
@@ -11625,6 +11610,52 @@ void fix_system_generators(BurpGlobals* tdgbl)
1162511610
}
1162611611
}
1162711612

11613+
void set_transaction(BurpGlobals* tdgbl)
11614+
{
11615+
/**************************************
11616+
*
11617+
* s e t _ t r a n s a c t i o n
11618+
*
11619+
**************************************
11620+
*
11621+
* Functional description
11622+
* Start a transaction with options
11623+
* supported by the target server.
11624+
*
11625+
**************************************/
11626+
11627+
while (true)
11628+
{
11629+
if (tdgbl->gbl_use_auto_release_temp_blobid && tdgbl->gbl_use_no_auto_undo)
11630+
{
11631+
EXEC SQL SET TRANSACTION NO_AUTO_UNDO AUTO_RELEASE_TEMP_BLOBID;
11632+
if (gds_status->hasData() && fb_utils::containsErrorCode(gds_status->getErrors(), isc_bad_tpb_form))
11633+
{
11634+
// First try to disable AUTO_RELEASE_TEMP_BLOBID transaction
11635+
// option because it was implemented later than NO_AUTO_UNDO
11636+
tdgbl->gbl_use_auto_release_temp_blobid = false;
11637+
continue;
11638+
}
11639+
}
11640+
else if (tdgbl->gbl_use_no_auto_undo)
11641+
{
11642+
EXEC SQL SET TRANSACTION NO_AUTO_UNDO;
11643+
if (gds_status->hasData() && fb_utils::containsErrorCode(gds_status->getErrors(), isc_bad_tpb_form))
11644+
{
11645+
tdgbl->gbl_use_no_auto_undo = false;
11646+
continue;
11647+
}
11648+
}
11649+
else
11650+
{
11651+
fb_assert(!tdgbl->gbl_use_auto_release_temp_blobid);
11652+
EXEC SQL SET TRANSACTION;
11653+
}
11654+
11655+
break;
11656+
}
11657+
}
11658+
1162811659
} // namespace
1162911660

1163011661
namespace Burp

src/common/ParserTokens.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ PARSER_TOKEN(TOK_BINARY, "BINARY", false)
9797
PARSER_TOKEN(TOK_BIND, "BIND", true)
9898
PARSER_TOKEN(TOK_BIT_LENGTH, "BIT_LENGTH", false)
9999
PARSER_TOKEN(TOK_BLOB, "BLOB", false)
100+
PARSER_TOKEN(TOK_BLOBID, "BLOBID", true)
100101
PARSER_TOKEN(TOK_BLOB_APPEND, "BLOB_APPEND", true)
101102
PARSER_TOKEN(TOK_BLOCK, "BLOCK", true)
102103
PARSER_TOKEN(TOK_BODY, "BODY", true)
@@ -491,6 +492,7 @@ PARSER_TOKEN(TOK_TAGS, "TAGS", true)
491492
PARSER_TOKEN(TOK_TAN, "TAN", true)
492493
PARSER_TOKEN(TOK_TANH, "TANH", true)
493494
PARSER_TOKEN(TOK_TARGET, "TARGET", true)
495+
PARSER_TOKEN(TOK_TEMP, "TEMP", true)
494496
PARSER_TOKEN(TOK_TEMPORARY, "TEMPORARY", true)
495497
PARSER_TOKEN(TOK_THEN, "THEN", false)
496498
PARSER_TOKEN(TOK_TIES, "TIES", true)

src/dsql/StmtNodes.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9720,6 +9720,9 @@ SetTransactionNode* SetTransactionNode::dsqlPass(DsqlCompilerScratch* dsqlScratc
97209720
if (autoCommit.isAssigned())
97219721
dsqlScratch->appendUChar(isc_tpb_autocommit);
97229722

9723+
if (autoReleaseTempBlobID.isAssigned())
9724+
dsqlScratch->appendUChar(isc_tpb_auto_release_temp_blobid);
9725+
97239726
if (lockTimeout.has_value())
97249727
{
97259728
dsqlScratch->appendUChar(isc_tpb_lock_timeout);

src/dsql/StmtNodes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,6 +1607,7 @@ class SetTransactionNode : public TransactionNode
16071607
NODE_PRINT(printer, ignoreLimbo);
16081608
NODE_PRINT(printer, restartRequests);
16091609
NODE_PRINT(printer, autoCommit);
1610+
NODE_PRINT(printer, autoReleaseTempBlobID);
16101611
NODE_PRINT(printer, lockTimeout);
16111612
//// FIXME-PRINT: NODE_PRINT(printer, reserveList);
16121613
NODE_PRINT(printer, tpb);
@@ -1633,6 +1634,7 @@ class SetTransactionNode : public TransactionNode
16331634
Firebird::TriState ignoreLimbo;
16341635
Firebird::TriState restartRequests;
16351636
Firebird::TriState autoCommit;
1637+
Firebird::TriState autoReleaseTempBlobID;
16361638
};
16371639

16381640

src/dsql/parse.y

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,10 +343,12 @@ using namespace Firebird;
343343

344344
%token <metaNamePtr> ACTION
345345
%token <metaNamePtr> ADMIN
346+
%token <metaNamePtr> BLOBID
346347
%token <metaNamePtr> CASCADE
347348
%token <metaNamePtr> FREE_IT // ISC SQL extension
348349
%token <metaNamePtr> RESTRICT
349350
%token <metaNamePtr> ROLE
351+
%token <metaNamePtr> TEMP
350352

351353
// New tokens added v6.0
352354

@@ -5938,6 +5940,8 @@ tran_option($setTransactionNode)
59385940
{ setClause($setTransactionNode->restartRequests, "RESTART REQUESTS", true); }
59395941
| AUTO COMMIT
59405942
{ setClause($setTransactionNode->autoCommit, "AUTO COMMIT", true); }
5943+
| AUTO RELEASE TEMP BLOBID
5944+
{ setClause($setTransactionNode->autoReleaseTempBlobID, "AUTO RELEASE TEMP BLOBID", true); }
59415945
// timeout
59425946
| LOCK TIMEOUT nonneg_short_integer
59435947
{ setClause($setTransactionNode->lockTimeout, "LOCK TIMEOUT", (USHORT) $3); }
@@ -9749,10 +9753,12 @@ non_reserved_word
97499753
// added in FB 4.0.2
97509754
| BLOB_APPEND
97519755
// added in FB 5.0
9756+
| BLOBID
97529757
| LOCKED
97539758
| OPTIMIZE
97549759
| QUARTER
97559760
| TARGET
9761+
| TEMP
97569762
| TIMEZONE_NAME
97579763
| UNICODE_CHAR
97589764
| UNICODE_VAL

src/gpre/cmp.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,8 @@ void CMP_t_start( gpre_tra* trans)
408408
*text++ = isc_tpb_autocommit;
409409
if (trans->tra_flags & TRA_no_auto_undo)
410410
*text++ = isc_tpb_no_auto_undo;
411+
if (trans->tra_flags & TRA_auto_release_temp_blobid)
412+
*text++ = isc_tpb_auto_release_temp_blobid;
411413
*text = 0;
412414
const USHORT tpb_len = text - tpb_buffer;
413415

src/gpre/gpre.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1414,7 +1414,8 @@ enum tra_flags_vals {
14141414
TRA_read_committed = 32,
14151415
TRA_autocommit = 64,
14161416
TRA_rec_version = 128,
1417-
TRA_no_auto_undo = 256
1417+
TRA_no_auto_undo = 256,
1418+
TRA_auto_release_temp_blobid = 512
14181419
};
14191420

14201421
const int MAX_TRA_OPTIONS = 8;

0 commit comments

Comments
 (0)