diff options
Diffstat (limited to 'sql/sql_class.h')
-rw-r--r-- | sql/sql_class.h | 414 |
1 files changed, 95 insertions, 319 deletions
diff --git a/sql/sql_class.h b/sql/sql_class.h index 60dc9a4cbad..1ef3322bc8f 100644 --- a/sql/sql_class.h +++ b/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(); |