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