86
88
#define GET_LOCK_UNLOCK 1
87
89
#define GET_LOCK_STORE_LOCKS 2
89
static DRIZZLE_LOCK *get_lock_data(THD *thd, Table **table,uint32_t count,
90
uint32_t flags, Table **write_locked);
91
static int lock_external(THD *thd, Table **table,uint32_t count);
92
static int unlock_external(THD *thd, Table **table,uint32_t count);
91
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table,uint count,
92
uint flags, TABLE **write_locked);
93
static int lock_external(THD *thd, TABLE **table,uint count);
94
static int unlock_external(THD *thd, TABLE **table,uint count);
93
95
static void print_lock_error(int error, const char *);
101
103
tables An array of pointers to the tables to lock.
102
104
count The number of tables to lock.
104
DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK Ignore a global read lock
105
DRIZZLE_LOCK_IGNORE_GLOBAL_READ_ONLY Ignore SET GLOBAL READ_ONLY
106
DRIZZLE_LOCK_IGNORE_FLUSH Ignore a flush tables.
107
DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN Instead of reopening altered
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
108
110
or dropped tables by itself,
109
111
mysql_lock_tables() should
110
112
notify upper level and rely
121
123
static int thr_lock_errno_to_mysql[]=
122
124
{ 0, 1, ER_LOCK_WAIT_TIMEOUT, ER_LOCK_DEADLOCK };
127
Perform semantic checks for mysql_lock_tables.
128
@param thd The current thread
129
@param tables The tables to lock
130
@param count The number of tables to lock
131
@param flags Lock flags
132
@return 0 if all the check passed, non zero if a check failed.
134
int mysql_lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags)
139
DBUG_ENTER("mysql_lock_tables_check");
143
for (i=0 ; i<count; i++)
147
/* Protect against 'fake' partially initialized TABLE_SHARE */
148
DBUG_ASSERT(t->s->table_category != TABLE_UNKNOWN_CATEGORY);
150
if ((t->s->table_category == TABLE_CATEGORY_SYSTEM) &&
151
(t->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE))
158
Locking of system tables is restricted:
159
locking a mix of system and non-system tables in the same lock
160
is prohibited, to prevent contention.
162
if ((system_count > 0) && (system_count < count))
164
my_error(ER_WRONG_LOCK_OF_SYSTEM_TABLE, MYF(0));
126
173
Reset lock type in lock data and free.
142
189
lock request will set its lock type properly.
145
static void reset_lock_data_and_free(DRIZZLE_LOCK **mysql_lock)
192
static void reset_lock_data_and_free(MYSQL_LOCK **mysql_lock)
147
DRIZZLE_LOCK *sql_lock= *mysql_lock;
194
MYSQL_LOCK *sql_lock= *mysql_lock;
148
195
THR_LOCK_DATA **ldata, **ldata_end;
150
197
/* Clear the lock type of all lock data to avoid reusage. */
155
202
/* Reset lock type. */
156
203
(*ldata)->type= TL_UNLOCK;
158
free((unsigned char*) sql_lock);
205
my_free((uchar*) sql_lock, MYF(0));
163
DRIZZLE_LOCK *mysql_lock_tables(THD *thd, Table **tables, uint32_t count,
164
uint32_t flags, bool *need_reopen)
210
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
211
uint flags, bool *need_reopen)
166
DRIZZLE_LOCK *sql_lock;
167
Table *write_lock_used;
213
MYSQL_LOCK *sql_lock;
214
TABLE *write_lock_used;
217
DBUG_ENTER("mysql_lock_tables");
221
if (mysql_lock_tables_check(thd, tables, count, flags))
213
thd->set_proc_info("System lock");
265
thd_proc_info(thd, "System lock");
266
DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
214
267
if (sql_lock->table_count && lock_external(thd, sql_lock->table,
215
268
sql_lock->table_count))
218
271
reset_lock_data_and_free(&sql_lock);
221
thd->set_proc_info("Table lock");
274
thd_proc_info(thd, "Table lock");
275
DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
222
276
/* Copy the lock data array. thr_multi_lock() reorders its contens. */
223
277
memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks,
224
278
sql_lock->lock_count * sizeof(*sql_lock->locks));
230
284
if (rc > 1) /* a timeout or a deadlock */
232
286
if (sql_lock->table_count)
233
unlock_external(thd, sql_lock->table, sql_lock->table_count);
287
VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count));
234
288
reset_lock_data_and_free(&sql_lock);
235
289
my_error(rc, MYF(0));
241
295
sql_lock->lock_count= 0; // Locks are already freed
242
296
// Fall through: unlock, reset lock data, free and retry
244
else if (!thd->some_tables_deleted || (flags & DRIZZLE_LOCK_IGNORE_FLUSH))
298
else if (!thd->some_tables_deleted || (flags & MYSQL_LOCK_IGNORE_FLUSH))
247
301
Thread was killed or lock aborted. Let upper level close all
255
309
thd->some_tables_deleted=0;
258
thd->set_proc_info(0);
312
thd_proc_info(thd, 0);
260
314
/* going to retry, unlock all tables */
261
315
if (sql_lock->lock_count)
262
316
thr_multi_unlock(sql_lock->locks, sql_lock->lock_count);
264
318
if (sql_lock->table_count)
265
unlock_external(thd, sql_lock->table, sql_lock->table_count);
319
VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count));
268
322
If thr_multi_lock fails it resets lock type for tables, which
293
347
thd->set_time_after_lock();
348
DBUG_RETURN (sql_lock);
298
static int lock_external(THD *thd, Table **tables, uint32_t count)
352
static int lock_external(THD *thd, TABLE **tables, uint count)
301
355
int lock_type,error;
356
DBUG_ENTER("lock_external");
358
DBUG_PRINT("info", ("count %d", count));
302
359
for (i=1 ; i <= count ; i++, tables++)
304
assert((*tables)->reginfo.lock_type >= TL_READ);
361
DBUG_ASSERT((*tables)->reginfo.lock_type >= TL_READ);
305
362
lock_type=F_WRLCK; /* Lock exclusive */
306
363
if ((*tables)->db_stat & HA_READ_ONLY ||
307
364
((*tables)->reginfo.lock_type >= TL_READ &&
325
382
(*tables)->current_lock= lock_type;
332
void mysql_unlock_tables(THD *thd, DRIZZLE_LOCK *sql_lock)
389
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
391
DBUG_ENTER("mysql_unlock_tables");
334
392
if (sql_lock->lock_count)
335
393
thr_multi_unlock(sql_lock->locks,sql_lock->lock_count);
336
394
if (sql_lock->table_count)
337
unlock_external(thd,sql_lock->table,sql_lock->table_count);
338
free((unsigned char*) sql_lock);
395
VOID(unlock_external(thd,sql_lock->table,sql_lock->table_count));
396
my_free((uchar*) sql_lock,MYF(0));
345
403
This will work even if get_lock_data fails (next unlock will free all)
348
void mysql_unlock_some_tables(THD *thd, Table **table,uint32_t count)
406
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count)
350
DRIZZLE_LOCK *sql_lock;
351
Table *write_lock_used;
408
MYSQL_LOCK *sql_lock;
409
TABLE *write_lock_used;
352
410
if ((sql_lock= get_lock_data(thd, table, count, GET_LOCK_UNLOCK,
353
411
&write_lock_used)))
354
412
mysql_unlock_tables(thd, sql_lock);
359
417
unlock all tables locked for read.
362
void mysql_unlock_read_tables(THD *thd, DRIZZLE_LOCK *sql_lock)
420
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
423
DBUG_ENTER("mysql_unlock_read_tables");
366
425
/* Move all write locks first */
367
426
THR_LOCK_DATA **lock=sql_lock->locks;
384
443
/* Then do the same for the external locks */
385
444
/* Move all write locked tables first */
386
Table **table=sql_lock->table;
445
TABLE **table=sql_lock->table;
387
446
for (i=found=0 ; i < sql_lock->table_count ; i++)
389
assert(sql_lock->table[i]->lock_position == i);
448
DBUG_ASSERT(sql_lock->table[i]->lock_position == i);
390
449
if ((uint) sql_lock->table[i]->reginfo.lock_type >= TL_WRITE_ALLOW_READ)
392
std::swap(*table, sql_lock->table[i]);
451
swap_variables(TABLE *, *table, sql_lock->table[i]);
397
456
/* Unlock all read locked tables */
400
unlock_external(thd,table,i-found);
459
VOID(unlock_external(thd,table,i-found));
401
460
sql_lock->table_count=found;
403
/* Fix the lock positions in Table */
462
/* Fix the lock positions in TABLE */
404
463
table= sql_lock->table;
406
465
for (i= 0; i < sql_lock->table_count; i++)
409
468
tbl->lock_position= table - sql_lock->table;
410
469
tbl->lock_data_start= found;
411
470
found+= tbl->lock_count;
435
494
effect is desired.
438
void mysql_lock_remove(THD *thd, DRIZZLE_LOCK *locked,Table *table,
497
void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table,
439
498
bool always_unlock)
441
if (always_unlock == true)
500
if (always_unlock == TRUE)
442
501
mysql_unlock_some_tables(thd, &table, /* table count */ 1);
446
505
for (i=0; i < locked->table_count; i++)
448
507
if (locked->table[i] == table)
450
uint32_t j, removed_locks, old_tables;
452
uint32_t lock_data_end;
509
uint j, removed_locks, old_tables;
454
assert(table->lock_position == i);
513
DBUG_ASSERT(table->lock_position == i);
456
515
/* Unlock if not yet unlocked */
457
if (always_unlock == false)
516
if (always_unlock == FALSE)
458
517
mysql_unlock_some_tables(thd, &table, /* table count */ 1);
460
519
/* Decrement table_count in advance, making below expressions easier */
464
523
removed_locks= table->lock_count;
466
525
/* Move down all table pointers above 'i'. */
467
memcpy((locked->table+i), (locked->table+i+1),
468
(old_tables - i) * sizeof(Table*));
526
bmove((char*) (locked->table+i),
527
(char*) (locked->table+i+1),
528
(old_tables - i) * sizeof(TABLE*));
470
530
lock_data_end= table->lock_data_start + table->lock_count;
471
531
/* Move down all lock data pointers above 'table->lock_data_end-1' */
472
memcpy((locked->locks + table->lock_data_start),
473
(locked->locks + lock_data_end),
474
(locked->lock_count - lock_data_end) *
475
sizeof(THR_LOCK_DATA*));
532
bmove((char*) (locked->locks + table->lock_data_start),
533
(char*) (locked->locks + lock_data_end),
534
(locked->lock_count - lock_data_end) *
535
sizeof(THR_LOCK_DATA*));
478
538
Fix moved table elements.
501
561
/* Downgrade all locks on a table to new WRITE level from WRITE_ONLY */
503
void mysql_lock_downgrade_write(THD *thd, Table *table,
563
void mysql_lock_downgrade_write(THD *thd, TABLE *table,
504
564
thr_lock_type new_lock_type)
506
DRIZZLE_LOCK *locked;
507
Table *write_lock_used;
567
TABLE *write_lock_used;
508
568
if ((locked = get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
509
569
&write_lock_used)))
511
for (uint32_t i=0; i < locked->lock_count; i++)
571
for (uint i=0; i < locked->lock_count; i++)
512
572
thr_downgrade_write_lock(locked->locks[i], new_lock_type);
513
free((unsigned char*) locked);
573
my_free((uchar*) locked,MYF(0));
518
578
/** Abort all other threads waiting to get lock in table. */
520
void mysql_lock_abort(THD *thd, Table *table, bool upgrade_lock)
580
void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
522
DRIZZLE_LOCK *locked;
523
Table *write_lock_used;
583
TABLE *write_lock_used;
584
DBUG_ENTER("mysql_lock_abort");
525
586
if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
526
587
&write_lock_used)))
528
for (uint32_t i=0; i < locked->lock_count; i++)
589
for (uint i=0; i < locked->lock_count; i++)
529
590
thr_abort_locks(locked->locks[i]->lock, upgrade_lock);
530
free((unsigned char*) locked);
591
my_free((uchar*) locked,MYF(0));
545
606
1 Table was locked by at least one other thread
548
bool mysql_lock_abort_for_thread(THD *thd, Table *table)
609
bool mysql_lock_abort_for_thread(THD *thd, TABLE *table)
550
DRIZZLE_LOCK *locked;
551
Table *write_lock_used;
612
TABLE *write_lock_used;
614
DBUG_ENTER("mysql_lock_abort_for_thread");
554
616
if ((locked= get_lock_data(thd, &table, 1, GET_LOCK_UNLOCK,
555
617
&write_lock_used)))
557
for (uint32_t i=0; i < locked->lock_count; i++)
619
for (uint i=0; i < locked->lock_count; i++)
559
621
if (thr_abort_locks_for_thread(locked->locks[i]->lock,
560
622
table->in_use->thread_id))
563
free((unsigned char*) locked);
625
my_free((uchar*) locked,MYF(0));
569
DRIZZLE_LOCK *mysql_lock_merge(DRIZZLE_LOCK *a,DRIZZLE_LOCK *b)
631
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
571
DRIZZLE_LOCK *sql_lock;
572
Table **table, **end_table;
633
MYSQL_LOCK *sql_lock;
634
TABLE **table, **end_table;
635
DBUG_ENTER("mysql_lock_merge");
574
if (!(sql_lock= (DRIZZLE_LOCK*)
637
if (!(sql_lock= (MYSQL_LOCK*)
575
638
my_malloc(sizeof(*sql_lock)+
576
639
sizeof(THR_LOCK_DATA*)*(a->lock_count+b->lock_count)+
577
sizeof(Table*)*(a->table_count+b->table_count),MYF(MY_WME))))
578
return(0); // Fatal error
640
sizeof(TABLE*)*(a->table_count+b->table_count),MYF(MY_WME))))
641
DBUG_RETURN(0); // Fatal error
579
642
sql_lock->lock_count=a->lock_count+b->lock_count;
580
643
sql_lock->table_count=a->table_count+b->table_count;
581
644
sql_lock->locks=(THR_LOCK_DATA**) (sql_lock+1);
582
sql_lock->table=(Table**) (sql_lock->locks+sql_lock->lock_count);
645
sql_lock->table=(TABLE**) (sql_lock->locks+sql_lock->lock_count);
583
646
memcpy(sql_lock->locks,a->locks,a->lock_count*sizeof(*a->locks));
584
647
memcpy(sql_lock->locks+a->lock_count,b->locks,
585
648
b->lock_count*sizeof(*b->locks));
586
649
memcpy(sql_lock->table,a->table,a->table_count*sizeof(*a->table));
587
650
memcpy(sql_lock->table+a->table_count,b->table,
588
b->table_count*sizeof(*b->table));
651
b->table_count*sizeof(*b->table));
591
654
Now adjust lock_position and lock_data_start for all objects that was
630
693
!NULL First table from 'haystack' that matches a lock on 'needle'.
633
TableList *mysql_lock_have_duplicate(THD *thd, TableList *needle,
696
TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
697
TABLE_LIST *haystack)
636
DRIZZLE_LOCK *mylock;
640
703
THR_LOCK_DATA **lock_locks;
641
704
THR_LOCK_DATA **table_lock_data;
642
705
THR_LOCK_DATA **end_data;
643
706
THR_LOCK_DATA **lock_data2;
644
707
THR_LOCK_DATA **end_data2;
708
DBUG_ENTER("mysql_lock_have_duplicate");
647
711
Table may not be defined for derived or view tables.
666
730
lock_tables= mylock->table;
668
732
/* Prepare table related variables that don't change in loop. */
669
assert((table->lock_position < mylock->table_count) &&
733
DBUG_ASSERT((table->lock_position < mylock->table_count) &&
670
734
(table == lock_tables[table->lock_position]));
671
735
table_lock_data= lock_locks + table->lock_data_start;
672
736
end_data= table_lock_data + table->lock_count;
698
762
if ((*lock_data)->lock == lock2)
764
DBUG_PRINT("info", ("haystack match: '%s'", haystack->table_name));
765
DBUG_RETURN(haystack);
772
DBUG_PRINT("info", ("no duplicate found"));
711
777
/** Unlock a set of external. */
713
static int unlock_external(THD *thd, Table **table,uint32_t count)
779
static int unlock_external(THD *thd, TABLE **table,uint count)
715
781
int error,error_code;
782
DBUG_ENTER("unlock_external");
739
806
@param table_ptr Pointer to tables that should be locks
740
807
@param flags One of:
741
808
- GET_LOCK_UNLOCK : If we should send TL_IGNORE to store lock
742
- GET_LOCK_STORE_LOCKS : Store lock info in Table
809
- GET_LOCK_STORE_LOCKS : Store lock info in TABLE
743
810
@param write_lock_used Store pointer to last table with WRITE_ALLOW_WRITE
746
static DRIZZLE_LOCK *get_lock_data(THD *thd, Table **table_ptr, uint32_t count,
747
uint32_t flags, Table **write_lock_used)
813
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
814
uint flags, TABLE **write_lock_used)
749
uint32_t i,tables,lock_count;
750
DRIZZLE_LOCK *sql_lock;
816
uint i,tables,lock_count;
817
MYSQL_LOCK *sql_lock;
751
818
THR_LOCK_DATA **locks, **locks_buf, **locks_start;
752
Table **to, **table_buf;
754
assert((flags == GET_LOCK_UNLOCK) || (flags == GET_LOCK_STORE_LOCKS));
819
TABLE **to, **table_buf;
820
DBUG_ENTER("get_lock_data");
822
DBUG_ASSERT((flags == GET_LOCK_UNLOCK) || (flags == GET_LOCK_STORE_LOCKS));
824
DBUG_PRINT("info", ("count %d", count));
756
825
*write_lock_used=0;
757
826
for (i=tables=lock_count=0 ; i < count ; i++)
759
Table *t= table_ptr[i];
828
TABLE *t= table_ptr[i];
761
830
if (t->s->tmp_table != NON_TRANSACTIONAL_TMP_TABLE)
771
840
update the table values. So the second part of the array is copied
772
841
from the first part immediately before calling thr_multi_lock().
774
if (!(sql_lock= (DRIZZLE_LOCK*)
843
if (!(sql_lock= (MYSQL_LOCK*)
775
844
my_malloc(sizeof(*sql_lock) +
776
845
sizeof(THR_LOCK_DATA*) * tables * 2 +
777
846
sizeof(table_ptr) * lock_count,
780
849
locks= locks_buf= sql_lock->locks= (THR_LOCK_DATA**) (sql_lock + 1);
781
to= table_buf= sql_lock->table= (Table**) (locks + tables * 2);
850
to= table_buf= sql_lock->table= (TABLE**) (locks + tables * 2);
782
851
sql_lock->table_count=lock_count;
784
853
for (i=0 ; i < count ; i++)
787
856
enum thr_lock_type lock_type;
789
858
if ((table=table_ptr[i])->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
791
860
lock_type= table->reginfo.lock_type;
792
assert (lock_type != TL_WRITE_DEFAULT);
861
DBUG_ASSERT (lock_type != TL_WRITE_DEFAULT);
793
862
if (lock_type >= TL_WRITE_ALLOW_WRITE)
795
864
*write_lock_used=table;
799
868
/* Clear the lock type of the lock data that are stored already. */
800
869
sql_lock->lock_count= locks - sql_lock->locks;
801
870
reset_lock_data_and_free(&sql_lock);
874
THR_LOCK_DATA **org_locks = locks;
805
875
locks_start= locks;
806
876
locks= table->file->store_lock(thd, locks,
807
877
(flags & GET_LOCK_UNLOCK) ? TL_IGNORE :
857
int lock_and_wait_for_table_name(THD *thd, TableList *table_list)
932
int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list)
859
934
int lock_retcode;
936
DBUG_ENTER("lock_and_wait_for_table_name");
862
938
if (wait_if_global_read_lock(thd, 0, 1))
864
pthread_mutex_lock(&LOCK_open);
865
if ((lock_retcode = lock_table_name(thd, table_list, true)) < 0)
940
VOID(pthread_mutex_lock(&LOCK_open));
941
if ((lock_retcode = lock_table_name(thd, table_list, TRUE)) < 0)
867
943
if (lock_retcode && wait_for_locked_table_names(thd, table_list))
905
981
> 0 table locked, but someone is using it
908
int lock_table_name(THD *thd, TableList *table_list, bool check_in_use)
984
int lock_table_name(THD *thd, TABLE_LIST *table_list, bool check_in_use)
911
987
char key[MAX_DBKEY_LENGTH];
912
988
char *db= table_list->db;
914
bool found_locked_table= false;
990
bool found_locked_table= FALSE;
915
991
HASH_SEARCH_STATE state;
992
DBUG_ENTER("lock_table_name");
993
DBUG_PRINT("enter",("db: %s name: %s", db, table_list->table_name));
917
995
key_length= create_table_def_key(thd, key, table_list, 0);
919
997
if (check_in_use)
921
999
/* Only insert the table if we haven't insert it already */
922
for (table=(Table*) hash_first(&open_cache, (unsigned char*)key,
1000
for (table=(TABLE*) hash_first(&open_cache, (uchar*)key,
923
1001
key_length, &state);
925
table = (Table*) hash_next(&open_cache,(unsigned char*) key,
1003
table = (TABLE*) hash_next(&open_cache,(uchar*) key,
926
1004
key_length, &state))
928
1006
if (table->reginfo.lock_type < TL_WRITE)
930
1008
if (table->in_use == thd)
931
found_locked_table= true;
1009
found_locked_table= TRUE;
935
1013
if (table->in_use == thd)
1015
DBUG_PRINT("info", ("Table is in use"));
937
1016
table->s->version= 0; // Ensure no one can use this
938
1017
table->locked_by_name= 1;
950
1029
my_error(ER_TABLE_NOT_LOCKED, MYF(0), table_list->alias);
955
1034
if (!(table= table_cache_insert_placeholder(thd, key, key_length)))
958
1037
table_list->table=table;
960
1039
/* Return 1 if table is in use */
961
return(test(remove_table_from_cache(thd, db, table_list->table_name,
1040
DBUG_RETURN(test(remove_table_from_cache(thd, db, table_list->table_name,
962
1041
check_in_use ? RTFC_NO_FLAG : RTFC_WAIT_OTHER_THREAD_FLAG)));
966
void unlock_table_name(THD *thd __attribute__((unused)),
967
TableList *table_list)
1045
void unlock_table_name(THD *thd, TABLE_LIST *table_list)
969
1047
if (table_list->table)
971
hash_delete(&open_cache, (unsigned char*) table_list->table);
1049
hash_delete(&open_cache, (uchar*) table_list->table);
972
1050
broadcast_refresh();
977
static bool locked_named_table(THD *thd __attribute__((unused)),
978
TableList *table_list)
1055
static bool locked_named_table(THD *thd, TABLE_LIST *table_list)
980
1057
for (; table_list ; table_list=table_list->next_local)
982
Table *table= table_list->table;
1059
TABLE *table= table_list->table;
985
Table *save_next= table->next;
1062
TABLE *save_next= table->next;
988
1065
result= table_is_used(table_list->table, 0);
1034
1112
1 Fatal error (end of memory ?)
1037
bool lock_table_names(THD *thd, TableList *table_list)
1115
bool lock_table_names(THD *thd, TABLE_LIST *table_list)
1039
1117
bool got_all_locks=1;
1040
TableList *lock_table;
1118
TABLE_LIST *lock_table;
1042
1120
for (lock_table= table_list; lock_table; lock_table= lock_table->next_local)
1045
if ((got_lock=lock_table_name(thd,lock_table, true)) < 0)
1123
if ((got_lock=lock_table_name(thd,lock_table, TRUE)) < 0)
1046
1124
goto end; // Fatal error
1048
1126
got_all_locks=0; // Someone is using table
1078
1156
@retval FALSE Name lock successfully acquired.
1081
bool lock_table_names_exclusively(THD *thd, TableList *table_list)
1159
bool lock_table_names_exclusively(THD *thd, TABLE_LIST *table_list)
1083
1161
if (lock_table_names(thd, table_list))
1087
1165
Upgrade the table name locks from semi-exclusive to exclusive locks.
1089
for (TableList *table= table_list; table; table= table->next_global)
1167
for (TABLE_LIST *table= table_list; table; table= table->next_global)
1091
1169
if (table->table)
1092
1170
table->table->open_placeholder= 1;
1113
1191
is_table_name_exclusively_locked_by_this_thread(THD *thd,
1114
TableList *table_list)
1192
TABLE_LIST *table_list)
1116
1194
char key[MAX_DBKEY_LENGTH];
1117
uint32_t key_length;
1119
1197
key_length= create_table_def_key(thd, key, table_list, 0);
1121
return is_table_name_exclusively_locked_by_this_thread(thd, (unsigned char *)key,
1199
return is_table_name_exclusively_locked_by_this_thread(thd, (uchar *)key,
1140
is_table_name_exclusively_locked_by_this_thread(THD *thd, unsigned char *key,
1218
is_table_name_exclusively_locked_by_this_thread(THD *thd, uchar *key,
1141
1219
int key_length)
1143
1221
HASH_SEARCH_STATE state;
1146
for (table= (Table*) hash_first(&open_cache, key,
1224
for (table= (TABLE*) hash_first(&open_cache, key,
1147
1225
key_length, &state);
1149
table= (Table*) hash_next(&open_cache, key,
1227
table= (TABLE*) hash_next(&open_cache, key,
1150
1228
key_length, &state))
1152
1230
if (table->in_use == thd &&
1153
1231
table->open_placeholder == 1 &&
1154
1232
table->s->version == 0)
1182
1260
1 Fatal error (end of memory ?)
1185
void unlock_table_names(THD *thd, TableList *table_list,
1186
TableList *last_table)
1263
void unlock_table_names(THD *thd, TABLE_LIST *table_list,
1264
TABLE_LIST *last_table)
1188
for (TableList *table= table_list;
1266
DBUG_ENTER("unlock_table_names");
1267
for (TABLE_LIST *table= table_list;
1189
1268
table != last_table;
1190
1269
table= table->next_local)
1191
1270
unlock_table_name(thd,table);
1192
1271
broadcast_refresh();
1197
1276
static void print_lock_error(int error, const char *table)
1279
DBUG_ENTER("print_lock_error");
1201
1281
switch (error) {
1202
1282
case HA_ERR_LOCK_WAIT_TIMEOUT:
1301
1381
****************************************************************************/
1303
volatile uint32_t global_read_lock=0;
1304
volatile uint32_t global_read_lock_blocks_commit=0;
1305
static volatile uint32_t protect_against_global_read_lock=0;
1306
static volatile uint32_t waiting_for_read_lock=0;
1383
volatile uint global_read_lock=0;
1384
volatile uint global_read_lock_blocks_commit=0;
1385
static volatile uint protect_against_global_read_lock=0;
1386
static volatile uint waiting_for_read_lock=0;
1308
1388
#define GOT_GLOBAL_READ_LOCK 1
1309
1389
#define MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT 2
1311
1391
bool lock_global_read_lock(THD *thd)
1393
DBUG_ENTER("lock_global_read_lock");
1313
1395
if (!thd->global_read_lock)
1315
1397
const char *old_message;
1316
1398
(void) pthread_mutex_lock(&LOCK_global_read_lock);
1317
1399
old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1318
1400
"Waiting to get readlock");
1402
("waiting_for: %d protect_against: %d",
1403
waiting_for_read_lock, protect_against_global_read_lock));
1320
1405
waiting_for_read_lock++;
1321
1406
while (protect_against_global_read_lock && !thd->killed)
1338
1423
forbid it before, or we can have a 3-thread deadlock if 2 do SELECT FOR
1339
1424
UPDATE and one does FLUSH TABLES WITH READ LOCK).
1345
1430
void unlock_global_read_lock(THD *thd)
1433
DBUG_ENTER("unlock_global_read_lock");
1435
("global_read_lock: %u global_read_lock_blocks_commit: %u",
1436
global_read_lock, global_read_lock_blocks_commit));
1349
1438
pthread_mutex_lock(&LOCK_global_read_lock);
1350
1439
tmp= --global_read_lock;
1392
1483
This allowance is needed to not break existing versions of innobackup
1393
1484
which do a BEGIN; INSERT; FLUSH TABLES WITH READ LOCK; COMMIT.
1395
return(is_not_commit);
1486
DBUG_RETURN(is_not_commit);
1397
1488
old_message=thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1398
1489
"Waiting for release of readlock");
1399
1490
while (must_wait && ! thd->killed &&
1400
1491
(!abort_on_refresh || thd->version == refresh_version))
1493
DBUG_PRINT("signal", ("Waiting for COND_global_read_lock"));
1402
1494
(void) pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
1495
DBUG_PRINT("signal", ("Got COND_global_read_lock"));
1404
1497
if (thd->killed)
1414
1507
thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1416
1509
pthread_mutex_unlock(&LOCK_global_read_lock);
1510
DBUG_RETURN(result);
1421
1514
void start_waiting_global_read_lock(THD *thd)
1517
DBUG_ENTER("start_waiting_global_read_lock");
1424
1518
if (unlikely(thd->global_read_lock))
1426
1520
(void) pthread_mutex_lock(&LOCK_global_read_lock);
1427
1521
tmp= (!--protect_against_global_read_lock &&
1428
1522
(waiting_for_read_lock || global_read_lock_blocks_commit));
1429
1523
(void) pthread_mutex_unlock(&LOCK_global_read_lock);
1431
1525
pthread_cond_broadcast(&COND_global_read_lock);
1439
1533
const char *old_message;
1534
DBUG_ENTER("make_global_read_lock_block_commit");
1441
1536
If we didn't succeed lock_global_read_lock(), or if we already suceeded
1442
1537
make_global_read_lock_block_commit(), do nothing.
1444
1539
if (thd->global_read_lock != GOT_GLOBAL_READ_LOCK)
1446
1541
pthread_mutex_lock(&LOCK_global_read_lock);
1447
1542
/* increment this BEFORE waiting on cond (otherwise race cond) */
1448
1543
global_read_lock_blocks_commit++;
1449
1544
/* For testing we set up some blocking, to see if we can be killed */
1450
protect_against_global_read_lock++;
1545
DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop",
1546
protect_against_global_read_lock++;);
1451
1547
old_message= thd->enter_cond(&COND_global_read_lock, &LOCK_global_read_lock,
1452
1548
"Waiting for all running commits to finish");
1453
1549
while (protect_against_global_read_lock && !thd->killed)
1454
1550
pthread_cond_wait(&COND_global_read_lock, &LOCK_global_read_lock);
1455
protect_against_global_read_lock--;
1551
DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop",
1552
protect_against_global_read_lock--;);
1456
1553
if ((error= test(thd->killed)))
1457
1554
global_read_lock_blocks_commit--; // undo what we did
1459
1556
thd->global_read_lock= MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT;
1460
1557
thd->exit_cond(old_message); // this unlocks LOCK_global_read_lock
1506
1603
-1 Error: no recovery possible.
1509
int try_transactional_lock(THD *thd, TableList *table_list)
1606
int try_transactional_lock(THD *thd, TABLE_LIST *table_list)
1511
uint32_t dummy_counter;
1611
DBUG_ENTER("try_transactional_lock");
1515
1613
/* Need to open the tables to be able to access engine methods. */
1516
1614
if (open_tables(thd, &table_list, &dummy_counter, 0))
1518
1616
/* purecov: begin tested */
1617
DBUG_PRINT("lock_info", ("aborting, open_tables failed"));
1520
1619
/* purecov: end */
1523
1622
/* Required by InnoDB. */
1524
thd->in_lock_tables= true;
1623
thd->in_lock_tables= TRUE;
1526
if ((error= set_handler_table_locks(thd, table_list, true)))
1625
if ((error= set_handler_table_locks(thd, table_list, TRUE)))
1529
1628
Not all transactional locks could be taken. If the error was
1549
1650
(void) ha_autocommit_or_rollback(thd, 0);
1550
1651
/* Close the tables. The locks (if taken) persist in the storage engines. */
1551
1652
close_tables_for_reopen(thd, &table_list);
1552
thd->in_lock_tables= false;
1653
thd->in_lock_tables= FALSE;
1654
DBUG_PRINT("lock_info", ("result: %d", result));
1655
DBUG_RETURN(result);
1579
1681
-1 Error: Lock conversion is prohibited.
1582
int check_transactional_lock(THD *thd, TableList *table_list)
1684
int check_transactional_lock(THD *thd, TABLE_LIST *table_list)
1586
char warn_buff[DRIZZLE_ERRMSG_SIZE];
1688
char warn_buff[MYSQL_ERRMSG_SIZE];
1689
DBUG_ENTER("check_transactional_lock");
1588
1691
for (tlist= table_list; tlist; tlist= tlist->next_global)
1693
DBUG_PRINT("lock_info", ("checking table: '%s'", tlist->table_name));
1592
1696
Unfortunately we cannot use tlist->placeholder() here. This method
1593
1697
returns TRUE if the table is not open, which is always the case
1594
here. Whenever the definition of TableList::placeholder() is
1698
here. Whenever the definition of TABLE_LIST::placeholder() is
1595
1699
changed, probably this condition needs to be changed too.
1597
1701
if (tlist->derived || tlist->schema_table || !tlist->lock_transactional)
1703
DBUG_PRINT("lock_info", ("skipping placeholder: %d transactional: %d",
1704
tlist->placeholder(),
1705
tlist->lock_transactional));
1619
1726
/* Warn about the conversion. */
1620
snprintf(warn_buff, sizeof(warn_buff), ER(ER_WARN_AUTO_CONVERT_LOCK),
1621
tlist->alias ? tlist->alias : tlist->table_name);
1622
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1727
my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_WARN_AUTO_CONVERT_LOCK),
1728
tlist->alias ? tlist->alias : tlist->table_name);
1729
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1623
1730
ER_WARN_AUTO_CONVERT_LOCK, warn_buff);
1733
DBUG_PRINT("lock_info", ("result: %d", result));
1734
DBUG_RETURN(result);
1641
1749
!= 0 Error code from handler::lock_table().
1644
int set_handler_table_locks(THD *thd, TableList *table_list,
1752
int set_handler_table_locks(THD *thd, TABLE_LIST *table_list,
1645
1753
bool transactional)
1757
DBUG_ENTER("set_handler_table_locks");
1758
DBUG_PRINT("lock_info", ("transactional: %d", transactional));
1650
1760
for (tlist= table_list; tlist; tlist= tlist->next_global)
1678
1788
Non-transactional locks do not support a lock_timeout.
1680
1790
lock_timeout= tlist->top_table()->lock_timeout;
1791
DBUG_PRINT("lock_info",
1792
("table: '%s' tlist==top_table: %d lock_timeout: %d",
1793
tlist->table_name, tlist==tlist->top_table(), lock_timeout));
1683
1796
For warning/error reporting we need to set the intended lock
1684
method in the TableList object. It will be used later by
1797
method in the TABLE_LIST object. It will be used later by
1685
1798
check_transactional_lock(). The lock method is not set if this
1686
1799
table belongs to a view. We can safely set it to transactional
1687
1800
locking here. Even for non-view tables. This function is not
1688
1801
called if non-transactional locking was requested for any
1691
tlist->lock_transactional= true;
1804
tlist->lock_transactional= TRUE;