[ https://issues.apache.org/activemq/browse/AMQ-732?page=all ]

Hiram Chirino updated AMQ-732:
------------------------------

    Fix Version: 4.0.2
                     (was: 4.0.1)

> Infinite recovery loop.
> -----------------------
>
>          Key: AMQ-732
>          URL: https://issues.apache.org/activemq/browse/AMQ-732
>      Project: ActiveMQ
>         Type: Bug

>   Components: Broker
>     Versions: 4.0
>  Environment: Linux RHEL 3
>     Reporter: Maxim Fateev
>     Assignee: Hiram Chirino
>      Fix For: 4.1, 4.0.2
>  Attachments: activemq-data-1-journal.tar.gz, activemq-data-2-journal.tar.gz
>
>
> The simplest way to reproduce the problem:
> 1. Remove storage directory. 
> 2. Start broker using the following code:
>  public static void main(String[] args)  throws Exception {
>            BrokerService broker = new BrokerService();
>            broker.setPersistent(true);
>            DefaultPersistenceAdapterFactory pFactory = new 
> DefaultPersistenceAdapterFactory();
>            pFactory.setJournalLogFiles(1);
>            pFactory.setJournalLogFileSize(2048);
>            broker.setPersistenceFactory(pFactory);
>            broker.setUseJmx(false);
>            broker.addConnector("tcp://localhost:61616");
>            broker.start();
>            Thread.sleep(1000000000000l);
>    }
> 3. Shutdown the broker.
> 4. Start broker.
> It enters infinite loop
> [                          main] BrokerService                  INFO  
> ActiveMQ null JMS Message Broker (localhost) is starting
> [                          main] BrokerService                  INFO  For 
> help or more information please see: http://incubator.apache.org/activemq/
> [                          main] JDBCPersistenceAdapter         INFO  
> Database driver recognized: [apache_derby_embedded_jdbc_driver]
> [                          main] DefaultJDBCAdapter             DEBUG 
> Executing SQL: CREATE TABLE ACTIVEMQ_MSGS(ID INTEGER NOT NULL, CONTAINER 
> VARCHAR(250), MSGID_PROD VARCHAR(250), MSGID_SEQ INTEGER, EXPIRATION BIGINT, 
> MSG BLOB, PRIMARY KEY ( ID ) )
> [                          main] DefaultJDBCAdapter             DEBUG Could 
> not create JDBC tables; The message table already existed. Failure was: 
> CREATE TABLE ACTIVEMQ_MSGS(ID INTEGER NOT NULL, CONTAINER VARCHAR(250), 
> MSGID_PROD VARCHAR(250), MSGID_SEQ INTEGER, EXPIRATION BIGINT, MSG BLOB, 
> PRIMARY KEY ( ID ) ) Message: Table/View 'ACTIVEMQ_MSGS' already exists in 
> Schema 'APP'. SQLState: X0Y32 Vendor code: 20000
> [                          main] DefaultJDBCAdapter             DEBUG 
> Executing SQL: CREATE INDEX ACTIVEMQ_MSGS_MIDX ON ACTIVEMQ_MSGS 
> (MSGID_PROD,MSGID_SEQ)
> [                          main] DefaultJDBCAdapter             DEBUG 
> Executing SQL: CREATE INDEX ACTIVEMQ_MSGS_CIDX ON ACTIVEMQ_MSGS (CONTAINER)
> [                          main] DefaultJDBCAdapter             DEBUG 
> Executing SQL: CREATE INDEX ACTIVEMQ_MSGS_EIDX ON ACTIVEMQ_MSGS (EXPIRATION)
> [                          main] DefaultJDBCAdapter             DEBUG 
> Executing SQL: CREATE TABLE ACTIVEMQ_ACKS(CONTAINER VARCHAR(250) NOT NULL, 
> CLIENT_ID VARCHAR(250) NOT NULL, SUB_NAME VARCHAR(250) NOT NULL, SELECTOR 
> VARCHAR(250), LAST_ACKED_ID INTEGER, PRIMARY KEY ( CONTAINER, CLIENT_ID, 
> SUB_NAME))
> [                          main] DefaultJDBCAdapter             DEBUG Could 
> not create JDBC tables; The message table already existed. Failure was: 
> CREATE TABLE ACTIVEMQ_ACKS(CONTAINER VARCHAR(250) NOT NULL, CLIENT_ID 
> VARCHAR(250) NOT NULL, SUB_NAME VARCHAR(250) NOT NULL, SELECTOR VARCHAR(250), 
> LAST_ACKED_ID INTEGER, PRIMARY KEY ( CONTAINER, CLIENT_ID, SUB_NAME)) 
> Message: Table/View 'ACTIVEMQ_ACKS' already exists in Schema 'APP'. SQLState: 
> X0Y32 Vendor code: 20000
> [                          main] JDBCPersistenceAdapter         DEBUG 
> Cleaning up old messages.
> [                          main] DefaultJDBCAdapter             DEBUG 
> Executing SQL: DELETE FROM ACTIVEMQ_MSGS WHERE ( EXPIRATION<>0 AND 
> EXPIRATION<?) OR ID <= ( SELECT min(ACTIVEMQ_ACKS.LAST_ACKED_ID) FROM 
> ACTIVEMQ_ACKS WHERE ACTIVEMQ_ACKS.CONTAINER=ACTIVEMQ_MSGS.CONTAINER)
> [                          main] DefaultJDBCAdapter             DEBUG Deleted 
> 0 old message(s).
> [                          main] JDBCPersistenceAdapter         DEBUG Cleanup 
> done.
> [                          main] JournalPersistenceAdapter      INFO  Journal 
> Recovery Started from: Active Journal: using 1 x 0.001953125 Megs at: 
> /workplace/fateev/install/activemq-4.0-SNAPSHOT/activemq-core/activemq-data/journal
> [                          main] JournalPersistenceAdapter      DEBUG TRACE 
> Entry: RECOVERED
> [                Journal Writer] LogFileManager                 DEBUG 
> getNextDataRecordLocation offset=53
> [                Journal Writer] LogFileManager                 DEBUG 
> getNextDataRecordLocation offset=97
> [                Journal Writer] LogFileManager                 DEBUG 
> getNextDataRecordLocation overflowing into next logFile=0
> [                          main] JournalPersistenceAdapter      DEBUG TRACE 
> Entry: RECOVERED
> [                Journal Writer] LogFileManager                 DEBUG 
> getNextDataRecordLocation offset=53
> [                Journal Writer] LogFileManager                 DEBUG 
> getNextDataRecordLocation offset=97
> [                Journal Writer] LogFileManager                 DEBUG 
> getNextDataRecordLocation overflowing into next logFile=0
> [                          main] JournalPersistenceAdapter      DEBUG TRACE 
> Entry: RECOVERED
> [                Journal Writer] LogFileManager                 DEBUG 
> getNextDataRecordLocation offset=53
> [                Journal Writer] LogFileManager                 DEBUG 
> getNextDataRecordLocation offset=97
> [                Journal Writer] LogFileManager                 DEBUG 
> getNextDataRecordLocation overflowing into next logFile=0
> The log entry from getNextDataRecordLocation is coming from log statement 
> I've added to LogFileManager.getNextDataRecordLocation:
>    public Location getNextDataRecordLocation(Location lastLocation) throws 
> IOException, InvalidRecordLocationException {
>         RecordInfo ri = readRecordInfo(lastLocation);
>         while (true) {
>             int logFileId = ri.getLocation().getLogFileId();
>             int offset = ri.getNextLocation();
>             log.debug("getNextDataRecordLocation offset=" + offset);
>             // Are we overflowing into next logFile?
>             if (offset >= ri.getLogFileState().getAppendOffset()) {
>                 LogFileNode nextActive = ri.getLogFileState().getNextActive();
>                 log.debug("getNextDataRecordLocation overflowing into next 
> logFile=" + (nextActive == null ? "null"  : 
> String.valueOf(nextActive.getId())));
>                 if (nextActive == null) {
>                     return null;
>                 }
>                 logFileId = nextActive.getId();
>                 offset = 0;
>             }
>             try {
>                 ri = readRecordInfo(new Location(logFileId, offset));
>             } catch (InvalidRecordLocationException e) {
>                 return null;
>             }
>             // Is the next record the right record type?
>             if (ri.getHeader().getRecordType() == DATA_RECORD_TYPE) {
>                 return ri.getLocation();
>             }
>             // No? go onto the next record.
>         }
>     }
> It looks like recovery doesn't take into account that journaling storage file 
> should have some end at some point. 
> Similar problem happens if multiple files of bigger size are used. It happens 
> every time one of the log files grows bigger then size specified in 
> pFactory.setJournalLogFileSize(...) call.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   https://issues.apache.org/activemq/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira

Reply via email to