110
void write_bin_log(Session *session, const std::string &query)
108
void write_bin_log(Session *session,
112
111
TransactionServices &transaction_services= TransactionServices::singleton();
113
112
transaction_services.rawStatement(session, query);
116
/* Should should be refactored to go away */
117
void write_bin_log_drop_table(Session *session, bool if_exists, const char *db_name, const char *table_name)
119
TransactionServices &transaction_services= TransactionServices::singleton();
123
built_query.append("DROP TABLE IF EXISTS ");
125
built_query.append("DROP TABLE ");
127
built_query.append("`");
128
if (session->db.empty() || strcmp(db_name, session->db.c_str()) != 0)
130
built_query.append(db_name);
131
built_query.append("`.`");
134
built_query.append(table_name);
135
built_query.append("`");
136
transaction_services.rawStatement(session, built_query);
117
140
Execute the drop of a normal or temporary table
149
172
bool foreign_key_error= false;
152
table::Cache::singleton().mutex().lock(); /* Part 2 of rm a table */
154
if (not drop_temporary && session->lock_table_names_exclusively(tables))
156
table::Cache::singleton().mutex().unlock();
160
/* Don't give warnings for not found errors, as we already generate notes */
161
session->no_warnings_for_error= 1;
163
for (table= tables; table; table= table->next_local)
165
TableIdentifier tmp_identifier(table->getSchemaName(), table->getTableName());
167
error= session->drop_temporary_table(tmp_identifier);
171
// removed temporary table
174
pthread_mutex_lock(&LOCK_open); /* Part 2 of rm a table */
177
If we have the table in the definition cache, we don't have to check the
178
.frm cursor to find if the table is a normal table (not view) and what
182
for (table= tables; table; table= table->next_local)
184
TableIdentifier identifier(table->db, table->table_name);
186
table->setDbType(NULL);
188
if ((share= TableShare::getShare(identifier)))
190
table->setDbType(share->db_type());
194
if (not drop_temporary && lock_table_names_exclusively(session, tables))
196
pthread_mutex_unlock(&LOCK_open);
200
/* Don't give warnings for not found errors, as we already generate notes */
201
session->no_warnings_for_error= 1;
203
for (table= tables; table; table= table->next_local)
207
error= session->drop_temporary_table(table);
211
// removed temporary table
215
goto err_with_placeholders;
217
// temporary table not found
221
if (drop_temporary == false)
224
TableIdentifier identifier(db, table->table_name);
225
abort_locked_tables(session, identifier);
226
remove_table_from_cache(session, identifier,
227
RTFC_WAIT_OTHER_THREAD_FLAG |
228
RTFC_CHECK_KILLED_FLAG);
230
If the table was used in lock tables, remember it so that
231
unlock_table_names can free it
233
if ((locked_table= drop_locked_tables(session, identifier)))
234
table->table= locked_table;
239
goto err_with_placeholders;
242
TableIdentifier identifier(db, table->table_name, table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
244
if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, identifier))
246
// Table was not found on disk and table can't be created from engine
248
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
249
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
175
goto err_with_placeholders;
177
// temporary table not found
256
error= plugin::StorageEngine::dropTable(*session, identifier);
258
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && if_exists)
181
if (drop_temporary == false)
184
abort_locked_tables(session, tmp_identifier);
185
table::Cache::singleton().removeTable(session, tmp_identifier,
186
RTFC_WAIT_OTHER_THREAD_FLAG |
187
RTFC_CHECK_KILLED_FLAG);
189
If the table was used in lock tables, remember it so that
190
unlock_table_names can free it
192
if ((locked_table= drop_locked_tables(session, tmp_identifier)))
193
table->table= locked_table;
195
if (session->getKilled())
198
goto err_with_placeholders;
201
TableIdentifier identifier(table->getSchemaName(), table->getTableName(), table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
203
if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, identifier))
205
// Table was not found on disk and table can't be created from engine
207
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
208
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
209
table->getTableName());
215
error= plugin::StorageEngine::dropTable(*session, identifier);
217
if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && if_exists)
220
session->clear_error();
223
if (error == HA_ERR_ROW_IS_REFERENCED)
225
/* the table is referenced by a foreign key constraint */
226
foreign_key_error= true;
230
if (error == 0 || (if_exists && foreign_key_error == false))
232
TransactionServices &transaction_services= TransactionServices::singleton();
233
transaction_services.dropTable(session, string(table->getSchemaName()), string(table->getTableName()), if_exists);
238
if (wrong_tables.length())
239
wrong_tables.append(',');
240
wrong_tables.append(String(table->getTableName(), system_charset_info));
244
It's safe to unlock table::Cache::singleton().mutex(): we have an exclusive lock
247
table::Cache::singleton().mutex().unlock();
261
session->clear_error();
264
if (error == HA_ERR_ROW_IS_REFERENCED)
266
/* the table is referenced by a foreign key constraint */
267
foreign_key_error= true;
271
if (error == 0 || (if_exists && foreign_key_error == false))
273
TransactionServices &transaction_services= TransactionServices::singleton();
274
transaction_services.dropTable(session, string(db), string(table->table_name), if_exists);
279
if (wrong_tables.length())
280
wrong_tables.append(',');
281
wrong_tables.append(String(table->table_name,system_charset_info));
285
It's safe to unlock LOCK_open: we have an exclusive lock
288
pthread_mutex_unlock(&LOCK_open);
251
291
if (wrong_tables.length())
1822
1860
/* Close all instances of the table to allow repair to rename files */
1823
1861
if (lock_type == TL_WRITE && table->table->getShare()->getVersion())
1825
table::Cache::singleton().mutex().lock(); /* Lock type is TL_WRITE and we lock to repair the table */
1826
const char *old_message=session->enter_cond(COND_refresh, table::Cache::singleton().mutex(),
1827
"Waiting to get writelock");
1828
session->abortLock(table->table);
1829
TableIdentifier identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1830
table::Cache::singleton().removeTable(session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG);
1863
pthread_mutex_lock(&LOCK_open); /* Lock type is TL_WRITE and we lock to repair the table */
1864
const char *old_message=session->enter_cond(&COND_refresh, &LOCK_open,
1865
"Waiting to get writelock");
1866
mysql_lock_abort(session,table->table);
1867
TableIdentifier identifier(table->table->getMutableShare()->getSchemaName(), table->table->getMutableShare()->getTableName());
1868
remove_table_from_cache(session, identifier,
1869
RTFC_WAIT_OTHER_THREAD_FLAG |
1870
RTFC_CHECK_KILLED_FLAG);
1831
1871
session->exit_cond(old_message);
1832
if (session->getKilled())
1872
if (session->killed)
1834
1874
open_for_modify= 0;
1959
2000
Altough exclusive name-lock on target table protects us from concurrent
1960
2001
DML and DDL operations on it we still want to wrap .FRM creation and call
1961
2002
to plugin::StorageEngine::createTable() in critical section protected by
1962
table::Cache::singleton().mutex() in order to provide minimal atomicity against operations which
2003
LOCK_open in order to provide minimal atomicity against operations which
1963
2004
disregard name-locks, like I_S implementation, for example. This is a
1964
2005
temporary and should not be copied. Instead we should fix our code to
1965
2006
always honor name-locks.
1967
Also some engines (e.g. NDB cluster) require that table::Cache::singleton().mutex() should be held
2008
Also some engines (e.g. NDB cluster) require that LOCK_open should be held
1968
2009
during the call to plugin::StorageEngine::createTable().
1969
2010
See bug #28614 for more info.
1971
2012
static bool create_table_wrapper(Session &session, const message::Table& create_table_proto,
1972
const TableIdentifier &destination_identifier,
1973
const TableIdentifier &src_table,
2013
TableIdentifier &destination_identifier,
2014
TableIdentifier &src_table,
1974
2015
bool is_engine_set)
1976
2017
int protoerr= EEXIST;
1977
2018
message::Table new_proto;
1978
message::table::shared_ptr src_proto;
2019
message::Table src_proto;
1980
2021
protoerr= plugin::StorageEngine::getTableDefinition(session,
1983
new_proto.CopyFrom(*src_proto);
2024
new_proto.CopyFrom(src_proto);
1985
2026
if (destination_identifier.isTmp())
2130
2174
else // Otherwise we create the table
2134
boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* We lock for CREATE TABLE LIKE to copy table definition */
2135
was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2136
src_identifier, is_engine_set);
2176
pthread_mutex_lock(&LOCK_open); /* We lock for CREATE TABLE LIKE to copy table definition */
2177
bool was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2178
src_identifier, is_engine_set);
2179
pthread_mutex_unlock(&LOCK_open);
2139
2181
// So we blew the creation of the table, and we scramble to clean up
2140
2182
// anything that might have been created (read... it is a hack)
2141
2183
if (not was_created)
2143
plugin::StorageEngine::dropTable(*session, destination_identifier);
2185
quick_rm_table(*session, destination_identifier);