|
| 1 | +# MQTT Wildcard Queue Auto-Delete Bug Analysis |
| 2 | + |
| 3 | +## Bug Confirmed: Auto-Delete Logic Does Not Check Wildcard Queue Bindings |
| 4 | + |
| 5 | +The diagnostic output from the test proves this is an **auto-delete bug**, not a console bug. |
| 6 | + |
| 7 | +## Evidence from Test Execution |
| 8 | + |
| 9 | +### BEFORE RESTART (testWildcardQueueBindingPreventsAutoDelete) |
| 10 | + |
| 11 | +``` |
| 12 | +Addresses and their queues: |
| 13 | + Address: TEST.1 (AutoCreated: true, RoutingTypes: [MULTICAST], AddressSize: 798 bytes) |
| 14 | + Bindings (1): |
| 15 | + - mqtt-subscriber.TEST.# (Type: LOCAL_QUEUE) |
| 16 | + Queues (1): |
| 17 | + - mqtt-subscriber.TEST.# (Durable: true, Messages: 1, Consumers: 0, PersistentSize: 240 bytes) |
| 18 | +
|
| 19 | + Address: TEST.# (AutoCreated: true, RoutingTypes: [MULTICAST], AddressSize: 72 bytes) |
| 20 | + Bindings (1): |
| 21 | + - mqtt-subscriber.TEST.# (Type: LOCAL_QUEUE) |
| 22 | + Queues (1): |
| 23 | + - mqtt-subscriber.TEST.# (Durable: true, Messages: 1, Consumers: 0, PersistentSize: 240 bytes) |
| 24 | +``` |
| 25 | + |
| 26 | +**Key Findings:** |
| 27 | +1. ✓ The wildcard queue `mqtt-subscriber.TEST.#` **IS** bound to address `TEST.1` |
| 28 | +2. ✓ The binding is real and active (queue has 1 message received from TEST.1) |
| 29 | +3. ✓ The same queue appears in both addresses' binding lists |
| 30 | +4. ✓ Address `TEST.1` has **798 bytes** in paging store (proving it holds real data) |
| 31 | +5. ✓ Address `TEST.#` has **72 bytes** in paging store |
| 32 | +6. ✓ Queue persistent size is **240 bytes** (the actual message size) |
| 33 | + |
| 34 | +### AFTER RESTART |
| 35 | + |
| 36 | +``` |
| 37 | +AMQ224113: Auto removing address TEST.1 |
| 38 | +
|
| 39 | +Addresses and their queues: |
| 40 | + Address: TEST.# (AutoCreated: true, RoutingTypes: [MULTICAST], AddressSize: 72 bytes) |
| 41 | + Bindings (1): |
| 42 | + - mqtt-subscriber.TEST.# (Type: LOCAL_QUEUE) |
| 43 | + Queues (1): |
| 44 | + - mqtt-subscriber.TEST.# (Durable: true, Messages: 1, Consumers: 0, PersistentSize: 240 bytes) |
| 45 | +``` |
| 46 | + |
| 47 | +**Key Findings:** |
| 48 | +1. ✗ Address `TEST.1` was **incorrectly auto-deleted** during broker startup |
| 49 | +2. ✗ The **798 bytes** in `TEST.1` paging store was lost when the address was deleted |
| 50 | +3. ✓ The wildcard queue `mqtt-subscriber.TEST.#` survived (it's durable) |
| 51 | +4. ✓ The **240 bytes** of persistent queue data survived the restart |
| 52 | +5. ✗ The auto-delete logic did not detect the wildcard queue's binding to `TEST.1` |
| 53 | +6. ✗ Despite having 798 bytes in the paging store, `TEST.1` was still deleted |
| 54 | + |
| 55 | +## Root Cause Analysis |
| 56 | + |
| 57 | +The auto-delete logic during broker restart is checking if an address has queues bound to it, but it's **failing to detect wildcard queue bindings**. |
| 58 | + |
| 59 | +### How Wildcard Queues Work |
| 60 | + |
| 61 | +1. MQTT client subscribes to `TEST/#` (wildcard subscription) |
| 62 | +2. Artemis creates queue `mqtt-subscriber.TEST.#` bound to address `TEST.#` |
| 63 | +3. When a message is published to `TEST.1`: |
| 64 | + - Address `TEST.1` is auto-created |
| 65 | + - The message is routed via multicast to matching wildcard subscriptions |
| 66 | + - The wildcard queue `mqtt-subscriber.TEST.#` receives the message |
| 67 | + - **The queue gets bound to the specific address `TEST.1`** |
| 68 | + |
| 69 | +4. On broker restart: |
| 70 | + - The durable queue `mqtt-subscriber.TEST.#` is restored |
| 71 | + - Address `TEST.#` is restored with the queue binding |
| 72 | + - Address `TEST.1` is restored from bindings journal |
| 73 | + - **BUG**: Auto-delete logic checks `TEST.1` and fails to find the wildcard queue binding |
| 74 | + - Address `TEST.1` is incorrectly removed |
| 75 | + |
| 76 | +## Why This Is a Problem |
| 77 | + |
| 78 | +1. **Data Loss Risk**: Messages in the queue for `TEST.1` topics could be lost |
| 79 | +2. **Inconsistent State**: Before restart, the binding exists; after restart, it doesn't |
| 80 | +3. **User Confusion**: The console shows the binding before restart, then it disappears |
| 81 | +4. **Violates Expectations**: Addresses with bound queues should not be auto-deleted |
| 82 | +5. **Persistent Data Ignored**: Even with 240 bytes of persistent data, the address is deleted |
| 83 | +6. **Wildcard Routing Broken**: After restart, new messages to `TEST.1` may not route to the wildcard queue |
| 84 | + |
| 85 | +## Expected Behavior |
| 86 | + |
| 87 | +When checking if an address can be auto-deleted, the logic should: |
| 88 | +1. Check for direct queue bindings (currently working) |
| 89 | +2. **Check for wildcard queue bindings** (currently NOT working) |
| 90 | +3. Only delete if there are no bindings of any kind |
| 91 | + |
| 92 | +An address like `TEST.1` should survive restart if: |
| 93 | +- Any durable queue is bound to it, OR |
| 94 | +- Any wildcard queue (e.g., `TEST.#`) has a binding to it |
| 95 | + |
| 96 | +## Fix Required |
| 97 | + |
| 98 | +The auto-delete logic in the broker startup code needs to be updated to: |
| 99 | +1. When checking if address `TEST.1` can be deleted |
| 100 | +2. Look for ALL queues bound to it, including wildcard queues |
| 101 | +3. If ANY queue (direct or wildcard) is bound, do NOT auto-delete |
| 102 | + |
| 103 | +## Test Results |
| 104 | + |
| 105 | +Both test methods successfully reproduce the bug: |
| 106 | + |
| 107 | +1. **testWildcardQueueBindingPreventsAutoDelete**: |
| 108 | + - Status: **FAILS** (expected behavior after fix: PASS) |
| 109 | + - Proves the wildcard queue IS bound before restart |
| 110 | + - Proves TEST.1 is incorrectly deleted after restart |
| 111 | + |
| 112 | +2. **testWildcardSubscriptionPreventsAutoDeleteAfterRestart**: |
| 113 | + - Status: **PASSES** (currently expects buggy behavior) |
| 114 | + - Confirms TEST.1 is deleted after restart |
| 115 | + - Includes diagnostic message: "BUG REPRODUCED" |
| 116 | + |
| 117 | +## Files Created |
| 118 | + |
| 119 | +1. `MqttWildcardAutoDeleteAddressTest.java` - Test reproduction |
| 120 | +2. `MqttWildcardAutoDeleteAddressTest_README.md` - Test documentation |
| 121 | +3. `BUG_ANALYSIS.md` - This file with detailed analysis |
| 122 | + |
| 123 | +## Next Steps for Developers |
| 124 | + |
| 125 | +1. Review the auto-delete logic in the broker startup code |
| 126 | +2. Identify where address auto-deletion decisions are made |
| 127 | +3. Update the logic to check for wildcard queue bindings |
| 128 | +4. Run the test to verify the fix |
| 129 | +5. Update test assertions to expect correct behavior |
0 commit comments