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

Allow multiple appliers per attachment

This commit is contained in:
Dmitry Yemanov 2021-05-01 18:10:57 +03:00
parent ae643883dc
commit 5c0d3f82f1
6 changed files with 62 additions and 52 deletions

View File

@ -253,6 +253,7 @@ Jrd::Attachment::Attachment(MemoryPool* pool, Database* dbb, JProvider* provider
att_dest_bind(&att_bindings),
att_original_timezone(TimeZoneUtil::getSystemTimeZone()),
att_current_timezone(att_original_timezone),
att_repl_appliers(*pool),
att_utility(UTIL_NONE),
att_procedures(*pool),
att_functions(*pool),

View File

@ -483,7 +483,7 @@ public:
Firebird::RefPtr<Firebird::IReplicatedSession> att_replicator;
Firebird::AutoPtr<Replication::TableMatcher> att_repl_matcher;
Firebird::AutoPtr<Applier> att_repl_applier;
Firebird::Array<Applier*> att_repl_appliers;
enum UtilType { UTIL_NONE, UTIL_GBAK, UTIL_GFIX, UTIL_GSTAT };

View File

@ -41,6 +41,7 @@ class StableAttachmentPart;
class Attachment;
class Service;
class UserId;
class Applier;
// forward declarations
class JStatement;
@ -234,19 +235,25 @@ public:
void close(Firebird::CheckStatusWrapper* status) override;
public:
JReplicator(StableAttachmentPart* sa);
JReplicator(Applier* appl, StableAttachmentPart* sa);
StableAttachmentPart* getAttachment()
{
return sAtt;
}
JReplicator* getHandle() throw()
Applier* getHandle() throw()
{
return this;
return applier;
}
void resetHandle()
{
applier = NULL;
}
private:
Applier* applier;
Firebird::RefPtr<StableAttachmentPart> sAtt;
void freeEngineData(Firebird::CheckStatusWrapper* status);

View File

@ -702,12 +702,12 @@ namespace
validateHandle(tdbb, batch->getAttachment());
}
inline void validateHandle(thread_db* tdbb, JReplicator* const replicator)
inline void validateHandle(thread_db* tdbb, Applier* const applier)
{
if (!replicator)
if (!applier)
status_exception::raise(Arg::Gds(isc_bad_repl_handle));
validateHandle(tdbb, replicator->getAttachment()->getHandle());
validateHandle(tdbb, applier->getAttachment());
}
class AttachmentHolder
@ -5089,13 +5089,11 @@ IReplicator* JAttachment::createReplicator(CheckStatusWrapper* user_status)
try
{
const auto att = tdbb->getAttachment();
const auto applier = Applier::create(tdbb);
if (!att->att_repl_applier)
att->att_repl_applier = Applier::create(tdbb);
jr = FB_NEW JReplicator(getStable());
jr = FB_NEW JReplicator(applier, getStable());
jr->addRef();
applier->setInterfacePtr(jr);
}
catch (const Exception& ex)
{
@ -6196,8 +6194,8 @@ void JBatch::cancel(CheckStatusWrapper* status)
}
JReplicator::JReplicator(StableAttachmentPart* sa)
: sAtt(sa)
JReplicator::JReplicator(Applier* appl, StableAttachmentPart* sa)
: applier(appl), sAtt(sa)
{ }
@ -6207,10 +6205,13 @@ int JReplicator::release()
if (rc != 0)
return rc;
LocalStatus status;
CheckStatusWrapper statusWrapper(&status);
if (applier)
{
LocalStatus status;
CheckStatusWrapper statusWrapper(&status);
freeEngineData(&statusWrapper);
freeEngineData(&statusWrapper);
}
delete this;
return 0;
@ -6226,9 +6227,9 @@ void JReplicator::freeEngineData(Firebird::CheckStatusWrapper* user_status)
try
{
const auto att = sAtt->getHandle();
if (att)
att->att_repl_applier.reset();
AutoPtr<Applier> cleanupApplier(applier);
cleanupApplier->shutdown(tdbb);
fb_assert(!applier);
}
catch (const Exception& ex)
{
@ -6255,8 +6256,7 @@ void JReplicator::process(CheckStatusWrapper* status, unsigned length, const UCH
try
{
const auto att = sAtt->getHandle();
att->att_repl_applier->process(tdbb, length, data);
applier->process(tdbb, length, data);
}
catch (const Exception& ex)
{
@ -6276,34 +6276,9 @@ void JReplicator::process(CheckStatusWrapper* status, unsigned length, const UCH
}
void JReplicator::close(CheckStatusWrapper* status)
void JReplicator::close(CheckStatusWrapper* user_status)
{
try
{
EngineContextHolder tdbb(status, this, FB_FUNCTION);
check_database(tdbb);
try
{
const auto att = sAtt->getHandle();
att->att_repl_applier->shutdown(tdbb);
att->att_repl_applier.reset();
}
catch (const Exception& ex)
{
transliterateException(tdbb, ex, status, "JReplicator::close");
return;
}
trace_warning(tdbb, status, "JReplicator::close");
}
catch (const Exception& ex)
{
ex.stuffException(status);
return;
}
successful_completion(status);
freeEngineData(user_status);
}
@ -7380,8 +7355,11 @@ void release_attachment(thread_db* tdbb, Jrd::Attachment* attachment)
attachment->att_replicator = nullptr;
if (attachment->att_repl_applier)
attachment->att_repl_applier->shutdown(tdbb);
while (attachment->att_repl_appliers.hasData())
{
AutoPtr<Applier> cleanupApplier(attachment->att_repl_appliers.pop());
cleanupApplier->shutdown(tdbb);
}
if (dbb->dbb_crypto_manager)
dbb->dbb_crypto_manager->detach(tdbb, attachment);

View File

@ -221,11 +221,16 @@ Applier* Applier::create(thread_db* tdbb)
request->req_attachment = attachment;
auto& att_pool = *attachment->att_pool;
return FB_NEW_POOL(att_pool) Applier(att_pool, dbb->dbb_filename, request);
const auto applier = FB_NEW_POOL(att_pool) Applier(att_pool, dbb->dbb_filename, request);
attachment->att_repl_appliers.add(applier);
return applier;
}
void Applier::shutdown(thread_db* tdbb)
{
const auto attachment = tdbb->getAttachment();
cleanupTransactions(tdbb);
CMP_release(tdbb, m_request);
@ -233,6 +238,14 @@ void Applier::shutdown(thread_db* tdbb)
m_record = NULL;
m_bitmap->clear();
attachment->att_repl_appliers.findAndRemove(this);
if (m_interface)
{
m_interface->resetHandle();
m_interface = nullptr;
}
}
void Applier::process(thread_db* tdbb, ULONG length, const UCHAR* data)

View File

@ -137,12 +137,23 @@ namespace Jrd
void shutdown(thread_db* tdbb);
Attachment* getAttachment() const
{
return m_request ? m_request->req_attachment : nullptr;
}
void setInterfacePtr(JReplicator* interfacePtr)
{
m_interface = interfacePtr;
}
private:
TransactionMap m_txnMap;
const Firebird::PathName m_database;
jrd_req* m_request;
Firebird::AutoPtr<RecordBitmap> m_bitmap;
Record* m_record;
JReplicator* m_interface;
void startTransaction(thread_db* tdbb, TraNumber traNum);
void prepareTransaction(thread_db* tdbb, TraNumber traNum);