[
https://issues.apache.org/jira/browse/AMQ-7067?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16643136#comment-16643136
]
Christopher L. Shannon commented on AMQ-7067:
---------------------------------------------
Shouldn't we just record the reference location update inside of the
pageFile.tx() ? This would do it under the write lock and also prevent having
to iterate again plus then the change gets commited to the index in the
transaciton. Ie, change:
{code:java}
final List<Operation> messagingTx = inflightTx;
indexLock.writeLock().lock();
try {
pageFile.tx().execute(new Transaction.Closure<IOException>() {
@Override
public void execute(Transaction tx) throws IOException {
for (Operation op : messagingTx) {
op.execute(tx);
}
}
});
metadata.lastUpdate = location;
} finally {
indexLock.writeLock().unlock();
}
for (Operation op: inflightTx) {
recordAckMessageReferenceLocation(location, op.getLocation());
}
{code}
to:
{code:java}
final List<Operation> messagingTx = inflightTx;
indexLock.writeLock().lock();
try {
pageFile.tx().execute(new Transaction.Closure<IOException>() {
@Override
public void execute(Transaction tx) throws IOException {
for (Operation op : messagingTx) {
op.execute(tx);
recordAckMessageReferenceLocation(location,
op.getLocation());
}
}
});
metadata.lastUpdate = location;
} finally {
indexLock.writeLock().unlock();
}
{code}
> KahaDB Recovery can experience a dangling transaction when prepare and commit
> occur on different data files.
> ------------------------------------------------------------------------------------------------------------
>
> Key: AMQ-7067
> URL: https://issues.apache.org/jira/browse/AMQ-7067
> Project: ActiveMQ
> Issue Type: Bug
> Components: KahaDB, XA
> Affects Versions: 5.15.6
> Reporter: Jamie goodyear
> Priority: Critical
> Fix For: 5.16.0, 5.15.7
>
> Attachments: amq7067test.patch
>
>
> KahaDB Recovery can experience a dangling transaction when prepare and commit
> occur on different data files.
> Scenario:
> A XA Transaction is started, message is prepared and sent into Broker.
> We then send into broker enough messages to file page file (100 message with
> 512 * 1024 characters in message payload). This forces a new data file to be
> created.
> Commit the XA transaction. Commit will land on the new data file.
> Restart the Broker.
> Upon restart a KahaDB recovery is executed.
> The prepare in PageFile 1 is not matched to Commit on PageFile 2, as such, it
> will appear in recovered message state.
> Looking deeper into this scenario, it appears that the commit message is
> GC'd, hence the prepare & commit can not be matched.
> The MessageDatabase only checks the following for GC:
> {color:#808080}// Don't GC files referenced by in-progress
> tx{color}{color:#cc7832}if {color}(inProgressTxRange[{color:#6897bb}0{color}]
> != {color:#cc7832}null{color}) {
> {color:#cc7832}for {color}({color:#cc7832}int
> {color}pendingTx=inProgressTxRange[{color:#6897bb}0{color}].getDataFileId(){color:#cc7832};
> {color}pendingTx <=
> inProgressTxRange[{color:#6897bb}1{color}].getDataFileId(){color:#cc7832};
> {color}pendingTx++) {
> gcCandidateSet.remove(pendingTx){color:#cc7832};{color} }
> }
> We need to become aware of where the prepare & commits occur in pagefiles
> with respect to GCing files.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)