64
65
extern bool volatile shutdown_in_progress;
66
TableOpenCache &get_open_cache()
68
static TableOpenCache open_cache; /* Used by mysql_test */
73
static void free_cache_entry(table::Concurrent *entry);
75
void remove_table(table::Concurrent *arg)
77
TableOpenCacheRange ppp;
78
ppp= get_open_cache().equal_range(arg->getShare()->getCacheKey());
80
for (TableOpenCache::const_iterator iter= ppp.first;
81
iter != ppp.second; ++iter)
83
table::Concurrent *found_table= (*iter).second;
85
if (found_table == arg)
87
free_cache_entry(arg);
88
get_open_cache().erase(iter);
94
67
static bool add_table(table::Concurrent *arg)
96
TableOpenCache &open_cache(get_open_cache());
69
table::CacheMap &open_cache(table::getCache());
98
TableOpenCache::iterator returnable= open_cache.insert(make_pair(arg->getShare()->getCacheKey(), arg));
71
table::CacheMap::iterator returnable= open_cache.insert(make_pair(arg->getShare()->getCacheKey(), arg));
100
73
return not (returnable == open_cache.end());
104
table::Concurrent *tables; /* Used by mysql_test */
106
table::Concurrent *getTable() const
111
table::Concurrent *setTable(Table *arg)
113
return tables= static_cast<table::Concurrent *>(arg);
120
/* Free cache if too big */
121
while (cached_open_tables() > table_cache_size && getTable())
122
remove_table(getTable());
127
while (getTable() && not getTable()->getShare()->getVersion())
128
remove_table(getTable());
131
void link(table::Concurrent *table)
135
table->setNext(getTable()); /* Link in last */
136
table->setPrev(getTable()->getPrev());
137
getTable()->setPrev(table);
138
table->getPrev()->setNext(table);
142
table->setPrev(setTable(table));
143
table->setNext(table->getPrev());
144
assert(table->getNext() == table && table->getPrev() == table);
149
void unlink(table::Concurrent *table)
153
/* Unlink the table from "unused_tables" list. */
154
if (table == getTable())
156
setTable(getTable()->getNext()); // Remove from link
157
if (table == getTable())
162
/* move table first in unused links */
164
void relink(table::Concurrent *table)
166
if (table != getTable())
170
table->setNext(getTable()); /* Link in unused tables */
171
table->setPrev(getTable()->getPrev());
172
getTable()->getPrev()->setNext(table);
173
getTable()->setPrev(table);
182
remove_table(getTable());
194
static UnusedTables unused_tables;
196
76
bool table_cache_init(void)
1592
Wait until all threads has closed the tables in the list
1593
We have also to wait if there is thread that has a lock on this table even
1594
if the table is closed
1597
bool table_is_used(Table *table, bool wait_for_name_lock)
1601
const TableIdentifier::Key &key(table->getShare()->getCacheKey());
1603
TableOpenCacheRange ppp;
1604
ppp= get_open_cache().equal_range(key);
1606
for (TableOpenCache::const_iterator iter= ppp.first;
1607
iter != ppp.second; ++iter)
1609
Table *search= (*iter).second;
1610
if (search->in_use == table->in_use)
1611
continue; // Name locked by this thread
1613
We can't use the table under any of the following conditions:
1614
- There is an name lock on it (Table is to be deleted or altered)
1615
- If we are in flush table and we didn't execute the flush
1616
- If the table engine is open and it's an old version
1617
(We must wait until all engines are shut down to use the table)
1619
if ( (search->locked_by_name && wait_for_name_lock) ||
1620
(search->is_name_opened() && search->needs_reopen_or_name_lock()))
1623
} while ((table=table->getNext()));
1628
1449
/* Wait until all used tables are refreshed */
1630
1451
bool wait_for_tables(Session *session)
4146
3969
unireg support functions
4147
3970
*****************************************************************************/
4150
Invalidate any cache entries that are for some DB
4153
remove_db_from_cache()
4154
db Database name. This will be in lower case if
4155
lower_case_table_name is set
4158
We can't use hash_delete when looping hash_elements. We mark them first
4159
and afterwards delete those marked unused.
4162
void remove_db_from_cache(const SchemaIdentifier &schema_identifier)
4164
safe_mutex_assert_owner(LOCK_open.native_handle());
4166
for (TableOpenCache::const_iterator iter= get_open_cache().begin();
4167
iter != get_open_cache().end();
4170
table::Concurrent *table= (*iter).second;
4172
if (not schema_identifier.getPath().compare(table->getShare()->getSchemaName()))
4174
table->getMutableShare()->resetVersion(); /* Free when thread is ready */
4175
if (not table->in_use)
4176
unused_tables.relink(table);
4180
unused_tables.cullByVersion();
4185
Mark all entries with the table as deleted to force an reopen of the table
4187
The table will be closed (not stored in cache) by the current thread when
4188
close_thread_tables() is called.
4194
0 This thread now have exclusive access to this table and no other thread
4195
can access the table until close_thread_tables() is called.
4196
1 Table is in use by another thread
4199
bool remove_table_from_cache(Session *session, TableIdentifier &identifier, uint32_t flags)
4201
const TableIdentifier::Key &key(identifier.getKey());
4203
bool signalled= false;
4207
result= signalled= false;
4209
TableOpenCacheRange ppp;
4210
ppp= get_open_cache().equal_range(key);
4212
for (TableOpenCache::const_iterator iter= ppp.first;
4213
iter != ppp.second; ++iter)
4215
table::Concurrent *table= (*iter).second;
4218
table->getMutableShare()->resetVersion(); /* Free when thread is ready */
4219
if (not (in_use= table->in_use))
4221
unused_tables.relink(table);
4223
else if (in_use != session)
4226
Mark that table is going to be deleted from cache. This will
4227
force threads that are in mysql_lock_tables() (but not yet
4228
in thr_multi_lock()) to abort it's locks, close all tables and retry
4230
in_use->some_tables_deleted= true;
4231
if (table->is_name_opened())
4236
Now we must abort all tables locks used by this thread
4237
as the thread may be waiting to get a lock for another table.
4238
Note that we need to hold LOCK_open while going through the
4239
list. So that the other thread cannot change it. The other
4240
thread must also hold LOCK_open whenever changing the
4241
open_tables list. Aborting the MERGE lock after a child was
4242
closed and before the parent is closed would be fatal.
4244
for (Table *session_table= in_use->open_tables;
4246
session_table= session_table->getNext())
4248
/* Do not handle locks of MERGE children. */
4249
if (session_table->db_stat) // If table is open
4250
signalled|= mysql_lock_abort_for_thread(session, session_table);
4255
result= result || (flags & RTFC_OWNED_BY_Session_FLAG);
4259
unused_tables.cullByVersion();
4261
/* Remove table from table definition cache if it's not in use */
4262
TableShare::release(identifier);
4264
if (result && (flags & RTFC_WAIT_OTHER_THREAD_FLAG))
4267
Signal any thread waiting for tables to be freed to
4270
broadcast_refresh();
4271
if (!(flags & RTFC_CHECK_KILLED_FLAG) || !session->killed)
4274
if (likely(signalled))
4276
boost_unique_lock_t scoped(LOCK_open, boost::adopt_lock_t());
4277
COND_refresh.wait(scoped);
4283
It can happen that another thread has opened the
4284
table but has not yet locked any table at all. Since
4285
it can be locked waiting for a table that our thread
4286
has done LOCK Table x WRITE on previously, we need to
4287
ensure that the thread actually hears our signal
4288
before we go to sleep. Thus we wait for a short time
4289
and then we retry another loop in the
4290
remove_table_from_cache routine.
4293
xtime_get(&xt, boost::TIME_UTC);
4295
boost_unique_lock_t scoped(LOCK_open, boost::adopt_lock_t());
4296
COND_refresh.timed_wait(scoped, xt);