diff options
Diffstat (limited to 'sql/log.cc')
-rw-r--r-- | sql/log.cc | 119 |
1 files changed, 71 insertions, 48 deletions
diff --git a/sql/log.cc b/sql/log.cc index 86f8100be07..88352706318 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -4272,7 +4272,7 @@ bool use_trans_cache(const THD* thd, bool is_transactional) (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); return - ((thd->variables.binlog_format != BINLOG_FORMAT_STMT || + ((thd->is_current_stmt_binlog_format_row() || thd->variables.binlog_direct_non_trans_update) ? is_transactional : (is_transactional || !cache_mngr->trx_cache.empty())); } @@ -5447,70 +5447,93 @@ void sql_perror(const char *message) } +#ifdef __WIN__ +extern "C" my_bool reopen_fstreams(const char *filename, + FILE *outstream, FILE *errstream) +{ + int handle_fd; + int stream_fd; + HANDLE osfh; + + DBUG_ASSERT(filename && (outstream || errstream)); + + if ((osfh= CreateFile(filename, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE | + FILE_SHARE_DELETE, NULL, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, + NULL)) == INVALID_HANDLE_VALUE) + return TRUE; + + if ((handle_fd= _open_osfhandle((intptr_t)osfh, + _O_APPEND | _O_TEXT)) == -1) + { + CloseHandle(osfh); + return TRUE; + } + + if (outstream) + { + stream_fd= _fileno(outstream); + if (_dup2(handle_fd, stream_fd) < 0) + { + CloseHandle(osfh); + return TRUE; + } + } + + if (errstream) + { + stream_fd= _fileno(errstream); + if (_dup2(handle_fd, stream_fd) < 0) + { + CloseHandle(osfh); + return TRUE; + } + } + + _close(handle_fd); + return FALSE; +} +#else +extern "C" my_bool reopen_fstreams(const char *filename, + FILE *outstream, FILE *errstream) +{ + if (outstream && !freopen(filename, "a+", outstream)) + return TRUE; + + if (errstream && !freopen(filename, "a+", errstream)) + return TRUE; + + return FALSE; +} +#endif + + /* Unfortunately, there seems to be no good way to restore the original streams upon failure. */ static bool redirect_std_streams(const char *file) { - if (freopen(file, "a+", stdout) && freopen(file, "a+", stderr)) - { - setbuf(stderr, NULL); - return FALSE; - } + if (reopen_fstreams(file, stdout, stderr)) + return TRUE; - return TRUE; + setbuf(stderr, NULL); + return FALSE; } bool flush_error_log() { - bool result=0; + bool result= 0; if (opt_error_log) { - char err_renamed[FN_REFLEN], *end; - end= strmake(err_renamed,log_error_file,FN_REFLEN-5); - strmov(end, "-old"); mysql_mutex_lock(&LOCK_error_log); -#ifdef __WIN__ - char err_temp[FN_REFLEN+5]; - /* - On Windows is necessary a temporary file for to rename - the current error file. - */ - strxmov(err_temp, err_renamed,"-tmp",NullS); - my_delete(err_temp, MYF(0)); - if (freopen(err_temp,"a+",stdout)) - { - int fd; - size_t bytes; - uchar buf[IO_SIZE]; - - freopen(err_temp,"a+",stderr); - setbuf(stderr, NULL); - my_delete(err_renamed, MYF(0)); - my_rename(log_error_file, err_renamed, MYF(0)); - redirect_std_streams(log_error_file); - - if ((fd= my_open(err_temp, O_RDONLY, MYF(0))) >= 0) - { - while ((bytes= mysql_file_read(fd, buf, IO_SIZE, MYF(0))) && - bytes != MY_FILE_ERROR) - my_fwrite(stderr, buf, bytes, MYF(0)); - mysql_file_close(fd, MYF(0)); - } - my_delete(err_temp, MYF(0)); - } - else - result= 1; -#else - my_rename(log_error_file, err_renamed, MYF(0)); - if (redirect_std_streams(log_error_file)) - result= 1; -#endif + if (redirect_std_streams(log_error_file)) + result= 1; mysql_mutex_unlock(&LOCK_error_log); } - return result; + return result; } void MYSQL_BIN_LOG::signal_update() |