43
43
#include <limits.h>
46
#include "drizzled/error.h"
47
#include "drizzled/errmsg_print.h"
48
#include "drizzled/charset_info.h"
49
#include "drizzled/internal/m_string.h"
50
#include "drizzled/internal/my_sys.h"
51
#include "drizzled/my_hash.h"
52
#include "drizzled/plugin.h"
53
#include "drizzled/show.h"
54
#include "drizzled/data_home.h"
55
#include "drizzled/error.h"
56
#include "drizzled/field.h"
57
#include "drizzled/charset.h"
58
#include "drizzled/session.h"
59
#include "drizzled/current_session.h"
60
#include "drizzled/table.h"
61
#include "drizzled/field/blob.h"
62
#include "drizzled/field/varstring.h"
63
#include "drizzled/field/timestamp.h"
64
#include "drizzled/plugin/xa_storage_engine.h"
65
#include "drizzled/plugin/daemon.h"
66
#include "drizzled/memory/multi_malloc.h"
67
#include "drizzled/pthread_globals.h"
68
#include "drizzled/named_savepoint.h"
46
#include <drizzled/error.h>
47
#include <drizzled/errmsg_print.h>
48
#include <drizzled/internal/m_string.h>
49
#include <drizzled/internal/my_sys.h>
50
#include <drizzled/plugin.h>
51
#include <drizzled/show.h>
52
#include <drizzled/data_home.h>
53
#include <drizzled/error.h>
54
#include <drizzled/field.h>
55
#include <drizzled/charset.h>
56
#include <drizzled/session.h>
57
#include <drizzled/current_session.h>
58
#include <drizzled/table.h>
59
#include <drizzled/field/blob.h>
60
#include <drizzled/field/varstring.h>
61
#include <drizzled/plugin/xa_storage_engine.h>
62
#include <drizzled/plugin/daemon.h>
63
#include <drizzled/memory/multi_malloc.h>
64
#include <drizzled/pthread_globals.h>
65
#include <drizzled/named_savepoint.h>
66
#include <drizzled/session/table_messages.h>
70
67
#include <drizzled/transaction_services.h>
71
#include "drizzled/message/statement_transform.h"
68
#include <drizzled/message/statement_transform.h>
69
#include <drizzled/cached_directory.h>
70
#include <drizzled/statistics_variables.h>
71
#include <drizzled/system_variables.h>
72
#include <drizzled/session/times.h>
73
#include <drizzled/session/transactions.h>
74
#include <drizzled/typelib.h>
73
76
#include <boost/algorithm/string.hpp>
74
77
#include <boost/program_options.hpp>
78
#include <boost/scoped_array.hpp>
75
79
#include <boost/filesystem.hpp>
76
80
#include <drizzled/module/option_map.h>
77
81
#include <iostream>
128
129
#include <sstream>
129
130
#include <string>
131
#include "plugin/innobase/handler/status_function.h"
132
#include "plugin/innobase/handler/replication_log.h"
132
#include <plugin/innobase/handler/status_function.h>
133
#include <plugin/innobase/handler/replication_log.h>
134
135
#include <google/protobuf/io/zero_copy_stream.h>
135
136
#include <google/protobuf/io/zero_copy_stream_impl.h>
136
137
#include <google/protobuf/io/coded_stream.h>
137
138
#include <google/protobuf/text_format.h>
140
#include <boost/thread/mutex.hpp>
139
142
using namespace std;
140
143
using namespace drizzled;
142
145
/** to protect innobase_open_files */
143
static pthread_mutex_t innobase_share_mutex;
146
static boost::mutex innobase_share_mutex;
144
148
/** to force correct commit order in binlog */
145
static pthread_mutex_t prepare_commit_mutex;
146
149
static ulong commit_threads = 0;
147
static pthread_mutex_t commit_threads_m;
148
static pthread_cond_t commit_cond;
149
static pthread_mutex_t commit_cond_m;
150
static boost::condition_variable commit_cond;
151
static boost::mutex commit_cond_m;
150
152
static bool innodb_inited = 0;
152
154
#define INSIDE_HA_INNOBASE_CC
162
164
#endif /* MYSQL_DYNAMIC_PLUGIN && __WIN__ */
164
166
static plugin::XaStorageEngine* innodb_engine_ptr= NULL;
165
static plugin::TableFunction* status_table_function_ptr= NULL;
166
static plugin::TableFunction* cmp_tool= NULL;
167
static plugin::TableFunction* cmp_reset_tool= NULL;
168
static plugin::TableFunction* cmp_mem_tool= NULL;
169
static plugin::TableFunction* cmp_mem_reset_tool= NULL;
170
static plugin::TableFunction* innodb_trx_tool= NULL;
171
static plugin::TableFunction* innodb_locks_tool= NULL;
172
static plugin::TableFunction* innodb_lock_waits_tool= NULL;
173
static plugin::TableFunction* innodb_sys_tables_tool= NULL;
174
static plugin::TableFunction* innodb_sys_tablestats_tool= NULL;
176
static plugin::TableFunction* innodb_sys_indexes_tool= NULL;
177
static plugin::TableFunction* innodb_sys_columns_tool= NULL;
178
static plugin::TableFunction* innodb_sys_fields_tool= NULL;
179
static plugin::TableFunction* innodb_sys_foreign_tool= NULL;
180
static plugin::TableFunction* innodb_sys_foreign_cols_tool= NULL;
182
static ReplicationLog *replication_logger= NULL;
183
168
typedef constrained_check<uint32_t, UINT32_MAX, 10> open_files_constraint;
184
169
static open_files_constraint innobase_open_files;
185
170
typedef constrained_check<uint32_t, 10, 1> mirrored_log_groups_constraint;
194
179
static additional_mem_pool_constraint innobase_additional_mem_pool_size;
195
180
typedef constrained_check<unsigned int, 1000, 1> autoextend_constraint;
196
181
static autoextend_constraint innodb_auto_extend_increment;
197
typedef constrained_check<size_t, SIZE_MAX, 5242880, 1048576> buffer_pool_constraint;
182
typedef constrained_check<size_t, SIZE_MAX, 33554432, 1048576> buffer_pool_constraint;
198
183
static buffer_pool_constraint innobase_buffer_pool_size;
199
184
typedef constrained_check<uint32_t, MAX_BUFFER_POOLS, 1> buffer_pool_instances_constraint;
200
185
static buffer_pool_instances_constraint innobase_buffer_pool_instances;
186
typedef constrained_check<uint32_t,
187
(1 << UNIV_PAGE_SIZE_SHIFT_MAX),
188
(1 << 12)> page_size_constraint;
189
static page_size_constraint innobase_page_size;
190
typedef constrained_check<uint32_t,
191
(1 << UNIV_PAGE_SIZE_SHIFT_MAX),
192
(1 << 9)> log_block_size_constraint;
193
static log_block_size_constraint innobase_log_block_size;
201
194
typedef constrained_check<uint32_t, UINT32_MAX, 100> io_capacity_constraint;
202
195
static io_capacity_constraint innodb_io_capacity;
203
196
typedef constrained_check<uint32_t, 5000, 1> purge_batch_constraint;
204
197
static purge_batch_constraint innodb_purge_batch_size;
205
198
typedef constrained_check<uint32_t, 1, 0> purge_threads_constraint;
206
199
static purge_threads_constraint innodb_n_purge_threads;
207
typedef constrained_check<uint16_t, 2, 0> trinary_constraint;
200
typedef constrained_check<uint32_t, 2, 0> trinary_constraint;
208
201
static trinary_constraint innodb_flush_log_at_trx_commit;
209
202
typedef constrained_check<unsigned int, 99, 0> max_dirty_pages_constraint;
210
203
static max_dirty_pages_constraint innodb_max_dirty_pages_pct;
236
231
typedef constrained_check<uint32_t, 64, 0> read_ahead_threshold_constraint;
237
232
static read_ahead_threshold_constraint innodb_read_ahead_threshold;
234
static uint64_constraint ibuf_max_size;
236
typedef constrained_check<uint32_t, 1, 0> binary_constraint;
237
static binary_constraint ibuf_active_contract;
239
typedef constrained_check<uint32_t, 999999999, 100> ibuf_accel_rate_constraint;
240
static ibuf_accel_rate_constraint ibuf_accel_rate;
241
static uint32_constraint checkpoint_age_target;
242
static binary_constraint flush_neighbor_pages;
239
244
/* The default values for the following char* start-up parameters
240
245
are determined in innobase_init below: */
305
312
"all" /* IBUF_USE_ALL */
315
/** Allowed values of read_ahead */
316
static const char* read_ahead_names[] = {
321
/* For compatibility with the older Percona patch */
322
"0", /* 4 ("none" + 4) */
325
"3", /* 7 ("both" + 4) */
329
static TYPELIB read_ahead_typelib = {
330
array_elements(read_ahead_names) - 1, "read_ahead_typelib",
331
read_ahead_names, NULL
334
/** Allowed values of adaptive_flushing_method */
335
static const char* adaptive_flushing_method_names[] = {
338
"keep_average", /* 2 */
339
/* For compatibility with the older Percona patch */
340
"0", /* 3 ("native" + 3) */
341
"1", /* 4 ("estimate" + 3) */
342
"2", /* 5 ("keep_average" + 3) */
346
static TYPELIB adaptive_flushing_method_typelib = {
347
array_elements(adaptive_flushing_method_names) - 1,
348
"adaptive_flushing_method_typelib",
349
adaptive_flushing_method_names, NULL
308
352
/* "GEN_CLUST_INDEX" is the name reserved for Innodb default
309
353
system primary index. */
310
354
static const char innobase_index_reserve_name[]= "GEN_CLUST_INDEX";
341
385
virtual ~InnobaseEngine()
344
387
if (innodb_inited) {
345
388
srv_fast_shutdown = (ulint) innobase_fast_shutdown;
346
389
innodb_inited = 0;
347
390
hash_table_free(innobase_open_tables);
348
391
innobase_open_tables = NULL;
349
392
if (innobase_shutdown_for_mysql() != DB_SUCCESS) {
352
395
srv_free_paths_and_sizes();
353
if (internal_innobase_data_file_path)
354
free(internal_innobase_data_file_path);
355
pthread_mutex_destroy(&innobase_share_mutex);
356
pthread_mutex_destroy(&prepare_commit_mutex);
357
pthread_mutex_destroy(&commit_threads_m);
358
pthread_mutex_destroy(&commit_cond_m);
359
pthread_cond_destroy(&commit_cond);
396
free(internal_innobase_data_file_path);
362
399
/* These get strdup'd from vm variables */
486
523
UNIV_INTERN int doCreateTable(Session &session,
488
const TableIdentifier &identifier,
490
UNIV_INTERN int doRenameTable(Session&, const TableIdentifier &from, const TableIdentifier &to);
491
UNIV_INTERN int doDropTable(Session &session, const TableIdentifier &identifier);
525
const identifier::Table &identifier,
526
const message::Table&);
527
UNIV_INTERN int doRenameTable(Session&, const identifier::Table &from, const identifier::Table &to);
528
UNIV_INTERN int doDropTable(Session &session, const identifier::Table &identifier);
493
UNIV_INTERN virtual bool get_error_message(int error, String *buf);
530
UNIV_INTERN virtual bool get_error_message(int error, String *buf) const;
495
532
UNIV_INTERN uint32_t max_supported_keys() const;
496
533
UNIV_INTERN uint32_t max_supported_key_length() const;
509
546
int doGetTableDefinition(drizzled::Session& session,
510
const TableIdentifier &identifier,
547
const identifier::Table &identifier,
511
548
drizzled::message::Table &table_proto);
513
bool doDoesTableExist(drizzled::Session& session, const TableIdentifier &identifier);
550
bool doDoesTableExist(drizzled::Session& session, const identifier::Table &identifier);
515
552
void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
516
const drizzled::SchemaIdentifier &schema_identifier,
517
drizzled::TableIdentifier::vector &set_of_identifiers);
553
const drizzled::identifier::Schema &schema_identifier,
554
drizzled::identifier::table::vector &set_of_identifiers);
518
555
bool validateCreateTableOption(const std::string &key, const std::string &state);
519
556
void dropTemporarySchema();
544
581
void InnobaseEngine::doGetTableIdentifiers(drizzled::CachedDirectory &directory,
545
const drizzled::SchemaIdentifier &schema_identifier,
546
drizzled::TableIdentifier::vector &set_of_identifiers)
582
const drizzled::identifier::Schema &schema_identifier,
583
drizzled::identifier::table::vector &set_of_identifiers)
548
585
CachedDirectory::Entries entries= directory.getEntries();
587
std::string search_string(schema_identifier.getSchemaName());
589
boost::algorithm::to_lower(search_string);
591
if (search_string.compare("data_dictionary") == 0)
593
set_of_identifiers.push_back(identifier::Table(schema_identifier.getSchemaName(), "SYS_REPLICATION_LOG"));
550
596
for (CachedDirectory::Entries::iterator entry_iter= entries.begin();
551
597
entry_iter != entries.end(); ++entry_iter)
574
620
Using schema_identifier here to stop unused warning, could use
575
621
definition.schema() instead
577
TableIdentifier identifier(schema_identifier.getSchemaName(), definition.name());
623
identifier::Table identifier(schema_identifier.getSchemaName(), definition.name());
578
624
set_of_identifiers.push_back(identifier);
584
bool InnobaseEngine::doDoesTableExist(Session &session, const TableIdentifier &identifier)
630
bool InnobaseEngine::doDoesTableExist(Session &session, const identifier::Table &identifier)
586
632
string proto_path(identifier.getPath());
587
633
proto_path.append(DEFAULT_FILE_EXTENSION);
878
933
DRIZZLE: Note, we didn't change this name to avoid more ifdef forking
879
934
in non-Cursor code.
880
935
@return true if non-transactional tables have been edited */
881
extern "C" UNIV_INTERN
883
938
thd_has_edited_nontrans_tables(
884
939
/*===========================*/
885
void* session) /*!< in: thread handle (Session*) */
940
drizzled::Session *session) /*!< in: thread handle (Session*) */
887
return((ibool)((Session *)session)->transaction.all.hasModifiedNonTransData());
942
return((ibool)session->transaction.all.hasModifiedNonTransData());
890
945
/******************************************************************//**
891
946
Returns true if the thread is executing a SELECT statement.
892
947
@return true if session is executing SELECT */
893
extern "C" UNIV_INTERN
897
const void* session) /*!< in: thread handle (Session*) */
952
const drizzled::Session *session) /*!< in: thread handle (Session*) */
899
return(session_sql_command((const Session*) session) == SQLCOM_SELECT);
954
return(session->getSqlCommand() == SQLCOM_SELECT);
902
957
/******************************************************************//**
903
958
Returns true if the thread supports XA,
904
959
global value of innodb_supports_xa if session is NULL.
905
960
@return true if session has XA support */
906
extern "C" UNIV_INTERN
910
void* ) /*!< in: thread handle (Session*), or NULL to query
965
drizzled::Session* ) /*!< in: thread handle (Session*), or NULL to query
911
966
the global innodb_supports_xa */
913
968
/* TODO: Add support here for per-session value */
967
1021
trx_t *trx= session_to_trx(&session);
969
1023
uint64_t trx_id= message.transaction_context().transaction_id();
970
ulint error= insert_replication_message(data, message.ByteSize(), trx, trx_id);
1024
uint32_t seg_id= message.segment_id();
1025
uint64_t end_timestamp= message.transaction_context().end_timestamp();
1026
bool is_end_segment= message.end_segment();
1027
trx->log_commit_id= TRUE;
1029
string server_uuid= session.getServerUUID();
1030
string originating_server_uuid= session.getOriginatingServerUUID();
1031
uint64_t originating_commit_id= session.getOriginatingCommitID();
1032
bool use_originating_server_uuid= session.isOriginatingServerUUIDSet();
1034
ulint error= insert_replication_message(data, message.ByteSize(), trx, trx_id,
1035
end_timestamp, is_end_segment, seg_id, server_uuid.c_str(),
1036
use_originating_server_uuid, originating_server_uuid.c_str(),
1037
originating_commit_id);
1168
1237
/*************************************************************//**
1169
1238
Prints info of a Session object (== user session thread) to the given file. */
1170
extern "C" UNIV_INTERN
1172
1241
innobase_mysql_print_thd(
1173
1242
/*=====================*/
1174
1243
FILE* f, /*!< in: output stream */
1175
void * in_session, /*!< in: pointer to a Drizzle Session object */
1244
drizzled::Session *in_session, /*!< in: pointer to a Drizzle Session object */
1176
1245
uint ) /*!< in: max query length to print, or 0 to
1177
1246
use the default max length */
1179
Session *session= reinterpret_cast<Session *>(in_session);
1180
drizzled::identifier::User::const_shared_ptr user_identifier(session->user());
1248
drizzled::identifier::user::ptr user_identifier(in_session->user());
1183
1251
"Drizzle thread %"PRIu64", query id %"PRIu64", %s, %s, %s ",
1184
static_cast<uint64_t>(session->getSessionId()),
1185
static_cast<uint64_t>(session->getQueryId()),
1252
static_cast<uint64_t>(in_session->getSessionId()),
1253
static_cast<uint64_t>(in_session->getQueryId()),
1254
getServerHostname().c_str(),
1187
1255
user_identifier->address().c_str(),
1188
1256
user_identifier->username().c_str()
1190
fprintf(f, "\n%s", session->getQueryString()->c_str());
1258
fprintf(f, "\n%s", in_session->getQueryString()->c_str());
1194
1262
/******************************************************************//**
1195
1263
Get the variable length bounds of the given character set. */
1196
extern "C" UNIV_INTERN
1198
1266
innobase_get_cset_width(
1199
1267
/*====================*/
1270
1338
my_casedn_str(system_charset_info, a);
1273
/**********************************************************************//**
1274
Determines the connection character set.
1275
@return connection character set */
1276
extern "C" UNIV_INTERN
1278
innobase_get_charset(
1279
/*=================*/
1280
void* mysql_session) /*!< in: MySQL thread handle */
1282
return static_cast<Session*>(mysql_session)->charset();
1285
extern "C" UNIV_INTERN
1287
1343
innobase_isspace(
1289
1345
char char_to_test)
1291
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 */
1305
extern "C" UNIV_INTERN
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);
1347
return static_cast<const charset_info_st*>(cs)->isspace(char_to_test);
1315
1350
#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
1316
1351
/*******************************************************************//**
1317
1352
Map an OS error to an errno value. The OS error number is stored in
1318
1353
_doserrno and the mapped value is stored in errno) */
1322
1356
unsigned long); /*!< in: OS error value */
1404
1438
/*********************************************************************//**
1405
1439
Creates a temporary file.
1406
1440
@return temporary file descriptor, or < 0 on error */
1407
extern "C" UNIV_INTERN
1409
1443
innobase_mysql_tmpfile(void)
1410
1444
/*========================*/
1413
int fd = mysql_tmpfile("ib");
1447
int fd = ::drizzled::tmpfile("ib");
1415
1449
/* Copy the file descriptor, so that the additional resources
1416
1450
allocated by create_temp_file() can be freed by invoking
1667
1701
ulint buflen, /*!< in: length of buf, in bytes */
1668
1702
const char* id, /*!< in: identifier to convert */
1669
1703
ulint idlen, /*!< in: length of id, in bytes */
1670
void* session,/*!< in: MySQL connection thread, or NULL */
1704
drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
1671
1705
ibool file_id)/*!< in: TRUE=id is a table or database name;
1672
1706
FALSE=id is an UTF-8 string */
1674
1708
char nz[NAME_LEN + 1];
1675
char nz2[NAME_LEN + 1 + sizeof srv_mysql50_table_name_prefix];
1709
const size_t nz2_size= NAME_LEN + 1 + srv_mysql50_table_name_prefix.size();
1710
boost::scoped_array<char> nz2(new char[nz2_size]);
1677
1712
const char* s = id;
1752
1787
ulint buflen, /*!< in: length of buf, in bytes */
1753
1788
const char* id, /*!< in: identifier to convert */
1754
1789
ulint idlen, /*!< in: length of id, in bytes */
1755
void* session,/*!< in: MySQL connection thread, or NULL */
1790
drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
1756
1791
ibool table_id)/*!< in: TRUE=id is a table or database name;
1757
1792
FALSE=id is an index name */
1800
1835
/**********************************************************************//**
1801
1836
Determines if the currently running transaction has been interrupted.
1802
1837
@return TRUE if interrupted */
1803
extern "C" UNIV_INTERN
1805
1840
trx_is_interrupted(
1806
1841
/*===============*/
1807
1842
trx_t* trx) /*!< in: transaction */
1809
return(trx && trx->mysql_thd && static_cast<Session*>(trx->mysql_thd)->getKilled());
1844
return(trx && trx->mysql_thd && trx->mysql_thd->getKilled());
1812
1847
/**********************************************************************//**
1813
1848
Determines if the currently running transaction is in strict mode.
1814
1849
@return TRUE if strict */
1815
extern "C" UNIV_INTERN
1901
1936
srv_read_ahead_threshold= innodb_read_ahead_threshold.get();
1939
static void auto_lru_dump_update(Session *, sql_var_t)
1941
srv_auto_lru_dump= buffer_pool_restore_at_startup.get();
1944
static void ibuf_active_contract_update(Session *, sql_var_t)
1946
srv_ibuf_active_contract= ibuf_active_contract.get();
1949
static void ibuf_accel_rate_update(Session *, sql_var_t)
1951
srv_ibuf_accel_rate= ibuf_accel_rate.get();
1954
static void checkpoint_age_target_update(Session *, sql_var_t)
1956
srv_checkpoint_age_target= checkpoint_age_target.get();
1959
static void flush_neighbor_pages_update(Session *, sql_var_t)
1961
srv_flush_neighbor_pages= flush_neighbor_pages.get();
1905
1964
static int innodb_commit_concurrency_validate(Session *session, set_var *var)
1907
uint32_t new_value= var->save_result.uint32_t_value;
1966
uint64_t new_value= var->getInteger();
1909
1968
if ((innobase_commit_concurrency.get() == 0 && new_value != 0) ||
1910
1969
(innobase_commit_concurrency.get() != 0 && new_value == 0))
2010
2069
if (format_id >= 0) {
2011
innobase_file_format_max=
2012
trx_sys_file_format_id_to_name((uint)format_id);
2070
innobase_file_format_max.assign(
2071
trx_sys_file_format_id_to_name((uint)format_id));
2014
2073
/* Update the max format id in the system tablespace. */
2015
char name_buff[100];
2016
strcpy(name_buff, innobase_file_format_max.c_str());
2017
if (trx_sys_file_format_max_set(format_id, (const char **)&name_buff))
2074
const char *name_buff;
2076
if (trx_sys_file_format_max_set(format_id, &name_buff))
2019
errmsg_printf(ERRMSG_LVL_WARN,
2078
errmsg_printf(error::WARN,
2020
2079
" [Info] InnoDB: the file format in the system "
2021
2080
"tablespace is now set to %s.\n", name_buff);
2022
2081
innobase_file_format_max= name_buff;
2100
/*********************************************************************//**
2101
Check if argument is a valid value for srv_read_ahead and set it. This
2102
function is registered as a callback with MySQL.
2103
@return 0 for valid read_ahead value */
2106
read_ahead_validate(
2107
/*================*/
2108
Session*, /*!< in: thread handle */
2111
const char *read_ahead_input = var->value->str_value.ptr();
2112
int res = read_ahead_typelib.find_type(read_ahead_input, TYPELIB::e_none); // e_none is wrong
2115
srv_read_ahead = res - 1;
2122
/*********************************************************************//**
2123
Check if argument is a valid value for srv_adaptive_flushing_method and
2124
set it. This function is registered as a callback with MySQL.
2125
@return 0 for valid read_ahead value */
2128
adaptive_flushing_method_validate(
2129
/*==============================*/
2130
Session*, /*!< in: thread handle */
2133
const char *adaptive_flushing_method_input = var->value->str_value.ptr();
2134
int res = adaptive_flushing_method_typelib.find_type(adaptive_flushing_method_input, TYPELIB::e_none); // e_none is wrong
2137
srv_adaptive_flushing_method = res - 1;
2042
2144
/*********************************************************************//**
2043
2145
Opens an InnoDB database.
2069
2171
srv_spin_wait_delay= innodb_spin_wait_delay.get();
2070
2172
srv_thread_sleep_delay= innodb_thread_sleep_delay.get();
2071
2173
srv_read_ahead_threshold= innodb_read_ahead_threshold.get();
2174
srv_auto_lru_dump= buffer_pool_restore_at_startup.get();
2175
srv_ibuf_max_size= ibuf_max_size.get();
2176
srv_ibuf_active_contract= ibuf_active_contract.get();
2177
srv_ibuf_accel_rate= ibuf_accel_rate.get();
2178
srv_checkpoint_age_target= checkpoint_age_target.get();
2179
srv_flush_neighbor_pages= flush_neighbor_pages.get();
2181
srv_read_ahead = read_ahead_typelib.find_type_or_exit(vm["read-ahead"].as<string>().c_str(),
2182
"read_ahead_typelib") + 1;
2184
srv_adaptive_flushing_method = adaptive_flushing_method_typelib.find_type_or_exit(vm["adaptive-flushing-method"].as<string>().c_str(),
2185
"adaptive_flushing_method_typelib") + 1;
2073
2187
/* Inverted Booleans */
2075
innobase_use_checksums= (vm.count("disable-checksums")) ? false : true;
2076
innobase_use_doublewrite= (vm.count("disable-doublewrite")) ? false : true;
2077
srv_adaptive_flushing= (vm.count("disable-adaptive-flushing")) ? false : true;
2078
srv_use_sys_malloc= (vm.count("use-internal-malloc")) ? false : true;
2079
support_xa= (vm.count("disable-xa")) ? false : true;
2080
btr_search_enabled= (vm.count("disable-adaptive-hash-index")) ? false : true;
2189
innobase_use_checksums= not vm.count("disable-checksums");
2190
innobase_use_doublewrite= not vm.count("disable-doublewrite");
2191
srv_adaptive_flushing= not vm.count("disable-adaptive-flushing");
2192
srv_use_sys_malloc= not vm.count("use-internal-malloc");
2193
srv_use_native_aio= not vm.count("disable-native-aio");
2194
support_xa= not vm.count("disable-xa");
2195
btr_search_enabled= not vm.count("disable-adaptive-hash-index");
2083
2197
/* Hafta do this here because we need to late-bind the default value */
2084
if (vm.count("data-home-dir"))
2086
innobase_data_home_dir= vm["data-home-dir"].as<string>();
2090
innobase_data_home_dir= getDataHome().file_string();
2198
innobase_data_home_dir= vm.count("data-home-dir") ? vm["data-home-dir"].as<string>() : getDataHome().file_string();
2094
2200
if (vm.count("data-file-path"))
2104
2210
#ifdef UNIV_DEBUG
2105
2211
static const char test_filename[] = "-@";
2106
char test_tablename[sizeof test_filename
2107
+ sizeof srv_mysql50_table_name_prefix];
2108
if ((sizeof test_tablename) - 1
2109
!= filename_to_tablename(test_filename, test_tablename,
2110
sizeof test_tablename)
2111
|| strncmp(test_tablename,
2112
srv_mysql50_table_name_prefix,
2113
sizeof srv_mysql50_table_name_prefix)
2114
|| strcmp(test_tablename
2115
+ sizeof srv_mysql50_table_name_prefix,
2212
const size_t test_tablename_size= sizeof test_filename
2213
+ srv_mysql50_table_name_prefix.size();
2214
boost::scoped_array test_tablename(new char[test_tablename_size]);
2215
if ((test_tablename_size) - 1
2216
!= filename_to_tablename(test_filename, test_tablename.get(),
2217
test_tablename_size)
2218
|| strncmp(test_tablename.get(),
2219
srv_mysql50_table_name_prefix.c_str(),
2220
srv_mysql50_table_name_prefix.size())
2221
|| strcmp(test_tablename.get()
2222
+ srv_mysql50_table_name_prefix.size(),
2116
2223
test_filename)) {
2117
errmsg_printf(ERRMSG_LVL_ERROR, "tablename encoding has been changed");
2224
errmsg_printf(error::ERROR, "tablename encoding has been changed");
2120
2227
#endif /* UNIV_DEBUG */
2230
srv_page_size_shift = 0;
2232
uint32_t page_size = innobase_page_size.get();
2233
uint32_t log_block_size = innobase_log_block_size.get();
2235
if (innobase_page_size != (1 << 14)) {
2238
errmsg_printf(error::WARN,
2239
"InnoDB: Warning: innodb_page_size has been changed from default value 16384. (###EXPERIMENTAL### operation)\n");
2240
for (n_shift = 12; n_shift <= UNIV_PAGE_SIZE_SHIFT_MAX; n_shift++) {
2241
if (innobase_page_size == (1UL << n_shift)) {
2242
srv_page_size_shift = n_shift;
2243
srv_page_size = (1 << srv_page_size_shift);
2244
errmsg_printf(error::WARN,
2245
"InnoDB: The universal page size of the database is set to %lu.\n",
2251
srv_page_size_shift = 14;
2252
srv_page_size = (1 << srv_page_size_shift);
2255
if (!srv_page_size_shift) {
2256
errmsg_printf(error::ERROR,
2257
"InnoDB: Error: %"PRIu32" is not a valid value for innodb_page_size.\n"
2258
"InnoDB: Error: Valid values are 4096, 8192, and 16384 (default=16384).\n",
2263
srv_log_block_size = 0;
2264
if (log_block_size != (1 << 9)) { /*!=512*/
2267
errmsg_printf(error::WARN,
2268
"InnoDB: Warning: innodb_log_block_size has been changed from default value 512. (###EXPERIMENTAL### operation)\n");
2269
for (n_shift = 9; n_shift <= UNIV_PAGE_SIZE_SHIFT_MAX; n_shift++) {
2270
if (log_block_size == (1UL << n_shift)) {
2271
srv_log_block_size = (1 << n_shift);
2272
errmsg_printf(error::WARN, "InnoDB: The log block size is set to %"PRIu32".\n",
2273
srv_log_block_size);
2278
srv_log_block_size = 512;
2281
if (!srv_log_block_size) {
2282
errmsg_printf(error::ERROR,
2283
"InnoDB: Error: %"PRIu32" is not a valid value for innodb_log_block_size.\n"
2284
"InnoDB: Error: A valid value for innodb_log_block_size is\n"
2285
"InnoDB: Error: a power of 2 from 512 to 16384.\n",
2122
2290
os_innodb_umask = (ulint)internal::my_umask;
2148
2316
ret = (bool) srv_parse_data_file_paths_and_sizes(
2149
2317
internal_innobase_data_file_path);
2150
2318
if (ret == FALSE) {
2151
errmsg_printf(ERRMSG_LVL_ERROR,
2152
"InnoDB: syntax error in innodb_data_file_path");
2319
errmsg_printf(error::ERROR, "InnoDB: syntax error in innodb_data_file_path");
2153
2321
mem_free_and_error:
2154
2322
srv_free_paths_and_sizes();
2155
if (internal_innobase_data_file_path)
2156
free(internal_innobase_data_file_path);
2323
free(internal_innobase_data_file_path);
2219
2385
srv_max_file_format_at_startup */
2220
2386
if (innobase_file_format_validate_and_set(innobase_file_format_max.c_str()) < 0)
2222
errmsg_printf(ERRMSG_LVL_ERROR, _("InnoDB: invalid "
2223
"innodb_file_format_max value: "
2224
"should be any value up to %s or its "
2225
"equivalent numeric id"),
2226
trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
2388
errmsg_printf(error::ERROR, _("InnoDB: invalid innodb_file_format_max value: "
2389
"should be any value up to %s or its equivalent numeric id"),
2390
trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
2227
2391
goto mem_free_and_error;
2324
2489
innobase_open_tables = hash_create(200);
2325
pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
2326
pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
2327
pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
2328
pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
2329
pthread_cond_init(&commit_cond, NULL);
2330
2490
innodb_inited= 1;
2332
2492
actuall_engine_ptr->dropTemporarySchema();
2334
status_table_function_ptr= new InnodbStatusTool;
2494
context.add(new InnodbStatusTool);
2336
2495
context.add(innodb_engine_ptr);
2338
context.add(status_table_function_ptr);
2340
cmp_tool= new(std::nothrow)CmpTool(false);
2341
context.add(cmp_tool);
2343
cmp_reset_tool= new(std::nothrow)CmpTool(true);
2344
context.add(cmp_reset_tool);
2346
cmp_mem_tool= new(std::nothrow)CmpmemTool(false);
2347
context.add(cmp_mem_tool);
2349
cmp_mem_reset_tool= new(std::nothrow)CmpmemTool(true);
2350
context.add(cmp_mem_reset_tool);
2352
innodb_trx_tool= new(std::nothrow)InnodbTrxTool("INNODB_TRX");
2353
context.add(innodb_trx_tool);
2355
innodb_locks_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCKS");
2356
context.add(innodb_locks_tool);
2358
innodb_lock_waits_tool= new(std::nothrow)InnodbTrxTool("INNODB_LOCK_WAITS");
2359
context.add(innodb_lock_waits_tool);
2361
innodb_sys_tables_tool= new(std::nothrow)InnodbSysTablesTool();
2362
context.add(innodb_sys_tables_tool);
2364
innodb_sys_tablestats_tool= new(std::nothrow)InnodbSysTableStatsTool();
2365
context.add(innodb_sys_tablestats_tool);
2367
innodb_sys_indexes_tool= new(std::nothrow)InnodbSysIndexesTool();
2368
context.add(innodb_sys_indexes_tool);
2370
innodb_sys_columns_tool= new(std::nothrow)InnodbSysColumnsTool();
2371
context.add(innodb_sys_columns_tool);
2373
innodb_sys_fields_tool= new(std::nothrow)InnodbSysFieldsTool();
2374
context.add(innodb_sys_fields_tool);
2376
innodb_sys_foreign_tool= new(std::nothrow)InnodbSysForeignTool();
2377
context.add(innodb_sys_foreign_tool);
2379
innodb_sys_foreign_cols_tool= new(std::nothrow)InnodbSysForeignColsTool();
2380
context.add(innodb_sys_foreign_cols_tool);
2382
context.add(new(std::nothrow)InnodbInternalTables());
2383
context.add(new(std::nothrow)InnodbReplicationTable());
2496
context.add(new CmpTool(false));
2497
context.add(new CmpTool(true));
2498
context.add(new CmpmemTool(false));
2499
context.add(new CmpmemTool(true));
2500
context.add(new InnodbTrxTool("INNODB_TRX"));
2501
context.add(new InnodbTrxTool("INNODB_LOCKS"));
2502
context.add(new InnodbTrxTool("INNODB_LOCK_WAITS"));
2503
context.add(new InnodbSysTablesTool());
2504
context.add(new InnodbSysTableStatsTool());
2505
context.add(new InnodbSysIndexesTool());
2506
context.add(new InnodbSysColumnsTool());
2507
context.add(new InnodbSysFieldsTool());
2508
context.add(new InnodbSysForeignTool());
2509
context.add(new InnodbSysForeignColsTool());
2510
context.add(new InnodbInternalTables());
2511
context.add(new InnodbReplicationTable());
2385
2513
if (innobase_use_replication_log)
2387
replication_logger= new(std::nothrow)ReplicationLog();
2515
ReplicationLog *replication_logger= new ReplicationLog();
2388
2516
context.add(replication_logger);
2389
2517
ReplicationLog::setup(replication_logger);
2436
2564
innodb_file_format_max_validate));
2437
2565
context.registerVariable(new sys_var_constrained_value_readonly<size_t>("buffer_pool_size", innobase_buffer_pool_size));
2438
2566
context.registerVariable(new sys_var_constrained_value_readonly<int64_t>("log_file_size", innobase_log_file_size));
2439
context.registerVariable(new sys_var_constrained_value_readonly<uint16_t>("flush_log_at_trx_commit",
2567
context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("page_size", innobase_page_size));
2568
context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("log_block_size", innobase_log_block_size));
2569
context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("flush_log_at_trx_commit",
2440
2570
innodb_flush_log_at_trx_commit));
2441
2571
context.registerVariable(new sys_var_constrained_value_readonly<unsigned int>("max_dirty_pages_pct",
2442
2572
innodb_max_dirty_pages_pct));
2470
2600
context.registerVariable(new sys_var_constrained_value<uint32_t>("read_ahead_threshold",
2471
2601
innodb_read_ahead_threshold,
2472
2602
innodb_read_ahead_threshold_update));
2603
context.registerVariable(new sys_var_constrained_value<uint32_t>("auto_lru_dump",
2604
buffer_pool_restore_at_startup,
2605
auto_lru_dump_update));
2606
context.registerVariable(new sys_var_constrained_value_readonly<uint64_t>("ibuf_max_size",
2608
context.registerVariable(new sys_var_constrained_value<uint32_t>("ibuf_active_contract",
2609
ibuf_active_contract,
2610
ibuf_active_contract_update));
2611
context.registerVariable(new sys_var_constrained_value<uint32_t>("ibuf_accel_rate",
2613
ibuf_accel_rate_update));
2614
context.registerVariable(new sys_var_constrained_value<uint32_t>("checkpoint_age_target",
2615
checkpoint_age_target,
2616
checkpoint_age_target_update));
2617
context.registerVariable(new sys_var_constrained_value<uint32_t>("flush_neighbor_pages",
2618
flush_neighbor_pages,
2619
flush_neighbor_pages_update));
2620
context.registerVariable(new sys_var_std_string("read_ahead",
2622
read_ahead_validate));
2623
context.registerVariable(new sys_var_std_string("adaptive_flushing_method",
2624
adaptive_flushing_method,
2625
adaptive_flushing_method_validate));
2473
2626
/* Get the current high water mark format. */
2474
2627
innobase_file_format_max = trx_sys_file_format_max_get();
2475
2628
btr_search_fully_disabled = (!btr_search_enabled);
2571
2725
trx_search_latch_release_if_reserved(trx);
2575
|| (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
2577
2730
/* We were instructed to commit the whole transaction, or
2578
2731
this is an SQL statement end and autocommit is on */
2580
2733
/* We need current binlog position for ibbackup to work.
2581
2734
Note, the position is current because of
2582
2735
prepare_commit_mutex */
2584
if (innobase_commit_concurrency.get() > 0) {
2585
pthread_mutex_lock(&commit_cond_m);
2588
if (commit_threads > innobase_commit_concurrency.get()) {
2736
const uint32_t commit_concurrency= innobase_commit_concurrency.get();
2737
if (commit_concurrency)
2741
boost::mutex::scoped_lock scopedLock(commit_cond_m);
2744
if (commit_threads <= commit_concurrency)
2589
2747
commit_threads--;
2590
pthread_cond_wait(&commit_cond,
2592
pthread_mutex_unlock(&commit_cond_m);
2596
pthread_mutex_unlock(&commit_cond_m);
2748
commit_cond.wait(scopedLock);
2600
/* Store transaction point for binlog
2601
Later logic tests that this is set to _something_. We need
2602
that logic to fire, even though we do not have a real name. */
2603
trx->mysql_log_file_name = "UNUSED";
2752
trx->mysql_log_file_name = NULL;
2604
2753
trx->mysql_log_offset = 0;
2606
2755
/* Don't do write + flush right now. For group commit
2943
/*****************************************************************//**
2944
Normalizes a table name string. A normalized name consists of the
2945
database name catenated to '/' and table name. An example:
2946
test/mytable. On Windows normalization puts both the database name and the
2947
table name always to lower case. */
2950
normalize_table_name(
2951
/*=================*/
2952
char* norm_name, /*!< out: normalized name as a
2953
null-terminated string */
2954
const char* name) /*!< in: table name string */
2956
const char* name_ptr;
2960
/* Scan name from the end */
2962
ptr = strchr(name, '\0')-1;
2964
while (ptr >= name && *ptr != '\\' && *ptr != '/') {
2974
while (ptr >= name && *ptr != '\\' && *ptr != '/') {
2980
memcpy(norm_name, db_ptr, strlen(name) + 1 - (db_ptr - name));
2982
norm_name[name_ptr - db_ptr - 1] = '/';
2985
innobase_casedn_str(norm_name);
2989
3091
/********************************************************************//**
2990
3092
Get the upper limit of the MySQL integral and floating-point type.
2991
3093
@return maximum allowed value for the field */
3152
3254
if (!index_mapping) {
3153
3255
/* Report an error if index_mapping continues to be
3154
3256
NULL and mysql_num_index is a non-zero value */
3155
errmsg_printf(ERRMSG_LVL_ERROR,
3156
"InnoDB: fail to allocate memory for "
3157
"index translation table. Number of "
3158
"Index:%lu, array size:%lu",
3257
errmsg_printf(error::ERROR, "InnoDB: fail to allocate memory for "
3258
"index translation table. Number of Index:%lu, array size:%lu",
3159
3259
mysql_num_index,
3160
3260
share->idx_trans_tbl.array_size);
3176
3276
ib_table, table->key_info[count].name);
3178
3278
if (!index_mapping[count]) {
3179
errmsg_printf(ERRMSG_LVL_ERROR, "Cannot find index %s in InnoDB "
3180
"index dictionary.",
3181
table->key_info[count].name);
3279
errmsg_printf(error::ERROR, "Cannot find index %s in InnoDB index dictionary.",
3280
table->key_info[count].name);
3183
3282
goto func_exit;
3186
3285
/* Double check fetched index has the same
3187
3286
column info as those in mysql key_info. */
3188
if (!innobase_match_index_columns(&table->key_info[count],
3189
index_mapping[count])) {
3190
errmsg_printf(ERRMSG_LVL_ERROR, "Found index %s whose column info "
3191
"does not match that of MySQL.",
3192
table->key_info[count].name);
3287
if (!innobase_match_index_columns(&table->key_info[count], index_mapping[count])) {
3288
errmsg_printf(error::ERROR, "Found index %s whose column info does not match that of MySQL.",
3289
table->key_info[count].name);
3313
3409
case DB_RECORD_NOT_FOUND:
3314
3410
ut_print_timestamp(stderr);
3315
fprintf(stderr, " InnoDB: MySQL and InnoDB data "
3316
"dictionaries are out of sync.\n"
3317
"InnoDB: Unable to find the AUTOINC column "
3318
"%s in the InnoDB table %s.\n"
3319
"InnoDB: We set the next AUTOINC column "
3321
"InnoDB: in effect disabling the AUTOINC "
3322
"next value generation.\n"
3323
"InnoDB: You can either set the next "
3324
"AUTOINC value explicitly using ALTER TABLE\n"
3325
"InnoDB: or fix the data dictionary by "
3326
"recreating the table.\n",
3327
col_name, index->table->name);
3411
errmsg_printf(error::ERROR, "InnoDB: MySQL and InnoDB data dictionaries are out of sync.\n"
3412
"InnoDB: Unable to find the AUTOINC column %s in the InnoDB table %s.\n"
3413
"InnoDB: We set the next AUTOINC column value to 0,\n"
3414
"InnoDB: in effect disabling the AUTOINC next value generation.\n"
3415
"InnoDB: You can either set the next AUTOINC value explicitly using ALTER TABLE\n"
3416
"InnoDB: or fix the data dictionary by recreating the table.\n",
3417
col_name, index->table->name);
3329
3419
/* This will disable the AUTOINC generation. */
3370
3459
getTransactionalEngine()->releaseTemporaryLatches(session);
3373
normalize_table_name(norm_name, identifier.getPath().c_str());
3375
3462
user_session = NULL;
3377
if (!(share=get_share(identifier.getPath().c_str()))) {
3464
std::string search_string(identifier.getSchemaName());
3465
boost::algorithm::to_lower(search_string);
3467
if (search_string.compare("data_dictionary") == 0)
3469
std::string table_name(identifier.getTableName());
3470
boost::algorithm::to_upper(table_name);
3471
if (!(share=get_share(table_name.c_str())))
3478
if (!(share=get_share(identifier.getKeyPath().c_str())))
3382
3484
/* Create buffers for packing the fields of a record. Why
3405
3507
/* Get pointer to a table object in InnoDB dictionary cache */
3406
ib_table = dict_table_get(norm_name, TRUE);
3508
if (search_string.compare("data_dictionary") == 0)
3510
std::string table_name(identifier.getTableName());
3511
boost::algorithm::to_upper(table_name);
3512
ib_table = dict_table_get(table_name.c_str(), TRUE);
3516
ib_table = dict_table_get(identifier.getKeyPath().c_str(), TRUE);
3408
3519
if (NULL == ib_table) {
3409
errmsg_printf(ERRMSG_LVL_ERROR, "Cannot find or open table %s from\n"
3520
errmsg_printf(error::ERROR, "Cannot find or open table %s from\n"
3410
3521
"the internal data dictionary of InnoDB "
3411
3522
"though the .frm file for the\n"
3412
3523
"table exists. Maybe you have deleted and "
3429
3540
return(HA_ERR_NO_SUCH_TABLE);
3432
if (ib_table->ibd_file_missing && !session_tablespace_op(session)) {
3433
errmsg_printf(ERRMSG_LVL_ERROR, "MySQL is trying to open a table handle but "
3543
if (ib_table->ibd_file_missing && ! session->doing_tablespace_operation()) {
3544
errmsg_printf(error::ERROR, "MySQL is trying to open a table handle but "
3434
3545
"the .ibd file for\ntable %s does not exist.\n"
3435
3546
"Have you deleted the .ibd file from the "
3436
3547
"database directory under\nthe MySQL datadir, "
3437
3548
"or have you used DISCARD TABLESPACE?\n"
3438
3549
"See " REFMAN "innodb-troubleshooting.html\n"
3439
3550
"how you can resolve the problem.\n",
3551
identifier.getKeyPath().c_str());
3441
3552
free_share(share);
3442
3553
upd_buff.resize(0);
3443
3554
key_val_buff.resize(0);
3459
3570
key_used_on_scan = primary_key;
3461
3572
if (!innobase_build_index_translation(getTable(), ib_table, share)) {
3462
errmsg_printf(ERRMSG_LVL_ERROR, "Build InnoDB index translation table for"
3463
" Table %s failed", identifier.getPath().c_str());
3573
errmsg_printf(error::ERROR, "Build InnoDB index translation table for"
3574
" Table %s failed", identifier.getKeyPath().c_str());
3466
3577
/* Allocate a buffer for a 'row reference'. A row reference is
4288
4390
n_requested_fields++;
4290
4392
templ->col_no = i;
4393
templ->clust_rec_field_no = dict_col_get_clust_pos(col, clust_index);
4394
ut_ad(templ->clust_rec_field_no != ULINT_UNDEFINED);
4292
4396
if (index == clust_index) {
4293
templ->rec_field_no = dict_col_get_clust_pos(col, index);
4397
templ->rec_field_no = templ->clust_rec_field_no;
4295
4399
templ->rec_field_no = dict_index_get_nth_col_pos(
4299
if (templ->rec_field_no == ULINT_UNDEFINED) {
4300
prebuilt->need_to_access_clustered = TRUE;
4401
if (templ->rec_field_no == ULINT_UNDEFINED) {
4402
prebuilt->need_to_access_clustered = TRUE;
4303
4406
if (field->null_ptr) {
6122
6223
InnobaseEngine::doCreateTable(
6123
/*================*/
6124
Session &session, /*!< in: Session */
6125
Table& form, /*!< in: information on table columns and indexes */
6126
const TableIdentifier &identifier,
6127
message::Table& create_proto)
6224
/*================*/
6225
Session &session, /*!< in: Session */
6226
Table& form, /*!< in: information on table columns and indexes */
6227
const identifier::Table &identifier,
6228
const message::Table& create_proto)
6130
6231
dict_table_t* innobase_table;
6277
6375
if (lex_identified_temp_table)
6278
6376
iflags |= DICT_TF2_TEMPORARY << DICT_TF2_SHIFT;
6280
error= create_table_def(trx, &form, norm_name,
6281
lex_identified_temp_table ? name2 : NULL,
6378
error= create_table_def(trx, &form, identifier.getKeyPath().c_str(),
6379
lex_identified_temp_table ? identifier.getKeyPath().c_str() : NULL,
6284
6382
session.setXaId(trx->id);
6311
6409
for (i = 0; i < form.getShare()->sizeKeys(); i++) {
6312
6410
if (i != (uint) primary_key_no) {
6314
if ((error = create_index(trx, &form, iflags, norm_name,
6412
if ((error = create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
6321
stmt = innobase_get_stmt(&session, &stmt_len);
6419
stmt= session.getQueryStringCopy(stmt_len);
6324
6422
string generated_create_table;
6325
6423
const char *query= stmt;
6327
if (session_sql_command(&session) == SQLCOM_CREATE_TABLE)
6425
if (session.getSqlCommand() == SQLCOM_CREATE_TABLE)
6329
6427
message::transformTableDefinitionToSql(create_proto,
6330
6428
generated_create_table,
6335
6433
error = row_table_add_foreign_constraints(trx,
6336
6434
query, strlen(query),
6435
identifier.getKeyPath().c_str(),
6338
6436
lex_identified_temp_table);
6439
case DB_PARENT_NO_INDEX:
6440
push_warning_printf(
6441
&session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6442
HA_ERR_CANNOT_ADD_FOREIGN,
6443
"Create table '%s' with foreign key constraint"
6444
" failed. There is no index in the referenced"
6445
" table where the referenced columns appear"
6446
" as the first columns.\n", identifier.getKeyPath().c_str());
6449
case DB_CHILD_NO_INDEX:
6450
push_warning_printf(
6451
&session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6452
HA_ERR_CANNOT_ADD_FOREIGN,
6453
"Create table '%s' with foreign key constraint"
6454
" failed. There is no index in the referencing"
6455
" table where referencing columns appear"
6456
" as the first columns.\n", identifier.getKeyPath().c_str());
6340
6460
error = convert_error_code_to_mysql(error, iflags, NULL);
6505
6625
InnobaseEngine::doDropTable(
6506
6626
/*======================*/
6507
6627
Session &session,
6508
const TableIdentifier &identifier)
6628
const identifier::Table &identifier)
6511
6631
trx_t* parent_trx;
6513
char norm_name[1000];
6515
6634
ut_a(identifier.getPath().length() < 1000);
6517
/* Strangely, MySQL passes the table name without the '.frm'
6518
extension, in contrast to ::create */
6519
normalize_table_name(norm_name, identifier.getPath().c_str());
6636
std::string search_string(identifier.getSchemaName());
6637
boost::algorithm::to_lower(search_string);
6639
if (search_string.compare("data_dictionary") == 0)
6641
return HA_ERR_TABLE_READONLY;
6521
6644
/* Get the transaction associated with the current session, or create one
6522
6645
if not yet created */
6683
6807
innobase_rename_table(
6684
6808
/*==================*/
6685
6809
trx_t* trx, /*!< in: transaction */
6686
const char* from, /*!< in: old name of the table */
6687
const char* to, /*!< in: new name of the table */
6810
const identifier::Table &from,
6811
const identifier::Table &to,
6688
6812
ibool lock_and_commit)
6689
6813
/*!< in: TRUE=lock data dictionary and commit */
6692
char norm_to[FN_REFLEN];
6693
char norm_from[FN_REFLEN];
6695
6817
srv_lower_case_table_names = TRUE;
6697
normalize_table_name(norm_to, to);
6698
normalize_table_name(norm_from, from);
6700
6819
/* Serialize data dictionary operations with dictionary mutex:
6701
6820
no deadlocks can occur then in these operations */
6704
6823
row_mysql_lock_data_dictionary(trx);
6707
error = row_rename_table_for_mysql(
6708
norm_from, norm_to, trx, lock_and_commit);
6826
error = row_rename_table_for_mysql(from.getKeyPath().c_str(), to.getKeyPath().c_str(), trx, lock_and_commit);
6710
6828
if (error != DB_SUCCESS) {
6711
6829
FILE* ef = dict_foreign_err_file;
6713
6831
fputs("InnoDB: Renaming table ", ef);
6714
ut_print_name(ef, trx, TRUE, norm_from);
6832
ut_print_name(ef, trx, TRUE, from.getKeyPath().c_str());
6715
6833
fputs(" to ", ef);
6716
ut_print_name(ef, trx, TRUE, norm_to);
6834
ut_print_name(ef, trx, TRUE, to.getKeyPath().c_str());
6717
6835
fputs(" failed!\n", ef);
7241
7370
innodb_crash_recovery is set to a high value. */
7242
7371
stats.delete_length = 0;
7244
/* lock the data dictionary to avoid races with
7245
ibd_file_missing and tablespace_discarded */
7246
row_mysql_lock_data_dictionary(prebuilt->trx);
7248
/* ib_table->space must be an existent tablespace */
7249
if (!ib_table->ibd_file_missing
7250
&& !ib_table->tablespace_discarded) {
7252
stats.delete_length =
7253
fsp_get_available_space_in_free_extents(
7254
ib_table->space) * 1024;
7375
avail_space = fsp_get_available_space_in_free_extents(ib_table->space);
7377
if (avail_space == ULLINT_UNDEFINED) {
7257
7378
Session* session;
7259
7380
session= getTable()->in_use;
7721
7840
ha_innobase::get_foreign_key_list(Session *session, List<ForeignKeyInfo> *f_key_list)
7723
dict_foreign_t* foreign;
7725
7842
ut_a(prebuilt != NULL);
7726
7843
update_session(getTable()->in_use);
7727
prebuilt->trx->op_info = (char*)"getting list of foreign keys";
7844
prebuilt->trx->op_info = "getting list of foreign keys";
7728
7845
trx_search_latch_release_if_reserved(prebuilt->trx);
7729
7846
mutex_enter(&(dict_sys->mutex));
7730
foreign = UT_LIST_GET_FIRST(prebuilt->table->foreign_list);
7847
dict_foreign_t* foreign = UT_LIST_GET_FIRST(prebuilt->table->foreign_list);
7732
7849
while (foreign != NULL) {
7735
LEX_STRING *name = 0;
7737
7852
char uname[NAME_LEN + 1]; /* Unencoded name */
7738
7853
char db_name[NAME_LEN + 1];
7758
7873
db_name[i] = 0;
7759
ulen= TableIdentifier::filename_to_tablename(db_name, uname, sizeof(uname));
7760
LEX_STRING *tmp_referenced_db = session->make_lex_string(NULL, uname, ulen, true);
7874
ulen= identifier::Table::filename_to_tablename(db_name, uname, sizeof(uname));
7875
lex_string_t *tmp_referenced_db = session->make_lex_string(NULL, str_ref(uname, ulen));
7762
7877
/* Table name */
7763
7878
tmp_buff += i + 1;
7764
ulen= TableIdentifier::filename_to_tablename(tmp_buff, uname, sizeof(uname));
7765
LEX_STRING *tmp_referenced_table = session->make_lex_string(NULL, uname, ulen, true);
7879
ulen= identifier::Table::filename_to_tablename(tmp_buff, uname, sizeof(uname));
7880
lex_string_t *tmp_referenced_table = session->make_lex_string(NULL, str_ref(uname, ulen));
7767
7882
/** Foreign Fields **/
7768
List<LEX_STRING> tmp_foreign_fields;
7769
List<LEX_STRING> tmp_referenced_fields;
7771
tmp_buff= foreign->foreign_col_names[i];
7772
name = session->make_lex_string(name, tmp_buff, strlen(tmp_buff), true);
7773
tmp_foreign_fields.push_back(name);
7774
tmp_buff= foreign->referenced_col_names[i];
7775
name = session->make_lex_string(name, tmp_buff, strlen(tmp_buff), true);
7776
tmp_referenced_fields.push_back(name);
7883
List<lex_string_t> tmp_foreign_fields;
7884
List<lex_string_t> tmp_referenced_fields;
7887
tmp_foreign_fields.push_back(session->make_lex_string(NULL, str_ref(foreign->foreign_col_names[i])));
7888
tmp_referenced_fields.push_back(session->make_lex_string(NULL, str_ref(foreign->referenced_col_names[i])));
7777
7889
if (++i >= foreign->n_fields)
7823
7935
tmp_buff= "RESTRICT";
7825
LEX_STRING *tmp_update_method = session->make_lex_string(NULL, tmp_buff, length, true);
7827
LEX_STRING *tmp_referenced_key_name = NULL;
7829
if (foreign->referenced_index &&
7830
foreign->referenced_index->name)
7937
lex_string_t *tmp_update_method = session->make_lex_string(NULL, str_ref(tmp_buff, length));
7939
lex_string_t *tmp_referenced_key_name = NULL;
7941
if (foreign->referenced_index && foreign->referenced_index->name)
7832
tmp_referenced_key_name = session->make_lex_string(NULL,
7833
foreign->referenced_index->name, strlen(foreign->referenced_index->name), true);
7943
tmp_referenced_key_name = session->make_lex_string(NULL, str_ref(foreign->referenced_index->name));
7836
7946
ForeignKeyInfo f_key_info(
7838
7948
tmp_update_method, tmp_delete_method, tmp_referenced_key_name,
7839
7949
tmp_foreign_fields, tmp_referenced_fields);
7841
ForeignKeyInfo *pf_key_info = (ForeignKeyInfo *)
7842
session->memdup(&f_key_info, sizeof(ForeignKeyInfo));
7843
f_key_list->push_back(pf_key_info);
7951
f_key_list->push_back((ForeignKeyInfo*)session->mem.memdup(&f_key_info, sizeof(ForeignKeyInfo)));
7844
7952
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
7846
7954
mutex_exit(&(dict_sys->mutex));
7847
prebuilt->trx->op_info = (char*)"";
7955
prebuilt->trx->op_info = "";
8871
8972
finds charset information and returns length of prefix_len characters in the
8872
8973
index field in bytes.
8873
8974
@return number of bytes occupied by the first n characters */
8874
extern "C" UNIV_INTERN
8876
innobase_get_at_most_n_mbchars(
8877
/*===========================*/
8878
ulint charset_id, /*!< in: character set id */
8879
ulint prefix_len, /*!< in: prefix length in bytes of the index
8880
(this has to be divided by mbmaxlen to get the
8881
number of CHARACTERS n in the prefix) */
8882
ulint data_len, /*!< in: length of the string in bytes */
8883
const char* str); /*!< in: character string */
8886
8977
innobase_get_at_most_n_mbchars(
9228
9319
"Number of UNDO logs to purge in one batch from the history list. "
9229
9320
"Default is 20.");
9230
9321
context("purge-threads",
9231
po::value<purge_threads_constraint>(&innodb_n_purge_threads)->default_value(0),
9232
"Purge threads can be either 0 or 1. Defalut is 0.");
9322
po::value<purge_threads_constraint>(&innodb_n_purge_threads)->default_value(1),
9323
"Purge threads can be either 0 or 1. Default is 1.");
9233
9324
context("file-per-table",
9234
9325
po::value<bool>(&srv_file_per_table)->default_value(false)->zero_tokens(),
9235
"Stores each InnoDB table to an .ibd file in the database dir.");
9236
context("file-format",
9237
po::value<string>(&innobase_file_format_name)->default_value("Antelope"),
9238
"File format to use for new tables in .ibd files.");
9326
"Stores each InnoDB table to an .ibd file in the database dir.");
9239
9327
context("file-format-max",
9240
9328
po::value<string>(&innobase_file_format_max)->default_value("Antelope"),
9241
9329
"The highest file format in the tablespace.");
9242
9330
context("file-format-check",
9243
9331
po::value<bool>(&innobase_file_format_check)->default_value(true)->zero_tokens(),
9244
9332
"Whether to perform system file format check.");
9333
context("file-format",
9334
po::value<string>(&innobase_file_format_name)->default_value("Antelope"),
9335
"File format to use for new tables in .ibd files.");
9245
9336
context("flush-log-at-trx-commit",
9246
9337
po::value<trinary_constraint>(&innodb_flush_log_at_trx_commit)->default_value(1),
9247
9338
"Set to 0 (write and flush once per second), 1 (write and flush at each commit) or 2 (write at commit, flush once per second).");
9276
9367
po::value<additional_mem_pool_constraint>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
9277
9368
"Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.");
9278
9369
context("autoextend-increment",
9279
po::value<autoextend_constraint>(&innodb_auto_extend_increment)->default_value(8L),
9370
po::value<autoextend_constraint>(&innodb_auto_extend_increment)->default_value(64L),
9280
9371
"Data file autoextend increment in megabytes");
9281
9372
context("buffer-pool-size",
9282
9373
po::value<buffer_pool_constraint>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
9306
9397
context("log-file-size",
9307
9398
po::value<log_file_constraint>(&innobase_log_file_size)->default_value(20*1024*1024L),
9308
9399
"The size of the buffer which InnoDB uses to write log to the log files on disk.");
9400
context("page-size",
9401
po::value<page_size_constraint>(&innobase_page_size)->default_value(1 << 14),
9402
"###EXPERIMENTAL###: The universal page size of the database. Changing for created database is not supported. Use on your own risk!");
9403
context("log-block-size",
9404
po::value<log_block_size_constraint>(&innobase_log_block_size)->default_value(1 << 9),
9405
"###EXPERIMENTAL###: The log block size of the transaction log file. Changing for created log file is not supported. Use on your own risk!");
9309
9406
context("log-files-in-group",
9310
9407
po::value<log_files_in_group_constraint>(&innobase_log_files_in_group)->default_value(2),
9311
9408
"Number of log files in the log group. InnoDB writes to the files in a circular fashion.");
9335
9432
"InnoDB version");
9336
9433
context("use-internal-malloc",
9337
9434
"Use InnoDB's internal memory allocator instal of the OS memory allocator.");
9435
context("disable-native-aio",
9436
_("Do not use Native AIO library for IO, even if available"));
9338
9437
context("change-buffering",
9339
9438
po::value<string>(&innobase_change_buffering),
9340
9439
"Buffer changes to reduce random access: OFF, ON, inserting, deleting, changing, or purging.");
9341
9440
context("read-ahead-threshold",
9342
9441
po::value<read_ahead_threshold_constraint>(&innodb_read_ahead_threshold)->default_value(56),
9343
9442
"Number of pages that must be accessed sequentially for InnoDB to trigger a readahead.");
9443
context("auto-lru-dump",
9444
po::value<uint32_constraint>(&buffer_pool_restore_at_startup)->default_value(0),
9445
"Time in seconds between automatic buffer pool dumps. "
9446
"0 (the default) disables automatic dumps.");
9447
context("ibuf-max-size",
9448
po::value<uint64_constraint>(&ibuf_max_size)->default_value(UINT64_MAX),
9449
"The maximum size of the insert buffer (in bytes).");
9450
context("ibuf-active-contract",
9451
po::value<binary_constraint>(&ibuf_active_contract)->default_value(1),
9452
"Enable/Disable active_contract of insert buffer. 0:disable 1:enable");
9453
context("ibuf-accel-rate",
9454
po::value<ibuf_accel_rate_constraint>(&ibuf_accel_rate)->default_value(100),
9455
"Tunes amount of insert buffer processing of background, in addition to innodb_io_capacity. (in percentage)");
9456
context("checkpoint-age-target",
9457
po::value<uint32_constraint>(&checkpoint_age_target)->default_value(0),
9458
"Control soft limit of checkpoint age. (0 : not control)");
9459
context("flush-neighbor-pages",
9460
po::value<binary_constraint>(&flush_neighbor_pages)->default_value(1),
9461
"Enable/Disable flushing also neighbor pages. 0:disable 1:enable");
9462
context("read-ahead",
9463
po::value<string>(&read_ahead)->default_value("linear"),
9464
"Control read ahead activity (none, random, [linear], both). [from 1.0.5: random read ahead is ignored]");
9465
context("adaptive-flushing-method",
9466
po::value<string>(&adaptive_flushing_method)->default_value("estimate"),
9467
"Choose method of innodb_adaptive_flushing. (native, [estimate], keep_average)");
9344
9468
context("disable-xa",
9345
9469
"Disable InnoDB support for the XA two-phase commit");
9346
9470
context("disable-table-locks",
9349
9473
po::value<bool>(&strict_mode)->default_value(false)->zero_tokens(),
9350
9474
"Use strict mode when evaluating create options.");
9351
9475
context("replication-log",
9352
po::value<bool>(&innobase_use_replication_log)->default_value(false),
9476
po::value<bool>(&innobase_use_replication_log)->default_value(false)->zero_tokens(),
9353
9477
_("Enable internal replication log."));
9354
9478
context("lock-wait-timeout",
9355
9479
po::value<lock_wait_constraint>(&lock_wait_timeout)->default_value(50),