1700
1713
String log_query;
1701
1714
if (log_query.append(STRING_WITH_LEN("SAVEPOINT ")) ||
1702
log_query.append(thd->lex->ident.str, thd->lex->ident.length))
1715
log_query.append("`") ||
1716
log_query.append(thd->lex->ident.str, thd->lex->ident.length) ||
1717
log_query.append("`"))
1703
1718
DBUG_RETURN(1);
1704
1719
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
1705
1720
Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(),
1722
1737
String log_query;
1723
1738
if (log_query.append(STRING_WITH_LEN("ROLLBACK TO ")) ||
1724
log_query.append(thd->lex->ident.str, thd->lex->ident.length))
1739
log_query.append("`") ||
1740
log_query.append(thd->lex->ident.str, thd->lex->ident.length) ||
1741
log_query.append("`"))
1725
1742
DBUG_RETURN(1);
1726
1743
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
1727
1744
Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(),
1855
1872
length= (size_t) (end-start+1);
1857
if (!(dir_info = my_dir(buff,MYF(MY_DONT_SORT))))
1874
if ((DBUG_EVALUATE_IF("error_unique_log_filename", 1,
1875
!(dir_info = my_dir(buff,MYF(MY_DONT_SORT))))))
1858
1876
{ // This shouldn't happen
1859
1877
strmov(end,".1"); // use name+1
1862
1880
file_info= dir_info->dir_entry;
1863
1881
for (i=dir_info->number_off_files ; i-- ; file_info++)
1865
if (bcmp((uchar*) file_info->name, (uchar*) start, length) == 0 &&
1883
if (memcmp(file_info->name, start, length) == 0 &&
1866
1884
test_if_number(file_info->name+length, &number,0))
1868
1886
set_if_bigger(max_found,(ulong) number);
2580
2599
sync_purge_index_file() ||
2581
2600
DBUG_EVALUATE_IF("fault_injection_registering_index", 1, 0))
2603
TODO: although this was introduced to appease valgrind
2604
when injecting emulated faults using fault_injection_registering_index
2605
it may be good to consider what actually happens when
2606
open_purge_index_file succeeds but register or sync fails.
2608
Perhaps we might need the code below in MYSQL_LOG_BIN::cleanup
2609
for "real life" purposes as well?
2611
DBUG_EXECUTE_IF("fault_injection_registering_index", {
2612
if (my_b_inited(&purge_index_file))
2614
end_io_cache(&purge_index_file);
2615
my_close(purge_index_file.file, MYF(0));
2583
2619
sql_print_error("MSYQL_BIN_LOG::open failed to sync the index file.");
2584
2620
DBUG_RETURN(1);
2586
DBUG_EXECUTE_IF("crash_create_non_critical_before_update_index", abort(););
2622
DBUG_EXECUTE_IF("crash_create_non_critical_before_update_index", DBUG_SUICIDE(););
2589
2625
write_error= 0;
2966
2996
thread. If the transaction involved MyISAM tables, it should go
2967
2997
into binlog even on rollback.
2969
VOID(pthread_mutex_lock(&LOCK_thread_count));
2999
pthread_mutex_lock(&LOCK_thread_count);
3002
We need to get both locks to be sure that no one is trying to
3003
write to the index log file.
3005
pthread_mutex_lock(&LOCK_log);
3006
pthread_mutex_lock(&LOCK_index);
2971
3008
/* Save variables so that we can reopen the log */
2972
3009
save_name=name;
3049
3086
if (!thd->slave_thread)
3050
3087
need_start_event=1;
3051
3088
if (!open_index_file(index_file_name, 0, FALSE))
3052
open(save_name, log_type, 0, io_cache_type, no_auto_events, max_size, 0, FALSE);
3089
if ((error= open(save_name, log_type, 0, io_cache_type, no_auto_events, max_size, 0, FALSE)))
3053
3091
my_free((uchar*) save_name, MYF(0));
3151
3189
/* Store where we are in the new file for the execution thread */
3152
3190
flush_relay_log_info(rli);
3154
DBUG_EXECUTE_IF("crash_before_purge_logs", abort(););
3192
DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_SUICIDE(););
3156
3194
pthread_mutex_lock(&rli->log_space_lock);
3157
3195
rli->relay_log.purge_logs(to_purge_if_included, included,
3731
3775
@param need_lock Set to 1 if caller has not locked LOCK_log
3734
3781
The new file name is stored last in the index file
3737
void MYSQL_BIN_LOG::new_file_impl(bool need_lock)
3784
int MYSQL_BIN_LOG::new_file_impl(bool need_lock)
3739
char new_name[FN_REFLEN], *new_name_ptr, *old_name;
3786
int error= 0, close_on_error= FALSE;
3787
char new_name[FN_REFLEN], *new_name_ptr, *old_name, *file_to_open;
3741
3789
DBUG_ENTER("MYSQL_BIN_LOG::new_file_impl");
3742
3790
if (!is_open())
3744
3792
DBUG_PRINT("info",("log is closed"));
3795
3843
Rotate_log_event r(new_name+dirname_length(new_name),
3796
3844
0, LOG_EVENT_OFFSET, is_relay_log ? Rotate_log_event::RELAY_LOG : 0);
3845
if(DBUG_EVALUATE_IF("fault_injection_new_file_rotate_event", (error=close_on_error=TRUE), FALSE) ||
3846
(error= r.write(&log_file)))
3848
DBUG_EXECUTE_IF("fault_injection_new_file_rotate_event", errno=2;);
3849
close_on_error= TRUE;
3850
my_printf_error(ER_ERROR_ON_WRITE, ER(ER_CANT_OPEN_FILE), MYF(ME_FATALERROR), name, errno);
3798
3853
bytes_written += r.data_written;
3824
3879
/* reopen index binlog file, BUG#34582 */
3825
if (!open_index_file(index_file_name, 0, FALSE))
3826
open(old_name, log_type, new_name_ptr,
3827
io_cache_type, no_auto_events, max_size, 1, FALSE);
3880
file_to_open= index_file_name;
3881
error= open_index_file(index_file_name, 0, FALSE);
3884
/* reopen the binary log file. */
3885
file_to_open= new_name_ptr;
3886
error= open(old_name, log_type, new_name_ptr, io_cache_type,
3887
no_auto_events, max_size, 1, FALSE);
3890
/* handle reopening errors */
3893
my_printf_error(ER_CANT_OPEN_FILE, ER(ER_CANT_OPEN_FILE),
3894
MYF(ME_FATALERROR), file_to_open, error);
3895
close_on_error= TRUE;
3828
3898
my_free(old_name,MYF(0));
3902
if (error && close_on_error /* rotate or reopen failed */)
3905
Close whatever was left opened.
3907
We are keeping the behavior as it exists today, ie,
3908
we disable logging and move on (see: BUG#51014).
3910
TODO: as part of WL#1790 consider other approaches:
3911
- kill mysql (safety);
3912
- try multiple locations for opening a log file;
3913
- switch server to protected/readonly mode
3916
close(LOG_CLOSE_INDEX);
3917
sql_print_error("Could not open %s for logging (error %d). "
3918
"Turning logging off for the whole duration "
3919
"of the MySQL server process. To turn it on "
3920
"again: fix the cause, shutdown the MySQL "
3921
"server and restart it.",
3922
new_name_ptr, errno);
3832
3926
pthread_mutex_unlock(&LOCK_log);
3833
3927
pthread_mutex_unlock(&LOCK_index);
3855
3949
bytes_written+= ev->data_written;
3856
3950
DBUG_PRINT("info",("max_size: %lu",max_size));
3857
3951
if ((uint) my_b_append_tell(&log_file) > max_size)
3858
new_file_without_locking();
3952
error= new_file_without_locking();
3861
3954
pthread_mutex_unlock(&LOCK_log);
3862
3955
signal_update(); // Safe as we don't call close
4524
4629
if ((flags & RP_FORCE_ROTATE) ||
4525
4630
(my_b_tell(&log_file) >= (my_off_t) max_size))
4527
new_file_without_locking();
4632
if ((error= new_file_without_locking()))
4634
Be conservative... There are possible lost events (eg,
4635
failing to log the Execute_load_query_log_event
4636
on a LOAD DATA while using a non-transactional
4639
We give it a shot and try to write an incident event anyway
4642
if (!write_incident(current_thd, FALSE))
4528
4645
#ifdef HAVE_REPLICATION
4529
4646
check_purge= true;
4532
4649
if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED))
4533
4650
pthread_mutex_unlock(&LOCK_log);
4535
4651
#ifdef HAVE_REPLICATION
4537
4653
NOTE: Run purge_logs wo/ holding LOCK_log
4538
4654
as it otherwise will deadlock in ndbcluster_binlog_index_purge_file
4540
if (check_purge && expire_logs_days)
4656
if (!error && check_purge && expire_logs_days)
4542
4658
time_t purge_time= my_time(0) - expire_logs_days*24*60*60;
4543
4659
if (purge_time >= 0)
4544
4660
purge_logs_before_date(purge_time);
4549
4666
uint MYSQL_BIN_LOG::next_file_id()
5176
Change the file associated with two output streams. Used to
5177
redirect stdout and stderr to a file. The streams are reopened
5178
only for appending (writing at end of file).
5180
extern "C" my_bool reopen_fstreams(const char *filename,
5181
FILE *outstream, FILE *errstream)
5183
if (outstream && !my_freopen(filename, "a", outstream))
5186
if (errstream && !my_freopen(filename, "a", errstream))
5189
/* The error stream must be unbuffered. */
5191
setbuf(errstream, NULL);
5198
Unfortunately, there seems to be no good way
5199
to restore the original streams upon failure.
5201
static bool redirect_std_streams(const char *file)
5203
if (reopen_fstreams(file, stdout, stderr))
5206
setbuf(stderr, NULL);
5053
5211
bool flush_error_log()
5056
5214
if (opt_error_log)
5058
char err_renamed[FN_REFLEN], *end;
5059
end= strmake(err_renamed,log_error_file,FN_REFLEN-5);
5060
strmov(end, "-old");
5061
5216
VOID(pthread_mutex_lock(&LOCK_error_log));
5063
char err_temp[FN_REFLEN+5];
5065
On Windows is necessary a temporary file for to rename
5066
the current error file.
5068
strxmov(err_temp, err_renamed,"-tmp",NullS);
5069
(void) my_delete(err_temp, MYF(0));
5070
if (freopen(err_temp,"a+",stdout))
5076
freopen(err_temp,"a+",stderr);
5077
setbuf(stderr, NULL);
5078
(void) my_delete(err_renamed, MYF(0));
5079
my_rename(log_error_file,err_renamed,MYF(0));
5080
if (freopen(log_error_file,"a+",stdout))
5082
freopen(log_error_file,"a+",stderr);
5083
setbuf(stderr, NULL);
5086
if ((fd = my_open(err_temp, O_RDONLY, MYF(0))) >= 0)
5088
while ((bytes= my_read(fd, buf, IO_SIZE, MYF(0))) &&
5089
bytes != MY_FILE_ERROR)
5090
my_fwrite(stderr, buf, bytes, MYF(0));
5091
my_close(fd, MYF(0));
5093
(void) my_delete(err_temp, MYF(0));
5098
my_rename(log_error_file,err_renamed,MYF(0));
5099
if (freopen(log_error_file,"a+",stdout))
5102
reopen= freopen(log_error_file,"a+",stderr);
5103
setbuf(stderr, NULL);
5217
if (redirect_std_streams(log_error_file))
5108
5219
VOID(pthread_mutex_unlock(&LOCK_error_log));
5113
5224
void MYSQL_BIN_LOG::signal_update()
5153
5264
#endif /* __NT__ */
5157
Prints a printf style message to the error log and, under NT, to the
5160
This function prints the message into a buffer and then sends that buffer
5161
to other functions to write that message to other logging sources.
5163
@param event_type Type of event to write (Error, Warning, or Info)
5164
@param format Printf style format of message
5165
@param args va_list list of arguments for the message
5168
The function always returns 0. The return value is present in the
5169
signature to be compatible with other logging routines, which could
5170
return an error (e.g. logging to the log tables)
5173
5267
#ifndef EMBEDDED_LIBRARY
5174
static void print_buffer_to_file(enum loglevel level, const char *buffer)
5268
static void print_buffer_to_file(enum loglevel level, const char *buffer,
5177
5272
struct tm tm_tmp;
5202
5297
DBUG_VOID_RETURN;
5301
Prints a printf style message to the error log and, under NT, to the
5304
This function prints the message into a buffer and then sends that buffer
5305
to other functions to write that message to other logging sources.
5307
@param level The level of the msg significance
5308
@param format Printf style format of message
5309
@param args va_list list of arguments for the message
5312
The function always returns 0. The return value is present in the
5313
signature to be compatible with other logging routines, which could
5314
return an error (e.g. logging to the log tables)
5206
5316
int vprint_msg_to_log(enum loglevel level, const char *format, va_list args)
5208
5318
char buff[1024];
5210
5320
DBUG_ENTER("vprint_msg_to_log");
5212
5322
length= my_vsnprintf(buff, sizeof(buff), format, args);
5213
print_buffer_to_file(level, buff);
5323
print_buffer_to_file(level, buff, length);
5216
5326
print_buffer_to_nt_eventlog(level, buff, length, sizeof(buff));
5876
5987
DBUG_RETURN(!binlog_end_trans(thd, trx_data, &xle, TRUE));
5879
void TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid)
5990
int TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid)
5992
DBUG_ENTER("TC_LOG_BINLOG::unlog");
5881
5993
pthread_mutex_lock(&LOCK_prep_xids);
5882
5994
DBUG_ASSERT(prepared_xids > 0);
5883
5995
if (--prepared_xids == 0) {