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->db_type= NULL;
188
if ((share= TableShare::getShare(identifier)))
190
table->db_type= 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
abort_locked_tables(session, db, table->table_name);
225
remove_table_from_cache(session, db, table->table_name,
226
RTFC_WAIT_OTHER_THREAD_FLAG |
227
RTFC_CHECK_KILLED_FLAG);
229
If the table was used in lock tables, remember it so that
230
unlock_table_names can free it
232
if ((locked_table= drop_locked_tables(session, db, table->table_name)))
233
table->table= locked_table;
238
goto err_with_placeholders;
241
TableIdentifier identifier(db, table->table_name, table->internal_tmp_table ? message::Table::INTERNAL : message::Table::STANDARD);
243
if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, identifier))
245
// Table was not found on disk and table can't be created from engine
247
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
248
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
175
goto err_with_placeholders;
177
// temporary table not found
255
error= plugin::StorageEngine::dropTable(*session, identifier);
257
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();
260
session->clear_error();
263
if (error == HA_ERR_ROW_IS_REFERENCED)
265
/* the table is referenced by a foreign key constraint */
266
foreign_key_error= true;
270
if (error == 0 || (if_exists && foreign_key_error == false))
272
TransactionServices &transaction_services= TransactionServices::singleton();
273
transaction_services.dropTable(session, string(db), string(table->table_name), if_exists);
278
if (wrong_tables.length())
279
wrong_tables.append(',');
280
wrong_tables.append(String(table->table_name,system_charset_info));
284
It's safe to unlock LOCK_open: we have an exclusive lock
287
pthread_mutex_unlock(&LOCK_open);
251
290
if (wrong_tables.length())
1423
1459
assert(identifier.getTableName() == table_proto.name());
1424
1460
db_options= create_info->table_options;
1462
if (create_info->row_type == ROW_TYPE_DYNAMIC)
1463
db_options|=HA_OPTION_PACK_RECORD;
1426
1465
set_table_default_charset(create_info, identifier.getSchemaName().c_str());
1428
1467
/* Build a Table object to pass down to the engine, and the do the actual create. */
1429
1468
if (not mysql_prepare_create_table(session, create_info, table_proto, alter_info,
1432
&key_info_buffer, &key_count,
1433
select_field_count))
1471
&key_info_buffer, &key_count,
1472
select_field_count))
1435
boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* CREATE TABLE (some confussion on naming, double check) */
1474
pthread_mutex_lock(&LOCK_open); /* CREATE TABLE (some confussion on naming, double check) */
1436
1475
error= locked_create_event(session,
1822
1857
/* Close all instances of the table to allow repair to rename files */
1823
if (lock_type == TL_WRITE && table->table->getShare()->getVersion())
1858
if (lock_type == TL_WRITE && table->table->getShare()->version)
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);
1860
pthread_mutex_lock(&LOCK_open); /* Lock type is TL_WRITE and we lock to repair the table */
1861
const char *old_message=session->enter_cond(&COND_refresh, &LOCK_open,
1862
"Waiting to get writelock");
1863
mysql_lock_abort(session,table->table);
1864
remove_table_from_cache(session, table->table->getMutableShare()->getSchemaName(),
1865
table->table->getMutableShare()->getTableName(),
1866
RTFC_WAIT_OTHER_THREAD_FLAG |
1867
RTFC_CHECK_KILLED_FLAG);
1831
1868
session->exit_cond(old_message);
1832
if (session->getKilled())
1869
if (session->killed)
1834
1871
open_for_modify= 0;
1991
We have to write the query before we unlock the named table.
1993
Since temporary tables are not replicated under row-based
1994
replication, CREATE TABLE ... LIKE ... needs special
1995
treatement. We have four cases to consider, according to the
1996
following decision table:
1998
==== ========= ========= ==============================
1999
Case Target Source Write to binary log
2000
==== ========= ========= ==============================
2001
1 normal normal Original statement
2002
2 normal temporary Generated statement
2003
3 temporary normal Nothing
2004
4 temporary temporary Nothing
2005
==== ========= ========= ==============================
2007
static bool replicateCreateTableLike(Session *session, TableList *table, Table *name_lock,
2008
bool is_src_table_tmp, bool is_if_not_exists)
2010
if (is_src_table_tmp)
2013
String query(buf, sizeof(buf), system_charset_info);
2014
query.length(0); // Have to zero it since constructor doesn't
2018
Here we open the destination table, on which we already have
2019
name-lock. This is needed for store_create_info() to work.
2020
The table will be closed by unlink_open_table() at the end
2023
table->table= name_lock;
2024
pthread_mutex_lock(&LOCK_open); /* Open new table we have just acquired */
2025
if (session->reopen_name_locked_table(table, false))
2027
pthread_mutex_unlock(&LOCK_open);
2030
pthread_mutex_unlock(&LOCK_open);
2032
int result= store_create_info(table, &query, is_if_not_exists);
2034
assert(result == 0); // store_create_info() always return 0
2035
write_bin_log(session, query.ptr());
2039
write_bin_log(session, session->query.c_str());
1957
2046
Create a new table by copying from source table
1959
2048
Altough exclusive name-lock on target table protects us from concurrent
1960
2049
DML and DDL operations on it we still want to wrap .FRM creation and call
1961
2050
to plugin::StorageEngine::createTable() in critical section protected by
1962
table::Cache::singleton().mutex() in order to provide minimal atomicity against operations which
2051
LOCK_open in order to provide minimal atomicity against operations which
1963
2052
disregard name-locks, like I_S implementation, for example. This is a
1964
2053
temporary and should not be copied. Instead we should fix our code to
1965
2054
always honor name-locks.
1967
Also some engines (e.g. NDB cluster) require that table::Cache::singleton().mutex() should be held
2056
Also some engines (e.g. NDB cluster) require that LOCK_open should be held
1968
2057
during the call to plugin::StorageEngine::createTable().
1969
2058
See bug #28614 for more info.
1971
2060
static bool create_table_wrapper(Session &session, const message::Table& create_table_proto,
1972
const TableIdentifier &destination_identifier,
1973
const TableIdentifier &src_table,
2061
TableIdentifier &destination_identifier,
2062
TableIdentifier &src_table,
1974
2063
bool is_engine_set)
1976
2065
int protoerr= EEXIST;
1977
2066
message::Table new_proto;
1978
message::table::shared_ptr src_proto;
2067
message::Table src_proto;
1980
2069
protoerr= plugin::StorageEngine::getTableDefinition(session,
1983
new_proto.CopyFrom(*src_proto);
2072
new_proto.CopyFrom(src_proto);
1985
2074
if (destination_identifier.isTmp())
2081
2166
bool table_exists= false;
2082
2167
if (destination_identifier.isTmp())
2084
if (session->find_temporary_table(destination_identifier))
2169
if (session->find_temporary_table(db, table_name))
2086
2171
table_exists= true;
2090
2175
bool was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2091
src_identifier, is_engine_set);
2176
src_identifier, is_engine_set);
2092
2177
if (not was_created) // This is pretty paranoid, but we assume something might not clean up after itself
2094
(void) session->rm_temporary_table(destination_identifier, true);
2179
(void) session->rm_temporary_table(destination_identifier);
2096
2181
else if (not session->open_temporary_table(destination_identifier))
2098
2183
// We created, but we can't open... also, a hack.
2099
(void) session->rm_temporary_table(destination_identifier, true);
2184
(void) session->rm_temporary_table(destination_identifier);
2130
2216
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);
2218
pthread_mutex_lock(&LOCK_open); /* We lock for CREATE TABLE LIKE to copy table definition */
2219
bool was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2220
src_identifier, is_engine_set);
2221
pthread_mutex_unlock(&LOCK_open);
2139
2223
// So we blew the creation of the table, and we scramble to clean up
2140
2224
// anything that might have been created (read... it is a hack)
2141
2225
if (not was_created)
2143
plugin::StorageEngine::dropTable(*session, destination_identifier);
2227
quick_rm_table(*session, destination_identifier);
2231
bool rc= replicateCreateTableLike(session, table, name_lock, (src_table->table->getShare()->tmp_table), is_if_not_exists);
2153
boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* unlink open tables for create table like*/
2240
pthread_mutex_lock(&LOCK_open); /* unlink open tables for create table like*/
2154
2241
session->unlink_open_table(name_lock);
2242
pthread_mutex_unlock(&LOCK_open);