Skip to content

Commit a206a04

Browse files
TreeHunter9AlexPeshkoffArtyom Ivanov
authored
Fixed #8444: GBAK: GDS error batch_big_seg2 when restoring a table with many BLOBs, thanks to Vlad (#8574)
Co-authored-by: Alexander Peshkov <[email protected]> Co-authored-by: Artyom Ivanov <[email protected]>
1 parent e3aa4ec commit a206a04

File tree

6 files changed

+69
-6
lines changed

6 files changed

+69
-6
lines changed

src/burp/BurpTasks.cpp

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,33 @@ class BurpGblHolder
9292
};
9393

9494

95+
class SimpleGblHolder
96+
{
97+
public:
98+
SimpleGblHolder(BurpGlobals* gbl)
99+
{
100+
m_prev = BurpGlobals::getSpecific();
101+
102+
// Avoid threadDataPriorContext == this, it makes a loop in linked list of contexts
103+
if (m_prev != gbl)
104+
BurpGlobals::putSpecific(gbl);
105+
}
106+
107+
~SimpleGblHolder()
108+
{
109+
BurpGlobals* gbl = BurpGlobals::getSpecific();
110+
111+
if (m_prev != gbl)
112+
BurpGlobals::restoreSpecific();
113+
114+
fb_assert(m_prev == BurpGlobals::getSpecific());
115+
}
116+
117+
private:
118+
BurpGlobals* m_prev;
119+
};
120+
121+
95122
/// class BackupRelationTask
96123

97124
BackupRelationTask::BackupRelationTask(BurpGlobals* tdgbl) : BurpTask(tdgbl),
@@ -186,8 +213,16 @@ bool BackupRelationTask::handler(WorkItem& _item)
186213
m_error = true;
187214
stopItems();
188215
}
189-
catch (const Exception&) // could be different handlers for LongJump and Exception
216+
catch (const Exception& ex) // could be different handlers for LongJump and Exception
190217
{
218+
FbLocalStatus st;
219+
ex.stuffException(&st);
220+
221+
{ // scope
222+
SimpleGblHolder gbl(m_masterGbl);
223+
BURP_print_status(true, &st);
224+
}
225+
191226
m_stop = true;
192227
m_error = true;
193228
stopItems();
@@ -701,8 +736,16 @@ bool RestoreRelationTask::handler(WorkItem& _item)
701736
m_dirtyCond.notifyAll();
702737
m_cleanCond.notifyAll();
703738
}
704-
catch (const Exception&) // could be different handlers for LongJump and Exception
739+
catch (const Exception& ex) // could be different handlers for LongJump and Exception
705740
{
741+
FbLocalStatus st;
742+
ex.stuffException(&st);
743+
744+
{ // scope
745+
SimpleGblHolder gbl(m_masterGbl);
746+
BURP_print_status(true, &st);
747+
}
748+
706749
m_stop = true;
707750
m_error = true;
708751
m_dirtyCond.notifyAll();

src/burp/BurpTasks.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ class WriteRelationMeta
149149
bool m_batchMode;
150150
bool m_batchOk;
151151
ULONG m_inMsgLen;
152+
ULONG m_blobCount;
152153

153154
// batch mode
154155
Firebird::string m_sqlStatement;

src/burp/restore.epp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
#include "../common/dsc_proto.h"
6464
#include "../common/ThreadStart.h"
6565
#include "../common/msg_encode.h"
66+
#include "../common/classes/BatchCompletionState.h"
6667

6768
using MsgFormat::SafeArg;
6869
using namespace Firebird;
@@ -2311,7 +2312,6 @@ void get_blob(BurpGlobals* tdgbl, IBatch* batch, const burp_fld* fields, UCHAR*
23112312
}
23122313

23132314
// Eat up blob segments
2314-
23152315
for (; segments > 0; --segments)
23162316
{
23172317
USHORT length = get(tdgbl);
@@ -11672,6 +11672,7 @@ void WriteRelationMeta::clear()
1167211672
m_blr.clear();
1167311673
m_inMgsNum = 0;
1167411674
m_inMsgLen = 0;
11675+
m_blobCount = 0;
1167511676
}
1167611677

1167711678
void WriteRelationMeta::setRelation(BurpGlobals* tdgbl, const burp_rel* relation)
@@ -11793,11 +11794,17 @@ IBatch* WriteRelationMeta::createBatch(BurpGlobals* tdgbl, IAttachment* att)
1179311794
// correct batchStep if necessary
1179411795
unsigned msgSize = m_batchMeta->getAlignedLength(&tdgbl->throwStatus);
1179511796
if (msgSize * m_batchStep > bufSize)
11797+
{
1179611798
m_batchStep = bufSize / msgSize;
11799+
m_blobCount++; // looks like we are under low ram conditions on server...
11800+
// make batch step even smaller if we have some blobs
11801+
}
11802+
if (m_blobCount)
11803+
m_batchStep /= m_blobCount;
1179711804

1179811805
// determine maximum blob size for inline transfer
1179911806
m_batchInlineBlobLimit = bufSize / m_batchStep;
11800-
// take into an account: blob alignment header size
11807+
// take into an account: blob alignment header size
1180111808
m_batchInlineBlobLimit -= ((blAlign - 1) + blHdr);
1180211809
}
1180311810
fb_assert(m_batchInlineBlobLimit);
@@ -11877,6 +11884,8 @@ bool WriteRelationMeta::prepareBatch(BurpGlobals* tdgbl)
1187711884
offset = FB_ALIGN(offset, alignment);
1187811885
field->fld_offset = offset;
1187911886
offset += field->fld_total_len = desc.dsc_length;
11887+
if (desc.isBlob())
11888+
++m_blobCount;
1188011889

1188111890
SLONG sqlLength, sqlSubType, sqlScale, sqlType;
1188211891
desc.getSqlInfo(&sqlLength, &sqlSubType, &sqlScale, &sqlType);

src/common/classes/BatchCompletionState.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include "../common/classes/array.h"
2727
#include "../common/utils_proto.h"
2828

29+
#define DEB_BATCH(x)
30+
2931
namespace Firebird {
3032

3133
class Transliterate

src/dsql/DsqlBatch.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@
2929
#include "../common/classes/vector.h"
3030
#include "../common/classes/GenericMap.h"
3131

32-
#define DEB_BATCH(x)
33-
3432

3533
namespace Firebird {
3634

src/remote/client/interface.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9343,6 +9343,16 @@ static void receive_packet_noqueue(rem_port* port, PACKET* packet)
93439343
stmt_id = p->packet.p_sqlfree.p_sqlfree_statement;
93449344
bFreeStmt = (p->packet.p_sqlfree.p_sqlfree_option == DSQL_drop);
93459345
break;
9346+
9347+
case op_batch_blob_stream:
9348+
stmt_id = p->packet.p_batch_blob.p_batch_statement;
9349+
bCheckResponse = true;
9350+
break;
9351+
9352+
case op_batch_regblob:
9353+
stmt_id = p->packet.p_batch_regblob.p_batch_statement;
9354+
bCheckResponse = true;
9355+
break;
93469356
}
93479357

93489358
receive_packet_with_callback(port, &p->packet);

0 commit comments

Comments
 (0)