47 #include <drizzled/error.h>
48 #include <drizzled/errmsg_print.h>
49 #include <drizzled/internal/m_string.h>
50 #include <drizzled/internal/my_sys.h>
51 #include <drizzled/plugin.h>
53 #include <drizzled/data_home.h>
54 #include <drizzled/catalog/local.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/plugin/xa_storage_engine.h>
64 #include <drizzled/plugin/daemon.h>
65 #include <drizzled/memory/multi_malloc.h>
66 #include <drizzled/pthread_globals.h>
67 #include <drizzled/named_savepoint.h>
68 #include <drizzled/session/table_messages.h>
69 #include <drizzled/transaction_services.h>
72 #include <drizzled/statistics_variables.h>
73 #include <drizzled/system_variables.h>
74 #include <drizzled/session/times.h>
75 #include <drizzled/session/transactions.h>
76 #include <drizzled/typelib.h>
78 #include <boost/algorithm/string.hpp>
79 #include <boost/program_options.hpp>
80 #include <boost/scoped_array.hpp>
81 #include <boost/filesystem.hpp>
85 namespace po= boost::program_options;
86 namespace fs=boost::filesystem;
110 #include "create_replication.h"
124 #include "ha_innodb.h"
125 #include "data_dictionary.h"
126 #include "replication_dictionary.h"
127 #include "internal_dictionary.h"
134 #include <plugin/innobase/handler/status_function.h>
135 #include <plugin/innobase/handler/replication_log.h>
137 #include <google/protobuf/io/zero_copy_stream.h>
138 #include <google/protobuf/io/zero_copy_stream_impl.h>
139 #include <google/protobuf/io/coded_stream.h>
140 #include <google/protobuf/text_format.h>
142 #include <boost/thread/mutex.hpp>
145 using namespace drizzled;
152 static boost::condition_variable commit_cond;
153 static boost::mutex commit_cond_m;
154 static bool innodb_inited = 0;
156 #define INSIDE_HA_INNOBASE_CC
160 #if defined MYSQL_DYNAMIC_PLUGIN && defined __WIN__
161 # undef current_session
162 # define current_session NULL
163 # define EQ_CURRENT_SESSION(session) TRUE
165 # define EQ_CURRENT_SESSION(session) ((session) == current_session)
168 static plugin::XaStorageEngine* innodb_engine_ptr= NULL;
189 (1 << UNIV_PAGE_SIZE_SHIFT_MAX),
193 (1 << UNIV_PAGE_SIZE_SHIFT_MAX),
246 static string sysvar_transaction_log_use_replicator;
251 std::string innobase_data_home_dir;
252 std::string innobase_data_file_path;
253 std::string innobase_log_group_home_dir;
254 static string innobase_file_format_name;
255 static string innobase_change_buffering;
257 static string read_ahead;
258 static string adaptive_flushing_method;
263 static string innobase_file_format_max;
282 static my_bool innobase_file_format_check = TRUE;
283 static my_bool innobase_use_doublewrite = TRUE;
284 static my_bool innobase_use_checksums = TRUE;
285 static my_bool innobase_rollback_on_timeout = FALSE;
286 static my_bool innobase_create_status_file = FALSE;
287 static bool innobase_use_replication_log;
288 static bool support_xa;
289 static bool strict_mode;
293 static char* internal_innobase_data_file_path = NULL;
300 #define INNOBASE_WAKE_INTERVAL 32
301 static ulong innobase_active_counter = 0;
306 bool nw_panic = FALSE;
333 static TYPELIB read_ahead_typelib = {
350 static TYPELIB adaptive_flushing_method_typelib = {
352 "adaptive_flushing_method_typelib",
358 static const char innobase_index_reserve_name[]=
"GEN_CLUST_INDEX";
362 static const char* ha_innobase_exts[] = {
367 #define DEFAULT_FILE_EXTENSION ".dfe" // Deep Fried Elephant
376 plugin::XaStorageEngine(name_arg,
378 HTON_CAN_INDEX_BLOBS |
379 HTON_PRIMARY_KEY_IN_READ_INDEX |
380 HTON_PARTIAL_COLUMN_READ |
381 HTON_TABLE_SCAN_ON_INDEX |
382 HTON_HAS_FOREIGN_KEYS |
383 HTON_HAS_DOES_TRANSACTIONS)
385 table_definition_ext= plugin::DEFAULT_DEFINITION_FILE_EXT;
386 addAlias(
"INNOBASE");
392 srv_fast_shutdown = (ulint) innobase_fast_shutdown;
394 hash_table_free(innobase_open_tables);
395 innobase_open_tables = NULL;
400 free(internal_innobase_data_file_path);
408 virtual int doStartTransaction(
Session *session, start_transaction_option_t options);
409 virtual void doStartStatement(
Session *session);
410 virtual void doEndStatement(
Session *session);
420 virtual int doSetSavepoint(
Session* session,
422 virtual int doRollbackToSavepoint(
Session* session,
424 virtual int doReleaseSavepoint(
Session* session,
426 virtual int doXaCommit(
Session* session,
bool all)
428 return doCommit(session, all);
430 virtual int doXaRollback(
Session *session,
bool all)
432 return doRollback(session, all);
434 virtual uint64_t doGetCurrentTransactionId(
Session *session);
435 virtual uint64_t doGetNewTransactionId(
Session *session);
436 virtual int doCommit(
Session* session,
bool all);
437 virtual int doRollback(
Session* session,
bool all);
512 stat_print_fn *stat_print,
513 enum ha_stat_type stat_type);
517 doReleaseTemporaryLatches(
523 const char** bas_ext()
const {
524 return(ha_innobase_exts);
527 UNIV_INTERN
int doCreateTable(
Session &session,
534 UNIV_INTERN
virtual bool get_error_message(
int error,
String *buf)
const;
536 UNIV_INTERN uint32_t max_supported_keys()
const;
537 UNIV_INTERN uint32_t max_supported_key_length()
const;
538 UNIV_INTERN uint32_t max_supported_key_part_length()
const;
541 UNIV_INTERN uint32_t index_flags(
enum ha_key_alg)
const
543 return (HA_READ_NEXT |
558 drizzled::identifier::table::vector &set_of_identifiers);
559 bool validateCreateTableOption(
const std::string &key,
const std::string &state);
560 void dropTemporarySchema();
565 bool InnobaseEngine::validateCreateTableOption(
const std::string &key,
const std::string &state)
567 if (boost::iequals(key,
"ROW_FORMAT"))
569 if (boost::iequals(state,
"COMPRESSED"))
572 if (boost::iequals(state,
"COMPACT"))
575 if (boost::iequals(state,
"DYNAMIC"))
578 if (boost::iequals(state,
"REDUNDANT"))
587 drizzled::identifier::table::vector &set_of_identifiers)
589 CachedDirectory::Entries entries= directory.
getEntries();
591 std::string search_string(schema_identifier.getSchemaName());
593 boost::algorithm::to_lower(search_string);
595 if (search_string.compare(
"data_dictionary") == 0)
597 set_of_identifiers.push_back(
identifier::Table(schema_identifier.getSchemaName(),
"SYS_REPLICATION_LOG"));
600 for (CachedDirectory::Entries::iterator entry_iter= entries.begin();
601 entry_iter != entries.end(); ++entry_iter)
604 const string *filename= &entry->filename;
606 assert(filename->size());
608 const char *ext= strchr(filename->c_str(),
'.');
610 if (ext == NULL || system_charset_info->strcasecmp(ext, DEFAULT_FILE_EXTENSION) ||
618 path+= entry->filename;
621 if (StorageEngine::readTableFile(path, definition))
627 identifier::Table identifier(schema_identifier.getSchemaName(), definition.name());
628 set_of_identifiers.push_back(identifier);
636 string proto_path(identifier.getPath());
637 proto_path.append(DEFAULT_FILE_EXTENSION);
639 if (session.getMessageCache().doesTableMessageExist(identifier))
642 std::string search_string(identifier.getPath());
643 boost::algorithm::to_lower(search_string);
645 if (search_string.compare(
"data_dictionary/sys_replication_log") == 0)
648 if (access(proto_path.c_str(), F_OK))
656 int InnobaseEngine::doGetTableDefinition(
Session &session,
660 string proto_path(identifier.getPath());
661 proto_path.append(DEFAULT_FILE_EXTENSION);
664 if (session.getMessageCache().getTableMessage(identifier, table_proto))
667 if (read_replication_log_table_message(identifier.getTableName().c_str(), &table_proto) == 0)
670 if (access(proto_path.c_str(), F_OK))
675 if (StorageEngine::readTableFile(proto_path, table_proto))
689 const char* format_name);
699 const char* format_max);
701 static const char innobase_engine_name[]=
"InnoDB";
713 {
"buffer_pool_pages_data",
715 {
"buffer_pool_pages_dirty",
717 {
"buffer_pool_pages_flushed",
719 {
"buffer_pool_pages_free",
722 {
"buffer_pool_pages_latched",
723 (
char*) &
export_vars.innodb_buffer_pool_pages_latched, SHOW_LONG},
725 {
"buffer_pool_pages_misc",
727 {
"buffer_pool_pages_total",
729 {
"buffer_pool_read_ahead",
731 {
"buffer_pool_read_ahead_evicted",
733 {
"buffer_pool_read_requests",
735 {
"buffer_pool_reads",
737 {
"buffer_pool_wait_free",
739 {
"buffer_pool_write_requests",
743 {
"data_pending_fsyncs",
745 {
"data_pending_reads",
747 {
"data_pending_writes",
757 {
"dblwr_pages_written",
761 {
"have_atomic_builtins",
765 {
"log_write_requests",
771 {
"os_log_pending_fsyncs",
773 {
"os_log_pending_writes",
785 {
"row_lock_current_waits",
789 {
"row_lock_time_avg",
791 {
"row_lock_time_max",
803 {NULL, NULL, SHOW_LONG}
807 plugin::TableFunction::Generator(fields)
810 status_var_ptr= innodb_status_variables;
813 bool InnodbStatusTool::Generator::populate()
815 if (status_var_ptr->name)
817 std::ostringstream oss;
819 const char *value= status_var_ptr->value;
822 push(status_var_ptr->name);
824 switch (status_var_ptr->type)
827 oss << *(int64_t*) value;
828 return_value= oss.str();
831 oss << *(int64_t*) value;
832 return_value= oss.str();
835 return_value= *(
bool*) value ?
"ON" :
"OFF";
842 if (return_value.length())
884 if (UNIV_LIKELY(!srv_thread_concurrency)) {
901 if (UNIV_LIKELY(!trx->declared_to_be_inside_innodb)) {
920 if (trx->has_search_latch) {
924 if (trx->declared_to_be_inside_innodb) {
958 return(session->getSqlCommand() == SQLCOM_SELECT);
989 return((ulong)lock_wait_timeout.get());
1002 in_session->times.utime_after_lock+= value;
1014 return *(
trx_t**) session->getEngineData(innodb_engine_ptr);
1021 char *data=
new char[message.ByteSize()];
1023 message.SerializeToArray(data, message.ByteSize());
1027 uint64_t trx_id= message.transaction_context().transaction_id();
1028 uint32_t seg_id= message.segment_id();
1029 uint64_t end_timestamp= message.transaction_context().end_timestamp();
1030 bool is_end_segment= message.end_segment();
1033 string server_uuid= session.getServerUUID();
1034 string originating_server_uuid= session.getOriginatingServerUUID();
1035 uint64_t originating_commit_id= session.getOriginatingCommitID();
1036 bool use_originating_server_uuid= session.isOriginatingServerUUIDSet();
1038 ulint error= insert_replication_message(data, message.ByteSize(), trx, trx_id,
1039 end_timestamp, is_end_segment, seg_id, server_uuid.c_str(),
1040 use_originating_server_uuid, originating_server_uuid.c_str(),
1041 originating_commit_id);
1047 return plugin::SUCCESS;
1062 assert(
this == innodb_engine_ptr);
1064 if (!innodb_inited) {
1087 innobase_active_counter++;
1089 if ((innobase_active_counter % INNOBASE_WAKE_INTERVAL) == 0) {
1111 case DB_INTERRUPTED:
1112 my_error(ER_QUERY_INTERRUPTED, MYF(0));
1115 case DB_FOREIGN_EXCEED_MAX_CASCADE:
1116 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1117 HA_ERR_ROW_IS_REFERENCED,
1118 "InnoDB: Cannot delete/update "
1119 "rows with cascading foreign key "
1120 "constraints that exceed max "
1121 "depth of %d. Please "
1122 "drop extra constraints and try "
1130 case DB_DUPLICATE_KEY:
1137 return(HA_ERR_FOUND_DUPP_KEY);
1139 case DB_FOREIGN_DUPLICATE_KEY:
1140 return(HA_ERR_FOREIGN_DUPLICATE_KEY);
1142 case DB_MISSING_HISTORY:
1143 return(HA_ERR_TABLE_DEF_CHANGED);
1145 case DB_RECORD_NOT_FOUND:
1146 return(HA_ERR_NO_ACTIVE_RECORD);
1155 return(HA_ERR_LOCK_DEADLOCK);
1157 case DB_LOCK_WAIT_TIMEOUT:
1164 return(HA_ERR_LOCK_WAIT_TIMEOUT);
1166 case DB_NO_REFERENCED_ROW:
1167 return(HA_ERR_NO_REFERENCED_ROW);
1169 case DB_ROW_IS_REFERENCED:
1170 return(HA_ERR_ROW_IS_REFERENCED);
1172 case DB_CANNOT_ADD_CONSTRAINT:
1173 case DB_CHILD_NO_INDEX:
1174 case DB_PARENT_NO_INDEX:
1175 return(HA_ERR_CANNOT_ADD_FOREIGN);
1177 case DB_CANNOT_DROP_CONSTRAINT:
1179 return(HA_ERR_ROW_IS_REFERENCED);
1183 case DB_COL_APPEARS_TWICE_IN_INDEX:
1185 return(HA_ERR_CRASHED);
1187 case DB_OUT_OF_FILE_SPACE:
1188 return(HA_ERR_RECORD_FILE_FULL);
1190 case DB_TABLE_IS_BEING_USED:
1191 return(HA_ERR_WRONG_COMMAND);
1193 case DB_TABLE_NOT_FOUND:
1194 return(HA_ERR_NO_SUCH_TABLE);
1196 case DB_TOO_BIG_RECORD:
1197 my_error(ER_TOO_BIG_ROWSIZE, MYF(0),
1199 return(HA_ERR_TO_BIG_ROW);
1201 case DB_NO_SAVEPOINT:
1202 return(HA_ERR_NO_SAVEPOINT);
1204 case DB_LOCK_TABLE_FULL:
1211 return(HA_ERR_LOCK_TABLE_FULL);
1213 case DB_PRIMARY_KEY_IS_NULL:
1214 return(ER_PRIMARY_CANT_HAVE_NULL);
1216 case DB_TOO_MANY_CONCURRENT_TRXS:
1230 #ifdef HA_ERR_TOO_MANY_CONCURRENT_TRXS
1231 return(HA_ERR_TOO_MANY_CONCURRENT_TRXS);
1233 return(HA_ERR_RECORD_FILE_FULL);
1235 case DB_UNSUPPORTED:
1236 return(HA_ERR_UNSUPPORTED);
1252 drizzled::identifier::user::ptr user_identifier(in_session->user());
1255 "Drizzle thread %"PRIu64
", query id %"PRIu64
", %s, %s, %s ",
1257 static_cast<uint64_t>(in_session->
getQueryId()),
1258 getServerHostname().c_str(),
1259 user_identifier->address().c_str(),
1260 user_identifier->username().c_str()
1262 fprintf(f,
"\n%s", in_session->getQueryString()->c_str());
1281 cs = all_charsets[cset];
1283 *mbminlen = cs->mbminlen;
1284 *mbmaxlen = cs->mbmaxlen;
1285 ut_ad(*mbminlen < DATA_MBMAX);
1286 ut_ad(*mbmaxlen < DATA_MBMAX);
1289 *mbminlen = *mbmaxlen = 0;
1304 strncpy(to, from, len);
1318 strncpy(to, from, len);
1331 return(system_charset_info->strcasecmp(a, b));
1342 system_charset_info->casedn_str(a);
1351 return static_cast<const charset_info_st*
>(cs)->isspace(char_to_test);
1354 #if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
1374 TCHAR path_buf[MAX_PATH - 14];
1378 char filename[MAX_PATH];
1379 DWORD fileaccess = GENERIC_READ
1382 DWORD fileshare = FILE_SHARE_READ
1384 | FILE_SHARE_DELETE;
1385 DWORD filecreate = CREATE_ALWAYS;
1387 FILE_ATTRIBUTE_NORMAL
1388 | FILE_FLAG_DELETE_ON_CLOSE
1389 | FILE_ATTRIBUTE_TEMPORARY
1390 | FILE_FLAG_SEQUENTIAL_SCAN;
1392 tmpdir = my_tmpdir(&mysql_tmpdir_list);
1399 ret = GetTempPath(
sizeof(path_buf), path_buf);
1400 if (ret >
sizeof(path_buf) || (ret == 0)) {
1402 _dosmaperr(GetLastError());
1410 if (!GetTempFileName(tmpdir,
"ib", 0, filename)) {
1412 _dosmaperr(GetLastError());
1417 osfh = CreateFile(filename, fileaccess, fileshare, NULL,
1418 filecreate, fileattrib, NULL);
1419 if (osfh == INVALID_HANDLE_VALUE) {
1422 _dosmaperr(GetLastError());
1428 fd = _open_osfhandle((intptr_t) osfh, 0);
1429 }
while (fd == -1 && errno == EINTR);
1434 _dosmaperr(GetLastError());
1451 int fd = ::drizzled::tmpfile(
"ib");
1464 my_error(EE_OUT_OF_FILERESOURCES,
1465 MYF(ME_BELL+ME_WAITTANG),
1468 internal::my_close(fd, MYF(MY_WME));
1525 uint64_t next_value;
1528 ut_a(increment > 0);
1532 if (offset > increment) {
1536 if (max_value <= current) {
1537 next_value = max_value;
1538 }
else if (offset <= 1) {
1541 if (max_value - current <= increment) {
1542 next_value = max_value;
1544 next_value = current + increment;
1546 }
else if (max_value > current) {
1547 if (current > offset) {
1548 next_value = ((current - offset) / increment) + 1;
1550 next_value = ((offset - current) / increment) + 1;
1553 ut_a(increment > 0);
1554 ut_a(next_value > 0);
1557 if (increment > (max_value / next_value)) {
1559 next_value = max_value;
1561 next_value *= increment;
1563 ut_a(max_value >= next_value);
1566 if (max_value - next_value <= offset) {
1567 next_value = max_value;
1569 next_value += offset;
1573 next_value = max_value;
1576 ut_a(next_value <= max_value);
1592 trx->check_foreigns = !session_test_options(
1593 session, OPTION_NO_FOREIGN_KEY_CHECKS);
1595 trx->check_unique_secondary = !session_test_options(
1596 session, OPTION_RELAXED_UNIQUE_CHECKS);
1612 assert(session != NULL);
1613 assert(EQ_CURRENT_SESSION(session));
1637 ut_ad(EQ_CURRENT_SESSION(session));
1641 }
else if (UNIV_UNLIKELY(trx->magic_n != TRX_MAGIC_N)) {
1657 :
Cursor(engine_arg, table_arg),
1712 char nz[NAME_LEN + 1];
1714 boost::scoped_array<char> nz2(
new char[nz2_size]);
1724 if (UNIV_UNLIKELY(idlen > (
sizeof nz) - 1)) {
1725 idlen = (
sizeof nz) - 1;
1728 memcpy(nz,
id, idlen);
1732 idlen = identifier::Table::filename_to_tablename(nz, nz2.get(), nz2_size);
1736 if (UNIV_UNLIKELY(!session)) {
1739 q = get_quote_char_for_identifier();
1743 if (UNIV_UNLIKELY(idlen > buflen)) {
1746 memcpy(buf, s, idlen);
1747 return(buf + idlen);
1758 for (; idlen; idlen--) {
1760 if (UNIV_UNLIKELY(c == q)) {
1761 if (UNIV_UNLIKELY(buflen < 3)) {
1769 if (UNIV_UNLIKELY(buflen < 2)) {
1799 const char* bufend = buf + buflen;
1802 const char* slash = (
const char*) memchr(
id,
'/', idlen);
1811 if (UNIV_LIKELY(s < bufend)) {
1820 const char temp_index_suffix[]=
"--temporary--";
1824 if (s - buf + (
sizeof temp_index_suffix - 1) < buflen) {
1825 memcpy(s, temp_index_suffix,
1826 sizeof temp_index_suffix - 1);
1827 s +=
sizeof temp_index_suffix - 1;
1878 void align_value(T& value,
size_t align_val= 1024)
1880 value= value - (value % align_val);
1883 static void auto_extend_update(
Session *, sql_var_t)
1885 srv_auto_extend_increment= innodb_auto_extend_increment.get();
1888 static void io_capacity_update(
Session *, sql_var_t)
1890 srv_io_capacity= innodb_io_capacity.get();
1893 static void purge_batch_update(
Session *, sql_var_t)
1895 srv_purge_batch_size= innodb_purge_batch_size.get();
1898 static void purge_threads_update(
Session *, sql_var_t)
1900 srv_n_purge_threads= innodb_n_purge_threads.get();
1903 static void innodb_adaptive_hash_index_update(
Session *, sql_var_t)
1905 if (btr_search_enabled)
1907 btr_search_enable();
1909 btr_search_disable();
1913 static void innodb_old_blocks_pct_update(
Session *, sql_var_t)
1915 innobase_old_blocks_pct= buf_LRU_old_ratio_update(innobase_old_blocks_pct.get(), TRUE);
1918 static void innodb_thread_concurrency_update(
Session *, sql_var_t)
1920 srv_thread_concurrency= innobase_thread_concurrency.get();
1923 static void innodb_sync_spin_loops_update(
Session *, sql_var_t)
1925 srv_n_spin_wait_rounds= innodb_sync_spin_loops.get();
1928 static void innodb_spin_wait_delay_update(
Session *, sql_var_t)
1930 srv_spin_wait_delay= innodb_spin_wait_delay.get();
1933 static void innodb_thread_sleep_delay_update(
Session *, sql_var_t)
1935 srv_thread_sleep_delay= innodb_thread_sleep_delay.get();
1938 static void innodb_read_ahead_threshold_update(
Session *, sql_var_t)
1940 srv_read_ahead_threshold= innodb_read_ahead_threshold.get();
1943 static void auto_lru_dump_update(
Session *, sql_var_t)
1948 static void ibuf_active_contract_update(
Session *, sql_var_t)
1950 srv_ibuf_active_contract= ibuf_active_contract.get();
1953 static void ibuf_accel_rate_update(
Session *, sql_var_t)
1955 srv_ibuf_accel_rate= ibuf_accel_rate.get();
1958 static void checkpoint_age_target_update(
Session *, sql_var_t)
1960 srv_checkpoint_age_target= checkpoint_age_target.get();
1963 static void flush_neighbor_pages_update(
Session *, sql_var_t)
1965 srv_flush_neighbor_pages= flush_neighbor_pages.get();
1970 uint64_t new_value= var->getInteger();
1972 if ((innobase_commit_concurrency.get() == 0 && new_value != 0) ||
1973 (innobase_commit_concurrency.get() != 0 && new_value == 0))
1975 push_warning_printf(session,
1976 DRIZZLE_ERROR::WARN_LEVEL_WARN,
1978 _(
"Once InnoDB is running, innodb_commit_concurrency "
1979 "must not change between zero and nonzero."));
1996 const char *file_format_input = var->value->
str_value.ptr();
1997 if (file_format_input == NULL)
2000 if (file_format_input != NULL) {
2007 innobase_file_format_name =
2028 const char *change_buffering_input = var->value->
str_value.ptr();
2030 if (change_buffering_input == NULL)
2061 const char *file_format_input = var->value->
str_value.ptr();
2062 if (file_format_input == NULL)
2065 if (file_format_input != NULL) {
2073 if (format_id >= 0) {
2074 innobase_file_format_max.assign(
2078 const char *name_buff;
2082 errmsg_printf(error::WARN,
2083 " [Info] InnoDB: the file format in the system "
2084 "tablespace is now set to %s.\n", name_buff);
2085 innobase_file_format_max= name_buff;
2090 push_warning_printf(session,
2091 DRIZZLE_ERROR::WARN_LEVEL_WARN,
2093 "InnoDB: invalid innodb_file_format_max "
2094 "value; can be any format up to %s "
2095 "or equivalent id of %d",
2115 const char *read_ahead_input = var->value->
str_value.ptr();
2116 int res = read_ahead_typelib.find_type(read_ahead_input, TYPELIB::e_none);
2119 srv_read_ahead = res - 1;
2137 const char *adaptive_flushing_method_input = var->value->
str_value.ptr();
2138 int res = adaptive_flushing_method_typelib.find_type(adaptive_flushing_method_input, TYPELIB::e_none);
2141 srv_adaptive_flushing_method = res - 1;
2163 srv_auto_extend_increment= innodb_auto_extend_increment.get();
2164 srv_io_capacity= innodb_io_capacity.get();
2165 srv_purge_batch_size= innodb_purge_batch_size.get();
2166 srv_n_purge_threads= innodb_n_purge_threads.get();
2167 srv_flush_log_at_trx_commit= innodb_flush_log_at_trx_commit.get();
2168 srv_max_buf_pool_modified_pct= innodb_max_dirty_pages_pct.get();
2169 srv_max_purge_lag= innodb_max_purge_lag.get();
2170 srv_stats_sample_pages= innodb_stats_sample_pages.get();
2171 srv_n_free_tickets_to_enter= innodb_concurrency_tickets.get();
2172 srv_replication_delay= innodb_replication_delay.get();
2173 srv_thread_concurrency= innobase_thread_concurrency.get();
2174 srv_n_spin_wait_rounds= innodb_sync_spin_loops.get();
2175 srv_spin_wait_delay= innodb_spin_wait_delay.get();
2176 srv_thread_sleep_delay= innodb_thread_sleep_delay.get();
2177 srv_read_ahead_threshold= innodb_read_ahead_threshold.get();
2179 srv_ibuf_max_size= ibuf_max_size.get();
2180 srv_ibuf_active_contract= ibuf_active_contract.get();
2181 srv_ibuf_accel_rate= ibuf_accel_rate.get();
2182 srv_checkpoint_age_target= checkpoint_age_target.get();
2183 srv_flush_neighbor_pages= flush_neighbor_pages.get();
2185 srv_read_ahead = read_ahead_typelib.find_type_or_exit(vm[
"read-ahead"].as<string>().c_str(),
2186 "read_ahead_typelib") + 1;
2188 srv_adaptive_flushing_method = adaptive_flushing_method_typelib.find_type_or_exit(vm[
"adaptive-flushing-method"].as<string>().c_str(),
2189 "adaptive_flushing_method_typelib") + 1;
2193 innobase_use_checksums= not vm.count(
"disable-checksums");
2194 innobase_use_doublewrite= not vm.count(
"disable-doublewrite");
2195 srv_adaptive_flushing= not vm.count(
"disable-adaptive-flushing");
2196 srv_use_sys_malloc= not vm.count(
"use-internal-malloc");
2197 srv_use_native_aio= not vm.count(
"disable-native-aio");
2198 support_xa= not vm.count(
"disable-xa");
2199 btr_search_enabled= not vm.count(
"disable-adaptive-hash-index");
2202 innobase_data_home_dir= vm.count(
"data-home-dir") ? vm[
"data-home-dir"].as<
string>() : getDataHome().file_string();
2204 if (vm.count(
"data-file-path"))
2206 innobase_data_file_path= vm[
"data-file-path"].as<
string>();
2210 innodb_engine_ptr= actuall_engine_ptr=
new InnobaseEngine(innobase_engine_name);
2212 ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)DRIZZLE_TYPE_VARCHAR);
2215 static const char test_filename[] =
"-@";
2216 const size_t test_tablename_size=
sizeof test_filename
2218 boost::scoped_array test_tablename(
new char[test_tablename_size]);
2219 if ((test_tablename_size) - 1
2220 != filename_to_tablename(test_filename, test_tablename.get(),
2221 test_tablename_size)
2222 || strncmp(test_tablename.get(),
2225 || strcmp(test_tablename.get()
2228 errmsg_printf(error::ERROR,
"tablename encoding has been changed");
2234 srv_page_size_shift = 0;
2236 uint32_t page_size = innobase_page_size.get();
2237 uint32_t log_block_size = innobase_log_block_size.get();
2239 if (innobase_page_size != (1 << 14)) {
2242 errmsg_printf(error::WARN,
2243 "InnoDB: Warning: innodb_page_size has been changed from default value 16384. (###EXPERIMENTAL### operation)\n");
2244 for (n_shift = 12; n_shift <= UNIV_PAGE_SIZE_SHIFT_MAX; n_shift++) {
2245 if (innobase_page_size == (1UL << n_shift)) {
2246 srv_page_size_shift = n_shift;
2247 srv_page_size = (1 << srv_page_size_shift);
2248 errmsg_printf(error::WARN,
2249 "InnoDB: The universal page size of the database is set to %lu.\n",
2255 srv_page_size_shift = 14;
2256 srv_page_size = (1 << srv_page_size_shift);
2259 if (!srv_page_size_shift) {
2260 errmsg_printf(error::ERROR,
2261 "InnoDB: Error: %"PRIu32
" is not a valid value for innodb_page_size.\n"
2262 "InnoDB: Error: Valid values are 4096, 8192, and 16384 (default=16384).\n",
2267 srv_log_block_size = 0;
2268 if (log_block_size != (1 << 9)) {
2271 errmsg_printf(error::WARN,
2272 "InnoDB: Warning: innodb_log_block_size has been changed from default value 512. (###EXPERIMENTAL### operation)\n");
2273 for (n_shift = 9; n_shift <= UNIV_PAGE_SIZE_SHIFT_MAX; n_shift++) {
2274 if (log_block_size == (1UL << n_shift)) {
2275 srv_log_block_size = (1 << n_shift);
2276 errmsg_printf(error::WARN,
"InnoDB: The log block size is set to %"PRIu32
".\n",
2277 srv_log_block_size);
2282 srv_log_block_size = 512;
2285 if (!srv_log_block_size) {
2286 errmsg_printf(error::ERROR,
2287 "InnoDB: Error: %"PRIu32
" is not a valid value for innodb_log_block_size.\n"
2288 "InnoDB: Error: A valid value for innodb_log_block_size is\n"
2289 "InnoDB: Error: a power of 2 from 512 to 16384.\n",
2304 srv_data_home = (
char *)innobase_data_home_dir.c_str();
2310 if (innobase_data_file_path.empty())
2312 innobase_data_file_path= std::string(
"ibdata1:10M:autoextend");
2318 internal_innobase_data_file_path = strdup(innobase_data_file_path.c_str());
2321 internal_innobase_data_file_path);
2323 errmsg_printf(error::ERROR,
"InnoDB: syntax error in innodb_data_file_path");
2327 free(internal_innobase_data_file_path);
2335 if (vm.count(
"log-group-home-dir"))
2337 innobase_log_group_home_dir= vm[
"log-group-home-dir"].as<
string>();
2341 innobase_log_group_home_dir= getDataHome().file_string();
2347 if (ret == FALSE || innobase_mirrored_log_groups.get() != 1) {
2348 errmsg_printf(error::ERROR, _(
"syntax error in innodb_log_group_home_dir, or a "
2349 "wrong number of mirrored log groups"));
2351 goto mem_free_and_error;
2356 if (vm.count(
"file-format"))
2359 vm[
"file-format"].as<string>().c_str());
2363 errmsg_printf(error::ERROR,
"InnoDB: wrong innodb_file_format.");
2365 goto mem_free_and_error;
2374 innobase_file_format_name =
2378 if (!innobase_file_format_check)
2392 errmsg_printf(error::ERROR, _(
"InnoDB: invalid innodb_file_format_max value: "
2393 "should be any value up to %s or its equivalent numeric id"),
2395 goto mem_free_and_error;
2398 if (vm.count(
"change-buffering"))
2406 innobase_change_buffering.c_str(),
2409 goto innobase_change_buffering_inited_ok;
2413 errmsg_printf(error::ERROR,
"InnoDB: invalid value innodb_change_buffering=%s",
2414 vm[
"change-buffering"].as<string>().c_str());
2415 goto mem_free_and_error;
2418 innobase_change_buffering_inited_ok:
2424 if (vm.count(
"flush-method") != 0)
2426 srv_file_flush_method_str = (
char *)vm[
"flush-method"].as<string>().c_str();
2429 srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
2430 srv_n_log_files = (ulint) innobase_log_files_in_group;
2431 srv_log_file_size = (ulint) innobase_log_file_size;
2433 srv_log_buffer_size = (ulint) innobase_log_buffer_size;
2438 srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
2440 srv_n_read_io_threads = (ulint) innobase_read_io_threads;
2441 srv_n_write_io_threads = (ulint) innobase_write_io_threads;
2443 srv_read_ahead &= 3;
2444 srv_adaptive_flushing_method %= 3;
2446 srv_force_recovery = (ulint) innobase_force_recovery;
2448 srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
2449 srv_use_checksums = (ibool) innobase_use_checksums;
2451 #ifdef HAVE_LARGE_PAGES
2452 if ((os_use_large_pages = (ibool) my_use_large_pages))
2453 os_large_page_size = (ulint) opt_large_page_size;
2460 srv_max_n_open_files = (ulint) innobase_open_files;
2461 srv_innodb_status = (ibool) innobase_create_status_file;
2463 srv_print_verbose_log =
true;
2468 data_mysql_default_charset_coll = (ulint)default_charset_info->number;
2478 if (err != DB_SUCCESS)
2480 goto mem_free_and_error;
2483 err = dict_create_sys_replication_log();
2485 if (err != DB_SUCCESS) {
2486 goto mem_free_and_error;
2490 innobase_old_blocks_pct = buf_LRU_old_ratio_update(innobase_old_blocks_pct.get(),
2493 innobase_open_tables = hash_create(200);
2496 actuall_engine_ptr->dropTemporarySchema();
2499 context.add(innodb_engine_ptr);
2500 context.add(
new CmpTool(
false));
2501 context.add(
new CmpTool(
true));
2517 if (innobase_use_replication_log)
2520 context.add(replication_logger);
2521 ReplicationLog::setup(replication_logger, sysvar_transaction_log_use_replicator);
2526 vm.count(
"flush-method") ? vm[
"flush-method"].as<
string>() :
""));
2537 context.registerVariable(
new sys_var_bool_ptr(
"adaptive-flushing", &srv_adaptive_flushing));
2538 context.registerVariable(
new sys_var_bool_ptr(
"status-file", &innobase_create_status_file));
2543 context.registerVariable(
new sys_var_bool_ptr(
"strict_mode", &strict_mode));
2548 innodb_auto_extend_increment,
2549 auto_extend_update));
2552 io_capacity_update));
2554 innodb_purge_batch_size,
2555 purge_batch_update));
2557 innodb_n_purge_threads,
2558 purge_threads_update));
2561 innobase_file_format_name,
2564 innobase_change_buffering,
2567 innobase_file_format_max,
2574 innodb_flush_log_at_trx_commit));
2576 innodb_max_dirty_pages_pct));
2579 context.registerVariable(
new sys_var_bool_ptr(
"adaptive_hash_index", &btr_search_enabled, innodb_adaptive_hash_index_update));
2582 innobase_commit_concurrency,
2583 innodb_commit_concurrency_validate));
2585 innodb_concurrency_tickets));
2595 innobase_old_blocks_pct,
2596 innodb_old_blocks_pct_update));
2597 context.registerVariable(
new sys_var_uint32_t_ptr(
"old_blocks_time", &buf_LRU_old_threshold_ms));
2602 innobase_thread_concurrency,
2603 innodb_thread_concurrency_update));
2605 innodb_read_ahead_threshold,
2606 innodb_read_ahead_threshold_update));
2608 buffer_pool_restore_at_startup,
2609 auto_lru_dump_update));
2613 ibuf_active_contract,
2614 ibuf_active_contract_update));
2617 ibuf_accel_rate_update));
2619 checkpoint_age_target,
2620 checkpoint_age_target_update));
2622 flush_neighbor_pages,
2623 flush_neighbor_pages_update));
2628 adaptive_flushing_method,
2632 btr_search_fully_disabled = (!btr_search_enabled);
2635 sysvar_transaction_log_use_replicator));
2654 assert(
this == innodb_engine_ptr);
2688 start_transaction_option_t options)
2690 assert(
this == innodb_engine_ptr);
2704 if (options == START_TRANS_OPT_WITH_CONS_SNAPSHOT)
2724 assert(
this == innodb_engine_ptr);
2731 if (trx->has_search_latch) {
2743 const uint32_t commit_concurrency= innobase_commit_concurrency.get();
2744 if (commit_concurrency)
2748 boost::mutex::scoped_lock scopedLock(commit_cond_m);
2755 commit_cond.wait(scopedLock);
2759 trx->mysql_log_file_name = NULL;
2760 trx->mysql_log_offset = 0;
2765 trx->flush_log_later = TRUE;
2767 trx->flush_log_later = FALSE;
2769 if (commit_concurrency)
2771 boost::mutex::scoped_lock scopedLock(commit_cond_m);
2773 commit_cond.notify_one();
2794 if (! session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
2798 commit(session, TRUE);
2805 if (trx->declared_to_be_inside_innodb) {
2815 if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
2816 trx->global_read_view)
2840 assert(
this == innodb_engine_ptr);
2865 if (trx->isolation_level <= TRX_ISO_READ_COMMITTED &&
2866 trx->global_read_view)
2915 ib_int64_t mysql_binlog_cache_pos;
2919 assert(
this == innodb_engine_ptr);
2930 &mysql_binlog_cache_pos);
2948 assert(
this == innodb_engine_ptr);
2969 assert(
this == innodb_engine_ptr);
3004 assert(
this == innodb_engine_ptr);
3009 assert(session->getKilled() != Session::NOT_KILLED ||
3013 if (session->getKilled() != Session::NOT_KILLED &&
3016 global_system_variables.log_warnings)
3018 errmsg_printf(error::WARN,
3019 "Drizzle is closing a connection during a KILL operation\n"
3020 "that has an active InnoDB transaction. %llu row modifications will "
3084 return(&key_map_full);
3107 uint64_t max_value = 0;
3109 switch(field->key_type()) {
3111 case HA_KEYTYPE_BINARY:
3112 max_value = 0xFFULL;
3115 case HA_KEYTYPE_ULONG_INT:
3116 max_value = 0xFFFFFFFFULL;
3118 case HA_KEYTYPE_LONG_INT:
3119 max_value = 0x7FFFFFFFULL;
3122 case HA_KEYTYPE_ULONGLONG:
3123 max_value = 0xFFFFFFFFFFFFFFFFULL;
3125 case HA_KEYTYPE_LONGLONG:
3126 max_value = 0x7FFFFFFFFFFFFFFFULL;
3128 case HA_KEYTYPE_DOUBLE:
3130 max_value = 0x20000000000000ULL;
3162 key_part = key_info->key_part;
3163 key_end = key_part + key_info->key_parts;
3164 innodb_idx_fld = index_info->
fields;
3173 for (; key_part != key_end; ++key_part) {
3176 ulint mtype = innodb_idx_fld->
col->
mtype;
3184 while (mtype == DATA_SYS) {
3187 if (innodb_idx_fld >= innodb_idx_fld_end) {
3192 if (col_type != mtype) {
3226 ulint mysql_num_index;
3231 mutex_enter(&dict_sys->
mutex);
3233 mysql_num_index = table->getShare()->keys;
3242 if (UNIV_UNLIKELY(ib_num_index < mysql_num_index)) {
3257 index_mapping = (
dict_index_t**) realloc(index_mapping,
3259 sizeof(*index_mapping));
3261 if (!index_mapping) {
3264 errmsg_printf(error::ERROR,
"InnoDB: fail to allocate memory for "
3265 "index translation table. Number of Index:%lu, array size:%lu",
3278 for (ulint count = 0; count < mysql_num_index; count++) {
3282 index_mapping[count] = dict_table_get_index_on_name(
3283 ib_table, table->
key_info[count].name);
3285 if (!index_mapping[count]) {
3286 errmsg_printf(error::ERROR,
"Cannot find index %s in InnoDB index dictionary.",
3295 errmsg_printf(error::ERROR,
"Found index %s whose column info does not match that of MySQL.",
3308 free(index_mapping);
3312 index_mapping = NULL;
3317 mutex_exit(&dict_sys->
mutex);
3359 if (field != NULL) {
3368 errmsg_printf(error::ERROR,
"InnoDB: Unable to determine the AUTOINC column name");
3383 }
else if (field == NULL) {
3386 my_error(ER_AUTOINC_READ_FAILED, MYF(0));
3389 const char* col_name;
3390 uint64_t read_auto_inc;
3405 uint64_t col_max_value;
3416 case DB_RECORD_NOT_FOUND:
3418 errmsg_printf(error::ERROR,
"InnoDB: MySQL and InnoDB data dictionaries are out of sync.\n"
3419 "InnoDB: Unable to find the AUTOINC column %s in the InnoDB table %s.\n"
3420 "InnoDB: We set the next AUTOINC column value to 0,\n"
3421 "InnoDB: in effect disabling the AUTOINC next value generation.\n"
3422 "InnoDB: You can either set the next AUTOINC value explicitly using ALTER TABLE\n"
3423 "InnoDB: or fix the data dictionary by recreating the table.\n",
3452 uint test_if_locked)
3460 session= getTable()->
in_use;
3465 if (session != NULL) {
3471 std::string search_string(identifier.getSchemaName());
3472 boost::algorithm::to_lower(search_string);
3474 if (search_string.compare(
"data_dictionary") == 0)
3476 std::string table_name(identifier.getTableName());
3477 boost::algorithm::to_upper(table_name);
3496 upd_and_key_val_buff_len =
3497 getTable()->getShare()->sizeStoredRecord()
3498 + getTable()->getShare()->max_key_length
3499 + MAX_REF_PARTS * 3;
3501 upd_buff.resize(upd_and_key_val_buff_len);
3503 if (
upd_buff.size() < upd_and_key_val_buff_len)
3515 if (search_string.compare(
"data_dictionary") == 0)
3517 std::string table_name(identifier.getTableName());
3518 boost::algorithm::to_upper(table_name);
3519 ib_table = dict_table_get(table_name.c_str(), TRUE);
3523 ib_table = dict_table_get(identifier.getKeyPath().c_str(), TRUE);
3526 if (NULL == ib_table) {
3527 errmsg_printf(error::ERROR,
"Cannot find or open table %s from\n"
3528 "the internal data dictionary of InnoDB "
3529 "though the .frm file for the\n"
3530 "table exists. Maybe you have deleted and "
3531 "recreated InnoDB data\n"
3532 "files but have forgotten to delete the "
3533 "corresponding .frm files\n"
3534 "of InnoDB tables, or you have moved .frm "
3535 "files to another database?\n"
3536 "or, the table contains indexes that this "
3537 "version of the engine\n"
3538 "doesn't support.\n"
3539 "See " REFMAN
"innodb-troubleshooting.html\n"
3540 "how you can resolve the problem.\n",
3541 identifier.getKeyPath().c_str());
3547 return(HA_ERR_NO_SUCH_TABLE);
3550 if (ib_table->
ibd_file_missing && ! session->doing_tablespace_operation()) {
3551 errmsg_printf(error::ERROR,
"MySQL is trying to open a table handle but "
3552 "the .ibd file for\ntable %s does not exist.\n"
3553 "Have you deleted the .ibd file from the "
3554 "database directory under\nthe MySQL datadir, "
3555 "or have you used DISCARD TABLESPACE?\n"
3556 "See " REFMAN
"innodb-troubleshooting.html\n"
3557 "how you can resolve the problem.\n",
3558 identifier.getKeyPath().c_str());
3564 dict_table_decrement_handle_count(ib_table, FALSE);
3565 return(HA_ERR_NO_SUCH_TABLE);
3576 primary_key = getTable()->getShare()->getPrimaryKey();
3577 key_used_on_scan = primary_key;
3580 errmsg_printf(error::ERROR,
"Build InnoDB index translation table for"
3581 " Table %s failed", identifier.getKeyPath().c_str());
3594 if (UNIV_UNLIKELY(primary_key >= MAX_KEY)) {
3595 errmsg_printf(error::ERROR,
"Table %s has a primary key in "
3596 "InnoDB data dictionary, but not "
3597 "in MySQL!", identifier.getTableName().c_str());
3603 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3605 "InnoDB: Table %s has a "
3606 "primary key in InnoDB data "
3607 "dictionary, but not in "
3608 "MySQL!", identifier.getTableName().c_str());
3630 for (ulint i = 0; i < getTable()->getShare()->keys; i++) {
3635 getTable()->
key_info[i].key_length;
3649 if (primary_key != MAX_KEY) {
3650 errmsg_printf(error::ERROR,
3651 "Table %s has no primary key in InnoDB data "
3652 "dictionary, but has one in MySQL! If you "
3653 "created the table with a MySQL version < "
3654 "3.23.54 and did not define a primary key, "
3655 "but defined a unique key with all non-NULL "
3656 "columns, then MySQL internally treats that "
3657 "key as the primary key. You can fix this "
3658 "error by dump + DROP + CREATE + reimport "
3659 "of the table.", identifier.getTableName().c_str());
3665 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3667 "InnoDB: Table %s has no "
3668 "primary key in InnoDB data "
3669 "dictionary, but has one in "
3670 "MySQL!", identifier.getTableName().c_str());
3685 if (key_used_on_scan != MAX_KEY) {
3686 errmsg_printf(error::WARN,
3687 "Table %s key_used_on_scan is %lu even "
3688 "though there is no primary key inside "
3689 "InnoDB.", identifier.getTableName().c_str(), (ulong) key_used_on_scan);
3694 stats.block_size = 16 * 1024;
3703 char changed_file_format_max[100];
3704 strcpy(changed_file_format_max, innobase_file_format_max.c_str());
3707 innobase_file_format_max= changed_file_format_max;
3711 if (
prebuilt->
table != NULL && getTable()->found_next_number_field != NULL) {
3727 info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
3734 InnobaseEngine::max_supported_key_part_length()
const
3749 session= getTable()->
in_use;
3750 if (session != NULL) {
3780 return((uint) (field->
ptr - table->getInsertRecord()));
3802 null_offset = (uint) ((
char*) field->
null_ptr
3803 - (
char*) table->getInsertRecord());
3805 if (record[null_offset] & field->
null_bit) {
3826 null_offset = (uint) ((
char*) field->
null_ptr
3827 - (
char*) table->getInsertRecord());
3829 record[null_offset] = record[null_offset] | field->
null_bit;
3842 uint charset_number,
3843 const unsigned char* a,
3844 unsigned int a_length,
3846 const unsigned char* b,
3847 unsigned int b_length);
3855 uint charset_number,
3856 const unsigned char* a,
3857 unsigned int a_length,
3858 const unsigned char* b,
3859 unsigned int b_length)
3862 enum_field_types mysql_tp;
3865 assert(a_length != UNIV_SQL_NULL);
3866 assert(b_length != UNIV_SQL_NULL);
3868 mysql_tp = (enum_field_types) mysql_type;
3872 case DRIZZLE_TYPE_BLOB:
3873 case DRIZZLE_TYPE_VARCHAR:
3879 if (charset_number == default_charset_info->number) {
3880 charset = default_charset_info;
3882 charset = get_charset(charset_number);
3884 if (charset == NULL) {
3885 errmsg_printf(error::ERROR,
"InnoDB needs charset %lu for doing "
3886 "a comparison, but MySQL cannot "
3887 "find that charset.",
3888 (ulong) charset_number);
3898 ret = charset->coll->strnncollsp(charset,
3903 }
else if (ret > 0) {
3924 ulint* unsigned_flag,
3931 const class Field* field =
reinterpret_cast<const class
Field*
>(f);
3937 assert((ulint)DRIZZLE_TYPE_DOUBLE < 256);
3939 if (field->flags & UNSIGNED_FLAG) {
3941 *unsigned_flag = DATA_UNSIGNED;
3946 if (field->real_type() == DRIZZLE_TYPE_ENUM)
3952 *unsigned_flag = DATA_UNSIGNED;
3959 switch (field->type()) {
3962 case DRIZZLE_TYPE_VARCHAR:
3963 if (field->binary()) {
3964 return(DATA_BINARY);
3966 return(DATA_VARMYSQL);
3968 case DRIZZLE_TYPE_DECIMAL:
3969 case DRIZZLE_TYPE_MICROTIME:
3970 return(DATA_FIXBINARY);
3971 case DRIZZLE_TYPE_LONG:
3972 case DRIZZLE_TYPE_LONGLONG:
3973 case DRIZZLE_TYPE_DATETIME:
3974 case DRIZZLE_TYPE_TIME:
3975 case DRIZZLE_TYPE_DATE:
3976 case DRIZZLE_TYPE_TIMESTAMP:
3977 case DRIZZLE_TYPE_ENUM:
3979 case DRIZZLE_TYPE_DOUBLE:
3980 return(DATA_DOUBLE);
3981 case DRIZZLE_TYPE_BLOB:
3983 case DRIZZLE_TYPE_BOOLEAN:
3984 case DRIZZLE_TYPE_UUID:
3985 return(DATA_FIXBINARY);
3986 case DRIZZLE_TYPE_IPV6:
3987 return(DATA_FIXBINARY);
3988 case DRIZZLE_TYPE_NULL:
4005 ut_a(val < 256 * 256);
4007 buf[0] = (byte)(val & 0xFF);
4008 buf[1] = (byte)(val / 256);
4019 const unsigned char* buf)
4021 return (uint) ((ulint)(buf[0]) + 256 * ((ulint)(buf[1])));
4035 const unsigned char* record)
4039 KeyPartInfo* end = key_part + key_info->key_parts;
4040 char* buff_start = buff;
4041 enum_field_types mysql_type;
4070 bzero(buff, buff_len);
4072 for (; key_part != end; key_part++) {
4075 if (key_part->null_bit) {
4076 if (record[key_part->null_offset]
4077 & key_part->null_bit) {
4086 field = key_part->field;
4087 mysql_type = field->type();
4089 if (mysql_type == DRIZZLE_TYPE_VARCHAR) {
4099 key_len = key_part->length;
4102 buff += key_len + 2;
4106 cs = field->charset();
4121 if (len > 0 && cs->mbmaxlen > 1) {
4122 true_len = (ulint) cs->cset->well_formed_len(*cs,
str_ref(data, len), (uint) (key_len / cs->mbmaxlen), &error);
4128 if (true_len > key_len) {
4138 memcpy(buff, data, true_len);
4148 }
else if (mysql_type == DRIZZLE_TYPE_BLOB) {
4155 const byte* blob_data;
4157 ut_a(key_part->key_part_flag & HA_PART_KEY_SEG);
4159 key_len = key_part->length;
4162 buff += key_len + 2;
4167 cs = field->charset();
4174 true_len = blob_len;
4177 == key_part->offset);
4182 if (blob_len > 0 && cs->mbmaxlen > 1) {
4183 true_len = (ulint) cs->cset->well_formed_len(*cs,
str_ref(blob_data, blob_len), (uint) (key_len / cs->mbmaxlen), &error);
4190 if (true_len > key_len) {
4198 (byte*)buff, true_len);
4201 memcpy(buff, blob_data, true_len);
4215 const unsigned char* src_start;
4218 key_len = key_part->length;
4226 src_start = record + key_part->offset;
4234 memcpy(buff, src_start, true_len);
4239 if (true_len < key_len) {
4240 ulint pad_len = key_len - true_len;
4241 ut_a(!(pad_len % cs->mbminlen));
4243 cs->cset->fill(cs, buff, pad_len,
4250 ut_a(buff <= buff_start + buff_len);
4252 return((uint)(buff - buff_start));
4275 ulint n_requested_fields = 0;
4276 ibool fetch_all_in_key = FALSE;
4277 ibool fetch_primary_key_cols = FALSE;
4280 ulint mysql_prefix_len = 0;
4287 templ_type = ROW_MYSQL_WHOLE_ROW;
4290 if (templ_type == ROW_MYSQL_REC_FIELDS) {
4292 == ROW_RETRIEVE_ALL_COLS) {
4305 fetch_all_in_key = TRUE;
4307 templ_type = ROW_MYSQL_WHOLE_ROW;
4310 == ROW_RETRIEVE_PRIMARY_KEY) {
4318 fetch_primary_key_cols = TRUE;
4322 clust_index = dict_table_get_first_index(prebuilt->
table);
4324 if (templ_type == ROW_MYSQL_REC_FIELDS) {
4325 index = prebuilt->
index;
4327 index = clust_index;
4330 if (index == clust_index) {
4338 n_fields = (ulint)table->getShare()->sizeFields();
4352 for (i = 0; i < n_fields; i++)
4356 field = table->getField(i);
4358 if (UNIV_LIKELY(templ_type == ROW_MYSQL_REC_FIELDS)) {
4361 register const ibool index_contains_field =
4362 dict_index_contains_col_or_prefix(index, i);
4371 if (index_contains_field && fetch_all_in_key) {
4377 if (field->isReadSet() || field->isWriteSet())
4381 assert(table->isReadSet(i) == field->isReadSet());
4382 assert(table->isWriteSet(i) == field->isWriteSet());
4384 if (fetch_primary_key_cols
4385 && dict_table_col_in_clustered_key(
4397 n_requested_fields++;
4403 if (index == clust_index) {
4416 - (
char*) table->getInsertRecord());
4427 if (mysql_prefix_len < templ->mysql_col_offset
4435 if (templ->
mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
4444 if (templ->
type == DATA_BLOB) {
4457 for (i = 0; i < n_requested_fields; i++) {
4477 ulint error = DB_SUCCESS;
4481 return(ulong(error));
4497 return(ulong(DB_SUCCESS));
4511 dict_table_autoinc_update_if_greater(
prebuilt->
table, auto_inc);
4514 return(ulong(DB_SUCCESS));
4525 unsigned char* record)
4528 int error_result= 0;
4529 ibool auto_inc_used= FALSE;
4534 errmsg_printf(error::ERROR,
"The transaction object for the table handle is at "
4535 "%p, but for the current thread it is at %p",
4538 fputs(
"InnoDB: Dump of 200 bytes around prebuilt: ", stderr);
4541 "InnoDB: Dump of 200 bytes around ha_data: ",
4550 if ((sql_command == SQLCOM_ALTER_TABLE
4551 || sql_command == SQLCOM_CREATE_INDEX
4552 || sql_command == SQLCOM_DROP_INDEX)
4564 enum lock_mode mode;
4616 if (getTable()->next_number_field && record == getTable()->getInsertRecord()) {
4622 if ((error = update_auto_increment())) {
4628 error_result = ER_AUTOINC_READ_FAILED;
4630 my_error(ER_AUTOINC_READ_FAILED, MYF(0));
4639 error_result = (int) error;
4643 auto_inc_used = TRUE;
4662 if (auto_inc_used) {
4665 uint64_t col_max_value;
4678 getTable()->next_number_field);
4683 case DB_DUPLICATE_KEY:
4690 switch (sql_command) {
4693 & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))) {
4695 goto set_max_autoinc;
4699 case SQLCOM_REPLACE:
4700 case SQLCOM_INSERT_SELECT:
4701 case SQLCOM_REPLACE_SELECT:
4702 goto set_max_autoinc;
4720 if (auto_inc <= col_max_value) {
4731 need, offset, col_max_value);
4736 if (err != DB_SUCCESS) {
4755 return(error_result);
4767 unsigned char* old_row,
4768 unsigned char* new_row,
4771 unsigned char* upd_buff,
4776 unsigned char* original_upd_buff = upd_buff;
4777 enum_field_types field_mysql_type;
4782 const byte* new_mysql_row_col;
4788 ulint n_changed = 0;
4793 n_fields = table->getShare()->sizeFields();
4794 clust_index = dict_table_get_first_index(prebuilt->
table);
4797 buf = (byte*) upd_buff;
4799 for (i = 0; i < n_fields; i++) {
4800 Field *field= table->getField(i);
4807 new_mysql_row_col = n_ptr;
4810 o_len = col_pack_len;
4811 n_len = col_pack_len;
4816 field_mysql_type = field->type();
4831 if (field_mysql_type == DRIZZLE_TYPE_VARCHAR) {
4855 o_len = UNIV_SQL_NULL;
4860 n_len = UNIV_SQL_NULL;
4864 if (o_len != n_len || (o_len != UNIV_SQL_NULL &&
4865 0 != memcmp(o_ptr, n_ptr, o_len))) {
4868 ufield = uvect->
fields + n_changed;
4876 if (n_len != UNIV_SQL_NULL) {
4892 &prebuilt->
table->
cols[i], clust_index);
4900 ut_a(buf <= (byte*)original_upd_buff + buff_len);
4917 const unsigned char* old_row,
4918 unsigned char* new_row)
4936 &
upd_buff[0], (ulint)upd_and_key_val_buff_len,
4944 if (getTable()->found_next_number_field)
4947 uint64_t col_max_value;
4954 getTable()->found_next_number_field);
4956 uint64_t current_autoinc;
4958 if (autoinc_error == DB_SUCCESS
4959 && auto_inc <= col_max_value && auto_inc != 0
4960 && auto_inc >= current_autoinc)
4970 auto_inc, need, offset, col_max_value);
4972 dict_table_autoinc_update_if_greater(
prebuilt->
table, auto_inc);
4992 if (error == DB_SUCCESS
4993 && getTable()->next_number_field
4994 && new_row == getTable()->getInsertRecord()
4996 && (trx->
duplicates & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))
4997 == TRX_DUP_IGNORE) {
5000 uint64_t col_max_value;
5007 getTable()->next_number_field);
5009 if (auto_inc <= col_max_value && auto_inc != 0) {
5018 auto_inc, need, offset, col_max_value);
5037 error = HA_ERR_RECORD_IS_THE_SAME;
5055 const unsigned char* record)
5106 case ROW_READ_WITH_LOCKS:
5109 > TRX_ISO_READ_COMMITTED) {
5113 case ROW_READ_TRY_SEMI_CONSISTENT:
5116 case ROW_READ_DID_SEMI_CONSISTENT:
5148 ||
prebuilt->
trx->isolation_level <= TRX_ISO_READ_COMMITTED)) {
5177 active_index=MAX_KEY;
5188 enum ha_rkey_function find_flag)
5190 switch (find_flag) {
5191 case HA_READ_KEY_EXACT:
5193 return(PAGE_CUR_GE);
5194 case HA_READ_KEY_OR_NEXT:
5195 return(PAGE_CUR_GE);
5196 case HA_READ_KEY_OR_PREV:
5197 return(PAGE_CUR_LE);
5198 case HA_READ_AFTER_KEY:
5200 case HA_READ_BEFORE_KEY:
5202 case HA_READ_PREFIX:
5203 return(PAGE_CUR_GE);
5204 case HA_READ_PREFIX_LAST:
5205 return(PAGE_CUR_LE);
5206 case HA_READ_PREFIX_LAST_OR_PREV:
5207 return(PAGE_CUR_LE);
5221 case HA_READ_MBR_CONTAIN:
5222 case HA_READ_MBR_INTERSECT:
5223 case HA_READ_MBR_WITHIN:
5224 case HA_READ_MBR_DISJOINT:
5225 case HA_READ_MBR_EQUAL:
5226 return(PAGE_CUR_UNSUPP);
5232 my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0),
"this functionality");
5234 return(PAGE_CUR_UNSUPP);
5305 const unsigned char* key_ptr,
5315 enum ha_rkey_function find_flag)
5319 ulint match_mode = 0;
5325 ha_statistic_increment(&system_status_var::ha_read_key_count);
5329 if (UNIV_UNLIKELY(index == NULL)) {
5331 return(HA_ERR_CRASHED);
5335 return(HA_ERR_TABLE_DEF_CHANGED);
5343 ROW_MYSQL_REC_FIELDS);
5353 (ulint)upd_and_key_val_buff_len,
5369 if (find_flag == HA_READ_KEY_EXACT) {
5373 }
else if (find_flag == HA_READ_PREFIX
5374 || find_flag == HA_READ_PREFIX_LAST) {
5379 last_match_mode = (uint) match_mode;
5381 if (mode != PAGE_CUR_UNSUPP) {
5391 ret = DB_UNSUPPORTED;
5397 getTable()->status = 0;
5399 case DB_RECORD_NOT_FOUND:
5400 error = HA_ERR_KEY_NOT_FOUND;
5401 getTable()->status = STATUS_NOT_FOUND;
5403 case DB_END_OF_INDEX:
5404 error = HA_ERR_KEY_NOT_FOUND;
5405 getTable()->status = STATUS_NOT_FOUND;
5411 getTable()->status = STATUS_NOT_FOUND;
5427 const unsigned char* key_ptr,
5432 return(
index_read(buf, key_ptr, key_len, HA_READ_PREFIX_LAST));
5448 ha_statistic_increment(&system_status_var::ha_read_key_count);
5450 if (keynr != MAX_KEY && getTable()->getShare()->sizeKeys() > 0)
5462 errmsg_printf(error::ERROR,
5463 "InnoDB could not find "
5464 "index %s key no %u for "
5465 "table %s through its "
5466 "index translation table",
5467 key ? key->name :
"NULL",
5480 errmsg_printf(error::ERROR,
5481 "Innodb could not find key n:o %u with name %s "
5482 "from dict cache for table %s",
5483 keynr, getTable()->getShare()->getTableMessage()->indexes(keynr).name().c_str(),
5504 active_index = keynr;
5509 errmsg_printf(error::WARN,
"InnoDB: change_active_index(%u) failed",
5519 push_warning_printf(
user_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
5520 HA_ERR_TABLE_DEF_CHANGED,
5521 "InnoDB: insufficient history for index %u",
5558 const unsigned char* key,
5562 enum ha_rkey_function find_flag)
5569 return(
index_read(buf, key, key_len, find_flag));
5594 (byte*)buf, 0,
prebuilt, match_mode, direction);
5601 getTable()->status = 0;
5603 case DB_RECORD_NOT_FOUND:
5604 error = HA_ERR_END_OF_FILE;
5605 getTable()->status = STATUS_NOT_FOUND;
5607 case DB_END_OF_INDEX:
5608 error = HA_ERR_END_OF_FILE;
5609 getTable()->status = STATUS_NOT_FOUND;
5614 getTable()->status = STATUS_NOT_FOUND;
5632 ha_statistic_increment(&system_status_var::ha_read_next_count);
5645 const unsigned char* ,
5648 ha_statistic_increment(&system_status_var::ha_read_next_count);
5663 ha_statistic_increment(&system_status_var::ha_read_prev_count);
5680 ha_statistic_increment(&system_status_var::ha_read_first_count);
5682 error =
index_read(buf, NULL, 0, HA_READ_AFTER_KEY);
5686 if (error == HA_ERR_KEY_NOT_FOUND) {
5687 error = HA_ERR_END_OF_FILE;
5705 ha_statistic_increment(&system_status_var::ha_read_last_count);
5707 error =
index_read(buf, NULL, 0, HA_READ_BEFORE_KEY);
5711 if (error == HA_ERR_KEY_NOT_FOUND) {
5712 error = HA_ERR_END_OF_FILE;
5774 ha_statistic_increment(&system_status_var::ha_read_rnd_next_count);
5779 if (error == HA_ERR_KEY_NOT_FOUND) {
5780 error = HA_ERR_END_OF_FILE;
5805 uint keynr = active_index;
5807 ha_statistic_increment(&system_status_var::ha_read_rnd_count);
5851 const unsigned char* record)
5863 len = DATA_ROW_ID_LEN;
5875 errmsg_printf(error::ERROR,
"Stored ref len is %lu, but table ref len is %lu",
5890 const char* table_name,
5891 const char* path_of_temp_table,
5907 ulint nulls_allowed;
5908 ulint unsigned_type;
5910 ulint long_true_varchar;
5914 n_cols = form->getShare()->sizeFields();
5919 table = dict_mem_table_create(table_name, 0, n_cols, flags);
5921 if (path_of_temp_table) {
5926 for (i = 0; i < n_cols; i++) {
5927 field = form->getField(i);
5933 push_warning_printf(
5935 DRIZZLE_ERROR::WARN_LEVEL_WARN,
5936 ER_CANT_CREATE_TABLE,
5937 "Error creating table '%s' with "
5938 "column '%s'. Please check its "
5939 "column type and try to re-create "
5940 "the table with an appropriate "
5949 nulls_allowed = DATA_NOT_NULL;
5952 if (field->binary()) {
5953 binary_type = DATA_BINARY_TYPE;
5960 if (dtype_is_string_type(col_type)) {
5962 charset_no = (ulint)field->charset()->number;
5964 if (UNIV_UNLIKELY(charset_no >= 256)) {
5967 push_warning_printf(
5969 DRIZZLE_ERROR::WARN_LEVEL_ERROR,
5970 ER_CANT_CREATE_TABLE,
5971 "In InnoDB, charset-collation codes"
5972 " must be below 256."
5973 " Unsupported code %lu.",
5974 (ulong) charset_no);
5975 return(ER_CANT_CREATE_TABLE);
5979 ut_a(field->type() < 256);
5988 long_true_varchar = 0;
5990 if (field->type() == DRIZZLE_TYPE_VARCHAR) {
5994 long_true_varchar = DATA_LONG_TRUE_VARCHAR;
6000 if (dict_col_name_is_reserved(field->
field_name)){
6001 my_error(ER_WRONG_COLUMN_NAME, MYF(0), field->
field_name);
6004 dict_mem_table_free(table);
6011 dict_mem_table_add_col(table, table->
heap,
6015 (ulint)field->type()
6016 | nulls_allowed | unsigned_type
6017 | binary_type | long_true_varchar,
6024 if (error == DB_DUPLICATE_KEY) {
6027 buf,
sizeof buf - 1, table_name, strlen(table_name),
6031 my_error(ER_TABLE_EXISTS_ERROR, MYF(0), buf);
6050 const char* table_name,
6065 ulint* field_lengths;
6069 n_fields = key->key_parts;
6076 if (key_num == form->getShare()->getPrimaryKey()) {
6080 if (key->flags & HA_NOSAME ) {
6087 index = dict_mem_index_create(table_name, key->name, 0,
6088 ind_type, n_fields);
6090 field_lengths = (ulint*) malloc(
sizeof(ulint) * n_fields);
6092 for (i = 0; i < n_fields; i++) {
6093 key_part = key->key_part + i;
6102 for (j = 0; j < form->getShare()->sizeFields(); j++)
6105 field = form->getField(j);
6116 ut_a(j < form->getShare()->sizeFields());
6119 &is_unsigned, key_part->field);
6121 if (DATA_BLOB == col_type
6123 && field->type() != DRIZZLE_TYPE_VARCHAR)
6124 || (field->type() == DRIZZLE_TYPE_VARCHAR
6128 prefix_len = key_part->length;
6130 if (col_type == DATA_INT
6131 || col_type == DATA_FLOAT
6132 || col_type == DATA_DOUBLE
6133 || col_type == DATA_DECIMAL) {
6134 errmsg_printf(error::ERROR,
6135 "MySQL is trying to create a column "
6136 "prefix index field, on an "
6137 "inappropriate data type. Table "
6138 "name %s, column name %s.",
6148 field_lengths[i] = key_part->length;
6150 dict_mem_index_add_field(index,
6151 (
char*) key_part->field->
field_name, prefix_len);
6161 free(field_lengths);
6175 const char* table_name)
6183 index = dict_mem_index_create(table_name,
6184 innobase_index_reserve_name,
6203 create_options_are_valid(
6210 ibool kbs_specified = FALSE;
6214 ut_ad(session != NULL);
6217 if (!(SessionVAR(session, strict_mode))) {
6243 ib_int64_t auto_inc_value;
6248 bool lex_identified_temp_table= (create_proto.type() == message::Table::TEMPORARY);
6252 std::string search_string(identifier.getSchemaName());
6253 boost::algorithm::to_lower(search_string);
6255 if (search_string.compare(
"data_dictionary") == 0)
6257 return HA_WRONG_CREATE_OPTION;
6260 if (form.getShare()->sizeFields() > 1000) {
6264 return(HA_ERR_TO_BIG_ROW);
6279 srv_lower_case_table_names = TRUE;
6285 row_mysql_lock_data_dictionary(trx);
6291 #if 0 // Since we validate the options before this stage, we no longer need to do this.
6293 if (! create_options_are_valid(&session, form, create_proto)) {
6294 error = ER_ILLEGAL_HA_CREATE_OPTION;
6302 size_t num_engine_options= create_proto.engine().options_size();
6303 for (
size_t x= 0; x < num_engine_options; ++x)
6305 if (boost::iequals(create_proto.engine().options(x).name(),
"ROW_FORMAT"))
6307 if (boost::iequals(create_proto.engine().options(x).state(),
"COMPRESSED"))
6311 else if (boost::iequals(create_proto.engine().options(x).state(),
"COMPACT"))
6315 else if (boost::iequals(create_proto.engine().options(x).state(),
"DYNAMIC"))
6319 else if (boost::iequals(create_proto.engine().options(x).state(),
"REDUNDANT"))
6336 iflags= (DICT_TF_ZSSIZE_MAX - 1)
6346 push_warning_printf(
6348 DRIZZLE_ERROR::WARN_LEVEL_WARN,
6349 ER_ILLEGAL_HA_CREATE_OPTION,
6350 "InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table.");
6354 push_warning_printf(
6356 DRIZZLE_ERROR::WARN_LEVEL_WARN,
6357 ER_ILLEGAL_HA_CREATE_OPTION,
6358 "InnoDB: ROW_FORMAT=compressed requires innodb_file_format > Antelope.");
6365 primary_key_no= (form.getShare()->hasPrimaryKey() ?
6366 (int) form.getShare()->getPrimaryKey() :
6372 assert(primary_key_no == -1 || primary_key_no == 0);
6376 if (innobase_index_name_is_reserved(trx, form.
key_info,
6377 form.getShare()->keys)) {
6382 if (lex_identified_temp_table)
6386 lex_identified_temp_table ? identifier.getKeyPath().c_str() : NULL,
6389 session.setXaId(trx->
id);
6397 if (form.getShare()->sizeKeys() == 0 || primary_key_no == -1) {
6408 if (primary_key_no != -1) {
6410 if ((error =
create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
6411 (uint) primary_key_no))) {
6416 for (i = 0; i < form.getShare()->sizeKeys(); i++) {
6417 if (i != (uint) primary_key_no) {
6419 if ((error =
create_index(trx, &form, iflags, identifier.getKeyPath().c_str(),
6426 stmt= session.getQueryStringCopy(stmt_len);
6429 string generated_create_table;
6430 const char *query= stmt;
6432 if (session.getSqlCommand() == SQLCOM_CREATE_TABLE)
6434 message::transformTableDefinitionToSql(create_proto,
6435 generated_create_table,
6436 message::DRIZZLE,
true);
6437 query= generated_create_table.c_str();
6441 query, strlen(query),
6442 identifier.getKeyPath().c_str(),
6443 lex_identified_temp_table);
6446 case DB_PARENT_NO_INDEX:
6447 push_warning_printf(
6448 &session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6449 HA_ERR_CANNOT_ADD_FOREIGN,
6450 "Create table '%s' with foreign key constraint"
6451 " failed. There is no index in the referenced"
6452 " table where the referenced columns appear"
6453 " as the first columns.\n", identifier.getKeyPath().c_str());
6456 case DB_CHILD_NO_INDEX:
6457 push_warning_printf(
6458 &session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
6459 HA_ERR_CANNOT_ADD_FOREIGN,
6460 "Create table '%s' with foreign key constraint"
6461 " failed. There is no index in the referencing"
6462 " table where referencing columns appear"
6463 " as the first columns.\n", identifier.getKeyPath().c_str());
6484 innobase_table = dict_table_get(identifier.getKeyPath().c_str(), FALSE);
6486 assert(innobase_table != 0);
6488 if (innobase_table) {
6492 char changed_file_format_max[100];
6493 strcpy(changed_file_format_max, innobase_file_format_max.c_str());
6496 innobase_file_format_max= changed_file_format_max;
6506 if ((create_proto.options().has_auto_increment_value()
6507 || session.getSqlCommand() == SQLCOM_ALTER_TABLE
6508 || session.getSqlCommand() == SQLCOM_CREATE_INDEX)
6509 && create_proto.options().auto_increment_value() != 0) {
6520 auto_inc_value = create_proto.options().auto_increment_value();
6522 dict_table_autoinc_lock(innobase_table);
6523 dict_table_autoinc_initialize(innobase_table, auto_inc_value);
6524 dict_table_autoinc_unlock(innobase_table);
6534 if (lex_identified_temp_table)
6536 session.getMessageCache().storeTableMessage(identifier, create_proto);
6540 StorageEngine::writeDefinitionFromPath(identifier, create_proto);
6601 if (
user_session->getSqlCommand() != SQLCOM_TRUNCATE) {
6606 return(errno=HA_ERR_WRONG_COMMAND);
6612 if (error == DB_ERROR) {
6641 ut_a(identifier.getPath().length() < 1000);
6643 std::string search_string(identifier.getSchemaName());
6644 boost::algorithm::to_lower(search_string);
6646 if (search_string.compare(
"data_dictionary") == 0)
6648 return HA_ERR_TABLE_READONLY;
6663 srv_lower_case_table_names = TRUE;
6668 session.getSqlCommand()
6671 session.setXaId(trx->
id);
6688 if (error != ENOENT)
6691 if (error == 0 || error == ENOENT)
6693 if (identifier.getType() == message::Table::TEMPORARY)
6695 session.getMessageCache().removeTableMessage(identifier);
6696 ulint sql_command = session.getSqlCommand();
6700 if ((sql_command == SQLCOM_ALTER_TABLE
6701 || sql_command == SQLCOM_CREATE_INDEX
6702 || sql_command == SQLCOM_DROP_INDEX))
6704 string path(identifier.getPath());
6706 path.append(DEFAULT_FILE_EXTENSION);
6708 (void)internal::my_delete(path.c_str(), MYF(0));
6713 string path(identifier.getPath());
6715 path.append(DEFAULT_FILE_EXTENSION);
6717 (void)internal::my_delete(path.c_str(), MYF(0));
6737 string schema_path(identifier.getPath());
6738 Session* session = current_session;
6743 assert(
this == innodb_engine_ptr);
6756 schema_path.append(
"/");
6781 void InnobaseEngine::dropTemporarySchema()
6783 string schema_path(GLOBAL_TEMPORARY_EXT);
6790 trx->check_foreigns =
false;
6791 trx->check_unique_secondary =
false;
6819 ibool lock_and_commit)
6824 srv_lower_case_table_names = TRUE;
6829 if (lock_and_commit) {
6830 row_mysql_lock_data_dictionary(trx);
6835 if (error != DB_SUCCESS) {
6836 FILE* ef = dict_foreign_err_file;
6838 fputs(
"InnoDB: Renaming table ", ef);
6842 fputs(
" failed!\n", ef);
6845 if (lock_and_commit) {
6864 if (to.getType() == message::Table::TEMPORARY && from.getType() == message::Table::TEMPORARY)
6866 session.getMessageCache().renameTableMessage(from, to);
6888 session.setXaId(trx->
id);
6910 if (error == (
int) DB_DUPLICATE_KEY) {
6911 my_error(ER_TABLE_EXISTS_ERROR, to);
6920 plugin::StorageEngine::renameDefinitionFromPath(to, from);
6941 unsigned char* key_val_buff2 = (
unsigned char*) malloc(
6942 getTable()->getShare()->sizeStoredRecord()
6943 + getTable()->getShare()->max_key_length + 100);
6944 ulint buff2_len = getTable()->getShare()->sizeStoredRecord()
6945 + getTable()->getShare()->max_key_length + 100;
6962 active_index = keynr;
6964 key = &getTable()->
key_info[active_index];
6971 if (UNIV_UNLIKELY(!index)) {
6972 n_rows = HA_POS_ERROR;
6977 n_rows = HA_ERR_TABLE_DEF_CHANGED;
6985 dict_index_copy_types(range_start, index, key->key_parts);
6988 dict_index_copy_types(range_end, index, key->key_parts);
6992 (ulint)upd_and_key_val_buff_len,
6994 (byte*) (min_key ? min_key->key :
6995 (
const unsigned char*) 0),
6996 (ulint) (min_key ? min_key->length : 0),
7000 range_end, (byte*) key_val_buff2,
7002 (byte*) (max_key ? max_key->key :
7003 (
const unsigned char*) 0),
7004 (ulint) (max_key ? max_key->length : 0),
7012 if (mode1 != PAGE_CUR_UNSUPP && mode2 != PAGE_CUR_UNSUPP) {
7014 n_rows = btr_estimate_n_rows_in_range(index, range_start,
7019 n_rows = HA_POS_ERROR;
7025 free(key_val_buff2);
7039 return((ha_rows) n_rows);
7053 uint64_t local_data_file_length;
7054 ulint stat_n_leaf_pages;
7063 "calculating upper bound for table rows";
7074 ut_a(stat_n_leaf_pages > 0);
7076 local_data_file_length =
7077 ((uint64_t) stat_n_leaf_pages) * UNIV_PAGE_SIZE;
7085 estimate = 2 * local_data_file_length /
7086 dict_index_calc_min_rec_len(index);
7090 return((ha_rows) estimate);
7124 double time_for_scan;
7126 if (index != getTable()->getShare()->getPrimaryKey()) {
7128 return(Cursor::read_time(index, ranges, rows));
7133 return((
double) rows);
7143 return(time_for_scan);
7146 return(ranges + (
double) rows / (
double) total_rows * time_for_scan);
7180 if (index->
table != ib_table) {
7182 ind = dict_table_get_first_index(index->
table);
7184 while (index != ind) {
7185 ind = dict_table_get_next_index(ind);
7199 if (index->
table != ib_table) {
7201 ind = dict_table_get_first_index(index->
table);
7203 while (index != ind) {
7204 ind = dict_table_get_next_index(ind);
7227 errmsg_printf(error::ERROR,
7228 "Cannot find index %s in InnoDB index "
7229 "translation table.", index->
name);
7235 for (i = 0; i < table->getShare()->keys; i++) {
7236 ind = dict_table_get_index_on_name(
7237 ib_table, table->
key_info[i].name);
7244 errmsg_printf(error::ERROR,
7245 "Cannot find matching index number for index %s "
7246 "in InnoDB index list.", index->
name);
7261 ha_rows rec_per_key;
7284 if (flag & HA_STATUS_TIME) {
7290 dict_update_statistics(ib_table,
7297 fs::path get_status_path(catalog::local_identifier().getPath());
7298 get_status_path /= ib_table->
name;
7299 fs::change_extension(get_status_path,
"dfe");
7305 stats.create_time = (ulong) stat_info.
ctime;
7309 if (flag & HA_STATUS_VARIABLE) {
7311 dict_table_stats_lock(ib_table, RW_S_LATCH);
7332 if (n_rows == 0 && !(flag & HA_STATUS_TIME)) {
7340 if (
user_session->getSqlCommand() == SQLCOM_TRUNCATE) {
7353 stats.records = (ha_rows)n_rows;
7355 stats.data_file_length = ((uint64_t)
7358 stats.index_file_length = ((uint64_t)
7362 dict_table_stats_unlock(ib_table, RW_S_LATCH);
7369 if (flag & HA_STATUS_NO_LOCK) {
7374 }
else if (UNIV_UNLIKELY
7378 stats.delete_length = 0;
7382 avail_space = fsp_get_available_space_in_free_extents(ib_table->
space);
7384 if (avail_space == ULLINT_UNDEFINED) {
7387 session= getTable()->
in_use;
7390 push_warning_printf(
7392 DRIZZLE_ERROR::WARN_LEVEL_WARN,
7394 "InnoDB: Trying to get the free "
7395 "space for table %s but its "
7396 "tablespace has been discarded or "
7397 "the .ibd file is missing. Setting "
7398 "the free space to zero.",
7401 stats.delete_length = 0;
7403 stats.delete_length = avail_space * 1024;
7407 stats.check_time = 0;
7409 if (stats.records == 0) {
7410 stats.mean_rec_length = 0;
7412 stats.mean_rec_length = (ulong) (stats.data_file_length / stats.records);
7416 if (flag & HA_STATUS_CONST) {
7423 if (getTable()->getShare()->keys != num_innodb_index) {
7424 errmsg_printf(error::ERROR,
"Table %s contains %lu "
7425 "indexes inside InnoDB, which "
7426 "is different from the number of "
7427 "indexes %u defined in the MySQL ",
7428 ib_table->
name, num_innodb_index,
7429 getTable()->getShare()->keys);
7432 dict_table_stats_lock(ib_table, RW_S_LATCH);
7434 for (i = 0; i < getTable()->getShare()->sizeKeys(); i++) {
7443 if (index == NULL) {
7444 errmsg_printf(error::ERROR,
"Table %s contains fewer "
7445 "indexes inside InnoDB than "
7446 "are defined in the MySQL "
7447 ".frm file. Have you mixed up "
7448 ".frm files from different "
7449 "installations? See "
7451 "innodb-troubleshooting.html\n",
7456 for (j = 0; j < getTable()->
key_info[i].key_parts; j++) {
7458 if (j + 1 > index->
n_uniq) {
7459 errmsg_printf(error::ERROR,
7460 "Index %s of %s has %lu columns unique inside InnoDB, but MySQL is asking "
7461 "statistics for %lu columns. Have you mixed up .frm files from different "
7463 "See " REFMAN
"innodb-troubleshooting.html\n",
7473 rec_per_key = stats.records;
7475 rec_per_key = (ha_rows)(stats.records /
7484 rec_per_key = rec_per_key / 2;
7486 if (rec_per_key == 0) {
7490 getTable()->
key_info[i].rec_per_key[j]=
7491 rec_per_key >= ~(ulong) 0 ? ~(ulong) 0 :
7492 (ulong) rec_per_key;
7496 dict_table_stats_unlock(ib_table, RW_S_LATCH);
7503 if (flag & HA_STATUS_ERRKEY) {
7512 errkey = (
unsigned int)
7541 info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
7559 ulint n_rows_in_table = ULINT_UNDEFINED;
7561 ulint old_isolation_level;
7563 assert(session == getTable()->in_use);
7576 errmsg_printf(error::ERROR,
"InnoDB: Error:\n"
7577 "InnoDB: MySQL is trying to use a table handle"
7578 " but the .ibd file for\n"
7579 "InnoDB: table %s does not exist.\n"
7580 "InnoDB: Have you deleted the .ibd file"
7581 " from the database directory under\n"
7582 "InnoDB: the MySQL datadir, or have you"
7583 " used DISCARD TABLESPACE?\n"
7584 "InnoDB: Please refer to\n"
7585 "InnoDB: " REFMAN
"innodb-troubleshooting.html\n"
7586 "InnoDB: how you can resolve the problem.\n",
7588 return(HA_ADMIN_CORRUPT);
7593 old_isolation_level =
prebuilt->
trx->isolation_level;
7600 prebuilt->
trx->isolation_level = TRX_ISO_REPEATABLE_READ;
7603 mutex_enter(&kernel_mutex);
7604 srv_fatal_semaphore_wait_threshold += 7200;
7605 mutex_exit(&kernel_mutex);
7609 index = dict_table_get_next_index(index)) {
7611 fputs(
"Validating index ", stderr);
7618 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7620 "InnoDB: The B-tree of"
7621 " index '%-.200s' is corrupted.",
7635 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7636 HA_ERR_TABLE_DEF_CHANGED,
7637 "InnoDB: Insufficient history for"
7653 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7655 "InnoDB: The B-tree of"
7656 " index '%-.200s' is corrupted.",
7666 fprintf(stderr,
"%lu entries in index %s\n", n_rows,
7671 n_rows_in_table = n_rows;
7672 }
else if (n_rows != n_rows_in_table) {
7673 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7675 "InnoDB: Index '%-.200s'"
7676 " contains %lu entries,"
7680 (ulong) n_rows_in_table);
7686 prebuilt->
trx->isolation_level = old_isolation_level;
7691 if (!btr_search_validate()) {
7692 push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
7694 "InnoDB: The adaptive hash index is corrupted.");
7699 mutex_enter(&kernel_mutex);
7700 srv_fatal_semaphore_wait_threshold -= 7200;
7701 mutex_exit(&kernel_mutex);
7705 my_error(ER_QUERY_INTERRUPTED, MYF(0));
7708 return(is_ok ? HA_ADMIN_OK : HA_ADMIN_CORRUPT);
7720 const char* comment)
7722 uint length = (uint) strlen(comment);
7730 if (length > 64000 - 3) {
7731 return((
char*)comment);
7746 mutex_enter(&srv_dict_tmpfile_mutex);
7747 rewind(srv_dict_tmpfile);
7749 fprintf(srv_dict_tmpfile,
"InnoDB free: %llu kB",
7750 fsp_get_available_space_in_free_extents(
7753 dict_print_info_on_foreign_keys(FALSE, srv_dict_tmpfile,
7755 flen = ftell(srv_dict_tmpfile);
7758 }
else if (length + flen + 3 > 64000) {
7759 flen = 64000 - 3 - length;
7765 str = (
char*) malloc(length + flen + 3);
7768 char* pos = str + length;
7770 memcpy(str, comment, length);
7774 rewind(srv_dict_tmpfile);
7775 flen = (uint) fread(pos, 1, flen, srv_dict_tmpfile);
7779 mutex_exit(&srv_dict_tmpfile_mutex);
7783 return(str ? str : (
char*) comment);
7815 mutex_enter(&srv_dict_tmpfile_mutex);
7816 rewind(srv_dict_tmpfile);
7819 dict_print_info_on_foreign_keys(TRUE, srv_dict_tmpfile,
7823 flen = ftell(srv_dict_tmpfile);
7831 str = (
char*) malloc(flen + 1);
7834 rewind(srv_dict_tmpfile);
7835 flen = (uint) fread(str, 1, flen, srv_dict_tmpfile);
7839 mutex_exit(&srv_dict_tmpfile_mutex);
7853 mutex_enter(&(dict_sys->
mutex));
7856 while (foreign != NULL)
7859 char uname[NAME_LEN + 1];
7860 char db_name[NAME_LEN + 1];
7861 const char *tmp_buff;
7864 tmp_buff = foreign->
id;
7866 while (tmp_buff[i] !=
'/')
7875 while (tmp_buff[i] !=
'/')
7877 db_name[i]= tmp_buff[i];
7881 ulen= identifier::Table::filename_to_tablename(db_name, uname,
sizeof(uname));
7886 ulen= identifier::Table::filename_to_tablename(tmp_buff, uname,
sizeof(uname));
7901 tmp_buff=
"CASCADE";
7903 tmp_buff=
"SET NULL";
7905 tmp_buff=
"NO ACTION";
7907 tmp_buff=
"RESTRICT";
7911 tmp_buff=
"CASCADE";
7913 tmp_buff=
"SET NULL";
7915 tmp_buff=
"NO ACTION";
7917 tmp_buff=
"RESTRICT";
7925 tmp_foreign_id, tmp_referenced_db, tmp_referenced_table,
7926 tmp_update_method, tmp_delete_method, tmp_referenced_key_name,
7927 tmp_foreign_fields, tmp_referenced_fields);
7932 mutex_exit(&(dict_sys->
mutex));
7953 "determining if there are foreign key constraints";
7976 if (dict_table_is_referenced_by_foreign_key(
prebuilt->
table)) {
8003 enum ha_extra_function operation)
8010 switch (operation) {
8011 case HA_EXTRA_FLUSH:
8016 case HA_EXTRA_RESET_STATE:
8019 case HA_EXTRA_NO_KEYREAD:
8022 case HA_EXTRA_KEYREAD:
8025 case HA_EXTRA_KEYREAD_PRESERVE_FIELDS:
8035 case HA_EXTRA_IGNORE_DUP_KEY:
8038 case HA_EXTRA_WRITE_CAN_REPLACE:
8041 case HA_EXTRA_WRITE_CANNOT_REPLACE:
8044 case HA_EXTRA_NO_IGNORE_DUP_KEY:
8046 ~(TRX_DUP_IGNORE | TRX_DUP_REPLACE);
8081 enum_tx_isolation iso)
8084 case ISO_REPEATABLE_READ:
return(TRX_ISO_REPEATABLE_READ);
8085 case ISO_READ_COMMITTED:
return(TRX_ISO_READ_COMMITTED);
8086 case ISO_SERIALIZABLE:
return(TRX_ISO_SERIALIZABLE);
8087 case ISO_READ_UNCOMMITTED:
return(TRX_ISO_READ_UNCOMMITTED);
8088 default:
ut_a(0);
return(0);
8113 if (lock_type == F_WRLCK) {
8121 if (lock_type != F_UNLCK) {
8124 if (trx->isolation_level == TRX_ISO_SERIALIZABLE
8126 && session_test_options(session,
8127 OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
8153 trx->mysql_n_tables_locked++;
8163 trx->mysql_n_tables_locked= 0;
8175 plugin::StorageEngine* engine,
8177 stat_print_fn *stat_print)
8180 static const char truncated_msg[] =
"... truncated...\n";
8181 const long MAX_STATUS_SIZE = 1048576;
8182 ulint trx_list_start = ULINT_UNDEFINED;
8183 ulint trx_list_end = ULINT_UNDEFINED;
8185 assert(engine == innodb_engine_ptr);
8194 long flen, usable_len;
8197 mutex_enter(&srv_monitor_file_mutex);
8198 rewind(srv_monitor_file);
8200 &trx_list_start, &trx_list_end);
8201 flen = ftell(srv_monitor_file);
8208 if (flen > MAX_STATUS_SIZE) {
8209 usable_len = MAX_STATUS_SIZE;
8210 srv_truncated_status_writes++;
8218 if (!(str = (
char*) malloc(usable_len + 1))) {
8219 mutex_exit(&srv_monitor_file_mutex);
8223 rewind(srv_monitor_file);
8224 if (flen < MAX_STATUS_SIZE) {
8226 flen = (long) fread(str, 1, flen, srv_monitor_file);
8227 }
else if (trx_list_end < (ulint) flen
8228 && trx_list_start < trx_list_end
8229 && trx_list_start + (flen - trx_list_end)
8230 < MAX_STATUS_SIZE -
sizeof truncated_msg - 1) {
8232 long len = (long) fread(str, 1, trx_list_start, srv_monitor_file);
8233 memcpy(str + len, truncated_msg,
sizeof truncated_msg - 1);
8234 len +=
sizeof truncated_msg - 1;
8235 usable_len = (MAX_STATUS_SIZE - 1) - len;
8236 fseek(srv_monitor_file, flen - usable_len, SEEK_SET);
8237 len += (long) fread(str + len, 1, usable_len, srv_monitor_file);
8241 flen = (long) fread(str, 1, MAX_STATUS_SIZE - 1, srv_monitor_file);
8244 mutex_exit(&srv_monitor_file_mutex);
8246 stat_print(session, innobase_engine_name, strlen(innobase_engine_name),
8247 STRING_WITH_LEN(
""), str, flen);
8261 plugin::StorageEngine* engine,
8264 stat_print_fn* stat_print)
8267 char buf1[IO_SIZE], buf2[IO_SIZE];
8270 ulint block_mutex_oswait_count = 0;
8271 ulint block_lock_oswait_count = 0;
8275 ulint rw_lock_count= 0;
8276 ulint rw_lock_count_spin_loop= 0;
8277 ulint rw_lock_count_spin_rounds= 0;
8278 ulint rw_lock_count_os_wait= 0;
8279 ulint rw_lock_count_os_yield= 0;
8280 uint64_t rw_lock_wait_time= 0;
8282 uint engine_name_len= strlen(innobase_engine_name), buf1len, buf2len;
8283 assert(engine == innodb_engine_ptr);
8295 block_mutex = mutex;
8300 if (mutex->mutex_type != 1) {
8301 if (mutex->count_using > 0) {
8302 buf1len= my_snprintf(buf1,
sizeof(buf1),
8305 buf2len= my_snprintf(buf2,
sizeof(buf2),
8306 "count=%lu, spin_waits=%lu,"
8307 " spin_rounds=%lu, "
8308 "os_waits=%lu, os_yields=%lu,"
8309 " os_wait_times=%lu",
8311 mutex->count_spin_loop,
8312 mutex->count_spin_rounds,
8314 mutex->count_os_yield,
8315 (ulong) (mutex->lspent_time/1000));
8317 if (stat_print(session, innobase_engine_name,
8318 engine_name_len, buf1, buf1len,
8325 rw_lock_count += mutex->count_using;
8326 rw_lock_count_spin_loop += mutex->count_spin_loop;
8327 rw_lock_count_spin_rounds += mutex->count_spin_rounds;
8329 rw_lock_count_os_yield += mutex->count_os_yield;
8330 rw_lock_wait_time += mutex->lspent_time;
8333 buf1len= snprintf(buf1,
sizeof(buf1),
"%s:%lu",
8335 buf2len= snprintf(buf2,
sizeof(buf2),
"os_waits=%lu",
8338 if (stat_print(session, innobase_engine_name,
8339 engine_name_len, buf1, buf1len,
8348 buf1len = snprintf(buf1,
sizeof buf1,
8351 (ulong) block_mutex->
cline);
8352 buf2len = snprintf(buf2,
sizeof buf2,
8354 (ulong) block_mutex_oswait_count);
8356 if (stat_print(session, innobase_engine_name,
8357 strlen(innobase_engine_name), buf1, buf1len,
8366 mutex_enter(&rw_lock_list_mutex);
8380 buf1len = snprintf(buf1,
sizeof buf1,
"%s:%lu",
8382 buf2len = snprintf(buf2,
sizeof buf2,
"os_waits=%lu",
8385 if (stat_print(session, innobase_engine_name,
8386 strlen(innobase_engine_name), buf1, buf1len,
8388 mutex_exit(&rw_lock_list_mutex);
8394 buf1len = snprintf(buf1,
sizeof buf1,
8397 (ulong) block_lock->
cline);
8398 buf2len = snprintf(buf2,
sizeof buf2,
8400 (ulong) block_lock_oswait_count);
8402 if (stat_print(session, innobase_engine_name,
8403 strlen(innobase_engine_name), buf1, buf1len,
8405 mutex_exit(&rw_lock_list_mutex);
8410 mutex_exit(&rw_lock_list_mutex);
8413 buf2len = snprintf(buf2,
sizeof buf2,
8414 "count=%lu, spin_waits=%lu, spin_rounds=%lu, "
8415 "os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
8416 (ulong) rw_lock_count,
8417 (ulong) rw_lock_count_spin_loop,
8418 (ulong) rw_lock_count_spin_rounds,
8419 (ulong) rw_lock_count_os_wait,
8420 (ulong) rw_lock_count_os_yield,
8421 (ulong) (rw_lock_wait_time / 1000));
8423 if (stat_print(session, innobase_engine_name, engine_name_len,
8424 STRING_WITH_LEN(
"rw_lock_mutexes"), buf2, buf2len)) {
8432 bool InnobaseEngine::show_status(
Session* session,
8433 stat_print_fn* stat_print,
8434 enum ha_stat_type stat_type)
8436 assert(
this == innodb_engine_ptr);
8438 switch (stat_type) {
8439 case HA_ENGINE_STATUS:
8441 case HA_ENGINE_MUTEX:
8460 HASH_SEARCH(table_name_hash, innobase_open_tables, fold,
8472 innobase_open_tables, fold, share);
8474 thr_lock_init(&share->
lock);
8495 HASH_SEARCH(table_name_hash, innobase_open_tables, fold,
8500 ut_a(share2 == share);
8507 innobase_open_tables, fold, share);
8538 enum thr_lock_type lock_type)
8550 assert(EQ_CURRENT_SESSION(session));
8551 const uint32_t sql_command = session->getSqlCommand();
8553 if (sql_command == SQLCOM_DROP_TABLE) {
8559 }
else if (lock_type == TL_READ_WITH_SHARED_LOCKS
8560 || lock_type == TL_READ_NO_INSERT
8561 || (lock_type != TL_IGNORE
8562 && sql_command != SQLCOM_SELECT)) {
8582 ulint isolation_level;
8584 isolation_level = trx->isolation_level;
8587 || isolation_level <= TRX_ISO_READ_COMMITTED)
8588 && isolation_level != TRX_ISO_SERIALIZABLE
8589 && (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
8590 && (sql_command == SQLCOM_INSERT_SELECT
8591 || sql_command == SQLCOM_REPLACE_SELECT
8592 || sql_command == SQLCOM_UPDATE
8593 || sql_command == SQLCOM_CREATE_TABLE
8594 || sql_command == SQLCOM_SET_OPTION)) {
8608 }
else if (sql_command == SQLCOM_CHECKSUM) {
8618 }
else if (lock_type != TL_IGNORE) {
8627 if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) {
8635 if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
8636 && lock_type <= TL_WRITE)
8637 && ! session->doing_tablespace_operation()
8638 && sql_command != SQLCOM_TRUNCATE
8639 && sql_command != SQLCOM_CREATE_TABLE) {
8641 lock_type = TL_WRITE_ALLOW_WRITE;
8651 if (lock_type == TL_READ_NO_INSERT) {
8653 lock_type = TL_READ;
8656 lock.type = lock_type;
8708 dict_table_autoinc_lock(innodb_table);
8710 auto_inc = dict_table_autoinc_read(innodb_table);
8712 if (auto_inc == 0) {
8714 errmsg_printf(error::ERROR,
" InnoDB: AUTOINC next value generation is disabled for '%s'\n", innodb_table->
name);
8717 dict_table_autoinc_unlock(innodb_table);
8735 uint64_t nb_desired_values,
8736 uint64_t *first_value,
8737 uint64_t *nb_reserved_values)
8741 uint64_t autoinc = 0;
8748 if (error != DB_SUCCESS) {
8749 *first_value = (~(uint64_t) 0);
8779 if (nb_desired_values == 0) {
8784 set_if_bigger(*first_value, autoinc);
8787 set_if_bigger(*first_value, autoinc);
8789 }
else if (*first_value > col_max_value && trx->
n_autoinc_rows > 0) {
8801 uint64_t next_value;
8803 current = *first_value > col_max_value ? autoinc : *first_value;
8804 need = *nb_reserved_values * increment;
8812 *first_value = (~(
unsigned long long) 0);
8815 dict_table_autoinc_update_if_greater(
8848 if (error != DB_SUCCESS) {
8869 InnobaseEngine::get_error_message(
int,
String *buf)
const
8874 system_charset_info);
8888 const unsigned char* ref1,
8890 const unsigned char* ref2)
8893 enum_field_types mysql_type;
8904 return(memcmp(ref1, ref2, DATA_ROW_ID_LEN));
8910 key_part = getTable()->
key_info[getTable()->getShare()->getPrimaryKey()].key_part;
8912 key_part_end = key_part
8913 + getTable()->
key_info[getTable()->getShare()->getPrimaryKey()].key_parts;
8915 for (; key_part != key_part_end; ++key_part) {
8916 field = key_part->field;
8917 mysql_type = field->type();
8919 if (mysql_type == DRIZZLE_TYPE_BLOB) {
8929 result = ((
Field_blob*)field)->cmp( ref1, len1,
8932 result = field->key_cmp(ref1, ref2);
8940 ref1 += key_part->store_length;
8941 ref2 += key_part->store_length;
8968 charset = get_charset((uint) charset_id);
8971 ut_ad(charset->mbmaxlen);
8975 n_chars = prefix_len / charset->mbmaxlen;
8982 if (charset->mbmaxlen > 1) {
9001 char_length = my_charpos(charset, str,
9002 str + data_len, (
int) n_chars);
9003 if (char_length > data_len) {
9004 char_length = data_len;
9007 if (data_len < prefix_len) {
9008 char_length = data_len;
9010 char_length = prefix_len;
9014 return(char_length);
9040 InnobaseEngine::doEndStatement(
9069 assert(
this == innodb_engine_ptr);
9079 session->get_xid(reinterpret_cast<DrizzleXid*>(&trx->
xid));
9088 || (!session_test_options(session, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
9120 uint64_t InnobaseEngine::doGetCurrentTransactionId(
Session *session)
9126 uint64_t InnobaseEngine::doGetNewTransactionId(
Session *session)
9137 mutex_enter(&kernel_mutex);
9139 mutex_exit(&kernel_mutex);
9141 uint64_t transaction_id= trx->
id;
9143 return transaction_id;
9155 assert(
this == innodb_engine_ptr);
9157 if (len == 0 || xid_list == NULL) {
9176 assert(
this == innodb_engine_ptr);
9201 assert(
this == innodb_engine_ptr);
9220 const char* format_name)
9225 ut_a(format_name != NULL);
9229 format_id = (uint) strtoul(format_name, &endp, 10);
9232 if (*endp ==
'\0' && *format_name !=
'\0') {
9264 const char* format_max)
9272 return((
int) format_id);
9282 context(
"disable-checksums",
9283 "Disable InnoDB checksums validation.");
9284 context(
"data-home-dir",
9285 po::value<string>(),
9286 "The common part for InnoDB table spaces.");
9287 context(
"disable-doublewrite",
9288 "Disable InnoDB doublewrite buffer.");
9289 context(
"io-capacity",
9290 po::value<io_capacity_constraint>(&innodb_io_capacity)->default_value(200),
9291 "Number of IOPs the server can do. Tunes the background IO rate");
9292 context(
"fast-shutdown",
9293 po::value<trinary_constraint>(&innobase_fast_shutdown)->default_value(1),
9294 "Speeds up the shutdown process of the InnoDB storage engine. Possible values are 0, 1 (faster) or 2 (fastest - crash-like).");
9295 context(
"purge-batch-size",
9296 po::value<purge_batch_constraint>(&innodb_purge_batch_size)->default_value(20),
9297 "Number of UNDO logs to purge in one batch from the history list. "
9299 context(
"purge-threads",
9300 po::value<purge_threads_constraint>(&innodb_n_purge_threads)->default_value(1),
9301 "Purge threads can be either 0 or 1. Default is 1.");
9302 context(
"file-per-table",
9303 po::value<bool>(&srv_file_per_table)->default_value(
false)->zero_tokens(),
9304 "Stores each InnoDB table to an .ibd file in the database dir.");
9305 context(
"file-format-max",
9306 po::value<string>(&innobase_file_format_max)->default_value(
"Antelope"),
9307 "The highest file format in the tablespace.");
9308 context(
"file-format-check",
9309 po::value<bool>(&innobase_file_format_check)->default_value(
true)->zero_tokens(),
9310 "Whether to perform system file format check.");
9311 context(
"file-format",
9312 po::value<string>(&innobase_file_format_name)->default_value(
"Antelope"),
9313 "File format to use for new tables in .ibd files.");
9314 context(
"flush-log-at-trx-commit",
9315 po::value<trinary_constraint>(&innodb_flush_log_at_trx_commit)->default_value(1),
9316 "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).");
9317 context(
"flush-method",
9318 po::value<string>(),
9319 "With which method to flush data.");
9320 context(
"log-group-home-dir",
9321 po::value<string>(),
9322 "Path to InnoDB log files.");
9323 context(
"max-dirty-pages-pct",
9324 po::value<max_dirty_pages_constraint>(&innodb_max_dirty_pages_pct)->default_value(75),
9325 "Percentage of dirty pages allowed in bufferpool.");
9326 context(
"disable-adaptive-flushing",
9327 "Do not attempt flushing dirty pages to avoid IO bursts at checkpoints.");
9328 context(
"max-purge-lag",
9329 po::value<uint64_constraint>(&innodb_max_purge_lag)->default_value(0),
9330 "Desired maximum length of the purge queue (0 = no limit)");
9331 context(
"status-file",
9332 po::value<bool>(&innobase_create_status_file)->default_value(
false)->zero_tokens(),
9333 "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file");
9334 context(
"disable-stats-on-metadata",
9335 "Disable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)");
9336 context(
"stats-sample-pages",
9337 po::value<uint64_nonzero_constraint>(&innodb_stats_sample_pages)->default_value(8),
9338 "The number of index pages to sample when calculating statistics (default 8)");
9339 context(
"disable-adaptive-hash-index",
9340 "Enable InnoDB adaptive hash index (enabled by default)");
9341 context(
"replication-delay",
9342 po::value<uint64_constraint>(&innodb_replication_delay)->default_value(0),
9343 "Replication thread delay (ms) on the slave server if innodb_thread_concurrency is reached (0 by default)");
9344 context(
"additional-mem-pool-size",
9345 po::value<additional_mem_pool_constraint>(&innobase_additional_mem_pool_size)->default_value(8*1024*1024L),
9346 "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.");
9347 context(
"autoextend-increment",
9348 po::value<autoextend_constraint>(&innodb_auto_extend_increment)->default_value(64L),
9349 "Data file autoextend increment in megabytes");
9350 context(
"buffer-pool-size",
9351 po::value<buffer_pool_constraint>(&innobase_buffer_pool_size)->default_value(128*1024*1024L),
9352 "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.");
9353 context(
"buffer-pool-instances",
9354 po::value<buffer_pool_instances_constraint>(&innobase_buffer_pool_instances)->default_value(1),
9355 "Number of buffer pool instances, set to higher value on high-end machines to increase scalability");
9357 context(
"commit-concurrency",
9358 po::value<concurrency_constraint>(&innobase_commit_concurrency)->default_value(0),
9359 "Helps in performance tuning in heavily concurrent environments.");
9360 context(
"concurrency-tickets",
9361 po::value<uint32_nonzero_constraint>(&innodb_concurrency_tickets)->default_value(500L),
9362 "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket");
9363 context(
"read-io-threads",
9364 po::value<io_threads_constraint>(&innobase_read_io_threads)->default_value(4),
9365 "Number of background read I/O threads in InnoDB.");
9366 context(
"write-io-threads",
9367 po::value<io_threads_constraint>(&innobase_write_io_threads)->default_value(4),
9368 "Number of background write I/O threads in InnoDB.");
9369 context(
"force-recovery",
9370 po::value<force_recovery_constraint>(&innobase_force_recovery)->default_value(0),
9371 "Helps to save your data in case the disk image of the database becomes corrupt.");
9372 context(
"log-buffer-size",
9373 po::value<log_buffer_constraint>(&innobase_log_buffer_size)->default_value(8*1024*1024L),
9374 "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9375 context(
"log-file-size",
9376 po::value<log_file_constraint>(&innobase_log_file_size)->default_value(20*1024*1024L),
9377 "The size of the buffer which InnoDB uses to write log to the log files on disk.");
9378 context(
"page-size",
9379 po::value<page_size_constraint>(&innobase_page_size)->default_value(1 << 14),
9380 "###EXPERIMENTAL###: The universal page size of the database. Changing for created database is not supported. Use on your own risk!");
9381 context(
"log-block-size",
9382 po::value<log_block_size_constraint>(&innobase_log_block_size)->default_value(1 << 9),
9383 "###EXPERIMENTAL###: The log block size of the transaction log file. Changing for created log file is not supported. Use on your own risk!");
9384 context(
"log-files-in-group",
9385 po::value<log_files_in_group_constraint>(&innobase_log_files_in_group)->default_value(2),
9386 "Number of log files in the log group. InnoDB writes to the files in a circular fashion.");
9387 context(
"mirrored-log-groups",
9388 po::value<mirrored_log_groups_constraint>(&innobase_mirrored_log_groups)->default_value(1),
9389 "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.");
9390 context(
"open-files",
9391 po::value<open_files_constraint>(&innobase_open_files)->default_value(300L),
9392 "How many files at the maximum InnoDB keeps open at the same time.");
9393 context(
"sync-spin-loops",
9394 po::value<uint32_constraint>(&innodb_sync_spin_loops)->default_value(30L),
9395 "Count of spin-loop rounds in InnoDB mutexes (30 by default)");
9396 context(
"spin-wait-delay",
9397 po::value<uint32_constraint>(&innodb_spin_wait_delay)->default_value(6L),
9398 "Maximum delay between polling for a spin lock (6 by default)");
9399 context(
"thread-concurrency",
9400 po::value<concurrency_constraint>(&innobase_thread_concurrency)->default_value(0),
9401 "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.");
9402 context(
"thread-sleep-delay",
9403 po::value<uint32_constraint>(&innodb_thread_sleep_delay)->default_value(10000L),
9404 "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep");
9405 context(
"data-file-path",
9406 po::value<string>(),
9407 "Path to individual files and their sizes.");
9409 po::value<string>()->default_value(INNODB_VERSION_STR),
9411 context(
"use-internal-malloc",
9412 "Use InnoDB's internal memory allocator instal of the OS memory allocator.");
9413 context(
"disable-native-aio",
9414 _(
"Do not use Native AIO library for IO, even if available"));
9415 context(
"change-buffering",
9416 po::value<string>(&innobase_change_buffering),
9417 "Buffer changes to reduce random access: OFF, ON, inserting, deleting, changing, or purging.");
9418 context(
"read-ahead-threshold",
9419 po::value<read_ahead_threshold_constraint>(&innodb_read_ahead_threshold)->default_value(56),
9420 "Number of pages that must be accessed sequentially for InnoDB to trigger a readahead.");
9421 context(
"auto-lru-dump",
9422 po::value<uint32_constraint>(&buffer_pool_restore_at_startup)->default_value(0),
9423 "Time in seconds between automatic buffer pool dumps. "
9424 "0 (the default) disables automatic dumps.");
9425 context(
"ibuf-max-size",
9426 po::value<uint64_constraint>(&ibuf_max_size)->default_value(UINT64_MAX),
9427 "The maximum size of the insert buffer (in bytes).");
9428 context(
"ibuf-active-contract",
9429 po::value<binary_constraint>(&ibuf_active_contract)->default_value(1),
9430 "Enable/Disable active_contract of insert buffer. 0:disable 1:enable");
9431 context(
"ibuf-accel-rate",
9432 po::value<ibuf_accel_rate_constraint>(&ibuf_accel_rate)->default_value(100),
9433 "Tunes amount of insert buffer processing of background, in addition to innodb_io_capacity. (in percentage)");
9434 context(
"checkpoint-age-target",
9435 po::value<uint32_constraint>(&checkpoint_age_target)->default_value(0),
9436 "Control soft limit of checkpoint age. (0 : not control)");
9437 context(
"flush-neighbor-pages",
9438 po::value<binary_constraint>(&flush_neighbor_pages)->default_value(1),
9439 "Enable/Disable flushing also neighbor pages. 0:disable 1:enable");
9440 context(
"read-ahead",
9441 po::value<string>(&read_ahead)->default_value(
"linear"),
9442 "Control read ahead activity (none, random, [linear], both). [from 1.0.5: random read ahead is ignored]");
9443 context(
"adaptive-flushing-method",
9444 po::value<string>(&adaptive_flushing_method)->default_value(
"estimate"),
9445 "Choose method of innodb_adaptive_flushing. (native, [estimate], keep_average)");
9446 context(
"disable-xa",
9447 "Disable InnoDB support for the XA two-phase commit");
9448 context(
"disable-table-locks",
9449 "Disable InnoDB locking in LOCK TABLES");
9450 context(
"strict-mode",
9451 po::value<bool>(&strict_mode)->default_value(
false)->zero_tokens(),
9452 "Use strict mode when evaluating create options.");
9453 context(
"replication-log",
9454 po::value<bool>(&innobase_use_replication_log)->default_value(
false)->zero_tokens(),
9455 _(
"Enable internal replication log."));
9456 context(
"use-replicator",
9457 po::value<string>(&sysvar_transaction_log_use_replicator)->default_value(DEFAULT_USE_REPLICATOR),
9458 _(
"Name of the replicator plugin to use (default='default_replicator')"));
9459 context(
"lock-wait-timeout",
9460 po::value<lock_wait_constraint>(&lock_wait_timeout)->default_value(50),
9461 _(
"Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout."));
9462 context(
"old-blocks-pct",
9463 po::value<old_blocks_constraint>(&innobase_old_blocks_pct)->default_value(100 * 3 / 8),
9464 _(
"Percentage of the buffer pool to reserve for 'old' blocks."));
9465 context(
"old-blocks-time",
9466 po::value<uint32_t>(&buf_LRU_old_threshold_ms)->default_value(0),
9467 _(
"ove blocks to the 'new' end of the buffer pool if the first access"
9468 " was at least this many milliseconds ago."
9469 " The timeout is disabled if 0 (the default)."));
9474 DRIZZLE_DECLARE_PLUGIN
9480 "InnoDB storage engine: transactional, row-level locking, foreign keys",
9486 DRIZZLE_DECLARE_PLUGIN_END;
9496 res= Cursor::read_range_first(start_key, end_key, eq_range_arg, sorted);
9505 int res= Cursor::read_range_next();
9517 innobase_index_name_is_reserved(
9529 for (key_num = 0; key_num < num_of_keys; key_num++) {
9530 key = &key_info[key_num];
9533 innobase_index_reserve_name) == 0) {
9536 DRIZZLE_ERROR::WARN_LEVEL_WARN,
9537 ER_WRONG_NAME_FOR_INDEX,
9538 "Cannot Create Index with name "
9539 "'%s'. The name is reserved "
9540 "for the system default primary "
9542 innobase_index_reserve_name);
9544 my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0),
9545 innobase_index_reserve_name);
9554 #ifdef UNIV_COMPILE_TEST_FUNCS
9556 typedef struct innobase_convert_name_test_struct {
9564 const char* expected;
9565 } innobase_convert_name_test_t;
9568 test_innobase_convert_name()
9573 innobase_convert_name_test_t test_input[] = {
9574 {buf,
sizeof(buf),
"abcd", 4, NULL, TRUE,
"\"abcd\""},
9575 {buf, 7,
"abcd", 4, NULL, TRUE,
"\"abcd\""},
9576 {buf, 6,
"abcd", 4, NULL, TRUE,
"\"abcd\""},
9577 {buf, 5,
"abcd", 4, NULL, TRUE,
"\"abc\""},
9578 {buf, 4,
"abcd", 4, NULL, TRUE,
"\"ab\""},
9580 {buf,
sizeof(buf),
"ab@0060cd", 9, NULL, TRUE,
"\"ab`cd\""},
9581 {buf, 9,
"ab@0060cd", 9, NULL, TRUE,
"\"ab`cd\""},
9582 {buf, 8,
"ab@0060cd", 9, NULL, TRUE,
"\"ab`cd\""},
9583 {buf, 7,
"ab@0060cd", 9, NULL, TRUE,
"\"ab`cd\""},
9584 {buf, 6,
"ab@0060cd", 9, NULL, TRUE,
"\"ab`c\""},
9585 {buf, 5,
"ab@0060cd", 9, NULL, TRUE,
"\"ab`\""},
9586 {buf, 4,
"ab@0060cd", 9, NULL, TRUE,
"\"ab\""},
9588 {buf,
sizeof(buf),
"ab\"cd", 5, NULL, TRUE,
9589 "\"#mysql50#ab\"\"cd\""},
9590 {buf, 17,
"ab\"cd", 5, NULL, TRUE,
9591 "\"#mysql50#ab\"\"cd\""},
9592 {buf, 16,
"ab\"cd", 5, NULL, TRUE,
9593 "\"#mysql50#ab\"\"c\""},
9594 {buf, 15,
"ab\"cd", 5, NULL, TRUE,
9595 "\"#mysql50#ab\"\"\""},
9596 {buf, 14,
"ab\"cd", 5, NULL, TRUE,
9598 {buf, 13,
"ab\"cd", 5, NULL, TRUE,
9600 {buf, 12,
"ab\"cd", 5, NULL, TRUE,
9602 {buf, 11,
"ab\"cd", 5, NULL, TRUE,
9604 {buf, 10,
"ab\"cd", 5, NULL, TRUE,
9607 {buf,
sizeof(buf),
"ab/cd", 5, NULL, TRUE,
"\"ab\".\"cd\""},
9608 {buf, 9,
"ab/cd", 5, NULL, TRUE,
"\"ab\".\"cd\""},
9609 {buf, 8,
"ab/cd", 5, NULL, TRUE,
"\"ab\".\"c\""},
9610 {buf, 7,
"ab/cd", 5, NULL, TRUE,
"\"ab\".\"\""},
9611 {buf, 6,
"ab/cd", 5, NULL, TRUE,
"\"ab\"."},
9612 {buf, 5,
"ab/cd", 5, NULL, TRUE,
"\"ab\"."},
9613 {buf, 4,
"ab/cd", 5, NULL, TRUE,
"\"ab\""},
9614 {buf, 3,
"ab/cd", 5, NULL, TRUE,
"\"a\""},
9615 {buf, 2,
"ab/cd", 5, NULL, TRUE,
"\"\""},
9619 {buf, 0,
"ab/cd", 5, NULL, TRUE,
""},
9622 for (i = 0; i <
sizeof(test_input) /
sizeof(test_input[0]); i++) {
9628 fprintf(stderr,
"TESTING %lu, %s, %lu, %s\n",
9629 test_input[i].buflen,
9631 test_input[i].idlen,
9632 test_input[i].expected);
9636 test_input[i].buflen,
9638 test_input[i].idlen,
9639 test_input[i].session,
9640 test_input[i].file_id);
9642 res_len = (size_t) (end - test_input[i].buf);
9644 if (res_len != strlen(test_input[i].expected)) {
9646 fprintf(stderr,
"unexpected len of the result: %u, "
9647 "expected: %u\n", (
unsigned) res_len,
9648 (
unsigned) strlen(test_input[i].expected));
9652 if (memcmp(test_input[i].buf,
9653 test_input[i].expected,
9654 strlen(test_input[i].expected)) != 0
9657 fprintf(stderr,
"unexpected result: %.*s, "
9658 "expected: %s\n", (
int) res_len,
9660 test_input[i].expected);
9665 fprintf(stderr,
"OK: res: %.*s\n\n", (
int) res_len,
9668 fprintf(stderr,
"FAILED\n\n");