Doug posted a question on MQ List Server regarding the MQ error message AMQ7234. His question was:
My shop has always struggled with large number of messages just being left on the queue. Sometimes to be processed later, sometimes because the application does not know what to do with them, but they cannot be removed. The following error “AMQ7234” is generated frequently about message being loaded onto the queue.
What I have observed, is that when this “loading” occurs all processing of MQSeries halts until the entire queue is read and loaded into memory. Sometimes this takes more than a couple of seconds causing delays in time sensitive responses to other queues for other applications. This queue manager is used, by executive mandate, by many applications – it would appear to me that this delay is the cause of other applications not meeting their performance SLA.
My reply was:
Now that’s an interesting problem. I had to Google the error messages because I have not see it before.
Here’s a good explanation: https://www.ibm.com/support/pages/amq7234-issued-periodically-wmq
It gives 4 solutions:
- Avoid deep queues (MQ was not designed to be a database to keep messages for long periods of time)
- Ensure that the queue is referenced very often by putting or getting messages
- Keep an open handle on the queue so that the queue will not be unloaded to disk.
- One possible way to do this would be to write a simple program that opens the queue for MQOO_INQUIRE, and then sleep indefinitely. The queue will be unloaded from memory if the last application accessing it has closed the queue. Therefore, if at least one application has the queue open, then the queue will not be unloaded from memory.
Pretty standard stuff but I do like the last solution. It is weird just like me. 🙂 But the only problem about sleeping forever is that if you try to stop the queue manager it may wait on the application. Hence, I would change it to do a Get and match on a crazy CorrelId. i.e. CorrelId = “Doug is an awesome MQAdm” (max 24 characters). Issue an MQGET with wait-forever and the “Fail if Quiescing” option.
Therefore, the queue will never to be unloaded and the problem is solved. Bonus: Set it up in as a ‘Server’ service in the queue manager then you never have to worry about it again.
I took one of my C sample programs and created a simple program called ‘GetMatchNone.c’. It opens a queue, performs a non-destructive get (browse) for a crazy Correlation Id and waits forever. You can download the program from here.
Here’s a sample MQSC service definition for GetMatchNone:
DEFINE SERVICE ('GetMatchNone') + DESCR('Keep QMgr from unloading the messages of this queue.') + STARTCMD('C:\Capitalware\Utils\GetMatchNone.exe') + STARTARG('TEST.Q1 +QMNAME+') + STOPCMD(' ') + STOPARG(' ') + STDOUT('C:\Capitalware\Utils\stdout.log') + STDERR('C:\Capitalware\Utils\stderr.log') + CONTROL(STARTONLY) + SERVTYPE(SERVER) + REPLACE
- where:
- TEST.Q1 is the queue name that we don’t want messages to be unloaded.
- C:\Capitalware\Utils\ is the directory where the executable is located and where the output files will be written to.
- +QMNAME+ is an MQ environment variable for the name of the queue manager
- Control is set to ‘STARTONLY’ because when the queue manager ends, the GetMatchNone program will gracefuly end.
Regards,
Roger Lacroix
Capitalware Inc.