+--source include/rpl_end.inc
--- a/sql/log.cc
+++ b/sql/log.cc
-@@ -5079,6 +5079,12 @@
+@@ -5076,6 +5076,12 @@
user_var_event->type,
user_var_event->charset_number,
flags);
supported at all.
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
-@@ -481,6 +481,8 @@
+@@ -479,6 +479,8 @@
my_bool engine_condition_pushdown;
my_bool keep_files_on_create;
goto err;
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
-@@ -6140,6 +6140,10 @@
+@@ -6146,6 +6146,10 @@
uint *idx_end_p;
alter_flags= table->file->alter_table_flags(alter_info->flags);
for (idx_p= index_drop_buffer, idx_end_p= idx_p + index_drop_count;
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
-@@ -2186,6 +2186,13 @@
+@@ -2192,6 +2192,13 @@
GLOBAL_VAR(opt_optimizer_fix),
NO_CMD_LINE, DEFAULT(TRUE));
int (*recover)(handlerton *hton, XID *xid_list, uint len);
--- a/sql/log.cc
+++ b/sql/log.cc
-@@ -49,6 +49,7 @@
-
- #include "sql_plugin.h"
- #include "rpl_handler.h"
-+#include "debug_sync.h"
-
- /* max size of the log message */
- #define MAX_LOG_BUFFER_SIZE 1024
-@@ -71,6 +72,25 @@
+@@ -71,6 +71,25 @@
static int binlog_rollback(handlerton *hton, THD *thd, bool all);
static int binlog_prepare(handlerton *hton, THD *thd, bool all);
/**
purge logs, master and slave sides both, related error code
convertor.
-@@ -167,41 +187,6 @@
+@@ -167,41 +186,6 @@
}
/*
Helper classes to store non-transactional and transactional data
before copying it to the binary log.
*/
-@@ -211,7 +196,8 @@
+@@ -211,7 +195,8 @@
binlog_cache_data(): m_pending(0), before_stmt_pos(MY_OFF_T_UNDEF),
incident(FALSE), changes_to_non_trans_temp_table_flag(FALSE),
saved_max_binlog_cache_size(0), ptr_binlog_cache_use(0),
{ }
~binlog_cache_data()
-@@ -270,6 +256,8 @@
+@@ -270,6 +255,8 @@
variable after truncating the cache.
*/
cache_log.disk_writes= 0;
DBUG_ASSERT(empty());
}
-@@ -411,6 +399,20 @@
+@@ -411,6 +398,20 @@
binlog_cache_data& operator=(const binlog_cache_data& info);
binlog_cache_data(const binlog_cache_data& info);
};
class binlog_cache_mngr {
-@@ -1627,7 +1629,7 @@
+@@ -1624,7 +1625,7 @@
*/
static inline int
binlog_flush_cache(THD *thd, binlog_cache_data* cache_data, Log_event *end_evt,
{
DBUG_ENTER("binlog_flush_cache");
int error= 0;
-@@ -1646,8 +1648,8 @@
+@@ -1643,8 +1644,8 @@
were, we would have to ensure that we're not ending a statement
inside a stored function.
*/
}
cache_data->reset();
-@@ -1666,12 +1668,12 @@
+@@ -1663,12 +1664,12 @@
*/
static inline int
binlog_commit_flush_stmt_cache(THD *thd,
}
/**
-@@ -1684,12 +1686,12 @@
+@@ -1681,12 +1682,12 @@
nonzero if an error pops up when flushing the cache.
*/
static inline int
}
/**
-@@ -1702,12 +1704,12 @@
+@@ -1699,12 +1700,12 @@
nonzero if an error pops up when flushing the cache.
*/
static inline int
}
/**
-@@ -1722,11 +1724,11 @@
+@@ -1719,11 +1720,11 @@
*/
static inline int
binlog_commit_flush_trx_cache(THD *thd, binlog_cache_mngr *cache_mngr,
}
/**
-@@ -1788,7 +1790,7 @@
+@@ -1785,7 +1786,7 @@
do nothing.
just pretend we can do 2pc, so that MySQL won't
switch to 1pc.
*/
return 0;
}
-@@ -1821,7 +1823,7 @@
+@@ -1818,7 +1819,7 @@
if (!cache_mngr->stmt_cache.empty())
{
}
if (cache_mngr->trx_cache.empty())
-@@ -1840,7 +1842,7 @@
+@@ -1837,7 +1838,7 @@
Otherwise, we accumulate the changes.
*/
if (!error && ending_trans(thd, all))
/*
This is part of the stmt rollback.
-@@ -1884,7 +1886,7 @@
+@@ -1881,7 +1882,7 @@
}
else if (!cache_mngr->stmt_cache.empty())
{
}
if (cache_mngr->trx_cache.empty())
-@@ -1932,7 +1934,7 @@
+@@ -1929,7 +1930,7 @@
(trans_has_updated_non_trans_table(thd) &&
ending_single_stmt_trans(thd,all) &&
thd->variables.binlog_format == BINLOG_FORMAT_MIXED)))
/*
Truncate the cache if:
. aborting a single or multi-statement transaction or;
-@@ -2907,6 +2909,7 @@
+@@ -2904,6 +2905,7 @@
MYSQL_BIN_LOG::MYSQL_BIN_LOG(uint *sync_period)
:bytes_written(0), prepared_xids(0), file_id(1), open_count(1),
need_start_event(TRUE),
sync_period_ptr(sync_period),
is_relay_log(0), signal_cnt(0),
description_event_for_exec(0), description_event_for_queue(0)
-@@ -5279,19 +5282,15 @@
+@@ -5325,19 +5327,15 @@
SYNOPSIS
write_cache()
cache Cache to write to the binary log
if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
return ER_ERROR_ON_WRITE;
uint length= my_b_bytes_in_cache(cache), group, carry, hdr_offs;
-@@ -5402,6 +5401,8 @@
+@@ -5448,6 +5446,8 @@
}
/* Write data to the binary log file */
if (my_b_write(&log_file, cache->read_pos, length))
return ER_ERROR_ON_WRITE;
thd->binlog_bytes_written+= length;
-@@ -5410,9 +5411,6 @@
+@@ -5456,9 +5456,6 @@
DBUG_ASSERT(carry == 0);
return 0; // All OK
}
-@@ -5453,8 +5451,6 @@
+@@ -5499,8 +5496,6 @@
if (!is_open())
DBUG_RETURN(error);
Incident incident= INCIDENT_LOST_EVENTS;
Incident_log_event ev(thd, incident, write_error_msg);
if (lock)
-@@ -5496,104 +5492,320 @@
+@@ -5549,112 +5544,332 @@
'cache' needs to be reinitialized after this functions returns.
*/
+bool
+MYSQL_BIN_LOG::write_transaction_to_binlog(THD *thd, binlog_cache_data *cache_data,
+ Log_event *end_ev, bool all)
- {
-- DBUG_ENTER("MYSQL_BIN_LOG::write(THD *, IO_CACHE *, Log_event *)");
++{
+ group_commit_entry entry;
+ bool ret;
+ DBUG_ENTER("MYSQL_BIN_LOG::write_transaction_to_binlog");
+
+bool
+MYSQL_BIN_LOG::write_transaction_to_binlog_events(group_commit_entry *entry)
-+{
+ {
+- DBUG_ENTER("MYSQL_BIN_LOG::write(THD *, IO_CACHE *, Log_event *)");
+ /*
+ To facilitate group commit for the binlog, we first queue up ourselves in
+ the group commit queue. Then the first thread to enter the queue waits for
+ "Error writing transaction to binary log: %d",
+ MYF(ME_NOREFRESH), entry->error);
+ }
-+
+
+ /*
+ Since we return error, this transaction XID will not be committed, so
+ we need to mark it as not needed for recovery (unlog() is not called
+ DBUG_ENTER("MYSQL_BIN_LOG::trx_group_commit_leader");
+ uint xid_count= 0;
+ uint write_count= 0;
-+
-+ /*
-+ Lock the LOCK_log(), and once we get it, collect any additional writes
-+ that queued up while we were waiting.
-+ */
- mysql_mutex_lock(&LOCK_log);
-+ DEBUG_SYNC(leader->thd, "commit_after_get_LOCK_log");
-+ mysql_mutex_lock(&LOCK_group_commit_queue);
-+ group_commit_entry *current= group_commit_queue;
-+ group_commit_queue= NULL;
-+ mysql_mutex_unlock(&LOCK_group_commit_queue);
-+
-+ /* As the queue is in reverse order of entering, reverse it. */
-+ group_commit_entry *queue= NULL;
-+ while (current)
-+ {
-+ group_commit_entry *next= current->next;
-+ current->next= queue;
-+ queue= current;
-+ current= next;
-+ }
-+ DBUG_ASSERT(leader == queue /* the leader should be first in queue */);
-
-+ /* Now we have in queue the list of transactions to be committed in order. */
++ bool check_purge= false;
++ group_commit_entry *current= 0;
DBUG_ASSERT(is_open());
if (likely(is_open())) // Should always be true
{
+- bool check_purge;
+-
++ /*
++ Lock the LOCK_log(), and once we get it, collect any additional writes
++ that queued up while we were waiting.
++ */
+ mysql_mutex_lock(&LOCK_log);
++
++ DEBUG_SYNC(leader->thd, "commit_after_get_LOCK_log");
++ mysql_mutex_lock(&LOCK_group_commit_queue);
++ current= group_commit_queue;
++ group_commit_queue= NULL;
++ mysql_mutex_unlock(&LOCK_group_commit_queue);
++
++ /* As the queue is in reverse order of entering, reverse it. */
++ group_commit_entry *queue= NULL;
++ while (current)
++ {
++ group_commit_entry *next= current->next;
++ current->next= queue;
++ queue= current;
++ current= next;
++ }
++ DBUG_ASSERT(leader == queue /* the leader should be first in queue */);
/*
- We only bother to write to the binary log if there is anything
- to write.
- */
- if (my_b_tell(cache) > 0)
++ Now we have in queue the list of transactions to be committed in order.
++
+ Commit every transaction in the queue.
+
+ Note that we are doing this in a different thread than the one running
- DBUG_PRINT("info", ("crashing before writing xid"));
- DBUG_SUICIDE();
- });
+-
+- if ((write_error= write_cache(thd, cache, false, false)))
+- goto err;
+-
+- if (commit_event && commit_event->write(&log_file))
+- goto err;
+- if (commit_event)
+- thd->binlog_bytes_written+= commit_event->data_written;
+ if (my_b_tell(cache) > 0)
+ {
+ if ((current->error= write_transaction(current)))
+ current->commit_errno= errno;
-
-- if ((write_error= write_cache(thd, cache, false, false)))
-- goto err;
+ write_count++;
+ }
-- if (commit_event && commit_event->write(&log_file))
+- if (incident && write_incident(thd, FALSE))
- goto err;
-- if (commit_event)
-- thd->binlog_bytes_written+= commit_event->data_written;
+ cache_data->commit_bin_log_file_pos= my_b_write_tell(&log_file);
+ if (cache_data->using_xa && cache_data->xa_xid)
+ xid_count++;
+ }
-- if (incident && write_incident(thd, FALSE))
-- goto err;
-
+ if (write_count > 0)
+ {
bool synced= 0;
- mysql_mutex_lock(&LOCK_prep_xids);
- prepared_xids++;
- mysql_mutex_unlock(&LOCK_prep_xids);
+- mysql_mutex_unlock(&LOCK_log);
+ mark_xids_active(xid_count);
}
else
- if (rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED))
+ {
+ if (rotate(false, &check_purge))
- goto err;
+- mysql_mutex_unlock(&LOCK_log);
+- if (check_purge)
+- purge();
+ {
+ for (current= queue; current != NULL; current= current->next)
+ {
+ }
+ }
+ }
- }
-+ DEBUG_SYNC(leader->thd, "commit_before_get_LOCK_commit_ordered");
-+ mysql_mutex_lock(&LOCK_commit_ordered);
-+ /*
-+ We cannot unlock LOCK_log until we have locked LOCK_commit_ordered;
-+ otherwise scheduling could allow the next group commit to run ahead of us,
-+ messing up the order of commit_ordered() calls. But as soon as
-+ LOCK_commit_ordered is obtained, we can let the next group commit start.
-+ */
- mysql_mutex_unlock(&LOCK_log);
-+ DEBUG_SYNC(leader->thd, "commit_after_release_LOCK_log");
-+ ++num_group_commits;
+ }
+- }
- DBUG_RETURN(0);
--
++ DEBUG_SYNC(leader->thd, "commit_before_get_LOCK_commit_ordered");
++ mysql_mutex_lock(&LOCK_commit_ordered);
++ /*
++ We cannot unlock LOCK_log until we have locked LOCK_commit_ordered;
++ otherwise scheduling could allow the next group commit to run ahead of us,
++ messing up the order of commit_ordered() calls. But as soon as
++ LOCK_commit_ordered is obtained, we can let the next group commit start.
++ */
+
-err:
- if (!write_error)
-+ /*
-+ Wakeup each participant waiting for our group commit, first calling the
-+ commit_ordered() methods for any transactions doing 2-phase commit.
-+ */
-+ current= queue;
-+ while (current != NULL)
- {
+- {
- write_error= 1;
- sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
-+ group_commit_entry *next;
++ mysql_mutex_unlock(&LOCK_log);
+
-+ DEBUG_SYNC(leader->thd, "commit_loop_entry_commit_ordered");
-+ ++num_commits;
-+ if (current->cache_data->using_xa && !current->error)
-+ run_commit_ordered(current->thd, current->all);
++ if (xid_count > 0 && check_purge)
++ {
++ purge();
++ }
++
++ DEBUG_SYNC(leader->thd, "commit_after_release_LOCK_log");
++ ++num_group_commits;
+
+ /*
-+ Careful not to access current->next after waking up the other thread! As
-+ it may change immediately after wakeup.
++ Wakeup each participant waiting for our group commit, first calling the
++ commit_ordered() methods for any transactions doing 2-phase commit.
+ */
-+ next= current->next;
-+ if (current != leader) // Don't wake up ourself
-+ current->thd->signal_wakeup_ready();
-+ current= next;
++ current= queue;
++ while (current != NULL)
++ {
++ group_commit_entry *next;
++
++ DEBUG_SYNC(leader->thd, "commit_loop_entry_commit_ordered");
++ ++num_commits;
++ if (current->cache_data->using_xa && !current->error)
++ run_commit_ordered(current->thd, current->all);
++
++ /*
++ Careful not to access current->next after waking up the other thread! As
++ it may change immediately after wakeup.
++ */
++ next= current->next;
++ if (current != leader) // Don't wake up ourself
++ current->thd->signal_wakeup_ready();
++ current= next;
++ }
++ DEBUG_SYNC(leader->thd, "commit_after_group_run_commit_ordered");
++ mysql_mutex_unlock(&LOCK_commit_ordered);
}
- mysql_mutex_unlock(&LOCK_log);
- DBUG_RETURN(1);
-+ DEBUG_SYNC(leader->thd, "commit_after_group_run_commit_ordered");
-+ mysql_mutex_unlock(&LOCK_commit_ordered);
+
+ DBUG_VOID_RETURN;
}
+
+int
+MYSQL_BIN_LOG::write_transaction(group_commit_entry *entry)
+{
+
+ return 0;
+}
-
++
/**
Wait until we get a signal that the relay log has been updated.
-@@ -5999,6 +6211,68 @@
+
+@@ -6059,6 +6274,68 @@
}
/********* transaction coordinator log for 2pc - mmap() based solution *******/
/*
-@@ -6135,6 +6409,7 @@
+@@ -6195,6 +6472,7 @@
mysql_mutex_init(key_LOCK_pool, &LOCK_pool, MY_MUTEX_INIT_FAST);
mysql_cond_init(key_COND_active, &COND_active, 0);
mysql_cond_init(key_COND_pool, &COND_pool, 0);
inited=6;
-@@ -6142,6 +6417,8 @@
+@@ -6202,6 +6480,8 @@
active=pages;
pool=pages+1;
pool_last=pages+npages-1;
return 0;
-@@ -6247,7 +6524,7 @@
+@@ -6307,7 +6587,7 @@
to the position in memory where xid was logged to.
*/
{
int err;
PAGE *p;
-@@ -6386,7 +6663,9 @@
+@@ -6446,7 +6726,9 @@
mysql_mutex_destroy(&LOCK_sync);
mysql_mutex_destroy(&LOCK_active);
mysql_mutex_destroy(&LOCK_pool);
case 5:
data[0]='A'; // garble the first (signature) byte, in case mysql_file_delete fails
case 4:
-@@ -6596,42 +6875,87 @@
+@@ -6656,42 +6938,87 @@
mysql_cond_destroy(&COND_prep_xids);
}
}
int TC_LOG_BINLOG::recover(IO_CACHE *log, Format_description_log_event *fdle)
-@@ -6700,9 +7024,67 @@
+@@ -6760,9 +7087,67 @@
{
return (ulonglong) mysql_bin_log.get_log_file()->pos_in_file;
}
struct st_mysql_storage_engine binlog_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
-@@ -6717,7 +7099,7 @@
+@@ -6777,7 +7162,7 @@
binlog_init, /* Plugin Init */
NULL, /* Plugin Deinit */
0x0100 /* 1.0 */,
void set_write_error(THD *thd, bool is_transactional);
bool check_write_error(THD *thd);
-@@ -507,6 +595,7 @@
+@@ -509,6 +597,7 @@
inline void unlock_index() { mysql_mutex_unlock(&LOCK_index);}
inline IO_CACHE *get_index_file() { return &index_file;}
inline uint32 get_open_count() { return open_count; }
key_thread_handle_manager, key_thread_kill_server, key_thread_main,
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
-@@ -912,6 +912,8 @@
+@@ -1005,6 +1005,8 @@
mysql_mutex_init(key_LOCK_thd_data, &LOCK_thd_data, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_LOCK_temporary_tables, &LOCK_temporary_tables,
MY_MUTEX_INIT_FAST);
/* Variables with default values */
proc_info="login";
-@@ -1516,6 +1518,8 @@
+@@ -1609,6 +1611,8 @@
my_free(db);
db= NULL;
free_root(&transaction.mem_root,MYF(0));
mysql_mutex_destroy(&LOCK_thd_data);
mysql_mutex_destroy(&LOCK_temporary_tables);
#ifndef DBUG_OFF
-@@ -5199,6 +5203,24 @@
+@@ -5292,6 +5296,24 @@
DBUG_RETURN(0);
}
{
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
-@@ -3017,6 +3017,14 @@
+@@ -3078,6 +3078,14 @@
LEX_STRING get_invoker_user() { return invoker_user; }
LEX_STRING get_invoker_host() { return invoker_host; }
bool has_invoker() { return invoker_user.length > 0; }
private:
/** The current internal error handler for this thread, or NULL. */
-@@ -3059,6 +3067,16 @@
+@@ -3120,6 +3128,16 @@
*/
LEX_STRING invoker_user;
LEX_STRING invoker_host;
trx_deregister_from_2pc(trx);
-@@ -10973,6 +11140,7 @@
+@@ -10982,6 +11149,7 @@
srv_active_wake_master_thread();
if (thd_sql_command(thd) != SQLCOM_XA_PREPARE
&& (all
|| !thd_test_options(
-@@ -10999,6 +11167,7 @@
+@@ -11008,6 +11176,7 @@
mysql_mutex_lock(&prepare_commit_mutex);
trx_owns_prepare_commit_mutex_set(trx);
}
--- a/storage/innobase/btr/btr0cur.c
+++ b/storage/innobase/btr/btr0cur.c
-@@ -502,7 +502,7 @@
+@@ -500,7 +500,7 @@
#ifdef UNIV_SEARCH_PERF_STAT
info->n_searches++;
#endif
&& latch_mode <= BTR_MODIFY_LEAF
&& info->last_hash_succ
&& !estimate
-@@ -538,7 +538,7 @@
+@@ -536,7 +536,7 @@
if (has_search_latch) {
/* Release possible search latch to obey latching order */
}
/* Store the position of the tree latch we push to mtr so that we
-@@ -862,7 +862,7 @@
+@@ -847,7 +847,7 @@
if (has_search_latch) {
}
}
-@@ -1992,13 +1992,13 @@
+@@ -1977,13 +1977,13 @@
btr_search_update_hash_on_delete(cursor);
}
}
--- a/storage/innobase/buf/buf0buf.c
+++ b/storage/innobase/buf/buf0buf.c
-@@ -950,6 +950,7 @@
+@@ -960,6 +960,7 @@
block->check_index_page_at_flush = FALSE;
block->index = NULL;
#ifdef UNIV_DEBUG
block->page.in_page_hash = FALSE;
-@@ -1392,7 +1393,11 @@
+@@ -1427,7 +1428,11 @@
ulint p;
#ifdef UNIV_SYNC_DEBUG
#endif /* UNIV_SYNC_DEBUG */
ut_ad(!btr_search_enabled);
-@@ -2107,6 +2112,7 @@
+@@ -2142,6 +2147,7 @@
{
block->check_index_page_at_flush = FALSE;
block->index = NULL;
}
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
-@@ -11824,6 +11824,11 @@
+@@ -11833,6 +11833,11 @@
"Disable with --skip-innodb-adaptive-hash-index.",
NULL, innodb_adaptive_hash_index_update, TRUE);
static MYSQL_SYSVAR_ULONG(replication_delay, srv_replication_delay,
PLUGIN_VAR_RQCMDARG,
"Replication thread delay (ms) on the slave server if "
-@@ -12204,6 +12209,7 @@
+@@ -12213,6 +12218,7 @@
MYSQL_SYSVAR(use_sys_stats_table),
MYSQL_SYSVAR(stats_sample_pages),
MYSQL_SYSVAR(adaptive_hash_index),
# should be done or reviewed by the maintainer!
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
-@@ -11990,7 +11990,8 @@
+@@ -11999,7 +11999,8 @@
i_s_innodb_sys_foreign_cols,
i_s_innodb_sys_stats,
i_s_innodb_table_stats,
+select * from information_schema.XTRADB_ADMIN_COMMAND /*!XTRA_HELLO*/;
--- a/mysql-test/r/mysqld--help-notwin.result
+++ b/mysql-test/r/mysqld--help-notwin.result
-@@ -731,6 +731,10 @@
+@@ -733,6 +733,10 @@
-V, --version Output version information and exit.
--wait-timeout=# The number of seconds the server waits for activity on a
connection before closing it
Variables (--variable-name=value)
abort-slave-event-count 0
-@@ -955,6 +959,7 @@
+@@ -958,6 +962,7 @@
updatable-views-with-limit YES
verbose TRUE
wait-timeout 28800
# should be done or reviewed by the maintainer!
--- a/storage/innobase/buf/buf0buf.c
+++ b/storage/innobase/buf/buf0buf.c
-@@ -4126,6 +4126,36 @@
+@@ -4161,6 +4161,36 @@
mutex_exit(block_mutex);
}
@return TRUE */
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
-@@ -12287,6 +12287,9 @@
+@@ -12296,6 +12296,9 @@
i_s_innodb_sys_stats,
i_s_innodb_table_stats,
i_s_innodb_index_stats,
# should be done or reviewed by the maintainer!
--- a/storage/innobase/buf/buf0buf.c
+++ b/storage/innobase/buf/buf0buf.c
-@@ -1005,10 +1005,12 @@
+@@ -1022,10 +1022,12 @@
buf_block_t* block;
byte* frame;
ulint i;
/* Reserve space for the block descriptors. */
mem_size += ut_2pow_round((mem_size / UNIV_PAGE_SIZE) * (sizeof *block)
+ (UNIV_PAGE_SIZE - 1), UNIV_PAGE_SIZE);
-@@ -1046,6 +1048,10 @@
+@@ -1063,6 +1065,10 @@
chunk->size = size;
}
srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
srv_n_file_io_threads = (ulint) innobase_file_io_threads;
-@@ -11855,6 +11863,16 @@
+@@ -11864,6 +11872,16 @@
"Number of buffer pool instances, set to higher value on high-end machines to increase scalability",
NULL, NULL, 1L, 1L, MAX_BUFFER_POOLS, 1L);
static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
PLUGIN_VAR_RQCMDARG,
"Helps in performance tuning in heavily concurrent environments.",
-@@ -12161,6 +12179,8 @@
+@@ -12170,6 +12188,8 @@
MYSQL_SYSVAR(autoextend_increment),
MYSQL_SYSVAR(buffer_pool_size),
MYSQL_SYSVAR(buffer_pool_instances),
{"have_atomic_builtins",
(char*) &export_vars.innodb_have_atomic_builtins, SHOW_BOOL},
{"log_waits",
-@@ -11765,6 +11767,11 @@
+@@ -11774,6 +11776,11 @@
"Choose method of innodb_adaptive_flushing. (native, [estimate], keep_average)",
NULL, innodb_adaptive_flushing_method_update, 1, &adaptive_flushing_method_typelib);
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(additional_mem_pool_size),
MYSQL_SYSVAR(autoextend_increment),
-@@ -11834,6 +11841,7 @@
+@@ -11843,6 +11850,7 @@
MYSQL_SYSVAR(flush_neighbor_pages),
MYSQL_SYSVAR(read_ahead),
MYSQL_SYSVAR(adaptive_flushing_method),
MYSQL_SYSVAR(change_buffering),
--- a/storage/innobase/ibuf/ibuf0ibuf.c
+++ b/storage/innobase/ibuf/ibuf0ibuf.c
-@@ -566,6 +566,7 @@
+@@ -575,6 +575,7 @@
/* Use old-style record format for the insert buffer. */
table = dict_mem_table_create(IBUF_TABLE_NAME, IBUF_SPACE_ID, 1, 0);
key_info++;
}
if (!unique_key && !primary_key &&
-@@ -5256,6 +5280,10 @@
+@@ -5261,6 +5285,10 @@
List<Create_field> new_create_list;
/* New key definitions are added here */
List<Key> new_key_list;
List_iterator<Alter_drop> drop_it(alter_info->drop_list);
List_iterator<Create_field> def_it(alter_info->create_list);
List_iterator<Alter_column> alter_it(alter_info->alter_list);
-@@ -5268,6 +5296,7 @@
+@@ -5273,6 +5301,7 @@
uint used_fields= create_info->used_fields;
KEY *key_info=table->key_info;
bool rc= TRUE;
DBUG_ENTER("mysql_prepare_alter_table");
-@@ -5457,7 +5486,26 @@
+@@ -5462,7 +5491,26 @@
/*
Collect all keys which isn't in drop list. Add only those
for which some fields exists.
for (uint i=0 ; i < table->s->keys ; i++,key_info++)
{
-@@ -5574,6 +5622,8 @@
+@@ -5579,6 +5627,8 @@
test(key_info->flags & HA_GENERATED_KEY),
key_parts);
new_key_list.push_back(key);
}
}
{
-@@ -5581,7 +5631,21 @@
+@@ -5586,7 +5636,21 @@
while ((key=key_it++)) // Add new keys
{
if (key->type != Key::FOREIGN_KEY)
if (key->name.str &&
!my_strcasecmp(system_charset_info, key->name.str, primary_key_name))
{
-@@ -5630,12 +5694,104 @@
+@@ -5635,12 +5699,104 @@
rc= FALSE;
alter_info->create_list.swap(new_create_list);
alter_info->key_list.swap(new_key_list);
Alter table
SYNOPSIS
-@@ -6428,19 +6584,38 @@
+@@ -6434,19 +6590,38 @@
*/
if (new_table && !(new_table->file->ha_table_flags() & HA_NO_COPY_ON_ALTER))
{
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
-@@ -556,6 +556,7 @@
+@@ -551,6 +551,7 @@
double long_query_time_double;
--expire-logs-days=#
If non-zero, binary logs will be purged after
expire_logs_days days; possible purges happen at startup
-@@ -821,6 +825,7 @@
+@@ -823,6 +827,7 @@
div-precision-increment 4
engine-condition-pushdown TRUE
event-scheduler OFF
--expire-logs-days=#
If non-zero, binary logs will be purged after
expire_logs_days days; possible purges happen at startup
-@@ -775,6 +779,7 @@
+@@ -777,6 +781,7 @@
div-precision-increment 4
engine-condition-pushdown TRUE
event-scheduler OFF
#endif /* !UNIV_HOTBACKUP */
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
-@@ -7423,6 +7423,14 @@
+@@ -7422,6 +7422,14 @@
err = row_discard_tablespace_for_mysql(dict_table->name, trx);
} else {
err = row_import_tablespace_for_mysql(dict_table->name, trx);
}
err = convert_error_code_to_mysql(err, dict_table->flags, NULL);
-@@ -11772,6 +11780,11 @@
+@@ -11781,6 +11789,11 @@
"Choose method of innodb_adaptive_flushing. (native, [estimate], keep_average)",
NULL, innodb_adaptive_flushing_method_update, 1, &adaptive_flushing_method_typelib);
static MYSQL_SYSVAR_ULONG(dict_size_limit, srv_dict_size_limit,
PLUGIN_VAR_RQCMDARG,
"Limit the allocated memory for dictionary cache. (0: unlimited)",
-@@ -11846,6 +11859,7 @@
+@@ -11855,6 +11868,7 @@
MYSQL_SYSVAR(flush_neighbor_pages),
MYSQL_SYSVAR(read_ahead),
MYSQL_SYSVAR(adaptive_flushing_method),
/*
IMPLEMENTATION OF THE BUFFER POOL
-@@ -1834,8 +1868,16 @@
+@@ -1869,8 +1903,16 @@
mutex_t* block_mutex;
ibool must_read;
unsigned access_time;
buf_pool->stat.n_page_gets++;
for (;;) {
-@@ -1853,7 +1895,7 @@
+@@ -1888,7 +1930,7 @@
//buf_pool_mutex_exit(buf_pool);
rw_lock_s_unlock(&buf_pool->page_hash_latch);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
ut_a(++buf_dbg_counter % 37 || buf_validate());
-@@ -1949,6 +1991,13 @@
+@@ -1984,6 +2026,13 @@
/* Let us wait until the read operation
completes */
for (;;) {
enum buf_io_fix io_fix;
-@@ -1963,6 +2012,12 @@
+@@ -1998,6 +2047,12 @@
break;
}
}
}
#ifdef UNIV_IBUF_COUNT_DEBUG
-@@ -2277,6 +2332,11 @@
+@@ -2312,6 +2367,11 @@
ibool must_read;
ulint retries = 0;
mutex_t* block_mutex = NULL;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
ut_ad(mtr);
-@@ -2306,6 +2366,9 @@
+@@ -2341,6 +2401,9 @@
|| ibuf_page_low(space, zip_size, offset,
FALSE, file, line, NULL));
#endif
buf_pool->stat.n_page_gets++;
fold = buf_page_address_fold(space, offset);
loop:
-@@ -2376,9 +2439,9 @@
+@@ -2411,9 +2474,9 @@
return(NULL);
}
retries = 0;
} else if (retries < BUF_PAGE_READ_MAX_RETRIES) {
-@@ -2688,6 +2751,13 @@
+@@ -2723,6 +2786,13 @@
/* Let us wait until the read operation
completes */
for (;;) {
enum buf_io_fix io_fix;
-@@ -2702,6 +2772,12 @@
+@@ -2737,6 +2807,12 @@
break;
}
}
}
fix_type = MTR_MEMO_BUF_FIX;
-@@ -2728,13 +2804,17 @@
+@@ -2763,13 +2839,17 @@
read-ahead */
buf_read_ahead_linear(space, zip_size, offset,
return(block);
}
-@@ -2758,6 +2838,7 @@
+@@ -2793,6 +2873,7 @@
unsigned access_time;
ibool success;
ulint fix_type;
ut_ad(block);
ut_ad(mtr);
-@@ -2835,6 +2916,10 @@
+@@ -2870,6 +2951,10 @@
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(block->page.file_page_was_freed == FALSE);
#endif
if (UNIV_UNLIKELY(!access_time)) {
/* In the case of a first access, try to apply linear
read-ahead */
-@@ -2842,7 +2927,7 @@
+@@ -2877,7 +2962,7 @@
buf_read_ahead_linear(buf_block_get_space(block),
buf_block_get_zip_size(block),
buf_block_get_page_no(block),
}
#ifdef UNIV_IBUF_COUNT_DEBUG
-@@ -2852,6 +2937,9 @@
+@@ -2887,6 +2972,9 @@
buf_pool = buf_pool_from_block(block);
buf_pool->stat.n_page_gets++;
return(TRUE);
}
-@@ -2874,6 +2962,7 @@
+@@ -2909,6 +2997,7 @@
buf_pool_t* buf_pool;
ibool success;
ulint fix_type;
ut_ad(mtr);
ut_ad(mtr->state == MTR_ACTIVE);
-@@ -2960,6 +3049,11 @@
+@@ -2995,6 +3084,11 @@
#endif
buf_pool->stat.n_page_gets++;
--- a/storage/innobase/fil/fil0fil.c
+++ b/storage/innobase/fil/fil0fil.c
-@@ -4748,7 +4748,7 @@
+@@ -4757,7 +4757,7 @@
node->name, node->handle, buf,
offset_low, offset_high,
page_size * n_pages,
#endif
if (success) {
node->size += n_pages;
-@@ -5075,7 +5075,7 @@
+@@ -5084,7 +5084,7 @@
i/o on a tablespace which does not exist */
UNIV_INTERN
ulint
/*===*/
ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE,
ORed to OS_FILE_LOG, if a log i/o
-@@ -5100,8 +5100,9 @@
+@@ -5109,8 +5109,9 @@
void* buf, /*!< in/out: buffer where to store read data
or from where to write; in aio this must be
appropriately aligned */
{
ulint mode;
fil_space_t* space;
-@@ -5269,7 +5270,7 @@
+@@ -5278,7 +5279,7 @@
#else
/* Queue the aio request */
ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
/*********************************************************************//**
Note that a transaction has been registered with MySQL.
@return true if transaction is registered with MySQL 2PC coordinator */
-@@ -9409,6 +9445,25 @@
+@@ -9418,6 +9454,25 @@
statement has ended */
if (trx->n_mysql_tables_in_use == 0) {
order to contract the insert buffer tree. Technically, this function is like
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
-@@ -611,9 +611,12 @@
+@@ -615,9 +615,12 @@
Reads or writes data. This operation is asynchronous (aio).
@return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do
i/o on a tablespace which does not exist */
/*===*/
ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE,
ORed to OS_FILE_LOG, if a log i/o
-@@ -638,8 +641,9 @@
+@@ -642,8 +645,9 @@
void* buf, /*!< in/out: buffer where to store read data
or from where to write; in aio this must be
appropriately aligned */
# should be done or reviewed by the maintainer!
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
-@@ -11655,6 +11655,7 @@
+@@ -11664,6 +11664,7 @@
NULL, /* reserved */
0, /* flags */
},
# should be done or reviewed by the maintainer!
--- a/storage/innobase/btr/btr0cur.c
+++ b/storage/innobase/btr/btr0cur.c
-@@ -1173,6 +1173,11 @@
+@@ -1158,6 +1158,11 @@
rec_t* rec;
roll_ptr_t roll_ptr;
/* Check if we have to wait for a lock: enqueue an explicit lock
request if yes */
-@@ -1304,7 +1309,7 @@
+@@ -1289,7 +1294,7 @@
}
#endif /* UNIV_DEBUG */
max_size = page_get_max_insert_size_after_reorganize(page, 1);
leaf = page_is_leaf(page);
-@@ -1399,6 +1404,12 @@
+@@ -1384,6 +1389,12 @@
goto fail_err;
}
page_cursor = btr_cur_get_page_cur(cursor);
/* Now, try the insert */
-@@ -1541,10 +1552,10 @@
+@@ -1526,10 +1537,10 @@
*big_rec = NULL;
MTR_MEMO_PAGE_X_FIX));
/* Try first an optimistic insert; reset the cursor flag: we do not
-@@ -1610,6 +1621,16 @@
+@@ -1595,6 +1606,16 @@
}
}
if (dict_index_get_page(index)
== buf_block_get_page_no(btr_cur_get_block(cursor))) {
-@@ -1666,6 +1687,11 @@
+@@ -1651,6 +1672,11 @@
ut_ad(cursor && update && thr && roll_ptr);
rec = btr_cur_get_rec(cursor);
index = cursor->index;
-@@ -1965,6 +1991,14 @@
+@@ -1950,6 +1976,14 @@
return(err);
}
if (!(flags & BTR_KEEP_SYS_FLAG)) {
row_upd_rec_sys_fields(rec, NULL,
index, offsets, trx, roll_ptr);
-@@ -2074,7 +2108,7 @@
+@@ -2059,7 +2093,7 @@
rec = btr_cur_get_rec(cursor);
index = cursor->index;
ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table));
/* The insert buffer tree should never be updated in place. */
ut_ad(!dict_index_is_ibuf(index));
-@@ -2187,6 +2221,11 @@
+@@ -2172,6 +2206,11 @@
goto err_exit;
}
/* Ok, we may do the replacement. Store on the page infimum the
explicit locks on rec, before deleting rec (see the comment in
btr_cur_pessimistic_update). */
-@@ -2337,9 +2376,9 @@
+@@ -2322,9 +2361,9 @@
rec = btr_cur_get_rec(cursor);
index = cursor->index;
#ifdef UNIV_ZIP_DEBUG
ut_a(!page_zip || page_zip_validate(page_zip, page));
#endif /* UNIV_ZIP_DEBUG */
-@@ -2427,6 +2466,9 @@
+@@ -2412,6 +2451,9 @@
ut_ad(big_rec_vec == NULL);
btr_rec_free_updated_extern_fields(
index, rec, page_zip, offsets, update,
trx_is_recv(trx) ? RB_RECOVERY : RB_NORMAL, mtr);
-@@ -2461,6 +2503,12 @@
+@@ -2446,6 +2488,12 @@
}
}
/* Store state of explicit locks on rec on the page infimum record,
before deleting rec. The page infimum acts as a dummy carrier of the
locks, taking care also of lock releases, before we can move the locks
-@@ -2763,6 +2811,11 @@
+@@ -2748,6 +2796,11 @@
ut_ad(dict_index_is_clust(index));
ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
err = lock_clust_rec_modify_check_and_lock(flags, block,
rec, index, offsets, thr);
-@@ -2897,6 +2950,11 @@
+@@ -2882,6 +2935,11 @@
rec_t* rec;
ulint err;
/* Transaction is deregistered only in a commit or a rollback. If
it is deregistered we know there cannot be resources to be freed
and we could return immediately. For the time being, we play safe
-@@ -7545,6 +7558,12 @@
+@@ -7544,6 +7557,12 @@
trx = innobase_trx_allocate(thd);
/* Latch the InnoDB data dictionary exclusively so that no deadlocks
or lock waits can happen in it during a table create operation.
Drop table etc. do this latching in row0mysql.c. */
-@@ -7765,6 +7784,10 @@
+@@ -7764,6 +7783,10 @@
DBUG_RETURN(HA_ERR_CRASHED);
}
/* Truncate the table in InnoDB */
error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx);
-@@ -7821,6 +7844,12 @@
+@@ -7820,6 +7843,12 @@
trx = innobase_trx_allocate(thd);
name_len = strlen(name);
ut_a(name_len < 1000);
-@@ -7907,6 +7936,12 @@
+@@ -7906,6 +7935,12 @@
trx->mysql_thd = NULL;
#else
trx = innobase_trx_allocate(thd);
#endif
row_drop_database_for_mysql(namebuf, trx);
my_free(namebuf);
-@@ -8012,6 +8047,11 @@
+@@ -8011,6 +8046,11 @@
trx_search_latch_release_if_reserved(parent_trx);
trx = innobase_trx_allocate(thd);
error = innobase_rename_table(trx, from, to, TRUE);
-@@ -10872,6 +10912,10 @@
+@@ -10881,6 +10921,10 @@
return(0);
}
thd_get_xid(thd, (MYSQL_XID*) &trx->xid);
/* Release a possible FIFO ticket and search latch. Since we will
-@@ -12429,6 +12473,7 @@
+@@ -12438,6 +12482,7 @@
MYSQL_SYSVAR(rollback_segments),
MYSQL_SYSVAR(corrupt_table_action),
MYSQL_SYSVAR(lazy_drop_table),
/* Flag this transaction as a dictionary operation, so that
--- a/storage/innobase/ibuf/ibuf0ibuf.c
+++ b/storage/innobase/ibuf/ibuf0ibuf.c
-@@ -3496,6 +3496,8 @@
+@@ -3424,6 +3424,8 @@
ut_a(trx_sys_multiple_tablespace_format);
srv_blocking_lru_restore = (ibool) innobase_blocking_lru_restore;
-@@ -11533,6 +11535,15 @@
+@@ -11542,6 +11544,15 @@
"Disable with --skip-innodb-checksums.",
NULL, NULL, TRUE);
static MYSQL_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
PLUGIN_VAR_READONLY,
"The common part for InnoDB table spaces.",
-@@ -12064,6 +12075,7 @@
+@@ -12073,6 +12084,7 @@
MYSQL_SYSVAR(buffer_pool_size),
MYSQL_SYSVAR(buffer_pool_instances),
MYSQL_SYSVAR(checksums),
looked at the first few bytes of the page. This calculates that old
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
-@@ -118,6 +118,7 @@
+@@ -119,6 +119,7 @@
#define FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 34 /*!< starting from 4.1.x this
contains the space id of the page */
#define FIL_PAGE_DATA 38 /*!< start of the data on the page */
fprintf(stderr,
"InnoDB: Error: the size of single-table"
" tablespace file %s\n"
-@@ -4152,7 +4152,7 @@
+@@ -4161,7 +4161,7 @@
size = (((ib_int64_t)size_high) << 32) + (ib_int64_t)size_low;
#ifndef UNIV_HOTBACKUP
fprintf(stderr,
"InnoDB: Error: the size of single-table tablespace"
" file %s\n"
-@@ -4172,7 +4172,7 @@
+@@ -4181,7 +4181,7 @@
/* Align the memory for file i/o if we might have O_DIRECT set */
page = ut_align(buf2, UNIV_PAGE_SIZE);
success = os_file_read(file, page, 0, 0, UNIV_PAGE_SIZE);
/* We have to read the tablespace id from the file */
-@@ -5150,9 +5150,9 @@
+@@ -5159,9 +5159,9 @@
ut_ad(ut_is_2pow(zip_size));
ut_ad(buf);
ut_ad(len > 0);
#ifndef MYSQL_SERVER
innodb_overwrite_relay_log_info = FALSE;
#endif
-@@ -7291,9 +7353,9 @@
+@@ -7290,9 +7352,9 @@
| DICT_TF_COMPACT
| DICT_TF_FORMAT_ZIP
<< DICT_TF_FORMAT_SHIFT;
}
}
-@@ -11544,6 +11606,16 @@
+@@ -11553,6 +11615,16 @@
"#### Attention: The checksum is not compatible for normal or disabled version! ####",
NULL, NULL, FALSE);
static MYSQL_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
PLUGIN_VAR_READONLY,
"The common part for InnoDB table spaces.",
-@@ -12070,6 +12142,8 @@
+@@ -12079,6 +12151,8 @@
NULL, NULL, 0, &corrupt_table_action_typelib);
static struct st_mysql_sys_var* innobase_system_variables[]= {
# should be done or reviewed by the maintainer!
--- a/storage/innobase/buf/buf0buf.c
+++ b/storage/innobase/buf/buf0buf.c
-@@ -1944,6 +1944,27 @@
+@@ -1979,6 +1979,27 @@
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
}
if (UNIV_UNLIKELY(!bpage->zip.data)) {
/* There is no compressed page. */
err_exit:
-@@ -2452,6 +2473,27 @@
+@@ -2487,6 +2508,27 @@
block = (buf_block_t*) buf_page_hash_get_low(
buf_pool, space, offset, fold);
if (block) {
block_mutex = buf_page_get_mutex_enter((buf_page_t*)block);
ut_a(block_mutex);
}
-@@ -3374,11 +3416,28 @@
+@@ -3409,11 +3451,28 @@
fold = buf_page_address_fold(space, offset);
if (watch_page && !buf_pool_watch_is_sentinel(buf_pool, watch_page)) {
/* The page is already in the buffer pool. */
watch_page = NULL;
-@@ -3509,6 +3568,7 @@
+@@ -3544,6 +3603,7 @@
bpage->state = BUF_BLOCK_ZIP_PAGE;
bpage->space = space;
bpage->offset = offset;
#ifdef UNIV_DEBUG
bpage->in_page_hash = FALSE;
-@@ -3593,6 +3653,7 @@
+@@ -3628,6 +3688,7 @@
fold = buf_page_address_fold(space, offset);
//buf_pool_mutex_enter(buf_pool);
mutex_enter(&buf_pool->LRU_list_mutex);
rw_lock_x_lock(&buf_pool->page_hash_latch);
-@@ -3600,6 +3661,21 @@
+@@ -3635,6 +3696,21 @@
block = (buf_block_t*) buf_page_hash_get_low(
buf_pool, space, offset, fold);
if (block
&& buf_page_in_file(&block->page)
&& !buf_pool_watch_is_sentinel(buf_pool, &block->page)) {
-@@ -3953,8 +4029,11 @@
+@@ -3988,8 +4064,11 @@
}
if (io_type == BUF_IO_WRITE
#endif
/* printf("Deleting tablespace %s id %lu\n", space->name, id); */
-@@ -4722,6 +4729,10 @@
+@@ -4731,6 +4738,10 @@
ulint page_size;
ibool success = TRUE;
fil_mutex_enter_and_prepare_for_io(space_id);
space = fil_space_get_by_id(space_id);
-@@ -4733,6 +4744,7 @@
+@@ -4742,6 +4753,7 @@
*actual_size = space->size;
mutex_exit(&fil_system->mutex);
return(TRUE);
}
-@@ -4765,6 +4777,8 @@
+@@ -4774,6 +4786,8 @@
offset_low = ((start_page_no - file_start_page_no)
% (4096 * ((1024 * 1024) / page_size)))
* page_size;
#ifdef UNIV_HOTBACKUP
success = os_file_write(node->name, node->handle, buf,
offset_low, offset_high,
-@@ -4774,8 +4788,10 @@
+@@ -4783,8 +4797,10 @@
node->name, node->handle, buf,
offset_low, offset_high,
page_size * n_pages,
if (success) {
node->size += n_pages;
space->size += n_pages;
-@@ -4821,6 +4837,7 @@
+@@ -4830,6 +4846,7 @@
printf("Extended %s to %lu, actual size %lu pages\n", space->name,
size_after_extend, *actual_size); */
mutex_exit(&fil_system->mutex);
fil_flush(space_id, TRUE);
-@@ -5183,6 +5200,22 @@
+@@ -5192,6 +5209,22 @@
srv_data_written+= len;
}
/* Reserve the fil_system mutex and make sure that we can open at
least one file while holding it, if the file is not already open */
-@@ -5324,10 +5357,24 @@
+@@ -5333,10 +5366,24 @@
#else
/* Queue the aio request */
ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
ut_a(ret);
if (mode == OS_AIO_SYNC) {
-@@ -5427,6 +5474,7 @@
+@@ -5436,6 +5483,7 @@
fil_node_t* fil_node;
void* message;
ulint type;
ut_ad(fil_validate_skip());
-@@ -5434,10 +5482,10 @@
+@@ -5443,10 +5491,10 @@
srv_set_io_thread_op_info(segment, "native aio handle");
#ifdef WIN_ASYNC_IO
ret = os_aio_windows_handle(segment, 0, &fil_node,
#else
ut_error;
ret = 0; /* Eliminate compiler warning */
-@@ -5446,7 +5494,22 @@
+@@ -5455,7 +5503,22 @@
srv_set_io_thread_op_info(segment, "simulated aio handle");
ret = os_aio_simulated_handle(segment, &fil_node,
ut_a(ret);
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
-@@ -12141,6 +12141,12 @@
+@@ -12150,6 +12150,12 @@
"except for the deletion.",
NULL, NULL, 0, &corrupt_table_action_typelib);
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(page_size),
MYSQL_SYSVAR(log_block_size),
-@@ -12235,6 +12241,7 @@
+@@ -12244,6 +12250,7 @@
MYSQL_SYSVAR(purge_batch_size),
MYSQL_SYSVAR(rollback_segments),
MYSQL_SYSVAR(corrupt_table_action),
NULL
};
-@@ -12244,7 +12251,7 @@
+@@ -12253,7 +12260,7 @@
&innobase_storage_engine,
innobase_hton_name,
plugin_author,
/* We know that the writes have been flushed to disk now
and in recovery we will find them in the doublewrite buffer
-@@ -1378,7 +1378,7 @@
+@@ -1375,10 +1375,11 @@
+ ulint high;
+ ulint count = 0;
+ buf_pool_t* buf_pool = buf_pool_get(space, offset);
++ ibool is_forward_scan;
ut_ad(flush_type == BUF_FLUSH_LRU || flush_type == BUF_FLUSH_LIST);
/* If there is little space, it is better not to flush
any block except from the end of the LRU list */
+@@ -1405,7 +1406,32 @@
+ high = fil_space_get_size(space);
+ }
+
+- for (i = low; i < high; i++) {
++ if (srv_flush_neighbor_pages == 2) {
++
++ /* In the case of contiguous flush where the requested page
++ does not fall at the start of flush area, first scan backward
++ from the page and later forward from it. */
++ is_forward_scan = (offset == low);
++ }
++ else {
++ is_forward_scan = TRUE;
++ }
++
++scan:
++ if (srv_flush_neighbor_pages == 2) {
++ if (is_forward_scan) {
++ i = offset;
++ }
++ else {
++ i = offset - 1;
++ }
++ }
++ else {
++ i = low;
++ }
++
++ for (; is_forward_scan ? (i < high) : (i >= low);
++ is_forward_scan ? i++ : i--) {
+
+ buf_page_t* bpage;
+
+@@ -1434,6 +1460,12 @@
+ if (!bpage) {
+
+ buf_pool_mutex_exit(buf_pool);
++ if (srv_flush_neighbor_pages == 2) {
++
++ /* This is contiguous neighbor page flush and
++ the pages here are not contiguous. */
++ break;
++ }
+ continue;
+ }
+
+@@ -1470,6 +1502,22 @@
+ }
+ }
+ buf_pool_mutex_exit(buf_pool);
++
++ if (srv_flush_neighbor_pages == 2) {
++
++ /* We are trying to do the contiguous neighbor page
++ flush, but the last page we checked was unflushable,
++ making a "hole" in the flush, so stop this attempt. */
++ break;
++ }
++ }
++
++ if (!is_forward_scan) {
++
++ /* Backward scan done, now do the forward scan */
++ ut_a (srv_flush_neighbor_pages == 2);
++ is_forward_scan = TRUE;
++ goto scan;
+ }
+
+ return(count);
+@@ -1940,6 +1988,22 @@
+
+ buf_pool = buf_pool_from_array(i);
+
++ if (lsn_limit != IB_ULONGLONG_MAX) {
++ buf_page_t* bpage;
++
++ buf_flush_list_mutex_enter(buf_pool);
++ bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
++ if (!bpage
++ || bpage->oldest_modification >= lsn_limit) {
++
++ buf_flush_list_mutex_exit(buf_pool);
++ continue;
++ } else {
++
++ buf_flush_list_mutex_exit(buf_pool);
++ }
++ }
++
+ if (!buf_flush_start(buf_pool, BUF_FLUSH_LIST)) {
+ /* We have two choices here. If lsn_limit was
+ specified then skipping an instance of buffer
--- a/storage/innobase/buf/buf0rea.c
+++ b/storage/innobase/buf/buf0rea.c
@@ -427,6 +427,10 @@
srv_force_recovery = (ulint) innobase_force_recovery;
srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
-@@ -11133,7 +11153,7 @@
+@@ -11142,7 +11162,7 @@
PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
"Purge threads can be either 0 or 1.",
NULL, NULL,
0, /* Minimum value */
1, 0); /* Maximum value */
-@@ -11175,12 +11195,18 @@
+@@ -11184,12 +11204,18 @@
innodb_file_format_max_validate,
innodb_file_format_max_update, "Antelope");
static MYSQL_SYSVAR_STR(flush_method, innobase_file_flush_method,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
-@@ -11285,7 +11311,7 @@
+@@ -11294,7 +11320,7 @@
static MYSQL_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
static MYSQL_SYSVAR_LONG(buffer_pool_instances, innobase_buffer_pool_instances,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
-@@ -11442,6 +11468,95 @@
+@@ -11451,6 +11477,135 @@
"trigger a readahead.",
NULL, NULL, 56, 0, 64, 0);
+ "Control soft limit of checkpoint age. (0 : not control)",
+ NULL, NULL, 0, 0, ~0UL, 0);
+
-+static MYSQL_SYSVAR_ULONG(flush_neighbor_pages, srv_flush_neighbor_pages,
-+ PLUGIN_VAR_RQCMDARG,
-+ "Enable/Disable flushing also neighbor pages. 0:disable 1:enable",
-+ NULL, NULL, 1, 0, 1, 0);
++static
++void
++innodb_flush_neighbor_pages_update(
++ THD* thd,
++ struct st_mysql_sys_var* var,
++ void* var_ptr,
++ const void* save)
++{
++ *(long *)var_ptr = (*(long *)save) % 3;
++}
++
++const char *flush_neighbor_pages_names[]=
++{
++ "none", /* 0 */
++ "area",
++ "cont", /* 2 */
++ /* For compatibility with the older patch */
++ "0", /* "none" + 3 */
++ "1", /* "area" + 3 */
++ "2", /* "cont" + 3 */
++ NullS
++};
++
++TYPELIB flush_neighbor_pages_typelib=
++{
++ array_elements(flush_neighbor_pages_names) - 1,
++ "flush_neighbor_pages_typelib",
++ flush_neighbor_pages_names,
++ NULL
++};
++
++static MYSQL_SYSVAR_ENUM(flush_neighbor_pages, srv_flush_neighbor_pages,
++ PLUGIN_VAR_RQCMDARG, "Neighbor page flushing behaviour: none: do not flush, "
++ "[area]: flush selected pages one-by-one, "
++ "cont: flush a contiguous block of pages", NULL,
++ innodb_flush_neighbor_pages_update, 1, &flush_neighbor_pages_typelib);
+
+static
+void
+ PLUGIN_VAR_RQCMDARG,
+ "Choose method of innodb_adaptive_flushing. (native, [estimate], keep_average)",
+ NULL, innodb_adaptive_flushing_method_update, 1, &adaptive_flushing_method_typelib);
++
++#ifdef UNIV_DEBUG
++static MYSQL_SYSVAR_ULONG(flush_checkpoint_debug, srv_flush_checkpoint_debug,
++ PLUGIN_VAR_RQCMDARG,
++ "Debug flags for InnoDB flushing and checkpointing (0=none,"
++ "1=stop preflush and checkpointing)",
++ NULL, NULL, 0, 0, 1, 0);
++#endif
+
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(additional_mem_pool_size),
MYSQL_SYSVAR(autoextend_increment),
-@@ -11462,6 +11577,7 @@
+@@ -11471,6 +11626,7 @@
MYSQL_SYSVAR(file_format_check),
MYSQL_SYSVAR(file_format_max),
MYSQL_SYSVAR(flush_log_at_trx_commit),
MYSQL_SYSVAR(flush_method),
MYSQL_SYSVAR(force_recovery),
MYSQL_SYSVAR(large_prefix),
-@@ -11501,6 +11617,13 @@
+@@ -11510,6 +11666,13 @@
MYSQL_SYSVAR(show_verbose_locks),
MYSQL_SYSVAR(show_locks_held),
MYSQL_SYSVAR(version),
MYSQL_SYSVAR(use_sys_malloc),
MYSQL_SYSVAR(use_native_aio),
MYSQL_SYSVAR(change_buffering),
+@@ -11522,6 +11685,9 @@
+ MYSQL_SYSVAR(purge_threads),
+ MYSQL_SYSVAR(purge_batch_size),
+ MYSQL_SYSVAR(rollback_segments),
++#ifdef UNIV_DEBUG
++ MYSQL_SYSVAR(flush_checkpoint_debug),
++#endif
+ NULL
+ };
+
--- a/storage/innobase/ibuf/ibuf0ibuf.c
+++ b/storage/innobase/ibuf/ibuf0ibuf.c
-@@ -514,8 +514,10 @@
+@@ -523,8 +523,10 @@
grow in size, as the references on the upper levels of the tree can
change */
mutex_create(ibuf_pessimistic_insert_mutex_key,
&ibuf_pessimistic_insert_mutex,
-@@ -2753,9 +2755,11 @@
+@@ -2763,9 +2765,11 @@
size = ibuf->size;
max_size = ibuf->max_size;
/*-------------------------------------------*/
extern ulint srv_n_rows_inserted;
-@@ -399,8 +410,9 @@
+@@ -255,6 +266,9 @@
+ extern ibool srv_print_buf_io;
+ extern ibool srv_print_log_io;
+ extern ibool srv_print_latch_waits;
++
++extern ulint srv_flush_checkpoint_debug;
++
+ #else /* UNIV_DEBUG */
+ # define srv_print_thread_releases FALSE
+ # define srv_print_lock_waits FALSE
+@@ -399,8 +413,9 @@
when writing data files, but do flush
after writing to log files */
SRV_UNIX_NOSYNC, /*!< do not flush after writing */
log_sys->flushed_to_disk_lsn = log_sys->write_lsn;
}
-@@ -2120,10 +2151,10 @@
+@@ -1655,10 +1686,13 @@
+ recv_apply_hashed_log_recs(TRUE);
+ }
+
++ retry:
+ n_pages = buf_flush_list(ULINT_MAX, new_oldest);
+
+- if (sync) {
+- buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
++ if (sync && n_pages != 0) {
++ //buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
++ os_thread_sleep(100000);
++ goto retry;
+ }
+
+ if (n_pages == ULINT_UNDEFINED) {
+@@ -1979,6 +2013,13 @@
+ {
+ ib_uint64_t oldest_lsn;
+
++#ifdef UNIV_DEBUG
++ if (srv_flush_checkpoint_debug == 1) {
++
++ return TRUE;
++ }
++#endif
++
+ if (recv_recovery_is_on()) {
+ recv_apply_hashed_log_recs(TRUE);
+ }
+@@ -2070,7 +2111,11 @@
+ physical write will always be made to
+ log files */
+ {
+- /* Preflush pages synchronously */
++#ifdef UNIV_DEBUG
++ if (srv_flush_checkpoint_debug == 1)
++ return;
++#endif
++/* Preflush pages synchronously */
+
+ while (!log_preflush_pool_modified_pages(lsn, TRUE));
+
+@@ -2096,7 +2141,13 @@
+ ibool checkpoint_sync;
+ ibool do_checkpoint;
+ ibool success;
+-loop:
++
++#ifdef UNIV_DEBUG
++ if (srv_flush_checkpoint_debug == 1)
++ return;
++#endif
++
++ loop:
+ sync = FALSE;
+ checkpoint_sync = FALSE;
+ do_checkpoint = FALSE;
+@@ -2119,13 +2170,15 @@
+ /* A flush is urgent: we have to do a synchronous preflush */
sync = TRUE;
- advance = 2 * (age - log->max_modified_age_sync);
+- advance = 2 * (age - log->max_modified_age_sync);
- } else if (age > log->max_modified_age_async) {
++ advance = age - log->max_modified_age_sync;
+ } else if (age > log_max_modified_age_async()) {
/* A flush is not urgent: we do an asynchronous preflush */
- advance = age - log->max_modified_age_async;
+ advance = age - log_max_modified_age_async();
++ log->check_flush_or_checkpoint = FALSE;
} else {
advance = 0;
++ log->check_flush_or_checkpoint = FALSE;
}
-@@ -2137,7 +2168,7 @@
+
+ checkpoint_age = log->lsn - log->last_checkpoint_lsn;
+@@ -2137,14 +2190,14 @@
do_checkpoint = TRUE;
/* A checkpoint is not urgent: do it asynchronously */
do_checkpoint = TRUE;
-@@ -2607,7 +2638,7 @@
+
+- log->check_flush_or_checkpoint = FALSE;
++ //log->check_flush_or_checkpoint = FALSE;
+ } else {
+- log->check_flush_or_checkpoint = FALSE;
++ //log->check_flush_or_checkpoint = FALSE;
+ }
+
+ mutex_exit(&(log->mutex));
+@@ -2152,6 +2205,7 @@
+ if (advance) {
+ ib_uint64_t new_oldest = oldest_lsn + advance;
+
++retry:
+ success = log_preflush_pool_modified_pages(new_oldest, sync);
+
+ /* If the flush succeeded, this thread has done its part
+@@ -2166,7 +2220,7 @@
+ log->check_flush_or_checkpoint = TRUE;
+
+ mutex_exit(&(log->mutex));
+- goto loop;
++ goto retry;
+ }
+ }
+
+@@ -2607,7 +2661,7 @@
mutex_exit(&(log_sys->mutex));
mutex_enter(&(log_sys->mutex));
-@@ -3349,6 +3380,17 @@
+@@ -3044,7 +3098,11 @@
+ log_check_margins(void)
+ /*===================*/
+ {
+-loop:
++#ifdef UNIV_DEBUG
++ if (srv_flush_checkpoint_debug == 1)
++ return;
++#endif
++ loop:
+ log_flush_margin();
+
+ log_checkpoint_margin();
+@@ -3349,6 +3407,17 @@
log_sys->flushed_to_disk_lsn,
log_sys->last_checkpoint_lsn);
+#define PCT_IBUF_IO(pct) ((ulint) (srv_io_capacity * srv_ibuf_accel_rate * ((double) pct / 10000.0)))
+
+UNIV_INTERN ulint srv_checkpoint_age_target = 0;
-+UNIV_INTERN ulint srv_flush_neighbor_pages = 1; /* 0:disable 1:enable */
++UNIV_INTERN ulint srv_flush_neighbor_pages = 1; /* 0:disable 1:area 2:contiguous */
+
+UNIV_INTERN ulint srv_enable_unsafe_group_commit = 0; /* 0:disable 1:enable */
+UNIV_INTERN ulint srv_read_ahead = 3; /* 1: random 2: linear 3: Both */
/*-------------------------------------------*/
UNIV_INTERN ulong srv_n_spin_wait_rounds = 30;
UNIV_INTERN ulong srv_n_free_tickets_to_enter = 500;
-@@ -2713,7 +2725,7 @@
+@@ -417,6 +429,9 @@
+ UNIV_INTERN ibool srv_print_buf_io = FALSE;
+ UNIV_INTERN ibool srv_print_log_io = FALSE;
+ UNIV_INTERN ibool srv_print_latch_waits = FALSE;
++
++UNIV_INTERN ulong srv_flush_checkpoint_debug = 0;
++
+ #endif /* UNIV_DEBUG */
+
+ UNIV_INTERN ulint srv_n_rows_inserted = 0;
+@@ -2713,7 +2728,7 @@
ut_ad(!mutex_own(&kernel_mutex));
do {
/* Check for shutdown and change in purge config. */
-@@ -2746,6 +2758,7 @@
+@@ -2746,6 +2761,7 @@
ulint n_pages_purged = 0;
ulint n_bytes_merged;
ulint n_pages_flushed;
ulint n_bytes_archived;
ulint n_tables_to_drop;
ulint n_ios;
-@@ -2753,7 +2766,20 @@
+@@ -2753,7 +2769,20 @@
ulint n_ios_very_old;
ulint n_pend_ios;
ulint next_itr_time;
#ifdef UNIV_DEBUG_THREAD_CREATION
fprintf(stderr, "Master thread starts, id %lu\n",
-@@ -2775,6 +2801,9 @@
+@@ -2775,6 +2804,9 @@
mutex_exit(&kernel_mutex);
loop:
/*****************************************************************/
/* ---- When there is database activity by users, we cycle in this
-@@ -2805,9 +2834,13 @@
+@@ -2805,9 +2837,13 @@
/* Sleep for 1 second on entrying the for loop below the first time. */
next_itr_time = ut_time_ms() + 1000;
/* ALTER TABLE in MySQL requires on Unix that the table handler
can drop tables lazily after there no longer are SELECT
queries to them. */
-@@ -2831,6 +2864,7 @@
+@@ -2831,6 +2867,7 @@
srv_main_thread_op_info = "sleeping";
srv_main_1_second_loops++;
if (next_itr_time > cur_time
&& srv_shutdown_state == SRV_SHUTDOWN_NONE) {
-@@ -2841,10 +2875,26 @@
+@@ -2841,10 +2878,26 @@
(next_itr_time - cur_time)
* 1000));
srv_main_sleeps++;
/* Flush logs if needed */
srv_sync_log_buffer_in_background();
-@@ -2864,7 +2914,7 @@
+@@ -2864,7 +2917,7 @@
if (n_pend_ios < SRV_PEND_IO_THRESHOLD
&& (n_ios - n_ios_old < SRV_RECENT_IO_ACTIVITY)) {
srv_main_thread_op_info = "doing insert buffer merge";
/* Flush logs if needed */
srv_sync_log_buffer_in_background();
-@@ -2881,7 +2931,11 @@
+@@ -2881,7 +2934,11 @@
n_pages_flushed = buf_flush_list(
PCT_IO(100), IB_ULONGLONG_MAX);
/* Try to keep the rate of flushing of dirty
pages such that redo log generation does not
-@@ -2897,6 +2951,224 @@
+@@ -2897,6 +2954,224 @@
n_flush,
IB_ULONGLONG_MAX);
}
}
if (srv_activity_count == old_activity_count) {
-@@ -2945,12 +3217,12 @@
+@@ -2945,12 +3220,12 @@
even if the server were active */
srv_main_thread_op_info = "doing insert buffer merge";
srv_main_thread_op_info = "master purging";
srv_master_do_purge();
-@@ -3028,7 +3300,7 @@
+@@ -2982,11 +3257,18 @@
+ PCT_IO(10), IB_ULONGLONG_MAX);
+ }
+
+- srv_main_thread_op_info = "making checkpoint";
++#ifdef UNIV_DEBUG
++ if (srv_flush_checkpoint_debug != 1) {
++#endif
+
+- /* Make a new checkpoint about once in 10 seconds */
++ srv_main_thread_op_info = "making checkpoint";
+
+- log_checkpoint(TRUE, FALSE);
++ /* Make a new checkpoint about once in 10 seconds */
++
++ log_checkpoint(TRUE, FALSE);
++#ifdef UNIV_DEBUG
++ }
++#endif
+
+ srv_main_thread_op_info = "reserving kernel mutex";
+
+@@ -3028,7 +3310,7 @@
}
}
srv_main_thread_op_info = "master purging";
srv_master_do_purge();
-@@ -3053,7 +3325,7 @@
+@@ -3053,7 +3335,7 @@
buf_flush_list below. Otherwise, the system favors
clean pages over cleanup throughput. */
n_bytes_merged = ibuf_contract_for_n_pages(FALSE,
}
srv_main_thread_op_info = "reserving kernel mutex";
-@@ -3193,6 +3465,7 @@
+@@ -3065,6 +3347,10 @@
+ }
+ mutex_exit(&kernel_mutex);
+
++#ifdef UNIV_DEBUG
++ if (srv_flush_checkpoint_debug == 1)
++ goto skip_flush;
++#endif
+ flush_loop:
+ srv_main_thread_op_info = "flushing buffer pool pages";
+ srv_main_flush_loops++;
+@@ -3105,6 +3391,9 @@
+ goto flush_loop;
+ }
+
++#ifdef UNIV_DEBUG
++skip_flush:
++#endif
+ srv_main_thread_op_info = "reserving kernel mutex";
+
+ mutex_enter(&kernel_mutex);
+@@ -3193,6 +3482,7 @@
srv_slot_t* slot;
ulint retries = 0;
ulint n_total_purged = ULINT_UNDEFINED;
ut_a(srv_n_purge_threads == 1);
-@@ -3213,9 +3486,12 @@
+@@ -3213,9 +3503,12 @@
mutex_exit(&kernel_mutex);
/* If there are very few records to purge or the last
purge didn't purge any records then wait for activity.
-@@ -3262,6 +3538,16 @@
+@@ -3262,6 +3555,16 @@
} while (n_pages_purged > 0 && !srv_fast_shutdown);
srv_sync_log_buffer_in_background();
SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size';
variable_value
16384
+--- /dev/null
++++ b/mysql-test/suite/innodb/r/percona_flush_contiguous_neighbors.result
+@@ -0,0 +1,21 @@
++DROP TABLE IF EXISTS t1;
++CREATE TABLE t1 (id INT AUTO_INCREMENT, foo CHAR(255), PRIMARY KEY (id)) ENGINE=InnoDB;
++INSERT INTO t1(foo) VALUES ('a'), ('b');
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++DROP TABLE t1;
+--- /dev/null
++++ b/mysql-test/suite/innodb/t/percona_flush_contiguous_neighbors-master.opt
+@@ -0,0 +1 @@
++--innodb_flush_neighbor_pages=cont
+--- /dev/null
++++ b/mysql-test/suite/innodb/t/percona_flush_contiguous_neighbors.test
+@@ -0,0 +1,36 @@
++# Test for innodb_flush_neighbor_pages=contiguous.
++# The test is very crude: we simply overflow the buffer pool with such a number of
++# new/modified pages that some flushing is bound to happen.
++
++--source include/have_innodb.inc
++
++--disable_warnings
++DROP TABLE IF EXISTS t1;
++--enable_warnings
++
++CREATE TABLE t1 (id INT AUTO_INCREMENT, foo CHAR(255), PRIMARY KEY (id)) ENGINE=InnoDB;
++
++INSERT INTO t1(foo) VALUES ('a'), ('b');
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++INSERT INTO t1(foo) SELECT foo FROM t1;
++
++# TODO: cannot record a stable value here. A check of > 0 should be enough,
++# but the variable is not accessible through INFORMATION_SCHEMA currently.
++# SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages_flushed';
++
++DROP TABLE t1;
+--- /dev/null
++++ b/mysql-test/suite/innodb/r/percona_sync_flush.result
+@@ -0,0 +1,35 @@
++DROP TABLE IF EXISTS t1;
++CREATE TABLE t1 (id INT AUTO_INCREMENT, foo CHAR(255), PRIMARY KEY (id)) ENGINE=InnoDB;
++SET @@global.innodb_flush_checkpoint_debug=1;
++INSERT INTO t1(foo) VALUES ('a'), ('b');
++INSERT INTO t1(foo) SELECT foo FROM t1;
++UPDATE t1 SET foo='c';
++INSERT INTO t1(foo) SELECT foo FROM t1;
++UPDATE t1 SET foo='c';
++INSERT INTO t1(foo) SELECT foo FROM t1;
++UPDATE t1 SET foo='c';
++INSERT INTO t1(foo) SELECT foo FROM t1;
++UPDATE t1 SET foo='c';
++INSERT INTO t1(foo) SELECT foo FROM t1;
++UPDATE t1 SET foo='c';
++INSERT INTO t1(foo) SELECT foo FROM t1;
++UPDATE t1 SET foo='c';
++INSERT INTO t1(foo) SELECT foo FROM t1;
++UPDATE t1 SET foo='c';
++INSERT INTO t1(foo) SELECT foo FROM t1;
++UPDATE t1 SET foo='c';
++INSERT INTO t1(foo) SELECT foo FROM t1;
++UPDATE t1 SET foo='c';
++INSERT INTO t1(foo) SELECT foo FROM t1;
++UPDATE t1 SET foo='c';
++INSERT INTO t1(foo) SELECT foo FROM t1;
++UPDATE t1 SET foo='c';
++INSERT INTO t1(foo) SELECT foo FROM t1;
++UPDATE t1 SET foo='c';
++INSERT INTO t1(foo) SELECT foo FROM t1;
++UPDATE t1 SET foo='c';
++INSERT INTO t1(foo) SELECT foo FROM t1;
++UPDATE t1 SET foo='c';
++SET @@global.innodb_flush_checkpoint_debug=0;
++UPDATE t1 SET foo='d' WHERE foo='c';
++DROP TABLE t1;
+--- /dev/null
++++ b/mysql-test/suite/innodb/t/percona_sync_flush.test
+@@ -0,0 +1,33 @@
++# Test for InnoDB sync state flushing.
++
++--source include/have_innodb.inc
++--source include/have_debug.inc
++
++--disable_warnings
++DROP TABLE IF EXISTS t1;
++--enable_warnings
++
++CREATE TABLE t1 (id INT AUTO_INCREMENT, foo CHAR(255), PRIMARY KEY (id)) ENGINE=InnoDB;
++
++# It is hard to get to InnoDB sync state flushing in MTR with regular workload. Perhaps
++# it is possible with many parallel connections, but that would be brittle anyway.
++# So, just disable preflushing and checkpointing and issue simple workload.
++SET @@global.innodb_flush_checkpoint_debug=1;
++
++INSERT INTO t1(foo) VALUES ('a'), ('b');
++
++let $rep=0;
++while ($rep < 14)
++{
++ INSERT INTO t1(foo) SELECT foo FROM t1;
++ UPDATE t1 SET foo='c';
++ inc $rep;
++}
++
++# By now checkpoint age should be well past sync flush point. Allow
++# preflushing/checkpointing again and do some work in order to do the sync flush.
++SET @@global.innodb_flush_checkpoint_debug=0;
++
++UPDATE t1 SET foo='d' WHERE foo='c';
++
++DROP TABLE t1;
+--- a/mysql-test/suite/sys_vars/r/all_vars.result
++++ b/mysql-test/suite/sys_vars/r/all_vars.result
+@@ -4,6 +4,7 @@
+ insert into t2 select variable_name from information_schema.global_variables;
+ insert into t2 select variable_name from information_schema.session_variables;
+ delete from t2 where variable_name='innodb_change_buffering_debug';
++delete from t2 where variable_name='innodb_flush_checkpoint_debug';
+ update t2 set variable_name= replace(variable_name, "PERFORMANCE_SCHEMA_", "PFS_");
+ select variable_name as `There should be *no* long test name listed below:` from t2
+ where length(variable_name) > 50;
+--- a/mysql-test/suite/sys_vars/t/all_vars.test
++++ b/mysql-test/suite/sys_vars/t/all_vars.test
+@@ -47,8 +47,9 @@
+ insert into t2 select variable_name from information_schema.global_variables;
+ insert into t2 select variable_name from information_schema.session_variables;
+
+-# This is only present in debug builds.
++# These are only present in debug builds.
+ delete from t2 where variable_name='innodb_change_buffering_debug';
++delete from t2 where variable_name='innodb_flush_checkpoint_debug';
+
+ # Performance schema variables are too long for files named
+ # 'mysql-test/suite/sys_vars/t/' ...
#ifdef HAVE_PSI_INTERFACE
/* Register keys with MySQL performance schema */
if (PSI_server) {
-@@ -11686,6 +11690,57 @@
+@@ -11695,6 +11699,57 @@
return(false);
}
static SHOW_VAR innodb_status_variables_export[]= {
{"Innodb", (char*) &show_innodb_vars, SHOW_FUNC},
{NullS, NullS, SHOW_LONG}
-@@ -11977,6 +12032,15 @@
+@@ -11986,6 +12041,15 @@
"Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket",
NULL, NULL, 500L, 1L, ~0L, 0);
static MYSQL_SYSVAR_LONG(file_io_threads, innobase_file_io_threads,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY | PLUGIN_VAR_NOSYSVAR,
"Number of file I/O threads in InnoDB.",
-@@ -12279,6 +12343,7 @@
+@@ -12288,6 +12352,7 @@
MYSQL_SYSVAR(fast_checksum),
MYSQL_SYSVAR(commit_concurrency),
MYSQL_SYSVAR(concurrency_tickets),
/*==============*/
--- a/storage/innobase/fil/fil0fil.c
+++ b/storage/innobase/fil/fil0fil.c
-@@ -5290,6 +5290,70 @@
+@@ -5299,6 +5299,70 @@
return(DB_SUCCESS);
}
#ifdef HAVE_LARGE_PAGES
if ((os_use_large_pages = (ibool) my_use_large_pages))
os_large_page_size = (ulint) opt_large_page_size;
-@@ -11916,6 +11920,19 @@
+@@ -11925,6 +11929,19 @@
"Limit the allocated memory for dictionary cache. (0: unlimited)",
NULL, NULL, 0, 0, LONG_MAX, 0);
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(additional_mem_pool_size),
MYSQL_SYSVAR(autoextend_increment),
-@@ -12000,6 +12017,8 @@
+@@ -12009,6 +12026,8 @@
MYSQL_SYSVAR(random_read_ahead),
MYSQL_SYSVAR(read_ahead_threshold),
MYSQL_SYSVAR(io_capacity),
}
#define OK(expr) \
-@@ -4298,6 +4299,36 @@
+@@ -4336,6 +4337,36 @@
"Hello!");
goto end_func;
}
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
-@@ -644,6 +644,14 @@
+@@ -648,6 +648,14 @@
void* message, /*!< in: message for aio handler if non-sync
aio used, else ignored */
trx_t* trx);
ut_a(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_FREE);
--- a/storage/innobase/buf/buf0buf.c
+++ b/storage/innobase/buf/buf0buf.c
-@@ -880,9 +880,9 @@
+@@ -890,9 +890,9 @@
block->page.in_zip_hash = FALSE;
block->page.in_flush_list = FALSE;
block->page.in_free_list = FALSE;
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
block->n_pointers = 0;
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
-@@ -1366,7 +1366,7 @@
+@@ -1401,7 +1401,7 @@
memcpy(dpage, bpage, sizeof *dpage);
ut_d(bpage->in_page_hash = FALSE);
/* relocate buf_pool->LRU */
-@@ -3188,8 +3188,8 @@
+@@ -3223,8 +3223,8 @@
bpage->in_zip_hash = FALSE;
bpage->in_flush_list = FALSE;
bpage->in_free_list = FALSE;
ut_d(bpage->in_page_hash = TRUE);
-@@ -3354,7 +3354,7 @@
+@@ -3389,7 +3389,7 @@
ibuf_merge_or_delete_for_page(NULL, space, offset, zip_size, TRUE);
/* Flush pages from the end of the LRU list if necessary */
trx_commit_for_mysql(trx);
}
-@@ -11122,6 +11314,12 @@
+@@ -11131,6 +11323,12 @@
"The common part for InnoDB table spaces.",
NULL, NULL, NULL);
static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
"Enable InnoDB doublewrite buffer (enabled by default). "
-@@ -11599,6 +11797,7 @@
+@@ -11608,6 +11806,7 @@
MYSQL_SYSVAR(old_blocks_pct),
MYSQL_SYSVAR(old_blocks_time),
MYSQL_SYSVAR(open_files),
#ifdef UNIV_BTR_DEBUG
ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
#endif /* UNIV_BTR_DEBUG */
-@@ -592,6 +622,19 @@
+@@ -590,6 +620,19 @@
file, line, mtr);
if (block == NULL) {
/* This must be a search to perform an insert/delete
mark/ delete; try using the insert/delete buffer */
-@@ -666,6 +709,16 @@
+@@ -664,6 +707,16 @@
block->check_index_page_at_flush = TRUE;
page = buf_block_get_frame(block);
if (rw_latch != RW_NO_LATCH) {
#ifdef UNIV_ZIP_DEBUG
const page_zip_des_t* page_zip
-@@ -872,6 +925,17 @@
+@@ -857,6 +910,17 @@
RW_NO_LATCH, NULL, BUF_GET,
file, line, mtr);
page = buf_block_get_frame(block);
ut_ad(index->id == btr_page_get_index_id(page));
block->check_index_page_at_flush = TRUE;
-@@ -992,6 +1056,14 @@
+@@ -977,6 +1041,14 @@
RW_NO_LATCH, NULL, BUF_GET,
file, line, mtr);
page = buf_block_get_frame(block);
ut_ad(index->id == btr_page_get_index_id(page));
if (height == ULINT_UNDEFINED) {
-@@ -1205,6 +1277,12 @@
+@@ -1190,6 +1262,12 @@
*big_rec = NULL;
block = btr_cur_get_block(cursor);
page = buf_block_get_frame(block);
index = cursor->index;
zip_size = buf_block_get_zip_size(block);
-@@ -2937,6 +3015,11 @@
+@@ -2922,6 +3000,11 @@
block = btr_cur_get_block(cursor);
ut_ad(page_is_leaf(buf_block_get_frame(block)));
rec = btr_cur_get_rec(cursor);
-@@ -3645,6 +3728,11 @@
+@@ -3630,6 +3713,11 @@
page = btr_cur_get_page(&cursor);
index = btr_cur_get_index(btr_pcur_get_btr_cur(cursor));
page_cursor = btr_pcur_get_page_cur(cursor);
-@@ -395,6 +401,15 @@
+@@ -397,6 +403,15 @@
cursor->latch_mode,
btr_pcur_get_btr_cur(cursor)->index, mtr);
next_page = buf_block_get_frame(next_block);
/* prototypes for new functions added to ha_innodb.cc */
trx_t* innobase_get_trx();
-@@ -1134,6 +1135,11 @@
+@@ -1151,6 +1152,11 @@
ready = buf_flush_ready_for_replace(&block->page);
mutex_exit(&block->mutex);
if (!ready) {
return(block);
-@@ -1910,6 +1916,13 @@
+@@ -1945,6 +1951,13 @@
return(NULL);
}
block_mutex = buf_page_get_mutex_enter(bpage);
rw_lock_s_unlock(&buf_pool->page_hash_latch);
-@@ -2489,6 +2502,13 @@
+@@ -2524,6 +2537,13 @@
return(NULL);
}
switch (buf_block_get_state(block)) {
buf_page_t* bpage;
ibool success;
-@@ -3163,6 +3183,7 @@
+@@ -3198,6 +3218,7 @@
bpage->newest_modification = 0;
bpage->oldest_modification = 0;
HASH_INVALIDATE(bpage, hash);
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
bpage->file_page_was_freed = FALSE;
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
-@@ -3801,6 +3822,7 @@
+@@ -3836,6 +3857,7 @@
(ulong) bpage->offset);
}
/* From version 3.23.38 up we store the page checksum
to the 4 first bytes of the page end lsn field */
-@@ -3842,6 +3864,23 @@
+@@ -3877,6 +3899,23 @@
REFMAN "forcing-innodb-recovery.html\n"
"InnoDB: about forcing recovery.\n", stderr);
if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) {
/* If page space id is larger than TRX_SYS_SPACE
(0), we will attempt to mark the corresponding
-@@ -3858,6 +3897,7 @@
+@@ -3893,6 +3932,7 @@
}
}
}
if (recv_recovery_is_on()) {
/* Pages must be uncompressed for crash recovery. */
-@@ -3867,8 +3907,11 @@
+@@ -3902,8 +3942,11 @@
if (uncompressed && !recv_no_ibuf_operations) {
ibuf_merge_or_delete_for_page(
UT_LIST_ADD_LAST(space_list, fil_system->space_list, space);
mutex_exit(&fil_system->mutex);
-@@ -5268,6 +5271,34 @@
+@@ -5277,6 +5280,34 @@
ut_a(byte_offset % OS_FILE_LOG_BLOCK_SIZE == 0);
ut_a((len % OS_FILE_LOG_BLOCK_SIZE) == 0);
#ifdef UNIV_HOTBACKUP
/* In ibbackup do normal i/o, not aio */
if (type == OS_FILE_READ) {
-@@ -5282,6 +5313,8 @@
+@@ -5291,6 +5322,8 @@
ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
offset_low, offset_high, len, node, message, trx);
#endif
ut_a(ret);
if (mode == OS_AIO_SYNC) {
-@@ -5782,3 +5815,46 @@
+@@ -5791,3 +5824,46 @@
return 0;
}
}
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time();
-@@ -5404,6 +5427,10 @@
+@@ -5403,6 +5426,10 @@
func_exit:
innobase_active_small();
DBUG_RETURN(error_result);
}
-@@ -5581,6 +5608,10 @@
+@@ -5580,6 +5607,10 @@
ha_statistic_increment(&SSV::ha_update_count);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
table->timestamp_field->set_time();
-@@ -5670,6 +5701,10 @@
+@@ -5668,6 +5699,10 @@
innobase_active_small();
DBUG_RETURN(error);
}
-@@ -5691,6 +5726,10 @@
+@@ -5689,6 +5724,10 @@
ha_statistic_increment(&SSV::ha_delete_count);
if (!prebuilt->upd_node) {
row_get_prebuilt_update_vector(prebuilt);
}
-@@ -5717,6 +5756,10 @@
+@@ -5715,6 +5754,10 @@
innobase_active_small();
DBUG_RETURN(error);
}
-@@ -5956,6 +5999,10 @@
+@@ -5954,6 +5997,10 @@
ha_statistic_increment(&SSV::ha_read_key_count);
index = prebuilt->index;
if (UNIV_UNLIKELY(index == NULL) || dict_index_is_corrupted(index)) {
-@@ -6023,6 +6070,10 @@
+@@ -6022,6 +6069,10 @@
ret = DB_UNSUPPORTED;
}
switch (ret) {
case DB_SUCCESS:
error = 0;
-@@ -6138,6 +6189,10 @@
+@@ -6137,6 +6188,10 @@
{
DBUG_ENTER("change_active_index");
ut_ad(user_thd == ha_thd());
ut_a(prebuilt->trx == thd_to_trx(user_thd));
-@@ -6251,6 +6306,10 @@
+@@ -6250,6 +6305,10 @@
DBUG_ENTER("general_fetch");
ut_a(prebuilt->trx == thd_to_trx(user_thd));
innodb_srv_conc_enter_innodb(prebuilt->trx);
-@@ -6260,6 +6319,10 @@
+@@ -6259,6 +6318,10 @@
innodb_srv_conc_exit_innodb(prebuilt->trx);
switch (ret) {
case DB_SUCCESS:
error = 0;
-@@ -7526,10 +7589,18 @@
+@@ -7525,10 +7588,18 @@
update_thd(ha_thd());
error = convert_error_code_to_mysql(error, prebuilt->table->flags,
NULL);
-@@ -8034,6 +8105,16 @@
+@@ -8040,6 +8111,16 @@
return(ranges + (double) rows / (double) total_rows * time_for_scan);
}
/*********************************************************************//**
Calculates the key number used inside MySQL for an Innobase index. We will
first check the "index translation table" for a match of the index to get
-@@ -8211,7 +8292,7 @@
+@@ -8217,7 +8298,7 @@
ib_table = prebuilt->table;
if (flag & HA_STATUS_TIME) {
/* In sql_show we call with this flag: update
then statistics so that they are up-to-date */
-@@ -8511,10 +8592,18 @@
+@@ -8517,10 +8598,18 @@
THD* thd, /*!< in: connection thread handle */
HA_CHECK_OPT* check_opt) /*!< in: currently ignored */
{
return(0);
}
-@@ -8747,6 +8836,10 @@
+@@ -8756,6 +8845,10 @@
my_error(ER_QUERY_INTERRUPTED, MYF(0));
}
DBUG_RETURN(is_ok ? HA_ADMIN_OK : HA_ADMIN_CORRUPT);
}
-@@ -9517,6 +9610,10 @@
+@@ -9526,6 +9619,10 @@
update_thd(thd);
if (prebuilt->table->ibd_file_missing && !thd_tablespace_op(thd)) {
ut_print_timestamp(stderr);
fprintf(stderr,
-@@ -11941,6 +12038,26 @@
+@@ -11990,6 +12087,26 @@
"dump file (if present). Disabled by default.",
NULL, NULL, FALSE);
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(additional_mem_pool_size),
MYSQL_SYSVAR(autoextend_increment),
-@@ -12031,6 +12148,7 @@
- MYSQL_SYSVAR(purge_threads),
- MYSQL_SYSVAR(purge_batch_size),
- MYSQL_SYSVAR(rollback_segments),
+@@ -12083,6 +12200,7 @@
+ #ifdef UNIV_DEBUG
+ MYSQL_SYSVAR(flush_checkpoint_debug),
+ #endif
+ MYSQL_SYSVAR(corrupt_table_action),
NULL
};
#ifdef UNIV_DEBUG
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
-@@ -750,6 +750,19 @@
+@@ -754,6 +754,19 @@
fil_system_hash_nodes(void);
/*========================*/
srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
srv_use_checksums = (ibool) innobase_use_checksums;
-@@ -11382,6 +11385,11 @@
+@@ -11391,6 +11394,11 @@
"The common part for InnoDB table spaces.",
NULL, NULL, NULL);
static MYSQL_SYSVAR_BOOL(recovery_update_relay_log, innobase_overwrite_relay_log_info,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
"During InnoDB crash recovery on slave overwrite relay-log.info "
-@@ -11870,6 +11878,7 @@
+@@ -11879,6 +11887,7 @@
MYSQL_SYSVAR(data_file_path),
MYSQL_SYSVAR(data_home_dir),
MYSQL_SYSVAR(doublewrite),
# should be done or reviewed by the maintainer!
--- a/storage/innobase/buf/buf0buf.c
+++ b/storage/innobase/buf/buf0buf.c
-@@ -3770,7 +3770,8 @@
+@@ -3805,7 +3805,8 @@
read_space_id = mach_read_from_4(
frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
if (err != DB_SUCCESS) {
return(err);
-@@ -4159,7 +4169,7 @@
+@@ -4168,7 +4178,7 @@
}
#ifndef UNIV_HOTBACKUP
fprintf(stderr,
"InnoDB: Error: tablespace id %lu in file %s"
" is not sensible\n",
-@@ -4168,7 +4178,7 @@
+@@ -4177,7 +4187,7 @@
goto func_exit;
}
#else
char* new_path;
fprintf(stderr,
-@@ -4989,7 +4999,7 @@
+@@ -4998,7 +5008,7 @@
}
if (node->n_pending == 0 && space->purpose == FIL_TABLESPACE
/* The node is in the LRU list, remove it */
ut_a(UT_LIST_GET_LEN(system->LRU) > 0);
-@@ -5035,7 +5045,7 @@
+@@ -5044,7 +5054,7 @@
}
if (node->n_pending == 0 && node->space->purpose == FIL_TABLESPACE
/* The node must be put back to the LRU list */
UT_LIST_ADD_FIRST(LRU, system->LRU, node);
}
-@@ -5646,7 +5656,7 @@
+@@ -5655,7 +5665,7 @@
ut_a(fil_node->n_pending == 0);
ut_a(fil_node->open);
ut_a(fil_node->space->purpose == FIL_TABLESPACE);
srv_use_sys_stats_table = (ibool) innobase_use_sys_stats_table;
/* -------------- Log files ---------------------------*/
-@@ -11763,6 +11766,11 @@
+@@ -11772,6 +11775,11 @@
"Path to individual files and their sizes.",
NULL, NULL, NULL);
static MYSQL_SYSVAR_LONG(autoinc_lock_mode, innobase_autoinc_lock_mode,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"The AUTOINC lock modes supported by InnoDB: "
-@@ -11942,6 +11950,7 @@
+@@ -11951,6 +11959,7 @@
MYSQL_SYSVAR(commit_concurrency),
MYSQL_SYSVAR(concurrency_tickets),
MYSQL_SYSVAR(data_file_path),
# should be done or reviewed by the maintainer!
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
-@@ -9701,9 +9701,8 @@
+@@ -9710,9 +9710,8 @@
rw_lock_wait_time += mutex->lspent_time;
}
#else /* UNIV_DEBUG */
buf2len= (uint) my_snprintf(buf2, sizeof(buf2), "os_waits=%lu",
(ulong) mutex->count_os_wait);
-@@ -9718,10 +9717,8 @@
+@@ -9727,10 +9726,8 @@
if (block_mutex) {
buf1len = (uint) my_snprintf(buf1, sizeof buf1,
buf2len = (uint) my_snprintf(buf2, sizeof buf2,
"os_waits=%lu",
(ulong) block_mutex_oswait_count);
-@@ -9750,9 +9747,8 @@
+@@ -9759,9 +9756,8 @@
continue;
}
buf2len = my_snprintf(buf2, sizeof buf2, "os_waits=%lu",
(ulong) lock->count_os_wait);
-@@ -9766,10 +9762,8 @@
+@@ -9775,10 +9771,8 @@
if (block_lock) {
buf1len = (uint) my_snprintf(buf1, sizeof buf1,
# should be done or reviewed by the maintainer!
--- a/storage/innobase/buf/buf0buf.c
+++ b/storage/innobase/buf/buf0buf.c
-@@ -4330,6 +4330,7 @@
+@@ -4365,6 +4365,7 @@
}
total_info->pool_size += pool_info->pool_size;
total_info->lru_len += pool_info->lru_len;
total_info->old_lru_len += pool_info->old_lru_len;
total_info->free_list_len += pool_info->free_list_len;
-@@ -4395,6 +4396,8 @@
+@@ -4430,6 +4431,8 @@
pool_info->pool_size = buf_pool->curr_size;
pool_info->lru_len = UT_LIST_GET_LEN(buf_pool->LRU);
pool_info->old_lru_len = buf_pool->LRU_old_len;
-@@ -4516,14 +4519,16 @@
+@@ -4551,14 +4554,16 @@
ut_ad(pool_info);
fprintf(file,
{"buffer_pool_pages_free",
(char*) &export_vars.innodb_buffer_pool_pages_free, SHOW_LONG},
#ifdef UNIV_DEBUG
-@@ -11199,6 +11201,16 @@
+@@ -11208,6 +11210,16 @@
"Force InnoDB to not use next-key locking, to use only row-level locking.",
NULL, NULL, FALSE);
#ifdef UNIV_LOG_ARCHIVE
static MYSQL_SYSVAR_STR(log_arch_dir, innobase_log_arch_dir,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
-@@ -11386,7 +11398,7 @@
+@@ -11395,7 +11407,7 @@
static MYSQL_SYSVAR_STR(version, innodb_version_str,
PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_READONLY,
static MYSQL_SYSVAR_BOOL(use_sys_malloc, srv_use_sys_malloc,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
-@@ -11486,6 +11498,8 @@
+@@ -11495,6 +11507,8 @@
MYSQL_SYSVAR(thread_concurrency),
MYSQL_SYSVAR(thread_sleep_delay),
MYSQL_SYSVAR(autoinc_lock_mode),
--- a/storage/innobase/ibuf/ibuf0ibuf.c
+++ b/storage/innobase/ibuf/ibuf0ibuf.c
-@@ -469,6 +469,45 @@
+@@ -478,6 +478,45 @@
}
/******************************************************************//**
Determine the flags of a table described in SYS_TABLES.
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
-@@ -11899,7 +11899,14 @@
+@@ -11908,7 +11908,14 @@
i_s_innodb_cmp,
i_s_innodb_cmp_reset,
i_s_innodb_cmpmem,
# should be done or reviewed by the maintainer!
--- a/storage/innobase/btr/btr0cur.c
+++ b/storage/innobase/btr/btr0cur.c
-@@ -4085,7 +4085,8 @@
+@@ -4070,7 +4070,8 @@
mtr_commit(mtr);
mutex_enter(&block->mutex);
/* Only free the block if it is still allocated to
-@@ -4096,16 +4097,21 @@
+@@ -4081,16 +4082,21 @@
&& buf_block_get_space(block) == space
&& buf_block_get_page_no(block) == page_no) {
UNIV_INTERN mysql_pfs_key_t flush_list_mutex_key;
#endif /* UNIV_PFS_MUTEX */
-@@ -880,9 +885,13 @@
+@@ -890,9 +895,13 @@
block->page.in_zip_hash = FALSE;
block->page.in_flush_list = FALSE;
block->page.in_free_list = FALSE;
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
block->n_pointers = 0;
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
-@@ -980,9 +989,11 @@
+@@ -997,9 +1006,11 @@
memset(block->frame, '\0', UNIV_PAGE_SIZE);
#endif
/* Add the block to the free list */
ut_ad(buf_pool_from_block(block) == buf_pool);
block++;
-@@ -1037,7 +1048,8 @@
+@@ -1054,7 +1065,8 @@
buf_chunk_t* chunk = buf_pool->chunks;
ut_ad(buf_pool);
for (n = buf_pool->n_chunks; n--; chunk++) {
buf_block_t* block = buf_chunk_contains_zip(chunk, data);
-@@ -1143,9 +1155,21 @@
+@@ -1160,9 +1172,21 @@
------------------------------- */
mutex_create(buf_pool_mutex_key,
&buf_pool->mutex, SYNC_BUF_POOL);
buf_pool_mutex_enter(buf_pool);
if (buf_pool_size > 0) {
-@@ -1158,6 +1182,8 @@
+@@ -1175,6 +1199,8 @@
mem_free(chunk);
mem_free(buf_pool);
buf_pool_mutex_exit(buf_pool);
return(DB_ERROR);
-@@ -1188,6 +1214,8 @@
+@@ -1205,6 +1231,8 @@
/* All fields are initialized by mem_zalloc(). */
buf_pool_mutex_exit(buf_pool);
return(DB_SUCCESS);
-@@ -1339,7 +1367,11 @@
+@@ -1374,7 +1402,11 @@
ulint fold;
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
ut_a(buf_page_get_io_fix(bpage) == BUF_IO_NONE);
ut_a(bpage->buf_fix_count == 0);
-@@ -1450,21 +1482,32 @@
+@@ -1485,21 +1517,32 @@
buf_page_t* bpage;
ulint i;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
for (i = 0; i < BUF_POOL_WATCH_SIZE; i++) {
bpage = &buf_pool->watch[i];
-@@ -1488,10 +1531,12 @@
+@@ -1523,10 +1566,12 @@
bpage->space = space;
bpage->offset = offset;
bpage->buf_fix_count = 1;
return(NULL);
case BUF_BLOCK_ZIP_PAGE:
ut_ad(bpage->in_page_hash);
-@@ -1509,6 +1554,8 @@
+@@ -1544,6 +1589,8 @@
ut_error;
/* Fix compiler warning */
return(NULL);
}
-@@ -1526,7 +1573,11 @@
+@@ -1561,7 +1608,11 @@
space, offset) */
buf_page_t* watch) /*!< in/out: sentinel for watch */
{
HASH_DELETE(buf_page_t, hash, buf_pool->page_hash, fold, watch);
ut_d(watch->in_page_hash = FALSE);
-@@ -1548,28 +1599,31 @@
+@@ -1583,28 +1634,31 @@
buf_pool_t* buf_pool = buf_pool_get(space, offset);
ulint fold = buf_page_address_fold(space, offset);
}
/****************************************************************//**
-@@ -1589,14 +1643,16 @@
+@@ -1624,14 +1678,16 @@
buf_pool_t* buf_pool = buf_pool_get(space, offset);
ulint fold = buf_page_address_fold(space, offset);
return(ret);
}
-@@ -1613,13 +1669,15 @@
+@@ -1648,13 +1704,15 @@
{
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
}
/********************************************************************//**
-@@ -1643,14 +1701,20 @@
+@@ -1678,14 +1736,20 @@
ut_a(buf_page_in_file(bpage));
if (buf_page_peek_if_too_old(bpage)) {
}
}
-@@ -1667,7 +1731,8 @@
+@@ -1702,7 +1766,8 @@
buf_block_t* block;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
block = (buf_block_t*) buf_page_hash_get(buf_pool, space, offset);
-@@ -1676,7 +1741,8 @@
+@@ -1711,7 +1776,8 @@
block->check_index_page_at_flush = FALSE;
}
}
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
-@@ -1696,7 +1762,8 @@
+@@ -1731,7 +1797,8 @@
buf_page_t* bpage;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
bpage = buf_page_hash_get(buf_pool, space, offset);
-@@ -1707,7 +1774,8 @@
+@@ -1742,7 +1809,8 @@
bpage->file_page_was_freed = TRUE;
}
return(bpage);
}
-@@ -1728,7 +1796,8 @@
+@@ -1763,7 +1831,8 @@
buf_page_t* bpage;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
bpage = buf_page_hash_get(buf_pool, space, offset);
-@@ -1737,7 +1806,8 @@
+@@ -1772,7 +1841,8 @@
bpage->file_page_was_freed = FALSE;
}
return(bpage);
}
-@@ -1769,8 +1839,9 @@
+@@ -1804,8 +1874,9 @@
buf_pool->stat.n_page_gets++;
for (;;) {
bpage = buf_page_hash_get(buf_pool, space, offset);
if (bpage) {
ut_ad(!buf_pool_watch_is_sentinel(buf_pool, bpage));
-@@ -1779,7 +1850,8 @@
+@@ -1814,7 +1885,8 @@
/* Page not in buf_pool: needs to be read from file */
buf_read_page(space, zip_size, offset);
-@@ -1791,10 +1863,15 @@
+@@ -1826,10 +1898,15 @@
if (UNIV_UNLIKELY(!bpage->zip.data)) {
/* There is no compressed page. */
err_exit:
ut_ad(!buf_pool_watch_is_sentinel(buf_pool, bpage));
switch (buf_page_get_state(bpage)) {
-@@ -1803,24 +1880,43 @@
+@@ -1838,24 +1915,43 @@
case BUF_BLOCK_MEMORY:
case BUF_BLOCK_REMOVE_HASH:
case BUF_BLOCK_ZIP_FREE:
buf_block_buf_fix_inc((buf_block_t*) bpage,
__FILE__, __LINE__);
goto got_block;
-@@ -1833,7 +1929,7 @@
+@@ -1868,7 +1964,7 @@
must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ;
access_time = buf_page_is_accessed(bpage);
mutex_exit(block_mutex);
-@@ -2144,7 +2240,7 @@
+@@ -2179,7 +2275,7 @@
const buf_block_t* block) /*!< in: pointer to block,
not dereferenced */
{
if (UNIV_UNLIKELY((((ulint) block) % sizeof *block) != 0)) {
/* The pointer should be aligned. */
-@@ -2180,6 +2276,7 @@
+@@ -2215,6 +2311,7 @@
ulint fix_type;
ibool must_read;
ulint retries = 0;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
ut_ad(mtr);
-@@ -2213,18 +2310,24 @@
+@@ -2248,18 +2345,24 @@
fold = buf_page_address_fold(space, offset);
loop:
block = guess;
block = guess = NULL;
} else {
ut_ad(!block->page.in_zip_hash);
-@@ -2233,12 +2336,19 @@
+@@ -2268,12 +2371,19 @@
}
if (block == NULL) {
block = NULL;
}
-@@ -2250,12 +2360,14 @@
+@@ -2285,12 +2395,14 @@
space, offset, fold);
if (UNIV_LIKELY_NULL(block)) {
if (mode == BUF_GET_IF_IN_POOL
|| mode == BUF_PEEK_IF_IN_POOL
-@@ -2308,7 +2420,8 @@
+@@ -2343,7 +2455,8 @@
/* The page is being read to buffer pool,
but we cannot wait around for the read to
complete. */
return(NULL);
}
-@@ -2318,38 +2431,49 @@
+@@ -2353,38 +2466,49 @@
ibool success;
case BUF_BLOCK_FILE_PAGE:
{
buf_page_t* hash_bpage;
-@@ -2362,35 +2486,47 @@
+@@ -2397,35 +2521,47 @@
while buf_pool->mutex was released.
Free the block that was allocated. */
buf_block_init_low(block);
block->lock_hash_val = lock_rec_hash(space, offset);
-@@ -2400,7 +2536,7 @@
+@@ -2435,7 +2571,7 @@
if (buf_page_get_state(&block->page)
== BUF_BLOCK_ZIP_PAGE) {
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
&block->page);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
ut_ad(!block->page.in_flush_list);
-@@ -2418,18 +2554,23 @@
+@@ -2453,18 +2589,23 @@
/* Insert at the front of unzip_LRU list */
buf_unzip_LRU_add_block(block, FALSE);
buf_page_free_descriptor(bpage);
/* Decompress the page and apply buffered operations
-@@ -2443,12 +2584,15 @@
+@@ -2478,12 +2619,15 @@
}
/* Unfix and unlatch the block. */
rw_lock_x_unlock(&block->lock);
break;
-@@ -2464,7 +2608,7 @@
+@@ -2499,7 +2643,7 @@
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
#if UNIV_WORD_SIZE == 4
/* On 32-bit systems, there is no padding in buf_page_t. On
other systems, Valgrind could complain about uninitialized pad
-@@ -2477,8 +2621,8 @@
+@@ -2512,8 +2656,8 @@
/* Try to evict the block from the buffer pool, to use the
insert buffer (change buffer) as much as possible. */
if (mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
/* Set the watch, as it would have
been set if the page were not in the
-@@ -2487,6 +2631,9 @@
+@@ -2522,6 +2666,9 @@
space, offset, fold);
if (UNIV_LIKELY_NULL(block)) {
/* The page entered the buffer
pool for some reason. Try to
-@@ -2494,7 +2641,7 @@
+@@ -2529,7 +2676,7 @@
goto got_block;
}
}
fprintf(stderr,
"innodb_change_buffering_debug evict %u %u\n",
(unsigned) space, (unsigned) offset);
-@@ -2516,13 +2663,14 @@
+@@ -2551,13 +2698,14 @@
ut_a(mode == BUF_GET_POSSIBLY_FREED
|| !block->page.file_page_was_freed);
#endif
if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL)) {
buf_page_set_accessed_make_young(&block->page, access_time);
-@@ -2755,9 +2903,11 @@
+@@ -2790,9 +2938,11 @@
buf_pool = buf_pool_from_block(block);
if (mode == BUF_MAKE_YOUNG && buf_page_peek_if_too_old(&block->page)) {
} else if (!buf_page_is_accessed(&block->page)) {
/* Above, we do a dirty read on purpose, to avoid
mutex contention. The field buf_page_t::access_time
-@@ -2765,9 +2915,11 @@
+@@ -2800,9 +2950,11 @@
field must be protected by mutex, however. */
ulint time_ms = ut_time_ms();
}
ut_ad(!ibuf_inside(mtr) || mode == BUF_KEEP_OLD);
-@@ -2834,18 +2986,21 @@
+@@ -2869,18 +3021,21 @@
ut_ad(mtr);
ut_ad(mtr->state == MTR_ACTIVE);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
-@@ -2935,7 +3090,10 @@
+@@ -2970,7 +3125,10 @@
buf_page_t* hash_page;
ut_ad(buf_pool == buf_pool_get(space, offset));
ut_ad(mutex_own(&(block->mutex)));
ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE);
-@@ -2964,11 +3122,14 @@
+@@ -2999,11 +3157,14 @@
if (UNIV_LIKELY(!hash_page)) {
} else if (buf_pool_watch_is_sentinel(buf_pool, hash_page)) {
/* Preserve the reference count. */
} else {
fprintf(stderr,
"InnoDB: Error: page %lu %lu already found"
-@@ -2978,7 +3139,8 @@
+@@ -3013,7 +3174,8 @@
(const void*) hash_page, (const void*) block);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
mutex_exit(&block->mutex);
buf_print();
buf_LRU_print();
buf_validate();
-@@ -3061,7 +3223,9 @@
+@@ -3096,7 +3258,9 @@
fold = buf_page_address_fold(space, offset);
watch_page = buf_page_hash_get_low(buf_pool, space, offset, fold);
if (watch_page && !buf_pool_watch_is_sentinel(buf_pool, watch_page)) {
-@@ -3070,9 +3234,15 @@
+@@ -3105,9 +3269,15 @@
err_exit:
if (block) {
mutex_enter(&block->mutex);
bpage = NULL;
goto func_exit;
-@@ -3095,6 +3265,8 @@
+@@ -3130,6 +3300,8 @@
buf_page_init(buf_pool, space, offset, fold, block);
/* The block must be put to the LRU list, to the old blocks */
buf_LRU_add_block(bpage, TRUE/* to old blocks */);
-@@ -3122,7 +3294,7 @@
+@@ -3157,7 +3329,7 @@
been added to buf_pool->LRU and
buf_pool->page_hash. */
mutex_exit(&block->mutex);
mutex_enter(&block->mutex);
block->page.zip.data = data;
-@@ -3135,13 +3307,14 @@
+@@ -3170,13 +3342,14 @@
buf_unzip_LRU_add_block(block, TRUE);
}
/* If buf_buddy_alloc() allocated storage from the LRU list,
it released and reacquired buf_pool->mutex. Thus, we must
-@@ -3157,7 +3330,10 @@
+@@ -3192,7 +3365,10 @@
/* The block was added by some other thread. */
watch_page = NULL;
bpage = NULL;
goto func_exit;
-@@ -3205,20 +3381,26 @@
+@@ -3240,20 +3416,26 @@
HASH_INSERT(buf_page_t, hash, buf_pool->page_hash, fold,
bpage);
if (mode == BUF_READ_IBUF_PAGES_ONLY) {
-@@ -3260,7 +3442,9 @@
+@@ -3295,7 +3477,9 @@
fold = buf_page_address_fold(space, offset);
block = (buf_block_t*) buf_page_hash_get_low(
buf_pool, space, offset, fold);
-@@ -3276,7 +3460,9 @@
+@@ -3311,7 +3495,9 @@
#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
/* Page can be found in buf_pool */
buf_block_free(free_block);
-@@ -3298,6 +3484,7 @@
+@@ -3333,6 +3519,7 @@
mutex_enter(&block->mutex);
buf_page_init(buf_pool, space, offset, fold, block);
/* The block must be put to the LRU list */
buf_LRU_add_block(&block->page, FALSE);
-@@ -3324,7 +3511,7 @@
+@@ -3359,7 +3546,7 @@
the reacquisition of buf_pool->mutex. We also must
defer this operation until after the block descriptor
has been added to buf_pool->LRU and buf_pool->page_hash. */
mutex_enter(&block->mutex);
block->page.zip.data = data;
-@@ -3342,7 +3529,8 @@
+@@ -3377,7 +3564,8 @@
buf_page_set_accessed(&block->page, time_ms);
mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
-@@ -3397,7 +3585,9 @@
+@@ -3432,7 +3620,9 @@
ibool ret = TRUE;
/* First unfix and release lock on the bpage */
mutex_enter(buf_page_get_mutex(bpage));
ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_READ);
ut_ad(bpage->buf_fix_count == 0);
-@@ -3418,11 +3608,15 @@
+@@ -3453,11 +3643,15 @@
ret = FALSE;
}
return(ret);
}
-@@ -3440,6 +3634,8 @@
+@@ -3475,6 +3669,8 @@
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
const ibool uncompressed = (buf_page_get_state(bpage)
== BUF_BLOCK_FILE_PAGE);
ut_a(buf_page_in_file(bpage));
-@@ -3582,8 +3778,26 @@
+@@ -3617,8 +3813,26 @@
}
}
#ifdef UNIV_IBUF_COUNT_DEBUG
if (io_type == BUF_IO_WRITE || uncompressed) {
-@@ -3606,6 +3820,7 @@
+@@ -3641,6 +3855,7 @@
the x-latch to this OS thread: do not let this confuse you in
debugging! */
ut_ad(buf_pool->n_pend_reads > 0);
buf_pool->n_pend_reads--;
buf_pool->stat.n_pages_read++;
-@@ -3623,6 +3838,9 @@
+@@ -3658,6 +3873,9 @@
buf_flush_write_complete(bpage);
if (uncompressed) {
rw_lock_s_unlock_gen(&((buf_block_t*) bpage)->lock,
BUF_IO_WRITE);
-@@ -3645,8 +3863,8 @@
+@@ -3680,8 +3898,8 @@
}
#endif /* UNIV_DEBUG */
}
/*********************************************************************//**
-@@ -3663,7 +3881,9 @@
+@@ -3698,7 +3916,9 @@
ut_ad(buf_pool);
chunk = buf_pool->chunks;
-@@ -3680,7 +3900,9 @@
+@@ -3715,7 +3935,9 @@
}
}
return(TRUE);
}
-@@ -3728,7 +3950,8 @@
+@@ -3763,7 +3985,8 @@
freed = buf_LRU_search_and_free_block(buf_pool, 100);
}
ut_ad(UT_LIST_GET_LEN(buf_pool->LRU) == 0);
ut_ad(UT_LIST_GET_LEN(buf_pool->unzip_LRU) == 0);
-@@ -3741,7 +3964,8 @@
+@@ -3776,7 +3999,8 @@
memset(&buf_pool->stat, 0x00, sizeof(buf_pool->stat));
buf_refresh_io_stats(buf_pool);
}
/*********************************************************************//**
-@@ -3783,7 +4007,10 @@
+@@ -3818,7 +4042,10 @@
ut_ad(buf_pool);
chunk = buf_pool->chunks;
-@@ -3878,7 +4105,7 @@
+@@ -3913,7 +4140,7 @@
/* Check clean compressed-only blocks. */
for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
switch (buf_page_get_io_fix(b)) {
case BUF_IO_NONE:
-@@ -3909,7 +4136,7 @@
+@@ -3944,7 +4171,7 @@
buf_flush_list_mutex_enter(buf_pool);
for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
ut_ad(b->in_flush_list);
ut_a(b->oldest_modification);
n_flush++;
-@@ -3968,6 +4195,8 @@
+@@ -4003,6 +4230,8 @@
}
ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == n_lru);
if (UT_LIST_GET_LEN(buf_pool->free) != n_free) {
fprintf(stderr, "Free list len %lu, free blocks %lu\n",
(ulong) UT_LIST_GET_LEN(buf_pool->free),
-@@ -3978,8 +4207,11 @@
+@@ -4013,8 +4242,11 @@
ut_a(buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE] == n_single_flush);
ut_a(buf_pool->n_flush[BUF_FLUSH_LIST] == n_list_flush);
ut_a(buf_pool->n_flush[BUF_FLUSH_LRU] == n_lru_flush);
ut_a(buf_LRU_validate());
ut_a(buf_flush_validate(buf_pool));
-@@ -4035,7 +4267,9 @@
+@@ -4070,7 +4302,9 @@
index_ids = mem_alloc(size * sizeof *index_ids);
counts = mem_alloc(sizeof(ulint) * size);
buf_flush_list_mutex_enter(buf_pool);
fprintf(stderr,
-@@ -4104,7 +4338,9 @@
+@@ -4139,7 +4373,9 @@
}
}
for (i = 0; i < n_found; i++) {
index = dict_index_get_if_in_cache(index_ids[i]);
-@@ -4161,7 +4397,7 @@
+@@ -4196,7 +4432,7 @@
buf_chunk_t* chunk;
ulint fixed_pages_number = 0;
chunk = buf_pool->chunks;
-@@ -4195,7 +4431,7 @@
+@@ -4230,7 +4466,7 @@
/* Traverse the lists of clean and dirty compressed-only blocks. */
for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
ut_a(buf_page_get_state(b) == BUF_BLOCK_ZIP_PAGE);
ut_a(buf_page_get_io_fix(b) != BUF_IO_WRITE);
-@@ -4207,7 +4443,7 @@
+@@ -4242,7 +4478,7 @@
buf_flush_list_mutex_enter(buf_pool);
for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
ut_ad(b->in_flush_list);
switch (buf_page_get_state(b)) {
-@@ -4233,7 +4469,7 @@
+@@ -4268,7 +4504,7 @@
buf_flush_list_mutex_exit(buf_pool);
mutex_exit(&buf_pool->zip_mutex);
return(fixed_pages_number);
}
-@@ -4391,6 +4627,8 @@
+@@ -4426,6 +4662,8 @@
/* Find appropriate pool_info to store stats for this buffer pool */
pool_info = &all_pool_info[pool_id];
buf_pool_mutex_enter(buf_pool);
buf_flush_list_mutex_enter(buf_pool);
-@@ -4506,6 +4744,8 @@
+@@ -4541,6 +4779,8 @@
pool_info->unzip_cur = buf_LRU_stat_cur.unzip;
buf_refresh_io_stats(buf_pool);
buf_pool_mutex_exit(buf_pool);
}
-@@ -4750,11 +4990,13 @@
+@@ -4785,11 +5025,13 @@
{
ulint len;
ut_ad(buf_flush_ready_for_flush(bpage, flush_type));
buf_page_set_io_fix(bpage, BUF_IO_WRITE);
-@@ -1429,14 +1439,16 @@
+@@ -1457,14 +1467,16 @@
buf_pool = buf_pool_get(space, i);
- buf_pool_mutex_exit(buf_pool);
+ //buf_pool_mutex_exit(buf_pool);
+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
- continue;
- }
+ if (srv_flush_neighbor_pages == 2) {
-@@ -1448,11 +1460,9 @@
+ /* This is contiguous neighbor page flush and
+@@ -1482,11 +1494,9 @@
if (flush_type != BUF_FLUSH_LRU
|| i == offset
|| buf_page_is_old(bpage)) {
&& (i == offset || !bpage->buf_fix_count)) {
/* We only try to flush those
neighbors != offset where the buf fix
-@@ -1468,11 +1478,12 @@
+@@ -1502,11 +1512,12 @@
ut_ad(!buf_pool_mutex_own(buf_pool));
count++;
continue;
- buf_pool_mutex_exit(buf_pool);
+ //buf_pool_mutex_exit(buf_pool);
+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
- }
- return(count);
-@@ -1505,21 +1516,25 @@
+ if (srv_flush_neigbor_pages == 2) {
+
+@@ -1555,21 +1566,25 @@
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
#endif /* UNIV_DEBUG */
/* These fields are protected by both the
buffer pool mutex and block mutex. */
-@@ -1535,13 +1550,18 @@
+@@ -1585,13 +1600,18 @@
*count,
n_to_flush);
return(flushed);
}
-@@ -1562,7 +1582,8 @@
+@@ -1612,7 +1632,8 @@
buf_page_t* bpage;
ulint count = 0;
do {
/* Start from the end of the list looking for a
-@@ -1584,7 +1605,8 @@
+@@ -1634,7 +1655,8 @@
should be flushed, we factor in this value. */
buf_lru_flush_page_count += count;
return(count);
}
-@@ -1612,9 +1634,10 @@
+@@ -1662,9 +1684,10 @@
{
ulint len;
buf_page_t* bpage;
/* If we have flushed enough, leave the loop */
do {
-@@ -1633,6 +1656,7 @@
+@@ -1683,6 +1706,7 @@
if (bpage) {
ut_a(bpage->oldest_modification > 0);
}
if (!bpage || bpage->oldest_modification >= lsn_limit) {
-@@ -1674,9 +1698,17 @@
+@@ -1724,9 +1748,17 @@
break;
}
buf_flush_list_mutex_exit(buf_pool);
-@@ -1685,7 +1717,7 @@
+@@ -1735,7 +1767,7 @@
} while (count < min_n && bpage != NULL && len > 0);
return(count);
}
-@@ -1724,13 +1756,15 @@
+@@ -1774,13 +1806,15 @@
|| sync_thread_levels_empty_except_dict());
#endif /* UNIV_SYNC_DEBUG */
break;
case BUF_FLUSH_LIST:
count = buf_flush_flush_list_batch(buf_pool, min_n, lsn_limit);
-@@ -1739,7 +1773,7 @@
+@@ -1789,7 +1823,7 @@
ut_error;
}
buf_flush_buffered_writes();
-@@ -1995,7 +2029,7 @@
+@@ -2045,7 +2079,7 @@
retry:
//buf_pool_mutex_enter(buf_pool);
if (have_LRU_mutex)
n_replaceable = UT_LIST_GET_LEN(buf_pool->free);
-@@ -2012,15 +2046,15 @@
+@@ -2062,15 +2096,15 @@
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
continue;
}
distance++;
-@@ -2029,7 +2063,7 @@
+@@ -2079,7 +2113,7 @@
//buf_pool_mutex_exit(buf_pool);
if (have_LRU_mutex)
if (n_replaceable >= BUF_FLUSH_FREE_BLOCK_MARGIN(buf_pool)) {
-@@ -2228,7 +2262,7 @@
+@@ -2278,7 +2312,7 @@
ut_ad(buf_flush_list_mutex_own(buf_pool));
ut_ad(ut_list_node_313->in_flush_list));
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
-@@ -2268,7 +2302,7 @@
+@@ -2318,7 +2352,7 @@
rnode = rbt_next(buf_pool->flush_rbt, rnode);
}
break;
--- a/storage/innobase/ibuf/ibuf0ibuf.c
+++ b/storage/innobase/ibuf/ibuf0ibuf.c
-@@ -3821,9 +3821,11 @@
+@@ -3760,9 +3760,11 @@
ulint fold = buf_page_address_fold(space, page_no);
buf_pool_t* buf_pool = buf_pool_get(space, page_no);
}
if (node->state == INDEX_CREATE_INDEX_TREE) {
-@@ -1177,6 +1316,66 @@
- return(NULL);
- }
+@@ -1183,6 +1322,66 @@
+ }
-+ thr->run_node = que_node_get_parent(node);
-+
-+ return(thr);
-+}
-+
-+/****************************************************************//**
+ /****************************************************************//**
+*/
+UNIV_INTERN
+que_thr_t*
+ return(NULL);
+ }
+
- thr->run_node = que_node_get_parent(node);
-
- return(thr);
++ thr->run_node = que_node_get_parent(node);
++
++ return(thr);
++}
++
++/****************************************************************//**
+ Creates the foreign key constraints system tables inside InnoDB
+ at database creation or database start if they are not found or are
+ not of the right form.
--- a/storage/innobase/dict/dict0dict.c
+++ b/storage/innobase/dict/dict0dict.c
@@ -755,7 +755,7 @@
/* Handle duplicate key errors */
if (auto_inc_used) {
ulint err;
-@@ -5593,6 +5600,10 @@
+@@ -5591,6 +5598,10 @@
}
}
innodb_srv_conc_exit_innodb(trx);
error = convert_error_code_to_mysql(error,
-@@ -5646,6 +5657,10 @@
+@@ -5644,6 +5655,10 @@
error = row_update_for_mysql((byte*) record, prebuilt);
innodb_srv_conc_exit_innodb(trx);
error = convert_error_code_to_mysql(
-@@ -5966,6 +5981,11 @@
+@@ -5965,6 +5980,11 @@
case DB_SUCCESS:
error = 0;
table->status = 0;
break;
case DB_RECORD_NOT_FOUND:
error = HA_ERR_KEY_NOT_FOUND;
-@@ -6198,6 +6218,11 @@
+@@ -6197,6 +6217,11 @@
case DB_SUCCESS:
error = 0;
table->status = 0;
break;
case DB_RECORD_NOT_FOUND:
error = HA_ERR_END_OF_FILE;
-@@ -8144,11 +8169,35 @@
+@@ -8150,11 +8175,35 @@
/* In sql_show we call with this flag: update
then statistics so that they are up-to-date */
prebuilt->trx->op_info = "returning various info to MySQL";
}
-@@ -8233,7 +8282,7 @@
+@@ -8239,7 +8288,7 @@
are asked by MySQL to avoid locking. Another reason to
avoid the call is that it uses quite a lot of CPU.
See Bug#38185. */
|| !(flag & HA_STATUS_VARIABLE_EXTRA)) {
/* We do not update delete_length if no
locking is requested so the "old" value can
-@@ -11503,6 +11552,26 @@
+@@ -11512,6 +11561,26 @@
"The number of index pages to sample when calculating statistics (default 8)",
NULL, NULL, 8, 1, ~0ULL, 0);
static MYSQL_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled,
PLUGIN_VAR_OPCMDARG,
"Enable InnoDB adaptive hash index (enabled by default). "
-@@ -11835,6 +11904,9 @@
+@@ -11844,6 +11913,9 @@
MYSQL_SYSVAR(recovery_update_relay_log),
MYSQL_SYSVAR(rollback_on_timeout),
MYSQL_SYSVAR(stats_on_metadata),
MYSQL_SYSVAR(stats_sample_pages),
MYSQL_SYSVAR(adaptive_hash_index),
MYSQL_SYSVAR(stats_method),
-@@ -11906,7 +11978,10 @@
+@@ -11915,7 +11987,10 @@
i_s_innodb_sys_columns,
i_s_innodb_sys_fields,
i_s_innodb_sys_foreign,
static ST_FIELD_INFO i_s_innodb_rseg_fields_info[] =
@@ -3677,3 +3897,349 @@
/* unsigned long */
- STRUCT_FLD(flags, 0UL)
+ STRUCT_FLD(flags, 0UL),
};
+
+/***********************************************************************
#ifdef UNIV_LOG_ARCHIVE
srv_log_archive_on = (ulint) innobase_log_archive;
#endif /* UNIV_LOG_ARCHIVE */
-@@ -11593,6 +11597,12 @@
+@@ -11602,6 +11606,12 @@
"Maximum delay between polling for a spin lock (6 by default)",
NULL, NULL, 6L, 0L, ~0L, 0);
static MYSQL_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
PLUGIN_VAR_RQCMDARG,
"Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.",
-@@ -11811,6 +11821,7 @@
+@@ -11820,6 +11830,7 @@
MYSQL_SYSVAR(spin_wait_delay),
MYSQL_SYSVAR(table_locks),
MYSQL_SYSVAR(thread_concurrency),
using my_pthread_setspecific_ptr()/my_thread_getspecific_ptr().
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
-@@ -4931,7 +4931,7 @@
+@@ -5024,7 +5024,7 @@
ER_BINLOG_UNSAFE_STATEMENT,
ER(ER_BINLOG_UNSAFE_STATEMENT),
ER(LEX::binlog_stmt_unsafe_errcode[unsafe_type]));
sprintf(buf, ER(ER_BINLOG_UNSAFE_STATEMENT),
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
-@@ -90,6 +90,7 @@
+@@ -87,6 +87,7 @@
SLOG_F_TMP_TABLE, SLOG_F_TMP_DISK, SLOG_F_FILESORT,
SLOG_F_FILESORT_DISK
};
SLAVE_EXEC_MODE_LAST_BIT};
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
-@@ -1493,6 +1493,15 @@
+@@ -1499,6 +1499,15 @@
READ_ONLY GLOBAL_VAR(mysqld_port), CMD_LINE(REQUIRED_ARG, 'P'),
VALID_RANGE(0, UINT_MAX32), DEFAULT(0), BLOCK_SIZE(1));
--long-query-time=# Log all queries that have taken more than long_query_time
seconds to execute to file. The argument will be treated
as a decimal value with microsecond precision
-@@ -863,6 +866,7 @@
+@@ -865,6 +868,7 @@
log-tc tc.log
log-tc-size 24576
log-warnings 1
+2
+DROP FUNCTION f1;
+DROP TABLE t1;
-+SET default_storage_engine=@old_default_storage_engine;
+SET @old_max_heap_table_size = @@global.max_heap_table_size;
+SET @old_max_allowed_packet = @@global.max_allowed_packet;
+SET GLOBAL max_heap_table_size = 18 * 1024 * 1024;
+SET GLOBAL max_allowed_packet = 24 * 1024 * 1024;
+drop table if exists t1;
-+CREATE TABLE t1 (data LONGBLOB) ENGINE=memory;
++CREATE TABLE t1 (data LONGBLOB);
+INSERT INTO t1 (data) VALUES (NULL);
+UPDATE t1 set data=repeat('a',18*1024*1024);
+select length(data) from t1;
+length(data)
+0
+drop table t1;
-+CREATE TABLE t1 (data BLOB) ENGINE=myisam;
++CREATE TABLE t1 (data BLOB);
+INSERT INTO t1 (data) VALUES (NULL);
+UPDATE t1 set data=repeat('a',18*1024*1024);
+Warnings:
+drop table t1;
+SET GLOBAL max_allowed_packet = @old_max_allowed_packet;
+SET GLOBAL max_heap_table_size = @old_max_heap_table_size;
++SET default_storage_engine=@old_default_storage_engine;
--- /dev/null
+++ b/mysql-test/r/percona_heap_bug783366.result
@@ -0,0 +1,14 @@
+
+
+
-+SET default_storage_engine=@old_default_storage_engine;
+
+
+########################################################################
+
+# Bug #2159 (Problem with update of blob to > 16M)
+
-+CREATE TABLE t1 (data LONGBLOB) ENGINE=memory;
++CREATE TABLE t1 (data LONGBLOB);
+INSERT INTO t1 (data) VALUES (NULL);
+UPDATE t1 set data=repeat('a',18*1024*1024);
+select length(data) from t1;
+select length(data) from t1;
+drop table t1;
+
-+CREATE TABLE t1 (data BLOB) ENGINE=myisam;
++CREATE TABLE t1 (data BLOB);
+INSERT INTO t1 (data) VALUES (NULL);
+UPDATE t1 set data=repeat('a',18*1024*1024);
+select length(data) from t1;
+
+SET GLOBAL max_allowed_packet = @old_max_allowed_packet;
+SET GLOBAL max_heap_table_size = @old_max_heap_table_size;
++SET default_storage_engine=@old_default_storage_engine;
--- /dev/null
+++ b/mysql-test/t/percona_heap_bug783366.test
@@ -0,0 +1,19 @@
Summary(uk.UTF-8): MySQL - швидкий SQL-сервер
Summary(zh_CN.UTF-8): MySQL数据库服务器
Name: mysql
-Version: 5.5.18
+Version: 5.5.19
Release: 1
License: GPL + MySQL FLOSS Exception
Group: Applications/Databases
# Source0Download: http://dev.mysql.com/downloads/mysql/5.5.html#downloads
Source0: http://vesta.informatik.rwth-aachen.de/mysql/Downloads/MySQL-5.5/%{name}-%{version}.tar.gz
-# Source0-md5: 38b65815249f3bcacf3b0ee85171c486
+# Source0-md5: a78cf450974e9202bd43674860349b5a
Source100: http://www.sphinxsearch.com/files/sphinx-2.0.1-beta.tar.gz
# Source100-md5: 95c217d81d0b7a4ff73d5297318c3481
Source1: %{name}.init
DBUG_RETURN(HA_POS_ERROR); /* This shouldn't happend */
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
-@@ -2180,6 +2180,12 @@
+@@ -2186,6 +2186,12 @@
VALID_RANGE(1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT)),
DEFAULT(NET_WAIT_TIMEOUT), BLOCK_SIZE(1));
# should be done or reviewed by the maintainer!
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
-@@ -2326,6 +2326,7 @@
+@@ -2419,6 +2419,7 @@
thd->sent_row_count++;
thd->sent_row_count_2++;
#ifdef EMBEDDED_LIBRARY
#include "emb_qcache.h"
#endif
-@@ -454,7 +939,12 @@
+@@ -454,7 +944,12 @@
Query_cache_wait_state wait_state(thd, __func__, __FILE__, __LINE__);
DBUG_ENTER("Query_cache::try_lock");
while (1)
{
if (m_cache_lock_status == Query_cache::UNLOCKED)
-@@ -1274,6 +1764,8 @@
+@@ -1274,6 +1769,8 @@
unlock();
DBUG_VOID_RETURN;
}
/* Key is query + database + flag */
if (thd->db_length)
-@@ -1440,7 +1932,7 @@
+@@ -1440,7 +1937,7 @@
*/
int
{
ulonglong engine_data;
Query_cache_query *query;
-@@ -1452,6 +1944,11 @@
+@@ -1452,6 +1949,11 @@
ulong tot_length;
Query_cache_query_flags flags;
DBUG_ENTER("Query_cache::send_result_to_client");
/*
Testing 'query_cache_size' without a lock here is safe: the thing
-@@ -1471,13 +1968,7 @@
+@@ -1471,13 +1973,7 @@
}
{
/*
Test if the query is a SELECT
-@@ -1487,10 +1978,11 @@
+@@ -1487,10 +1983,11 @@
frequently appeared in real life, consequently we can
check all such queries, too.
*/
{
DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached"));
goto err;
-@@ -1543,6 +2035,7 @@
+@@ -1543,6 +2040,7 @@
goto err_unlock;
Query_cache_block *query_block;
tot_length= query_length + 1 + sizeof(size_t) +
thd->db_length + QUERY_CACHE_FLAGS_SIZE;
-@@ -1611,6 +2104,7 @@
+@@ -1611,6 +2109,7 @@
(uchar*) &flags, QUERY_CACHE_FLAGS_SIZE);
query_block = (Query_cache_block *) my_hash_search(&queries, (uchar*) sql,
tot_length);
query_block->query()->result() == 0 ||
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
-@@ -1487,6 +1487,74 @@
+@@ -1485,6 +1485,74 @@
extern "C" void my_message_sql(uint error, const char *str, myf MyFlags);
/**
@class THD
For each client connection we create a separate thread with THD serving as
-@@ -1544,6 +1612,7 @@
+@@ -1542,6 +1610,7 @@
struct st_mysql_stmt *current_stmt;
#endif
#ifdef HAVE_QUERY_CACHE
NET net; // client connection descriptor
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
-@@ -1809,6 +1809,11 @@
+@@ -1815,6 +1815,11 @@
NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
ON_UPDATE(fix_query_cache_size));
+SET GLOBAL query_cache_size=0;
--- a/mysql-test/r/mysqld--help-notwin.result
+++ b/mysql-test/r/mysqld--help-notwin.result
-@@ -491,6 +491,10 @@
+@@ -493,6 +493,10 @@
The minimum size for blocks allocated by the query cache
--query-cache-size=#
The memory allocated to store results from old queries
--query-cache-type=name
OFF = Don't cache or retrieve results. ON = Cache all
results except SELECT SQL_NO_CACHE ... queries. DEMAND =
-@@ -928,6 +932,7 @@
+@@ -931,6 +935,7 @@
query-cache-limit 1048576
query-cache-min-res-unit 4096
query-cache-size 0
/*
This forward declaration is needed because including sql_base.h
causes further includes. [TODO] Eliminate this forward declaration
-@@ -1860,6 +1861,26 @@
+@@ -1866,6 +1867,26 @@
DEFAULT(FALSE));
#endif /* HAVE_QUERY_CACHE */
/*
--- a/mysql-test/r/mysqld--help-notwin.result
+++ b/mysql-test/r/mysqld--help-notwin.result
-@@ -503,6 +503,12 @@
+@@ -505,6 +505,12 @@
Invalidate queries in query cache on LOCK for write
--query-prealloc-size=#
Persistent buffer for query parsing and execution
--range-alloc-block-size=#
Allocation block size for storing ranges during
optimization
-@@ -936,6 +942,8 @@
+@@ -939,6 +945,8 @@
query-cache-type ON
query-cache-wlock-invalidate FALSE
query-prealloc-size 8192
#endif
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
-@@ -1004,6 +1004,11 @@
+@@ -1002,6 +1002,11 @@
XXX Why are internal temporary tables added to this list?
*/
TABLE *temporary_tables;
const char *user_host, uint user_host_len,
ulonglong query_utime, ulonglong lock_utime, bool is_command,
const char *sql_text, uint sql_text_len);
-@@ -515,7 +515,7 @@
+@@ -517,7 +517,7 @@
virtual bool init()= 0;
virtual void cleanup()= 0;
time_t query_start_arg, const char *user_host,
uint user_host_len, ulonglong query_utime,
ulonglong lock_utime, bool is_command,
-@@ -544,7 +544,7 @@
+@@ -546,7 +546,7 @@
virtual bool init();
virtual void cleanup();
time_t query_start_arg, const char *user_host,
uint user_host_len, ulonglong query_utime,
ulonglong lock_utime, bool is_command,
-@@ -576,7 +576,7 @@
+@@ -578,7 +578,7 @@
virtual bool init();
virtual void cleanup();
mysql_mutex_lock(&LOCK_thread_count);
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
-@@ -2152,7 +2152,7 @@
+@@ -2164,7 +2164,7 @@
DBUG_PRINT("info",(" %.*s: eval args done", (int) m_name.length,
m_name.str));
}
save_enable_slow_log= true;
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
-@@ -1756,6 +1756,7 @@
+@@ -1780,6 +1780,7 @@
response, we can't handle it anyway.
*/
(void) trans_commit_stmt(thd);
if (!thd->stmt_da->is_set())
thd->stmt_da->disable_status();
-@@ -1766,6 +1767,7 @@
+@@ -1790,6 +1791,7 @@
err_unlock:
unlock();
err:
enum enum_slave_exec_mode { SLAVE_EXEC_MODE_STRICT,
SLAVE_EXEC_MODE_IDEMPOTENT,
SLAVE_EXEC_MODE_LAST_BIT};
-@@ -508,6 +535,21 @@
+@@ -506,6 +533,21 @@
my_bool sysdate_is_now;
double long_query_time_double;
} SV;
-@@ -1140,6 +1182,24 @@
+@@ -1138,6 +1180,24 @@
uint in_sub_stmt;
bool enable_slow_log;
bool last_insert_id_used;
SAVEPOINT *savepoints;
enum enum_check_fields count_cuted_fields;
};
-@@ -1588,6 +1648,71 @@
+@@ -1586,6 +1646,71 @@
thr_lock_type update_lock_default;
Delayed_insert *di;
const char *any_db="*any*"; // Special symbol for check_access
-@@ -888,6 +889,7 @@
+@@ -890,6 +891,7 @@
the slow log only if opt_log_slow_admin_statements is set.
*/
thd->enable_slow_log= TRUE;
thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
thd->set_time();
if (!thd->is_valid_time())
-@@ -1430,6 +1432,60 @@
+@@ -1440,6 +1442,60 @@
DBUG_RETURN(error);
}
void log_slow_statement(THD *thd)
{
-@@ -1443,13 +1499,48 @@
+@@ -1453,13 +1509,48 @@
if (unlikely(thd->in_sub_stmt))
DBUG_VOID_RETURN; // Don't set time for sub stmt
thd_proc_info(thd, "logging slow query");
if (((thd->server_status & SERVER_QUERY_WAS_SLOW) ||
-@@ -5301,7 +5392,8 @@
+@@ -5368,7 +5459,8 @@
thd->stmt_da->reset_diagnostics_area();
thd->warning_info->reset_for_next_command();
thd->rand_used= 0;
thd->binlog_unsafe_warning_flags= 0;
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
-@@ -6902,7 +6902,10 @@
+@@ -6912,7 +6912,10 @@
{
join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
if (statistics)
}
}
else
-@@ -6916,7 +6919,10 @@
+@@ -6926,7 +6929,10 @@
{
join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
if (statistics)
}
}
if (!table->no_keyread)
-@@ -10264,6 +10270,7 @@
+@@ -10274,6 +10280,7 @@
(ulong) rows_limit,test(group)));
status_var_increment(thd->status_var.created_tmp_tables);
if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
temp_pool_slot = bitmap_lock_set_next(&temp_pool);
-@@ -11162,6 +11169,7 @@
+@@ -11175,6 +11182,7 @@
goto err;
}
status_var_increment(table->in_use->status_var.created_tmp_disk_tables);
share->db_record_offset= 1;
DBUG_RETURN(0);
err:
-@@ -11180,6 +11188,14 @@
+@@ -11193,6 +11201,14 @@
save_proc_info=thd->proc_info;
thd_proc_info(thd, "removing tmp table");
static bool fix_low_prio_updates(sys_var *self, THD *thd, enum_var_type type)
{
if (type == OPT_SESSION)
-@@ -2898,6 +2921,123 @@
+@@ -2904,6 +2927,123 @@
DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
ON_UPDATE(fix_log_state));
CHECK_SPACE(pos, end, 1);
--- a/sql/log_event.h
+++ b/sql/log_event.h
-@@ -342,6 +342,10 @@
+@@ -343,6 +343,10 @@
#define Q_INVOKER 11
--log-tc=name Path to transaction coordinator log (used for
transactions that affect more than one storage engine,
when binary log is disabled).
-@@ -660,6 +676,18 @@
+@@ -662,6 +678,18 @@
Log slow queries to given log file. Defaults logging to
hostname-slow.log. Must be enabled to activate other slow
log options
--socket=name Socket file to use for connection
--sort-buffer-size=#
Each thread that needs to do a sort allocates a buffer of
-@@ -817,7 +845,11 @@
+@@ -819,7 +847,11 @@
log-short-format FALSE
log-slave-updates FALSE
log-slow-admin-statements FALSE
log-tc tc.log
log-tc-size 24576
log-warnings 1
-@@ -933,6 +965,9 @@
+@@ -936,6 +968,9 @@
slave-type-conversions
slow-launch-time 2
slow-query-log FALSE
+ my ($time) = @_;
+ my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($time);
+ open(SUBUNITOUT, ">>$SUBUNIT_OUT");
-+ printf SUBUNITOUT "time: %04d-%02d-%02d %02d:%02d:%02dZ\n", $year+1900, $mon, $mday, $hour, $min, $sec;
++ printf SUBUNITOUT "time: %04d-%02d-%02d %02d:%02d:%02dZ\n", $year+1900, ($mon+1), $mday, $hour, $min, $sec;
+ close(SUBUNITOUT);
+ return;
+}
require "lib/mtr_process.pl";
require "lib/mtr_io.pl";
-@@ -630,6 +631,7 @@
+@@ -291,6 +292,7 @@
+ my $opt_valgrind_path;
+ my $valgrind_reports= 0;
+ my $opt_callgrind;
++my $opt_helgrind;
+ my %mysqld_logs;
+ my $opt_debug_sync_timeout= 300; # Default timeout for WAIT_FOR actions.
+
+@@ -630,6 +632,7 @@
# Report test status
mtr_report_test($result);
if ( $result->is_failed() ) {
+@@ -1142,6 +1145,7 @@
+ 'valgrind-option=s' => \@valgrind_args,
+ 'valgrind-path=s' => \$opt_valgrind_path,
+ 'callgrind' => \$opt_callgrind,
++ 'helgrind' => \$opt_helgrind,
+ 'debug-sync-timeout=i' => \$opt_debug_sync_timeout,
+
+ # Directories
+@@ -1703,11 +1707,18 @@
+ unless @valgrind_args;
+ }
+
++ if ( $opt_helgrind )
++ {
++ mtr_report("Turning on valgrind with helgrind for mysqld(s)");
++ $opt_valgrind= 1;
++ $opt_valgrind_mysqld= 1;
++ }
++
+ if ( $opt_valgrind )
+ {
+ # Set valgrind_options to default unless already defined
+ push(@valgrind_args, @default_valgrind_args)
+- unless @valgrind_args;
++ unless @valgrind_args || $opt_helgrind;
+
+ # Don't add --quiet; you will loose the summary reports.
+
+@@ -5796,6 +5807,10 @@
+ mtr_add_arg($args, "--tool=callgrind");
+ mtr_add_arg($args, "--base=$opt_vardir/log");
+ }
++ elsif ( $opt_helgrind )
++ {
++ mtr_add_arg($args, "--tool=helgrind");
++ }
+ else
+ {
+ mtr_add_arg($args, "--tool=memcheck"); # From >= 2.1.2 needs this option
/*
Log error with all enabled log event handlers
-@@ -5029,6 +5036,8 @@
+@@ -5026,6 +5033,8 @@
thd->first_successful_insert_id_in_prev_stmt_for_binlog);
if (e.write(file))
goto err;
}
if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
{
-@@ -5040,12 +5049,16 @@
+@@ -5037,12 +5046,16 @@
minimum());
if (e.write(file))
goto err;
}
if (thd->user_var_events.elements)
{
-@@ -5068,6 +5081,8 @@
+@@ -5065,6 +5078,8 @@
flags);
if (e.write(file))
goto err;
}
}
}
-@@ -5079,6 +5094,8 @@
+@@ -5076,6 +5091,8 @@
if (event_info->write(file) ||
DBUG_EVALUATE_IF("injecting_fault_writing", 1, 0))
goto err;
error= 0;
err:
-@@ -5264,7 +5281,8 @@
+@@ -5310,7 +5327,8 @@
be reset as a READ_CACHE to be able to read the contents from it.
*/
{
Mutex_sentry sentry(lock_log ? &LOCK_log : NULL);
-@@ -5311,6 +5329,7 @@
+@@ -5357,6 +5375,7 @@
/* write the first half of the split header */
if (my_b_write(&log_file, header, carry))
return ER_ERROR_ON_WRITE;
/*
copy fixed second half of header to cache so the correct
-@@ -5379,6 +5398,7 @@
+@@ -5425,6 +5444,7 @@
/* Write data to the binary log file */
if (my_b_write(&log_file, cache->read_pos, length))
return ER_ERROR_ON_WRITE;
cache->read_pos=cache->read_end; // Mark buffer used up
} while ((length= my_b_fill(cache)));
-@@ -5493,20 +5513,23 @@
+@@ -5548,20 +5568,23 @@
Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, FALSE, TRUE, 0);
if (qinfo.write(&log_file))
goto err;
void set_write_error(THD *thd, bool is_transactional);
bool check_write_error(THD *thd);
-@@ -589,6 +590,7 @@
+@@ -591,6 +592,7 @@
const char *sql_text, uint sql_text_len,
CHARSET_INFO *client_cs);
void flush();
if (delete_table)
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
-@@ -885,6 +885,13 @@
+@@ -978,6 +978,13 @@
mysys_var=0;
binlog_evt_union.do_union= FALSE;
enable_slow_log= 0;
#ifndef DBUG_OFF
dbug_sentry=THD_SENTRY_MAGIC;
#endif
-@@ -1264,6 +1271,7 @@
+@@ -1357,6 +1364,7 @@
variables.option_bits|= OPTION_BIN_LOG;
else
variables.option_bits&= ~OPTION_BIN_LOG;
#if defined(ENABLED_DEBUG_SYNC)
/* Initialize the Debug Sync Facility. See debug_sync.cc. */
-@@ -1273,6 +1281,94 @@
+@@ -1366,6 +1374,94 @@
clear_slow_extended();
}
/*
Init THD for query processing.
-@@ -2027,6 +2123,32 @@
+@@ -2120,6 +2216,32 @@
}
#endif
struct Item_change_record: public ilink
{
-@@ -2203,6 +2325,7 @@
+@@ -2296,6 +2418,7 @@
}
thd->sent_row_count++;
if (thd->vio_ok())
DBUG_RETURN(protocol->write());
-@@ -2295,6 +2418,7 @@
+@@ -2388,6 +2511,7 @@
select_export::~select_export()
{
thd->sent_row_count=row_count;
}
-@@ -3318,6 +3442,7 @@
+@@ -3411,6 +3535,7 @@
if (likely(thd != 0))
{ /* current_thd==0 when close_connection() calls net_send_error() */
thd->status_var.bytes_sent+= length;
}
}
-@@ -3325,6 +3450,7 @@
+@@ -3418,6 +3543,7 @@
void thd_increment_bytes_received(ulong length)
{
current_thd->status_var.bytes_received+= length;
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
-@@ -1644,6 +1644,8 @@
+@@ -1705,6 +1705,8 @@
*/
enum enum_server_command command;
uint32 server_id;
uint32 file_id; // for LOAD DATA INFILE
/* remote (peer) port */
uint16 peer_port;
-@@ -2153,6 +2155,8 @@
+@@ -2214,6 +2216,8 @@
*/
enum_tx_isolation tx_isolation;
enum_check_fields count_cuted_fields;
DYNAMIC_ARRAY user_var_events; /* For user variables replication */
MEM_ROOT *user_var_events_alloc; /* Allocate above array elements here */
-@@ -2247,6 +2251,49 @@
+@@ -2308,6 +2312,49 @@
*/
LOG_INFO* current_linfo;
NET* slave_net; // network connection from slave -> m.
/* Used by the sys_var class to store temporary values */
union
{
-@@ -2327,6 +2374,11 @@
+@@ -2388,6 +2435,11 @@
alloc_root.
*/
void init_for_queries();
void change_user(void);
void cleanup(void);
void cleanup_after_query();
-@@ -2799,6 +2851,15 @@
+@@ -2860,6 +2912,15 @@
}
thd_scheduler scheduler;
public:
inline Internal_error_handler *get_internal_handler()
{ return m_internal_handler; }
-@@ -2999,6 +3060,10 @@
+@@ -3060,6 +3121,10 @@
LEX_STRING invoker_host;
};
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
-@@ -1070,13 +1070,14 @@
+@@ -1072,13 +1072,14 @@
if (error)
goto abort;
}
else
{
-@@ -1092,8 +1093,10 @@
+@@ -1094,8 +1095,10 @@
sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
(ulong) (info.deleted + updated),
(ulong) thd->warning_info->statement_warn_count());
thd->abort_on_warning= 0;
DBUG_RETURN(FALSE);
-@@ -3535,6 +3538,7 @@
+@@ -3540,6 +3543,7 @@
thd->first_successful_insert_id_in_prev_stmt :
(info.copied ? autoinc_value_of_last_inserted_row : 0));
::my_ok(thd, row_count, id, buff);
#define REG_NEW_RECORD 2 /* Write a new record if not found */
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
-@@ -1632,6 +1632,17 @@
+@@ -1638,6 +1638,17 @@
NO_MUTEX_GUARD, NOT_IN_BINLOG,
ON_CHECK(check_read_only), ON_UPDATE(fix_read_only));
\ No newline at end of file
--- a/mysql-test/r/mysqld--help-notwin.result
+++ b/mysql-test/r/mysqld--help-notwin.result
-@@ -743,6 +743,8 @@
+@@ -745,6 +745,8 @@
Define threads usage for handling queries, one of
one-thread-per-connection, no-threads, loaded-dynamically
--thread-stack=# The stack size for each thread
--time-format=name The TIME format (ignored)
--timed-mutexes Specify whether to time mutexes (only InnoDB mutexes are
currently supported)
-@@ -768,6 +770,9 @@
+@@ -770,6 +772,9 @@
of the underlying table and the query uses a LIMIT clause
(usually get from GUI tools)
-u, --user=name Run mysqld daemon as user.
-v, --verbose Used with --help option for detailed help.
-V, --version Output version information and exit.
--wait-timeout=# The number of seconds the server waits for activity on a
-@@ -1002,6 +1007,7 @@
+@@ -1005,6 +1010,7 @@
thread-cache-size 0
thread-handling one-thread-per-connection
thread-stack 262144
time-format %H:%i:%s
timed-mutexes FALSE
tmp-table-size 16777216
-@@ -1009,6 +1015,7 @@
+@@ -1012,6 +1018,7 @@
transaction-isolation REPEATABLE-READ
transaction-prealloc-size 4096
updatable-views-with-limit YES