65
63
extern bool volatile shutdown_in_progress;
65
TableOpenCache &get_open_cache()
67
static TableOpenCache open_cache; /* Used by mysql_test */
72
static void free_cache_entry(Table *entry);
74
void remove_table(Table *arg)
76
TableOpenCacheRange ppp;
77
ppp= get_open_cache().equal_range(arg->getShare()->getCacheKey());
79
for (TableOpenCache::const_iterator iter= ppp.first;
80
iter != ppp.second; ++iter)
82
Table *found_table= (*iter).second;
84
if (found_table == arg)
86
free_cache_entry(arg);
87
get_open_cache().erase(iter);
93
static bool add_table(Table *arg)
95
TableOpenCache &open_cache(get_open_cache());
97
TableOpenCache::iterator returnable= open_cache.insert(make_pair(arg->getShare()->getCacheKey(), arg));
99
return not (returnable == open_cache.end());
103
Table *tables; /* Used by mysql_test */
105
Table *getTable() const
110
Table *setTable(Table *arg)
119
/* Free cache if too big */
120
while (cached_open_tables() > table_cache_size && getTable())
121
remove_table(getTable());
126
while (getTable() && not getTable()->getShare()->getVersion())
127
remove_table(getTable());
130
void link(Table *table)
134
table->setNext(getTable()); /* Link in last */
135
table->setPrev(getTable()->getPrev());
136
getTable()->setPrev(table);
137
table->getPrev()->setNext(table);
141
table->setPrev(setTable(table));
142
table->setNext(table->getPrev());
143
assert(table->getNext() == table && table->getPrev() == table);
148
void unlink(Table *table)
152
/* Unlink the table from "unused_tables" list. */
153
if (table == getTable())
155
setTable(getTable()->getNext()); // Remove from link
156
if (table == getTable())
161
/* move table first in unused links */
163
void relink(Table *table)
165
if (table != getTable())
169
table->setNext(getTable()); /* Link in unused tables */
170
table->setPrev(getTable()->getPrev());
171
getTable()->getPrev()->setNext(table);
172
getTable()->setPrev(table);
181
remove_table(getTable());
193
static UnusedTables unused_tables;
194
static int open_unireg_entry(Session *session,
197
TableIdentifier &identifier);
199
unsigned char *table_cache_key(const unsigned char *record,
203
unsigned char *table_cache_key(const unsigned char *record,
207
Table *entry=(Table*) record;
208
*length= entry->getShare()->getCacheKey().size();
209
return (unsigned char*) &entry->getShare()->getCacheKey()[0];
67
212
bool table_cache_init(void)
113
259
TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
114
260
const TableIdentifier::Key &key(identifier.getKey());
115
TableShare *share= new TableShare(identifier.getType(),
117
const_cast<char *>(key.vector()), static_cast<uint32_t>(table->getShare()->getCacheKeySize()));
261
share= new TableShare(identifier.getType(),
263
const_cast<char *>(&key[0]), static_cast<uint32_t>(old_share->getCacheKeySize()));
119
265
table->cursor->close();
120
266
table->db_stat= 0; // Mark cursor closed
121
267
TableShare::release(table->getMutableShare());
122
268
table->setShare(share);
269
table->cursor->change_table_ptr(table, table->getMutableShare());
532
void Open_tables_state::doGetTableNames(CachedDirectory &,
533
const SchemaIdentifier &schema_identifier,
534
std::set<std::string> &set_of_names)
701
void Session::doGetTableNames(CachedDirectory &,
702
const SchemaIdentifier &schema_identifier,
703
std::set<std::string> &set_of_names)
536
705
doGetTableNames(schema_identifier, set_of_names);
539
void Open_tables_state::doGetTableIdentifiers(const SchemaIdentifier &schema_identifier,
540
TableIdentifier::vector &set_of_identifiers)
708
void Session::doGetTableIdentifiers(const SchemaIdentifier &schema_identifier,
709
TableIdentifiers &set_of_identifiers)
542
for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
711
for (Table *table= temporary_tables ; table ; table= table->getNext())
544
713
if (schema_identifier.compare(table->getShare()->getSchemaName()))
553
void Open_tables_state::doGetTableIdentifiers(CachedDirectory &,
554
const SchemaIdentifier &schema_identifier,
555
TableIdentifier::vector &set_of_identifiers)
722
void Session::doGetTableIdentifiers(CachedDirectory &,
723
const SchemaIdentifier &schema_identifier,
724
TableIdentifiers &set_of_identifiers)
557
726
doGetTableIdentifiers(schema_identifier, set_of_identifiers);
560
bool Open_tables_state::doDoesTableExist(const TableIdentifier &identifier)
729
bool Session::doDoesTableExist(const TableIdentifier &identifier)
562
for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
731
for (Table *table= temporary_tables ; table ; table= table->getNext())
564
733
if (table->getShare()->getType() == message::Table::TEMPORARY)
595
Table *Open_tables_state::find_temporary_table(const TableIdentifier &identifier)
764
Table *Session::find_temporary_table(const char *new_db, const char *table_name)
766
char key[MAX_DBKEY_LENGTH];
769
key_length= TableIdentifier::createKey(key, new_db, table_name);
771
for (Table *table= temporary_tables ; table ; table= table->getNext())
773
const TableIdentifier::Key &share_key(table->getShare()->getCacheKey());
774
if (share_key.size() == key_length &&
775
not memcmp(&share_key[0], key, key_length))
780
return NULL; // Not a temporary table
783
Table *Session::find_temporary_table(TableList *table_list)
785
return find_temporary_table(table_list->db, table_list->table_name);
788
Table *Session::find_temporary_table(TableIdentifier &identifier)
597
790
for (Table *table= temporary_tables ; table ; table= table->getNext())
657
850
@param session Thread context
658
851
@param find Table to remove
660
@note because we risk the chance of deleting the share, we can't assume that it will exist past, this should be modified once we can use a TableShare::shared_ptr here.
663
854
void Session::unlink_open_table(Table *find)
665
const TableIdentifier::Key find_key(find->getShare()->getCacheKey());
667
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
856
char key[MAX_DBKEY_LENGTH];
857
uint32_t key_length= find->getShare()->getCacheKeySize();
859
safe_mutex_assert_owner(LOCK_open.native_handle());
861
memcpy(key, &find->getMutableShare()->getCacheKey()[0], key_length);
670
Note that we need to hold table::Cache::singleton().mutex() while changing the
863
Note that we need to hold LOCK_open while changing the
671
864
open_tables list. Another thread may work on it.
672
(See: table::Cache::singleton().removeTable(), mysql_wait_completed_table())
865
(See: remove_table_from_cache(), mysql_wait_completed_table())
673
866
Closing a MERGE child before the parent would be fatal if the
674
867
other thread tries to abort the MERGE lock in between.
676
869
for (prev= &open_tables; *prev; )
680
if (list->getShare()->getCacheKey() == find_key)
873
if (list->getShare()->getCacheKeySize() == key_length &&
874
not memcmp(&list->getShare()->getCacheKey()[0], key, key_length))
682
876
/* Remove table from open_tables list. */
683
877
*prev= list->getNext();
685
879
/* Close table. */
686
table::remove_table(static_cast<table::Concurrent *>(list));
976
Open table which is already name-locked by this thread.
979
reopen_name_locked_table()
980
session Thread handle
981
table_list TableList object for table to be open, TableList::table
982
member should point to Table object which was used for
984
link_in true - if Table object for table to be opened should be
985
linked into Session::open_tables list.
986
false - placeholder used for name-locking is already in
987
this list so we only need to preserve Table::next
991
This function assumes that its caller already acquired LOCK_open mutex.
998
bool Session::reopen_name_locked_table(TableList* table_list, bool link_in)
1000
Table *table= table_list->table;
1002
char *table_name= table_list->table_name;
1005
safe_mutex_assert_owner(LOCK_open.native_handle());
1007
if (killed || !table)
1012
TableIdentifier identifier(table_list->db, table_list->table_name);
1013
if (open_unireg_entry(this, table, table_name, identifier))
1015
table->intern_close_table();
1017
If there was an error during opening of table (for example if it
1018
does not exist) '*table' object can be wiped out. To be able
1019
properly release name-lock in this case we should restore this
1020
object to its original state.
1026
share= table->getMutableShare();
1028
We want to prevent other connections from opening this table until end
1029
of statement as it is likely that modifications of table's metadata are
1030
not yet finished (for example CREATE TRIGGER have to change .TRG cursor,
1031
or we might want to drop table if CREATE TABLE ... SELECT fails).
1032
This also allows us to assume that no other connection will sneak in
1033
before we will get table-level lock on this table.
1035
share->resetVersion();
1036
table->in_use = this;
1040
table->setNext(open_tables);
1046
Table object should be already in Session::open_tables list so we just
1047
need to set Table::next correctly.
1049
table->setNext(orig_table.getNext());
1052
table->tablenr= current_tablenr++;
1053
table->used_fields= 0;
1054
table->const_table= 0;
1055
table->null_row= false;
1056
table->maybe_null= false;
1057
table->force_index= false;
1058
table->status= STATUS_NO_RECORD;
782
1065
Create and insert into table cache placeholder for table
783
1066
which will prevent its opening (or creation) (a.k.a lock
791
1074
case of failure.
794
table::Placeholder *Session::table_cache_insert_placeholder(const drizzled::TableIdentifier &arg)
1077
Table *Session::table_cache_insert_placeholder(const char *db_name, const char *table_name)
796
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
1079
safe_mutex_assert_owner(LOCK_open.native_handle());
799
1082
Create a table entry with the right key and with an old refresh version
801
TableIdentifier identifier(arg.getSchemaName(), arg.getTableName(), message::Table::INTERNAL);
802
table::Placeholder *table= new table::Placeholder(this, identifier);
1084
TableIdentifier identifier(db_name, table_name, message::Table::INTERNAL);
1085
TablePlaceholder *table= new TablePlaceholder(this, identifier);
804
if (not table::Cache::singleton().insert(table))
1087
if (not add_table(table))
833
1116
@retval true Error occured (OOM)
834
1117
@retval false Success. 'table' parameter set according to above rules.
836
bool Session::lock_table_name_if_not_cached(const TableIdentifier &identifier, Table **table)
1119
bool Session::lock_table_name_if_not_cached(TableIdentifier &identifier, Table **table)
838
1121
const TableIdentifier::Key &key(identifier.getKey());
840
boost_unique_lock_t scope_lock(table::Cache::singleton().mutex()); /* Obtain a name lock even though table is not in cache (like for create table) */
842
table::CacheMap::iterator iter;
844
iter= table::getCache().find(key);
846
if (iter != table::getCache().end())
1123
boost_unique_lock_t scope_lock(LOCK_open); /* Obtain a name lock even though table is not in cache (like for create table) */
1125
TableOpenCache::iterator iter;
1127
iter= get_open_cache().find(key);
1129
if (iter != get_open_cache().end())
852
if (not (*table= table_cache_insert_placeholder(identifier)))
1135
if (not (*table= table_cache_insert_placeholder(identifier.getSchemaName().c_str(), identifier.getTableName().c_str())))
1111
1394
/* Insert a new Table instance into the open cache */
1113
1396
/* Free cache if too big */
1114
table::getUnused().cull();
1397
unused_tables.cull();
1116
1399
if (table_list->isCreate())
1118
TableIdentifier lock_table_identifier(table_list->getSchemaName(), table_list->getTableName(), message::Table::STANDARD);
1401
TableIdentifier lock_table_identifier(table_list->db, table_list->table_name, message::Table::STANDARD);
1120
1403
if (not plugin::StorageEngine::doesTableExist(*this, lock_table_identifier))
1123
1406
Table to be created, so we need to create placeholder in table-cache.
1125
if (!(table= table_cache_insert_placeholder(lock_table_identifier)))
1408
if (!(table= table_cache_insert_placeholder(table_list->db, table_list->table_name)))
1127
table::Cache::singleton().mutex().unlock();
1436
locking::broadcast_refresh();
1718
broadcast_refresh();
1723
Wait until all threads has closed the tables in the list
1724
We have also to wait if there is thread that has a lock on this table even
1725
if the table is closed
1728
bool table_is_used(Table *table, bool wait_for_name_lock)
1732
const TableIdentifier::Key &key(table->getShare()->getCacheKey());
1734
TableOpenCacheRange ppp;
1735
ppp= get_open_cache().equal_range(key);
1737
for (TableOpenCache::const_iterator iter= ppp.first;
1738
iter != ppp.second; ++iter)
1740
Table *search= (*iter).second;
1741
if (search->in_use == table->in_use)
1742
continue; // Name locked by this thread
1744
We can't use the table under any of the following conditions:
1745
- There is an name lock on it (Table is to be deleted or altered)
1746
- If we are in flush table and we didn't execute the flush
1747
- If the table engine is open and it's an old version
1748
(We must wait until all engines are shut down to use the table)
1750
if ( (search->locked_by_name && wait_for_name_lock) ||
1751
(search->is_name_opened() && search->needs_reopen_or_name_lock()))
1754
} while ((table=table->getNext()));
1559
1876
if (table->getShare()->getCacheKey() == identifier.getKey())
1561
1878
/* If MERGE child, forward lock handling to parent. */
1562
session->abortLock(table);
1879
mysql_lock_abort(session, table);
1886
Load a table definition from cursor and open unireg table
1890
session Thread handle
1891
entry Store open table definition here
1892
table_list TableList with db, table_name
1894
cache_key Key for share_cache
1895
cache_key_length length of cache_key
1898
Extra argument for open is taken from session->open_options
1899
One must have a lock on LOCK_open when calling this function
1906
static int open_unireg_entry(Session *session,
1909
TableIdentifier &identifier)
1912
TableSharePtr share;
1913
uint32_t discover_retry_count= 0;
1915
safe_mutex_assert_owner(LOCK_open.native_handle());
1917
if (not (share= TableShare::getShareCreate(session,
1922
while ((error= share->open_table_from_share(session,
1925
(uint32_t) (HA_OPEN_KEYFILE |
1929
session->open_options, *entry)))
1931
if (error == 7) // Table def changed
1933
share->resetVersion(); // Mark share as old
1934
if (discover_retry_count++) // Retry once
1939
Here we should wait until all threads has released the table.
1940
For now we do one retry. This may cause a deadlock if there
1941
is other threads waiting for other tables used by this thread.
1943
Proper fix would be to if the second retry failed:
1944
- Mark that table def changed
1945
- Return from open table
1946
- Close all tables used by this thread
1947
- Start waiting that the share is released
1948
- Retry by opening all tables again
1953
To avoid deadlock, only wait for release if no one else is
1956
if (share->getTableCount() != 1)
1958
/* Free share and wait until it's released by all threads */
1959
TableShare::release(share);
1961
if (!session->killed)
1963
drizzle_reset_errors(session, 1); // Clear warnings
1964
session->clear_error(); // Clear error message
1976
TableShare::release(share);
1570
1983
Open all tables in list
1837
Table *Open_tables_state::open_temporary_table(const TableIdentifier &identifier,
2251
Table *Session::open_temporary_table(TableIdentifier &identifier,
1840
2256
assert(identifier.isTmp());
1843
table::Temporary *new_tmp_table= new table::Temporary(identifier.getType(),
1845
const_cast<char *>(const_cast<TableIdentifier&>(identifier).getPath().c_str()),
1846
static_cast<uint32_t>(identifier.getPath().length()));
2257
share= new TableShare(identifier.getType(),
2259
const_cast<char *>(identifier.getPath().c_str()), static_cast<uint32_t>(identifier.getPath().length()));
2262
Table *new_tmp_table= new Table;
1847
2263
if (not new_tmp_table)
1851
2267
First open the share, and then open the table from the share we just opened.
1853
if (new_tmp_table->getMutableShare()->open_table_def(*static_cast<Session *>(this), identifier) ||
1854
new_tmp_table->getMutableShare()->open_table_from_share(static_cast<Session *>(this), identifier, identifier.getTableName().c_str(),
1855
(uint32_t) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
2269
if (share->open_table_def(*this, identifier) ||
2270
share->open_table_from_share(this, identifier, identifier.getTableName().c_str(),
2271
(uint32_t) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
1860
2276
/* No need to lock share->mutex as this is not needed for tmp tables */
1861
delete new_tmp_table->getMutableShare();
1862
2278
delete new_tmp_table;
3958
4380
unireg support functions
3959
4381
*****************************************************************************/
4384
Invalidate any cache entries that are for some DB
4387
remove_db_from_cache()
4388
db Database name. This will be in lower case if
4389
lower_case_table_name is set
4392
We can't use hash_delete when looping hash_elements. We mark them first
4393
and afterwards delete those marked unused.
4396
void remove_db_from_cache(const SchemaIdentifier &schema_identifier)
4398
safe_mutex_assert_owner(LOCK_open.native_handle());
4400
for (TableOpenCache::const_iterator iter= get_open_cache().begin();
4401
iter != get_open_cache().end();
4404
Table *table= (*iter).second;
4406
if (not schema_identifier.getPath().compare(table->getMutableShare()->getSchemaName()))
4408
table->getMutableShare()->resetVersion(); /* Free when thread is ready */
4409
if (not table->in_use)
4410
unused_tables.relink(table);
4414
unused_tables.cullByVersion();
4419
Mark all entries with the table as deleted to force an reopen of the table
4421
The table will be closed (not stored in cache) by the current thread when
4422
close_thread_tables() is called.
4428
0 This thread now have exclusive access to this table and no other thread
4429
can access the table until close_thread_tables() is called.
4430
1 Table is in use by another thread
4433
bool remove_table_from_cache(Session *session, TableIdentifier &identifier, uint32_t flags)
4435
const TableIdentifier::Key &key(identifier.getKey());
4437
bool signalled= false;
4441
result= signalled= false;
4443
TableOpenCacheRange ppp;
4444
ppp= get_open_cache().equal_range(key);
4446
for (TableOpenCache::const_iterator iter= ppp.first;
4447
iter != ppp.second; ++iter)
4449
Table *table= (*iter).second;
4452
table->getMutableShare()->resetVersion(); /* Free when thread is ready */
4453
if (!(in_use=table->in_use))
4455
unused_tables.relink(table);
4457
else if (in_use != session)
4460
Mark that table is going to be deleted from cache. This will
4461
force threads that are in mysql_lock_tables() (but not yet
4462
in thr_multi_lock()) to abort it's locks, close all tables and retry
4464
in_use->some_tables_deleted= true;
4465
if (table->is_name_opened())
4470
Now we must abort all tables locks used by this thread
4471
as the thread may be waiting to get a lock for another table.
4472
Note that we need to hold LOCK_open while going through the
4473
list. So that the other thread cannot change it. The other
4474
thread must also hold LOCK_open whenever changing the
4475
open_tables list. Aborting the MERGE lock after a child was
4476
closed and before the parent is closed would be fatal.
4478
for (Table *session_table= in_use->open_tables;
4480
session_table= session_table->getNext())
4482
/* Do not handle locks of MERGE children. */
4483
if (session_table->db_stat) // If table is open
4484
signalled|= mysql_lock_abort_for_thread(session, session_table);
4488
result= result || (flags & RTFC_OWNED_BY_Session_FLAG);
4491
unused_tables.cullByVersion();
4493
/* Remove table from table definition cache if it's not in use */
4494
TableShare::release(identifier);
4496
if (result && (flags & RTFC_WAIT_OTHER_THREAD_FLAG))
4499
Signal any thread waiting for tables to be freed to
4502
broadcast_refresh();
4503
if (!(flags & RTFC_CHECK_KILLED_FLAG) || !session->killed)
4506
if (likely(signalled))
4508
boost_unique_lock_t scoped(LOCK_open, boost::adopt_lock_t());
4509
COND_refresh.wait(scoped);
4515
It can happen that another thread has opened the
4516
table but has not yet locked any table at all. Since
4517
it can be locked waiting for a table that our thread
4518
has done LOCK Table x WRITE on previously, we need to
4519
ensure that the thread actually hears our signal
4520
before we go to sleep. Thus we wait for a short time
4521
and then we retry another loop in the
4522
remove_table_from_cache routine.
4525
xtime_get(&xt, boost::TIME_UTC);
4527
boost_unique_lock_t scoped(LOCK_open, boost::adopt_lock_t());
4528
COND_refresh.timed_wait(scoped, xt);