Auto-merge from mysql-next-mr.
This commit is contained in:
commit
f30223d9f5
@ -19,7 +19,8 @@ BUILT_SOURCES = $(HEADERS_GEN_MAKE) link_sources probes_mysql_nodtrace.h
|
|||||||
HEADERS_GEN_CONFIGURE = mysql_version.h
|
HEADERS_GEN_CONFIGURE = mysql_version.h
|
||||||
HEADERS_GEN_MAKE = my_config.h
|
HEADERS_GEN_MAKE = my_config.h
|
||||||
HEADERS_ABI = mysql.h mysql_com.h mysql_time.h \
|
HEADERS_ABI = mysql.h mysql_com.h mysql_time.h \
|
||||||
my_list.h my_alloc.h typelib.h mysql/plugin.h
|
my_list.h my_alloc.h typelib.h mysql/plugin.h \
|
||||||
|
mysql/plugin_audit.h mysql/plugin_ftparser.h
|
||||||
pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \
|
pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \
|
||||||
my_xml.h mysql_embed.h mysql/services.h \
|
my_xml.h mysql_embed.h mysql/services.h \
|
||||||
mysql/service_my_snprintf.h mysql/service_thd_alloc.h \
|
mysql/service_my_snprintf.h mysql/service_thd_alloc.h \
|
||||||
|
@ -66,8 +66,9 @@ typedef struct st_mysql_xid MYSQL_XID;
|
|||||||
#define MYSQL_FTPARSER_PLUGIN 2 /* Full-text parser plugin */
|
#define MYSQL_FTPARSER_PLUGIN 2 /* Full-text parser plugin */
|
||||||
#define MYSQL_DAEMON_PLUGIN 3 /* The daemon/raw plugin type */
|
#define MYSQL_DAEMON_PLUGIN 3 /* The daemon/raw plugin type */
|
||||||
#define MYSQL_INFORMATION_SCHEMA_PLUGIN 4 /* The I_S plugin type */
|
#define MYSQL_INFORMATION_SCHEMA_PLUGIN 4 /* The I_S plugin type */
|
||||||
#define MYSQL_REPLICATION_PLUGIN 5 /* The replication plugin type */
|
#define MYSQL_AUDIT_PLUGIN 5 /* The Audit plugin type */
|
||||||
#define MYSQL_MAX_PLUGIN_TYPE_NUM 6 /* The number of plugin types */
|
#define MYSQL_REPLICATION_PLUGIN 6 /* The replication plugin type */
|
||||||
|
#define MYSQL_MAX_PLUGIN_TYPE_NUM 7 /* The number of plugin types */
|
||||||
|
|
||||||
/* We use the following strings to define licenses for plugins */
|
/* We use the following strings to define licenses for plugins */
|
||||||
#define PLUGIN_LICENSE_PROPRIETARY 0
|
#define PLUGIN_LICENSE_PROPRIETARY 0
|
||||||
@ -403,191 +404,7 @@ struct st_mysql_plugin
|
|||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
API for Full-text parser plugin. (MYSQL_FTPARSER_PLUGIN)
|
API for Full-text parser plugin. (MYSQL_FTPARSER_PLUGIN)
|
||||||
*/
|
*/
|
||||||
|
#include "plugin_ftparser.h"
|
||||||
#define MYSQL_FTPARSER_INTERFACE_VERSION 0x0100
|
|
||||||
|
|
||||||
/* Parsing modes. Set in MYSQL_FTPARSER_PARAM::mode */
|
|
||||||
enum enum_ftparser_mode
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Fast and simple mode. This mode is used for indexing, and natural
|
|
||||||
language queries.
|
|
||||||
|
|
||||||
The parser is expected to return only those words that go into the
|
|
||||||
index. Stopwords or too short/long words should not be returned. The
|
|
||||||
'boolean_info' argument of mysql_add_word() does not have to be set.
|
|
||||||
*/
|
|
||||||
MYSQL_FTPARSER_SIMPLE_MODE= 0,
|
|
||||||
|
|
||||||
/*
|
|
||||||
Parse with stopwords mode. This mode is used in boolean searches for
|
|
||||||
"phrase matching."
|
|
||||||
|
|
||||||
The parser is not allowed to ignore words in this mode. Every word
|
|
||||||
should be returned, including stopwords and words that are too short
|
|
||||||
or long. The 'boolean_info' argument of mysql_add_word() does not
|
|
||||||
have to be set.
|
|
||||||
*/
|
|
||||||
MYSQL_FTPARSER_WITH_STOPWORDS= 1,
|
|
||||||
|
|
||||||
/*
|
|
||||||
Parse in boolean mode. This mode is used to parse a boolean query string.
|
|
||||||
|
|
||||||
The parser should provide a valid MYSQL_FTPARSER_BOOLEAN_INFO
|
|
||||||
structure in the 'boolean_info' argument to mysql_add_word().
|
|
||||||
Usually that means that the parser should recognize boolean operators
|
|
||||||
in the parsing stream and set appropriate fields in
|
|
||||||
MYSQL_FTPARSER_BOOLEAN_INFO structure accordingly. As for
|
|
||||||
MYSQL_FTPARSER_WITH_STOPWORDS mode, no word should be ignored.
|
|
||||||
Instead, use FT_TOKEN_STOPWORD for the token type of such a word.
|
|
||||||
*/
|
|
||||||
MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Token types for boolean mode searching (used for the type member of
|
|
||||||
MYSQL_FTPARSER_BOOLEAN_INFO struct)
|
|
||||||
|
|
||||||
FT_TOKEN_EOF: End of data.
|
|
||||||
FT_TOKEN_WORD: Regular word.
|
|
||||||
FT_TOKEN_LEFT_PAREN: Left parenthesis (start of group/sub-expression).
|
|
||||||
FT_TOKEN_RIGHT_PAREN: Right parenthesis (end of group/sub-expression).
|
|
||||||
FT_TOKEN_STOPWORD: Stopword.
|
|
||||||
*/
|
|
||||||
|
|
||||||
enum enum_ft_token_type
|
|
||||||
{
|
|
||||||
FT_TOKEN_EOF= 0,
|
|
||||||
FT_TOKEN_WORD= 1,
|
|
||||||
FT_TOKEN_LEFT_PAREN= 2,
|
|
||||||
FT_TOKEN_RIGHT_PAREN= 3,
|
|
||||||
FT_TOKEN_STOPWORD= 4
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
This structure is used in boolean search mode only. It conveys
|
|
||||||
boolean-mode metadata to the MySQL search engine for every word in
|
|
||||||
the search query. A valid instance of this structure must be filled
|
|
||||||
in by the plugin parser and passed as an argument in the call to
|
|
||||||
mysql_add_word (the callback function in the MYSQL_FTPARSER_PARAM
|
|
||||||
structure) when a query is parsed in boolean mode.
|
|
||||||
|
|
||||||
type: The token type. Should be one of the enum_ft_token_type values.
|
|
||||||
|
|
||||||
yesno: Whether the word must be present for a match to occur:
|
|
||||||
>0 Must be present
|
|
||||||
<0 Must not be present
|
|
||||||
0 Neither; the word is optional but its presence increases the relevance
|
|
||||||
With the default settings of the ft_boolean_syntax system variable,
|
|
||||||
>0 corresponds to the '+' operator, <0 corrresponds to the '-' operator,
|
|
||||||
and 0 means neither operator was used.
|
|
||||||
|
|
||||||
weight_adjust: A weighting factor that determines how much a match
|
|
||||||
for the word counts. Positive values increase, negative - decrease the
|
|
||||||
relative word's importance in the query.
|
|
||||||
|
|
||||||
wasign: The sign of the word's weight in the query. If it's non-negative
|
|
||||||
the match for the word will increase document relevance, if it's
|
|
||||||
negative - decrease (the word becomes a "noise word", the less of it the
|
|
||||||
better).
|
|
||||||
|
|
||||||
trunc: Corresponds to the '*' operator in the default setting of the
|
|
||||||
ft_boolean_syntax system variable.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct st_mysql_ftparser_boolean_info
|
|
||||||
{
|
|
||||||
enum enum_ft_token_type type;
|
|
||||||
int yesno;
|
|
||||||
int weight_adjust;
|
|
||||||
char wasign;
|
|
||||||
char trunc;
|
|
||||||
/* These are parser state and must be removed. */
|
|
||||||
char prev;
|
|
||||||
char *quot;
|
|
||||||
} MYSQL_FTPARSER_BOOLEAN_INFO;
|
|
||||||
|
|
||||||
/*
|
|
||||||
The following flag means that buffer with a string (document, word)
|
|
||||||
may be overwritten by the caller before the end of the parsing (that is
|
|
||||||
before st_mysql_ftparser::deinit() call). If one needs the string
|
|
||||||
to survive between two successive calls of the parsing function, she
|
|
||||||
needs to save a copy of it. The flag may be set by MySQL before calling
|
|
||||||
st_mysql_ftparser::parse(), or it may be set by a plugin before calling
|
|
||||||
st_mysql_ftparser_param::mysql_parse() or
|
|
||||||
st_mysql_ftparser_param::mysql_add_word().
|
|
||||||
*/
|
|
||||||
#define MYSQL_FTFLAGS_NEED_COPY 1
|
|
||||||
|
|
||||||
/*
|
|
||||||
An argument of the full-text parser plugin. This structure is
|
|
||||||
filled in by MySQL server and passed to the parsing function of the
|
|
||||||
plugin as an in/out parameter.
|
|
||||||
|
|
||||||
mysql_parse: A pointer to the built-in parser implementation of the
|
|
||||||
server. It's set by the server and can be used by the parser plugin
|
|
||||||
to invoke the MySQL default parser. If plugin's role is to extract
|
|
||||||
textual data from .doc, .pdf or .xml content, it might extract
|
|
||||||
plaintext from the content, and then pass the text to the default
|
|
||||||
MySQL parser to be parsed.
|
|
||||||
|
|
||||||
mysql_add_word: A server callback to add a new word. When parsing
|
|
||||||
a document, the server sets this to point at a function that adds
|
|
||||||
the word to MySQL full-text index. When parsing a search query,
|
|
||||||
this function will add the new word to the list of words to search
|
|
||||||
for. The boolean_info argument can be NULL for all cases except
|
|
||||||
when mode is MYSQL_FTPARSER_FULL_BOOLEAN_INFO.
|
|
||||||
|
|
||||||
ftparser_state: A generic pointer. The plugin can set it to point
|
|
||||||
to information to be used internally for its own purposes.
|
|
||||||
|
|
||||||
mysql_ftparam: This is set by the server. It is used by MySQL functions
|
|
||||||
called via mysql_parse() and mysql_add_word() callback. The plugin
|
|
||||||
should not modify it.
|
|
||||||
|
|
||||||
cs: Information about the character set of the document or query string.
|
|
||||||
|
|
||||||
doc: A pointer to the document or query string to be parsed.
|
|
||||||
|
|
||||||
length: Length of the document or query string, in bytes.
|
|
||||||
|
|
||||||
flags: See MYSQL_FTFLAGS_* constants above.
|
|
||||||
|
|
||||||
mode: The parsing mode. With boolean operators, with stopwords, or
|
|
||||||
nothing. See enum_ftparser_mode above.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct st_mysql_ftparser_param
|
|
||||||
{
|
|
||||||
int (*mysql_parse)(struct st_mysql_ftparser_param *,
|
|
||||||
char *doc, int doc_len);
|
|
||||||
int (*mysql_add_word)(struct st_mysql_ftparser_param *,
|
|
||||||
char *word, int word_len,
|
|
||||||
MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
|
|
||||||
void *ftparser_state;
|
|
||||||
void *mysql_ftparam;
|
|
||||||
struct charset_info_st *cs;
|
|
||||||
char *doc;
|
|
||||||
int length;
|
|
||||||
int flags;
|
|
||||||
enum enum_ftparser_mode mode;
|
|
||||||
} MYSQL_FTPARSER_PARAM;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Full-text parser descriptor.
|
|
||||||
|
|
||||||
interface_version is, e.g., MYSQL_FTPARSER_INTERFACE_VERSION.
|
|
||||||
The parsing, initialization, and deinitialization functions are
|
|
||||||
invoked per SQL statement for which the parser is used.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct st_mysql_ftparser
|
|
||||||
{
|
|
||||||
int interface_version;
|
|
||||||
int (*parse)(MYSQL_FTPARSER_PARAM *param);
|
|
||||||
int (*init)(MYSQL_FTPARSER_PARAM *param);
|
|
||||||
int (*deinit)(MYSQL_FTPARSER_PARAM *param);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
API for Storage Engine plugin. (MYSQL_DAEMON_PLUGIN)
|
API for Storage Engine plugin. (MYSQL_DAEMON_PLUGIN)
|
||||||
@ -596,6 +413,17 @@ struct st_mysql_ftparser
|
|||||||
/* handlertons of different MySQL releases are incompatible */
|
/* handlertons of different MySQL releases are incompatible */
|
||||||
#define MYSQL_DAEMON_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
|
#define MYSQL_DAEMON_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Here we define only the descriptor structure, that is referred from
|
||||||
|
st_mysql_plugin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct st_mysql_daemon
|
||||||
|
{
|
||||||
|
int interface_version;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
API for I_S plugin. (MYSQL_INFORMATION_SCHEMA_PLUGIN)
|
API for I_S plugin. (MYSQL_INFORMATION_SCHEMA_PLUGIN)
|
||||||
*/
|
*/
|
||||||
@ -603,6 +431,17 @@ struct st_mysql_ftparser
|
|||||||
/* handlertons of different MySQL releases are incompatible */
|
/* handlertons of different MySQL releases are incompatible */
|
||||||
#define MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
|
#define MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Here we define only the descriptor structure, that is referred from
|
||||||
|
st_mysql_plugin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct st_mysql_information_schema
|
||||||
|
{
|
||||||
|
int interface_version;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
API for Storage Engine plugin. (MYSQL_STORAGE_ENGINE_PLUGIN)
|
API for Storage Engine plugin. (MYSQL_STORAGE_ENGINE_PLUGIN)
|
||||||
*/
|
*/
|
||||||
@ -623,25 +462,6 @@ struct st_mysql_storage_engine
|
|||||||
|
|
||||||
struct handlerton;
|
struct handlerton;
|
||||||
|
|
||||||
/*
|
|
||||||
Here we define only the descriptor structure, that is referred from
|
|
||||||
st_mysql_plugin.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct st_mysql_daemon
|
|
||||||
{
|
|
||||||
int interface_version;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Here we define only the descriptor structure, that is referred from
|
|
||||||
st_mysql_plugin.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct st_mysql_information_schema
|
|
||||||
{
|
|
||||||
int interface_version;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
API for Replication plugin. (MYSQL_REPLICATION_PLUGIN)
|
API for Replication plugin. (MYSQL_REPLICATION_PLUGIN)
|
||||||
@ -655,7 +475,7 @@ struct st_mysql_information_schema
|
|||||||
int interface_version;
|
int interface_version;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*************************************************************************
|
||||||
st_mysql_value struct for reading values from mysqld.
|
st_mysql_value struct for reading values from mysqld.
|
||||||
Used by server variables framework to parse user-provided values.
|
Used by server variables framework to parse user-provided values.
|
||||||
Will be used for arguments when implementing UDFs.
|
Will be used for arguments when implementing UDFs.
|
||||||
|
@ -76,6 +76,8 @@ struct st_mysql_plugin
|
|||||||
struct st_mysql_sys_var **system_vars;
|
struct st_mysql_sys_var **system_vars;
|
||||||
void * __reserved1;
|
void * __reserved1;
|
||||||
};
|
};
|
||||||
|
#include "plugin_ftparser.h"
|
||||||
|
#include "plugin.h"
|
||||||
enum enum_ftparser_mode
|
enum enum_ftparser_mode
|
||||||
{
|
{
|
||||||
MYSQL_FTPARSER_SIMPLE_MODE= 0,
|
MYSQL_FTPARSER_SIMPLE_MODE= 0,
|
||||||
@ -122,11 +124,6 @@ struct st_mysql_ftparser
|
|||||||
int (*init)(MYSQL_FTPARSER_PARAM *param);
|
int (*init)(MYSQL_FTPARSER_PARAM *param);
|
||||||
int (*deinit)(MYSQL_FTPARSER_PARAM *param);
|
int (*deinit)(MYSQL_FTPARSER_PARAM *param);
|
||||||
};
|
};
|
||||||
struct st_mysql_storage_engine
|
|
||||||
{
|
|
||||||
int interface_version;
|
|
||||||
};
|
|
||||||
struct handlerton;
|
|
||||||
struct st_mysql_daemon
|
struct st_mysql_daemon
|
||||||
{
|
{
|
||||||
int interface_version;
|
int interface_version;
|
||||||
@ -135,6 +132,11 @@ struct st_mysql_information_schema
|
|||||||
{
|
{
|
||||||
int interface_version;
|
int interface_version;
|
||||||
};
|
};
|
||||||
|
struct st_mysql_storage_engine
|
||||||
|
{
|
||||||
|
int interface_version;
|
||||||
|
};
|
||||||
|
struct handlerton;
|
||||||
struct Mysql_replication {
|
struct Mysql_replication {
|
||||||
int interface_version;
|
int interface_version;
|
||||||
};
|
};
|
||||||
|
97
include/mysql/plugin_audit.h
Normal file
97
include/mysql/plugin_audit.h
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/* Copyright (C) 2007 MySQL AB
|
||||||
|
|
||||||
|
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
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#ifndef _my_audit_h
|
||||||
|
#define _my_audit_h
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
API for Audit plugin. (MYSQL_AUDIT_PLUGIN)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "plugin.h"
|
||||||
|
|
||||||
|
#define MYSQL_AUDIT_CLASS_MASK_SIZE 1
|
||||||
|
|
||||||
|
#define MYSQL_AUDIT_INTERFACE_VERSION 0x0100
|
||||||
|
|
||||||
|
/*
|
||||||
|
The first word in every event class struct indicates the specific
|
||||||
|
class of the event.
|
||||||
|
*/
|
||||||
|
struct mysql_event
|
||||||
|
{
|
||||||
|
int event_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
AUDIT CLASS : GENERAL
|
||||||
|
|
||||||
|
LOG events occurs before emitting to the general query log.
|
||||||
|
ERROR events occur before transmitting errors to the user.
|
||||||
|
RESULT events occur after transmitting a resultset to the user.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MYSQL_AUDIT_GENERAL_CLASS 0
|
||||||
|
#define MYSQL_AUDIT_GENERAL_CLASSMASK (1 << MYSQL_AUDIT_GENERAL_CLASS)
|
||||||
|
#define MYSQL_AUDIT_GENERAL_LOG 0
|
||||||
|
#define MYSQL_AUDIT_GENERAL_ERROR 1
|
||||||
|
#define MYSQL_AUDIT_GENERAL_RESULT 2
|
||||||
|
|
||||||
|
struct mysql_event_general
|
||||||
|
{
|
||||||
|
int event_class;
|
||||||
|
int general_error_code;
|
||||||
|
unsigned long general_thread_id;
|
||||||
|
const char *general_user;
|
||||||
|
unsigned int general_user_length;
|
||||||
|
const char *general_command;
|
||||||
|
unsigned int general_command_length;
|
||||||
|
const char *general_query;
|
||||||
|
unsigned int general_query_length;
|
||||||
|
struct charset_info_st *general_charset;
|
||||||
|
unsigned long long general_time;
|
||||||
|
unsigned long long general_rows;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Here we define the descriptor structure, that is referred from
|
||||||
|
st_mysql_plugin.
|
||||||
|
|
||||||
|
release_thd() event occurs when the event class consumer is to be
|
||||||
|
disassociated from the specified THD. This would typically occur
|
||||||
|
before some operation which may require sleeping - such as when
|
||||||
|
waiting for the next query from the client.
|
||||||
|
|
||||||
|
event_notify() is invoked whenever an event occurs which is of any
|
||||||
|
class for which the plugin has interest. The first word of the
|
||||||
|
mysql_event argument indicates the specific event class and the
|
||||||
|
remainder of the structure is as required for that class.
|
||||||
|
|
||||||
|
class_mask is an array of bits used to indicate what event classes
|
||||||
|
that this plugin wants to receive.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct st_mysql_audit
|
||||||
|
{
|
||||||
|
int interface_version;
|
||||||
|
void (*release_thd)(MYSQL_THD);
|
||||||
|
void (*event_notify)(MYSQL_THD, const struct mysql_event *);
|
||||||
|
unsigned long class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
211
include/mysql/plugin_ftparser.h
Normal file
211
include/mysql/plugin_ftparser.h
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
/* Copyright (C) 2005 MySQL AB
|
||||||
|
|
||||||
|
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
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#ifndef _my_plugin_ftparser_h
|
||||||
|
#define _my_plugin_ftparser_h
|
||||||
|
#include "plugin.h"
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
API for Full-text parser plugin. (MYSQL_FTPARSER_PLUGIN)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MYSQL_FTPARSER_INTERFACE_VERSION 0x0100
|
||||||
|
|
||||||
|
/* Parsing modes. Set in MYSQL_FTPARSER_PARAM::mode */
|
||||||
|
enum enum_ftparser_mode
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Fast and simple mode. This mode is used for indexing, and natural
|
||||||
|
language queries.
|
||||||
|
|
||||||
|
The parser is expected to return only those words that go into the
|
||||||
|
index. Stopwords or too short/long words should not be returned. The
|
||||||
|
'boolean_info' argument of mysql_add_word() does not have to be set.
|
||||||
|
*/
|
||||||
|
MYSQL_FTPARSER_SIMPLE_MODE= 0,
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parse with stopwords mode. This mode is used in boolean searches for
|
||||||
|
"phrase matching."
|
||||||
|
|
||||||
|
The parser is not allowed to ignore words in this mode. Every word
|
||||||
|
should be returned, including stopwords and words that are too short
|
||||||
|
or long. The 'boolean_info' argument of mysql_add_word() does not
|
||||||
|
have to be set.
|
||||||
|
*/
|
||||||
|
MYSQL_FTPARSER_WITH_STOPWORDS= 1,
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parse in boolean mode. This mode is used to parse a boolean query string.
|
||||||
|
|
||||||
|
The parser should provide a valid MYSQL_FTPARSER_BOOLEAN_INFO
|
||||||
|
structure in the 'boolean_info' argument to mysql_add_word().
|
||||||
|
Usually that means that the parser should recognize boolean operators
|
||||||
|
in the parsing stream and set appropriate fields in
|
||||||
|
MYSQL_FTPARSER_BOOLEAN_INFO structure accordingly. As for
|
||||||
|
MYSQL_FTPARSER_WITH_STOPWORDS mode, no word should be ignored.
|
||||||
|
Instead, use FT_TOKEN_STOPWORD for the token type of such a word.
|
||||||
|
*/
|
||||||
|
MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Token types for boolean mode searching (used for the type member of
|
||||||
|
MYSQL_FTPARSER_BOOLEAN_INFO struct)
|
||||||
|
|
||||||
|
FT_TOKEN_EOF: End of data.
|
||||||
|
FT_TOKEN_WORD: Regular word.
|
||||||
|
FT_TOKEN_LEFT_PAREN: Left parenthesis (start of group/sub-expression).
|
||||||
|
FT_TOKEN_RIGHT_PAREN: Right parenthesis (end of group/sub-expression).
|
||||||
|
FT_TOKEN_STOPWORD: Stopword.
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum enum_ft_token_type
|
||||||
|
{
|
||||||
|
FT_TOKEN_EOF= 0,
|
||||||
|
FT_TOKEN_WORD= 1,
|
||||||
|
FT_TOKEN_LEFT_PAREN= 2,
|
||||||
|
FT_TOKEN_RIGHT_PAREN= 3,
|
||||||
|
FT_TOKEN_STOPWORD= 4
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
This structure is used in boolean search mode only. It conveys
|
||||||
|
boolean-mode metadata to the MySQL search engine for every word in
|
||||||
|
the search query. A valid instance of this structure must be filled
|
||||||
|
in by the plugin parser and passed as an argument in the call to
|
||||||
|
mysql_add_word (the callback function in the MYSQL_FTPARSER_PARAM
|
||||||
|
structure) when a query is parsed in boolean mode.
|
||||||
|
|
||||||
|
type: The token type. Should be one of the enum_ft_token_type values.
|
||||||
|
|
||||||
|
yesno: Whether the word must be present for a match to occur:
|
||||||
|
>0 Must be present
|
||||||
|
<0 Must not be present
|
||||||
|
0 Neither; the word is optional but its presence increases the relevance
|
||||||
|
With the default settings of the ft_boolean_syntax system variable,
|
||||||
|
>0 corresponds to the '+' operator, <0 corrresponds to the '-' operator,
|
||||||
|
and 0 means neither operator was used.
|
||||||
|
|
||||||
|
weight_adjust: A weighting factor that determines how much a match
|
||||||
|
for the word counts. Positive values increase, negative - decrease the
|
||||||
|
relative word's importance in the query.
|
||||||
|
|
||||||
|
wasign: The sign of the word's weight in the query. If it's non-negative
|
||||||
|
the match for the word will increase document relevance, if it's
|
||||||
|
negative - decrease (the word becomes a "noise word", the less of it the
|
||||||
|
better).
|
||||||
|
|
||||||
|
trunc: Corresponds to the '*' operator in the default setting of the
|
||||||
|
ft_boolean_syntax system variable.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct st_mysql_ftparser_boolean_info
|
||||||
|
{
|
||||||
|
enum enum_ft_token_type type;
|
||||||
|
int yesno;
|
||||||
|
int weight_adjust;
|
||||||
|
char wasign;
|
||||||
|
char trunc;
|
||||||
|
/* These are parser state and must be removed. */
|
||||||
|
char prev;
|
||||||
|
char *quot;
|
||||||
|
} MYSQL_FTPARSER_BOOLEAN_INFO;
|
||||||
|
|
||||||
|
/*
|
||||||
|
The following flag means that buffer with a string (document, word)
|
||||||
|
may be overwritten by the caller before the end of the parsing (that is
|
||||||
|
before st_mysql_ftparser::deinit() call). If one needs the string
|
||||||
|
to survive between two successive calls of the parsing function, she
|
||||||
|
needs to save a copy of it. The flag may be set by MySQL before calling
|
||||||
|
st_mysql_ftparser::parse(), or it may be set by a plugin before calling
|
||||||
|
st_mysql_ftparser_param::mysql_parse() or
|
||||||
|
st_mysql_ftparser_param::mysql_add_word().
|
||||||
|
*/
|
||||||
|
#define MYSQL_FTFLAGS_NEED_COPY 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
An argument of the full-text parser plugin. This structure is
|
||||||
|
filled in by MySQL server and passed to the parsing function of the
|
||||||
|
plugin as an in/out parameter.
|
||||||
|
|
||||||
|
mysql_parse: A pointer to the built-in parser implementation of the
|
||||||
|
server. It's set by the server and can be used by the parser plugin
|
||||||
|
to invoke the MySQL default parser. If plugin's role is to extract
|
||||||
|
textual data from .doc, .pdf or .xml content, it might extract
|
||||||
|
plaintext from the content, and then pass the text to the default
|
||||||
|
MySQL parser to be parsed.
|
||||||
|
|
||||||
|
mysql_add_word: A server callback to add a new word. When parsing
|
||||||
|
a document, the server sets this to point at a function that adds
|
||||||
|
the word to MySQL full-text index. When parsing a search query,
|
||||||
|
this function will add the new word to the list of words to search
|
||||||
|
for. The boolean_info argument can be NULL for all cases except
|
||||||
|
when mode is MYSQL_FTPARSER_FULL_BOOLEAN_INFO.
|
||||||
|
|
||||||
|
ftparser_state: A generic pointer. The plugin can set it to point
|
||||||
|
to information to be used internally for its own purposes.
|
||||||
|
|
||||||
|
mysql_ftparam: This is set by the server. It is used by MySQL functions
|
||||||
|
called via mysql_parse() and mysql_add_word() callback. The plugin
|
||||||
|
should not modify it.
|
||||||
|
|
||||||
|
cs: Information about the character set of the document or query string.
|
||||||
|
|
||||||
|
doc: A pointer to the document or query string to be parsed.
|
||||||
|
|
||||||
|
length: Length of the document or query string, in bytes.
|
||||||
|
|
||||||
|
flags: See MYSQL_FTFLAGS_* constants above.
|
||||||
|
|
||||||
|
mode: The parsing mode. With boolean operators, with stopwords, or
|
||||||
|
nothing. See enum_ftparser_mode above.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct st_mysql_ftparser_param
|
||||||
|
{
|
||||||
|
int (*mysql_parse)(struct st_mysql_ftparser_param *,
|
||||||
|
char *doc, int doc_len);
|
||||||
|
int (*mysql_add_word)(struct st_mysql_ftparser_param *,
|
||||||
|
char *word, int word_len,
|
||||||
|
MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
|
||||||
|
void *ftparser_state;
|
||||||
|
void *mysql_ftparam;
|
||||||
|
struct charset_info_st *cs;
|
||||||
|
char *doc;
|
||||||
|
int length;
|
||||||
|
int flags;
|
||||||
|
enum enum_ftparser_mode mode;
|
||||||
|
} MYSQL_FTPARSER_PARAM;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Full-text parser descriptor.
|
||||||
|
|
||||||
|
interface_version is, e.g., MYSQL_FTPARSER_INTERFACE_VERSION.
|
||||||
|
The parsing, initialization, and deinitialization functions are
|
||||||
|
invoked per SQL statement for which the parser is used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct st_mysql_ftparser
|
||||||
|
{
|
||||||
|
int interface_version;
|
||||||
|
int (*parse)(MYSQL_FTPARSER_PARAM *param);
|
||||||
|
int (*init)(MYSQL_FTPARSER_PARAM *param);
|
||||||
|
int (*deinit)(MYSQL_FTPARSER_PARAM *param);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -132,7 +132,8 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
|
|||||||
../sql/strfunc.cc ../sql/table.cc ../sql/thr_malloc.cc
|
../sql/strfunc.cc ../sql/table.cc ../sql/thr_malloc.cc
|
||||||
../sql/time.cc ../sql/tztime.cc ../sql/uniques.cc ../sql/unireg.cc
|
../sql/time.cc ../sql/tztime.cc ../sql/uniques.cc ../sql/unireg.cc
|
||||||
../sql/partition_info.cc ../sql/sql_connect.cc
|
../sql/partition_info.cc ../sql/sql_connect.cc
|
||||||
../sql/scheduler.cc ../sql/event_parse_data.cc
|
../sql/scheduler.cc ../sql/sql_audit.cc
|
||||||
|
../sql/event_parse_data.cc
|
||||||
../sql/sql_signal.cc ../sql/rpl_handler.cc
|
../sql/sql_signal.cc ../sql/rpl_handler.cc
|
||||||
${GEN_SOURCES}
|
${GEN_SOURCES}
|
||||||
${LIB_SOURCES})
|
${LIB_SOURCES})
|
||||||
|
@ -78,8 +78,8 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
|
|||||||
debug_sync.cc \
|
debug_sync.cc \
|
||||||
sql_tablespace.cc \
|
sql_tablespace.cc \
|
||||||
rpl_injector.cc my_user.c partition_info.cc \
|
rpl_injector.cc my_user.c partition_info.cc \
|
||||||
sql_servers.cc event_parse_data.cc sql_signal.cc \
|
sql_servers.cc sql_audit.cc event_parse_data.cc \
|
||||||
rpl_handler.cc keycaches.cc
|
sql_signal.cc rpl_handler.cc keycaches.cc
|
||||||
|
|
||||||
libmysqld_int_a_SOURCES= $(libmysqld_sources)
|
libmysqld_int_a_SOURCES= $(libmysqld_sources)
|
||||||
nodist_libmysqld_int_a_SOURCES= $(libmysqlsources) $(sqlsources)
|
nodist_libmysqld_int_a_SOURCES= $(libmysqlsources) $(sqlsources)
|
||||||
|
@ -32,6 +32,7 @@ rpl.rpl_sync* @windows # Bug#50473 2010-01-20 alik rpl_sync f
|
|||||||
rpl.rpl_timezone* # Bug#47017 2009-10-27 alik rpl_timezone fails on PB-2 with mismatch error
|
rpl.rpl_timezone* # Bug#47017 2009-10-27 alik rpl_timezone fails on PB-2 with mismatch error
|
||||||
|
|
||||||
sys_vars.max_sp_recursion_depth_func @solaris # Bug#47791 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun
|
sys_vars.max_sp_recursion_depth_func @solaris # Bug#47791 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun
|
||||||
|
sys_vars.delayed_insert_limit_func # Bug#50435 2010-01-25 alik sys_vars.delayed_insert_limit_func fails on Ubuntu x86_64 in debug mode
|
||||||
|
|
||||||
# Declare all NDB-tests in ndb and rpl_ndb test suites experimental.
|
# Declare all NDB-tests in ndb and rpl_ndb test suites experimental.
|
||||||
# Usually the test cases from ndb and rpl_ndb test suites are not run in PB,
|
# Usually the test cases from ndb and rpl_ndb test suites are not run in PB,
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
perl mysql-test-run.pl --timer --force --comment=1st --experimental=collections/default.experimental 1st
|
@ -9,11 +9,11 @@ wait/synch/mutex/sql/Delayed_insert::mutex YES YES
|
|||||||
wait/synch/mutex/sql/Event_scheduler::LOCK_scheduler_state YES YES
|
wait/synch/mutex/sql/Event_scheduler::LOCK_scheduler_state YES YES
|
||||||
wait/synch/mutex/sql/hash_filo::lock YES YES
|
wait/synch/mutex/sql/hash_filo::lock YES YES
|
||||||
wait/synch/mutex/sql/LOCK_active_mi YES YES
|
wait/synch/mutex/sql/LOCK_active_mi YES YES
|
||||||
|
wait/synch/mutex/sql/LOCK_audit_mask YES YES
|
||||||
wait/synch/mutex/sql/LOCK_connection_count YES YES
|
wait/synch/mutex/sql/LOCK_connection_count YES YES
|
||||||
wait/synch/mutex/sql/LOCK_crypt YES YES
|
wait/synch/mutex/sql/LOCK_crypt YES YES
|
||||||
wait/synch/mutex/sql/LOCK_delayed_create YES YES
|
wait/synch/mutex/sql/LOCK_delayed_create YES YES
|
||||||
wait/synch/mutex/sql/LOCK_delayed_insert YES YES
|
wait/synch/mutex/sql/LOCK_delayed_insert YES YES
|
||||||
wait/synch/mutex/sql/LOCK_delayed_status YES YES
|
|
||||||
select * from performance_schema.SETUP_INSTRUMENTS
|
select * from performance_schema.SETUP_INSTRUMENTS
|
||||||
where name like 'Wait/Synch/Rwlock/sql/%'
|
where name like 'Wait/Synch/Rwlock/sql/%'
|
||||||
order by name limit 10;
|
order by name limit 10;
|
||||||
|
32
plugin/audit_null/Makefile.am
Normal file
32
plugin/audit_null/Makefile.am
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# Copyright (C) 2007 MySQL AB
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
# the Free Software Foundation; version 2 of the License.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
#Makefile.am example for a plugin
|
||||||
|
|
||||||
|
pkgplugindir= $(pkglibdir)/plugin
|
||||||
|
|
||||||
|
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||||
|
|
||||||
|
EXTRA_LTLIBRARIES= adt_null.la
|
||||||
|
pkgplugin_LTLIBRARIES= @plugin_audit_null_shared_target@
|
||||||
|
adt_null_la_LDFLAGS= -module -rpath $(pkgplugindir)
|
||||||
|
adt_null_la_CPPFLAGS= $(AM_CPPFLAGS) -DMYSQL_DYNAMIC_PLUGIN
|
||||||
|
adt_null_la_SOURCES= audit_null.c
|
||||||
|
|
||||||
|
EXTRA_LIBRARIES= libadtnull.a
|
||||||
|
noinst_LIBRARIES= @plugin_audit_null_static_target@
|
||||||
|
libadtnull_a_SOURCES= audit_null.c
|
||||||
|
|
||||||
|
EXTRA_DIST= plug.in
|
130
plugin/audit_null/audit_null.c
Normal file
130
plugin/audit_null/audit_null.c
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/* Copyright (C) 2006-2007 MySQL AB
|
||||||
|
|
||||||
|
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
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <mysql/plugin.h>
|
||||||
|
#include <mysql/plugin_audit.h>
|
||||||
|
|
||||||
|
#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
|
||||||
|
#define __attribute__(A)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static volatile int number_of_calls; /* for SHOW STATUS, see below */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Initialize the plugin at server start or plugin installation.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
audit_null_plugin_init()
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Does nothing.
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
0 success
|
||||||
|
1 failure (cannot happen)
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int audit_null_plugin_init(void *arg __attribute__((unused)))
|
||||||
|
{
|
||||||
|
number_of_calls= 0;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Terminate the plugin at server shutdown or plugin deinstallation.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
audit_null_plugin_deinit()
|
||||||
|
Does nothing.
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
0 success
|
||||||
|
1 failure (cannot happen)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int audit_null_plugin_deinit(void *arg __attribute__((unused)))
|
||||||
|
{
|
||||||
|
printf("audit_null was invoked %u times\n", number_of_calls);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Foo
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
audit_null_notify()
|
||||||
|
thd connection context
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void audit_null_notify(MYSQL_THD thd __attribute__((unused)),
|
||||||
|
const struct mysql_event *event
|
||||||
|
__attribute__((unused)))
|
||||||
|
{
|
||||||
|
/* prone to races, oh well */
|
||||||
|
number_of_calls++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Plugin type-specific descriptor
|
||||||
|
*/
|
||||||
|
|
||||||
|
static struct st_mysql_audit audit_null_descriptor=
|
||||||
|
{
|
||||||
|
MYSQL_AUDIT_INTERFACE_VERSION, /* interface version */
|
||||||
|
NULL, /* release_thd function */
|
||||||
|
audit_null_notify, /* notify function */
|
||||||
|
{ (unsigned long) -1 } /* class mask */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Plugin status variables for SHOW STATUS
|
||||||
|
*/
|
||||||
|
|
||||||
|
static struct st_mysql_show_var simple_status[]=
|
||||||
|
{
|
||||||
|
{"audit_null_called", (char *)&number_of_calls, SHOW_INT},
|
||||||
|
{0,0,0}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Plugin library descriptor
|
||||||
|
*/
|
||||||
|
|
||||||
|
mysql_declare_plugin(audit_null)
|
||||||
|
{
|
||||||
|
MYSQL_AUDIT_PLUGIN, /* type */
|
||||||
|
&audit_null_descriptor, /* descriptor */
|
||||||
|
"NULL_AUDIT", /* name */
|
||||||
|
"MySQL AB", /* author */
|
||||||
|
"Simple NULL Audit", /* description */
|
||||||
|
PLUGIN_LICENSE_GPL,
|
||||||
|
audit_null_plugin_init, /* init function (when loaded) */
|
||||||
|
audit_null_plugin_deinit, /* deinit function (when unloaded) */
|
||||||
|
0x0001, /* version */
|
||||||
|
simple_status, /* status variables */
|
||||||
|
NULL, /* system variables */
|
||||||
|
NULL
|
||||||
|
}
|
||||||
|
mysql_declare_plugin_end;
|
||||||
|
|
4
plugin/audit_null/plug.in
Normal file
4
plugin/audit_null/plug.in
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
MYSQL_PLUGIN(audit_null, [NULL Audit Plug-in],
|
||||||
|
[Simple black-hole Audit example plug-in])
|
||||||
|
MYSQL_PLUGIN_DYNAMIC(audit_null, [adt_null.la])
|
||||||
|
MYSQL_PLUGIN_STATIC(audit_null, [libadtnull.a])
|
@ -73,7 +73,7 @@ SET (SQL_SOURCE
|
|||||||
event_queue.cc event_db_repository.cc
|
event_queue.cc event_db_repository.cc
|
||||||
sql_tablespace.cc events.cc ../sql-common/my_user.c
|
sql_tablespace.cc events.cc ../sql-common/my_user.c
|
||||||
partition_info.cc rpl_utility.cc rpl_injector.cc sql_locale.cc
|
partition_info.cc rpl_utility.cc rpl_injector.cc sql_locale.cc
|
||||||
rpl_rli.cc rpl_mi.cc sql_servers.cc
|
rpl_rli.cc rpl_mi.cc sql_servers.cc sql_audit.cc
|
||||||
sql_connect.cc scheduler.cc
|
sql_connect.cc scheduler.cc
|
||||||
sql_profile.cc event_parse_data.cc
|
sql_profile.cc event_parse_data.cc
|
||||||
sql_signal.cc rpl_handler.cc sys_vars.cc
|
sql_signal.cc rpl_handler.cc sys_vars.cc
|
||||||
|
@ -111,6 +111,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
|
|||||||
sql_plugin.h authors.h event_parse_data.h \
|
sql_plugin.h authors.h event_parse_data.h \
|
||||||
event_data_objects.h event_scheduler.h \
|
event_data_objects.h event_scheduler.h \
|
||||||
sql_partition.h partition_info.h partition_element.h \
|
sql_partition.h partition_info.h partition_element.h \
|
||||||
|
sql_audit.h \
|
||||||
contributors.h sql_servers.h sql_signal.h records.h \
|
contributors.h sql_servers.h sql_signal.h records.h \
|
||||||
sql_prepare.h rpl_handler.h replication.h sys_vars.h
|
sql_prepare.h rpl_handler.h replication.h sys_vars.h
|
||||||
|
|
||||||
@ -157,7 +158,8 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
|
|||||||
event_queue.cc event_db_repository.cc events.cc \
|
event_queue.cc event_db_repository.cc events.cc \
|
||||||
sql_plugin.cc sql_binlog.cc \
|
sql_plugin.cc sql_binlog.cc \
|
||||||
sql_builtin.cc sql_tablespace.cc partition_info.cc \
|
sql_builtin.cc sql_tablespace.cc partition_info.cc \
|
||||||
sql_servers.cc event_parse_data.cc sql_signal.cc \
|
sql_servers.cc sql_audit.cc \
|
||||||
|
event_parse_data.cc sql_signal.cc \
|
||||||
rpl_handler.cc
|
rpl_handler.cc
|
||||||
|
|
||||||
nodist_mysqld_SOURCES = mini_client_errors.c pack.c client.c my_time.c my_user.c
|
nodist_mysqld_SOURCES = mini_client_errors.c pack.c client.c my_time.c my_user.c
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
#include "event_queue.h"
|
#include "event_queue.h"
|
||||||
#include "event_data_objects.h"
|
#include "event_data_objects.h"
|
||||||
|
#include "sql_audit.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@addtogroup Event_Scheduler
|
@addtogroup Event_Scheduler
|
||||||
@ -581,6 +582,9 @@ Event_queue::get_top_for_execution_if_time(THD *thd,
|
|||||||
/* There are no events in the queue */
|
/* There are no events in the queue */
|
||||||
next_activation_at= 0;
|
next_activation_at= 0;
|
||||||
|
|
||||||
|
/* Release any held audit resources before waiting */
|
||||||
|
mysql_audit_release(thd);
|
||||||
|
|
||||||
/* Wait on condition until signaled. Release LOCK_queue while waiting. */
|
/* Wait on condition until signaled. Release LOCK_queue while waiting. */
|
||||||
cond_wait(thd, NULL, queue_empty_msg, SCHED_FUNC, __LINE__);
|
cond_wait(thd, NULL, queue_empty_msg, SCHED_FUNC, __LINE__);
|
||||||
|
|
||||||
@ -600,6 +604,10 @@ Event_queue::get_top_for_execution_if_time(THD *thd,
|
|||||||
*/
|
*/
|
||||||
struct timespec top_time;
|
struct timespec top_time;
|
||||||
set_timespec(top_time, next_activation_at - thd->query_start());
|
set_timespec(top_time, next_activation_at - thd->query_start());
|
||||||
|
|
||||||
|
/* Release any held audit resources before waiting */
|
||||||
|
mysql_audit_release(thd);
|
||||||
|
|
||||||
cond_wait(thd, &top_time, queue_wait_msg, SCHED_FUNC, __LINE__);
|
cond_wait(thd, &top_time, queue_wait_msg, SCHED_FUNC, __LINE__);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
@ -7466,7 +7466,6 @@ static int connect_callback()
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern int ndb_dictionary_is_mysqld;
|
extern int ndb_dictionary_is_mysqld;
|
||||||
extern mysql_mutex_t LOCK_plugin;
|
|
||||||
|
|
||||||
#ifdef HAVE_PSI_INTERFACE
|
#ifdef HAVE_PSI_INTERFACE
|
||||||
|
|
||||||
@ -7559,13 +7558,6 @@ static int ndbcluster_init(void *p)
|
|||||||
init_ndbcluster_psi_keys();
|
init_ndbcluster_psi_keys();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
Below we create new THD's. They'll need LOCK_plugin, but it's taken now by
|
|
||||||
plugin initialization code. Release it to avoid deadlocks. It's safe, as
|
|
||||||
there're no threads that may concurrently access plugin control structures.
|
|
||||||
*/
|
|
||||||
mysql_mutex_unlock(&LOCK_plugin);
|
|
||||||
|
|
||||||
mysql_mutex_init(key_ndbcluster_mutex,
|
mysql_mutex_init(key_ndbcluster_mutex,
|
||||||
&ndbcluster_mutex, MY_MUTEX_INIT_FAST);
|
&ndbcluster_mutex, MY_MUTEX_INIT_FAST);
|
||||||
mysql_mutex_init(key_LOCK_ndb_util_thread,
|
mysql_mutex_init(key_LOCK_ndb_util_thread,
|
||||||
@ -7722,8 +7714,6 @@ static int ndbcluster_init(void *p)
|
|||||||
goto ndbcluster_init_error;
|
goto ndbcluster_init_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
mysql_mutex_lock(&LOCK_plugin);
|
|
||||||
|
|
||||||
ndbcluster_inited= 1;
|
ndbcluster_inited= 1;
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
|
|
||||||
@ -7736,8 +7726,6 @@ ndbcluster_init_error:
|
|||||||
g_ndb_cluster_connection= NULL;
|
g_ndb_cluster_connection= NULL;
|
||||||
ndbcluster_hton->state= SHOW_OPTION_DISABLED; // If we couldn't use handler
|
ndbcluster_hton->state= SHOW_OPTION_DISABLED; // If we couldn't use handler
|
||||||
|
|
||||||
mysql_mutex_lock(&LOCK_plugin);
|
|
||||||
|
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
17
sql/log.cc
17
sql/log.cc
@ -28,6 +28,7 @@
|
|||||||
#include "sql_repl.h"
|
#include "sql_repl.h"
|
||||||
#include "rpl_filter.h"
|
#include "rpl_filter.h"
|
||||||
#include "rpl_rli.h"
|
#include "rpl_rli.h"
|
||||||
|
#include "sql_audit.h"
|
||||||
|
|
||||||
#include <my_dir.h>
|
#include <my_dir.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@ -42,7 +43,6 @@
|
|||||||
|
|
||||||
/* max size of the log message */
|
/* max size of the log message */
|
||||||
#define MAX_LOG_BUFFER_SIZE 1024
|
#define MAX_LOG_BUFFER_SIZE 1024
|
||||||
#define MAX_USER_HOST_SIZE 512
|
|
||||||
#define MAX_TIME_SIZE 32
|
#define MAX_TIME_SIZE 32
|
||||||
#define MY_OFF_T_UNDEF (~(my_off_t)0UL)
|
#define MY_OFF_T_UNDEF (~(my_off_t)0UL)
|
||||||
|
|
||||||
@ -1157,7 +1157,6 @@ bool LOGGER::general_log_write(THD *thd, enum enum_server_command command,
|
|||||||
bool error= FALSE;
|
bool error= FALSE;
|
||||||
Log_event_handler **current_handler= general_log_handler_list;
|
Log_event_handler **current_handler= general_log_handler_list;
|
||||||
char user_host_buff[MAX_USER_HOST_SIZE + 1];
|
char user_host_buff[MAX_USER_HOST_SIZE + 1];
|
||||||
Security_context *sctx= thd->security_ctx;
|
|
||||||
uint user_host_len= 0;
|
uint user_host_len= 0;
|
||||||
time_t current_time;
|
time_t current_time;
|
||||||
|
|
||||||
@ -1169,14 +1168,16 @@ bool LOGGER::general_log_write(THD *thd, enum enum_server_command command,
|
|||||||
unlock();
|
unlock();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
|
user_host_len= make_user_name(thd, user_host_buff);
|
||||||
sctx->priv_user ? sctx->priv_user : "", "[",
|
|
||||||
sctx->user ? sctx->user : "", "] @ ",
|
|
||||||
sctx->host ? sctx->host : "", " [",
|
|
||||||
sctx->ip ? sctx->ip : "", "]", NullS) -
|
|
||||||
user_host_buff;
|
|
||||||
|
|
||||||
current_time= my_time(0);
|
current_time= my_time(0);
|
||||||
|
|
||||||
|
mysql_audit_general_log(thd, current_time,
|
||||||
|
user_host_buff, user_host_len,
|
||||||
|
command_name[(uint) command].str,
|
||||||
|
command_name[(uint) command].length,
|
||||||
|
query, query_length);
|
||||||
|
|
||||||
while (*current_handler)
|
while (*current_handler)
|
||||||
error|= (*current_handler++)->
|
error|= (*current_handler++)->
|
||||||
log_general(thd, current_time, user_host_buff,
|
log_general(thd, current_time, user_host_buff,
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "mysqld_suffix.h"
|
#include "mysqld_suffix.h"
|
||||||
#include "mysys_err.h"
|
#include "mysys_err.h"
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
|
#include "sql_audit.h"
|
||||||
#include "probes_mysql.h"
|
#include "probes_mysql.h"
|
||||||
#include "debug_sync.h"
|
#include "debug_sync.h"
|
||||||
|
|
||||||
@ -955,6 +956,7 @@ static void close_server_sock();
|
|||||||
static void clean_up_mutexes(void);
|
static void clean_up_mutexes(void);
|
||||||
static void wait_for_signal_thread_to_end(void);
|
static void wait_for_signal_thread_to_end(void);
|
||||||
static void create_pid_file();
|
static void create_pid_file();
|
||||||
|
static void mysqld_exit(int exit_code) __attribute__((noreturn));
|
||||||
static void end_ssl();
|
static void end_ssl();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1365,6 +1367,7 @@ void unireg_end(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" void unireg_abort(int exit_code)
|
extern "C" void unireg_abort(int exit_code)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("unireg_abort");
|
DBUG_ENTER("unireg_abort");
|
||||||
@ -1375,15 +1378,25 @@ extern "C" void unireg_abort(int exit_code)
|
|||||||
sql_print_error("Aborting\n");
|
sql_print_error("Aborting\n");
|
||||||
clean_up(!opt_help && (exit_code || !opt_bootstrap)); /* purecov: inspected */
|
clean_up(!opt_help && (exit_code || !opt_bootstrap)); /* purecov: inspected */
|
||||||
DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
|
DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
|
||||||
|
mysqld_exit(exit_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mysqld_exit(int exit_code)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Important note: we wait for the signal thread to end,
|
||||||
|
but if a kill -15 signal was sent, the signal thread did
|
||||||
|
spawn the kill_server_thread thread, which is running concurrently.
|
||||||
|
*/
|
||||||
wait_for_signal_thread_to_end();
|
wait_for_signal_thread_to_end();
|
||||||
|
mysql_audit_finalize();
|
||||||
clean_up_mutexes();
|
clean_up_mutexes();
|
||||||
clean_up_error_log_mutex();
|
clean_up_error_log_mutex();
|
||||||
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
|
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
|
||||||
exit(exit_code); /* purecov: inspected */
|
exit(exit_code); /* purecov: inspected */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /*EMBEDDED_LIBRARY*/
|
#endif /* !EMBEDDED_LIBRARY */
|
||||||
|
|
||||||
|
|
||||||
void clean_up(bool print_message)
|
void clean_up(bool print_message)
|
||||||
{
|
{
|
||||||
@ -3024,6 +3037,8 @@ void my_message_sql(uint error, const char *str, myf MyFlags)
|
|||||||
error= ER_UNKNOWN_ERROR;
|
error= ER_UNKNOWN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_ERROR, error, str);
|
||||||
|
|
||||||
if (thd)
|
if (thd)
|
||||||
{
|
{
|
||||||
if (MyFlags & ME_FATALERROR)
|
if (MyFlags & ME_FATALERROR)
|
||||||
@ -4579,6 +4594,9 @@ int main(int argc, char **argv)
|
|||||||
thr_kill_signal= SIGINT;
|
thr_kill_signal= SIGINT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Initialize audit interface globals. Audit plugins are inited later. */
|
||||||
|
mysql_audit_initialize();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Perform basic logger initialization logger. Should be called after
|
Perform basic logger initialization logger. Should be called after
|
||||||
MY_INIT, as it initializes mutexes. Log tables are inited later.
|
MY_INIT, as it initializes mutexes. Log tables are inited later.
|
||||||
@ -4871,14 +4889,6 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
clean_up(1);
|
clean_up(1);
|
||||||
/*
|
|
||||||
Important note: we wait for the signal thread to end,
|
|
||||||
but if a kill -15 signal was sent, the signal thread did
|
|
||||||
spawn the kill_server_thread thread, which is running concurrently.
|
|
||||||
*/
|
|
||||||
wait_for_signal_thread_to_end();
|
|
||||||
clean_up_mutexes();
|
|
||||||
clean_up_error_log_mutex();
|
|
||||||
#ifdef HAVE_PSI_INTERFACE
|
#ifdef HAVE_PSI_INTERFACE
|
||||||
/*
|
/*
|
||||||
Disable the instrumentation, to avoid recording events
|
Disable the instrumentation, to avoid recording events
|
||||||
@ -4891,13 +4901,10 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
shutdown_performance_schema();
|
shutdown_performance_schema();
|
||||||
#endif
|
#endif
|
||||||
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
|
mysqld_exit(0);
|
||||||
|
|
||||||
exit(0);
|
|
||||||
return(0); /* purecov: deadcode */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* EMBEDDED_LIBRARY */
|
#endif /* !EMBEDDED_LIBRARY */
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
477
sql/sql_audit.cc
Normal file
477
sql/sql_audit.cc
Normal file
@ -0,0 +1,477 @@
|
|||||||
|
/* Copyright (C) 2007 MySQL AB, 2008-2009 Sun Microsystems, Inc
|
||||||
|
|
||||||
|
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
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
#include "mysql_priv.h"
|
||||||
|
#include "sql_audit.h"
|
||||||
|
|
||||||
|
extern int initialize_audit_plugin(st_plugin_int *plugin);
|
||||||
|
extern int finalize_audit_plugin(st_plugin_int *plugin);
|
||||||
|
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
|
||||||
|
unsigned long mysql_global_audit_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
|
||||||
|
|
||||||
|
static mysql_mutex_t LOCK_audit_mask;
|
||||||
|
|
||||||
|
static void event_class_dispatch(THD *thd, const struct mysql_event *event);
|
||||||
|
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void set_audit_mask(unsigned long *mask, uint event_class)
|
||||||
|
{
|
||||||
|
mask[0]= 1;
|
||||||
|
mask[0]<<= event_class;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void add_audit_mask(unsigned long *mask, const unsigned long *rhs)
|
||||||
|
{
|
||||||
|
mask[0]|= rhs[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
bool check_audit_mask(const unsigned long *lhs,
|
||||||
|
const unsigned long *rhs)
|
||||||
|
{
|
||||||
|
return !(lhs[0] & rhs[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef void (*audit_handler_t)(THD *thd, uint event_subtype, va_list ap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
MYSQL_AUDIT_GENERAL_CLASS handler
|
||||||
|
|
||||||
|
@param[in] thd
|
||||||
|
@param[in] event_subtype
|
||||||
|
@param[in] error_code
|
||||||
|
@param[in] ap
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void general_class_handler(THD *thd, uint event_subtype, va_list ap)
|
||||||
|
{
|
||||||
|
mysql_event_general event;
|
||||||
|
event.event_class= MYSQL_AUDIT_GENERAL_CLASS;
|
||||||
|
event.general_error_code= va_arg(ap, int);
|
||||||
|
event.general_thread_id= thd ? thd->thread_id : 0;
|
||||||
|
event.general_time= va_arg(ap, time_t);
|
||||||
|
event.general_user= va_arg(ap, const char *);
|
||||||
|
event.general_user_length= va_arg(ap, unsigned int);
|
||||||
|
event.general_command= va_arg(ap, const char *);
|
||||||
|
event.general_command_length= va_arg(ap, unsigned int);
|
||||||
|
event.general_query= va_arg(ap, const char *);
|
||||||
|
event.general_query_length= va_arg(ap, unsigned int);
|
||||||
|
event.general_charset= va_arg(ap, struct charset_info_st *);
|
||||||
|
event.general_rows= (unsigned long long) va_arg(ap, ha_rows);
|
||||||
|
event_class_dispatch(thd, (const mysql_event*) &event);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static audit_handler_t audit_handlers[] =
|
||||||
|
{
|
||||||
|
general_class_handler
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint audit_handlers_count=
|
||||||
|
(sizeof(audit_handlers) / sizeof(audit_handler_t));
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Acquire and lock any additional audit plugins as required
|
||||||
|
|
||||||
|
@param[in] thd
|
||||||
|
@param[in] plugin
|
||||||
|
@param[in] arg
|
||||||
|
|
||||||
|
@retval FALSE Always
|
||||||
|
*/
|
||||||
|
|
||||||
|
static my_bool acquire_plugins(THD *thd, plugin_ref plugin, void *arg)
|
||||||
|
{
|
||||||
|
uint event_class= *(uint*) arg;
|
||||||
|
unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
|
||||||
|
st_mysql_audit *data= plugin_data(plugin, struct st_mysql_audit *);
|
||||||
|
|
||||||
|
set_audit_mask(event_class_mask, event_class);
|
||||||
|
|
||||||
|
/* Check if this plugin is interested in the event */
|
||||||
|
if (check_audit_mask(data->class_mask, event_class_mask))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check if this plugin may already be registered. This will fail to
|
||||||
|
acquire a newly installed plugin on a specific corner case where
|
||||||
|
one or more event classes already in use by the calling thread
|
||||||
|
are an event class of which the audit plugin has interest.
|
||||||
|
*/
|
||||||
|
if (!check_audit_mask(data->class_mask, thd->audit_class_mask))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Check if we need to initialize the array of acquired plugins */
|
||||||
|
if (unlikely(!thd->audit_class_plugins.buffer))
|
||||||
|
{
|
||||||
|
/* specify some reasonable initialization defaults */
|
||||||
|
my_init_dynamic_array(&thd->audit_class_plugins,
|
||||||
|
sizeof(plugin_ref), 16, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lock the plugin and add it to the list */
|
||||||
|
plugin= my_plugin_lock(NULL, &plugin);
|
||||||
|
insert_dynamic(&thd->audit_class_plugins, (uchar*) &plugin);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Notify the audit system of an event
|
||||||
|
|
||||||
|
@param[in] thd
|
||||||
|
@param[in] event_class
|
||||||
|
@param[in] event_subtype
|
||||||
|
@param[in] error_code
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
void mysql_audit_notify(THD *thd, uint event_class, uint event_subtype, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
audit_handler_t *handlers= audit_handlers + event_class;
|
||||||
|
unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
|
||||||
|
|
||||||
|
DBUG_ASSERT(event_class < audit_handlers_count);
|
||||||
|
|
||||||
|
set_audit_mask(event_class_mask, event_class);
|
||||||
|
/*
|
||||||
|
Check to see if we have acquired the audit plugins for the
|
||||||
|
required audit event classes.
|
||||||
|
*/
|
||||||
|
if (thd && check_audit_mask(thd->audit_class_mask, event_class_mask))
|
||||||
|
{
|
||||||
|
plugin_foreach(thd, acquire_plugins, MYSQL_AUDIT_PLUGIN, &event_class);
|
||||||
|
add_audit_mask(thd->audit_class_mask, event_class_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_start(ap, event_subtype);
|
||||||
|
(*handlers)(thd, event_subtype, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Release any resources associated with the current thd.
|
||||||
|
|
||||||
|
@param[in] thd
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
void mysql_audit_release(THD *thd)
|
||||||
|
{
|
||||||
|
plugin_ref *plugins, *plugins_last;
|
||||||
|
|
||||||
|
if (!thd || !(thd->audit_class_plugins.elements))
|
||||||
|
return;
|
||||||
|
|
||||||
|
plugins= (plugin_ref*) thd->audit_class_plugins.buffer;
|
||||||
|
plugins_last= plugins + thd->audit_class_plugins.elements;
|
||||||
|
for (; plugins < plugins_last; plugins++)
|
||||||
|
{
|
||||||
|
st_mysql_audit *data= plugin_data(*plugins, struct st_mysql_audit *);
|
||||||
|
|
||||||
|
/* Check to see if the plugin has a release method */
|
||||||
|
if (!(data->release_thd))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Tell the plugin to release its resources */
|
||||||
|
data->release_thd(thd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we actually unlock the plugins */
|
||||||
|
plugin_unlock_list(NULL, (plugin_ref*) thd->audit_class_plugins.buffer,
|
||||||
|
thd->audit_class_plugins.elements);
|
||||||
|
|
||||||
|
/* Reset the state of thread values */
|
||||||
|
reset_dynamic(&thd->audit_class_plugins);
|
||||||
|
bzero(thd->audit_class_mask, sizeof(thd->audit_class_mask));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initialize thd variables used by Audit
|
||||||
|
|
||||||
|
@param[in] thd
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
void mysql_audit_init_thd(THD *thd)
|
||||||
|
{
|
||||||
|
bzero(&thd->audit_class_plugins, sizeof(thd->audit_class_plugins));
|
||||||
|
bzero(thd->audit_class_mask, sizeof(thd->audit_class_mask));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Free thd variables used by Audit
|
||||||
|
|
||||||
|
@param[in] thd
|
||||||
|
@param[in] plugin
|
||||||
|
@param[in] arg
|
||||||
|
|
||||||
|
@retval FALSE Always
|
||||||
|
*/
|
||||||
|
|
||||||
|
void mysql_audit_free_thd(THD *thd)
|
||||||
|
{
|
||||||
|
mysql_audit_release(thd);
|
||||||
|
DBUG_ASSERT(thd->audit_class_plugins.elements == 0);
|
||||||
|
delete_dynamic(&thd->audit_class_plugins);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_PSI_INTERFACE
|
||||||
|
static PSI_mutex_key key_LOCK_audit_mask;
|
||||||
|
|
||||||
|
static PSI_mutex_info all_audit_mutexes[]=
|
||||||
|
{
|
||||||
|
{ &key_LOCK_audit_mask, "LOCK_audit_mask", PSI_FLAG_GLOBAL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void init_audit_psi_keys(void)
|
||||||
|
{
|
||||||
|
const char* category= "sql";
|
||||||
|
int count;
|
||||||
|
|
||||||
|
if (PSI_server == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
count= array_elements(all_audit_mutexes);
|
||||||
|
PSI_server->register_mutex(category, all_audit_mutexes, count);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_PSI_INTERFACE */
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initialize Audit global variables
|
||||||
|
*/
|
||||||
|
|
||||||
|
void mysql_audit_initialize()
|
||||||
|
{
|
||||||
|
#ifdef HAVE_PSI_INTERFACE
|
||||||
|
init_audit_psi_keys();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
mysql_mutex_init(key_LOCK_audit_mask, &LOCK_audit_mask, MY_MUTEX_INIT_FAST);
|
||||||
|
bzero(mysql_global_audit_mask, sizeof(mysql_global_audit_mask));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Finalize Audit global variables
|
||||||
|
*/
|
||||||
|
|
||||||
|
void mysql_audit_finalize()
|
||||||
|
{
|
||||||
|
mysql_mutex_destroy(&LOCK_audit_mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initialize an Audit plug-in
|
||||||
|
|
||||||
|
@param[in] plugin
|
||||||
|
|
||||||
|
@retval FALSE OK
|
||||||
|
@retval TRUE There was an error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int initialize_audit_plugin(st_plugin_int *plugin)
|
||||||
|
{
|
||||||
|
st_mysql_audit *data= (st_mysql_audit*) plugin->plugin->info;
|
||||||
|
|
||||||
|
if (!data->class_mask || !data->event_notify ||
|
||||||
|
!data->class_mask[0])
|
||||||
|
{
|
||||||
|
sql_print_error("Plugin '%s' has invalid data.",
|
||||||
|
plugin->name.str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugin->plugin->init && plugin->plugin->init(NULL))
|
||||||
|
{
|
||||||
|
sql_print_error("Plugin '%s' init function returned error.",
|
||||||
|
plugin->name.str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make the interface info more easily accessible */
|
||||||
|
plugin->data= plugin->plugin->info;
|
||||||
|
|
||||||
|
/* Add the bits the plugin is interested in to the global mask */
|
||||||
|
mysql_mutex_lock(&LOCK_audit_mask);
|
||||||
|
add_audit_mask(mysql_global_audit_mask, data->class_mask);
|
||||||
|
mysql_mutex_unlock(&LOCK_audit_mask);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs a bitwise OR of the installed plugins event class masks
|
||||||
|
|
||||||
|
@param[in] thd
|
||||||
|
@param[in] plugin
|
||||||
|
@param[in] arg
|
||||||
|
|
||||||
|
@retval FALSE always
|
||||||
|
*/
|
||||||
|
static my_bool calc_class_mask(THD *thd, plugin_ref plugin, void *arg)
|
||||||
|
{
|
||||||
|
st_mysql_audit *data= plugin_data(plugin, struct st_mysql_audit *);
|
||||||
|
if ((data= plugin_data(plugin, struct st_mysql_audit *)))
|
||||||
|
add_audit_mask((unsigned long *) arg, data->class_mask);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Finalize an Audit plug-in
|
||||||
|
|
||||||
|
@param[in] plugin
|
||||||
|
|
||||||
|
@retval FALSE OK
|
||||||
|
@retval TRUE There was an error.
|
||||||
|
*/
|
||||||
|
int finalize_audit_plugin(st_plugin_int *plugin)
|
||||||
|
{
|
||||||
|
unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
|
||||||
|
|
||||||
|
if (plugin->plugin->deinit && plugin->plugin->deinit(NULL))
|
||||||
|
{
|
||||||
|
DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.",
|
||||||
|
plugin->name.str));
|
||||||
|
DBUG_EXECUTE("finalize_audit_plugin", return 1; );
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin->data= NULL;
|
||||||
|
bzero(&event_class_mask, sizeof(event_class_mask));
|
||||||
|
|
||||||
|
/* Iterate through all the installed plugins to create new mask */
|
||||||
|
|
||||||
|
/*
|
||||||
|
LOCK_audit_mask/LOCK_plugin order is not fixed, but serialized with table
|
||||||
|
lock on mysql.plugin.
|
||||||
|
*/
|
||||||
|
mysql_mutex_lock(&LOCK_audit_mask);
|
||||||
|
plugin_foreach(current_thd, calc_class_mask, MYSQL_AUDIT_PLUGIN,
|
||||||
|
&event_class_mask);
|
||||||
|
|
||||||
|
/* Set the global audit mask */
|
||||||
|
bmove(mysql_global_audit_mask, event_class_mask, sizeof(event_class_mask));
|
||||||
|
mysql_mutex_unlock(&LOCK_audit_mask);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Dispatches an event by invoking the plugin's event_notify method.
|
||||||
|
|
||||||
|
@param[in] thd
|
||||||
|
@param[in] plugin
|
||||||
|
@param[in] arg
|
||||||
|
|
||||||
|
@retval FALSE always
|
||||||
|
*/
|
||||||
|
|
||||||
|
static my_bool plugins_dispatch(THD *thd, plugin_ref plugin, void *arg)
|
||||||
|
{
|
||||||
|
const struct mysql_event *event= (const struct mysql_event *) arg;
|
||||||
|
unsigned long event_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
|
||||||
|
st_mysql_audit *data= plugin_data(plugin, struct st_mysql_audit *);
|
||||||
|
|
||||||
|
set_audit_mask(event_class_mask, event->event_class);
|
||||||
|
|
||||||
|
/* Check to see if the plugin is interested in this event */
|
||||||
|
if (check_audit_mask(data->class_mask, event_class_mask))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Actually notify the plugin */
|
||||||
|
data->event_notify(thd, event);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Distributes an audit event to plug-ins
|
||||||
|
|
||||||
|
@param[in] thd
|
||||||
|
@param[in] event
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void event_class_dispatch(THD *thd, const struct mysql_event *event)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Check if we are doing a slow global dispatch. This event occurs when
|
||||||
|
thd == NULL as it is not associated with any particular thread.
|
||||||
|
*/
|
||||||
|
if (unlikely(!thd))
|
||||||
|
{
|
||||||
|
plugin_foreach(thd, plugins_dispatch, MYSQL_AUDIT_PLUGIN, (void*) event);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
plugin_ref *plugins, *plugins_last;
|
||||||
|
|
||||||
|
/* Use the cached set of audit plugins */
|
||||||
|
plugins= (plugin_ref*) thd->audit_class_plugins.buffer;
|
||||||
|
plugins_last= plugins + thd->audit_class_plugins.elements;
|
||||||
|
|
||||||
|
for (; plugins < plugins_last; plugins++)
|
||||||
|
plugins_dispatch(thd, *plugins, (void*) event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#else /* EMBEDDED_LIBRARY */
|
||||||
|
|
||||||
|
|
||||||
|
void mysql_audit_initialize()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mysql_audit_finalize()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int initialize_audit_plugin(st_plugin_int *plugin)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int finalize_audit_plugin(st_plugin_int *plugin)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mysql_audit_release(THD *thd)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* EMBEDDED_LIBRARY */
|
131
sql/sql_audit.h
Normal file
131
sql/sql_audit.h
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
#ifndef SQL_AUDIT_INCLUDED
|
||||||
|
#define SQL_AUDIT_INCLUDED
|
||||||
|
|
||||||
|
/* Copyright (C) 2007 MySQL AB
|
||||||
|
|
||||||
|
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
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
|
#include <mysql/plugin_audit.h>
|
||||||
|
|
||||||
|
extern unsigned long mysql_global_audit_mask[];
|
||||||
|
|
||||||
|
|
||||||
|
extern void mysql_audit_initialize();
|
||||||
|
extern void mysql_audit_finalize();
|
||||||
|
|
||||||
|
|
||||||
|
extern void mysql_audit_init_thd(THD *thd);
|
||||||
|
extern void mysql_audit_free_thd(THD *thd);
|
||||||
|
|
||||||
|
|
||||||
|
extern void mysql_audit_notify(THD *thd, uint event_class,
|
||||||
|
uint event_subtype, ...);
|
||||||
|
extern void mysql_audit_release(THD *thd);
|
||||||
|
|
||||||
|
#define MAX_USER_HOST_SIZE 512
|
||||||
|
static inline uint make_user_name(THD *thd, char *buf)
|
||||||
|
{
|
||||||
|
Security_context *sctx= thd->security_ctx;
|
||||||
|
return strxnmov(buf, MAX_USER_HOST_SIZE,
|
||||||
|
sctx->priv_user ? sctx->priv_user : "", "[",
|
||||||
|
sctx->user ? sctx->user : "", "] @ ",
|
||||||
|
sctx->host ? sctx->host : "", " [",
|
||||||
|
sctx->ip ? sctx->ip : "", "]", NullS) - buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Call audit plugins of GENERAL audit class, MYSQL_AUDIT_GENERAL_LOG subtype.
|
||||||
|
|
||||||
|
@param[in] thd
|
||||||
|
@param[in] time time that event occurred
|
||||||
|
@param[in] user User name
|
||||||
|
@param[in] userlen User name length
|
||||||
|
@param[in] cmd Command name
|
||||||
|
@param[in] cmdlen Command name length
|
||||||
|
@param[in] query Query string
|
||||||
|
@param[in] querylen Query string length
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void mysql_audit_general_log(THD *thd, time_t time,
|
||||||
|
const char *user, uint userlen,
|
||||||
|
const char *cmd, uint cmdlen,
|
||||||
|
const char *query, uint querylen)
|
||||||
|
{
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
if (mysql_global_audit_mask[0] & MYSQL_AUDIT_GENERAL_CLASSMASK)
|
||||||
|
{
|
||||||
|
CHARSET_INFO *clientcs= thd ? thd->variables.character_set_client
|
||||||
|
: global_system_variables.character_set_client;
|
||||||
|
|
||||||
|
mysql_audit_notify(thd, MYSQL_AUDIT_GENERAL_CLASS, MYSQL_AUDIT_GENERAL_LOG,
|
||||||
|
0, time, user, userlen, cmd, cmdlen,
|
||||||
|
query, querylen, clientcs, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Call audit plugins of GENERAL audit class.
|
||||||
|
event_subtype should be set to one of:
|
||||||
|
MYSQL_AUDIT_GENERAL_ERROR
|
||||||
|
MYSQL_AUDIT_GENERAL_RESULT
|
||||||
|
|
||||||
|
@param[in] thd
|
||||||
|
@param[in] event_subtype Type of general audit event.
|
||||||
|
@param[in] error_code Error code
|
||||||
|
@param[in] msg Message
|
||||||
|
*/
|
||||||
|
static inline
|
||||||
|
void mysql_audit_general(THD *thd, uint event_subtype,
|
||||||
|
int error_code, const char *msg)
|
||||||
|
{
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
if (mysql_global_audit_mask[0] & MYSQL_AUDIT_GENERAL_CLASSMASK)
|
||||||
|
{
|
||||||
|
time_t time= my_time(0);
|
||||||
|
uint msglen= msg ? strlen(msg) : 0;
|
||||||
|
const char *query, *user;
|
||||||
|
uint querylen, userlen;
|
||||||
|
char user_buff[MAX_USER_HOST_SIZE];
|
||||||
|
CHARSET_INFO *clientcs;
|
||||||
|
ha_rows rows;
|
||||||
|
|
||||||
|
if (thd)
|
||||||
|
{
|
||||||
|
query= thd->query();
|
||||||
|
querylen= thd->query_length();
|
||||||
|
user= user_buff;
|
||||||
|
userlen= make_user_name(thd, user_buff);
|
||||||
|
clientcs= thd->variables.character_set_client;
|
||||||
|
rows= thd->warning_info->current_row_for_warning();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
query= user= 0;
|
||||||
|
querylen= userlen= 0;
|
||||||
|
clientcs= global_system_variables.character_set_client;
|
||||||
|
rows= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql_audit_notify(thd, MYSQL_AUDIT_GENERAL_CLASS, event_subtype,
|
||||||
|
error_code, time, user, userlen, msg, msglen,
|
||||||
|
query, querylen, clientcs, rows);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* SQL_AUDIT_INCLUDED */
|
@ -32,6 +32,7 @@
|
|||||||
#include "slave.h"
|
#include "slave.h"
|
||||||
#include <my_bitmap.h>
|
#include <my_bitmap.h>
|
||||||
#include "log_event.h"
|
#include "log_event.h"
|
||||||
|
#include "sql_audit.h"
|
||||||
#include <m_ctype.h>
|
#include <m_ctype.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <thr_alarm.h>
|
#include <thr_alarm.h>
|
||||||
@ -525,6 +526,7 @@ THD::THD()
|
|||||||
dbug_sentry=THD_SENTRY_MAGIC;
|
dbug_sentry=THD_SENTRY_MAGIC;
|
||||||
#endif
|
#endif
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
mysql_audit_init_thd(this);
|
||||||
net.vio=0;
|
net.vio=0;
|
||||||
#endif
|
#endif
|
||||||
client_capabilities= 0; // minimalistic client
|
client_capabilities= 0; // minimalistic client
|
||||||
@ -1043,6 +1045,7 @@ THD::~THD()
|
|||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
ha_close_connection(this);
|
ha_close_connection(this);
|
||||||
|
mysql_audit_release(this);
|
||||||
plugin_thdvar_cleanup(this);
|
plugin_thdvar_cleanup(this);
|
||||||
|
|
||||||
DBUG_PRINT("info", ("freeing security context"));
|
DBUG_PRINT("info", ("freeing security context"));
|
||||||
@ -1060,6 +1063,8 @@ THD::~THD()
|
|||||||
delete rli_fake;
|
delete rli_fake;
|
||||||
rli_fake= NULL;
|
rli_fake= NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mysql_audit_free_thd(this);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
free_root(&main_mem_root, MYF(0));
|
free_root(&main_mem_root, MYF(0));
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#pragma interface /* gcc class implementation */
|
#pragma interface /* gcc class implementation */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <mysql/plugin_audit.h>
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "rpl_tblmap.h"
|
#include "rpl_tblmap.h"
|
||||||
|
|
||||||
@ -1836,6 +1837,20 @@ public:
|
|||||||
partition_info *work_part_info;
|
partition_info *work_part_info;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
/**
|
||||||
|
Array of active audit plugins which have been used by this THD.
|
||||||
|
This list is later iterated to invoke release_thd() on those
|
||||||
|
plugins.
|
||||||
|
*/
|
||||||
|
DYNAMIC_ARRAY audit_class_plugins;
|
||||||
|
/**
|
||||||
|
Array of bits indicating which audit classes have already been
|
||||||
|
added to the list of audit plugins which are currently in use.
|
||||||
|
*/
|
||||||
|
unsigned long audit_class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(ENABLED_DEBUG_SYNC)
|
#if defined(ENABLED_DEBUG_SYNC)
|
||||||
/* Debug Sync facility. See debug_sync.cc. */
|
/* Debug Sync facility. See debug_sync.cc. */
|
||||||
struct st_debug_sync_control *debug_sync_control;
|
struct st_debug_sync_control *debug_sync_control;
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
|
#include "sql_audit.h"
|
||||||
#include "probes_mysql.h"
|
#include "probes_mysql.h"
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
@ -1169,6 +1170,7 @@ void do_handle_one_connection(THD *thd_arg)
|
|||||||
while (!net->error && net->vio != 0 &&
|
while (!net->error && net->vio != 0 &&
|
||||||
!(thd->killed == THD::KILL_CONNECTION))
|
!(thd->killed == THD::KILL_CONNECTION))
|
||||||
{
|
{
|
||||||
|
mysql_audit_release(thd);
|
||||||
if (do_command(thd))
|
if (do_command(thd))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
#include "sql_show.h"
|
#include "sql_show.h"
|
||||||
#include "slave.h"
|
#include "slave.h"
|
||||||
#include "rpl_mi.h"
|
#include "rpl_mi.h"
|
||||||
|
#include "sql_audit.h"
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
static bool delayed_get_table(THD *thd, TABLE_LIST *table_list);
|
static bool delayed_get_table(THD *thd, TABLE_LIST *table_list);
|
||||||
@ -2473,6 +2474,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
|
|||||||
while (!thd->killed)
|
while (!thd->killed)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
mysql_audit_release(thd);
|
||||||
#if defined(HAVE_BROKEN_COND_TIMEDWAIT)
|
#if defined(HAVE_BROKEN_COND_TIMEDWAIT)
|
||||||
error= mysql_cond_wait(&di->cond, &di->mutex);
|
error= mysql_cond_wait(&di->cond, &di->mutex);
|
||||||
#else
|
#else
|
||||||
@ -2554,6 +2556,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
|
|||||||
mysql_unlock_tables(thd, lock);
|
mysql_unlock_tables(thd, lock);
|
||||||
ha_autocommit_or_rollback(thd, 0);
|
ha_autocommit_or_rollback(thd, 0);
|
||||||
di->group_count=0;
|
di->group_count=0;
|
||||||
|
mysql_audit_release(thd);
|
||||||
mysql_mutex_lock(&di->mutex);
|
mysql_mutex_lock(&di->mutex);
|
||||||
}
|
}
|
||||||
if (di->tables_in_use)
|
if (di->tables_in_use)
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "sp_cache.h"
|
#include "sp_cache.h"
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
#include "sql_trigger.h"
|
#include "sql_trigger.h"
|
||||||
|
#include "sql_audit.h"
|
||||||
#include "sql_prepare.h"
|
#include "sql_prepare.h"
|
||||||
#include "probes_mysql.h"
|
#include "probes_mysql.h"
|
||||||
#include "set_var.h"
|
#include "set_var.h"
|
||||||
@ -1495,6 +1496,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
/* Free tables */
|
/* Free tables */
|
||||||
close_thread_tables(thd);
|
close_thread_tables(thd);
|
||||||
|
|
||||||
|
if (!thd->is_error() && !thd->killed_errno())
|
||||||
|
mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_RESULT, 0, 0);
|
||||||
|
|
||||||
log_slow_statement(thd);
|
log_slow_statement(thd);
|
||||||
|
|
||||||
thd_proc_info(thd, "cleaning up");
|
thd_proc_info(thd, "cleaning up");
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "sys_vars_shared.h"
|
#include "sys_vars_shared.h"
|
||||||
#include <my_pthread.h>
|
#include <my_pthread.h>
|
||||||
#include <my_getopt.h>
|
#include <my_getopt.h>
|
||||||
|
#include <mysql/plugin_audit.h>
|
||||||
#define REPORT_TO_LOG 1
|
#define REPORT_TO_LOG 1
|
||||||
#define REPORT_TO_USER 2
|
#define REPORT_TO_USER 2
|
||||||
|
|
||||||
@ -48,12 +49,16 @@ const LEX_STRING plugin_type_names[MYSQL_MAX_PLUGIN_TYPE_NUM]=
|
|||||||
{ C_STRING_WITH_LEN("FTPARSER") },
|
{ C_STRING_WITH_LEN("FTPARSER") },
|
||||||
{ C_STRING_WITH_LEN("DAEMON") },
|
{ C_STRING_WITH_LEN("DAEMON") },
|
||||||
{ C_STRING_WITH_LEN("INFORMATION SCHEMA") },
|
{ C_STRING_WITH_LEN("INFORMATION SCHEMA") },
|
||||||
|
{ C_STRING_WITH_LEN("AUDIT") },
|
||||||
{ C_STRING_WITH_LEN("REPLICATION") },
|
{ C_STRING_WITH_LEN("REPLICATION") },
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int initialize_schema_table(st_plugin_int *plugin);
|
extern int initialize_schema_table(st_plugin_int *plugin);
|
||||||
extern int finalize_schema_table(st_plugin_int *plugin);
|
extern int finalize_schema_table(st_plugin_int *plugin);
|
||||||
|
|
||||||
|
extern int initialize_audit_plugin(st_plugin_int *plugin);
|
||||||
|
extern int finalize_audit_plugin(st_plugin_int *plugin);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The number of elements in both plugin_type_initialize and
|
The number of elements in both plugin_type_initialize and
|
||||||
plugin_type_deinitialize should equal to the number of plugins
|
plugin_type_deinitialize should equal to the number of plugins
|
||||||
@ -61,12 +66,14 @@ extern int finalize_schema_table(st_plugin_int *plugin);
|
|||||||
*/
|
*/
|
||||||
plugin_type_init plugin_type_initialize[MYSQL_MAX_PLUGIN_TYPE_NUM]=
|
plugin_type_init plugin_type_initialize[MYSQL_MAX_PLUGIN_TYPE_NUM]=
|
||||||
{
|
{
|
||||||
0,ha_initialize_handlerton,0,0,initialize_schema_table
|
0,ha_initialize_handlerton,0,0,initialize_schema_table,
|
||||||
|
initialize_audit_plugin
|
||||||
};
|
};
|
||||||
|
|
||||||
plugin_type_init plugin_type_deinitialize[MYSQL_MAX_PLUGIN_TYPE_NUM]=
|
plugin_type_init plugin_type_deinitialize[MYSQL_MAX_PLUGIN_TYPE_NUM]=
|
||||||
{
|
{
|
||||||
0,ha_finalize_handlerton,0,0,finalize_schema_table
|
0,ha_finalize_handlerton,0,0,finalize_schema_table,
|
||||||
|
finalize_audit_plugin
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HAVE_DLOPEN
|
#ifdef HAVE_DLOPEN
|
||||||
@ -88,7 +95,8 @@ static int min_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
|
|||||||
MYSQL_FTPARSER_INTERFACE_VERSION,
|
MYSQL_FTPARSER_INTERFACE_VERSION,
|
||||||
MYSQL_DAEMON_INTERFACE_VERSION,
|
MYSQL_DAEMON_INTERFACE_VERSION,
|
||||||
MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION,
|
MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION,
|
||||||
MYSQL_REPLICATION_INTERFACE_VERSION,
|
MYSQL_AUDIT_INTERFACE_VERSION,
|
||||||
|
MYSQL_REPLICATION_INTERFACE_VERSION
|
||||||
};
|
};
|
||||||
static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
|
static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
|
||||||
{
|
{
|
||||||
@ -97,7 +105,8 @@ static int cur_plugin_info_interface_version[MYSQL_MAX_PLUGIN_TYPE_NUM]=
|
|||||||
MYSQL_FTPARSER_INTERFACE_VERSION,
|
MYSQL_FTPARSER_INTERFACE_VERSION,
|
||||||
MYSQL_DAEMON_INTERFACE_VERSION,
|
MYSQL_DAEMON_INTERFACE_VERSION,
|
||||||
MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION,
|
MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION,
|
||||||
MYSQL_REPLICATION_INTERFACE_VERSION,
|
MYSQL_AUDIT_INTERFACE_VERSION,
|
||||||
|
MYSQL_REPLICATION_INTERFACE_VERSION
|
||||||
};
|
};
|
||||||
|
|
||||||
/* support for Services */
|
/* support for Services */
|
||||||
@ -1025,6 +1034,10 @@ static int plugin_initialize(struct st_plugin_int *plugin)
|
|||||||
DBUG_ENTER("plugin_initialize");
|
DBUG_ENTER("plugin_initialize");
|
||||||
|
|
||||||
mysql_mutex_assert_owner(&LOCK_plugin);
|
mysql_mutex_assert_owner(&LOCK_plugin);
|
||||||
|
uint state= plugin->state;
|
||||||
|
DBUG_ASSERT(state == PLUGIN_IS_UNINITIALIZED);
|
||||||
|
|
||||||
|
mysql_mutex_unlock(&LOCK_plugin);
|
||||||
if (plugin_type_initialize[plugin->plugin->type])
|
if (plugin_type_initialize[plugin->plugin->type])
|
||||||
{
|
{
|
||||||
if ((*plugin_type_initialize[plugin->plugin->type])(plugin))
|
if ((*plugin_type_initialize[plugin->plugin->type])(plugin))
|
||||||
@ -1043,8 +1056,7 @@ static int plugin_initialize(struct st_plugin_int *plugin)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
state= PLUGIN_IS_READY; // plugin->init() succeeded
|
||||||
plugin->state= PLUGIN_IS_READY;
|
|
||||||
|
|
||||||
if (plugin->plugin->status_vars)
|
if (plugin->plugin->status_vars)
|
||||||
{
|
{
|
||||||
@ -1063,7 +1075,8 @@ static int plugin_initialize(struct st_plugin_int *plugin)
|
|||||||
if (add_status_vars(array)) // add_status_vars makes a copy
|
if (add_status_vars(array)) // add_status_vars makes a copy
|
||||||
goto err;
|
goto err;
|
||||||
#else
|
#else
|
||||||
add_status_vars(plugin->plugin->status_vars); // add_status_vars makes a copy
|
if (add_status_vars(plugin->plugin->status_vars))
|
||||||
|
goto err;
|
||||||
#endif /* FIX_LATER */
|
#endif /* FIX_LATER */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1086,10 +1099,13 @@ static int plugin_initialize(struct st_plugin_int *plugin)
|
|||||||
ret= 0;
|
ret= 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
mysql_mutex_lock(&LOCK_plugin);
|
||||||
|
plugin->state= state;
|
||||||
|
|
||||||
/* maintain the obsolete @@have_innodb variable */
|
/* maintain the obsolete @@have_innodb variable */
|
||||||
if (!my_strcasecmp(&my_charset_latin1, plugin->name.str, "InnoDB"))
|
if (!my_strcasecmp(&my_charset_latin1, plugin->name.str, "InnoDB"))
|
||||||
have_innodb= plugin->state & PLUGIN_IS_READY ? SHOW_OPTION_YES
|
have_innodb= state & PLUGIN_IS_READY ? SHOW_OPTION_YES
|
||||||
: SHOW_OPTION_DISABLED;
|
: SHOW_OPTION_DISABLED;
|
||||||
|
|
||||||
DBUG_RETURN(ret);
|
DBUG_RETURN(ret);
|
||||||
}
|
}
|
||||||
@ -1422,26 +1438,22 @@ end:
|
|||||||
*/
|
*/
|
||||||
static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
|
static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
|
||||||
{
|
{
|
||||||
|
THD thd;
|
||||||
TABLE_LIST tables;
|
TABLE_LIST tables;
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
READ_RECORD read_record_info;
|
READ_RECORD read_record_info;
|
||||||
int error;
|
int error;
|
||||||
THD *new_thd;
|
THD *new_thd= &thd;
|
||||||
#ifdef EMBEDDED_LIBRARY
|
#ifdef EMBEDDED_LIBRARY
|
||||||
bool table_exists;
|
bool table_exists;
|
||||||
#endif /* EMBEDDED_LIBRARY */
|
#endif /* EMBEDDED_LIBRARY */
|
||||||
DBUG_ENTER("plugin_load");
|
DBUG_ENTER("plugin_load");
|
||||||
|
|
||||||
if (!(new_thd= new THD))
|
|
||||||
{
|
|
||||||
sql_print_error("Can't allocate memory for plugin structures");
|
|
||||||
delete new_thd;
|
|
||||||
DBUG_VOID_RETURN;
|
|
||||||
}
|
|
||||||
new_thd->thread_stack= (char*) &tables;
|
new_thd->thread_stack= (char*) &tables;
|
||||||
new_thd->store_globals();
|
new_thd->store_globals();
|
||||||
new_thd->db= my_strdup("mysql", MYF(0));
|
new_thd->db= my_strdup("mysql", MYF(0));
|
||||||
new_thd->db_length= 5;
|
new_thd->db_length= 5;
|
||||||
|
bzero((char*) &thd.net, sizeof(thd.net));
|
||||||
bzero((uchar*)&tables, sizeof(tables));
|
bzero((uchar*)&tables, sizeof(tables));
|
||||||
tables.alias= tables.table_name= (char*)"plugin";
|
tables.alias= tables.table_name= (char*)"plugin";
|
||||||
tables.lock_type= TL_READ;
|
tables.lock_type= TL_READ;
|
||||||
@ -1499,7 +1511,6 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
|
|||||||
new_thd->version--; // Force close to free memory
|
new_thd->version--; // Force close to free memory
|
||||||
end:
|
end:
|
||||||
close_thread_tables(new_thd);
|
close_thread_tables(new_thd);
|
||||||
delete new_thd;
|
|
||||||
/* Remember that we don't have a THD */
|
/* Remember that we don't have a THD */
|
||||||
my_pthread_setspecific_ptr(THR_THD, 0);
|
my_pthread_setspecific_ptr(THR_THD, 0);
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
@ -1763,7 +1774,6 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(tmp->state == PLUGIN_IS_UNINITIALIZED);
|
|
||||||
if (plugin_initialize(tmp))
|
if (plugin_initialize(tmp))
|
||||||
{
|
{
|
||||||
my_error(ER_CANT_INITIALIZE_UDF, MYF(0), name->str,
|
my_error(ER_CANT_INITIALIZE_UDF, MYF(0), name->str,
|
||||||
@ -2176,7 +2186,7 @@ static int check_func_set(THD *thd, struct st_mysql_sys_var *var,
|
|||||||
{
|
{
|
||||||
if (value->val_int(value, (long long *)&result))
|
if (value->val_int(value, (long long *)&result))
|
||||||
goto err;
|
goto err;
|
||||||
if (unlikely((result >= (ULL(1) << typelib->count)) &&
|
if (unlikely((result >= (1ULL << typelib->count)) &&
|
||||||
(typelib->count < sizeof(long)*8)))
|
(typelib->count < sizeof(long)*8)))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -2261,10 +2271,6 @@ sys_var *find_sys_var(THD *thd, const char *str, uint length)
|
|||||||
mysql_rwlock_unlock(&LOCK_system_variables_hash);
|
mysql_rwlock_unlock(&LOCK_system_variables_hash);
|
||||||
mysql_mutex_unlock(&LOCK_plugin);
|
mysql_mutex_unlock(&LOCK_plugin);
|
||||||
|
|
||||||
/*
|
|
||||||
If the variable exists but the plugin it is associated with is not ready
|
|
||||||
then the intern_plugin_lock did not raise an error, so we do it here.
|
|
||||||
*/
|
|
||||||
if (!var)
|
if (!var)
|
||||||
my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
|
my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
|
||||||
DBUG_RETURN(var);
|
DBUG_RETURN(var);
|
||||||
@ -2727,7 +2733,7 @@ TYPELIB* sys_var_pluginvar::plugin_var_typelib(void)
|
|||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL; /* Keep compiler happy */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2888,7 +2894,7 @@ static void plugin_opt_set_limits(struct my_option *options,
|
|||||||
options->typelib= ((sysvar_set_t*) opt)->typelib;
|
options->typelib= ((sysvar_set_t*) opt)->typelib;
|
||||||
options->def_value= ((sysvar_set_t*) opt)->def_val;
|
options->def_value= ((sysvar_set_t*) opt)->def_val;
|
||||||
options->min_value= options->block_size= 0;
|
options->min_value= options->block_size= 0;
|
||||||
options->max_value= (ULL(1) << options->typelib->count) - 1;
|
options->max_value= (1ULL << options->typelib->count) - 1;
|
||||||
break;
|
break;
|
||||||
case PLUGIN_VAR_BOOL:
|
case PLUGIN_VAR_BOOL:
|
||||||
options->var_type= GET_BOOL;
|
options->var_type= GET_BOOL;
|
||||||
@ -2930,7 +2936,7 @@ static void plugin_opt_set_limits(struct my_option *options,
|
|||||||
options->typelib= ((thdvar_set_t*) opt)->typelib;
|
options->typelib= ((thdvar_set_t*) opt)->typelib;
|
||||||
options->def_value= ((thdvar_set_t*) opt)->def_val;
|
options->def_value= ((thdvar_set_t*) opt)->def_val;
|
||||||
options->min_value= options->block_size= 0;
|
options->min_value= options->block_size= 0;
|
||||||
options->max_value= (ULL(1) << options->typelib->count) - 1;
|
options->max_value= (1ULL << options->typelib->count) - 1;
|
||||||
break;
|
break;
|
||||||
case PLUGIN_VAR_BOOL | PLUGIN_VAR_THDLOCAL:
|
case PLUGIN_VAR_BOOL | PLUGIN_VAR_THDLOCAL:
|
||||||
options->var_type= GET_BOOL;
|
options->var_type= GET_BOOL;
|
||||||
|
@ -28,5 +28,6 @@ extern char *longlong2str_with_dig_vector(longlong val,char *dst,int radix,
|
|||||||
|
|
||||||
char *ll2str(longlong val,char *dst,int radix, int upcase)
|
char *ll2str(longlong val,char *dst,int radix, int upcase)
|
||||||
{
|
{
|
||||||
return longlong2str_with_dig_vector(val, dst, radix, _dig_vec_upper);
|
return longlong2str_with_dig_vector(val, dst, radix,
|
||||||
|
upcase ? _dig_vec_upper : _dig_vec_lower);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user