~jlukas79/+junk/mysql-server

« back to all changes in this revision

Viewing changes to sql/lock.cc

manual merge 6.0-main --> 6.0-bka-review

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
      This is followed by a call to thr_multi_lock() for all tables.
35
35
 
36
36
  - When statement is done, we call mysql_unlock_tables().
37
 
    This will call thr_multi_unlock() followed by
38
 
    table_handler->external_lock(thd, F_UNLCK) for each table.
 
37
    table_handler->external_lock(thd, F_UNLCK) followed by
 
38
    thr_multi_unlock() for each table.
39
39
 
40
40
  - Note that mysql_unlock_tables() may be called several times as
41
41
    MySQL in some cases can free some tables earlier than others.
94
94
static int unlock_external(THD *thd, TABLE **table,uint count);
95
95
static void print_lock_error(int error, const char *);
96
96
 
97
 
/*
98
 
  Lock tables.
99
 
 
100
 
  SYNOPSIS
101
 
    mysql_lock_tables()
102
 
    thd                         The current thread.
103
 
    tables                      An array of pointers to the tables to lock.
104
 
    count                       The number of tables to lock.
105
 
    flags                       Options:
106
 
      MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK      Ignore a global read lock
107
 
      MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY      Ignore SET GLOBAL READ_ONLY
108
 
      MYSQL_LOCK_IGNORE_FLUSH                 Ignore a flush tables.
109
 
      MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN        Instead of reopening altered
110
 
                                              or dropped tables by itself,
111
 
                                              mysql_lock_tables() should
112
 
                                              notify upper level and rely
113
 
                                              on caller doing this.
114
 
    need_reopen                 Out parameter, TRUE if some tables were altered
115
 
                                or deleted and should be reopened by caller.
116
 
 
117
 
  RETURN
118
 
    A lock structure pointer on success.
119
 
    NULL on error or if some tables should be reopen.
120
 
*/
121
 
 
122
97
/* Map the return value of thr_lock to an error from errmsg.txt */
123
98
static int thr_lock_errno_to_mysql[]=
124
99
{ 0, 1, ER_LOCK_WAIT_TIMEOUT, ER_LOCK_DEADLOCK };
232
207
}
233
208
 
234
209
 
 
210
/**
 
211
   Lock tables.
 
212
 
 
213
   @param thd          The current thread.
 
214
   @param tables       An array of pointers to the tables to lock.
 
215
   @param count        The number of tables to lock.
 
216
   @param flags        Options:
 
217
                 MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK Ignore a global read lock
 
218
                 MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY Ignore SET GLOBAL READ_ONLY
 
219
                 MYSQL_LOCK_IGNORE_FLUSH            Ignore a flush tables.
 
220
   @param need_reopen  Out parameter, TRUE if some tables were altered
 
221
                       or deleted and should be reopened by caller.
 
222
 
 
223
   @note Caller of this function should always be ready to handle request to
 
224
         reopen table unless there are external invariants which guarantee
 
225
         that such thing won't be needed (for example we are obtaining lock
 
226
         on table on which we already have exclusive metadata lock).
 
227
 
 
228
   @retval  A lock structure pointer on success.
 
229
   @retval  NULL on error or if some tables should be reopen.
 
230
*/
 
231
 
235
232
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
236
233
                              uint flags, bool *need_reopen)
237
234
{
310
307
    if (rc > 1)                                 /* a timeout or a deadlock */
311
308
    {
312
309
      if (sql_lock->table_count)
313
 
        VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count));
 
310
        (void) unlock_external(thd, sql_lock->table, sql_lock->table_count);
314
311
      reset_lock_data_and_free(&sql_lock);
315
312
      my_error(rc, MYF(0));
316
313
      break;
317
314
    }
318
 
    else if (rc == 1)                           /* aborted */
 
315
    else if (rc == 1)                           /* aborted or killed */
319
316
    {
320
317
      thd->some_tables_deleted=1;               // Try again
321
318
      sql_lock->lock_count= 0;                  // Locks are already freed
324
321
    else if (!thd->some_tables_deleted || (flags & MYSQL_LOCK_IGNORE_FLUSH))
325
322
    {
326
323
      /*
327
 
        Thread was killed or lock aborted. Let upper level close all
328
 
        used tables and retry or give error.
 
324
        Success and nobody set thd->some_tables_deleted to force reopen
 
325
        or we were called with MYSQL_LOCK_IGNORE_FLUSH so such attempts
 
326
        should be ignored.
329
327
      */
330
328
      break;
331
329
    }
342
340
        thr_multi_unlock(sql_lock->locks, sql_lock->lock_count);
343
341
 
344
342
    if (sql_lock->table_count)
345
 
      VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count));
 
343
      (void) unlock_external(thd, sql_lock->table, sql_lock->table_count);
346
344
 
347
345
    /*
348
346
      If thr_multi_lock fails it resets lock type for tables, which
351
349
    */
352
350
    reset_lock_data_and_free(&sql_lock);
353
351
retry:
354
 
    if (flags & MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN)
355
 
    {
356
 
      *need_reopen= TRUE;
357
 
      break;
358
 
    }
359
 
    if (wait_for_tables(thd))
360
 
      break;                                    // Couldn't open tables
 
352
    DEBUG_SYNC(thd, "mysql_lock_retry");
 
353
    /* Let upper level close all used tables and retry or give error. */
 
354
    *need_reopen= TRUE;
 
355
    break;
361
356
  }
362
357
  thd_proc_info(thd, 0);
363
358
  if (thd->killed)
415
410
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
416
411
{
417
412
  DBUG_ENTER("mysql_unlock_tables");
 
413
  if (sql_lock->table_count)
 
414
    (void)(unlock_external(thd,sql_lock->table,sql_lock->table_count));
418
415
  if (sql_lock->lock_count)
419
416
    thr_multi_unlock(sql_lock->locks,sql_lock->lock_count);
420
 
  if (sql_lock->table_count)
421
 
    VOID(unlock_external(thd,sql_lock->table,sql_lock->table_count));
422
417
  my_free((uchar*) sql_lock,MYF(0));
423
418
  DBUG_VOID_RETURN;
424
419
}
482
477
  /* Unlock all read locked tables */
483
478
  if (i != found)
484
479
  {
485
 
    VOID(unlock_external(thd,table,i-found));
 
480
    (void) unlock_external(thd,table,i-found);
486
481
    sql_lock->table_count=found;
487
482
  }
488
483
  /* Fix the lock positions in TABLE */
503
498
/**
504
499
  Try to find the table in the list of locked tables.
505
500
  In case of success, unlock the table and remove it from this list.
506
 
 
507
 
  @note This function has a legacy side effect: the table is
508
 
  unlocked even if it is not found in the locked list.
509
 
  It's not clear if this side effect is intentional or still
510
 
  desirable. It might lead to unmatched calls to
511
 
  unlock_external(). Moreover, a discrepancy can be left
512
 
  unnoticed by the storage engine, because in
513
 
  unlock_external() we call handler::external_lock(F_UNLCK) only
514
 
  if table->current_lock is not F_UNLCK.
 
501
  If a table has more than one lock instance, removes them all.
515
502
 
516
503
  @param  thd             thread context
517
504
  @param  locked          list of locked tables
518
505
  @param  table           the table to unlock
519
 
  @param  always_unlock   specify explicitly if the legacy side
520
 
                          effect is desired.
521
506
*/
522
507
 
523
 
void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table,
524
 
                       bool always_unlock)
 
508
void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table)
525
509
{
526
 
  if (always_unlock == TRUE)
527
 
    mysql_unlock_some_tables(thd, &table, /* table count */ 1);
528
510
  if (locked)
529
511
  {
530
512
    reg1 uint i;
538
520
 
539
521
        DBUG_ASSERT(table->lock_position == i);
540
522
 
541
 
        /* Unlock if not yet unlocked */
542
 
        if (always_unlock == FALSE)
543
 
          mysql_unlock_some_tables(thd, &table, /* table count */ 1);
 
523
        /* Unlock the table. */
 
524
        mysql_unlock_some_tables(thd, &table, /* table count */ 1);
544
525
 
545
526
        /* Decrement table_count in advance, making below expressions easier */
546
527
        old_tables= --locked->table_count;
692
673
  /* Delete old, not needed locks */
693
674
  my_free((uchar*) a,MYF(0));
694
675
  my_free((uchar*) b,MYF(0));
 
676
 
 
677
  thr_lock_merge_status(sql_lock->locks, sql_lock->lock_count);
695
678
  DBUG_RETURN(sql_lock);
696
679
}
697
680
 
745
728
    goto end;
746
729
 
747
730
  /* Get command lock or LOCK TABLES lock. Maybe empty for INSERT DELAYED. */
748
 
  if (! (mylock= thd->lock ? thd->lock : thd->locked_tables))
 
731
  if (! (mylock= thd->lock))
749
732
    goto end;
750
733
 
751
734
  /* If we have less than two tables, we cannot have duplicates. */
940
923
*****************************************************************************/
941
924
 
942
925
/**
943
 
  Lock and wait for the named lock.
944
 
 
945
 
  @param thd                    Thread handler
946
 
  @param table_list             Lock first table in this list
947
 
 
948
 
 
949
 
  @note
950
 
    Works together with global read lock.
951
 
 
952
 
  @retval
953
 
    0   ok
954
 
  @retval
955
 
    1   error
956
 
*/
957
 
 
958
 
int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list)
959
 
{
960
 
  int lock_retcode;
961
 
  int error= -1;
962
 
  DBUG_ENTER("lock_and_wait_for_table_name");
963
 
 
964
 
  if (wait_if_global_read_lock(thd, 0, 1))
965
 
    DBUG_RETURN(1);
966
 
  VOID(pthread_mutex_lock(&LOCK_open));
967
 
  if ((lock_retcode = lock_table_name(thd, table_list, TRUE)) < 0)
968
 
    goto end;
969
 
  if (lock_retcode && wait_for_locked_table_names(thd, table_list))
970
 
  {
971
 
    unlock_table_name(thd, table_list);
972
 
    goto end;
973
 
  }
974
 
  error=0;
975
 
 
976
 
end:
977
 
  pthread_mutex_unlock(&LOCK_open);
978
 
  start_waiting_global_read_lock(thd);
979
 
  DBUG_RETURN(error);
980
 
}
981
 
 
982
 
 
983
 
/**
984
 
  Put a not open table with an old refresh version in the table cache.
985
 
 
986
 
  @param thd                    Thread handler
987
 
  @param table_list             Lock first table in this list
988
 
  @param check_in_use           Do we need to check if table already in use by us
989
 
 
990
 
  @note
991
 
    One must have a lock on LOCK_open!
992
 
 
993
 
  @warning
994
 
    If you are going to update the table, you should use
995
 
    lock_and_wait_for_table_name instead of this function as this works
996
 
    together with 'FLUSH TABLES WITH READ LOCK'
997
 
 
998
 
  @note
999
 
    This will force any other threads that uses the table to release it
1000
 
    as soon as possible.
1001
 
 
1002
 
  @return
1003
 
    < 0 error
1004
 
  @return
1005
 
    == 0 table locked
1006
 
  @return
1007
 
    > 0  table locked, but someone is using it
1008
 
*/
1009
 
 
1010
 
int lock_table_name(THD *thd, TABLE_LIST *table_list, bool check_in_use)
1011
 
{
1012
 
  TABLE *table;
1013
 
  char  key[MAX_DBKEY_LENGTH];
1014
 
  char *db= table_list->db;
1015
 
  uint  key_length;
1016
 
  bool  found_locked_table= FALSE;
1017
 
  HASH_SEARCH_STATE state;
1018
 
  DBUG_ENTER("lock_table_name");
1019
 
  DBUG_PRINT("enter",("db: %s  name: %s", db, table_list->table_name));
1020
 
 
1021
 
  key_length= create_table_def_key(thd, key, table_list, 0);
1022
 
 
1023
 
  if (check_in_use)
1024
 
  {
1025
 
    /* Only insert the table if we haven't insert it already */
1026
 
    for (table=(TABLE*) hash_first(&open_cache, (uchar*)key,
1027
 
                                   key_length, &state);
1028
 
         table ;
1029
 
         table = (TABLE*) hash_next(&open_cache,(uchar*) key,
1030
 
                                    key_length, &state))
1031
 
    {
1032
 
      if (table->reginfo.lock_type < TL_WRITE)
1033
 
      {
1034
 
        if (table->in_use == thd)
1035
 
          found_locked_table= TRUE;
1036
 
        continue;
1037
 
      }
1038
 
 
1039
 
      if (table->in_use == thd)
1040
 
      {
1041
 
        DBUG_PRINT("info", ("Table is in use"));
1042
 
        table->s->version= 0;                  // Ensure no one can use this
1043
 
        table->locked_by_name= 1;
1044
 
        DBUG_RETURN(0);
1045
 
      }
1046
 
    }
1047
 
  }
1048
 
 
1049
 
  if (thd->locked_tables && thd->locked_tables->table_count &&
1050
 
      ! find_temporary_table(thd, table_list->db, table_list->table_name))
1051
 
  {
1052
 
    if (found_locked_table)
1053
 
      my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table_list->alias);
1054
 
    else
1055
 
      my_error(ER_TABLE_NOT_LOCKED, MYF(0), table_list->alias);
1056
 
 
1057
 
    DBUG_RETURN(-1);
1058
 
  }
1059
 
 
1060
 
  if (!(table= table_cache_insert_placeholder(thd, key, key_length)))
1061
 
    DBUG_RETURN(-1);
1062
 
 
1063
 
  table_list->table=table;
1064
 
 
1065
 
  /* Return 1 if table is in use */
1066
 
  DBUG_RETURN(test(remove_table_from_cache(thd, db, table_list->table_name,
1067
 
             check_in_use ? RTFC_NO_FLAG : RTFC_WAIT_OTHER_THREAD_FLAG)));
1068
 
}
1069
 
 
1070
 
 
1071
 
void unlock_table_name(THD *thd, TABLE_LIST *table_list)
1072
 
{
1073
 
  if (table_list->table)
1074
 
  {
1075
 
    hash_delete(&open_cache, (uchar*) table_list->table);
1076
 
    broadcast_refresh();
1077
 
  }
1078
 
}
1079
 
 
1080
 
 
1081
 
static bool locked_named_table(THD *thd, TABLE_LIST *table_list)
1082
 
{
1083
 
  for (; table_list ; table_list=table_list->next_local)
1084
 
  {
1085
 
    TABLE *table= table_list->table;
1086
 
    if (table)
1087
 
    {
1088
 
      TABLE *save_next= table->next;
1089
 
      bool result;
1090
 
      table->next= 0;
1091
 
      result= table_is_used(table_list->table, 0);
1092
 
      table->next= save_next;
1093
 
      if (result)
1094
 
        return 1;
1095
 
    }
1096
 
  }
1097
 
  return 0;                                     // All tables are locked
1098
 
}
1099
 
 
1100
 
 
1101
 
bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list)
1102
 
{
1103
 
  bool result=0;
1104
 
  DBUG_ENTER("wait_for_locked_table_names");
1105
 
 
1106
 
  safe_mutex_assert_owner(&LOCK_open);
1107
 
 
1108
 
  while (locked_named_table(thd,table_list))
1109
 
  {
1110
 
    if (thd->killed)
1111
 
    {
1112
 
      result=1;
1113
 
      break;
1114
 
    }
1115
 
    wait_for_condition(thd, &LOCK_open, &COND_refresh);
1116
 
    pthread_mutex_lock(&LOCK_open);
1117
 
  }
1118
 
  DBUG_RETURN(result);
1119
 
}
1120
 
 
1121
 
 
1122
 
/**
1123
 
  Lock all tables in list with a name lock.
1124
 
 
1125
 
  REQUIREMENTS
1126
 
  - One must have a lock on LOCK_open when calling this
1127
 
 
1128
 
  @param thd                    Thread handle
1129
 
  @param table_list             Names of tables to lock
1130
 
 
1131
 
  @note
1132
 
    If you are just locking one table, you should use
1133
 
    lock_and_wait_for_table_name().
1134
 
 
1135
 
  @retval
1136
 
    0   ok
1137
 
  @retval
1138
 
    1   Fatal error (end of memory ?)
 
926
   Obtain exclusive metadata locks on the list of tables.
 
927
 
 
928
   @param thd         Thread handle
 
929
   @param table_list  List of tables to lock
 
930
 
 
931
   @note This function assumes that no metadata locks were acquired
 
932
         before calling it. Also it cannot be called while holding
 
933
         LOCK_open mutex. Both these invariants are enforced by asserts
 
934
         in mdl_acquire_exclusive_locks() functions.
 
935
 
 
936
   @retval FALSE  Success.
 
937
   @retval TRUE   Failure (OOM or thread was killed).
1139
938
*/
1140
939
 
1141
940
bool lock_table_names(THD *thd, TABLE_LIST *table_list)
1142
941
{
1143
 
  bool got_all_locks=1;
1144
942
  TABLE_LIST *lock_table;
 
943
  MDL_LOCK_DATA *mdl_lock_data;
1145
944
 
 
945
  DEBUG_SYNC(thd, "before_wait_locked_tname");
1146
946
  for (lock_table= table_list; lock_table; lock_table= lock_table->next_local)
1147
947
  {
1148
 
    int got_lock;
1149
 
    if ((got_lock=lock_table_name(thd,lock_table, TRUE)) < 0)
1150
 
      goto end;                                 // Fatal error
1151
 
    if (got_lock)
1152
 
      got_all_locks=0;                          // Someone is using table
 
948
    if (!(mdl_lock_data= mdl_alloc_lock(0, lock_table->db,
 
949
                                        lock_table->table_name,
 
950
                                        thd->mem_root)))
 
951
      goto end;
 
952
    mdl_set_lock_type(mdl_lock_data, MDL_EXCLUSIVE);
 
953
    mdl_add_lock(&thd->mdl_context, mdl_lock_data);
 
954
    lock_table->mdl_lock_data= mdl_lock_data;
1153
955
  }
1154
 
 
1155
 
  /* If some table was in use, wait until we got the lock */
1156
 
  if (!got_all_locks && wait_for_locked_table_names(thd, table_list))
 
956
  if (mdl_acquire_exclusive_locks(&thd->mdl_context))
1157
957
    goto end;
1158
958
  return 0;
1159
959
 
1160
960
end:
1161
 
  unlock_table_names(thd, table_list, lock_table);
 
961
  mdl_remove_all_locks(&thd->mdl_context);
1162
962
  return 1;
1163
963
}
1164
964
 
1165
965
 
1166
966
/**
1167
 
  Unlock all tables in list with a name lock.
1168
 
 
1169
 
  @param thd        Thread handle.
1170
 
  @param table_list Names of tables to lock.
1171
 
 
1172
 
  @note 
1173
 
    This function needs to be protected by LOCK_open. If we're 
1174
 
    under LOCK TABLES, this function does not work as advertised. Namely,
1175
 
    it does not exclude other threads from using this table and does not
1176
 
    put an exclusive name lock on this table into the table cache.
1177
 
 
1178
 
  @see lock_table_names
1179
 
  @see unlock_table_names
1180
 
 
1181
 
  @retval TRUE An error occured.
1182
 
  @retval FALSE Name lock successfully acquired.
1183
 
*/
1184
 
 
1185
 
bool lock_table_names_exclusively(THD *thd, TABLE_LIST *table_list)
1186
 
{
1187
 
  if (lock_table_names(thd, table_list))
1188
 
    return TRUE;
1189
 
 
1190
 
  /*
1191
 
    Upgrade the table name locks from semi-exclusive to exclusive locks.
1192
 
  */
1193
 
  for (TABLE_LIST *table= table_list; table; table= table->next_global)
1194
 
  {
1195
 
    if (table->table)
1196
 
      table->table->open_placeholder= 1;
1197
 
  }
1198
 
  return FALSE;
1199
 
}
1200
 
 
1201
 
 
1202
 
/**
1203
 
  Test is 'table' is protected by an exclusive name lock.
1204
 
 
1205
 
  @param[in] thd        The current thread handler
1206
 
  @param[in] table_list Table container containing the single table to be
1207
 
                        tested
1208
 
 
1209
 
  @note Needs to be protected by LOCK_open mutex.
1210
 
 
1211
 
  @return Error status code
1212
 
    @retval TRUE Table is protected
1213
 
    @retval FALSE Table is not protected
1214
 
*/
1215
 
 
1216
 
bool
1217
 
is_table_name_exclusively_locked_by_this_thread(THD *thd,
1218
 
                                                TABLE_LIST *table_list)
1219
 
{
1220
 
  char  key[MAX_DBKEY_LENGTH];
1221
 
  uint  key_length;
1222
 
 
1223
 
  key_length= create_table_def_key(thd, key, table_list, 0);
1224
 
 
1225
 
  return is_table_name_exclusively_locked_by_this_thread(thd, (uchar *)key,
1226
 
                                                         key_length);
1227
 
}
1228
 
 
1229
 
 
1230
 
/**
1231
 
  Test is 'table key' is protected by an exclusive name lock.
1232
 
 
1233
 
  @param[in] thd        The current thread handler.
1234
 
  @param[in] key
1235
 
  @param[in] key_length
1236
 
 
1237
 
  @note Needs to be protected by LOCK_open mutex
1238
 
 
1239
 
  @retval TRUE Table is protected
1240
 
  @retval FALSE Table is not protected
1241
 
 */
1242
 
 
1243
 
bool
1244
 
is_table_name_exclusively_locked_by_this_thread(THD *thd, uchar *key,
1245
 
                                                int key_length)
1246
 
{
1247
 
  HASH_SEARCH_STATE state;
1248
 
  TABLE *table;
1249
 
 
1250
 
  for (table= (TABLE*) hash_first(&open_cache, key,
1251
 
                                  key_length, &state);
1252
 
       table ;
1253
 
       table= (TABLE*) hash_next(&open_cache, key,
1254
 
                                 key_length, &state))
1255
 
  {
1256
 
    if (table->in_use == thd &&
1257
 
        table->open_placeholder == 1 &&
1258
 
        table->s->version == 0)
1259
 
      return TRUE;
1260
 
  }
1261
 
 
1262
 
  return FALSE;
1263
 
}
1264
 
 
1265
 
/**
1266
 
  Unlock all tables in list with a name lock.
1267
 
 
1268
 
  @param
1269
 
    thd                 Thread handle
1270
 
  @param
1271
 
    table_list          Names of tables to unlock
1272
 
  @param
1273
 
    last_table          Don't unlock any tables after this one.
1274
 
                                (default 0, which will unlock all tables)
1275
 
 
1276
 
  @note
1277
 
    One must have a lock on LOCK_open when calling this.
1278
 
 
1279
 
  @note
1280
 
    This function will broadcast refresh signals to inform other threads
1281
 
    that the name locks are removed.
1282
 
 
1283
 
  @retval
1284
 
    0   ok
1285
 
  @retval
1286
 
    1   Fatal error (end of memory ?)
1287
 
*/
1288
 
 
1289
 
void unlock_table_names(THD *thd, TABLE_LIST *table_list,
1290
 
                        TABLE_LIST *last_table)
 
967
   Release all metadata locks previously obtained by lock_table_names().
 
968
 
 
969
   @param thd  Thread handle.
 
970
 
 
971
   @note Cannot be called while holding LOCK_open mutex.
 
972
*/
 
973
 
 
974
void unlock_table_names(THD *thd)
1291
975
{
1292
976
  DBUG_ENTER("unlock_table_names");
1293
 
  for (TABLE_LIST *table= table_list;
1294
 
       table != last_table;
1295
 
       table= table->next_local)
1296
 
    unlock_table_name(thd,table);
1297
 
  broadcast_refresh();
 
977
  mdl_release_locks(&thd->mdl_context);
 
978
  mdl_remove_all_locks(&thd->mdl_context);
1298
979
  DBUG_VOID_RETURN;
1299
980
}
1300
981
 
1421
1102
  if (!thd->global_read_lock)
1422
1103
  {
1423
1104
    const char *old_message;
 
1105
    const char *new_message= "Waiting to get readlock";
1424
1106
    (void) pthread_mutex_lock(&LOCK_global_read_lock);
 
1107
 
 
1108
#if defined(ENABLED_DEBUG_SYNC)
 
1109
    /*
 
1110
      The below sync point fires if we have to wait for
 
1111
      protect_against_global_read_lock.
 
1112
 
 
1113
      WARNING: Beware to use WAIT_FOR with this sync point. We hold
 
1114
      LOCK_global_read_lock here.
 
1115
 
 
1116
      Call the sync point before calling enter_cond() as it does use
 
1117
      enter_cond() and exit_cond() itself if a WAIT_FOR action is
 
1118
      executed in spite of the above warning.
 
1119
 
 
1120
      Pre-set proc_info so that it is available immediately after the
 
1121
      sync point sends a SIGNAL. This makes tests more reliable.
 
1122
    */
 
1123
    if (protect_against_global_read_lock)
 
1124
    {
 
1125
      thd_proc_info(thd, new_message);
 
1126
      DEBUG_SYNC(thd, "wait_lock_global_read_lock");
 
1127
    }
 
1128
#endif /* defined(ENABLED_DEBUG_SYNC) */
 
1129
 
1425
1130
    old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1426
 
                                "Waiting to get readlock");
 
1131
                                new_message);
1427
1132
    DBUG_PRINT("info",
1428
1133
               ("waiting_for: %d  protect_against: %d",
1429
1134
                waiting_for_read_lock, protect_against_global_read_lock));
1440
1145
    thd->global_read_lock= GOT_GLOBAL_READ_LOCK;
1441
1146
    global_read_lock++;
1442
1147
    thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock
 
1148
    /*
 
1149
      When we perform FLUSH TABLES or ALTER TABLE under LOCK TABLES,
 
1150
      tables being reopened are protected only by meta-data locks at
 
1151
      some point. To avoid sneaking in with our global read lock at
 
1152
      this moment we have to take global shared meta data lock.
 
1153
 
 
1154
      TODO: We should change this code to acquire global shared metadata
 
1155
            lock before acquiring global read lock. But in order to do
 
1156
            this we have to get rid of all those places in which
 
1157
            wait_if_global_read_lock() is called before acquiring
 
1158
            metadata locks first. Also long-term we should get rid of
 
1159
            redundancy between metadata locks, global read lock and DDL
 
1160
            blocker (see WL#4399 and WL#4400).
 
1161
    */
 
1162
    if (mdl_acquire_global_shared_lock(&thd->mdl_context))
 
1163
    {
 
1164
      /* Our thread was killed -- return back to initial state. */
 
1165
      pthread_mutex_lock(&LOCK_global_read_lock);
 
1166
      if (!(--global_read_lock))
 
1167
      {
 
1168
        DBUG_PRINT("signal", ("Broadcasting COND_global_read_lock"));
 
1169
        pthread_cond_broadcast(&COND_global_read_lock);
 
1170
      }
 
1171
      pthread_mutex_unlock(&LOCK_global_read_lock);
 
1172
      thd->global_read_lock= 0;
 
1173
      DBUG_RETURN(1);
 
1174
    }
1443
1175
  }
1444
1176
  /*
1445
1177
    We DON'T set global_read_lock_blocks_commit now, it will be set after
1461
1193
             ("global_read_lock: %u  global_read_lock_blocks_commit: %u",
1462
1194
              global_read_lock, global_read_lock_blocks_commit));
1463
1195
 
 
1196
  mdl_release_global_shared_lock(&thd->mdl_context);
 
1197
 
1464
1198
  pthread_mutex_lock(&LOCK_global_read_lock);
1465
1199
  tmp= --global_read_lock;
1466
1200
  if (thd->global_read_lock == MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT)
1499
1233
  (void) pthread_mutex_lock(&LOCK_global_read_lock);
1500
1234
  if ((need_exit_cond= must_wait))
1501
1235
  {
 
1236
    const char *new_message= "Waiting for release of readlock";
 
1237
 
1502
1238
    if (thd->global_read_lock)          // This thread had the read locks
1503
1239
    {
1504
1240
      if (is_not_commit)
1512
1248
      */
1513
1249
      DBUG_RETURN(is_not_commit);
1514
1250
    }
 
1251
 
 
1252
#if defined(ENABLED_DEBUG_SYNC)
 
1253
    /*
 
1254
      The below sync point fires if we have to wait for
 
1255
      global_read_lock.
 
1256
 
 
1257
      WARNING: Beware to use WAIT_FOR with this sync point. We hold
 
1258
      LOCK_global_read_lock here.
 
1259
 
 
1260
      Call the sync point before calling enter_cond() as it does use
 
1261
      enter_cond() and exit_cond() itself if a WAIT_FOR action is
 
1262
      executed in spite of the above warning.
 
1263
 
 
1264
      Pre-set proc_info so that it is available immediately after the
 
1265
      sync point sends a SIGNAL. This makes tests more reliable.
 
1266
    */
 
1267
    if (must_wait)
 
1268
    {
 
1269
      thd_proc_info(thd, new_message);
 
1270
      DEBUG_SYNC(thd, "wait_if_global_read_lock");
 
1271
    }
 
1272
#endif /* defined(ENABLED_DEBUG_SYNC) */
 
1273
 
1515
1274
    old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1516
 
                                "Waiting for release of readlock");
 
1275
                                new_message);
1517
1276
    while (must_wait && ! thd->killed &&
1518
1277
           (!abort_on_refresh || thd->version == refresh_version))
1519
1278
    {
1525
1284
      result=1;
1526
1285
  }
1527
1286
  if (!abort_on_refresh && !result)
 
1287
  {
1528
1288
    protect_against_global_read_lock++;
 
1289
    DBUG_PRINT("sql_lock", ("protect_against_global_read_lock incr: %u",
 
1290
                            protect_against_global_read_lock));
 
1291
  }
1529
1292
  /*
1530
1293
    The following is only true in case of a global read locks (which is rare)
1531
1294
    and if old_message is set
1545
1308
  if (unlikely(thd->global_read_lock))
1546
1309
    DBUG_VOID_RETURN;
1547
1310
  (void) pthread_mutex_lock(&LOCK_global_read_lock);
 
1311
  DBUG_ASSERT(protect_against_global_read_lock);
1548
1312
  tmp= (!--protect_against_global_read_lock &&
1549
1313
        (waiting_for_read_lock || global_read_lock_blocks_commit));
 
1314
  DBUG_PRINT("sql_lock", ("protect_against_global_read_lock decr: %u",
 
1315
                          protect_against_global_read_lock));
1550
1316
  (void) pthread_mutex_unlock(&LOCK_global_read_lock);
1551
1317
  if (tmp)
1552
1318
    pthread_cond_broadcast(&COND_global_read_lock);
1607
1373
 
1608
1374
void broadcast_refresh(void)
1609
1375
{
1610
 
  VOID(pthread_cond_broadcast(&COND_refresh));
1611
 
  VOID(pthread_cond_broadcast(&COND_global_read_lock));
 
1376
  pthread_cond_broadcast(&COND_refresh);
 
1377
  pthread_cond_broadcast(&COND_global_read_lock);
1612
1378
}
1613
1379
 
1614
1380
 
1676
1442
  /* We need to explicitly commit if autocommit mode is active. */
1677
1443
  (void) ha_autocommit_or_rollback(thd, 0);
1678
1444
  /* Close the tables. The locks (if taken) persist in the storage engines. */
1679
 
  close_tables_for_reopen(thd, &table_list);
 
1445
  close_tables_for_reopen(thd, &table_list, FALSE);
1680
1446
  thd->in_lock_tables= FALSE;
1681
1447
  DBUG_PRINT("lock_info", ("result: %d", result));
1682
1448
  DBUG_RETURN(result);
1800
1566
                (tlist->lock_type == TL_READ_NO_INSERT) ||
1801
1567
                (tlist->lock_type == TL_WRITE_DEFAULT) ||
1802
1568
                (tlist->lock_type == TL_WRITE) ||
 
1569
                (tlist->lock_type == TL_WRITE_CONCURRENT_INSERT) ||
1803
1570
                (tlist->lock_type == TL_WRITE_LOW_PRIORITY));
1804
1571
 
1805
1572
    /*