WL#1159: Allow multiple locks in GET_LOCK()

Affects: Server-5.7   —   Status: Complete

Original task description
=========================

We shall allow one to request multiple of locks Via serie of GET_LOCK 
statements, 
it would be even nice to allow several locks in single function call:

GET_LOCK("lock1","lock2",0);
GET_LOCK("lock3",0)

Implementing this option one shall take care of possible deadlocks.

Also in such case we shall allow RELEASE_LOCK to release all locks which thread 
has.

It would be also convenient to be able to get list of locks which current thread
owns for debugging purposes.

Current task description/differences from original proposal
===========================================================

There is a contribution implementing some of the above ideas

http://bugs.mysql.com/bug.php?id=67806

Particularly:

+) It allows to request multiple user-level locks via serie of GET_LOCK
   calls. GET_LOCK no longer releases user-level locks which were previously
   acquired.
+) It replaces custom user-level lock implementation with one based on
   MDL lock manager. As result deadlocks between different connections
   acquiring user-level locks, metadata locks and waiting for table
   flushes are detected and reported as errors.
0) GET_LOCK("lock1","lock2",...) syntax is not supported (but this mostly
   seems like a syntax sugar).
-) RELEASE_LOCK still releases only individual locks. There is no simple
   way to release all locks in connection.
-) There is no simple way to get list of locks which current connection
   has. Work-around is to use p_s.metadata_locks.

Decision has been made to accept this contribution, possibly with some
extensions.

Some use-cases in which multiple user-level locks are important
===============================================================

User-level locks are often used:

1) to organize mutual exclusion when accessing some resource in
   cases when table/row-level locks are not appropriate.
2) to implement waits for some condition to change. Think of
   a queue in a producer-consumer setup. The queue itself is stored
   in a table in such a setup, but to avoid polling this table
   often/too much consumer waits for producer to insert into the
   queue on user-level lock.

In cases when one connection needs to work with more than one resource/
condition ability to acquire and hold multiple user-level locks becomes
necessary.

Additionaly, code working with resources/conditions might have complex
structure, so one might end-up in situation when one module which has
acquired on user-level lock calls another module which needs to acquire
another user-level lock. In this case the fact that the second module
will release user-level lock acquired by the first module and thus
break its invariants/atomicity as a side-effect might easily cause
unexpected errors. So for better module isolation it would be nice if
one connection can acquire different user-level locks independently 
without them affecting state of each other.

User Documentation
==================

http://dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-5.html
http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-
functions.html#function_get-lock
http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-
functions.html#function_release-all-locks
http://dev.mysql.com/doc/refman/5.7/en/metadata-locks-table.html