summaryrefslogtreecommitdiff
path: root/sql/sql_class.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_class.h')
-rw-r--r--sql/sql_class.h232
1 files changed, 227 insertions, 5 deletions
diff --git a/sql/sql_class.h b/sql/sql_class.h
index a1b9fc0969e..f001f14c219 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -381,6 +381,29 @@ public:
};
+/* An ALTER INDEX operation that changes the ignorability of an index. */
+class Alter_index_ignorability: public Sql_alloc
+{
+public:
+ Alter_index_ignorability(const char *name, bool is_ignored) :
+ m_name(name), m_is_ignored(is_ignored)
+ {
+ assert(name != NULL);
+ }
+
+ const char *name() const { return m_name; }
+
+ /* The ignorability after the operation is performed. */
+ bool is_ignored() const { return m_is_ignored; }
+ Alter_index_ignorability *clone(MEM_ROOT *mem_root) const
+ { return new (mem_root) Alter_index_ignorability(*this); }
+
+private:
+ const char *m_name;
+ bool m_is_ignored;
+};
+
+
class Key :public Sql_alloc, public DDL_options {
public:
enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT, SPATIAL, FOREIGN_KEY};
@@ -836,7 +859,6 @@ typedef struct system_status_var
ulong com_create_tmp_table;
ulong com_drop_tmp_table;
ulong com_other;
- ulong com_multi;
ulong com_stmt_prepare;
ulong com_stmt_reprepare;
@@ -933,6 +955,12 @@ typedef struct system_status_var
ulong lost_connections;
ulong max_statement_time_exceeded;
/*
+ Number of times where column info was not
+ sent with prepared statement metadata.
+ */
+ ulong skip_metadata_count;
+
+ /*
Number of statements sent from the client
*/
ulong questions;
@@ -951,6 +979,7 @@ typedef struct system_status_var
ulonglong table_open_cache_hits;
ulonglong table_open_cache_misses;
ulonglong table_open_cache_overflows;
+ ulonglong send_metadata_skips;
double last_query_cost;
double cpu_time, busy_time;
uint32 threads_running;
@@ -1209,6 +1238,38 @@ public:
class Server_side_cursor;
+/*
+ Struct to catch changes in column metadata that is sent to client.
+ in the "result set metadata". Used to support
+ MARIADB_CLIENT_CACHE_METADATA.
+*/
+struct send_column_info_state
+{
+ /* Last client charset (affects metadata) */
+ CHARSET_INFO *last_charset= nullptr;
+
+ /* Checksum, only used to check changes if 'immutable' is false*/
+ uint32 checksum= 0;
+
+ /*
+ Column info can only be changed by PreparedStatement::reprepare()
+
+ There is a class of "weird" prepared statements like SELECT ? or SELECT @a
+ that are not immutable, and depend on input parameters or user variables
+ */
+ bool immutable= false;
+
+ bool initialized= false;
+
+ /* Used by PreparedStatement::reprepare()*/
+ void reset()
+ {
+ initialized= false;
+ checksum= 0;
+ }
+};
+
+
/**
@class Statement
@brief State of a single command executed against this connection.
@@ -1298,6 +1359,8 @@ public:
LEX_CSTRING db;
+ send_column_info_state column_info_state;
+
/* This is set to 1 of last call to send_result_to_client() was ok */
my_bool query_cache_is_applicable;
@@ -2282,6 +2345,164 @@ struct THD_count
~THD_count() { thread_count--; }
};
+/**
+ Support structure for asynchronous group commit, or more generally
+ any asynchronous operation that needs to finish before server writes
+ response to client.
+
+ An engine, or any other server component, can signal that there is
+ a pending operation by incrementing a counter, i.e inc_pending_ops()
+ and that pending operation is finished by decrementing that counter
+ dec_pending_ops().
+
+ NOTE: Currently, pending operations can not fail, i.e there is no
+ way to pass a return code in dec_pending_ops()
+
+ The server does not write response to the client before the counter
+ becomes 0. In case of group commit it ensures that data is persistent
+ before success reported to client, i.e durability in ACID.
+*/
+struct thd_async_state
+{
+ enum class enum_async_state
+ {
+ NONE,
+ SUSPENDED, /* do_command() did not finish, and needs to be resumed */
+ RESUMED /* do_command() is resumed*/
+ };
+ enum_async_state m_state{enum_async_state::NONE};
+
+ /* Stuff we need to resume do_command where we finished last time*/
+ enum enum_server_command m_command{COM_SLEEP};
+ LEX_STRING m_packet{0,0};
+
+ mysql_mutex_t m_mtx;
+ mysql_cond_t m_cond;
+
+ /** Pending counter*/
+ Atomic_counter<int> m_pending_ops=0;
+
+#ifndef DBUG_OFF
+ /* Checks */
+ pthread_t m_dbg_thread;
+#endif
+
+ thd_async_state()
+ {
+ mysql_mutex_init(PSI_NOT_INSTRUMENTED, &m_mtx, 0);
+ mysql_cond_init(PSI_INSTRUMENT_ME, &m_cond, 0);
+ }
+
+ /*
+ Currently only used with threadpool, one can "suspend" and "resume" a THD.
+ Suspend only means leaving do_command earlier, after saving some state.
+ Resume is continuing suspended THD's do_command(), from where it finished last time.
+ */
+ bool try_suspend()
+ {
+ bool ret;
+ mysql_mutex_lock(&m_mtx);
+ DBUG_ASSERT(m_state == enum_async_state::NONE);
+ DBUG_ASSERT(m_pending_ops >= 0);
+
+ if(m_pending_ops)
+ {
+ ret=true;
+ m_state= enum_async_state::SUSPENDED;
+ }
+ else
+ {
+ /*
+ If there is no pending operations, can't suspend, since
+ nobody can resume it.
+ */
+ ret=false;
+ }
+ mysql_mutex_unlock(&m_mtx);
+ return ret;
+ }
+
+ ~thd_async_state()
+ {
+ wait_for_pending_ops();
+ mysql_mutex_destroy(&m_mtx);
+ mysql_cond_destroy(&m_cond);
+ }
+
+ /*
+ Increment pending asynchronous operations.
+ The client response may not be written if
+ this count > 0.
+ So, without threadpool query needs to wait for
+ the operations to finish.
+ With threadpool, THD can be suspended and resumed
+ when this counter goes to 0.
+ */
+ void inc_pending_ops()
+ {
+ mysql_mutex_lock(&m_mtx);
+
+#ifndef DBUG_OFF
+ /*
+ Check that increments are always done by the same thread.
+ */
+ if (!m_pending_ops)
+ m_dbg_thread= pthread_self();
+ else
+ DBUG_ASSERT(pthread_equal(pthread_self(),m_dbg_thread));
+#endif
+
+ m_pending_ops++;
+ mysql_mutex_unlock(&m_mtx);
+ }
+
+ int dec_pending_ops(enum_async_state* state)
+ {
+ int ret;
+ mysql_mutex_lock(&m_mtx);
+ ret= --m_pending_ops;
+ if (!ret)
+ mysql_cond_signal(&m_cond);
+ *state = m_state;
+ mysql_mutex_unlock(&m_mtx);
+ return ret;
+ }
+
+ /*
+ This is used for "dirty" reading pending ops,
+ when dirty read is OK.
+ */
+ int pending_ops()
+ {
+ return m_pending_ops;
+ }
+
+ /* Wait for pending operations to finish.*/
+ void wait_for_pending_ops()
+ {
+ /*
+ It is fine to read m_pending_ops and compare it with 0,
+ without mutex protection.
+
+ The value is only incremented by the current thread, and will
+ be decremented by another one, thus "dirty" may show positive number
+ when it is really 0, but this is not a problem, and the only
+ bad thing from that will be rechecking under mutex.
+ */
+ if (!pending_ops())
+ return;
+
+ mysql_mutex_lock(&m_mtx);
+ DBUG_ASSERT(m_pending_ops >= 0);
+ while (m_pending_ops)
+ mysql_cond_wait(&m_cond, &m_mtx);
+ mysql_mutex_unlock(&m_mtx);
+ }
+};
+
+extern "C" MYSQL_THD thd_increment_pending_ops(void);
+extern "C" void thd_decrement_pending_ops(MYSQL_THD);
+
/**
@class THD
@@ -2401,6 +2622,8 @@ public:
/* Last created prepared statement */
Statement *last_stmt;
+ Statement *cur_stmt= 0;
+
inline void set_last_stmt(Statement *stmt)
{ last_stmt= (is_error() ? NULL : stmt); }
inline void clear_last_stmt() { last_stmt= NULL; }
@@ -4989,6 +5212,7 @@ private:
}
public:
+ thd_async_state async_state;
#ifdef HAVE_REPLICATION
/*
If we do a purge of binary logs, log index info of the threads
@@ -5051,6 +5275,8 @@ public:
uint64 wsrep_current_gtid_seqno;
ulong wsrep_affected_rows;
bool wsrep_has_ignored_error;
+ /* true if wsrep_on was ON in last wsrep_on_update */
+ bool wsrep_was_on;
/*
When enabled, do not replicate/binlog updates from the current table that's
@@ -6963,10 +7189,6 @@ public:
#define CF_SKIP_WSREP_CHECK 0
#endif /* WITH_WSREP */
-/**
- Do not allow it for COM_MULTI batch
-*/
-#define CF_NO_COM_MULTI (1U << 3)
/* Inline functions */