maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #05361
MDEV-260 auditing table accesses
Hi, Monty,
Here's a patch for MDEV-260 (auditing table accesses).
Please review and see whether it's safe for 5.5.
Regards,
Sergei
------------------------------------------------------------
revno: 3728
fixes bug: https://mariadb.atlassian.net/browse/MDEV-260
committer: Sergei Golubchik <sergii@xxxxxxxxx>
branch nick: 5.5
timestamp: Wed 2013-04-17 09:31:24 +0200
message:
MDEV-260 auditing table accesses
modified:
include/mysql/plugin_audit.h
include/mysql/plugin_audit.h.pp
mysql-test/suite/plugins/r/audit_null.result
mysql-test/suite/plugins/t/audit_null.test
plugin/audit_null/audit_null.c
sql/handler.cc
sql/handler.h
sql/sql_audit.cc
sql/sql_audit.h
sql/sql_table.cc
diff:
=== modified file 'include/mysql/plugin_audit.h'
--- include/mysql/plugin_audit.h 2011-07-05 23:13:50 +0000
+++ include/mysql/plugin_audit.h 2013-04-17 07:31:24 +0000
@@ -25,7 +25,7 @@
#define MYSQL_AUDIT_CLASS_MASK_SIZE 1
-#define MYSQL_AUDIT_INTERFACE_VERSION 0x0300
+#define MYSQL_AUDIT_INTERFACE_VERSION 0x0301
/*************************************************************************
@@ -97,6 +97,50 @@ struct mysql_event_connection
unsigned int database_length;
};
+/*
+ AUDIT CLASS : TABLE
+
+ LOCK occurs when a connection "locks" (this does not necessarily mean a table
+ lock and also happens for row-locking engines) the table at the beginning of
+ a statement. This event is generated at the beginning of every statement for
+ every affected table, unless there's a LOCK TABLES statement in effect (in
+ which case it is generated once for LOCK TABLES and then is suppressed until
+ the tables are unlocked).
+
+ CREATE/DROP/RENAME occur when a table is created, dropped, or renamed.
+*/
+
+#define MYSQL_AUDIT_TABLE_CLASS 15
+#define MYSQL_AUDIT_TABLE_CLASSMASK (1 << MYSQL_AUDIT_TABLE_CLASS)
+#define MYSQL_AUDIT_TABLE_LOCK 0
+#define MYSQL_AUDIT_TABLE_CREATE 1
+#define MYSQL_AUDIT_TABLE_DROP 2
+#define MYSQL_AUDIT_TABLE_RENAME 3
+#define MYSQL_AUDIT_TABLE_ALTER 4
+
+struct mysql_event_table
+{
+ unsigned int event_subclass;
+ unsigned long thread_id;
+ const char *user;
+ const char *priv_user;
+ const char *priv_host;
+ const char *external_user;
+ const char *proxy_user;
+ const char *host;
+ const char *ip;
+ const char *database;
+ unsigned int database_length;
+ const char *table;
+ unsigned int table_length;
+ /* for MYSQL_AUDIT_TABLE_LOCK, true if read-only, false if read/write */
+ int read_only;
+ /* for MYSQL_AUDIT_TABLE_RENAME */
+ const char *new_database;
+ unsigned int new_database_length;
+ const char *new_table;
+ unsigned int new_table_length;
+};
/*************************************************************************
Here we define the descriptor structure, that is referred from
=== modified file 'include/mysql/plugin_audit.h.pp'
--- include/mysql/plugin_audit.h.pp 2013-01-18 18:04:23 +0000
+++ include/mysql/plugin_audit.h.pp 2013-04-17 07:31:24 +0000
@@ -279,6 +279,27 @@ struct mysql_event_connection
const char *database;
unsigned int database_length;
};
+struct mysql_event_table
+{
+ unsigned int event_subclass;
+ unsigned long thread_id;
+ const char *user;
+ const char *priv_user;
+ const char *priv_host;
+ const char *external_user;
+ const char *proxy_user;
+ const char *host;
+ const char *ip;
+ const char *database;
+ unsigned int database_length;
+ const char *table;
+ unsigned int table_length;
+ int read_only;
+ const char *new_database;
+ unsigned int new_database_length;
+ const char *new_table;
+ unsigned int new_table_length;
+};
struct st_mysql_audit
{
int interface_version;
=== modified file 'mysql-test/suite/plugins/r/audit_null.result'
--- mysql-test/suite/plugins/r/audit_null.result 2012-11-08 15:49:07 +0000
+++ mysql-test/suite/plugins/r/audit_null.result 2013-04-17 07:31:24 +0000
@@ -1,5 +1,6 @@
set @old_global_general_log=@@global.general_log;
set global general_log=OFF;
+grant select on *.* to testuser@localhost;
install plugin audit_null soname 'adt_null';
select 1;
1
@@ -18,12 +19,82 @@ concat("test1", x)
test1-12
show status like 'audit_null%';
Variable_name Value
-Audit_null_called 19
+Audit_null_called 21
Audit_null_general_error 1
Audit_null_general_log 7
Audit_null_general_result 5
+create table t1 (a int);
+insert t1 values (1), (2);
+select * from t1;
+a
+1
+2
+rename table t1 to t2;
+alter table t2 add column b int;
+create definer=testuser@localhost view v1 as select t2.a+1, t2_copy.a+2 from t2, t2 as t2_copy;
+select * from v1;
+t2.a+1 t2_copy.a+2
+2 3
+3 3
+2 4
+3 4
+drop view v1;
+create temporary table t2 (a date);
+insert t2 values ('2020-10-09');
+select * from t2;
+a
+2020-10-09
+drop table t2;
+explain select distinct * from t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using temporary
+select distinct * from t2;
+a b
+1 NULL
+2 NULL
+drop table t2;
uninstall plugin audit_null;
Warnings:
Warning 1620 Plugin is busy and will be uninstalled on shutdown
drop procedure au1;
+drop user testuser@localhost;
set global general_log=@old_global_general_log;
+root[root] @ localhost [] >> select 1
+root[root] @ localhost [] >> select foobar
+root[root] @ localhost [] >> show status like 'audit_null%'
+root[root] @ localhost [] >> create procedure au1(x char(16)) select concat("test1", x)
+root[root] @ localhost [] mysql.proc : write
+root[root] @ localhost [] >> call au1("-12")
+root[root] @ localhost [] mysql.proc : read
+root[root] @ localhost [] >> select concat("test1", NAME_CONST('x',_latin1'-12' COLLATE 'latin1_swedish_ci'))
+root[root] @ localhost [] >> show status like 'audit_null%'
+root[root] @ localhost [] >> create table t1 (a int)
+root[root] @ localhost [] test.t1 : create
+root[root] @ localhost [] >> insert t1 values (1), (2)
+root[root] @ localhost [] test.t1 : write
+root[root] @ localhost [] >> select * from t1
+root[root] @ localhost [] test.t1 : read
+root[root] @ localhost [] >> rename table t1 to t2
+root[root] @ localhost [] test.t1 : rename to test.t2
+root[root] @ localhost [] >> alter table t2 add column b int
+root[root] @ localhost [] test.t2 : alter
+root[root] @ localhost [] test.t2 : read
+root[root] @ localhost [] >> create definer=testuser@localhost view v1 as select t2.a+1, t2_copy.a+2 from t2, t2 as t2_copy
+root[root] @ localhost [] test.t2 : read
+root[root] @ localhost [] test.t2 : read
+root[root] @ localhost [] >> select * from v1
+root[root] @ localhost [] test.t2 : read
+root[root] @ localhost [] test.t2 : read
+root[root] @ localhost [] >> drop view v1
+root[root] @ localhost [] >> create temporary table t2 (a date)
+root[root] @ localhost [] >> insert t2 values ('2020-10-09')
+root[root] @ localhost [] >> select * from t2
+root[root] @ localhost [] >> drop table t2
+root[root] @ localhost [] >> explain select distinct * from t2
+root[root] @ localhost [] test.t2 : read
+root[root] @ localhost [] >> select distinct * from t2
+root[root] @ localhost [] test.t2 : read
+root[root] @ localhost [] >> drop table t2
+root[root] @ localhost [] test.t2 : drop
+root[root] @ localhost [] >> uninstall plugin audit_null
+root[root] @ localhost [] mysql.plugin : write
=== modified file 'mysql-test/suite/plugins/t/audit_null.test'
--- mysql-test/suite/plugins/t/audit_null.test 2012-11-22 09:19:31 +0000
+++ mysql-test/suite/plugins/t/audit_null.test 2013-04-17 07:31:24 +0000
@@ -8,6 +8,8 @@ if (!$ADT_NULL_SO) {
set @old_global_general_log=@@global.general_log;
set global general_log=OFF;
+grant select on *.* to testuser@localhost;
+
--disable_ps_protocol
install plugin audit_null soname 'adt_null';
@@ -22,9 +24,36 @@ call au1("-12");
show status like 'audit_null%';
+create table t1 (a int);
+insert t1 values (1), (2);
+select * from t1;
+rename table t1 to t2;
+alter table t2 add column b int;
+
+create definer=testuser@localhost view v1 as select t2.a+1, t2_copy.a+2 from t2, t2 as t2_copy;
+select * from v1;
+drop view v1;
+
+# temp table generates no audit events
+create temporary table t2 (a date);
+insert t2 values ('2020-10-09');
+select * from t2;
+drop table t2;
+
+# internal temp table generates no audit events
+explain select distinct * from t2;
+select distinct * from t2;
+
+drop table t2;
+
uninstall plugin audit_null;
--enable_ps_protocol
drop procedure au1;
+drop user testuser@localhost;
set global general_log=@old_global_general_log;
+let $MYSQLD_DATADIR= `SELECT @@datadir`;
+--replace_regex /#sql-[0-9a-f_]*/#sql-temporary/ /#sql2-[-0-9a-f_]*/#sql2-temporary/
+cat_file $MYSQLD_DATADIR/audit_null_tables.log;
+
=== modified file 'plugin/audit_null/audit_null.c'
--- plugin/audit_null/audit_null.c 2012-11-07 18:07:47 +0000
+++ plugin/audit_null/audit_null.c 2013-04-17 07:31:24 +0000
@@ -22,11 +22,12 @@
#define __attribute__(A)
#endif
-static volatile int number_of_calls; /* for SHOW STATUS, see below */
-static volatile int number_of_calls_general_log;
-static volatile int number_of_calls_general_error;
-static volatile int number_of_calls_general_result;
+static volatile int ncalls; /* for SHOW STATUS, see below */
+static volatile int ncalls_general_log;
+static volatile int ncalls_general_error;
+static volatile int ncalls_general_result;
+FILE *f;
/*
Initialize the plugin at server start or plugin installation.
@@ -44,11 +45,16 @@ static volatile int number_of_calls_gene
static int audit_null_plugin_init(void *arg __attribute__((unused)))
{
- number_of_calls= 0;
- number_of_calls_general_log= 0;
- number_of_calls_general_error= 0;
- number_of_calls_general_result= 0;
- return(0);
+ ncalls= 0;
+ ncalls_general_log= 0;
+ ncalls_general_error= 0;
+ ncalls_general_result= 0;
+
+ f = fopen("audit_null_tables.log", "w");
+ if (!f)
+ return 1;
+
+ return 0;
}
@@ -67,7 +73,8 @@ static int audit_null_plugin_init(void *
static int audit_null_plugin_deinit(void *arg __attribute__((unused)))
{
- return(0);
+ fclose(f);
+ return 0;
}
@@ -86,7 +93,7 @@ static void audit_null_notify(MYSQL_THD
const void *event)
{
/* prone to races, oh well */
- number_of_calls++;
+ ncalls++;
if (event_class == MYSQL_AUDIT_GENERAL_CLASS)
{
const struct mysql_event_general *event_general=
@@ -94,18 +101,56 @@ static void audit_null_notify(MYSQL_THD
switch (event_general->event_subclass)
{
case MYSQL_AUDIT_GENERAL_LOG:
- number_of_calls_general_log++;
+ ncalls_general_log++;
+ fprintf(f, "%s\t>> %s\n", event_general->general_user,
+ event_general->general_query);
break;
case MYSQL_AUDIT_GENERAL_ERROR:
- number_of_calls_general_error++;
+ ncalls_general_error++;
break;
case MYSQL_AUDIT_GENERAL_RESULT:
- number_of_calls_general_result++;
+ ncalls_general_result++;
break;
default:
break;
}
}
+ else
+ if (event_class == MYSQL_AUDIT_TABLE_CLASS)
+ {
+ const struct mysql_event_table *event_table=
+ (const struct mysql_event_table *) event;
+ const char *ip= event_table->ip ? event_table->ip : "";
+ const char *op= 0;
+ char buf[1024];
+
+ switch (event_table->event_subclass)
+ {
+ case MYSQL_AUDIT_TABLE_LOCK:
+ op= event_table->read_only ? "read" : "write";
+ break;
+ case MYSQL_AUDIT_TABLE_CREATE:
+ op= "create";
+ break;
+ case MYSQL_AUDIT_TABLE_DROP:
+ op= "drop";
+ break;
+ case MYSQL_AUDIT_TABLE_ALTER:
+ op= "alter";
+ break;
+ case MYSQL_AUDIT_TABLE_RENAME:
+ snprintf(buf, sizeof(buf), "rename to %s.%s",
+ event_table->new_database, event_table->new_table);
+ buf[sizeof(buf)-1]= 0;
+ op= buf;
+ break;
+ }
+
+ fprintf(f, "%s[%s] @ %s [%s]\t%s.%s : %s\n",
+ event_table->priv_user, event_table->user,
+ event_table->host, ip,
+ event_table->database, event_table->table, op);
+ }
}
@@ -127,12 +170,10 @@ static struct st_mysql_audit audit_null_
static struct st_mysql_show_var simple_status[]=
{
- { "Audit_null_called", (char *) &number_of_calls, SHOW_INT },
- { "Audit_null_general_log", (char *) &number_of_calls_general_log, SHOW_INT },
- { "Audit_null_general_error", (char *) &number_of_calls_general_error,
- SHOW_INT },
- { "Audit_null_general_result", (char *) &number_of_calls_general_result,
- SHOW_INT },
+ { "Audit_null_called", (char *) &ncalls, SHOW_INT },
+ { "Audit_null_general_log", (char *) &ncalls_general_log, SHOW_INT },
+ { "Audit_null_general_error", (char *) &ncalls_general_error, SHOW_INT },
+ { "Audit_null_general_result", (char *) &ncalls_general_result, SHOW_INT },
{ 0, 0, 0}
};
=== modified file 'sql/handler.cc'
--- sql/handler.cc 2013-01-18 18:04:23 +0000
+++ sql/handler.cc 2013-04-17 07:31:24 +0000
@@ -43,6 +43,7 @@
#include "myisam.h"
#include "probes_mysql.h"
#include "debug_sync.h" // DEBUG_SYNC
+#include "sql_audit.h"
#ifdef WITH_PARTITION_STORAGE_ENGINE
#include "ha_partition.h"
@@ -3722,8 +3722,11 @@ int
handler::ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info)
{
mark_trx_read_write();
-
- return create(name, form, info);
+ int error= create(name, form, info);
+ if (!error &&
+ !(info->options & (HA_LEX_CREATE_TMP_TABLE | HA_CREATE_TMP_ALTER)))
+ mysql_audit_create_table(form);
+ return error;
}
@@ -5099,7 +5102,11 @@ int handler::ha_external_lock(THD *thd,
int error= external_lock(thd, lock_type);
if (error == 0)
+ {
cached_table_flags= table_flags();
+ if (table_share->tmp_table == NO_TMP_TABLE)
+ mysql_audit_external_lock(thd, table_share, lock_type);
+ }
if (MYSQL_HANDLER_RDLOCK_DONE_ENABLED() ||
MYSQL_HANDLER_WRLOCK_DONE_ENABLED() ||
=== modified file 'sql/handler.h'
--- sql/handler.h 2013-01-18 18:04:23 +0000
+++ sql/handler.h 2013-04-17 07:31:24 +0000
@@ -318,6 +318,7 @@
#define HA_LEX_CREATE_TMP_TABLE 1
#define HA_LEX_CREATE_IF_NOT_EXISTS 2
#define HA_LEX_CREATE_TABLE_LIKE 4
+#define HA_CREATE_TMP_ALTER 8
#define HA_MAX_REC_LENGTH 65535
/* Table caching type */
=== modified file 'sql/sql_audit.cc'
--- sql/sql_audit.cc 2013-01-15 18:16:29 +0000
+++ sql/sql_audit.cc 2013-04-17 07:31:24 +0000
@@ -111,9 +110,36 @@ static void connection_class_handler(THD
}
+static void table_class_handler(THD *thd, uint event_subclass, va_list ap)
+{
+ mysql_event_table event;
+ event.event_subclass= event_subclass;
+ event.read_only= va_arg(ap, int);
+ event.thread_id= va_arg(ap, unsigned long);
+ event.user= va_arg(ap, const char *);
+ event.priv_user= va_arg(ap, const char *);
+ event.priv_host= va_arg(ap, const char *);
+ event.external_user= va_arg(ap, const char *);
+ event.proxy_user= va_arg(ap, const char *);
+ event.host= va_arg(ap, const char *);
+ event.ip= va_arg(ap, const char *);
+ event.database= va_arg(ap, const char *);
+ event.database_length= va_arg(ap, unsigned int);
+ event.table= va_arg(ap, const char *);
+ event.table_length= va_arg(ap, unsigned int);
+ event.new_database= va_arg(ap, const char *);
+ event.new_database_length= va_arg(ap, unsigned int);
+ event.new_table= va_arg(ap, const char *);
+ event.new_table_length= va_arg(ap, unsigned int);
+ event_class_dispatch(thd, MYSQL_AUDIT_TABLE_CLASS, &event);
+}
+
+
static audit_handler_t audit_handlers[] =
{
- general_class_handler, connection_class_handler
+ general_class_handler, connection_class_handler,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0, /* placeholders */
+ table_class_handler
};
static const uint audit_handlers_count=
=== modified file 'sql/sql_audit.h'
--- sql/sql_audit.h 2013-01-15 18:16:29 +0000
+++ sql/sql_audit.h 2013-04-17 07:31:24 +0000
@@ -43,17 +43,23 @@ static inline bool mysql_audit_general_e
return mysql_global_audit_mask[0] & MYSQL_AUDIT_GENERAL_CLASSMASK;
}
+static inline bool mysql_audit_table_enabled()
+{
+ return mysql_global_audit_mask[0] & MYSQL_AUDIT_TABLE_CLASSMASK;
+}
+
#else
static inline void mysql_audit_notify(THD *thd, uint event_class,
uint event_subtype, ...) { }
#define mysql_audit_general_enabled() 0
+#define mysql_audit_table_enabled() 0
#endif
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;
+ const Security_context *sctx= thd->security_ctx;
return strxnmov(buf, MAX_USER_HOST_SIZE,
sctx->priv_user[0] ? sctx->priv_user : "", "[",
sctx->user ? sctx->user : "", "] @ ",
@@ -174,4 +180,87 @@ void mysql_audit_general(THD *thd, uint
(thd)->security_ctx->ip ? strlen((thd)->security_ctx->ip) : 0,\
(thd)->db, (thd)->db ? strlen((thd)->db) : 0)
+static inline
+void mysql_audit_external_lock(THD *thd, TABLE_SHARE *share, int lock)
+{
+ if (lock != F_UNLCK && mysql_audit_table_enabled())
+ {
+ const Security_context *sctx= thd->security_ctx;
+ mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, MYSQL_AUDIT_TABLE_LOCK,
+ (int)(lock == F_RDLCK), (ulong)thd->thread_id,
+ sctx->user, sctx->priv_user, sctx->priv_host,
+ sctx->external_user, sctx->proxy_user, sctx->host,
+ sctx->ip, share->db.str, (uint)share->db.length,
+ share->table_name.str, (uint)share->table_name.length,
+ 0,0,0,0);
+ }
+}
+
+static inline
+void mysql_audit_create_table(TABLE *table)
+{
+ if (mysql_audit_table_enabled())
+ {
+ THD *thd= table->in_use;
+ const TABLE_SHARE *share= table->s;
+ const Security_context *sctx= thd->security_ctx;
+ mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, MYSQL_AUDIT_TABLE_CREATE,
+ 0, (ulong)thd->thread_id,
+ sctx->user, sctx->priv_user, sctx->priv_host,
+ sctx->external_user, sctx->proxy_user, sctx->host,
+ sctx->ip, share->db.str, (uint)share->db.length,
+ share->table_name.str, (uint)share->table_name.length,
+ 0,0,0,0);
+ }
+}
+
+static inline
+void mysql_audit_drop_table(THD *thd, TABLE_LIST *table)
+{
+ if (mysql_audit_table_enabled())
+ {
+ const Security_context *sctx= thd->security_ctx;
+ mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, MYSQL_AUDIT_TABLE_DROP,
+ 0, (ulong)thd->thread_id,
+ sctx->user, sctx->priv_user, sctx->priv_host,
+ sctx->external_user, sctx->proxy_user, sctx->host,
+ sctx->ip, table->db, (uint)table->db_length,
+ table->table_name, (uint)table->table_name_length,
+ 0,0,0,0);
+ }
+}
+
+static inline
+void mysql_audit_rename_table(THD *thd, const char *old_db, const char *old_tb,
+ const char *new_db, const char *new_tb)
+{
+ if (mysql_audit_table_enabled())
+ {
+ const Security_context *sctx= thd->security_ctx;
+ mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, MYSQL_AUDIT_TABLE_RENAME,
+ 0, (ulong)thd->thread_id,
+ sctx->user, sctx->priv_user, sctx->priv_host,
+ sctx->external_user, sctx->proxy_user, sctx->host,
+ sctx->ip,
+ old_db, (uint)strlen(old_db), old_tb, (uint)strlen(old_tb),
+ new_db, (uint)strlen(new_db), new_tb, (uint)strlen(new_tb));
+ }
+}
+
+static inline
+void mysql_audit_alter_table(THD *thd, TABLE_LIST *table)
+{
+ if (mysql_audit_table_enabled())
+ {
+ const Security_context *sctx= thd->security_ctx;
+ mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, MYSQL_AUDIT_TABLE_ALTER,
+ 0, (ulong)thd->thread_id,
+ sctx->user, sctx->priv_user, sctx->priv_host,
+ sctx->external_user, sctx->proxy_user, sctx->host,
+ sctx->ip, table->db, (uint)table->db_length,
+ table->table_name, (uint)table->table_name_length,
+ 0,0,0,0);
+ }
+}
+
#endif /* SQL_AUDIT_INCLUDED */
=== modified file 'sql/sql_table.cc'
--- sql/sql_table.cc 2013-03-05 18:15:36 +0000
+++ sql/sql_table.cc 2013-04-17 07:31:24 +0000
@@ -54,6 +54,7 @@
#include "sql_show.h"
#include "transaction.h"
#include "datadict.h" // dd_frm_type()
+#include "sql_audit.h"
#ifdef __WIN__
#include <io.h>
@@ -2344,6 +2345,10 @@ int mysql_rm_table_no_locks(THD *thd, TA
wrong_tables.append(',');
wrong_tables.append(String(table->table_name,system_charset_info));
}
+ else
+ {
+ mysql_audit_drop_table(thd, table);
+ }
DBUG_PRINT("table", ("table: 0x%lx s: 0x%lx", (long) table->table,
table->table ? (long) table->table->s : (long) -1));
@@ -4728,6 +4733,8 @@ mysql_rename_table(handlerton *base, con
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER TABLE");
else if (error)
my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error);
+ else if (!(flags & FN_IS_TMP))
+ mysql_audit_rename_table(thd, old_db, old_name, new_db, new_name);
DBUG_RETURN(error != 0);
}
@@ -6054,6 +6061,8 @@ bool mysql_alter_table(THD *thd,char *ne
mysql_ha_rm_tables(thd, table_list);
+ mysql_audit_alter_table(thd, table_list);
+
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
if (alter_info->tablespace_op != NO_TABLESPACE_OP)
/* Conditionally writes to binlog. */
@@ -6716,6 +6725,7 @@ bool mysql_alter_table(THD *thd,char *ne
HA_OPTION_PACK_RECORD));
}
tmp_disable_binlog(thd);
+ create_info->options|=HA_CREATE_TMP_ALTER;
error= mysql_create_table_no_lock(thd, new_db, tmp_name,
create_info,
alter_info,