1 /* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15
16 #ifndef LOG_H
17 #define LOG_H
18
19 #include "unireg.h" // REQUIRED: for other includes
20 #include "handler.h" /* my_xid */
21
22 class Relay_log_info;
23
24 class Format_description_log_event;
25
26 bool trans_has_updated_trans_table(const THD* thd);
27 bool stmt_has_updated_trans_table(Ha_trx_info* ha_list);
28 bool use_trans_cache(const THD* thd, bool is_transactional);
29 bool ending_trans(THD* thd, const bool all);
30 bool ending_single_stmt_trans(THD* thd, const bool all);
31 bool trans_has_updated_non_trans_table(const THD* thd);
32 bool stmt_has_updated_non_trans_table(const THD* thd);
33
34 /*
35 Transaction Coordinator log - a base abstract class
36 for two different implementations
37 */
38 class TC_LOG
39 {
40 public:
41 int using_heuristic_recover();
TC_LOG()42 TC_LOG() {}
~TC_LOG()43 virtual ~TC_LOG() {}
44
45 virtual int open(const char *opt_name)=0;
46 virtual void close()=0;
47 virtual int log_xid(THD *thd, my_xid xid)=0;
48 virtual int unlog(ulong cookie, my_xid xid)=0;
49 };
50
51 class TC_LOG_DUMMY: public TC_LOG // use it to disable the logging
52 {
53 public:
TC_LOG_DUMMY()54 TC_LOG_DUMMY() {}
open(const char * opt_name)55 int open(const char *opt_name) { return 0; }
close()56 void close() { }
log_xid(THD * thd,my_xid xid)57 int log_xid(THD *thd, my_xid xid) { return 1; }
unlog(ulong cookie,my_xid xid)58 int unlog(ulong cookie, my_xid xid) { return 0; }
59 };
60
61 #ifdef HAVE_MMAP
62 class TC_LOG_MMAP: public TC_LOG
63 {
64 public: // only to keep Sun Forte on sol9x86 happy
65 typedef enum {
66 PS_POOL, // page is in pool
67 PS_ERROR, // last sync failed
68 PS_DIRTY // new xids added since last sync
69 } PAGE_STATE;
70
71 private:
72 typedef struct st_page {
73 struct st_page *next; // page a linked in a fifo queue
74 my_xid *start, *end; // usable area of a page
75 my_xid *ptr; // next xid will be written here
76 int size, free; // max and current number of free xid slots on the page
77 int waiters; // number of waiters on condition
78 PAGE_STATE state; // see above
79 mysql_mutex_t lock; // to access page data or control structure
80 mysql_cond_t cond; // to wait for a sync
81 } PAGE;
82
83 char logname[FN_REFLEN];
84 File fd;
85 my_off_t file_length;
86 uint npages, inited;
87 uchar *data;
88 struct st_page *pages, *syncing, *active, *pool, *pool_last;
89 /*
90 note that, e.g. LOCK_active is only used to protect
91 'active' pointer, to protect the content of the active page
92 one has to use active->lock.
93 Same for LOCK_pool and LOCK_sync
94 */
95 mysql_mutex_t LOCK_active, LOCK_pool, LOCK_sync;
96 mysql_cond_t COND_pool, COND_active;
97
98 public:
TC_LOG_MMAP()99 TC_LOG_MMAP(): inited(0) {}
100 int open(const char *opt_name);
101 void close();
102 int log_xid(THD *thd, my_xid xid);
103 int unlog(ulong cookie, my_xid xid);
104 int recover();
105
106 private:
107 void get_active_from_pool();
108 int sync();
109 int overflow();
110 };
111 #else
112 #define TC_LOG_MMAP TC_LOG_DUMMY
113 #endif
114
115 extern TC_LOG *tc_log;
116 extern TC_LOG_MMAP tc_log_mmap;
117 extern TC_LOG_DUMMY tc_log_dummy;
118
119 /* log info errors */
120 #define LOG_INFO_EOF -1
121 #define LOG_INFO_IO -2
122 #define LOG_INFO_INVALID -3
123 #define LOG_INFO_SEEK -4
124 #define LOG_INFO_MEM -6
125 #define LOG_INFO_FATAL -7
126 #define LOG_INFO_IN_USE -8
127 #define LOG_INFO_EMFILE -9
128
129
130 /* bitmap to SQL_LOG::close() */
131 #define LOG_CLOSE_INDEX 1
132 #define LOG_CLOSE_TO_BE_OPENED 2
133 #define LOG_CLOSE_STOP_EVENT 4
134
135 /*
136 Maximum unique log filename extension.
137 Note: setting to 0x7FFFFFFF due to atol windows
138 overflow/truncate.
139 */
140 #define MAX_LOG_UNIQUE_FN_EXT 0x7FFFFFFF
141
142 /*
143 Number of warnings that will be printed to error log
144 before extension number is exhausted.
145 */
146 #define LOG_WARN_UNIQUE_FN_EXT_LEFT 1000
147
148 class Relay_log_info;
149
150 #ifdef HAVE_PSI_INTERFACE
151 extern PSI_mutex_key key_LOG_INFO_lock;
152 #endif
153
154 /*
155 Note that we destroy the lock mutex in the desctructor here.
156 This means that object instances cannot be destroyed/go out of scope,
157 until we have reset thd->current_linfo to NULL;
158 */
159 typedef struct st_log_info
160 {
161 char log_file_name[FN_REFLEN];
162 my_off_t index_file_offset, index_file_start_offset;
163 my_off_t pos;
164 bool fatal; // if the purge happens to give us a negative offset
165 mysql_mutex_t lock;
st_log_infost_log_info166 st_log_info()
167 : index_file_offset(0), index_file_start_offset(0),
168 pos(0), fatal(0)
169 {
170 log_file_name[0] = '\0';
171 mysql_mutex_init(key_LOG_INFO_lock, &lock, MY_MUTEX_INIT_FAST);
172 }
~st_log_infost_log_info173 ~st_log_info() { mysql_mutex_destroy(&lock);}
174 } LOG_INFO;
175
176 /*
177 Currently we have only 3 kinds of logging functions: old-fashioned
178 logs, stdout and csv logging routines.
179 */
180 #define MAX_LOG_HANDLERS_NUM 3
181
182 /* log event handler flags */
183 #define LOG_NONE 1
184 #define LOG_FILE 2
185 #define LOG_TABLE 4
186
187 class Log_event;
188 class Rows_log_event;
189
190 enum enum_log_type { LOG_UNKNOWN, LOG_NORMAL, LOG_BIN };
191 enum enum_log_state { LOG_OPENED, LOG_CLOSED, LOG_TO_BE_OPENED };
192
193 /*
194 TODO use mmap instead of IO_CACHE for binlog
195 (mmap+fsync is two times faster than write+fsync)
196 */
197
198 class MYSQL_LOG
199 {
200 public:
201 MYSQL_LOG();
202 void init_pthread_objects();
203 void cleanup();
204 bool open(
205 #ifdef HAVE_PSI_INTERFACE
206 PSI_file_key log_file_key,
207 #endif
208 const char *log_name,
209 enum_log_type log_type,
210 const char *new_name,
211 enum cache_type io_cache_type_arg);
212 bool init_and_set_log_file_name(const char *log_name,
213 const char *new_name,
214 enum_log_type log_type_arg,
215 enum cache_type io_cache_type_arg);
216 void init(enum_log_type log_type_arg,
217 enum cache_type io_cache_type_arg);
218 void close(uint exiting);
is_open()219 inline bool is_open() { return log_state != LOG_CLOSED; }
220 const char *generate_name(const char *log_name, const char *suffix,
221 bool strip_ext, char *buff);
222 int generate_new_name(char *new_name, const char *log_name);
223 protected:
224 /* LOCK_log is inited by init_pthread_objects() */
225 mysql_mutex_t LOCK_log;
226 char *name;
227 char log_file_name[FN_REFLEN];
228 char time_buff[20], db[NAME_LEN + 1];
229 bool write_error, inited;
230 IO_CACHE log_file;
231 enum_log_type log_type;
232 volatile enum_log_state log_state;
233 enum cache_type io_cache_type;
234 friend class Log_event;
235 #ifdef HAVE_PSI_INTERFACE
236 /** Instrumentation key to use for file io in @c log_file */
237 PSI_file_key m_log_file_key;
238 #endif
239 };
240
241 class MYSQL_QUERY_LOG: public MYSQL_LOG
242 {
243 public:
MYSQL_QUERY_LOG()244 MYSQL_QUERY_LOG() : last_time(0) {}
245 void reopen_file();
246 bool write(time_t event_time, const char *user_host,
247 uint user_host_len, int thread_id,
248 const char *command_type, uint command_type_len,
249 const char *sql_text, uint sql_text_len);
250 bool write(THD *thd, time_t current_time, time_t query_start_arg,
251 const char *user_host, uint user_host_len,
252 ulonglong query_utime, ulonglong lock_utime, bool is_command,
253 const char *sql_text, uint sql_text_len);
open_slow_log(const char * log_name)254 bool open_slow_log(const char *log_name)
255 {
256 char buf[FN_REFLEN];
257 return open(
258 #ifdef HAVE_PSI_INTERFACE
259 key_file_slow_log,
260 #endif
261 generate_name(log_name, "-slow.log", 0, buf),
262 LOG_NORMAL, 0, WRITE_CACHE);
263 }
open_query_log(const char * log_name)264 bool open_query_log(const char *log_name)
265 {
266 char buf[FN_REFLEN];
267 return open(
268 #ifdef HAVE_PSI_INTERFACE
269 key_file_query_log,
270 #endif
271 generate_name(log_name, ".log", 0, buf),
272 LOG_NORMAL, 0, WRITE_CACHE);
273 }
274
275 private:
276 time_t last_time;
277 };
278
279 class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
280 {
281 private:
282 #ifdef HAVE_PSI_INTERFACE
283 /** The instrumentation key to use for @ LOCK_index. */
284 PSI_mutex_key m_key_LOCK_index;
285 /** The instrumentation key to use for @ update_cond. */
286 PSI_cond_key m_key_update_cond;
287 /** The instrumentation key to use for opening the log file. */
288 PSI_file_key m_key_file_log;
289 /** The instrumentation key to use for opening the log index file. */
290 PSI_file_key m_key_file_log_index;
291 #endif
292 /* LOCK_log and LOCK_index are inited by init_pthread_objects() */
293 mysql_mutex_t LOCK_index;
294 mysql_mutex_t LOCK_prep_xids;
295 mysql_cond_t COND_prep_xids;
296 mysql_cond_t update_cond;
297 ulonglong bytes_written;
298 IO_CACHE index_file;
299 char index_file_name[FN_REFLEN];
300 /*
301 purge_file is a temp file used in purge_logs so that the index file
302 can be updated before deleting files from disk, yielding better crash
303 recovery. It is created on demand the first time purge_logs is called
304 and then reused for subsequent calls. It is cleaned up in cleanup().
305 */
306 IO_CACHE purge_index_file;
307 char purge_index_file_name[FN_REFLEN];
308 /*
309 The max size before rotation (usable only if log_type == LOG_BIN: binary
310 logs and relay logs).
311 For a binlog, max_size should be max_binlog_size.
312 For a relay log, it should be max_relay_log_size if this is non-zero,
313 max_binlog_size otherwise.
314 max_size is set in init(), and dynamically changed (when one does SET
315 GLOBAL MAX_BINLOG_SIZE|MAX_RELAY_LOG_SIZE) by fix_max_binlog_size and
316 fix_max_relay_log_size).
317 */
318 ulong max_size;
319 long prepared_xids; /* for tc log - number of xids to remember */
320 // current file sequence number for load data infile binary logging
321 uint file_id;
322 uint open_count; // For replication
323 int readers_count;
324 bool need_start_event;
325 /*
326 no_auto_events means we don't want any of these automatic events :
327 Start/Rotate/Stop. That is, in 4.x when we rotate a relay log, we don't
328 want a Rotate_log event to be written to the relay log. When we start a
329 relay log etc. So in 4.x this is 1 for relay logs, 0 for binlogs.
330 In 5.0 it's 0 for relay logs too!
331 */
332 bool no_auto_events;
333
334 /* pointer to the sync period variable, for binlog this will be
335 sync_binlog_period, for relay log this will be
336 sync_relay_log_period
337 */
338 uint *sync_period_ptr;
339 uint sync_counter;
340
get_sync_period()341 inline uint get_sync_period()
342 {
343 return *sync_period_ptr;
344 }
345
346 int write_to_file(IO_CACHE *cache);
347 /*
348 This is used to start writing to a new log file. The difference from
349 new_file() is locking. new_file_without_locking() does not acquire
350 LOCK_log.
351 */
352 int new_file_without_locking();
353 int new_file_impl(bool need_lock);
354
355 public:
356 using MYSQL_LOG::generate_name;
357 using MYSQL_LOG::is_open;
358
359 /* This is relay log */
360 bool is_relay_log;
361 ulong signal_cnt; // update of the counter is checked by heartbeat
362 /*
363 These describe the log's format. This is used only for relay logs.
364 _for_exec is used by the SQL thread, _for_queue by the I/O thread. It's
365 necessary to have 2 distinct objects, because the I/O thread may be reading
366 events in a different format from what the SQL thread is reading (consider
367 the case of a master which has been upgraded from 5.0 to 5.1 without doing
368 RESET MASTER, or from 4.x to 5.0).
369 */
370 Format_description_log_event *description_event_for_exec,
371 *description_event_for_queue;
372
373 MYSQL_BIN_LOG(uint *sync_period);
374 /*
375 note that there's no destructor ~MYSQL_BIN_LOG() !
376 The reason is that we don't want it to be automatically called
377 on exit() - but only during the correct shutdown process
378 */
379
380 #ifdef HAVE_PSI_INTERFACE
set_psi_keys(PSI_mutex_key key_LOCK_index,PSI_cond_key key_update_cond,PSI_file_key key_file_log,PSI_file_key key_file_log_index)381 void set_psi_keys(PSI_mutex_key key_LOCK_index,
382 PSI_cond_key key_update_cond,
383 PSI_file_key key_file_log,
384 PSI_file_key key_file_log_index)
385 {
386 m_key_LOCK_index= key_LOCK_index;
387 m_key_update_cond= key_update_cond;
388 m_key_file_log= key_file_log;
389 m_key_file_log_index= key_file_log_index;
390 }
391 #endif
392
393 int open(const char *opt_name);
394 void close();
395 int log_xid(THD *thd, my_xid xid);
396 int unlog(ulong cookie, my_xid xid);
397 int recover(IO_CACHE *log, Format_description_log_event *fdle);
398 #if !defined(MYSQL_CLIENT)
399
400 int flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event,
401 bool is_transactional);
402 int remove_pending_rows_event(THD *thd, bool is_transactional);
403
404 #endif /* !defined(MYSQL_CLIENT) */
reset_bytes_written()405 void reset_bytes_written()
406 {
407 bytes_written = 0;
408 }
harvest_bytes_written(ulonglong * counter)409 void harvest_bytes_written(ulonglong* counter)
410 {
411 #ifndef DBUG_OFF
412 char buf1[22],buf2[22];
413 #endif
414 DBUG_ENTER("harvest_bytes_written");
415 (*counter)+=bytes_written;
416 DBUG_PRINT("info",("counter: %s bytes_written: %s", llstr(*counter,buf1),
417 llstr(bytes_written,buf2)));
418 bytes_written=0;
419 DBUG_VOID_RETURN;
420 }
421 void set_max_size(ulong max_size_arg);
422 void signal_update();
423 void wait_for_update_relay_log(THD* thd);
424 int wait_for_update_bin_log(THD* thd, const struct timespec * timeout);
set_need_start_event()425 void set_need_start_event() { need_start_event = 1; }
426 void init(bool no_auto_events_arg, ulong max_size);
427 void init_pthread_objects();
428 void cleanup();
429 bool open(const char *log_name,
430 enum_log_type log_type,
431 const char *new_name,
432 enum cache_type io_cache_type_arg,
433 bool no_auto_events_arg, ulong max_size,
434 bool null_created,
435 bool need_mutex);
436 bool open_index_file(const char *index_file_name_arg,
437 const char *log_name, bool need_mutex);
438 /* Use this to start writing a new log file */
439 int new_file();
440
441 bool write(Log_event* event_info); // binary log write
442 bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event, bool incident);
443 bool write_incident(THD *thd, bool lock);
444
445 int write_cache(IO_CACHE *cache, bool lock_log, bool flush_and_sync);
446 void set_write_error(THD *thd, bool is_transactional);
447 bool check_write_error(THD *thd);
448
449 void start_union_events(THD *thd, query_id_t query_id_param);
450 void stop_union_events(THD *thd);
451 bool is_query_in_union(THD *thd, query_id_t query_id_param);
452
453 /*
454 v stands for vector
455 invoked as appendv(buf1,len1,buf2,len2,...,bufn,lenn,0)
456 */
457 bool appendv(const char* buf,uint len,...);
458 bool append(Log_event* ev);
459
460 void make_log_name(char* buf, const char* log_ident);
461 bool is_active(const char* log_file_name);
462 int update_log_index(LOG_INFO* linfo, bool need_update_threads);
463 int rotate(bool force_rotate, bool* check_purge);
464 void purge();
465 int rotate_and_purge(bool force_rotate);
466 /**
467 Flush binlog cache and synchronize to disk.
468
469 This function flushes events in binlog cache to binary log file,
470 it will do synchronizing according to the setting of system
471 variable 'sync_binlog'. If file is synchronized, @c synced will
472 be set to 1, otherwise 0.
473
474 @param[out] synced if not NULL, set to 1 if file is synchronized, otherwise 0
475
476 @retval 0 Success
477 @retval other Failure
478 */
479 bool flush_and_sync(bool *synced);
480 int purge_logs(const char *to_log, bool included,
481 bool need_mutex, bool need_update_threads,
482 ulonglong *decrease_log_space);
483 int purge_logs_before_date(time_t purge_time);
484 int purge_first_log(Relay_log_info* rli, bool included);
485 int set_purge_index_file_name(const char *base_file_name);
486 int open_purge_index_file(bool destroy);
487 bool is_inited_purge_index_file();
488 int close_purge_index_file();
489 int clean_purge_index_file();
490 int sync_purge_index_file();
491 int register_purge_index_entry(const char* entry);
492 int register_create_index_entry(const char* entry);
493 int purge_index_entry(THD *thd, ulonglong *decrease_log_space,
494 bool need_mutex);
495 bool reset_logs(THD* thd);
496 void close(uint exiting);
497
498 // iterating through the log index file
499 int find_log_pos(LOG_INFO* linfo, const char* log_name,
500 bool need_mutex);
501 int find_next_log(LOG_INFO* linfo, bool need_mutex);
502 int get_current_log(LOG_INFO* linfo);
503 int raw_get_current_log(LOG_INFO* linfo);
504 uint next_file_id();
get_index_fname()505 inline char* get_index_fname() { return index_file_name;}
get_log_fname()506 inline char* get_log_fname() { return log_file_name; }
get_name()507 inline char* get_name() { return name; }
get_log_lock()508 inline mysql_mutex_t* get_log_lock() { return &LOCK_log; }
get_log_cond()509 inline mysql_cond_t* get_log_cond() { return &update_cond; }
get_log_file()510 inline IO_CACHE* get_log_file() { return &log_file; }
511
lock_index()512 inline void lock_index() { mysql_mutex_lock(&LOCK_index);}
unlock_index()513 inline void unlock_index() { mysql_mutex_unlock(&LOCK_index);}
get_index_file()514 inline IO_CACHE *get_index_file() { return &index_file;}
get_open_count()515 inline uint32 get_open_count() { return open_count; }
516 };
517
518 class Log_event_handler
519 {
520 public:
Log_event_handler()521 Log_event_handler() {}
522 virtual bool init()= 0;
523 virtual void cleanup()= 0;
524
525 virtual bool log_slow(THD *thd, time_t current_time,
526 time_t query_start_arg, const char *user_host,
527 uint user_host_len, ulonglong query_utime,
528 ulonglong lock_utime, bool is_command,
529 const char *sql_text, uint sql_text_len)= 0;
530 virtual bool log_error(enum loglevel level, const char *format,
531 va_list args)= 0;
532 virtual bool log_general(THD *thd, time_t event_time, const char *user_host,
533 uint user_host_len, int thread_id,
534 const char *command_type, uint command_type_len,
535 const char *sql_text, uint sql_text_len,
536 CHARSET_INFO *client_cs)= 0;
~Log_event_handler()537 virtual ~Log_event_handler() {}
538 };
539
540
541 int check_if_log_table(size_t db_len, const char *db, size_t table_name_len,
542 const char *table_name, bool check_if_opened);
543
544 class Log_to_csv_event_handler: public Log_event_handler
545 {
546 friend class LOGGER;
547
548 public:
549 Log_to_csv_event_handler();
550 ~Log_to_csv_event_handler();
551 virtual bool init();
552 virtual void cleanup();
553
554 virtual bool log_slow(THD *thd, time_t current_time,
555 time_t query_start_arg, const char *user_host,
556 uint user_host_len, ulonglong query_utime,
557 ulonglong lock_utime, bool is_command,
558 const char *sql_text, uint sql_text_len);
559 virtual bool log_error(enum loglevel level, const char *format,
560 va_list args);
561 virtual bool log_general(THD *thd, time_t event_time, const char *user_host,
562 uint user_host_len, int thread_id,
563 const char *command_type, uint command_type_len,
564 const char *sql_text, uint sql_text_len,
565 CHARSET_INFO *client_cs);
566
567 int activate_log(THD *thd, uint log_type);
568 };
569
570
571 /* type of the log table */
572 #define QUERY_LOG_SLOW 1
573 #define QUERY_LOG_GENERAL 2
574
575 class Log_to_file_event_handler: public Log_event_handler
576 {
577 MYSQL_QUERY_LOG mysql_log;
578 MYSQL_QUERY_LOG mysql_slow_log;
579 bool is_initialized;
580 public:
Log_to_file_event_handler()581 Log_to_file_event_handler(): is_initialized(FALSE)
582 {}
583 virtual bool init();
584 virtual void cleanup();
585
586 virtual bool log_slow(THD *thd, time_t current_time,
587 time_t query_start_arg, const char *user_host,
588 uint user_host_len, ulonglong query_utime,
589 ulonglong lock_utime, bool is_command,
590 const char *sql_text, uint sql_text_len);
591 virtual bool log_error(enum loglevel level, const char *format,
592 va_list args);
593 virtual bool log_general(THD *thd, time_t event_time, const char *user_host,
594 uint user_host_len, int thread_id,
595 const char *command_type, uint command_type_len,
596 const char *sql_text, uint sql_text_len,
597 CHARSET_INFO *client_cs);
598 void flush();
599 void init_pthread_objects();
get_mysql_slow_log()600 MYSQL_QUERY_LOG *get_mysql_slow_log() { return &mysql_slow_log; }
get_mysql_log()601 MYSQL_QUERY_LOG *get_mysql_log() { return &mysql_log; }
602 };
603
604
605 /* Class which manages slow, general and error log event handlers */
606 class LOGGER
607 {
608 mysql_rwlock_t LOCK_logger;
609 /* flag to check whether logger mutex is initialized */
610 uint inited;
611
612 /* available log handlers */
613 Log_to_csv_event_handler *table_log_handler;
614 Log_to_file_event_handler *file_log_handler;
615
616 /* NULL-terminated arrays of log handlers */
617 Log_event_handler *error_log_handler_list[MAX_LOG_HANDLERS_NUM + 1];
618 Log_event_handler *slow_log_handler_list[MAX_LOG_HANDLERS_NUM + 1];
619 Log_event_handler *general_log_handler_list[MAX_LOG_HANDLERS_NUM + 1];
620
621 public:
622
623 bool is_log_tables_initialized;
624
LOGGER()625 LOGGER() : inited(0), table_log_handler(NULL),
626 file_log_handler(NULL), is_log_tables_initialized(FALSE)
627 {}
lock_shared()628 void lock_shared() { mysql_rwlock_rdlock(&LOCK_logger); }
lock_exclusive()629 void lock_exclusive() { mysql_rwlock_wrlock(&LOCK_logger); }
unlock()630 void unlock() { mysql_rwlock_unlock(&LOCK_logger); }
631 bool is_log_table_enabled(uint log_table_type);
632 bool log_command(THD *thd, enum enum_server_command command);
633
634 /*
635 We want to initialize all log mutexes as soon as possible,
636 but we cannot do it in constructor, as safe_mutex relies on
637 initialization, performed by MY_INIT(). This why this is done in
638 this function.
639 */
640 void init_base();
641 void init_log_tables();
642 bool flush_logs(THD *thd);
643 bool flush_slow_log();
644 bool flush_general_log();
645 /* Perform basic logger cleanup. this will leave e.g. error log open. */
646 void cleanup_base();
647 /* Free memory. Nothing could be logged after this function is called */
648 void cleanup_end();
649 bool error_log_print(enum loglevel level, const char *format,
650 va_list args);
651 bool slow_log_print(THD *thd, const char *query, uint query_length,
652 ulonglong current_utime);
653 bool general_log_print(THD *thd,enum enum_server_command command,
654 const char *format, va_list args);
655 bool general_log_write(THD *thd, enum enum_server_command command,
656 const char *query, uint query_length);
657
658 /* we use this function to setup all enabled log event handlers */
659 int set_handlers(uint error_log_printer,
660 uint slow_log_printer,
661 uint general_log_printer);
662 void init_error_log(uint error_log_printer);
663 void init_slow_log(uint slow_log_printer);
664 void init_general_log(uint general_log_printer);
665 void deactivate_log_handler(THD* thd, uint log_type);
666 bool activate_log_handler(THD* thd, uint log_type);
get_slow_log_file_handler()667 MYSQL_QUERY_LOG *get_slow_log_file_handler() const
668 {
669 if (file_log_handler)
670 return file_log_handler->get_mysql_slow_log();
671 return NULL;
672 }
get_log_file_handler()673 MYSQL_QUERY_LOG *get_log_file_handler() const
674 {
675 if (file_log_handler)
676 return file_log_handler->get_mysql_log();
677 return NULL;
678 }
679 };
680
681 enum enum_binlog_format {
682 BINLOG_FORMAT_MIXED= 0, ///< statement if safe, otherwise row - autodetected
683 BINLOG_FORMAT_STMT= 1, ///< statement-based
684 BINLOG_FORMAT_ROW= 2, ///< row-based
685 BINLOG_FORMAT_UNSPEC=3 ///< thd_binlog_format() returns it when binlog is closed
686 };
687
688 int query_error_code(THD *thd, bool not_killed);
689 uint purge_log_get_error_code(int res);
690
691 int vprint_msg_to_log(enum loglevel level, const char *format, va_list args);
692 void sql_print_error(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
693 void sql_print_warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
694 void sql_print_information(const char *format, ...)
695 ATTRIBUTE_FORMAT(printf, 1, 2);
696 typedef void (*sql_print_message_func)(const char *format, ...)
697 ATTRIBUTE_FORMAT_FPTR(printf, 1, 2);
698 extern sql_print_message_func sql_print_message_handlers[];
699
700 int error_log_print(enum loglevel level, const char *format,
701 va_list args);
702
703 bool slow_log_print(THD *thd, const char *query, uint query_length,
704 ulonglong current_utime);
705
706 bool general_log_print(THD *thd, enum enum_server_command command,
707 const char *format,...);
708
709 bool general_log_write(THD *thd, enum enum_server_command command,
710 const char *query, uint query_length);
711
712 void sql_perror(const char *message);
713 bool flush_error_log();
714
715 File open_binlog(IO_CACHE *log, const char *log_file_name,
716 const char **errmsg);
717
718 char *make_log_name(char *buff, const char *name, const char* log_ext);
719
720 /**
721 Check given log name against certain blacklisted names/extensions.
722
723 @param name Log name to check
724 @param len Length of log name
725
726 @returns true if name is valid, false otherwise.
727 */
728 bool is_valid_log_name(const char *name, size_t len);
729
730 extern MYSQL_PLUGIN_IMPORT MYSQL_BIN_LOG mysql_bin_log;
731 extern LOGGER logger;
732
733
734 /**
735 Turns a relative log binary log path into a full path, based on the
736 opt_bin_logname or opt_relay_logname.
737
738 @param from The log name we want to make into an absolute path.
739 @param to The buffer where to put the results of the
740 normalization.
741 @param is_relay_log Switch that makes is used inside to choose which
742 option (opt_bin_logname or opt_relay_logname) to
743 use when calculating the base path.
744
745 @returns true if a problem occurs, false otherwise.
746 */
747
normalize_binlog_name(char * to,const char * from,bool is_relay_log)748 inline bool normalize_binlog_name(char *to, const char *from, bool is_relay_log)
749 {
750 DBUG_ENTER("normalize_binlog_name");
751 bool error= false;
752 char buff[FN_REFLEN];
753 char *ptr= (char*) from;
754 char *opt_name= is_relay_log ? opt_relay_logname : opt_bin_logname;
755
756 DBUG_ASSERT(from);
757
758 /* opt_name is not null and not empty and from is a relative path */
759 if (opt_name && opt_name[0] && from && !test_if_hard_path(from))
760 {
761 // take the path from opt_name
762 // take the filename from from
763 char log_dirpart[FN_REFLEN], log_dirname[FN_REFLEN];
764 size_t log_dirpart_len, log_dirname_len;
765 dirname_part(log_dirpart, opt_name, &log_dirpart_len);
766 dirname_part(log_dirname, from, &log_dirname_len);
767
768 /* log may be empty => relay-log or log-bin did not
769 hold paths, just filename pattern */
770 if (log_dirpart_len > 0)
771 {
772 /* create the new path name */
773 if(fn_format(buff, from+log_dirname_len, log_dirpart, "",
774 MYF(MY_UNPACK_FILENAME | MY_SAFE_PATH)) == NULL)
775 {
776 error= true;
777 goto end;
778 }
779
780 ptr= buff;
781 }
782 }
783
784 DBUG_ASSERT(ptr);
785
786 if (ptr)
787 strmake(to, ptr, strlen(ptr));
788
789 end:
790 DBUG_RETURN(error);
791 }
792
793
794
795 #endif /* LOG_H */
796