diff options
author | He Zhenxing <hezx@mysql.com> | 2008-07-31 14:24:27 +0800 |
---|---|---|
committer | He Zhenxing <hezx@mysql.com> | 2008-07-31 14:24:27 +0800 |
commit | a018e98cba6158e7a2885cffcc092ab66a934d5e (patch) | |
tree | de2982498ec76b7c6ecf0d7d1258679a9ae3a459 /sql/log_event.h | |
parent | 1f28448efb44e62e9dee113ccc7d8309b1664c17 (diff) | |
download | mariadb-git-a018e98cba6158e7a2885cffcc092ab66a934d5e.tar.gz |
BUG#37051 Replication rules not evaluated correctly
The problem of this bug is that we need to get the list of tables
to be updated for a multi-table update statement, which requires to
open all the tables referenced by the statement and resolve all
the fields involved in update in order to figure out the list of
tables for update. However if there are replicate filter rules,
some tables might not exist on slave and result in a failure
before we could examine the filter rules.
I think the whole problem can not be solved on slave alone,
the master must record and send the information of tables
involved for update to slave, so that the slave do not need to
open all the tables referenced by the multi-table update statement to
figure out which tables are involved for update.
So a status variable is added to Query_log event to store the
value of table map for update on master. And on slave, it will
try to get the value of this variable and use it to examine
filter rules without opening any tables on slave, if this values
is not available, the old approach is used and thus the bug will
still occur for when replicating from old masters.
sql/sql_class.h:
add member table_map_for_update to THD
sql/sql_parse.cc:
check filter rules by using table_map_for_update value
sql/sql_update.cc:
save the value of table_map_for_update
Diffstat (limited to 'sql/log_event.h')
-rw-r--r-- | sql/log_event.h | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/sql/log_event.h b/sql/log_event.h index 76d92b23189..041c41dc71b 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -237,12 +237,15 @@ struct sql_ex_info packet (i.e. a query) sent from client to master; First, an auxiliary log_event status vars estimation: */ -#define MAX_SIZE_LOG_EVENT_STATUS (4 /* flags2 */ + \ - 8 /* sql mode */ + \ - 1 + 1 + 255 /* catalog */ + \ - 4 /* autoinc */ + \ - 6 /* charset */ + \ - MAX_TIME_ZONE_NAME_LENGTH) +#define MAX_SIZE_LOG_EVENT_STATUS (1 + 4 /* type, flags2 */ + \ + 1 + 8 /* type, sql_mode */ + \ + 1 + 1 + 255 /* type, length, catalog */ + \ + 1 + 4 /* type, auto_increment */ + \ + 1 + 6 /* type, charset */ + \ + 1 + 1 + 255 /* type, length, time_zone */ + \ + 1 + 2 /* type, lc_time_names_number */ + \ + 1 + 2 /* type, charset_database_number */ + \ + 1 + 8 /* type, table_map_for_update */) #define MAX_LOG_EVENT_HEADER ( /* in order of Query_log_event::write */ \ LOG_EVENT_HEADER_LEN + /* write_header */ \ QUERY_HEADER_LEN + /* write_data */ \ @@ -306,6 +309,8 @@ struct sql_ex_info #define Q_LC_TIME_NAMES_CODE 7 #define Q_CHARSET_DATABASE_CODE 8 + +#define Q_TABLE_MAP_FOR_UPDATE_CODE 9 /* Intvar event post-header */ #define I_TYPE_OFFSET 0 @@ -1455,6 +1460,22 @@ protected: This field is written if it is not 0. </td> </tr> + <tr> + <td>table_map_for_update</td> + <td>Q_TABLE_MAP_FOR_UPDATE_CODE == 9</td> + <td>8 byte integer</td> + + <td>The value of the table map that is to be updated by the + multi-table update query statement. Every bit of this variable + represents a table, and is set to 1 if the corresponding table is + to be updated by this statement. + + The value of this variable is set when executing a multi-table update + statement and used by slave to apply filter rules without opening + all the tables on slave. This is required because some tables may + not exist on slave because of the filter rules. + </td> + </tr> </table> @subsection Query_log_event_notes_on_previous_versions Notes on Previous Versions @@ -1471,6 +1492,9 @@ protected: * See Q_CHARSET_DATABASE_CODE in the table above. + * When adding new status vars, please don't forget to update the + MAX_SIZE_LOG_EVENT_STATUS, and update function code_name + */ class Query_log_event: public Log_event { @@ -1548,6 +1572,11 @@ public: const char *time_zone_str; uint lc_time_names_number; /* 0 means en_US */ uint charset_database_number; + /* + map for tables that will be updated for a multi-table update query + statement, for other query statements, this will be zero. + */ + ulonglong table_map_for_update; #ifndef MYSQL_CLIENT |