I have been testing my 64-bit MSMQ 3.0 server by chucking 1,000s of large messages at it to see how well it responds. I did have Performance Monitor running, showing “Total messages in all queues” and “Total bytes in all queues” for the MSMQ service. I would come back to the screen every now and then and think – “strange, there’s less messages than there was 10 minutes ago.” – but not having the time to investigate, I shrugged and left it.
Today I came to purge the queue and saw the attached Performance Monitor graph (image stitched together from a couple of screenshots).
As you can see, the Performance Monitor counters magically found more messages to count every time 4GBs of messages were purged. There was no other MSMQ activity – I don’t have any magic app that could deliver 4GB of messages in one perfmon tick!
I checked the Storage directory and there were 19GB of files. The messages were just over 1MB in size so I am expecting an amount of empty space in the *.MQ files (maybe 20% ?). From the Performance Monitor graph I must have had around 12GB-16GB of messages (I may have missed a peak when collecting screenshots) but only 4GB would display at any one time.
When ever it reached 4GB it must have reset to 0 and climbed up to the next 4GB step. This must have been why I could see less messages than 10 minutes earlier. This also explains why I couldn’t send more messages after it appeared that I had reached 4GB. In reality I must have had 8GB of messages and reached the system quota but perfmon only showed 4GB. To check this I removed the quota, rebooted, and messages flew again.
The root cause is as follows:
Performance counters in Windows 2003 are all 32-bit counters (type PERF_COUNTER_RAWCOUNT/PERF_COUNTER_COUNTER) as opposed to 64-bit counter (PERF_COUNTER_LARGE_RAWCOUNT/PERF_COUNTER_BULK_COUNT). Hence these counters will wrap-around after 4 GB. On Windows Vista, all the counters have been changed to 64-bit and hence this problem should not appear there.
Bottom line – what are you doing with more than 4GB stored in MSMQ? Use SQL Server instead!