Nicolas Grondin created AMQ-7425:
------------------------------------

             Summary: Messages in journal persistence don't get deleted upon ack
                 Key: AMQ-7425
                 URL: https://issues.apache.org/jira/browse/AMQ-7425
             Project: ActiveMQ
          Issue Type: Bug
          Components: JDBC
    Affects Versions: 5.15.11
            Reporter: Nicolas Grondin


When using a journal JDBC persistence, we noticed that some messages in the DB 
table (activemq_msgs) don't always get deleted upon the messages being 
consumed. The adverse effect is that if the broker restarts (hosted in a K8S 
pod, so local journal files also lost) the broker will consider all non-deleted 
message as still unconsumed and will offer them up for consumption (this was an 
issue for us in production)

This seems to be cause by the fact that the persistence adapter does not use 
the right ID in the SQL statement to delete the line.

This comes from the fact that sometimes, the messageId has a 
"futureOrSequenceLong" of 0 as opposed to the correct ID (from the DB). This is 
because the "futureOrSequenceLong" gets set on that message only at the time 
the message is being persisted. But in a journal persistence, this happens on a 
frequency (5 minutes by default).

If a browse action occurs before the message is persisted, then a copy of the 
message is taken, which also copies of the wrong "futureOrSequenceLong". Upon 
consumption (assuming no restarts of the broker in the meantime), it is this 
copy of the messageId that is used when comes the time to remove the message 
from the DB.

The removal code actually caters for the missing "futureOrSequenceLong" in 
JDBCMessageStore [257] with this line:

  {color:#FF0000}   long seq = ack.getLastMessageId().getFutureOrSequenceLong() 
!= null ?     long seq = ack.getLastMessageId().getFutureOrSequenceLong() != 
null ?                (Long) ack.getLastMessageId().getFutureOrSequenceLong() : 
               persistenceAdapter.getStoreSequenceIdForMessageId(context, 
ack.getLastMessageId(), destination)[0];{color}

In which case it will get it from the DB directly.

But the issue is that in the described case, the "futureOrSequenceLong" is not 
null, but has a value of 0L.

This is due to this line in JournalMessageStore.addMessage [142] (called when 
the message is originally produced)

{color:#FF0000}message.getMessageId().setFutureOrSequenceLong(0l);{color}

I actually think that creating a message on a JournalMessageStore should leave 
the "futureOrSequenceLong" null so that later condition checks can pick it up 
as such and properly get the sequence from the database.

 



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to