[MDEV-7026] Race in InnoDB/XtraDB mutex implementation can stall or hang the server Created: 2014-11-05 Updated: 2016-07-11 Resolved: 2014-11-25 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Platform Power, Storage Engine - InnoDB, Storage Engine - XtraDB |
| Affects Version/s: | 5.5.40, 10.0.14 |
| Fix Version/s: | 5.5.41, 10.0.15 |
| Type: | Bug | Priority: | Blocker |
| Reporter: | Kristian Nielsen | Assignee: | Sergey Vojtovich |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | buildbot | ||
| Issue Links: |
|
||||||||||||||||||||||||
| Description |
|
This failure is seen in Buildbot. It is a race that occurs somewhat rarely, The failure can occur in different tests, for example like this: http://buildbot.askmonty.org/buildbot/builders/bintar-trusty-p8-debug/builds/173
More failures are seen in a cross-reference search: It looks like it only fails in debug builds on Power8, but this is not 100% Looking into the error log, we consistently see that it hangs during creation
Normally there should be a message after this that the doublewrite buffer was Here is a GDB stacktrace from when it hangs:
Here is how I reproduced it, running the test in a loop and waiting for it to
|
| Comments |
| Comment by Kristian Nielsen [ 2014-11-05 ] | |||||||||||||||||||||||||
|
The problem is apparently that a waiting thread is not woken up when an InnoDB mutes is released:
The wakeup condition is not true...
But the mutex is not locked (lock_word == 0). Looks like some issue with the InnoDB mutex implementation... | |||||||||||||||||||||||||
| Comment by Sergey Vojtovich [ 2014-11-06 ] | |||||||||||||||||||||||||
|
There is a comment in mutex_exit_func():
Even though we added "os_isync" between "lock_word store" and "waiters load", it is not enough. Only full memory barrier guarantees StoreLoad order. So we still rely on the error monitor thread to wake up such stale threads. But error monitor thread is using mutexes itself and may get stuck similarly to other threads. To workaround this Monty added log_get_lsn_nowait(), which basically does trylock instead of lock. This is added in revision 4271 (monty@mariadb.org-20140819162835-sorv0ogd39f7mui8) of 5.5. In this case I suspect error monitor thread is either not started or is stuck on different mutex (other than log_get_lsn mutex). | |||||||||||||||||||||||||
| Comment by Sergey Vojtovich [ 2014-11-06 ] | |||||||||||||||||||||||||
| Comment by Kristian Nielsen [ 2014-11-06 ] | |||||||||||||||||||||||||
|
I wrote up a detailed analysis on maria-developers@ of what appears to be the https://lists.launchpad.net/maria-developers/msg07860.html Incidentally, it appears that this same bug is also what is I agree that in this case, the error monitor thread is not yet started (it was However, I strongly disagree that the whole idea of using error monitor | |||||||||||||||||||||||||
| Comment by Sergey Vojtovich [ 2014-11-12 ] | |||||||||||||||||||||||||
|
Kristian, please review fix for this bug. | |||||||||||||||||||||||||
| Comment by Sergey Vojtovich [ 2014-11-12 ] | |||||||||||||||||||||||||
|
...second patch:
| |||||||||||||||||||||||||
| Comment by Kristian Nielsen [ 2014-11-14 ] | |||||||||||||||||||||||||
|
Review sent to maria-developers@: | |||||||||||||||||||||||||
| Comment by Sergey Vojtovich [ 2014-11-18 ] | |||||||||||||||||||||||||
|
Kristian, please review updated patch. | |||||||||||||||||||||||||
| Comment by Kristian Nielsen [ 2014-11-18 ] | |||||||||||||||||||||||||
|
New review sent to maria-developers@: | |||||||||||||||||||||||||
| Comment by Kristian Nielsen [ 2014-11-19 ] | |||||||||||||||||||||||||
|
Patch to clarify suggestions in previously made review: http://lists.askmonty.org/pipermail/commits/2014-November/007050.html | |||||||||||||||||||||||||
| Comment by Sergey Vojtovich [ 2014-11-25 ] | |||||||||||||||||||||||||
|
Fixed in 10.0.15, 5.5.41:
| |||||||||||||||||||||||||
| Comment by Stewart Smith [ 2015-07-17 ] | |||||||||||||||||||||||||
|
The use of __sync_synchronize() here is incorrect as it gererates a sync() instruction which is a heavyweight barrier which is only needed if you're writing device drivers. __sync_lock_release() is sufficient realistically, __atomic_test_and_set() and __atomic_clear() should be used these days. | |||||||||||||||||||||||||
| Comment by Sergey Vojtovich [ 2015-07-17 ] | |||||||||||||||||||||||||
|
stewart-ibm, right. Good mutex implementation should never need to issue heavyweight sync. In 5.5 and 10.0 old mutex implementation was kept intact as much as possible, for which this sync is a must. In 10.1 there was an aim ( | |||||||||||||||||||||||||
| Comment by Stewart Smith [ 2015-07-17 ] | |||||||||||||||||||||||||
|
You should be able to remove the __sync_synchronize() and everything work. There's no reason for the sync instruction to be there. | |||||||||||||||||||||||||
| Comment by Kristian Nielsen [ 2015-07-17 ] | |||||||||||||||||||||||||
|
I do not plan to re-visit this issue myself. But be sure to read the mailing list discussion on this in the archive, there was a very detailed discussion on what kind of barriers are needed in the current implementation, and why. | |||||||||||||||||||||||||
| Comment by Sergey Vojtovich [ 2015-07-17 ] | |||||||||||||||||||||||||
|
stewart-ibm, we added __sync_synchronize() to make sure "lock_word" is stored before "waiters" are loaded. That is to ensure StoreLoad order. You say it's not needed. If so, how can we ensure StoreLoad order in this case? |