42
Open table which is already name-locked by this thread.
45
reopen_name_locked_table()
47
table_list TableList object for table to be open, TableList::table
48
member should point to Table object which was used for
50
link_in true - if Table object for table to be opened should be
51
linked into Session::open_tables list.
52
false - placeholder used for name-locking is already in
53
this list so we only need to preserve Table::next
57
This function assumes that its caller already acquired table::Cache::singleton().mutex() mutex.
64
bool Concurrent::reopen_name_locked_table(TableList* table_list, Session *session)
66
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
68
if (session->getKilled())
71
identifier::Table identifier(table_list->getSchemaName(), table_list->getTableName());
72
if (open_unireg_entry(session, table_list->getTableName(), identifier))
79
We want to prevent other connections from opening this table until end
80
of statement as it is likely that modifications of table's metadata are
81
not yet finished (for example CREATE TRIGGER have to change .TRG cursor,
82
or we might want to drop table if CREATE TABLE ... SELECT fails).
83
This also allows us to assume that no other connection will sneak in
84
before we will get table-level lock on this table.
86
getMutableShare()->resetVersion();
89
tablenr= session->current_tablenr++;
95
status= STATUS_NO_RECORD;
102
Load a table definition from cursor and open unireg table
106
session Thread handle
107
entry Store open table definition here
108
table_list TableList with db, table_name
110
cache_key Key for share_cache
111
cache_key_length length of cache_key
114
Extra argument for open is taken from session->open_options
115
One must have a lock on table::Cache::singleton().mutex() when calling this function
122
int table::Concurrent::open_unireg_entry(Session *session,
124
identifier::Table &identifier)
127
TableShare::shared_ptr share;
128
uint32_t discover_retry_count= 0;
130
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
132
if (not (share= table::instance::Shared::make_shared(session,
139
while ((error= share->open_table_from_share(session,
142
(uint32_t) (HA_OPEN_KEYFILE |
146
session->open_options, *this)))
148
if (error == 7) // Table def changed
150
share->resetVersion(); // Mark share as old
151
if (discover_retry_count++) // Retry once
153
table::instance::release(share);
159
Here we should wait until all threads has released the table.
160
For now we do one retry. This may cause a deadlock if there
161
is other threads waiting for other tables used by this thread.
163
Proper fix would be to if the second retry failed:
164
- Mark that table def changed
165
- Return from open table
166
- Close all tables used by this thread
167
- Start waiting that the share is released
168
- Retry by opening all tables again
173
To avoid deadlock, only wait for release if no one else is
176
if (share->getTableCount() != 1)
178
table::instance::release(share);
182
/* Free share and wait until it's released by all threads */
183
table::instance::release(share);
185
if (not session->getKilled())
187
drizzle_reset_errors(session, 1); // Clear warnings
188
session->clear_error(); // Clear error message
195
table::instance::release(share);
203
void table::Concurrent::release(void)
205
// During an ALTER TABLE we could see the proto go away when the
206
// definition is pushed out of this table object. In this case we would
207
// not release from the cache because we were not in the cache. We just
208
// delete if this happens.
209
if (getShare()->getType() == message::Table::STANDARD)
211
table::instance::release(getMutableShare());
220
39
} /* namespace table */
221
40
} /* namespace drizzled */