134
133
#include <google/protobuf/io/coded_stream.h>
135
134
#include <google/protobuf/text_format.h>
136
#include <boost/thread/mutex.hpp>
137
138
using namespace std;
138
139
using namespace drizzled;
140
141
/** to protect innobase_open_files */
141
static pthread_mutex_t innobase_share_mutex;
142
static boost::mutex innobase_share_mutex;
142
144
/** to force correct commit order in binlog */
143
static pthread_mutex_t prepare_commit_mutex;
144
145
static ulong commit_threads = 0;
145
static pthread_mutex_t commit_threads_m;
146
static pthread_cond_t commit_cond;
147
static pthread_mutex_t commit_cond_m;
146
static boost::condition_variable commit_cond;
147
static boost::mutex commit_cond_m;
148
148
static bool innodb_inited = 0;
150
150
#define INSIDE_HA_INNOBASE_CC
160
160
#endif /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
162
162
static plugin::XaStorageEngine* innodb_engine_ptr= NULL;
163
static plugin::TableFunction* status_table_function_ptr= NULL;
164
static plugin::TableFunction* cmp_tool= NULL;
165
static plugin::TableFunction* cmp_reset_tool= NULL;
166
static plugin::TableFunction* cmp_mem_tool= NULL;
167
static plugin::TableFunction* cmp_mem_reset_tool= NULL;
168
static plugin::TableFunction* innodb_trx_tool= NULL;
169
static plugin::TableFunction* innodb_locks_tool= NULL;
170
static plugin::TableFunction* innodb_lock_waits_tool= NULL;
171
static plugin::TableFunction* innodb_sys_tables_tool= NULL;
172
static plugin::TableFunction* innodb_sys_tablestats_tool= NULL;
174
static plugin::TableFunction* innodb_sys_indexes_tool= NULL;
175
static plugin::TableFunction* innodb_sys_columns_tool= NULL;
176
static plugin::TableFunction* innodb_sys_fields_tool= NULL;
177
static plugin::TableFunction* innodb_sys_foreign_tool= NULL;
178
static plugin::TableFunction* innodb_sys_foreign_cols_tool= NULL;
180
static ReplicationLog *replication_logger= NULL;
181
164
typedef constrained_check<uint32_t, UINT32_MAX, 10> open_files_constraint;
182
165
static open_files_constraint innobase_open_files;
183
166
typedef constrained_check<uint32_t, 10, 1> mirrored_log_groups_constraint;
1172
1149
innobase_mysql_print_thd(
1173
1150
/*=====================*/
1174
1151
FILE* f, /*!< in: output stream */
1175
void * in_session, /*!< in: pointer to a Drizzle Session object */
1152
drizzled::Session *in_session, /*!< in: pointer to a Drizzle Session object */
1176
1153
uint ) /*!< in: max query length to print, or 0 to
1177
1154
use the default max length */
1179
Session *session= reinterpret_cast<Session *>(in_session);
1180
drizzled::identifier::User::const_shared_ptr user_identifier(session->user());
1156
drizzled::identifier::User::const_shared_ptr user_identifier(in_session->user());
1183
1159
"Drizzle thread %"PRIu64", query id %"PRIu64", %s, %s, %s ",
1184
static_cast<uint64_t>(session->getSessionId()),
1185
static_cast<uint64_t>(session->getQueryId()),
1160
static_cast<uint64_t>(in_session->getSessionId()),
1161
static_cast<uint64_t>(in_session->getQueryId()),
1187
1163
user_identifier->address().c_str(),
1188
1164
user_identifier->username().c_str()
1190
fprintf(f, "\n%s", session->getQueryString()->c_str());
1166
fprintf(f, "\n%s", in_session->getQueryString()->c_str());
1291
1255
return my_isspace(static_cast<const CHARSET_INFO *>(cs), char_to_test);
1296
innobase_fast_mutex_init(
1297
os_fast_mutex_t* fast_mutex)
1299
return pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST);
1302
/**********************************************************************//**
1303
Determines the current SQL statement.
1304
@return SQL statement string */
1309
void* session, /*!< in: MySQL thread handle */
1310
size_t* length) /*!< out: length of the SQL statement */
1312
return static_cast<Session*>(session)->getQueryStringCopy(*length);
1315
1258
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
1316
1259
/*******************************************************************//**
1317
1260
Map an OS error to an errno value. The OS error number is stored in
1666
1609
ulint buflen, /*!< in: length of buf, in bytes */
1667
1610
const char* id, /*!< in: identifier to convert */
1668
1611
ulint idlen, /*!< in: length of id, in bytes */
1669
void* session,/*!< in: MySQL connection thread, or NULL */
1612
drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
1670
1613
ibool file_id)/*!< in: TRUE=id is a table or database name;
1671
1614
FALSE=id is an UTF-8 string */
1752
1695
ulint buflen, /*!< in: length of buf, in bytes */
1753
1696
const char* id, /*!< in: identifier to convert */
1754
1697
ulint idlen, /*!< in: length of id, in bytes */
1755
void* session,/*!< in: MySQL connection thread, or NULL */
1698
drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
1756
1699
ibool table_id)/*!< in: TRUE=id is a table or database name;
1757
1700
FALSE=id is an index name */
2221
2163
srv_max_file_format_at_startup */
2222
2164
if (innobase_file_format_validate_and_set(innobase_file_format_max.c_str()) < 0)
2224
errmsg_printf(error::ERROR, _("InnoDB: invalid "
2225
"innodb_file_format_max value: "
2226
"should be any value up to %s or its "
2227
"equivalent numeric id"),
2228
trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
2166
errmsg_printf(error::ERROR, _("InnoDB: invalid innodb_file_format_max value: "
2167
"should be any value up to %s or its equivalent numeric id"),
2168
trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
2229
2169
goto mem_free_and_error;
2326
2264
innobase_open_tables = hash_create(200);
2327
pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
2328
pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
2329
pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
2330
pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
2331
pthread_cond_init(&commit_cond, NULL);
2332
2265
innodb_inited= 1;
2334
2267
actuall_engine_ptr->dropTemporarySchema();
2336
status_table_function_ptr= new InnodbStatusTool;
2269
context.add(new InnodbStatusTool);
2338
2271
context.add(innodb_engine_ptr);
2340
context.add(status_table_function_ptr);
2342
cmp_tool= new(std::nothrow)CmpTool(false);
2343
context.add(cmp_tool);
2345
cmp_reset_tool= new(std::nothrow)CmpTool(true);
2346
context.add(cmp_reset_tool);
2348
cmp_mem_tool= new(std::nothrow)CmpmemTool(false);
2349
context.add(cmp_mem_tool);
2351
cmp_mem_reset_tool= new(std::nothrow)CmpmemTool(true);
2352
context.add(cmp_mem_reset_tool);
2354
innodb_trx_tool= new(std::nothrow)InnodbTrxTool("INNODB_TRX");
2355
context.add(innodb_trx_tool);
2357
innodb_locks_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCKS");
2358
context.add(innodb_locks_tool);
2360
innodb_lock_waits_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS");
2361
context.add(innodb_lock_waits_tool);
2363
innodb_sys_tables_tool= new(std::nothrow)InnodbSysTablesTool();
2364
context.add(innodb_sys_tables_tool);
2366
innodb_sys_tablestats_tool= new(std::nothrow)InnodbSysTableStatsTool();
2367
context.add(innodb_sys_tablestats_tool);
2369
innodb_sys_indexes_tool= new(std::nothrow)InnodbSysIndexesTool();
2370
context.add(innodb_sys_indexes_tool);
2372
innodb_sys_columns_tool= new(std::nothrow)InnodbSysColumnsTool();
2373
context.add(innodb_sys_columns_tool);
2375
innodb_sys_fields_tool= new(std::nothrow)InnodbSysFieldsTool();
2376
context.add(innodb_sys_fields_tool);
2378
innodb_sys_foreign_tool= new(std::nothrow)InnodbSysForeignTool();
2379
context.add(innodb_sys_foreign_tool);
2381
innodb_sys_foreign_cols_tool= new(std::nothrow)InnodbSysForeignColsTool();
2382
context.add(innodb_sys_foreign_cols_tool);
2273
context.add(new(std::nothrow)CmpTool(false));
2275
context.add(new(std::nothrow)CmpTool(true));
2277
context.add(new(std::nothrow)CmpmemTool(false));
2279
context.add(new(std::nothrow)CmpmemTool(true));
2281
context.add(new(std::nothrow)InnodbTrxTool("INNODB_TRX"));
2283
context.add(new(std::nothrow)InnodbTrxTool("INNODB_LOCKS"));
2285
context.add(new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS"));
2287
context.add(new(std::nothrow)InnodbSysTablesTool());
2289
context.add(new(std::nothrow)InnodbSysTableStatsTool());
2291
context.add(new(std::nothrow)InnodbSysIndexesTool());
2293
context.add(new(std::nothrow)InnodbSysColumnsTool());
2295
context.add(new(std::nothrow)InnodbSysFieldsTool());
2297
context.add(new(std::nothrow)InnodbSysForeignTool());
2299
context.add(new(std::nothrow)InnodbSysForeignColsTool());
2384
2301
context.add(new(std::nothrow)InnodbInternalTables());
2385
2302
context.add(new(std::nothrow)InnodbReplicationTable());
2387
2304
if (innobase_use_replication_log)
2389
replication_logger= new(std::nothrow)ReplicationLog();
2306
ReplicationLog *replication_logger= new(std::nothrow)ReplicationLog();
2390
2307
context.add(replication_logger);
2391
2308
ReplicationLog::setup(replication_logger);
2581
2499
/* We need current binlog position for ibbackup to work.
2582
2500
Note, the position is current because of
2583
2501
prepare_commit_mutex */
2585
if (innobase_commit_concurrency.get() > 0) {
2586
pthread_mutex_lock(&commit_cond_m);
2589
if (commit_threads > innobase_commit_concurrency.get()) {
2502
const uint32_t commit_concurrency= innobase_commit_concurrency.get();
2503
if (commit_concurrency)
2507
boost::mutex::scoped_lock scopedLock(commit_cond_m);
2510
if (commit_threads <= commit_concurrency)
2590
2513
commit_threads--;
2591
pthread_cond_wait(&commit_cond,
2593
pthread_mutex_unlock(&commit_cond_m);
2597
pthread_mutex_unlock(&commit_cond_m);
2514
commit_cond.wait(scopedLock);
2601
2518
trx->mysql_log_file_name = NULL;
2940
/*****************************************************************//**
2941
Normalizes a table name string. A normalized name consists of the
2942
database name catenated to '/' and table name. An example:
2943
test/mytable. On Windows normalization puts both the database name and the
2944
table name always to lower case. */
2947
normalize_table_name(
2948
/*=================*/
2949
char* norm_name, /*!< out: normalized name as a
2950
null-terminated string */
2951
const char* name) /*!< in: table name string */
2953
const char* name_ptr;
2957
/* Scan name from the end */
2959
ptr = strchr(name, '\0')-1;
2961
while (ptr >= name && *ptr != '\\' && *ptr != '/') {
2971
while (ptr >= name && *ptr != '\\' && *ptr != '/') {
2977
memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name));
2979
norm_name[name_ptr - db_ptr - 1] = '/';
2982
innobase_casedn_str(norm_name);
2986
2857
/********************************************************************//**
2987
2858
Get the upper limit of the MySQL integral and floating-point type.
2988
2859
@return maximum allowed value for the field */
3149
3020
if (!index_mapping) {
3150
3021
/* Report an error if index_mapping continues to be
3151
3022
NULL and mysql_num_index is a non-zero value */
3152
errmsg_printf(error::ERROR,
3153
"InnoDB: fail to allocate memory for "
3154
"index translation table. Number of "
3155
"Index:%lu, array size:%lu",
3023
errmsg_printf(error::ERROR, "InnoDB: fail to allocate memory for "
3024
"index translation table. Number of Index:%lu, array size:%lu",
3156
3025
mysql_num_index,
3157
3026
share->idx_trans_tbl.array_size);
3173
3042
ib_table, table->key_info[count].name);
3175
3044
if (!index_mapping[count]) {
3176
errmsg_printf(error::ERROR, "Cannot find index %s in InnoDB "
3177
"index dictionary.",
3178
table->key_info[count].name);
3045
errmsg_printf(error::ERROR, "Cannot find index %s in InnoDB index dictionary.",
3046
table->key_info[count].name);
3180
3048
goto func_exit;
3183
3051
/* Double check fetched index has the same
3184
3052
column info as those in mysql key_info. */
3185
if (!innobase_match_index_columns(&table->key_info[count],
3186
index_mapping[count])) {
3187
errmsg_printf(error::ERROR, "Found index %s whose column info "
3188
"does not match that of MySQL.",
3189
table->key_info[count].name);
3053
if (!innobase_match_index_columns(&table->key_info[count], index_mapping[count])) {
3054
errmsg_printf(error::ERROR, "Found index %s whose column info does not match that of MySQL.",
3055
table->key_info[count].name);
3310
3175
case DB_RECORD_NOT_FOUND:
3311
3176
ut_print_timestamp(stderr);
3312
fprintf(stderr, " InnoDB: MySQL and InnoDB data "
3313
"dictionaries are out of sync.\n"
3314
"InnoDB: Unable to find the AUTOINC column "
3315
"%s in the InnoDB table %s.\n"
3316
"InnoDB: We set the next AUTOINC column "
3318
"InnoDB: in effect disabling the AUTOINC "
3319
"next value generation.\n"
3320
"InnoDB: You can either set the next "
3321
"AUTOINC value explicitly using ALTER TABLE\n"
3322
"InnoDB: or fix the data dictionary by "
3323
"recreating the table.\n",
3324
col_name, index->table->name);
3177
errmsg_printf(error::ERROR, "InnoDB: MySQL and InnoDB data dictionaries are out of sync.\n"
3178
"InnoDB: Unable to find the AUTOINC column %s in the InnoDB table %s.\n"
3179
"InnoDB: We set the next AUTOINC column value to 0,\n"
3180
"InnoDB: in effect disabling the AUTOINC next value generation.\n"
3181
"InnoDB: You can either set the next AUTOINC value explicitly using ALTER TABLE\n"
3182
"InnoDB: or fix the data dictionary by recreating the table.\n",
3183
col_name, index->table->name);
3326
3185
/* This will disable the AUTOINC generation. */
6275
6123
if (lex_identified_temp_table)
6276
6124
iflags |= DICT_TF2_TEMPORARY << DICT_TF2_SHIFT;
6278
error= create_table_def(trx, &form, norm_name,
6279
lex_identified_temp_table ? name2 : NULL,
6126
error= create_table_def(trx, &form, identifier.getKeyPath().c_str(),
6127
lex_identified_temp_table ? identifier.getKeyPath().c_str() : NULL,
6282
6130
session.setXaId(trx->id);
6309
6157
for (i = 0; i < form.getShare()->sizeKeys(); i++) {
6310
6158
if (i != (uint) primary_key_no) {
6312
if ((error = create_index(trx, &form, iflags, norm_name,
6160
if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
6319
stmt = innobase_get_stmt(&session, &stmt_len);
6167
stmt= session.getQueryStringCopy(stmt_len);
6322
6170
string generated_create_table;
6703
6546
innobase_rename_table(
6704
6547
/*==================*/
6705
6548
trx_t* trx, /*!< in: transaction */
6706
const char* from, /*!< in: old name of the table */
6707
const char* to, /*!< in: new name of the table */
6549
const identifier::Table &from,
6550
const identifier::Table &to,
6708
6551
ibool lock_and_commit)
6709
6552
/*!< in: TRUE=lock data dictionary and commit */
6712
char norm_to[FN_REFLEN];
6713
char norm_from[FN_REFLEN];
6715
6556
srv_lower_case_table_names = TRUE;
6717
normalize_table_name(norm_to, to);
6718
normalize_table_name(norm_from, from);
6720
6558
/* Serialize data dictionary operations with dictionary mutex:
6721
6559
no deadlocks can occur then in these operations */
6724
6562
row_mysql_lock_data_dictionary(trx);
6727
error = row_rename_table_for_mysql(
6728
norm_from, norm_to, trx, lock_and_commit);
6565
error = row_rename_table_for_mysql(from.getKeyPath().c_str(), to.getKeyPath().c_str(), trx, lock_and_commit);
6730
6567
if (error != DB_SUCCESS) {
6731
6568
FILE* ef = dict_foreign_err_file;
6733
6570
fputs("InnoDB: Renaming table ", ef);
6734
ut_print_name(ef, trx, TRUE, norm_from);
6571
ut_print_name(ef, trx, TRUE, from.getKeyPath().c_str());
6735
6572
fputs(" to ", ef);
6736
ut_print_name(ef, trx, TRUE, norm_to);
6573
ut_print_name(ef, trx, TRUE, to.getKeyPath().c_str());
6737
6574
fputs(" failed!\n", ef);