Merge lp:~gl-az/percona-server/5.5-915814 into lp:percona-server/5.5

Proposed by George Ormond Lorch III
Status: Merged
Approved by: Alexey Kopytov
Approved revision: no longer in the source branch.
Merged at revision: 254
Proposed branch: lp:~gl-az/percona-server/5.5-915814
Merge into: lp:percona-server/5.5
Diff against target: 93 lines (+42/-3)
1 file modified
Percona-Server/sql/log_event.cc (+42/-3)
To merge this branch: bzr merge lp:~gl-az/percona-server/5.5-915814
Reviewer Review Type Date Requested Status
Alexey Kopytov (community) Approve
Review via email: mp+107306@code.launchpad.net

Description of the change

Corrected buffer allocation for query in replication slave event handler. Query buffers were being allocated at the wrong size causing query cache checks to read from and write to unallocated memory.

Fix addresses upstream MySQL issues 64624 and 62942.

Jenkins http://jenkins.percona.com/view/PS%205.5/job/percona-server-5.5-param/381/

To post a comment you must log in.
Revision history for this message
Alexey Kopytov (akopytov) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Percona-Server/sql/log_event.cc'
--- Percona-Server/sql/log_event.cc 2012-05-18 04:37:44 +0000
+++ Percona-Server/sql/log_event.cc 2012-05-25 00:05:24 +0000
@@ -3205,10 +3205,33 @@
3205 const char *query_arg, uint32 q_len_arg)3205 const char *query_arg, uint32 q_len_arg)
3206{3206{
3207 LEX_STRING new_db;3207 LEX_STRING new_db;
3208 char* query_buf;
3209 int query_buf_len;
3208 int expected_error,actual_error= 0;3210 int expected_error,actual_error= 0;
3209 HA_CREATE_INFO db_options;3211 HA_CREATE_INFO db_options;
32103212
3211 /*3213 /*
3214 We must allocate some extra memory for query cache
3215 The query buffer layout is:
3216 buffer :==
3217 <statement> The input statement(s)
3218 '\0' Terminating null char (1 byte)
3219 <length> Length of following current database name (size_t)
3220 <db_name> Name of current database
3221 <flags> Flags struct
3222 */
3223 query_buf_len = q_len_arg + 1 + sizeof(size_t) + thd->db_length
3224 + QUERY_CACHE_FLAGS_SIZE + 1;
3225 if ((query_buf= (char *) thd->alloc(query_buf_len)))
3226 {
3227 memcpy(query_buf, query_arg, q_len_arg);
3228 query_buf[q_len_arg]= 0;
3229 memcpy(query_buf+q_len_arg+1, (char *) &thd->db_length, sizeof(size_t));
3230 }
3231 else
3232 goto end;
3233
3234 /*
3212 Colleagues: please never free(thd->catalog) in MySQL. This would3235 Colleagues: please never free(thd->catalog) in MySQL. This would
3213 lead to bugs as here thd->catalog is a part of an alloced block,3236 lead to bugs as here thd->catalog is a part of an alloced block,
3214 not an entire alloced block (see3237 not an entire alloced block (see
@@ -3288,8 +3311,10 @@
3288 if (is_trans_keyword() || rpl_filter->db_ok(thd->db))3311 if (is_trans_keyword() || rpl_filter->db_ok(thd->db))
3289 {3312 {
3290 thd->set_time((time_t)when);3313 thd->set_time((time_t)when);
3291 thd->set_query_and_id((char*)query_arg, q_len_arg,3314
3315 thd->set_query_and_id((char*) query_buf, q_len_arg,
3292 thd->charset(), next_query_id());3316 thd->charset(), next_query_id());
3317
3293 thd->variables.pseudo_thread_id= thread_id; // for temp tables3318 thd->variables.pseudo_thread_id= thread_id; // for temp tables
3294 DBUG_PRINT("query",("%s", thd->query()));3319 DBUG_PRINT("query",("%s", thd->query()));
32953320
@@ -3352,7 +3377,7 @@
3352 result. This should be acceptable now. This is a reminder3377 result. This should be acceptable now. This is a reminder
3353 to fix this if any refactoring happens here sometime.3378 to fix this if any refactoring happens here sometime.
3354 */3379 */
3355 thd->set_query((char*) query_arg, q_len_arg, thd->charset());3380 thd->set_query((char*) query_buf, q_len_arg, thd->charset());
3356 }3381 }
3357 }3382 }
3358 if (time_zone_len)3383 if (time_zone_len)
@@ -4887,12 +4912,25 @@
4887 enum enum_duplicates handle_dup;4912 enum enum_duplicates handle_dup;
4888 bool ignore= 0;4913 bool ignore= 0;
4889 char *load_data_query;4914 char *load_data_query;
4915 int query_buf_len;
48904916
4891 /*4917 /*
4918 We must allocate some extra memory for query cache
4919 The query buffer layout is:
4920 buffer :==
4921 <statement> The input statement(s)
4922 '\0' Terminating null char (1 byte)
4923 <length> Length of following current database name (size_t)
4924 <db_name> Name of current database
4925 <flags> Flags struct
4926 */
4927 query_buf_len = get_query_buffer_length() + 1 + sizeof(size_t) + thd->db_length
4928 + QUERY_CACHE_FLAGS_SIZE + 1;
4929 /*
4892 Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST4930 Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST
4893 and written to slave's binlog if binlogging is on.4931 and written to slave's binlog if binlogging is on.
4894 */4932 */
4895 if (!(load_data_query= (char *)thd->alloc(get_query_buffer_length() + 1)))4933 if (!(load_data_query= (char *)thd->alloc(query_buf_len)))
4896 {4934 {
4897 /*4935 /*
4898 This will set thd->fatal_error in case of OOM. So we surely will notice4936 This will set thd->fatal_error in case of OOM. So we surely will notice
@@ -4903,6 +4941,7 @@
49034941
4904 print_query(FALSE, NULL, load_data_query, &end, NULL, NULL);4942 print_query(FALSE, NULL, load_data_query, &end, NULL, NULL);
4905 *end= 0;4943 *end= 0;
4944 memcpy(end+1, (char *) &thd->db_length, sizeof(size_t));
4906 thd->set_query(load_data_query, (uint) (end - load_data_query));4945 thd->set_query(load_data_query, (uint) (end - load_data_query));
49074946
4908 if (sql_ex.opt_flags & REPLACE_FLAG)4947 if (sql_ex.opt_flags & REPLACE_FLAG)

Subscribers

People subscribed via source and target branches