Merge lp:~sergei.glushchenko/percona-server/5.6-ps-bug1182535 into lp:percona-server/5.6

Proposed by Sergei Glushchenko
Status: Merged
Approved by: Alexey Kopytov
Approved revision: no longer in the source branch.
Merged at revision: 558
Proposed branch: lp:~sergei.glushchenko/percona-server/5.6-ps-bug1182535
Merge into: lp:percona-server/5.6
Diff against target: 318 lines (+145/-47)
8 files modified
mysql-test/r/percona_bug1182535.result (+24/-0)
mysql-test/t/percona_bug1182535-master.opt (+1/-0)
mysql-test/t/percona_bug1182535.test (+48/-0)
sql/log.cc (+8/-10)
sql/sql_audit.cc (+0/-21)
sql/sql_audit.h (+51/-4)
sql/sql_parse.cc (+3/-2)
sql/sql_prepare.cc (+10/-10)
To merge this branch: bzr merge lp:~sergei.glushchenko/percona-server/5.6-ps-bug1182535
Reviewer Review Type Date Requested Status
Alexey Kopytov (community) Approve
Laurynas Biveinis (community) Needs Fixing
Review via email: mp+169196@code.launchpad.net

Description of the change

Merge fix for bug 1182535 from 5.5 series.
Fix is modified in order to take care of new --log_raw option.

To post a comment you must log in.
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :

Repushed, changed wrong commit message.

Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

Same comments as for the 5.5 MP

review: Needs Fixing
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :

comments on 5.5 branch were addressed

Revision history for this message
Alexey Kopytov (akopytov) wrote :

Same comments as in the 5.5 MP + the changes in sql_parse.cc are fishy. Don't we always do query rewriting with those changes, regardless of the server options?

review: Needs Fixing
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :

Indeed, that is odd that it is not covered by test suite.

Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :
Revision history for this message
Alexey Kopytov (akopytov) wrote :

Sergei,

Same comments as in the 5.5 MP + the changes in sql_parse.cc are still wrong:

1. Now we do query rewriting even if we don't need it ('rewrite' will be true if all of opt_log, opt_log_raw and thd->slave_thread are false).

2. If the general log is disabled, we will still do general logging, because the "if (!thd->slave_thread)" check will pass.

3. If both the general log and --log-raw are enabled, we will be general-logging queries twice, once in dispatch_command() and once in mysql_parse()

Do we really need to change anything in sql_parse.cc? I.e. what problem are you trying to solve?

review: Needs Fixing
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :

Hi Alexey,

> 1. Now we do query rewriting even if we don't need it ('rewrite' will be true if all of opt_log, opt_log_raw and thd->slave_thread are false).
Don't we need to rewrite queries for audit plugin? Is it secure to send raw passwords to it?

> 2. If the general log is disabled, we will still do general logging, because the "if (!thd->slave_thread)" check will pass.
No, we don't since opt_log is checked in general_log_write.

> 3. If both the general log and --log-raw are enabled, we will be general-logging queries twice, once in dispatch_command() and once in mysql_parse()
Yes, I think the best choice is to remove logging from dispatch_command().

> Do we really need to change anything in sql_parse.cc? I.e. what problem are you trying to solve?
Yes, we do. This change simply allows us to still notify audit plugin even if opt_log in not specified. This is what entire bug is about.

http://jenkins.percona.com/view/PS%205.6/job/percona-server-5.6-param/193/

Revision history for this message
Alexey Kopytov (akopytov) wrote :

Hi Sergei,

On Fri, 12 Jul 2013 14:03:35 -0000, Sergei Glushchenko wrote:> Hi Alexey,
>
>> 1. Now we do query rewriting even if we don't need it ('rewrite' will be true if all of opt_log, opt_log_raw and thd->slave_thread are false).
> Don't we need to rewrite queries for audit plugin? Is it secure to send raw passwords to it?

My point was that we only need to rewrite queries only if there's an audit plugin installed. With the current patch we will be rewriting queries even if no general log or audit plugins are enabled.

>
>> 2. If the general log is disabled, we will still do general logging, because the "if (!thd->slave_thread)" check will pass.
> No, we don't since opt_log is checked in general_log_write.
>

Right.

>> 3. If both the general log and --log-raw are enabled, we will be general-logging queries twice, once in dispatch_command() and once in mysql_parse()
> Yes, I think the best choice is to remove logging from dispatch_command().
>

Sounds good.

>> Do we really need to change anything in sql_parse.cc? I.e. what problem are you trying to solve?
> Yes, we do. This change simply allows us to still notify audit plugin even if opt_log in not specified. This is what entire bug is about.
>

OK, I see. But again, I don't like that we do unnecessary work even if no logging or audit plugins are enabled. That's a rather serious performance issue. What about introducing mysql_audit_general_log_enabled() and calling it to see if we do need to rewrite query for an audit plugin?

review: Needs Fixing
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :
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
=== added file 'mysql-test/r/percona_bug1182535.result'
--- mysql-test/r/percona_bug1182535.result 1970-01-01 00:00:00 +0000
+++ mysql-test/r/percona_bug1182535.result 2014-01-15 14:48:48 +0000
@@ -0,0 +1,24 @@
1SET @general_log_save = @@general_log;
2SET GLOBAL general_log=OFF;
3CREATE PROCEDURE simpleproc (OUT param1 INT)
4BEGIN
5SELECT 1 INTO param1;
6END//
7INSTALL PLUGIN NULL_AUDIT SONAME 'AUDIT_NULL';
8SELECT 1;
91
101
11CALL simpleproc(@a);
12PREPARE stmt1 FROM 'SELECT 1';
13EXECUTE stmt1;
141
151
16SHOW STATUS LIKE 'Audit_null_general_log';
17Variable_name Value
18Audit_null_general_log 7
19DEALLOCATE PREPARE stmt1;
20DROP PROCEDURE simpleproc;
21UNINSTALL PLUGIN NULL_AUDIT;
22Warnings:
23Warning 1620 Plugin is busy and will be uninstalled on shutdown
24SET GLOBAL general_log=@general_log_save;
025
=== added file 'mysql-test/t/percona_bug1182535-master.opt'
--- mysql-test/t/percona_bug1182535-master.opt 1970-01-01 00:00:00 +0000
+++ mysql-test/t/percona_bug1182535-master.opt 2014-01-15 14:48:48 +0000
@@ -0,0 +1,1 @@
1$AUDIT_NULL_OPT
02
=== added file 'mysql-test/t/percona_bug1182535.test'
--- mysql-test/t/percona_bug1182535.test 1970-01-01 00:00:00 +0000
+++ mysql-test/t/percona_bug1182535.test 2014-01-15 14:48:48 +0000
@@ -0,0 +1,48 @@
1#########################################################################
2# Test for bug 1182535 (upstream bug 60782)
3# No MYSQL_AUDIT_GENERAL_LOG notifications with general log off
4#
5# Load audit_null plugin to check that it notified about
6# general log events with general log turned off
7#########################################################################
8
9--source include/have_null_audit_plugin.inc
10--source include/not_embedded.inc
11
12SET @general_log_save = @@general_log;
13SET GLOBAL general_log=OFF;
14
15DELIMITER //;
16
17CREATE PROCEDURE simpleproc (OUT param1 INT)
18BEGIN
19 SELECT 1 INTO param1;
20END//
21
22DELIMITER ;//
23
24# load audit plugin
25--replace_result $AUDIT_NULL AUDIT_NULL
26--eval INSTALL PLUGIN NULL_AUDIT SONAME '$AUDIT_NULL'
27
28# status variable should show 8 general log events
29# Query SELECT 1
30# Query CALL simpleproc(@a)
31# Query SELECT 1 INTO param1 ; will not be emitted
32# ; this is OK for scalability metrcis
33# Query PREPARE stmt1 FROM 'SELECT 1'
34# Prepare SELECT 1
35# Query EXECUTE stmt1
36# Execute SELECT 1
37# Query SHOW STATUS LIKE 'Audit_null_general_log';
38SELECT 1;
39CALL simpleproc(@a);
40PREPARE stmt1 FROM 'SELECT 1';
41EXECUTE stmt1;
42SHOW STATUS LIKE 'Audit_null_general_log';
43
44DEALLOCATE PREPARE stmt1;
45DROP PROCEDURE simpleproc;
46UNINSTALL PLUGIN NULL_AUDIT;
47
48SET GLOBAL general_log=@general_log_save;
049
=== modified file 'sql/log.cc'
--- sql/log.cc 2013-12-18 04:22:33 +0000
+++ sql/log.cc 2014-01-15 14:48:48 +0000
@@ -1145,12 +1145,6 @@
11451145
1146 current_time= my_time(0);1146 current_time= my_time(0);
11471147
1148 mysql_audit_general_log(thd, current_time,
1149 user_host_buff, user_host_len,
1150 command_name[(uint) command].str,
1151 command_name[(uint) command].length,
1152 query, query_length);
1153
1154 while (*current_handler)1148 while (*current_handler)
1155 error|= (*current_handler++)->1149 error|= (*current_handler++)->
1156 log_general(thd, current_time, user_host_buff,1150 log_general(thd, current_time, user_host_buff,
@@ -1177,6 +1171,12 @@
1177 else1171 else
1178 message_buff[0]= '\0';1172 message_buff[0]= '\0';
11791173
1174 mysql_audit_general_log(thd, command, message_buff, message_buff_len);
1175
1176 /* Print the message to the buffer if we want to log this kind of commands */
1177 if (! logger.log_command(thd, command))
1178 return FALSE;
1179
1180 return general_log_write(thd, command, message_buff, message_buff_len);1180 return general_log_write(thd, command, message_buff, message_buff_len);
1181}1181}
11821182
@@ -2234,10 +2234,6 @@
2234 va_list args;2234 va_list args;
2235 uint error= 0;2235 uint error= 0;
22362236
2237 /* Print the message to the buffer if we want to log this king of commands */
2238 if (! logger.log_command(thd, command))
2239 return FALSE;
2240
2241 va_start(args, format);2237 va_start(args, format);
2242 error= logger.general_log_print(thd, command, format, args);2238 error= logger.general_log_print(thd, command, format, args);
2243 va_end(args);2239 va_end(args);
@@ -2248,6 +2244,8 @@
2248bool general_log_write(THD *thd, enum enum_server_command command,2244bool general_log_write(THD *thd, enum enum_server_command command,
2249 const char *query, uint query_length)2245 const char *query, uint query_length)
2250{2246{
2247 mysql_audit_general_log(thd, command, query, query_length);
2248
2251 /* Write the message to the log if we want to log this king of commands */2249 /* Write the message to the log if we want to log this king of commands */
2252 if (logger.log_command(thd, command))2250 if (logger.log_command(thd, command))
2253 return logger.general_log_write(thd, command, query, query_length);2251 return logger.general_log_write(thd, command, query, query_length);
22542252
=== modified file 'sql/sql_audit.cc'
--- sql/sql_audit.cc 2013-08-23 03:57:09 +0000
+++ sql/sql_audit.cc 2014-01-15 14:48:48 +0000
@@ -35,27 +35,6 @@
35 const void *event);35 const void *event);
3636
3737
38static inline
39void set_audit_mask(unsigned long *mask, uint event_class)
40{
41 mask[0]= 1;
42 mask[0]<<= event_class;
43}
44
45static inline
46void add_audit_mask(unsigned long *mask, const unsigned long *rhs)
47{
48 mask[0]|= rhs[0];
49}
50
51static inline
52bool check_audit_mask(const unsigned long *lhs,
53 const unsigned long *rhs)
54{
55 return !(lhs[0] & rhs[0]);
56}
57
58
59typedef void (*audit_handler_t)(THD *thd, uint event_subtype, va_list ap);38typedef void (*audit_handler_t)(THD *thd, uint event_subtype, va_list ap);
6039
61/**40/**
6241
=== modified file 'sql/sql_audit.h'
--- sql/sql_audit.h 2013-08-23 03:57:09 +0000
+++ sql/sql_audit.h 2014-01-15 14:48:48 +0000
@@ -22,6 +22,7 @@
22#include <mysql/plugin_audit.h>22#include <mysql/plugin_audit.h>
23#include "sql_class.h"23#include "sql_class.h"
24#include "sql_rewrite.h"24#include "sql_rewrite.h"
25#include "sql_parse.h" // command_name
2526
26extern unsigned long mysql_global_audit_mask[];27extern unsigned long mysql_global_audit_mask[];
2728
@@ -55,6 +56,45 @@
55 "", "]", NullS) - buf;56 "", "]", NullS) - buf;
56}57}
5758
59static inline
60void set_audit_mask(unsigned long *mask, uint event_class)
61{
62 mask[0]= 1;
63 mask[0]<<= event_class;
64}
65
66static inline
67void add_audit_mask(unsigned long *mask, const unsigned long *rhs)
68{
69 mask[0]|= rhs[0];
70}
71
72static inline
73bool check_audit_mask(const unsigned long *lhs,
74 const unsigned long *rhs)
75{
76 return !(lhs[0] & rhs[0]);
77}
78
79/**
80 @brief Check if audit logging enables for specified class
81
82 @param[in] thd MySQL thread handle
83 @param[in] event_class Audit event class
84*/
85static inline
86bool mysql_audit_enabled(THD *thd, uint event_class)
87{
88#ifndef EMBEDDED_LIBRARY
89 unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
90 set_audit_mask(event_class_mask, event_class);
91 if (thd && !check_audit_mask(mysql_global_audit_mask, event_class_mask) &&
92 check_audit_mask(thd->audit_class_mask, event_class_mask))
93 return true;
94#endif
95 return false;
96}
97
58/**98/**
59 Call audit plugins of GENERAL audit class, MYSQL_AUDIT_GENERAL_LOG subtype.99 Call audit plugins of GENERAL audit class, MYSQL_AUDIT_GENERAL_LOG subtype.
60 100
@@ -69,14 +109,20 @@
69*/109*/
70 110
71static inline111static inline
72void mysql_audit_general_log(THD *thd, time_t time,112void mysql_audit_general_log(THD *thd,
73 const char *user, uint userlen,113 enum enum_server_command command,
74 const char *cmd, uint cmdlen,
75 const char *query, uint querylen)114 const char *query, uint querylen)
76{115{
77#ifndef EMBEDDED_LIBRARY116#ifndef EMBEDDED_LIBRARY
78 if (mysql_global_audit_mask[0] & MYSQL_AUDIT_GENERAL_CLASSMASK)117 if (mysql_global_audit_mask[0] & MYSQL_AUDIT_GENERAL_CLASSMASK)
79 {118 {
119 time_t time;
120 char user[MAX_USER_HOST_SIZE + 1];
121 uint userlen;
122
123 userlen= make_user_name(thd, user);
124 time= my_time(0);
125
80 MYSQL_LEX_STRING sql_command, ip, host, external_user;126 MYSQL_LEX_STRING sql_command, ip, host, external_user;
81 static MYSQL_LEX_STRING empty= { C_STRING_WITH_LEN("") };127 static MYSQL_LEX_STRING empty= { C_STRING_WITH_LEN("") };
82128
@@ -102,7 +148,8 @@
102 : global_system_variables.character_set_client;148 : global_system_variables.character_set_client;
103149
104 mysql_audit_notify(thd, MYSQL_AUDIT_GENERAL_CLASS, MYSQL_AUDIT_GENERAL_LOG,150 mysql_audit_notify(thd, MYSQL_AUDIT_GENERAL_CLASS, MYSQL_AUDIT_GENERAL_LOG,
105 0, time, user, userlen, cmd, cmdlen, query, querylen,151 0, time, user, userlen, command_name[(uint) command].str,
152 command_name[(uint) command].length, query, querylen,
106 clientcs, 0, sql_command, host, external_user, ip);153 clientcs, 0, sql_command, host, external_user, ip);
107 }154 }
108#endif155#endif
109156
=== modified file 'sql/sql_parse.cc'
--- sql/sql_parse.cc 2013-12-16 08:45:31 +0000
+++ sql/sql_parse.cc 2014-01-15 14:48:48 +0000
@@ -6572,9 +6572,10 @@
6572 no logging happens at all. If rewriting does not happen here,6572 no logging happens at all. If rewriting does not happen here,
6573 thd->rewritten_query is still empty from being reset in alloc_query().6573 thd->rewritten_query is still empty from being reset in alloc_query().
6574 */6574 */
6575 bool general= (opt_log && ! (opt_log_raw || thd->slave_thread));6575 bool audit= mysql_audit_enabled(thd, MYSQL_AUDIT_GENERAL_CLASS);
6576 bool general= ((opt_log || audit) && !(opt_log_raw || thd->slave_thread));
65766577
6577 if (general || opt_slow_log || opt_bin_log)6578 if (general || audit || opt_slow_log || opt_bin_log)
6578 {6579 {
6579 mysql_rewrite_query(thd);6580 mysql_rewrite_query(thd);
65806581
65816582
=== modified file 'sql/sql_prepare.cc'
--- sql/sql_prepare.cc 2013-12-16 08:45:31 +0000
+++ sql/sql_prepare.cc 2014-01-15 14:48:48 +0000
@@ -309,12 +309,12 @@
309 return;309 return;
310310
311 if (thd->rewritten_query.length())311 if (thd->rewritten_query.length())
312 logger.general_log_write(thd, COM_STMT_EXECUTE,312 general_log_write(thd, COM_STMT_EXECUTE,
313 thd->rewritten_query.c_ptr_safe(),313 thd->rewritten_query.c_ptr_safe(),
314 thd->rewritten_query.length());314 thd->rewritten_query.length());
315 else315 else
316 logger.general_log_write(thd, COM_STMT_EXECUTE,316 general_log_write(thd, COM_STMT_EXECUTE,
317 thd->query(), thd->query_length());317 thd->query(), thd->query_length());
318}318}
319319
320320
@@ -3843,12 +3843,12 @@
3843 if (thd->sp_runtime_ctx == NULL)3843 if (thd->sp_runtime_ctx == NULL)
3844 {3844 {
3845 if (thd->rewritten_query.length())3845 if (thd->rewritten_query.length())
3846 logger.general_log_write(thd, COM_STMT_PREPARE,3846 general_log_write(thd, COM_STMT_PREPARE,
3847 thd->rewritten_query.c_ptr_safe(),3847 thd->rewritten_query.c_ptr_safe(),
3848 thd->rewritten_query.length());3848 thd->rewritten_query.length());
3849 else3849 else
3850 logger.general_log_write(thd, COM_STMT_PREPARE,3850 general_log_write(thd, COM_STMT_PREPARE,
3851 query(), query_length());3851 query(), query_length());
3852 }3852 }
3853 }3853 }
3854 DBUG_RETURN(error);3854 DBUG_RETURN(error);

Subscribers

People subscribed via source and target branches