diff options
Diffstat (limited to 'sql/log_event.h')
-rw-r--r-- | sql/log_event.h | 285 |
1 files changed, 262 insertions, 23 deletions
diff --git a/sql/log_event.h b/sql/log_event.h index 446bd8cb827..4ecb3d49e63 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2014, Oracle and/or its affiliates. - Copyright (c) 2009, 2014, Monty Program Ab. + Copyright (c) 2009, 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -41,6 +41,7 @@ #include "rpl_utility.h" #include "hash.h" #include "rpl_tblmap.h" +#include "sql_string.h" #endif #ifdef MYSQL_SERVER @@ -52,7 +53,9 @@ #include "rpl_gtid.h" /* Forward declarations */ +#ifndef MYSQL_CLIENT class String; +#endif #define PREFIX_SQL_LOAD "SQL_LOAD-" #define LONG_FIND_ROW_THRESHOLD 60 /* seconds */ @@ -692,11 +695,75 @@ enum Log_event_type START_ENCRYPTION_EVENT= 164, + /* + Compressed binlog event. + + Note that the order between WRITE/UPDATE/DELETE events is significant; + this is so that we can convert from the compressed to the uncompressed + event type with (type-WRITE_ROWS_COMPRESSED_EVENT + WRITE_ROWS_EVENT) + and similar for _V1. + */ + QUERY_COMPRESSED_EVENT = 165, + WRITE_ROWS_COMPRESSED_EVENT_V1 = 166, + UPDATE_ROWS_COMPRESSED_EVENT_V1 = 167, + DELETE_ROWS_COMPRESSED_EVENT_V1 = 168, + WRITE_ROWS_COMPRESSED_EVENT = 169, + UPDATE_ROWS_COMPRESSED_EVENT = 170, + DELETE_ROWS_COMPRESSED_EVENT = 171, + /* Add new MariaDB events here - right above this comment! */ ENUM_END_EVENT /* end marker */ }; +static inline bool LOG_EVENT_IS_QUERY(enum Log_event_type type) +{ + return type == QUERY_EVENT || type == QUERY_COMPRESSED_EVENT; +} + + +static inline bool LOG_EVENT_IS_WRITE_ROW(enum Log_event_type type) +{ + return type == WRITE_ROWS_EVENT || type == WRITE_ROWS_EVENT_V1 || + type == WRITE_ROWS_COMPRESSED_EVENT || + type == WRITE_ROWS_COMPRESSED_EVENT_V1; +} + + +static inline bool LOG_EVENT_IS_UPDATE_ROW(enum Log_event_type type) +{ + return type == UPDATE_ROWS_EVENT || type == UPDATE_ROWS_EVENT_V1 || + type == UPDATE_ROWS_COMPRESSED_EVENT || + type == UPDATE_ROWS_COMPRESSED_EVENT_V1; +} + + +static inline bool LOG_EVENT_IS_DELETE_ROW(enum Log_event_type type) +{ + return type == DELETE_ROWS_EVENT || type == DELETE_ROWS_EVENT_V1 || + type == DELETE_ROWS_COMPRESSED_EVENT || + type == DELETE_ROWS_COMPRESSED_EVENT_V1; +} + + +static inline bool LOG_EVENT_IS_ROW_COMPRESSED(enum Log_event_type type) +{ + return type == WRITE_ROWS_COMPRESSED_EVENT || + type == WRITE_ROWS_COMPRESSED_EVENT_V1 || + type == UPDATE_ROWS_COMPRESSED_EVENT || + type == UPDATE_ROWS_COMPRESSED_EVENT_V1 || + type == DELETE_ROWS_COMPRESSED_EVENT || + type == DELETE_ROWS_COMPRESSED_EVENT_V1; +} + + +static inline bool LOG_EVENT_IS_ROW_V2(enum Log_event_type type) +{ + return (type >= WRITE_ROWS_EVENT && type <= DELETE_ROWS_EVENT) || + (type >= WRITE_ROWS_COMPRESSED_EVENT && type <= DELETE_ROWS_COMPRESSED_EVENT); +} + + /* The number of types we handle in Format_description_log_event (UNKNOWN_EVENT is not to be handled, it does not exist in binlogs, it does not have a @@ -754,14 +821,14 @@ typedef struct st_print_event_info bool flags2_inited; uint32 flags2; bool sql_mode_inited; - ulonglong sql_mode; /* must be same as THD.variables.sql_mode */ + sql_mode_t sql_mode; /* must be same as THD.variables.sql_mode */ ulong auto_increment_increment, auto_increment_offset; bool charset_inited; char charset[6]; // 3 variables, each of them storable in 2 bytes char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH]; uint lc_time_names_number; uint charset_database_number; - uint thread_id; + my_thread_id thread_id; bool thread_id_printed; uint32 server_id; bool server_id_printed; @@ -769,7 +836,7 @@ typedef struct st_print_event_info bool domain_id_printed; bool allow_parallel; bool allow_parallel_printed; - + static const uint max_delimiter_size= 16; /* Track when @@skip_replication changes so we need to output a SET statement for it. @@ -781,9 +848,16 @@ typedef struct st_print_event_info ~st_print_event_info() { close_cached_file(&head_cache); close_cached_file(&body_cache); +#ifdef WHEN_FLASHBACK_REVIEW_READY + close_cached_file(&review_sql_cache); +#endif } bool init_ok() /* tells if construction was successful */ - { return my_b_inited(&head_cache) && my_b_inited(&body_cache); } + { return my_b_inited(&head_cache) && my_b_inited(&body_cache) +#ifdef WHEN_FLASHBACK_REVIEW_READY + && my_b_inited(&review_sql_cache) +#endif + ; } /* Settings on how to print the events */ @@ -798,7 +872,7 @@ typedef struct st_print_event_info bool printed_fd_event; my_off_t hexdump_from; uint8 common_header_len; - char delimiter[16]; + char delimiter[max_delimiter_size]; uint verbose; table_mapping m_table_map; @@ -811,6 +885,10 @@ typedef struct st_print_event_info */ IO_CACHE head_cache; IO_CACHE body_cache; +#ifdef WHEN_FLASHBACK_REVIEW_READY + /* Storing the SQL for reviewing */ + IO_CACHE review_sql_cache; +#endif } PRINT_EVENT_INFO; #endif @@ -1159,6 +1237,37 @@ public: void print_base64(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info, bool do_print_encoded); #endif + + /* The following code used for Flashback */ +#ifdef MYSQL_CLIENT + my_bool is_flashback; + my_bool need_flashback_review; + String output_buf; // Storing the event output +#ifdef WHEN_FLASHBACK_REVIEW_READY + String m_review_dbname; + String m_review_tablename; + + void set_review_dbname(const char *name) + { + if (name) + { + m_review_dbname.free(); + m_review_dbname.append(name); + } + } + void set_review_tablename(const char *name) + { + if (name) + { + m_review_tablename.free(); + m_review_tablename.append(name); + } + } + const char *get_review_dbname() const { return m_review_dbname.ptr(); } + const char *get_review_tablename() const { return m_review_tablename.ptr(); } +#endif +#endif + /* read_log_event() functions read an event from a binlog or relay log; used by SHOW BINLOG EVENTS, the binlog_dump thread on the @@ -1899,7 +2008,7 @@ public: uint32 q_len; uint32 db_len; uint16 error_code; - ulong thread_id; + my_thread_id thread_id; /* For events created by Query_log_event::do_apply_event (and Load_log_event::do_apply_event()) we need the *original* thread @@ -1951,8 +2060,7 @@ public: bool charset_inited; uint32 flags2; - /* In connections sql_mode is 32 bits now but will be 64 bits soon */ - ulonglong sql_mode; + sql_mode_t sql_mode; ulong auto_increment_increment, auto_increment_offset; char charset[6]; uint time_zone_len; /* 0 means uninited */ @@ -2046,9 +2154,37 @@ public: /* !!! Public in this patch to allow old usage */ !strncasecmp(query, "SAVEPOINT", 9) || !strncasecmp(query, "ROLLBACK", 8); } - bool is_begin() { return !strcmp(query, "BEGIN"); } - bool is_commit() { return !strcmp(query, "COMMIT"); } - bool is_rollback() { return !strcmp(query, "ROLLBACK"); } + virtual bool is_begin() { return !strcmp(query, "BEGIN"); } + virtual bool is_commit() { return !strcmp(query, "COMMIT"); } + virtual bool is_rollback() { return !strcmp(query, "ROLLBACK"); } +}; + +class Query_compressed_log_event:public Query_log_event{ +protected: + Log_event::Byte* query_buf; // point to the uncompressed query +public: + Query_compressed_log_event(const char* buf, uint event_len, + const Format_description_log_event *description_event, + Log_event_type event_type); + ~Query_compressed_log_event() + { + if (query_buf) + my_free(query_buf); + } + Log_event_type get_type_code() { return QUERY_COMPRESSED_EVENT; } + + /* + the min length of log_bin_compress_min_len is 10, + means that Begin/Commit/Rollback would never be compressed! + */ + virtual bool is_begin() { return false; } + virtual bool is_commit() { return false; } + virtual bool is_rollback() { return false; } +#ifdef MYSQL_SERVER + Query_compressed_log_event(THD* thd_arg, const char* query_arg, ulong query_length, + bool using_trans, bool direct, bool suppress_use, int error); + virtual bool write(); +#endif }; @@ -2299,7 +2435,7 @@ public: void print_query(THD *thd, bool need_db, const char *cs, String *buf, my_off_t *fn_start, my_off_t *fn_end, const char *qualify_db); - ulong thread_id; + my_thread_id thread_id; ulong slave_proxy_id; uint32 table_name_len; /* @@ -3749,6 +3885,7 @@ private: uint m_query_len; char *m_save_thd_query_txt; uint m_save_thd_query_len; + bool m_saved_thd_query; }; /** @@ -4130,7 +4267,7 @@ public: int rewrite_db(const char* new_name, size_t new_name_len, const Format_description_log_event*); #endif - ulong get_table_id() const { return m_table_id; } + ulonglong get_table_id() const { return m_table_id; } const char *get_table_name() const { return m_tblnam; } const char *get_db_name() const { return m_dbnam; } @@ -4173,7 +4310,7 @@ private: uchar *m_coltype; uchar *m_memory; - ulong m_table_id; + ulonglong m_table_id; flag_set m_flags; size_t m_data_size; @@ -4241,7 +4378,10 @@ public: Indicates that rows in this event are complete, that is contain values for all columns of the table. */ - COMPLETE_ROWS_F = (1U << 3) + COMPLETE_ROWS_F = (1U << 3), + + /* Value of the OPTION_NO_CHECK_CONSTRAINT_CHECKS flag in thd->options */ + NO_CHECK_CONSTRAINT_CHECKS_F = (1U << 7) }; typedef uint16 flag_set; @@ -4257,6 +4397,7 @@ public: void set_flags(flag_set flags_arg) { m_flags |= flags_arg; } void clear_flags(flag_set flags_arg) { m_flags &= ~flags_arg; } flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; } + void update_flags() { int2store(temp_buf + m_flags_pos, m_flags); } Log_event_type get_type_code() { return m_type; } /* Specific type (_V1 etc) */ virtual Log_event_type get_general_type_code() = 0; /* General rows op type, no version */ @@ -4268,12 +4409,14 @@ public: #ifdef MYSQL_CLIENT /* not for direct call, each derived has its own ::print() */ virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info)= 0; + void change_to_flashback_event(PRINT_EVENT_INFO *print_event_info, uchar *rows_buff, Log_event_type ev_type); void print_verbose(IO_CACHE *file, PRINT_EVENT_INFO *print_event_info); size_t print_verbose_one_row(IO_CACHE *file, table_def *td, PRINT_EVENT_INFO *print_event_info, MY_BITMAP *cols_bitmap, - const uchar *ptr, const uchar *prefix); + const uchar *ptr, const uchar *prefix, + const my_bool no_fill_output= 0); // if no_fill_output=1, then print result is unnecessary #endif #ifdef MYSQL_SERVER @@ -4289,7 +4432,7 @@ public: MY_BITMAP const *get_cols() const { return &m_cols; } MY_BITMAP const *get_cols_ai() const { return &m_cols_ai; } size_t get_width() const { return m_width; } - ulong get_table_id() const { return m_table_id; } + ulonglong get_table_id() const { return m_table_id; } #if defined(MYSQL_SERVER) /* @@ -4342,6 +4485,7 @@ public: #ifdef MYSQL_SERVER virtual bool write_data_header(); virtual bool write_data_body(); + virtual bool write_compressed(); virtual const char *get_db() { return m_table->s->db.str; } #endif /* @@ -4376,6 +4520,7 @@ protected: #endif Rows_log_event(const char *row_data, uint event_len, const Format_description_log_event *description_event); + void uncompress_buf(); #ifdef MYSQL_CLIENT void print_helper(FILE *, PRINT_EVENT_INFO *, char const *const name); @@ -4388,7 +4533,7 @@ protected: #ifdef MYSQL_SERVER TABLE *m_table; /* The table the rows belong to */ #endif - ulong m_table_id; /* Table ID */ + ulonglong m_table_id; /* Table ID */ MY_BITMAP m_cols; /* Bitmap denoting columns available */ ulong m_width; /* The width of the columns bitmap */ /* @@ -4410,6 +4555,9 @@ protected: uchar *m_rows_cur; /* One-after the end of the data */ uchar *m_rows_end; /* One-after the end of the allocated space */ + size_t m_rows_before_size; /* The length before m_rows_buf */ + size_t m_flags_pos; /* The position of the m_flags */ + flag_set m_flags; /* Flags for row-level events */ Log_event_type m_type; /* Actual event type */ @@ -4588,6 +4736,23 @@ private: #endif }; +class Write_rows_compressed_log_event : public Write_rows_log_event +{ +public: +#if defined(MYSQL_SERVER) + Write_rows_compressed_log_event(THD*, TABLE*, ulong table_id, + bool is_transactional); + virtual bool write(); +#endif +#ifdef HAVE_REPLICATION + Write_rows_compressed_log_event(const char *buf, uint event_len, + const Format_description_log_event *description_event); +#endif +private: +#if defined(MYSQL_CLIENT) + void print(FILE *file, PRINT_EVENT_INFO *print_event_info); +#endif +}; /** @class Update_rows_log_event @@ -4658,6 +4823,24 @@ protected: #endif /* defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) */ }; +class Update_rows_compressed_log_event : public Update_rows_log_event +{ +public: +#if defined(MYSQL_SERVER) + Update_rows_compressed_log_event(THD*, TABLE*, ulong table_id, + bool is_transactional); + virtual bool write(); +#endif +#ifdef HAVE_REPLICATION + Update_rows_compressed_log_event(const char *buf, uint event_len, + const Format_description_log_event *description_event); +#endif +private: +#if defined(MYSQL_CLIENT) + void print(FILE *file, PRINT_EVENT_INFO *print_event_info); +#endif +}; + /** @class Delete_rows_log_event @@ -4724,6 +4907,23 @@ protected: #endif }; +class Delete_rows_compressed_log_event : public Delete_rows_log_event +{ +public: +#if defined(MYSQL_SERVER) + Delete_rows_compressed_log_event(THD*, TABLE*, ulong, bool is_transactional); + virtual bool write(); +#endif +#ifdef HAVE_REPLICATION + Delete_rows_compressed_log_event(const char *buf, uint event_len, + const Format_description_log_event *description_event); +#endif +private: +#if defined(MYSQL_CLIENT) + void print(FILE *file, PRINT_EVENT_INFO *print_event_info); +#endif +}; + #include "log_event_old.h" @@ -4892,12 +5092,36 @@ public: }; #ifdef MYSQL_CLIENT -void copy_cache_to_file_wrapped(FILE *file, - PRINT_EVENT_INFO *print_event_info, - IO_CACHE *body, - bool do_wrap); +void copy_cache_to_string_wrapped(IO_CACHE *body, + LEX_STRING *to, + bool do_wrap, + const char *delimiter, + bool is_verbose); #endif +static inline bool copy_event_cache_to_string_and_reinit(IO_CACHE *cache, LEX_STRING *to) +{ + String tmp; + + reinit_io_cache(cache, READ_CACHE, 0L, FALSE, FALSE); + if (tmp.append(cache, (uint32)cache->end_of_file)) + goto err; + reinit_io_cache(cache, WRITE_CACHE, 0, FALSE, TRUE); + + /* + Can't change the order, because the String::release() will clear the + length. + */ + to->length= tmp.length(); + to->str= tmp.release(); + + return false; + +err: + perror("Out of memory: can't allocate memory in copy_event_cache_to_string_and_reinit()."); + return true; +} + static inline bool copy_event_cache_to_file_and_reinit(IO_CACHE *cache, FILE *file) { @@ -4972,4 +5196,19 @@ extern TYPELIB binlog_checksum_typelib; @} (end of group Replication) */ + +int binlog_buf_compress(const char *src, char *dst, uint32 len, uint32 *comlen); +int binlog_buf_uncompress(const char *src, char *dst, uint32 len, uint32 *newlen); +uint32 binlog_get_compress_len(uint32 len); +uint32 binlog_get_uncompress_len(const char *buf); + +int query_event_uncompress(const Format_description_log_event *description_event, bool contain_checksum, + const char *src, ulong src_len, char* buf, ulong buf_size, bool* is_malloc, + char **dst, ulong *newlen); + +int row_log_event_uncompress(const Format_description_log_event *description_event, bool contain_checksum, + const char *src, ulong src_len, char* buf, ulong buf_size, bool* is_malloc, + char **dst, ulong *newlen); + + #endif /* _log_event_h */ |