MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
lock.cc
Go to the documentation of this file.
1 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software Foundation,
14  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
15 
16 
76 #include "sql_priv.h"
77 #include "debug_sync.h"
78 #include "unireg.h" // REQUIRED: for other includes
79 #include "lock.h"
80 #include "sql_base.h" // close_tables_for_reopen
81 #include "sql_parse.h" // is_log_table_write_query
82 #include "sql_acl.h" // SUPER_ACL
83 #include <hash.h>
84 #include <assert.h>
85 
91 extern HASH open_cache;
92 
93 /* flags for get_lock_data */
94 #define GET_LOCK_UNLOCK 1
95 #define GET_LOCK_STORE_LOCKS 2
96 
97 static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
98  uint flags);
99 static int lock_external(THD *thd, TABLE **table,uint count);
100 static int unlock_external(THD *thd, TABLE **table,uint count);
101 static void print_lock_error(int error, const char *);
102 
103 /* Map the return value of thr_lock to an error from errmsg.txt */
104 static int thr_lock_errno_to_mysql[]=
105 { 0, ER_LOCK_ABORTED, ER_LOCK_WAIT_TIMEOUT, ER_LOCK_DEADLOCK };
106 
115 static int
116 lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags)
117 {
118  uint system_count= 0, i= 0;
119  bool is_superuser= false;
120  /*
121  Identifies if the executed sql command can updated either a log
122  or rpl info table.
123  */
124  bool log_table_write_query= false;
125 
126  DBUG_ENTER("lock_tables_check");
127 
128  is_superuser= thd->security_ctx->master_access & SUPER_ACL;
129  log_table_write_query=
130  is_log_table_write_query(thd->lex->sql_command);
131 
132  for (i=0 ; i<count; i++)
133  {
134  TABLE *t= tables[i];
135 
136  /* Protect against 'fake' partially initialized TABLE_SHARE */
137  DBUG_ASSERT(t->s->table_category != TABLE_UNKNOWN_CATEGORY);
138 
139  /*
140  Table I/O to performance schema tables is performed
141  only internally by the server implementation.
142  When a user is requesting a lock, the following
143  constraints are enforced:
144  */
145  if (t->s->table_category == TABLE_CATEGORY_LOG &&
146  (flags & MYSQL_LOCK_LOG_TABLE) == 0 &&
147  !log_table_write_query)
148  {
149  /*
150  A user should not be able to prevent writes,
151  or hold any type of lock in a session,
152  since this would be a DOS attack.
153  */
154  if (t->reginfo.lock_type >= TL_READ_NO_INSERT ||
155  thd->lex->sql_command == SQLCOM_LOCK_TABLES)
156  {
157  my_error(ER_CANT_LOCK_LOG_TABLE, MYF(0));
158  DBUG_RETURN(1);
159  }
160  }
161 
162  if (t->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE)
163  {
164  if (t->s->table_category == TABLE_CATEGORY_SYSTEM)
165  system_count++;
166 
167  if (t->db_stat & HA_READ_ONLY)
168  {
169  my_error(ER_OPEN_AS_READONLY, MYF(0), t->alias);
170  DBUG_RETURN(1);
171  }
172  }
173 
174  /*
175  If we are going to lock a non-temporary table we must own metadata
176  lock of appropriate type on it (I.e. for table to be locked for
177  write we must own metadata lock of MDL_SHARED_WRITE or stronger
178  type. For table to be locked for read we must own metadata lock
179  of MDL_SHARED_READ or stronger type).
180  The only exception are HANDLER statements which are allowed to
181  lock table for read while having only MDL_SHARED lock on it.
182  */
183  DBUG_ASSERT(t->s->tmp_table ||
184  thd->mdl_context.is_lock_owner(MDL_key::TABLE,
185  t->s->db.str, t->s->table_name.str,
186  t->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE ?
187  MDL_SHARED_WRITE : MDL_SHARED_READ) ||
188  (t->open_by_handler &&
189  thd->mdl_context.is_lock_owner(MDL_key::TABLE,
190  t->s->db.str, t->s->table_name.str,
191  MDL_SHARED)));
192 
193  /*
194  Prevent modifications to base tables if READ_ONLY is activated.
195  In any case, read only does not apply to temporary tables.
196  */
197  if (!(flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY) && !t->s->tmp_table)
198  {
199  if (t->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE &&
200  !is_superuser && opt_readonly && !thd->slave_thread)
201  {
202  my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
203  DBUG_RETURN(1);
204  }
205  }
206  }
207 
208  /*
209  Locking of system tables is restricted:
210  locking a mix of system and non-system tables in the same lock
211  is prohibited, to prevent contention.
212  */
213  if ((system_count > 0) && (system_count < count))
214  {
215  my_error(ER_WRONG_LOCK_OF_SYSTEM_TABLE, MYF(0));
216  DBUG_RETURN(1);
217  }
218 
219  DBUG_RETURN(0);
220 }
221 
243 static void reset_lock_data(MYSQL_LOCK *sql_lock)
244 {
245  THR_LOCK_DATA **ldata, **ldata_end;
246  DBUG_ENTER("reset_lock_data");
247 
248  /* Clear the lock type of all lock data to avoid reusage. */
249  for (ldata= sql_lock->locks, ldata_end= ldata + sql_lock->lock_count;
250  ldata < ldata_end;
251  ldata++)
252  {
253  /* Reset lock type. */
254  (*ldata)->type= TL_UNLOCK;
255  }
256  DBUG_VOID_RETURN;
257 }
258 
259 
267 static void reset_lock_data_and_free(MYSQL_LOCK **mysql_lock)
268 {
269  reset_lock_data(*mysql_lock);
270  my_free(*mysql_lock);
271  *mysql_lock= 0;
272 }
273 
274 
289 MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, uint flags)
290 {
291  int rc;
292  MYSQL_LOCK *sql_lock;
293  ulong timeout= (flags & MYSQL_LOCK_IGNORE_TIMEOUT) ?
294  LONG_TIMEOUT : thd->variables.lock_wait_timeout;
295 
296  DBUG_ENTER("mysql_lock_tables");
297 
298  if (lock_tables_check(thd, tables, count, flags))
299  DBUG_RETURN(NULL);
300 
301  if (! (sql_lock= get_lock_data(thd, tables, count, GET_LOCK_STORE_LOCKS)))
302  DBUG_RETURN(NULL);
303 
304  THD_STAGE_INFO(thd, stage_system_lock);
305  DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
306  if (sql_lock->table_count && lock_external(thd, sql_lock->table,
307  sql_lock->table_count))
308  {
309  /* Clear the lock type of all lock data to avoid reusage. */
310  reset_lock_data_and_free(&sql_lock);
311  goto end;
312  }
313 
314  /* Copy the lock data array. thr_multi_lock() reorders its contents. */
315  memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks,
316  sql_lock->lock_count * sizeof(*sql_lock->locks));
317  /* Lock on the copied half of the lock data array. */
318  rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks +
319  sql_lock->lock_count,
320  sql_lock->lock_count,
321  &thd->lock_info, timeout)];
322  if (rc)
323  {
324  if (sql_lock->table_count)
325  (void) unlock_external(thd, sql_lock->table, sql_lock->table_count);
326  reset_lock_data_and_free(&sql_lock);
327  if (! thd->killed)
328  my_error(rc, MYF(0));
329  }
330 end:
331  if (!(flags & MYSQL_OPEN_IGNORE_KILLED) && thd->killed)
332  {
333  thd->send_kill_message();
334  if (sql_lock)
335  {
336  mysql_unlock_tables(thd, sql_lock);
337  sql_lock= 0;
338  }
339  }
340 
341  thd->set_time_after_lock();
342  DBUG_RETURN(sql_lock);
343 }
344 
345 
346 static int lock_external(THD *thd, TABLE **tables, uint count)
347 {
348  reg1 uint i;
349  int lock_type,error;
350  DBUG_ENTER("lock_external");
351 
352  DBUG_PRINT("info", ("count %d", count));
353  for (i=1 ; i <= count ; i++, tables++)
354  {
355  DBUG_ASSERT((*tables)->reginfo.lock_type >= TL_READ);
356  lock_type=F_WRLCK; /* Lock exclusive */
357  if ((*tables)->db_stat & HA_READ_ONLY ||
358  ((*tables)->reginfo.lock_type >= TL_READ &&
359  (*tables)->reginfo.lock_type <= TL_READ_NO_INSERT))
360  lock_type=F_RDLCK;
361 
362  if ((error=(*tables)->file->ha_external_lock(thd,lock_type)))
363  {
364  print_lock_error(error, (*tables)->file->table_type());
365  while (--i)
366  {
367  tables--;
368  (*tables)->file->ha_external_lock(thd, F_UNLCK);
369  (*tables)->current_lock=F_UNLCK;
370  }
371  DBUG_RETURN(error);
372  }
373  else
374  {
375  (*tables)->db_stat &= ~ HA_BLOCK_LOCK;
376  (*tables)->current_lock= lock_type;
377  }
378  }
379  DBUG_RETURN(0);
380 }
381 
382 
383 void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
384 {
385  DBUG_ENTER("mysql_unlock_tables");
386  if (sql_lock->lock_count)
387  thr_multi_unlock(sql_lock->locks,sql_lock->lock_count);
388  if (sql_lock->table_count)
389  (void) unlock_external(thd,sql_lock->table,sql_lock->table_count);
390  my_free(sql_lock);
391  DBUG_VOID_RETURN;
392 }
393 
400 void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count)
401 {
402  MYSQL_LOCK *sql_lock;
403  if ((sql_lock= get_lock_data(thd, table, count, GET_LOCK_UNLOCK)))
404  mysql_unlock_tables(thd, sql_lock);
405 }
406 
407 
412 void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
413 {
414  uint i,found;
415  DBUG_ENTER("mysql_unlock_read_tables");
416 
417  /* Move all write locks first */
418  THR_LOCK_DATA **lock=sql_lock->locks;
419  for (i=found=0 ; i < sql_lock->lock_count ; i++)
420  {
421  if (sql_lock->locks[i]->type > TL_WRITE_ALLOW_WRITE)
422  {
423  swap_variables(THR_LOCK_DATA *, *lock, sql_lock->locks[i]);
424  lock++;
425  found++;
426  }
427  }
428  /* unlock the read locked tables */
429  if (i != found)
430  {
431  thr_multi_unlock(lock,i-found);
432  sql_lock->lock_count= found;
433  }
434 
435  /* Then do the same for the external locks */
436  /* Move all write locked tables first */
437  TABLE **table=sql_lock->table;
438  for (i=found=0 ; i < sql_lock->table_count ; i++)
439  {
440  DBUG_ASSERT(sql_lock->table[i]->lock_position == i);
441  if ((uint) sql_lock->table[i]->reginfo.lock_type > TL_WRITE_ALLOW_WRITE)
442  {
443  swap_variables(TABLE *, *table, sql_lock->table[i]);
444  table++;
445  found++;
446  }
447  }
448  /* Unlock all read locked tables */
449  if (i != found)
450  {
451  (void) unlock_external(thd,table,i-found);
452  sql_lock->table_count=found;
453  }
454  /* Fix the lock positions in TABLE */
455  table= sql_lock->table;
456  found= 0;
457  for (i= 0; i < sql_lock->table_count; i++)
458  {
459  TABLE *tbl= *table;
460  tbl->lock_position= (uint) (table - sql_lock->table);
461  tbl->lock_data_start= found;
462  found+= tbl->lock_count;
463  table++;
464  }
465  DBUG_VOID_RETURN;
466 }
467 
468 
479 void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table)
480 {
481  if (locked)
482  {
483  reg1 uint i;
484  for (i=0; i < locked->table_count; i++)
485  {
486  if (locked->table[i] == table)
487  {
488  uint j, removed_locks, old_tables;
489  TABLE *tbl;
490  uint lock_data_end;
491 
492  DBUG_ASSERT(table->lock_position == i);
493 
494  /* Unlock the table. */
495  mysql_unlock_some_tables(thd, &table, /* table count */ 1);
496 
497  /* Decrement table_count in advance, making below expressions easier */
498  old_tables= --locked->table_count;
499 
500  /* The table has 'removed_locks' lock data elements in locked->locks */
501  removed_locks= table->lock_count;
502 
503  /* Move down all table pointers above 'i'. */
504  bmove((char*) (locked->table+i),
505  (char*) (locked->table+i+1),
506  (old_tables - i) * sizeof(TABLE*));
507 
508  lock_data_end= table->lock_data_start + table->lock_count;
509  /* Move down all lock data pointers above 'table->lock_data_end-1' */
510  bmove((char*) (locked->locks + table->lock_data_start),
511  (char*) (locked->locks + lock_data_end),
512  (locked->lock_count - lock_data_end) *
513  sizeof(THR_LOCK_DATA*));
514 
515  /*
516  Fix moved table elements.
517  lock_position is the index in the 'locked->table' array,
518  it must be fixed by one.
519  table->lock_data_start is pointer to the lock data for this table
520  in the 'locked->locks' array, they must be fixed by 'removed_locks',
521  the lock data count of the removed table.
522  */
523  for (j= i ; j < old_tables; j++)
524  {
525  tbl= locked->table[j];
526  tbl->lock_position--;
527  DBUG_ASSERT(tbl->lock_position == j);
528  tbl->lock_data_start-= removed_locks;
529  }
530 
531  /* Finally adjust lock_count. */
532  locked->lock_count-= removed_locks;
533  break;
534  }
535  }
536  }
537 }
538 
539 
542 void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
543 {
544  MYSQL_LOCK *locked;
545  DBUG_ENTER("mysql_lock_abort");
546 
547  if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK)))
548  {
549  for (uint i=0; i < locked->lock_count; i++)
550  thr_abort_locks(locked->locks[i]->lock, upgrade_lock);
551  my_free(locked);
552  }
553  DBUG_VOID_RETURN;
554 }
555 
556 
570 {
571  MYSQL_LOCK *locked;
572  bool result= FALSE;
573  DBUG_ENTER("mysql_lock_abort_for_thread");
574 
575  if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK)))
576  {
577  for (uint i=0; i < locked->lock_count; i++)
578  {
579  if (thr_abort_locks_for_thread(locked->locks[i]->lock,
580  table->in_use->thread_id))
581  result= TRUE;
582  }
583  my_free(locked);
584  }
585  DBUG_RETURN(result);
586 }
587 
588 
589 MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
590 {
591  MYSQL_LOCK *sql_lock;
592  TABLE **table, **end_table;
593  DBUG_ENTER("mysql_lock_merge");
594 
595  if (!(sql_lock= (MYSQL_LOCK*)
596  my_malloc(sizeof(*sql_lock)+
597  sizeof(THR_LOCK_DATA*)*(a->lock_count+b->lock_count)+
598  sizeof(TABLE*)*(a->table_count+b->table_count),MYF(MY_WME))))
599  DBUG_RETURN(0); // Fatal error
600  sql_lock->lock_count=a->lock_count+b->lock_count;
601  sql_lock->table_count=a->table_count+b->table_count;
602  sql_lock->locks=(THR_LOCK_DATA**) (sql_lock+1);
603  sql_lock->table=(TABLE**) (sql_lock->locks+sql_lock->lock_count);
604  memcpy(sql_lock->locks,a->locks,a->lock_count*sizeof(*a->locks));
605  memcpy(sql_lock->locks+a->lock_count,b->locks,
606  b->lock_count*sizeof(*b->locks));
607  memcpy(sql_lock->table,a->table,a->table_count*sizeof(*a->table));
608  memcpy(sql_lock->table+a->table_count,b->table,
609  b->table_count*sizeof(*b->table));
610 
611  /*
612  Now adjust lock_position and lock_data_start for all objects that was
613  moved in 'b' (as there is now all objects in 'a' before these).
614  */
615  for (table= sql_lock->table + a->table_count,
616  end_table= table + b->table_count;
617  table < end_table;
618  table++)
619  {
620  (*table)->lock_position+= a->table_count;
621  (*table)->lock_data_start+= a->lock_count;
622  }
623 
624  /* Delete old, not needed locks */
625  my_free(a);
626  my_free(b);
627 
628  thr_lock_merge_status(sql_lock->locks, sql_lock->lock_count);
629  DBUG_RETURN(sql_lock);
630 }
631 
632 
635 static int unlock_external(THD *thd, TABLE **table,uint count)
636 {
637  int error,error_code;
638  DBUG_ENTER("unlock_external");
639 
640  error_code=0;
641  do
642  {
643  if ((*table)->current_lock != F_UNLCK)
644  {
645  (*table)->current_lock = F_UNLCK;
646  if ((error=(*table)->file->ha_external_lock(thd, F_UNLCK)))
647  {
648  error_code=error;
649  print_lock_error(error_code, (*table)->file->table_type());
650  }
651  }
652  table++;
653  } while (--count);
654  DBUG_RETURN(error_code);
655 }
656 
657 
668 static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
669  uint flags)
670 {
671  uint i,tables,lock_count;
672  MYSQL_LOCK *sql_lock;
673  THR_LOCK_DATA **locks, **locks_buf, **locks_start;
674  TABLE **to, **table_buf;
675  DBUG_ENTER("get_lock_data");
676 
677  DBUG_ASSERT((flags == GET_LOCK_UNLOCK) || (flags == GET_LOCK_STORE_LOCKS));
678  DBUG_PRINT("info", ("count %d", count));
679 
680  for (i=tables=lock_count=0 ; i < count ; i++)
681  {
682  TABLE *t= table_ptr[i];
683 
684  if (t->s->tmp_table != NON_TRANSACTIONAL_TMP_TABLE)
685  {
686  tables+= t->file->lock_count();
687  lock_count++;
688  }
689  }
690 
691  /*
692  Allocating twice the number of pointers for lock data for use in
693  thr_mulit_lock(). This function reorders the lock data, but cannot
694  update the table values. So the second part of the array is copied
695  from the first part immediately before calling thr_multi_lock().
696  */
697  if (!(sql_lock= (MYSQL_LOCK*)
698  my_malloc(sizeof(*sql_lock) +
699  sizeof(THR_LOCK_DATA*) * tables * 2 +
700  sizeof(table_ptr) * lock_count,
701  MYF(0))))
702  DBUG_RETURN(0);
703  locks= locks_buf= sql_lock->locks= (THR_LOCK_DATA**) (sql_lock + 1);
704  to= table_buf= sql_lock->table= (TABLE**) (locks + tables * 2);
705  sql_lock->table_count=lock_count;
706 
707  for (i=0 ; i < count ; i++)
708  {
709  TABLE *table;
710  enum thr_lock_type lock_type;
711  THR_LOCK_DATA **org_locks = locks;
712 
713  if ((table=table_ptr[i])->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
714  continue;
715  lock_type= table->reginfo.lock_type;
716  DBUG_ASSERT(lock_type != TL_WRITE_DEFAULT && lock_type != TL_READ_DEFAULT);
717  locks_start= locks;
718  locks= table->file->store_lock(thd, locks,
719  (flags & GET_LOCK_UNLOCK) ? TL_IGNORE :
720  lock_type);
721  if (flags & GET_LOCK_STORE_LOCKS)
722  {
723  table->lock_position= (uint) (to - table_buf);
724  table->lock_data_start= (uint) (locks_start - locks_buf);
725  table->lock_count= (uint) (locks - locks_start);
726  }
727  *to++= table;
728  if (locks)
729  {
730  for ( ; org_locks != locks ; org_locks++)
731  {
732  (*org_locks)->debug_print_param= (void *) table;
733  (*org_locks)->m_psi= table->file->m_psi;
734  }
735  }
736  }
737  /*
738  We do not use 'tables', because there are cases where store_lock()
739  returns less locks than lock_count() claimed. This can happen when
740  a FLUSH TABLES tries to abort locks from a MERGE table of another
741  thread. When that thread has just opened the table, but not yet
742  attached its children, it cannot return the locks. lock_count()
743  always returns the number of locks that an attached table has.
744  This is done to avoid the reverse situation: If lock_count() would
745  return 0 for a non-attached MERGE table, and that table becomes
746  attached between the calls to lock_count() and store_lock(), then
747  we would have allocated too little memory for the lock data. Now
748  we may allocate too much, but better safe than memory overrun.
749  And in the FLUSH case, the memory is released quickly anyway.
750  */
751  sql_lock->lock_count= locks - locks_buf;
752  DBUG_PRINT("info", ("sql_lock->table_count %d sql_lock->lock_count %d",
753  sql_lock->table_count, sql_lock->lock_count));
754  DBUG_RETURN(sql_lock);
755 }
756 
757 
775 bool lock_schema_name(THD *thd, const char *db)
776 {
777  MDL_request_list mdl_requests;
778  MDL_request global_request;
779  MDL_request mdl_request;
780 
781  if (thd->locked_tables_mode)
782  {
783  my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
784  ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
785  return TRUE;
786  }
787 
788  if (thd->global_read_lock.can_acquire_protection())
789  return TRUE;
790  global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE,
791  MDL_STATEMENT);
792  mdl_request.init(MDL_key::SCHEMA, db, "", MDL_EXCLUSIVE, MDL_TRANSACTION);
793 
794  mdl_requests.push_front(&mdl_request);
795  mdl_requests.push_front(&global_request);
796 
797  if (thd->mdl_context.acquire_locks(&mdl_requests,
798  thd->variables.lock_wait_timeout))
799  return TRUE;
800 
801  DEBUG_SYNC(thd, "after_wait_locked_schema_name");
802  return FALSE;
803 }
804 
805 
830  const char *db, const char *name)
831 {
832  MDL_request_list mdl_requests;
833  MDL_request global_request;
834  MDL_request schema_request;
835  MDL_request mdl_request;
836 
837  if (thd->locked_tables_mode)
838  {
839  my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
840  ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
841  return TRUE;
842  }
843 
844  DBUG_ASSERT(name);
845  DEBUG_SYNC(thd, "before_wait_locked_pname");
846 
847  if (thd->global_read_lock.can_acquire_protection())
848  return TRUE;
849  global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE,
850  MDL_STATEMENT);
851  schema_request.init(MDL_key::SCHEMA, db, "", MDL_INTENTION_EXCLUSIVE,
852  MDL_TRANSACTION);
853  mdl_request.init(mdl_type, db, name, MDL_EXCLUSIVE, MDL_TRANSACTION);
854 
855  mdl_requests.push_front(&mdl_request);
856  mdl_requests.push_front(&schema_request);
857  mdl_requests.push_front(&global_request);
858 
859  if (thd->mdl_context.acquire_locks(&mdl_requests,
860  thd->variables.lock_wait_timeout))
861  return TRUE;
862 
863  DEBUG_SYNC(thd, "after_wait_locked_pname");
864  return FALSE;
865 }
866 
867 
868 static void print_lock_error(int error, const char *table)
869 {
870  DBUG_ENTER("print_lock_error");
871 
872  switch (error) {
873  case HA_ERR_LOCK_WAIT_TIMEOUT:
874  my_error(ER_LOCK_WAIT_TIMEOUT, MYF(ME_BELL+ME_OLDWIN+ME_WAITTANG), error);
875  break;
876  case HA_ERR_READ_ONLY_TRANSACTION:
877  my_error(ER_READ_ONLY_TRANSACTION, MYF(ME_BELL+ME_OLDWIN+ME_WAITTANG),
878  error);
879  break;
880  case HA_ERR_LOCK_DEADLOCK:
881  my_error(ER_LOCK_DEADLOCK, MYF(ME_BELL+ME_OLDWIN+ME_WAITTANG), error);
882  break;
883  case HA_ERR_WRONG_COMMAND:
884  my_error(ER_ILLEGAL_HA, MYF(ME_BELL+ME_OLDWIN+ME_WAITTANG), table);
885  break;
886  default:
887  {
888  char errbuf[MYSYS_STRERROR_SIZE];
889  my_error(ER_CANT_LOCK, MYF(ME_BELL+ME_OLDWIN+ME_WAITTANG),
890  error, my_strerror(errbuf, sizeof(errbuf), error));
891  }
892  break;
893  }
894 
895  DBUG_VOID_RETURN;
896 }
897 
898 
899 /****************************************************************************
900  Handling of global read locks
901 
902  Global read lock is implemented using metadata lock infrastructure.
903 
904  Taking the global read lock is TWO steps (2nd step is optional; without
905  it, COMMIT of existing transactions will be allowed):
906  lock_global_read_lock() THEN make_global_read_lock_block_commit().
907 
908  How blocking of threads by global read lock is achieved: that's
909  semi-automatic. We assume that any statement which should be blocked
910  by global read lock will either open and acquires write-lock on tables
911  or acquires metadata locks on objects it is going to modify. For any
912  such statement global IX metadata lock is automatically acquired for
913  its duration (in case of LOCK TABLES until end of LOCK TABLES mode).
914  And lock_global_read_lock() simply acquires global S metadata lock
915  and thus prohibits execution of statements which modify data (unless
916  they modify only temporary tables). If deadlock happens it is detected
917  by MDL subsystem and resolved in the standard fashion (by backing-off
918  metadata locks acquired so far and restarting open tables process
919  if possible).
920 
921  Why does FLUSH TABLES WITH READ LOCK need to block COMMIT: because it's used
922  to read a non-moving SHOW MASTER STATUS, and a COMMIT writes to the binary
923  log.
924 
925  Why getting the global read lock is two steps and not one. Because FLUSH
926  TABLES WITH READ LOCK needs to insert one other step between the two:
927  flushing tables. So the order is
928  1) lock_global_read_lock() (prevents any new table write locks, i.e. stalls
929  all new updates)
930  2) close_cached_tables() (the FLUSH TABLES), which will wait for tables
931  currently opened and being updated to close (so it's possible that there is
932  a moment where all new updates of server are stalled *and* FLUSH TABLES WITH
933  READ LOCK is, too).
934  3) make_global_read_lock_block_commit().
935  If we have merged 1) and 3) into 1), we would have had this deadlock:
936  imagine thread 1 and 2, in non-autocommit mode, thread 3, and an InnoDB
937  table t.
938  thd1: SELECT * FROM t FOR UPDATE;
939  thd2: UPDATE t SET a=1; # blocked by row-level locks of thd1
940  thd3: FLUSH TABLES WITH READ LOCK; # blocked in close_cached_tables() by the
941  table instance of thd2
942  thd1: COMMIT; # blocked by thd3.
943  thd1 blocks thd2 which blocks thd3 which blocks thd1: deadlock.
944 
945  Note that we need to support that one thread does
946  FLUSH TABLES WITH READ LOCK; and then COMMIT;
947  (that's what innobackup does, for some good reason).
948  So in this exceptional case the COMMIT should not be blocked by the FLUSH
949  TABLES WITH READ LOCK.
950 
951 ****************************************************************************/
952 
966 bool Global_read_lock::lock_global_read_lock(THD *thd)
967 {
968  DBUG_ENTER("lock_global_read_lock");
969 
970  if (!m_state)
971  {
972  MDL_request mdl_request;
973 
974  DBUG_ASSERT(! thd->mdl_context.is_lock_owner(MDL_key::GLOBAL, "", "",
975  MDL_SHARED));
976  mdl_request.init(MDL_key::GLOBAL, "", "", MDL_SHARED, MDL_EXPLICIT);
977 
978  if (thd->mdl_context.acquire_lock(&mdl_request,
979  thd->variables.lock_wait_timeout))
980  DBUG_RETURN(1);
981 
982  m_mdl_global_shared_lock= mdl_request.ticket;
983  m_state= GRL_ACQUIRED;
984  }
985  /*
986  We DON'T set global_read_lock_blocks_commit now, it will be set after
987  tables are flushed (as the present function serves for FLUSH TABLES WITH
988  READ LOCK only). Doing things in this order is necessary to avoid
989  deadlocks (we must allow COMMIT until all tables are closed; we should not
990  forbid it before, or we can have a 3-thread deadlock if 2 do SELECT FOR
991  UPDATE and one does FLUSH TABLES WITH READ LOCK).
992  */
993  DBUG_RETURN(0);
994 }
995 
996 
1007 void Global_read_lock::unlock_global_read_lock(THD *thd)
1008 {
1009  DBUG_ENTER("unlock_global_read_lock");
1010 
1011  DBUG_ASSERT(m_mdl_global_shared_lock && m_state);
1012 
1013  if (m_mdl_blocks_commits_lock)
1014  {
1015  thd->mdl_context.release_lock(m_mdl_blocks_commits_lock);
1016  m_mdl_blocks_commits_lock= NULL;
1017  }
1018  thd->mdl_context.release_lock(m_mdl_global_shared_lock);
1019  m_mdl_global_shared_lock= NULL;
1020  m_state= GRL_NONE;
1021 
1022  DBUG_VOID_RETURN;
1023 }
1024 
1025 
1041 bool Global_read_lock::make_global_read_lock_block_commit(THD *thd)
1042 {
1043  MDL_request mdl_request;
1044  DBUG_ENTER("make_global_read_lock_block_commit");
1045  /*
1046  If we didn't succeed lock_global_read_lock(), or if we already suceeded
1047  make_global_read_lock_block_commit(), do nothing.
1048  */
1049  if (m_state != GRL_ACQUIRED)
1050  DBUG_RETURN(0);
1051 
1052  mdl_request.init(MDL_key::COMMIT, "", "", MDL_SHARED, MDL_EXPLICIT);
1053 
1054  if (thd->mdl_context.acquire_lock(&mdl_request,
1055  thd->variables.lock_wait_timeout))
1056  DBUG_RETURN(TRUE);
1057 
1058  m_mdl_blocks_commits_lock= mdl_request.ticket;
1059  m_state= GRL_ACQUIRED_AND_BLOCKS_COMMIT;
1060 
1061  DBUG_RETURN(FALSE);
1062 }
1063 
1064 
1071 void Global_read_lock::set_explicit_lock_duration(THD *thd)
1072 {
1073  if (m_mdl_global_shared_lock)
1074  thd->mdl_context.set_lock_duration(m_mdl_global_shared_lock, MDL_EXPLICIT);
1075  if (m_mdl_blocks_commits_lock)
1076  thd->mdl_context.set_lock_duration(m_mdl_blocks_commits_lock, MDL_EXPLICIT);
1077 }
1078