40
Open table which is already name-locked by this thread.
43
reopen_name_locked_table()
45
table_list TableList object for table to be open, TableList::table
46
member should point to Table object which was used for
48
link_in true - if Table object for table to be opened should be
49
linked into Session::open_tables list.
50
false - placeholder used for name-locking is already in
51
this list so we only need to preserve Table::next
55
This function assumes that its caller already acquired LOCK_open mutex.
62
bool Concurrent::reopen_name_locked_table(TableList* table_list, Session *session)
64
safe_mutex_assert_owner(LOCK_open.native_handle());
69
TableIdentifier identifier(table_list->getSchemaName(), table_list->getTableName());
70
if (open_unireg_entry(session, table_list->getTableName(), identifier))
77
We want to prevent other connections from opening this table until end
78
of statement as it is likely that modifications of table's metadata are
79
not yet finished (for example CREATE TRIGGER have to change .TRG cursor,
80
or we might want to drop table if CREATE TABLE ... SELECT fails).
81
This also allows us to assume that no other connection will sneak in
82
before we will get table-level lock on this table.
84
getMutableShare()->resetVersion();
87
tablenr= session->current_tablenr++;
93
status= STATUS_NO_RECORD;
100
Load a table definition from cursor and open unireg table
104
session Thread handle
105
entry Store open table definition here
106
table_list TableList with db, table_name
108
cache_key Key for share_cache
109
cache_key_length length of cache_key
112
Extra argument for open is taken from session->open_options
113
One must have a lock on LOCK_open when calling this function
120
int table::Concurrent::open_unireg_entry(Session *session,
122
TableIdentifier &identifier)
126
uint32_t discover_retry_count= 0;
128
safe_mutex_assert_owner(LOCK_open.native_handle());
130
if (not (share= TableShare::getShareCreate(session,
135
while ((error= share->open_table_from_share(session,
138
(uint32_t) (HA_OPEN_KEYFILE |
142
session->open_options, *this)))
144
if (error == 7) // Table def changed
146
share->resetVersion(); // Mark share as old
147
if (discover_retry_count++) // Retry once
149
TableShare::release(share);
155
Here we should wait until all threads has released the table.
156
For now we do one retry. This may cause a deadlock if there
157
is other threads waiting for other tables used by this thread.
159
Proper fix would be to if the second retry failed:
160
- Mark that table def changed
161
- Return from open table
162
- Close all tables used by this thread
163
- Start waiting that the share is released
164
- Retry by opening all tables again
169
To avoid deadlock, only wait for release if no one else is
172
if (share->getTableCount() != 1)
174
TableShare::release(share);
177
/* Free share and wait until it's released by all threads */
178
TableShare::release(share);
180
if (!session->killed)
182
drizzle_reset_errors(session, 1); // Clear warnings
183
session->clear_error(); // Clear error message
189
TableShare::release(share);
39
197
} /* namespace table */
40
198
} /* namespace drizzled */