27
27
#include <drizzled/server_includes.h>
28
#include <drizzled/sql_repl.h>
29
#include <drizzled/rpl_filter.h>
30
#include <drizzled/rpl_rli.h>
29
#include "rpl_filter.h"
32
32
#include <mysys/my_dir.h>
33
33
#include <stdarg.h>
35
35
#include <drizzled/plugin.h>
36
#include <drizzled/error.h>
37
#include <drizzled/gettext.h>
38
#include <drizzled/data_home.h>
36
#include <drizzled/drizzled_error_messages.h>
37
#include <libdrizzle/gettext.h>
41
39
/* max size of the log message */
40
#define MAX_LOG_BUFFER_SIZE 1024
41
#define MAX_USER_HOST_SIZE 512
42
#define MAX_TIME_SIZE 32
42
43
#define MY_OFF_T_UNDEF (~(my_off_t)0UL)
45
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
46
49
DRIZZLE_BIN_LOG mysql_bin_log;
47
50
ulong sync_binlog_counter= 0;
49
52
static bool test_if_number(const char *str,
50
long *res, bool allow_wildcards);
53
long *res, bool allow_wildcards);
51
54
static int binlog_init(void *p);
52
static int binlog_close_connection(handlerton *hton, Session *session);
53
static int binlog_savepoint_set(handlerton *hton, Session *session, void *sv);
54
static int binlog_savepoint_rollback(handlerton *hton, Session *session, void *sv);
55
static int binlog_commit(handlerton *hton, Session *session, bool all);
56
static int binlog_rollback(handlerton *hton, Session *session, bool all);
57
static int binlog_prepare(handlerton *hton, Session *session, bool all);
55
static int binlog_close_connection(handlerton *hton, THD *thd);
56
static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv);
57
static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv);
58
static int binlog_commit(handlerton *hton, THD *thd, bool all);
59
static int binlog_rollback(handlerton *hton, THD *thd, bool all);
60
static int binlog_prepare(handlerton *hton, THD *thd, bool all);
60
63
sql_print_message_func sql_print_message_handlers[3] =
200
203
handlerton *binlog_hton;
206
/* Check if a given table is opened log table */
207
int check_if_log_table(uint db_len __attribute__((unused)),
208
const char *db __attribute__((unused)),
209
uint table_name_len __attribute__((unused)),
210
const char *table_name __attribute__((unused)),
211
uint check_if_opened __attribute__((unused)))
216
/* log event handlers */
218
bool Log_to_file_event_handler::
219
log_error(enum loglevel level, const char *format,
222
return vprint_msg_to_log(level, format, args);
225
void Log_to_file_event_handler::init_pthread_objects()
227
mysql_log.init_pthread_objects();
228
mysql_slow_log.init_pthread_objects();
232
/** Wrapper around DRIZZLE_LOG::write() for slow log. */
234
bool Log_to_file_event_handler::
235
log_slow(THD *thd, time_t current_time, time_t query_start_arg,
236
const char *user_host, uint user_host_len,
237
uint64_t query_utime, uint64_t lock_utime, bool is_command,
238
const char *sql_text, uint sql_text_len)
240
return mysql_slow_log.write(thd, current_time, query_start_arg,
241
user_host, user_host_len,
242
query_utime, lock_utime, is_command,
243
sql_text, sql_text_len);
248
Wrapper around DRIZZLE_LOG::write() for general log. We need it since we
249
want all log event handlers to have the same signature.
252
bool Log_to_file_event_handler::
253
log_general(THD *thd __attribute__((unused)),
254
time_t event_time, const char *user_host,
255
uint user_host_len, int thread_id,
256
const char *command_type, uint command_type_len,
257
const char *sql_text, uint sql_text_len,
258
const CHARSET_INFO * const client_cs __attribute__((unused)))
260
return mysql_log.write(event_time, user_host, user_host_len,
261
thread_id, command_type, command_type_len,
262
sql_text, sql_text_len);
266
bool Log_to_file_event_handler::init()
271
mysql_slow_log.open_slow_log(sys_var_slow_log_path.value);
274
mysql_log.open_query_log(sys_var_general_log_path.value);
276
is_initialized= true;
283
void Log_to_file_event_handler::cleanup()
286
mysql_slow_log.cleanup();
289
void Log_to_file_event_handler::flush()
291
/* reopen log files */
293
mysql_log.reopen_file();
295
mysql_slow_log.reopen_file();
204
299
Log error with all enabled log event handlers
270
378
logger.lock_exclusive();
380
/* reopen log files */
381
file_log_handler->flush();
272
383
/* end of log flush */
277
void LOGGER::init_error_log(uint32_t error_log_printer)
390
Log slow query with all enabled log event handlers
395
thd THD of the query being logged
396
query The query being logged
397
query_length The length of the query string
398
current_utime Current time in microseconds (from undefined start)
405
bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
406
uint64_t current_utime)
410
Log_event_handler **current_handler;
411
bool is_command= false;
412
char user_host_buff[MAX_USER_HOST_SIZE];
413
Security_context *sctx= thd->security_ctx;
414
uint user_host_len= 0;
415
uint64_t query_utime, lock_utime;
418
Print the message to the buffer if we have slow log enabled
421
if (*slow_log_handler_list)
425
/* do not log slow queries from replication threads */
426
if (thd->slave_thread && !opt_log_slow_slave_statements)
436
/* fill in user_host value: the format is "%s[%s] @ %s [%s]" */
437
user_host_len= (strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
438
sctx->user, "[", sctx->user, "] @ ",
440
sctx->ip, "]", NullS) -
443
current_time= my_time_possible_from_micro(current_utime);
444
if (thd->start_utime)
446
query_utime= (current_utime - thd->start_utime);
447
lock_utime= (thd->utime_after_lock - thd->start_utime);
451
query_utime= lock_utime= 0;
457
query= command_name[thd->command].str;
458
query_length= command_name[thd->command].length;
461
for (current_handler= slow_log_handler_list; *current_handler ;)
462
error= (*current_handler++)->log_slow(thd, current_time, thd->start_time,
463
user_host_buff, user_host_len,
464
query_utime, lock_utime, is_command,
465
query, query_length) || error;
472
bool LOGGER::general_log_write(THD *thd, enum enum_server_command command,
473
const char *query, uint query_length)
476
Log_event_handler **current_handler= general_log_handler_list;
477
char user_host_buff[MAX_USER_HOST_SIZE];
478
Security_context *sctx= thd->security_ctx;
480
uint user_host_len= 0;
484
id= thd->thread_id; /* Normal thread */
486
id= 0; /* Log from connect handler */
494
user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
498
sctx->ip, "]", NullS) -
501
current_time= my_time(0);
503
while (*current_handler)
504
error|= (*current_handler++)->
505
log_general(thd, current_time, user_host_buff,
507
command_name[(uint) command].str,
508
command_name[(uint) command].length,
510
thd->variables.character_set_client) || error;
516
bool LOGGER::general_log_print(THD *thd, enum enum_server_command command,
517
const char *format, va_list args)
519
uint message_buff_len= 0;
520
char message_buff[MAX_LOG_BUFFER_SIZE];
522
/* prepare message */
524
message_buff_len= vsnprintf(message_buff, sizeof(message_buff),
527
message_buff[0]= '\0';
529
return general_log_write(thd, command, message_buff, message_buff_len);
532
void LOGGER::init_error_log(uint error_log_printer)
279
534
if (error_log_printer & LOG_NONE)
287
int LOGGER::set_handlers(uint32_t error_log_printer)
540
switch (error_log_printer) {
542
error_log_handler_list[0]= file_log_handler;
543
error_log_handler_list[1]= 0;
548
void LOGGER::init_slow_log(uint slow_log_printer)
550
if (slow_log_printer & LOG_NONE)
552
slow_log_handler_list[0]= 0;
556
slow_log_handler_list[0]= file_log_handler;
557
slow_log_handler_list[1]= 0;
560
void LOGGER::init_general_log(uint general_log_printer)
562
if (general_log_printer & LOG_NONE)
564
general_log_handler_list[0]= 0;
568
general_log_handler_list[0]= file_log_handler;
569
general_log_handler_list[1]= 0;
573
bool LOGGER::activate_log_handler(THD* thd __attribute__((unused)),
576
DRIZZLE_QUERY_LOG *file_log;
583
file_log= file_log_handler->get_mysql_slow_log();
585
file_log->open_slow_log(sys_var_slow_log_path.value);
586
init_slow_log(log_output_options);
590
case QUERY_LOG_GENERAL:
593
file_log= file_log_handler->get_mysql_log();
595
file_log->open_query_log(sys_var_general_log_path.value);
596
init_general_log(log_output_options);
608
void LOGGER::deactivate_log_handler(THD *thd __attribute__((unused)),
612
DRIZZLE_LOG *file_log;
616
tmp_opt= &opt_slow_log;
617
file_log= file_log_handler->get_mysql_slow_log();
619
case QUERY_LOG_GENERAL:
621
file_log= file_log_handler->get_mysql_log();
624
assert(0); // Impossible
636
int LOGGER::set_handlers(uint error_log_printer,
637
uint slow_log_printer,
638
uint general_log_printer)
289
640
/* error log table is not supported yet */
290
641
lock_exclusive();
292
643
init_error_log(error_log_printer);
644
init_slow_log(slow_log_printer);
645
init_general_log(general_log_printer);
667
1029
that case there is no need to have it in the binlog).
670
static int binlog_savepoint_set(handlerton *, Session *session, void *sv)
1032
static int binlog_savepoint_set(handlerton *hton __attribute__((unused)),
672
binlog_trans_log_savepos(session, (my_off_t*) sv);
1035
binlog_trans_log_savepos(thd, (my_off_t*) sv);
673
1036
/* Write it to the binary log */
675
1038
int const error=
676
session->binlog_query(Session::STMT_QUERY_TYPE,
677
session->query, session->query_length, true, false);
1039
thd->binlog_query(THD::STMT_QUERY_TYPE,
1040
thd->query, thd->query_length, true, false);
681
static int binlog_savepoint_rollback(handlerton *, Session *session, void *sv)
1044
static int binlog_savepoint_rollback(handlerton *hton __attribute__((unused)),
684
1048
Write ROLLBACK TO SAVEPOINT to the binlog cache if we have updated some
685
1049
non-transactional table. Otherwise, truncate the binlog cache starting
686
1050
from the SAVEPOINT command.
688
if (unlikely(session->transaction.all.modified_non_trans_table ||
689
(session->options & OPTION_KEEP_LOG)))
1052
if (unlikely(thd->transaction.all.modified_non_trans_table ||
1053
(thd->options & OPTION_KEEP_LOG)))
692
session->binlog_query(Session::STMT_QUERY_TYPE,
693
session->query, session->query_length, true, false);
1056
thd->binlog_query(THD::STMT_QUERY_TYPE,
1057
thd->query, thd->query_length, true, false);
696
binlog_trans_log_truncate(session, *(my_off_t*)sv);
1060
binlog_trans_log_truncate(thd, *(my_off_t*)sv);
1367
Reopen the log file. The method is used during FLUSH LOGS
1368
and locks LOCK_log mutex
1372
void DRIZZLE_QUERY_LOG::reopen_file()
1381
pthread_mutex_lock(&LOCK_log);
1384
name= 0; // Don't free name
1385
close(LOG_CLOSE_TO_BE_OPENED);
1388
Note that at this point, log_state != LOG_CLOSED (important for is_open()).
1391
open(save_name, log_type, 0, io_cache_type);
1392
my_free(save_name, MYF(0));
1394
pthread_mutex_unlock(&LOCK_log);
1401
Write a command to traditional general log file
1406
event_time command start timestamp
1407
user_host the pointer to the string with user@host info
1408
user_host_len length of the user_host string. this is computed once
1409
and passed to all general log event handlers
1410
thread_id Id of the thread, issued a query
1411
command_type the type of the command being logged
1412
command_type_len the length of the string above
1413
sql_text the very text of the query being executed
1414
sql_text_len the length of sql_text string
1418
Log given command to to normal (not rotable) log file
1422
TRUE - error occured
1425
bool DRIZZLE_QUERY_LOG::write(time_t event_time,
1426
const char *user_host __attribute__((unused)),
1427
uint user_host_len __attribute__((unused)),
1429
const char *command_type, uint command_type_len,
1430
const char *sql_text, uint sql_text_len)
1434
char local_time_buff[MAX_TIME_SIZE];
1436
uint time_buff_len= 0;
1438
(void) pthread_mutex_lock(&LOCK_log);
1440
/* Test if someone closed between the is_open test and lock */
1443
/* Note that my_b_write() assumes it knows the length for this */
1444
if (event_time != last_time)
1446
last_time= event_time;
1448
localtime_r(&event_time, &start);
1450
time_buff_len= snprintf(local_time_buff, MAX_TIME_SIZE,
1451
"%02d%02d%02d %2d:%02d:%02d",
1452
start.tm_year % 100, start.tm_mon + 1,
1453
start.tm_mday, start.tm_hour,
1454
start.tm_min, start.tm_sec);
1456
if (my_b_write(&log_file, (uchar*) local_time_buff, time_buff_len))
1460
if (my_b_write(&log_file, (uchar*) "\t\t" ,2) < 0)
1463
/* command_type, thread_id */
1464
length= snprintf(buff, 32, "%5ld ", (long) thread_id);
1466
if (my_b_write(&log_file, (uchar*) buff, length))
1469
if (my_b_write(&log_file, (uchar*) command_type, command_type_len))
1472
if (my_b_write(&log_file, (uchar*) "\t", 1))
1476
if (my_b_write(&log_file, (uchar*) sql_text, sql_text_len))
1479
if (my_b_write(&log_file, (uchar*) "\n", 1) ||
1480
flush_io_cache(&log_file))
1484
(void) pthread_mutex_unlock(&LOCK_log);
1491
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
1493
(void) pthread_mutex_unlock(&LOCK_log);
1499
Log a query to the traditional slow log file
1504
thd THD of the query
1505
current_time current timestamp
1506
query_start_arg command start timestamp
1507
user_host the pointer to the string with user@host info
1508
user_host_len length of the user_host string. this is computed once
1509
and passed to all general log event handlers
1510
query_utime Amount of time the query took to execute (in microseconds)
1511
lock_utime Amount of time the query was locked (in microseconds)
1512
is_command The flag, which determines, whether the sql_text is a
1513
query or an administrator command.
1514
sql_text the very text of the query or administrator command
1516
sql_text_len the length of sql_text string
1520
Log a query to the slow log file.
1524
TRUE - error occured
1527
bool DRIZZLE_QUERY_LOG::write(THD *thd, time_t current_time,
1528
time_t query_start_arg __attribute__((unused)),
1529
const char *user_host,
1530
uint user_host_len, uint64_t query_utime,
1531
uint64_t lock_utime, bool is_command,
1532
const char *sql_text, uint sql_text_len)
1536
(void) pthread_mutex_lock(&LOCK_log);
1540
(void) pthread_mutex_unlock(&LOCK_log);
1545
{ // Safety agains reopen
1547
char buff[80], *end;
1548
char query_time_buff[22+7], lock_time_buff[22+7];
1553
if (current_time != last_time)
1555
last_time= current_time;
1557
localtime_r(¤t_time, &start);
1559
buff_len= snprintf(buff, sizeof buff,
1560
"# Time: %02d%02d%02d %2d:%02d:%02d\n",
1561
start.tm_year % 100, start.tm_mon + 1,
1562
start.tm_mday, start.tm_hour,
1563
start.tm_min, start.tm_sec);
1565
/* Note that my_b_write() assumes it knows the length for this */
1566
if (my_b_write(&log_file, (uchar*) buff, buff_len))
1569
const uchar uh[]= "# User@Host: ";
1570
if (my_b_write(&log_file, uh, sizeof(uh) - 1))
1572
if (my_b_write(&log_file, (uchar*) user_host, user_host_len))
1574
if (my_b_write(&log_file, (uchar*) "\n", 1))
1577
/* For slow query log */
1578
sprintf(query_time_buff, "%.6f", uint64_t2double(query_utime)/1000000.0);
1579
sprintf(lock_time_buff, "%.6f", uint64_t2double(lock_utime)/1000000.0);
1580
if (my_b_printf(&log_file,
1581
"# Query_time: %s Lock_time: %s"
1582
" Rows_sent: %lu Rows_examined: %lu\n",
1583
query_time_buff, lock_time_buff,
1584
(ulong) thd->sent_row_count,
1585
(ulong) thd->examined_row_count) == (uint) -1)
1587
if (thd->db && strcmp(thd->db, db))
1588
{ // Database changed
1589
if (my_b_printf(&log_file,"use %s;\n",thd->db) == (uint) -1)
1593
if (thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt)
1595
end=stpcpy(end, ",last_insert_id=");
1596
end=int64_t10_to_str((int64_t)
1597
thd->first_successful_insert_id_in_prev_stmt_for_binlog,
1600
// Save value if we do an insert.
1601
if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
1604
end=stpcpy(end,",insert_id=");
1605
end=int64_t10_to_str((int64_t)
1606
thd->auto_inc_intervals_in_cur_stmt_for_binlog.minimum(),
1612
This info used to show up randomly, depending on whether the query
1613
checked the query start time or not. now we always write current
1614
timestamp to the slow log
1616
end= stpcpy(end, ",timestamp=");
1617
end= int10_to_str((long) current_time, end, 10);
1623
if (my_b_write(&log_file, (uchar*) "SET ", 4) ||
1624
my_b_write(&log_file, (uchar*) buff + 1, (uint) (end-buff)))
1629
end= strxmov(buff, "# administrator command: ", NullS);
1630
buff_len= (ulong) (end - buff);
1631
my_b_write(&log_file, (uchar*) buff, buff_len);
1633
if (my_b_write(&log_file, (uchar*) sql_text, sql_text_len) ||
1634
my_b_write(&log_file, (uchar*) ";\n",2) ||
1635
flush_io_cache(&log_file))
1643
sql_print_error(ER(ER_ERROR_ON_WRITE), name, error);
1647
(void) pthread_mutex_unlock(&LOCK_log);
1006
1654
The following should be using fn_format(); We just need to
2544
3200
If row-based binlogging, Insert_id, Rand and other kind of "setting
2545
3201
context" events are not needed.
2549
if (!session->current_stmt_binlog_row_based)
3205
if (!thd->current_stmt_binlog_row_based)
2551
if (session->stmt_depends_on_first_successful_insert_id_in_prev_stmt)
3207
if (thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt)
2553
Intvar_log_event e(session,(unsigned char) LAST_INSERT_ID_EVENT,
2554
session->first_successful_insert_id_in_prev_stmt_for_binlog);
3209
Intvar_log_event e(thd,(uchar) LAST_INSERT_ID_EVENT,
3210
thd->first_successful_insert_id_in_prev_stmt_for_binlog);
2555
3211
if (e.write(file))
2558
if (session->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
3214
if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
2561
3217
If the auto_increment was second in a table's index (possible with
2562
3218
MyISAM or BDB) (table->next_number_keypart != 0), such event is
2563
3219
in fact not necessary. We could avoid logging it.
2565
Intvar_log_event e(session, (unsigned char) INSERT_ID_EVENT,
2566
session->auto_inc_intervals_in_cur_stmt_for_binlog.
3221
Intvar_log_event e(thd, (uchar) INSERT_ID_EVENT,
3222
thd->auto_inc_intervals_in_cur_stmt_for_binlog.
2568
3224
if (e.write(file))
2571
if (session->rand_used)
2573
Rand_log_event e(session,session->rand_saved_seed1,session->rand_saved_seed2);
3229
Rand_log_event e(thd,thd->rand_saved_seed1,thd->rand_saved_seed2);
2574
3230
if (e.write(file))
2577
if (session->user_var_events.elements)
3233
if (thd->user_var_events.elements)
2579
for (uint32_t i= 0; i < session->user_var_events.elements; i++)
3235
for (uint i= 0; i < thd->user_var_events.elements; i++)
2581
3237
BINLOG_USER_VAR_EVENT *user_var_event;
2582
get_dynamic(&session->user_var_events,(unsigned char*) &user_var_event, i);
2583
User_var_log_event e(session, user_var_event->user_var_event->name.str,
3238
get_dynamic(&thd->user_var_events,(uchar*) &user_var_event, i);
3239
User_var_log_event e(thd, user_var_event->user_var_event->name.str,
2584
3240
user_var_event->user_var_event->name.length,
2585
3241
user_var_event->value,
2586
3242
user_var_event->length,
2634
3290
return logger.error_log_print(level, format, args);
2637
void DRIZZLE_BIN_LOG::rotate_and_purge(uint32_t flags)
3294
bool slow_log_print(THD *thd, const char *query, uint query_length,
3295
uint64_t current_utime)
3297
return logger.slow_log_print(thd, query, query_length, current_utime);
3301
bool LOGGER::log_command(THD *thd, enum enum_server_command command)
3304
Log command if we have at least one log event handler enabled and want
3305
to log this king of commands
3307
if (*general_log_handler_list && (what_to_log & (1L << (uint) command)))
3309
if (thd->options & OPTION_LOG_OFF)
3322
bool general_log_print(THD *thd, enum enum_server_command command,
3323
const char *format, ...)
3328
/* Print the message to the buffer if we want to log this king of commands */
3329
if (! logger.log_command(thd, command))
3332
va_start(args, format);
3333
error= logger.general_log_print(thd, command, format, args);
3339
bool general_log_write(THD *thd, enum enum_server_command command,
3340
const char *query, uint query_length)
3342
/* Write the message to the log if we want to log this king of commands */
3343
if (logger.log_command(thd, command))
3344
return logger.general_log_write(thd, command, query, query_length);
3349
void DRIZZLE_BIN_LOG::rotate_and_purge(uint flags)
2639
3351
if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED))
2640
3352
pthread_mutex_lock(&LOCK_log);
3116
3832
char err_renamed[FN_REFLEN], *end;
3117
3833
end= strmake(err_renamed,log_error_file,FN_REFLEN-4);
3118
my_stpcpy(end, "-old");
3119
pthread_mutex_lock(&LOCK_error_log);
3834
stpcpy(end, "-old");
3835
VOID(pthread_mutex_lock(&LOCK_error_log));
3120
3836
char err_temp[FN_REFLEN+4];
3122
3838
On Windows is necessary a temporary file for to rename
3123
3839
the current error file.
3125
strxmov(err_temp, err_renamed,"-tmp",NULL);
3841
strxmov(err_temp, err_renamed,"-tmp",NullS);
3126
3842
(void) my_delete(err_temp, MYF(0));
3127
3843
if (freopen(err_temp,"a+",stdout))
3131
unsigned char buf[IO_SIZE];
3133
if(freopen(err_temp,"a+",stderr)==NULL)
3849
freopen(err_temp,"a+",stderr);
3135
3850
(void) my_delete(err_renamed, MYF(0));
3136
3851
my_rename(log_error_file,err_renamed,MYF(0));
3137
if (freopen(log_error_file,"a+",stdout)==NULL)
3140
if(freopen(log_error_file,"a+",stderr)==NULL)
3852
if (freopen(log_error_file,"a+",stdout))
3853
freopen(log_error_file,"a+",stderr);
3143
3855
if ((fd = my_open(err_temp, O_RDONLY, MYF(0))) >= 0)