mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
WL#1012: All changes as one single changeset.
This includes both code and test cases.
This commit is contained in:
414
sql/sql_class.h
414
sql/sql_class.h
@@ -21,19 +21,20 @@
|
||||
#pragma interface /* gcc class implementation */
|
||||
#endif
|
||||
|
||||
// TODO: create log.h and move all the log header stuff there
|
||||
#include "log.h"
|
||||
#include "rpl_rli.h"
|
||||
#include "rpl_tblmap.h"
|
||||
|
||||
class Query_log_event;
|
||||
class Load_log_event;
|
||||
class Slave_log_event;
|
||||
class Format_description_log_event;
|
||||
class sp_rcontext;
|
||||
class sp_cache;
|
||||
class Rows_log_event;
|
||||
|
||||
enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };
|
||||
enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY, RNEXT_SAME };
|
||||
enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_UPDATE };
|
||||
enum enum_log_type { LOG_CLOSED, LOG_TO_BE_OPENED, LOG_NORMAL, LOG_NEW, LOG_BIN};
|
||||
enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON,
|
||||
DELAY_KEY_WRITE_ALL };
|
||||
|
||||
@@ -50,117 +51,6 @@ extern const char **errmesg;
|
||||
#define TC_HEURISTIC_RECOVER_ROLLBACK 2
|
||||
extern uint tc_heuristic_recover;
|
||||
|
||||
/*
|
||||
Transaction Coordinator log - a base abstract class
|
||||
for two different implementations
|
||||
*/
|
||||
class TC_LOG
|
||||
{
|
||||
public:
|
||||
int using_heuristic_recover();
|
||||
TC_LOG() {}
|
||||
virtual ~TC_LOG() {}
|
||||
|
||||
virtual int open(const char *opt_name)=0;
|
||||
virtual void close()=0;
|
||||
virtual int log(THD *thd, my_xid xid)=0;
|
||||
virtual void unlog(ulong cookie, my_xid xid)=0;
|
||||
};
|
||||
|
||||
class TC_LOG_DUMMY: public TC_LOG // use it to disable the logging
|
||||
{
|
||||
public:
|
||||
int open(const char *opt_name) { return 0; }
|
||||
void close() { }
|
||||
int log(THD *thd, my_xid xid) { return 1; }
|
||||
void unlog(ulong cookie, my_xid xid) { }
|
||||
};
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
class TC_LOG_MMAP: public TC_LOG
|
||||
{
|
||||
public: // only to keep Sun Forte on sol9x86 happy
|
||||
typedef enum {
|
||||
POOL, // page is in pool
|
||||
ERROR, // last sync failed
|
||||
DIRTY // new xids added since last sync
|
||||
} PAGE_STATE;
|
||||
|
||||
private:
|
||||
typedef struct st_page {
|
||||
struct st_page *next; // page a linked in a fifo queue
|
||||
my_xid *start, *end; // usable area of a page
|
||||
my_xid *ptr; // next xid will be written here
|
||||
int size, free; // max and current number of free xid slots on the page
|
||||
int waiters; // number of waiters on condition
|
||||
PAGE_STATE state; // see above
|
||||
pthread_mutex_t lock; // to access page data or control structure
|
||||
pthread_cond_t cond; // to wait for a sync
|
||||
} PAGE;
|
||||
|
||||
char logname[FN_REFLEN];
|
||||
File fd;
|
||||
my_off_t file_length;
|
||||
uint npages, inited;
|
||||
uchar *data;
|
||||
struct st_page *pages, *syncing, *active, *pool, *pool_last;
|
||||
/*
|
||||
note that, e.g. LOCK_active is only used to protect
|
||||
'active' pointer, to protect the content of the active page
|
||||
one has to use active->lock.
|
||||
Same for LOCK_pool and LOCK_sync
|
||||
*/
|
||||
pthread_mutex_t LOCK_active, LOCK_pool, LOCK_sync;
|
||||
pthread_cond_t COND_pool, COND_active;
|
||||
|
||||
public:
|
||||
TC_LOG_MMAP(): inited(0) {}
|
||||
int open(const char *opt_name);
|
||||
void close();
|
||||
int log(THD *thd, my_xid xid);
|
||||
void unlog(ulong cookie, my_xid xid);
|
||||
int recover();
|
||||
|
||||
private:
|
||||
void get_active_from_pool();
|
||||
int sync();
|
||||
int overflow();
|
||||
};
|
||||
#else
|
||||
#define TC_LOG_MMAP TC_LOG_DUMMY
|
||||
#endif
|
||||
|
||||
extern TC_LOG *tc_log;
|
||||
extern TC_LOG_MMAP tc_log_mmap;
|
||||
extern TC_LOG_DUMMY tc_log_dummy;
|
||||
|
||||
/* log info errors */
|
||||
#define LOG_INFO_EOF -1
|
||||
#define LOG_INFO_IO -2
|
||||
#define LOG_INFO_INVALID -3
|
||||
#define LOG_INFO_SEEK -4
|
||||
#define LOG_INFO_MEM -6
|
||||
#define LOG_INFO_FATAL -7
|
||||
#define LOG_INFO_IN_USE -8
|
||||
|
||||
/* bitmap to SQL_LOG::close() */
|
||||
#define LOG_CLOSE_INDEX 1
|
||||
#define LOG_CLOSE_TO_BE_OPENED 2
|
||||
#define LOG_CLOSE_STOP_EVENT 4
|
||||
|
||||
struct st_relay_log_info;
|
||||
|
||||
typedef struct st_log_info
|
||||
{
|
||||
char log_file_name[FN_REFLEN];
|
||||
my_off_t index_file_offset, index_file_start_offset;
|
||||
my_off_t pos;
|
||||
bool fatal; // if the purge happens to give us a negative offset
|
||||
pthread_mutex_t lock;
|
||||
st_log_info():fatal(0) { pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST);}
|
||||
~st_log_info() { pthread_mutex_destroy(&lock);}
|
||||
} LOG_INFO;
|
||||
|
||||
typedef struct st_user_var_events
|
||||
{
|
||||
user_var_entry *user_var_event;
|
||||
@@ -173,188 +63,6 @@ typedef struct st_user_var_events
|
||||
#define RP_LOCK_LOG_IS_ALREADY_LOCKED 1
|
||||
#define RP_FORCE_ROTATE 2
|
||||
|
||||
class Log_event;
|
||||
|
||||
/*
|
||||
TODO split MYSQL_LOG into base MYSQL_LOG and
|
||||
MYSQL_QUERY_LOG, MYSQL_SLOW_LOG, MYSQL_BIN_LOG
|
||||
most of the code from MYSQL_LOG should be in the MYSQL_BIN_LOG
|
||||
only (TC_LOG included)
|
||||
|
||||
TODO use mmap instead of IO_CACHE for binlog
|
||||
(mmap+fsync is two times faster than write+fsync)
|
||||
*/
|
||||
|
||||
class MYSQL_LOG: public TC_LOG
|
||||
{
|
||||
private:
|
||||
/* LOCK_log and LOCK_index are inited by init_pthread_objects() */
|
||||
pthread_mutex_t LOCK_log, LOCK_index;
|
||||
pthread_mutex_t LOCK_prep_xids;
|
||||
pthread_cond_t COND_prep_xids;
|
||||
pthread_cond_t update_cond;
|
||||
ulonglong bytes_written;
|
||||
time_t last_time,query_start;
|
||||
IO_CACHE log_file;
|
||||
IO_CACHE index_file;
|
||||
char *name;
|
||||
char time_buff[20],db[NAME_LEN+1];
|
||||
char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN];
|
||||
/*
|
||||
The max size before rotation (usable only if log_type == LOG_BIN: binary
|
||||
logs and relay logs).
|
||||
For a binlog, max_size should be max_binlog_size.
|
||||
For a relay log, it should be max_relay_log_size if this is non-zero,
|
||||
max_binlog_size otherwise.
|
||||
max_size is set in init(), and dynamically changed (when one does SET
|
||||
GLOBAL MAX_BINLOG_SIZE|MAX_RELAY_LOG_SIZE) by fix_max_binlog_size and
|
||||
fix_max_relay_log_size).
|
||||
*/
|
||||
ulong max_size;
|
||||
ulong prepared_xids; /* for tc log - number of xids to remember */
|
||||
volatile enum_log_type log_type;
|
||||
enum cache_type io_cache_type;
|
||||
// current file sequence number for load data infile binary logging
|
||||
uint file_id;
|
||||
uint open_count; // For replication
|
||||
int readers_count;
|
||||
bool write_error, inited;
|
||||
bool need_start_event;
|
||||
/*
|
||||
no_auto_events means we don't want any of these automatic events :
|
||||
Start/Rotate/Stop. That is, in 4.x when we rotate a relay log, we don't
|
||||
want a Rotate_log event to be written to the relay log. When we start a
|
||||
relay log etc. So in 4.x this is 1 for relay logs, 0 for binlogs.
|
||||
In 5.0 it's 0 for relay logs too!
|
||||
*/
|
||||
bool no_auto_events;
|
||||
friend class Log_event;
|
||||
|
||||
public:
|
||||
/*
|
||||
These describe the log's format. This is used only for relay logs.
|
||||
_for_exec is used by the SQL thread, _for_queue by the I/O thread. It's
|
||||
necessary to have 2 distinct objects, because the I/O thread may be reading
|
||||
events in a different format from what the SQL thread is reading (consider
|
||||
the case of a master which has been upgraded from 5.0 to 5.1 without doing
|
||||
RESET MASTER, or from 4.x to 5.0).
|
||||
*/
|
||||
Format_description_log_event *description_event_for_exec,
|
||||
*description_event_for_queue;
|
||||
|
||||
MYSQL_LOG();
|
||||
/*
|
||||
note that there's no destructor ~MYSQL_LOG() !
|
||||
The reason is that we don't want it to be automatically called
|
||||
on exit() - but only during the correct shutdown process
|
||||
*/
|
||||
|
||||
int open(const char *opt_name);
|
||||
void close();
|
||||
int log(THD *thd, my_xid xid);
|
||||
void unlog(ulong cookie, my_xid xid);
|
||||
int recover(IO_CACHE *log, Format_description_log_event *fdle);
|
||||
void reset_bytes_written()
|
||||
{
|
||||
bytes_written = 0;
|
||||
}
|
||||
void harvest_bytes_written(ulonglong* counter)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
char buf1[22],buf2[22];
|
||||
#endif
|
||||
DBUG_ENTER("harvest_bytes_written");
|
||||
(*counter)+=bytes_written;
|
||||
DBUG_PRINT("info",("counter: %s bytes_written: %s", llstr(*counter,buf1),
|
||||
llstr(bytes_written,buf2)));
|
||||
bytes_written=0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
void set_max_size(ulong max_size_arg);
|
||||
void signal_update();
|
||||
void wait_for_update(THD* thd, bool master_or_slave);
|
||||
void set_need_start_event() { need_start_event = 1; }
|
||||
void init(enum_log_type log_type_arg,
|
||||
enum cache_type io_cache_type_arg,
|
||||
bool no_auto_events_arg, ulong max_size);
|
||||
void init_pthread_objects();
|
||||
void cleanup();
|
||||
bool open(const char *log_name,
|
||||
enum_log_type log_type,
|
||||
const char *new_name,
|
||||
enum cache_type io_cache_type_arg,
|
||||
bool no_auto_events_arg, ulong max_size,
|
||||
bool null_created);
|
||||
const char *generate_name(const char *log_name, const char *suffix,
|
||||
bool strip_ext, char *buff);
|
||||
/* simplified open_xxx wrappers for the gigantic open above */
|
||||
bool open_query_log(const char *log_name)
|
||||
{
|
||||
char buf[FN_REFLEN];
|
||||
return open(generate_name(log_name, ".log", 0, buf),
|
||||
LOG_NORMAL, 0, WRITE_CACHE, 0, 0, 0);
|
||||
}
|
||||
bool open_slow_log(const char *log_name)
|
||||
{
|
||||
char buf[FN_REFLEN];
|
||||
return open(generate_name(log_name, "-slow.log", 0, buf),
|
||||
LOG_NORMAL, 0, WRITE_CACHE, 0, 0, 0);
|
||||
}
|
||||
bool open_index_file(const char *index_file_name_arg,
|
||||
const char *log_name);
|
||||
void new_file(bool need_lock);
|
||||
bool write(THD *thd, enum enum_server_command command,
|
||||
const char *format,...);
|
||||
bool write(THD *thd, const char *query, uint query_length,
|
||||
time_t query_start=0);
|
||||
bool write(Log_event* event_info); // binary log write
|
||||
bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event);
|
||||
|
||||
void start_union_events(THD *thd);
|
||||
void stop_union_events(THD *thd);
|
||||
bool is_query_in_union(THD *thd, query_id_t query_id_param);
|
||||
|
||||
/*
|
||||
v stands for vector
|
||||
invoked as appendv(buf1,len1,buf2,len2,...,bufn,lenn,0)
|
||||
*/
|
||||
bool appendv(const char* buf,uint len,...);
|
||||
bool append(Log_event* ev);
|
||||
|
||||
int generate_new_name(char *new_name,const char *old_name);
|
||||
void make_log_name(char* buf, const char* log_ident);
|
||||
bool is_active(const char* log_file_name);
|
||||
int update_log_index(LOG_INFO* linfo, bool need_update_threads);
|
||||
void rotate_and_purge(uint flags);
|
||||
bool flush_and_sync();
|
||||
int purge_logs(const char *to_log, bool included,
|
||||
bool need_mutex, bool need_update_threads,
|
||||
ulonglong *decrease_log_space);
|
||||
int purge_logs_before_date(time_t purge_time);
|
||||
int purge_first_log(struct st_relay_log_info* rli, bool included);
|
||||
bool reset_logs(THD* thd);
|
||||
void close(uint exiting);
|
||||
|
||||
// iterating through the log index file
|
||||
int find_log_pos(LOG_INFO* linfo, const char* log_name,
|
||||
bool need_mutex);
|
||||
int find_next_log(LOG_INFO* linfo, bool need_mutex);
|
||||
int get_current_log(LOG_INFO* linfo);
|
||||
uint next_file_id();
|
||||
inline bool is_open() { return log_type != LOG_CLOSED; }
|
||||
inline char* get_index_fname() { return index_file_name;}
|
||||
inline char* get_log_fname() { return log_file_name; }
|
||||
inline char* get_name() { return name; }
|
||||
inline pthread_mutex_t* get_log_lock() { return &LOCK_log; }
|
||||
inline IO_CACHE* get_log_file() { return &log_file; }
|
||||
|
||||
inline void lock_index() { pthread_mutex_lock(&LOCK_index);}
|
||||
inline void unlock_index() { pthread_mutex_unlock(&LOCK_index);}
|
||||
inline IO_CACHE *get_index_file() { return &index_file;}
|
||||
inline uint32 get_open_count() { return open_count; }
|
||||
};
|
||||
|
||||
|
||||
typedef struct st_copy_info {
|
||||
ha_rows records;
|
||||
ha_rows deleted;
|
||||
@@ -461,28 +169,6 @@ public:
|
||||
|
||||
#include "sql_lex.h" /* Must be here */
|
||||
|
||||
/* Needed to be able to have an I_List of char* strings in mysqld.cc. */
|
||||
|
||||
class i_string: public ilink
|
||||
{
|
||||
public:
|
||||
const char* ptr;
|
||||
i_string():ptr(0) { }
|
||||
i_string(const char* s) : ptr(s) {}
|
||||
};
|
||||
|
||||
/* needed for linked list of two strings for replicate-rewrite-db */
|
||||
class i_string_pair: public ilink
|
||||
{
|
||||
public:
|
||||
const char* key;
|
||||
const char* val;
|
||||
i_string_pair():key(0),val(0) { }
|
||||
i_string_pair(const char* key_arg, const char* val_arg) :
|
||||
key(key_arg),val(val_arg) {}
|
||||
};
|
||||
|
||||
|
||||
class delayed_insert;
|
||||
class select_result;
|
||||
|
||||
@@ -1102,6 +788,9 @@ class THD :public Statement,
|
||||
public Open_tables_state
|
||||
{
|
||||
public:
|
||||
/* Used to execute base64 coded binlog events in MySQL server */
|
||||
RELAY_LOG_INFO* rli_fake;
|
||||
|
||||
/*
|
||||
Constant for THD::where initialization in the beginning of every query.
|
||||
|
||||
@@ -1206,12 +895,96 @@ public:
|
||||
|
||||
/* container for handler's private per-connection data */
|
||||
void *ha_data[MAX_HA];
|
||||
|
||||
#ifdef HAVE_ROW_BASED_REPLICATION
|
||||
#ifndef MYSQL_CLIENT
|
||||
|
||||
/*
|
||||
Public interface to write rows to the binlog
|
||||
*/
|
||||
int binlog_write_row(TABLE* table, bool is_transactional,
|
||||
MY_BITMAP const* cols, my_size_t colcnt,
|
||||
const byte *buf);
|
||||
int binlog_delete_row(TABLE* table, bool is_transactional,
|
||||
MY_BITMAP const* cols, my_size_t colcnt,
|
||||
const byte *buf);
|
||||
int binlog_update_row(TABLE* table, bool is_transactional,
|
||||
MY_BITMAP const* cols, my_size_t colcnt,
|
||||
const byte *old_data, const byte *new_data);
|
||||
|
||||
void set_server_id(uint32 sid) { server_id = sid; }
|
||||
|
||||
/*
|
||||
Member functions to handle pending event for row-level logging.
|
||||
*/
|
||||
template <class RowsEventT> Rows_log_event*
|
||||
binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id,
|
||||
MY_BITMAP const* cols,
|
||||
my_size_t colcnt,
|
||||
my_size_t needed,
|
||||
bool is_transactional);
|
||||
Rows_log_event* binlog_get_pending_rows_event() const;
|
||||
void binlog_set_pending_rows_event(Rows_log_event* ev);
|
||||
int binlog_setup_trx_data();
|
||||
|
||||
my_size_t max_row_length_blob(TABLE* table, const byte *data) const;
|
||||
my_size_t max_row_length(TABLE* table, const byte *data) const
|
||||
{
|
||||
TABLE_SHARE *table_s= table->s;
|
||||
my_size_t length= table_s->reclength + 2 * table_s->fields;
|
||||
if (table_s->blob_fields == 0)
|
||||
return length;
|
||||
|
||||
return (length+max_row_length_blob(table,data));
|
||||
}
|
||||
|
||||
my_size_t pack_row(TABLE* table, MY_BITMAP const* cols, byte *row_data,
|
||||
const byte *data) const;
|
||||
|
||||
int binlog_flush_pending_rows_event(bool stmt_end);
|
||||
void binlog_delete_pending_rows_event();
|
||||
|
||||
#endif
|
||||
#endif /* HAVE_ROW_BASED_REPLICATION */
|
||||
#ifndef MYSQL_CLIENT
|
||||
enum enum_binlog_query_type {
|
||||
/*
|
||||
The query can be logged row-based or statement-based
|
||||
*/
|
||||
ROW_QUERY_TYPE,
|
||||
|
||||
/*
|
||||
The query has to be logged statement-based
|
||||
*/
|
||||
STMT_QUERY_TYPE,
|
||||
|
||||
/*
|
||||
The query represents a change to a table in the "mysql"
|
||||
database and is currently mapped to ROW_QUERY_TYPE.
|
||||
*/
|
||||
MYSQL_QUERY_TYPE,
|
||||
QUERY_TYPE_COUNT
|
||||
};
|
||||
|
||||
int binlog_query(enum_binlog_query_type qtype,
|
||||
char const *query, ulong query_len,
|
||||
bool is_trans, bool suppress_use);
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
struct st_transactions {
|
||||
SAVEPOINT *savepoints;
|
||||
THD_TRANS all; // Trans since BEGIN WORK
|
||||
THD_TRANS stmt; // Trans for current statement
|
||||
bool on; // see ha_enable_transaction()
|
||||
XID xid; // transaction identifier
|
||||
enum xa_states xa_state; // used by external XA only
|
||||
XID_STATE xid_state;
|
||||
#ifdef HAVE_ROW_BASED_REPLICATION
|
||||
Rows_log_event *m_pending_rows_event;
|
||||
#endif
|
||||
|
||||
/*
|
||||
Tables changed in transaction (that must be invalidated in query cache).
|
||||
List contain only transactional tables, that not invalidated in query
|
||||
@@ -1768,6 +1541,7 @@ class select_create: public select_insert {
|
||||
HA_CREATE_INFO *create_info;
|
||||
MYSQL_LOCK *lock;
|
||||
Field **field;
|
||||
bool create_table_written;
|
||||
public:
|
||||
select_create (TABLE_LIST *table,
|
||||
HA_CREATE_INFO *create_info_par,
|
||||
@@ -1776,9 +1550,11 @@ public:
|
||||
List<Item> &select_fields,enum_duplicates duplic, bool ignore)
|
||||
:select_insert (NULL, NULL, &select_fields, 0, 0, duplic, ignore), create_table(table),
|
||||
extra_fields(&fields_par),keys(&keys_par), create_info(create_info_par),
|
||||
lock(0)
|
||||
lock(0), create_table_written(FALSE)
|
||||
{}
|
||||
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
|
||||
|
||||
void binlog_show_create_table();
|
||||
void store_values(List<Item> &values);
|
||||
void send_error(uint errcode,const char *err);
|
||||
bool send_eof();
|
||||
|
||||
Reference in New Issue
Block a user