426
423
effect is desired.
429
void mysql_lock_remove(Session *session, DRIZZLE_LOCK *locked,Table *table,
432
if (always_unlock == true)
433
mysql_unlock_some_tables(session, &table, /* table count */ 1);
437
for (i=0; i < locked->table_count; i++)
439
if (locked->table[i] == table)
441
uint32_t j, removed_locks, old_tables;
443
uint32_t lock_data_end;
445
assert(table->lock_position == i);
447
/* Unlock if not yet unlocked */
448
if (always_unlock == false)
449
mysql_unlock_some_tables(session, &table, /* table count */ 1);
451
/* Decrement table_count in advance, making below expressions easier */
452
old_tables= --locked->table_count;
454
/* The table has 'removed_locks' lock data elements in locked->locks */
455
removed_locks= table->lock_count;
457
/* Move down all table pointers above 'i'. */
458
memmove((locked->table+i), (locked->table+i+1),
459
(old_tables - i) * sizeof(Table*));
461
lock_data_end= table->lock_data_start + table->lock_count;
462
/* Move down all lock data pointers above 'table->lock_data_end-1' */
463
memmove((locked->locks + table->lock_data_start),
464
(locked->locks + lock_data_end),
465
(locked->lock_count - lock_data_end) *
466
sizeof(THR_LOCK_DATA*));
469
Fix moved table elements.
470
lock_position is the index in the 'locked->table' array,
471
it must be fixed by one.
472
table->lock_data_start is pointer to the lock data for this table
473
in the 'locked->locks' array, they must be fixed by 'removed_locks',
474
the lock data count of the removed table.
476
for (j= i ; j < old_tables; j++)
478
tbl= locked->table[j];
479
tbl->lock_position--;
480
assert(tbl->lock_position == j);
481
tbl->lock_data_start-= removed_locks;
484
/* Finally adjust lock_count. */
485
locked->lock_count-= removed_locks;
492
/* Downgrade all locks on a table to new WRITE level from WRITE_ONLY */
494
void mysql_lock_downgrade_write(Session *session, Table *table,
495
thr_lock_type new_lock_type)
497
DRIZZLE_LOCK *locked;
498
Table *write_lock_used;
499
if ((locked = get_lock_data(session, &table, 1, GET_LOCK_UNLOCK,
502
for (uint32_t i=0; i < locked->lock_count; i++)
503
thr_downgrade_write_lock(locked->locks[i], new_lock_type);
504
free((unsigned char*) locked);
426
void mysql_lock_remove(Session *session, Table *table)
428
mysql_unlock_some_tables(session, &table, /* table count */ 1);
509
432
/** Abort all other threads waiting to get lock in table. */
511
void mysql_lock_abort(Session *session, Table *table, bool upgrade_lock)
434
void mysql_lock_abort(Session *session, Table *table)
513
436
DRIZZLE_LOCK *locked;
514
437
Table *write_lock_used;
516
if ((locked= get_lock_data(session, &table, 1, GET_LOCK_UNLOCK,
439
if ((locked= get_lock_data(session, &table, 1, false,
517
440
&write_lock_used)))
519
for (uint32_t i=0; i < locked->lock_count; i++)
520
thr_abort_locks(locked->locks[i]->lock, upgrade_lock);
442
for (uint32_t x= 0; x < locked->lock_count; x++)
443
thr_abort_locks(locked->locks[x]->lock);
521
444
free((unsigned char*) locked);
554
476
free((unsigned char*) locked);
560
DRIZZLE_LOCK *mysql_lock_merge(DRIZZLE_LOCK *a,DRIZZLE_LOCK *b)
562
DRIZZLE_LOCK *sql_lock;
563
Table **table, **end_table;
565
if (!(sql_lock= (DRIZZLE_LOCK*)
566
malloc(sizeof(*sql_lock)+
567
sizeof(THR_LOCK_DATA*)*(a->lock_count+b->lock_count)+
568
sizeof(Table*)*(a->table_count+b->table_count))))
569
return(0); // Fatal error
570
sql_lock->lock_count=a->lock_count+b->lock_count;
571
sql_lock->table_count=a->table_count+b->table_count;
572
sql_lock->locks=(THR_LOCK_DATA**) (sql_lock+1);
573
sql_lock->table=(Table**) (sql_lock->locks+sql_lock->lock_count);
574
memcpy(sql_lock->locks,a->locks,a->lock_count*sizeof(*a->locks));
575
memcpy(sql_lock->locks+a->lock_count,b->locks,
576
b->lock_count*sizeof(*b->locks));
577
memcpy(sql_lock->table,a->table,a->table_count*sizeof(*a->table));
578
memcpy(sql_lock->table+a->table_count,b->table,
579
b->table_count*sizeof(*b->table));
582
Now adjust lock_position and lock_data_start for all objects that was
583
moved in 'b' (as there is now all objects in 'a' before these).
585
for (table= sql_lock->table + a->table_count,
586
end_table= table + b->table_count;
590
(*table)->lock_position+= a->table_count;
591
(*table)->lock_data_start+= a->lock_count;
594
/* Delete old, not needed locks */
595
free((unsigned char*) a);
596
free((unsigned char*) b);
602
Find duplicate lock in tables.
604
Temporary tables are ignored here like they are ignored in
605
get_lock_data(). If we allow two opens on temporary tables later,
606
both functions should be checked.
608
@param session The current thread.
609
@param needle The table to check for duplicate lock.
610
@param haystack The list of tables to search for the dup lock.
613
This is mainly meant for MERGE tables in INSERT ... SELECT
614
situations. The 'real', underlying tables can be found only after
615
the MERGE tables are opened. This function assumes that the tables are
619
NULL No duplicate lock found.
621
!NULL First table from 'haystack' that matches a lock on 'needle'.
624
TableList *mysql_lock_have_duplicate(Session *session, TableList *needle,
627
DRIZZLE_LOCK *mylock;
631
THR_LOCK_DATA **lock_locks;
632
THR_LOCK_DATA **table_lock_data;
633
THR_LOCK_DATA **end_data;
634
THR_LOCK_DATA **lock_data2;
635
THR_LOCK_DATA **end_data2;
638
Table may not be defined for derived or view tables.
639
Table may not be part of a lock for delayed operations.
641
if (! (table= needle->table) || ! table->lock_count)
644
/* A temporary table does not have locks. */
645
if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
648
/* Get command lock or LOCK TABLES lock. Maybe empty for INSERT DELAYED. */
649
if (! (mylock= session->lock ? session->lock : session->locked_tables))
652
/* If we have less than two tables, we cannot have duplicates. */
653
if (mylock->table_count < 2)
656
lock_locks= mylock->locks;
657
lock_tables= mylock->table;
659
/* Prepare table related variables that don't change in loop. */
660
assert((table->lock_position < mylock->table_count) &&
661
(table == lock_tables[table->lock_position]));
662
table_lock_data= lock_locks + table->lock_data_start;
663
end_data= table_lock_data + table->lock_count;
665
for (; haystack; haystack= haystack->next_global)
667
if (haystack->placeholder())
669
table2= haystack->table;
670
if (table2->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
673
/* All tables in list must be in lock. */
674
assert((table2->lock_position < mylock->table_count) &&
675
(table2 == lock_tables[table2->lock_position]));
677
for (lock_data2= lock_locks + table2->lock_data_start,
678
end_data2= lock_data2 + table2->lock_count;
679
lock_data2 < end_data2;
682
THR_LOCK_DATA **lock_data;
683
THR_LOCK *lock2= (*lock_data2)->lock;
685
for (lock_data= table_lock_data;
686
lock_data < end_data;
689
if ((*lock_data)->lock == lock2)
729
509
@param session Thread handler
730
510
@param table_ptr Pointer to tables that should be locks
732
- GET_LOCK_UNLOCK : If we should send TL_IGNORE to store lock
733
- GET_LOCK_STORE_LOCKS : Store lock info in Table
511
@param should_lock One of:
512
- false : If we should send TL_IGNORE to store lock
513
- true : Store lock info in Table
734
514
@param write_lock_used Store pointer to last table with WRITE_ALLOW_WRITE
737
517
static DRIZZLE_LOCK *get_lock_data(Session *session, Table **table_ptr, uint32_t count,
738
uint32_t flags, Table **write_lock_used)
518
bool should_lock, Table **write_lock_used)
740
520
uint32_t i,tables,lock_count;
741
521
DRIZZLE_LOCK *sql_lock;
742
522
THR_LOCK_DATA **locks, **locks_buf, **locks_start;
743
523
Table **to, **table_buf;
745
assert((flags == GET_LOCK_UNLOCK) || (flags == GET_LOCK_STORE_LOCKS));
747
525
*write_lock_used=0;
748
for (i=tables=lock_count=0 ; i < count ; i++)
526
for (i= tables= lock_count= 0 ; i < count ; i++)
750
528
Table *t= table_ptr[i];
752
if (t->s->tmp_table != NON_TRANSACTIONAL_TMP_TABLE)
530
if (! (t->getEngine()->check_flag(HTON_BIT_SKIP_STORE_LOCK)))
754
tables+= t->file->lock_count();
819
599
And in the FLUSH case, the memory is released quickly anyway.
821
601
sql_lock->lock_count= locks - locks_buf;
826
/*****************************************************************************
827
Lock table based on the name.
828
This is used when we need total access to a closed, not open table
829
*****************************************************************************/
832
Lock and wait for the named lock.
834
@param session Thread handler
835
@param table_list Lock first table in this list
839
Works together with global read lock.
847
int lock_and_wait_for_table_name(Session *session, TableList *table_list)
852
if (wait_if_global_read_lock(session, 0, 1))
854
pthread_mutex_lock(&LOCK_open);
855
if ((lock_retcode = lock_table_name(session, table_list, true)) < 0)
857
if (lock_retcode && wait_for_locked_table_names(session, table_list))
859
unlock_table_name(session, table_list);
865
pthread_mutex_unlock(&LOCK_open);
866
start_waiting_global_read_lock(session);
1089
Test is 'table' is protected by an exclusive name lock.
1091
@param[in] session The current thread handler
1092
@param[in] table_list Table container containing the single table to be
1095
@note Needs to be protected by LOCK_open mutex.
1097
@return Error status code
1098
@retval TRUE Table is protected
1099
@retval FALSE Table is not protected
1103
is_table_name_exclusively_locked_by_this_thread(Session *session,
1104
TableList *table_list)
1106
char key[MAX_DBKEY_LENGTH];
1107
uint32_t key_length;
1109
key_length= create_table_def_key(session, key, table_list, 0);
1111
return is_table_name_exclusively_locked_by_this_thread(session, (unsigned char *)key,
1117
Test is 'table key' is protected by an exclusive name lock.
1119
@param[in] session The current thread handler.
1121
@param[in] key_length
1123
@note Needs to be protected by LOCK_open mutex
1125
@retval TRUE Table is protected
1126
@retval FALSE Table is not protected
1130
is_table_name_exclusively_locked_by_this_thread(Session *session, unsigned char *key,
1133
HASH_SEARCH_STATE state;
1136
for (table= (Table*) hash_first(&open_cache, key,
1137
key_length, &state);
1139
table= (Table*) hash_next(&open_cache, key,
1140
key_length, &state))
1142
if (table->in_use == session &&
1143
table->open_placeholder == 1 &&
1144
table->s->version == 0)
1152
808
Unlock all tables in list with a name lock.
1155
session Thread handle
1157
811
table_list Names of tables to unlock
1159
813
last_table Don't unlock any tables after this one.
1479
Try to get transactional table locks for the tables in the list.
1482
try_transactional_lock()
1483
session Thread handle
1484
table_list List of tables to lock
1487
This is called if transactional table locks are requested for all
1488
tables in table_list and no non-transactional locks pre-exist.
1491
0 OK. All tables are transactional locked.
1492
1 Error: must fall back to non-transactional locks.
1493
-1 Error: no recovery possible.
1496
int try_transactional_lock(Session *session, TableList *table_list)
1498
uint32_t dummy_counter;
1502
/* Need to open the tables to be able to access engine methods. */
1503
if (open_tables(session, &table_list, &dummy_counter, 0))
1505
/* purecov: begin tested */
1510
/* Required by InnoDB. */
1511
session->in_lock_tables= true;
1513
if ((error= set_handler_table_locks(session, table_list, true)))
1516
Not all transactional locks could be taken. If the error was
1517
something else but "unsupported by storage engine", abort the
1518
execution of this statement.
1520
if (error != HA_ERR_WRONG_COMMAND)
1526
Fall back to non-transactional locks because transactional locks
1527
are unsupported by a storage engine. No need to unlock the
1528
successfully taken transactional locks. They go away at end of
1535
/* We need to explicitly commit if autocommit mode is active. */
1536
(void) ha_autocommit_or_rollback(session, 0);
1537
/* Close the tables. The locks (if taken) persist in the storage engines. */
1538
close_tables_for_reopen(session, &table_list);
1539
session->in_lock_tables= false;
1545
Check if lock method conversion was done and was allowed.
1548
check_transactional_lock()
1549
session Thread handle
1550
table_list List of tables to lock
1554
Lock method conversion can be done during parsing if one of the
1555
locks is non-transactional. It can also happen if non-transactional
1556
table locks exist when the statement is executed or if a storage
1557
engine does not support transactional table locks.
1559
Check if transactional table locks have been converted to
1560
non-transactional and if this was allowed. In a running transaction
1561
or in strict mode lock method conversion is not allowed - report an
1562
error. Otherwise it is allowed - issue a warning.
1565
0 OK. Proceed with non-transactional locks.
1566
-1 Error: Lock conversion is prohibited.
1569
int check_transactional_lock(Session *, TableList *table_list)
1574
for (tlist= table_list; tlist; tlist= tlist->next_global)
1578
Unfortunately we cannot use tlist->placeholder() here. This method
1579
returns TRUE if the table is not open, which is always the case
1580
here. Whenever the definition of TableList::placeholder() is
1581
changed, probably this condition needs to be changed too.
1583
if (tlist->derived || tlist->schema_table || !tlist->lock_transactional)
1588
/* We must not convert the lock method in strict mode. */
1590
my_error(ER_NO_AUTO_CONVERT_LOCK_STRICT, MYF(0),
1591
tlist->alias ? tlist->alias : tlist->table_name);
1603
Set table locks in the table handler.
1606
set_handler_table_locks()
1607
session Thread handle
1608
table_list List of tables to lock
1609
transactional If to lock transactional or non-transactional
1613
!= 0 Error code from handler::lock_table().
1616
int set_handler_table_locks(Session *session, TableList *table_list,
1622
for (tlist= table_list; tlist; tlist= tlist->next_global)
1625
int lock_timeout= -1; /* Use default for non-transactional locks. */
1627
if (tlist->placeholder())
1630
assert((tlist->lock_type == TL_READ) ||
1631
(tlist->lock_type == TL_READ_NO_INSERT) ||
1632
(tlist->lock_type == TL_WRITE_DEFAULT) ||
1633
(tlist->lock_type == TL_WRITE) ||
1634
(tlist->lock_type == TL_WRITE_LOW_PRIORITY));
1637
Every tlist object has a proper lock_type set. Even if it came in
1638
the list as a base table from a view only.
1640
lock_type= ((tlist->lock_type <= TL_READ_NO_INSERT) ?
1641
HA_LOCK_IN_SHARE_MODE : HA_LOCK_IN_EXCLUSIVE_MODE);
1646
The lock timeout is not set if this table belongs to a view. We
1647
need to take it from the top-level view. After this loop
1648
iteration, lock_timeout is not needed any more. Not even if the
1649
locks are converted to non-transactional locks later.
1650
Non-transactional locks do not support a lock_timeout.
1652
lock_timeout= tlist->top_table()->lock_timeout;
1655
For warning/error reporting we need to set the intended lock
1656
method in the TableList object. It will be used later by
1657
check_transactional_lock(). The lock method is not set if this
1658
table belongs to a view. We can safely set it to transactional
1659
locking here. Even for non-view tables. This function is not
1660
called if non-transactional locking was requested for any
1663
tlist->lock_transactional= true;
1667
Because we need to set the lock method (see above) for all
1668
involved tables, we cannot break the loop on an error.
1669
But we do not try more locks after the first error.
1670
However, for non-transactional locking handler::lock_table() is
1671
a hint only. So we continue to call it for other tables.
1673
if (!error || !transactional)
1675
error= tlist->table->file->lock_table(session, lock_type, lock_timeout);
1676
if (error && transactional && (error != HA_ERR_WRONG_COMMAND))
1677
tlist->table->file->print_error(error, MYF(0));
1686
1127
@} (end of group Locking)