27
27
#include <drizzled/server_includes.h>
29
#include "rpl_filter.h"
28
#include <drizzled/replication/replication.h>
29
#include <libdrizzle/libdrizzle.h>
30
#include <drizzled/replicator.h>
31
#include <mysys/hash.h>
32
#include <drizzled/replication/rli.h>
32
34
#include <mysys/my_dir.h>
33
35
#include <stdarg.h>
35
37
#include <drizzled/plugin.h>
36
#include <drizzled/drizzled_error_messages.h>
37
#include <libdrizzle/gettext.h>
38
#include <drizzled/error.h>
39
#include <drizzled/gettext.h>
40
#include <drizzled/data_home.h>
41
#include <drizzled/log_event.h>
43
#include <drizzled/errmsg.h>
39
45
/* 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
43
46
#define MY_OFF_T_UNDEF (~(my_off_t)0UL)
45
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
49
DRIZZLE_BIN_LOG mysql_bin_log;
50
ulong sync_binlog_counter= 0;
48
DRIZZLE_BIN_LOG drizzle_bin_log;
49
uint64_t sync_binlog_counter= 0; /* We should rationalize the largest possible counters for binlog sync */
52
51
static bool test_if_number(const char *str,
53
long *res, bool allow_wildcards);
52
long *res, bool allow_wildcards);
54
53
static int binlog_init(void *p);
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);
54
static int binlog_close_connection(handlerton *hton, Session *session);
55
static int binlog_savepoint_set(handlerton *hton, Session *session, void *sv);
56
static int binlog_savepoint_rollback(handlerton *hton, Session *session, void *sv);
57
static int binlog_commit(handlerton *hton, Session *session, bool all);
58
static int binlog_rollback(handlerton *hton, Session *session, bool all);
59
static int binlog_prepare(handlerton *hton, Session *session, bool all);
63
62
sql_print_message_func sql_print_message_handlers[3] =
108
107
void operator=(Mutex_sentry const&);
112
Helper class to store binary log transaction data.
114
class binlog_trx_data {
117
: at_least_one_stmt(0), m_pending(0), before_stmt_pos(MY_OFF_T_UNDEF)
119
trans_log.end_of_file= max_binlog_cache_size;
124
assert(pending() == NULL);
125
close_cached_file(&trans_log);
128
my_off_t position() const {
129
return my_b_tell(&trans_log);
134
return pending() == NULL && my_b_tell(&trans_log) == 0;
138
Truncate the transaction cache to a certain position. This
139
includes deleting the pending event.
141
void truncate(my_off_t pos)
145
reinit_io_cache(&trans_log, WRITE_CACHE, pos, 0, 0);
146
if (pos < before_stmt_pos)
147
before_stmt_pos= MY_OFF_T_UNDEF;
150
The only valid positions that can be truncated to are at the
151
beginning of a statement. We are relying on this fact to be able
152
to set the at_least_one_stmt flag correctly. In other word, if
153
we are truncating to the beginning of the transaction cache,
154
there will be no statements in the cache, otherwhise, we will
155
have at least one statement in the transaction cache.
157
at_least_one_stmt= (pos > 0);
161
Reset the entire contents of the transaction cache, emptying it
167
before_stmt_pos= MY_OFF_T_UNDEF;
168
trans_log.end_of_file= max_binlog_cache_size;
171
Rows_log_event *pending() const
176
void set_pending(Rows_log_event *const pending)
181
IO_CACHE trans_log; // The transaction cache
184
Boolean that is true if there is at least one statement in the
187
bool at_least_one_stmt;
191
Pending binrows event. This event is the event where the rows are
194
Rows_log_event *m_pending;
198
Binlog position before the start of the current statement.
200
my_off_t before_stmt_pos;
203
110
handlerton *binlog_hton;
206
/* Check if a given table is opened log table */
207
int check_if_log_table(uint32_t db_len __attribute__((unused)),
208
const char *db __attribute__((unused)),
209
uint32_t table_name_len __attribute__((unused)),
210
const char *table_name __attribute__((unused)),
211
uint32_t check_if_opened __attribute__((unused)))
217
Log error with all enabled log event handlers
222
level The level of the error significance: NOTE,
224
format format string for the error message
225
args list of arguments for the format string
232
bool LOGGER::error_log_print(enum loglevel level, const char *format,
236
Log_event_handler **current_handler;
238
/* currently we don't need locking here as there is no error_log table */
239
for (current_handler= error_log_handler_list ; *current_handler ;)
240
error= (*current_handler++)->log_error(level, format, args) || error;
246
void LOGGER::cleanup_base()
249
rwlock_destroy(&LOCK_logger);
253
void LOGGER::cleanup_end()
260
Perform basic log initialization: create file-based log handler and
263
void LOGGER::init_base()
268
/* by default we use traditional error log */
269
init_error_log(LOG_FILE);
271
my_rwlock_init(&LOCK_logger, NULL);
275
bool LOGGER::flush_logs(THD *thd __attribute__((unused)))
280
Now we lock logger, as nobody should be able to use logging routines while
281
log tables are closed
283
logger.lock_exclusive();
285
/* end of log flush */
290
void LOGGER::init_error_log(uint32_t error_log_printer)
292
if (error_log_printer & LOG_NONE)
294
error_log_handler_list[0]= 0;
300
int LOGGER::set_handlers(uint32_t error_log_printer)
302
/* error log table is not supported yet */
305
init_error_log(error_log_printer);
313
114
Save position of binary log transaction cache.
316
117
binlog_trans_log_savepos()
318
thd The thread to take the binlog data from
119
session The thread to take the binlog data from
319
120
pos Pointer to variable where the position will be stored
328
binlog_trans_log_savepos(THD *thd, my_off_t *pos)
129
binlog_trans_log_savepos(Session *, my_off_t *pos)
330
131
assert(pos != NULL);
331
if (thd_get_ha_data(thd, binlog_hton) == NULL)
332
thd->binlog_setup_trx_data();
333
binlog_trx_data *const trx_data=
334
(binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
335
assert(mysql_bin_log.is_open());
336
*pos= trx_data->position();
342
Truncate the binary log transaction cache.
345
binlog_trans_log_truncate()
347
thd The thread to take the binlog data from
348
pos Position to truncate to
352
Truncate the binary log to the given position. Will not change
357
binlog_trans_log_truncate(THD *thd, my_off_t pos)
359
assert(thd_get_ha_data(thd, binlog_hton) != NULL);
360
/* Only true if binlog_trans_log_savepos() wasn't called before */
361
assert(pos != ~(my_off_t) 0);
363
binlog_trx_data *const trx_data=
364
(binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
365
trx_data->truncate(pos);
392
static int binlog_close_connection(handlerton *hton __attribute__((unused)),
159
static int binlog_close_connection(handlerton *, Session *)
395
binlog_trx_data *const trx_data=
396
(binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
397
assert(trx_data->empty());
398
thd_set_ha_data(thd, binlog_hton, NULL);
399
trx_data->~binlog_trx_data();
400
free((unsigned char*)trx_data);
410
thd The thread whose transaction should be ended
411
trx_data Pointer to the transaction data to use
412
end_ev The end event to use, or NULL
413
all True if the entire transaction should be ended, false if
414
only the statement transaction should be ended.
418
End the currently open transaction. The transaction can be either
419
a real transaction (if 'all' is true) or a statement transaction
422
If 'end_ev' is NULL, the transaction is a rollback of only
423
transactional tables, so the transaction cache will be truncated
424
to either just before the last opened statement transaction (if
425
'all' is false), or reset completely (if 'all' is true).
428
binlog_end_trans(THD *thd, binlog_trx_data *trx_data,
429
Log_event *end_ev, bool all)
432
IO_CACHE *trans_log= &trx_data->trans_log;
435
NULL denotes ROLLBACK with nothing to replicate: i.e., rollback of
436
only transactional tables. If the transaction contain changes to
437
any non-transactiona tables, we need write the transaction and log
443
Doing a commit or a rollback including non-transactional tables,
444
i.e., ending a transaction where we might write the transaction
445
cache to the binary log.
447
We can always end the statement when ending a transaction since
448
transactions are not allowed inside stored functions. If they
449
were, we would have to ensure that we're not ending a statement
450
inside a stored function.
452
thd->binlog_flush_pending_rows_event(true);
454
error= mysql_bin_log.write(thd, &trx_data->trans_log, end_ev);
458
We need to step the table map version after writing the
459
transaction cache to disk.
461
mysql_bin_log.update_table_map_version();
462
statistic_increment(binlog_cache_use, &LOCK_status);
463
if (trans_log->disk_writes != 0)
465
statistic_increment(binlog_cache_disk_use, &LOCK_status);
466
trans_log->disk_writes= 0;
472
If rolling back an entire transaction or a single statement not
473
inside a transaction, we reset the transaction cache.
475
If rolling back a statement in a transaction, we truncate the
476
transaction cache to remove the statement.
478
if (all || !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT)))
482
assert(!thd->binlog_get_pending_rows_event());
483
thd->clear_binlog_table_maps();
486
trx_data->truncate(trx_data->before_stmt_pos);
489
We need to step the table map version on a rollback to ensure
490
that a new table map event is generated instead of the one that
491
was written to the thrown-away transaction cache.
493
mysql_bin_log.update_table_map_version();
499
static int binlog_prepare(handlerton *hton __attribute__((unused)),
500
THD *thd __attribute__((unused)),
501
bool all __attribute__((unused)))
165
static int binlog_prepare(handlerton *, Session *session, bool)
616
267
non-transactional tables, nothing needs to be logged.
618
269
@param hton The binlog handlerton.
619
@param thd The client thread that executes the transaction.
270
@param session The client thread that executes the transaction.
620
271
@param all This is @c true if this is a real transaction rollback, and
621
272
@false otherwise.
623
274
@see handlerton::rollback
625
static int binlog_rollback(handlerton *hton __attribute__((unused)),
276
static int binlog_rollback(handlerton *, Session *session, bool all)
629
binlog_trx_data *const trx_data=
630
(binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
632
if (trx_data->empty()) {
637
if ((all && thd->transaction.all.modified_non_trans_table) ||
638
(!all && thd->transaction.stmt.modified_non_trans_table) ||
639
(thd->options & OPTION_KEEP_LOG))
642
We write the transaction cache with a rollback last if we have
643
modified any non-transactional table. We do this even if we are
644
committing a single statement that has modified a
645
non-transactional table since it can have modified a
646
transactional table in that statement as well, which needs to be
647
rolled back on the slave.
649
Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), true, false);
650
qev.error_code= 0; // see comment in DRIZZLE_LOG::write(THD, IO_CACHE)
651
error= binlog_end_trans(thd, trx_data, &qev, all);
653
else if ((all && !thd->transaction.all.modified_non_trans_table) ||
654
(!all && !thd->transaction.stmt.modified_non_trans_table))
657
If we have modified only transactional tables, we can truncate
658
the transaction cache without writing anything to the binary
661
error= binlog_end_trans(thd, trx_data, 0, all);
280
/* TODO: Fix return type */
281
(void)replicator_end_transaction(session, all, false);
687
307
that case there is no need to have it in the binlog).
690
static int binlog_savepoint_set(handlerton *hton __attribute__((unused)),
310
static int binlog_savepoint_set(handlerton *, Session *session, void *sv)
693
binlog_trans_log_savepos(thd, (my_off_t*) sv);
313
binlog_trans_log_savepos(session, (my_off_t*) sv);
694
314
/* Write it to the binary log */
697
thd->binlog_query(THD::STMT_QUERY_TYPE,
698
thd->query, thd->query_length, true, false);
316
error= replicator_statement(session, session->query, session->query_length);
702
static int binlog_savepoint_rollback(handlerton *hton __attribute__((unused)),
321
static int binlog_savepoint_rollback(handlerton *, Session *session, void *)
706
Write ROLLBACK TO SAVEPOINT to the binlog cache if we have updated some
707
non-transactional table. Otherwise, truncate the binlog cache starting
708
from the SAVEPOINT command.
710
if (unlikely(thd->transaction.all.modified_non_trans_table ||
711
(thd->options & OPTION_KEEP_LOG)))
714
thd->binlog_query(THD::STMT_QUERY_TYPE,
715
thd->query, thd->query_length, true, false);
718
binlog_trans_log_truncate(thd, *(my_off_t*)sv);
325
error= replicator_statement(session, session->query, session->query_length);
887
495
if ((file= my_open(log_file_name, open_flags,
888
496
MYF(MY_WME | ME_WAITTANG))) < 0 ||
889
497
init_io_cache(&log_file, file, IO_SIZE, io_cache_type,
890
my_tell(file, MYF(MY_WME)), 0,
498
lseek(file, 0, SEEK_CUR), 0,
891
499
MYF(MY_WME | MY_NABP |
892
500
((log_type == LOG_BIN) ? MY_WAIT_IF_FULL : 0))))
895
503
if (log_type == LOG_NORMAL)
898
int len=snprintf(buff, sizeof(buff), "%s, Version: %s (%s). "
899
"started with:\nTCP Port: %d, Named Pipe: %s\n",
900
my_progname, server_version, DRIZZLE_COMPILATION_COMMENT,
903
end= my_stpncpy(buff + len, "Time Id Command Argument\n",
905
if (my_b_write(&log_file, (unsigned char*) buff, (uint) (end-buff)) ||
906
flush_io_cache(&log_file))
505
int len= snprintf(buff, sizeof(buff), "%s, Version: %s (%s). "
506
"started with:\nTCP Port: %d, Named Pipe: %s\n",
507
my_progname, server_version, COMPILATION_COMMENT,
509
len+= sprintf(buff+len, "Time Id Command Argument\n");
511
if (my_b_write(&log_file, (unsigned char*) buff, len) ||
512
flush_io_cache(&log_file))
2207
void DRIZZLE_BIN_LOG::start_union_events(THD *thd, query_id_t query_id_param)
2209
assert(!thd->binlog_evt_union.do_union);
2210
thd->binlog_evt_union.do_union= true;
2211
thd->binlog_evt_union.unioned_events= false;
2212
thd->binlog_evt_union.unioned_events_trans= false;
2213
thd->binlog_evt_union.first_query_id= query_id_param;
2216
void DRIZZLE_BIN_LOG::stop_union_events(THD *thd)
2218
assert(thd->binlog_evt_union.do_union);
2219
thd->binlog_evt_union.do_union= false;
2222
bool DRIZZLE_BIN_LOG::is_query_in_union(THD *thd, query_id_t query_id_param)
2224
return (thd->binlog_evt_union.do_union &&
2225
query_id_param >= thd->binlog_evt_union.first_query_id);
2230
These functions are placed in this file since they need access to
2231
binlog_hton, which has internal linkage.
2234
int THD::binlog_setup_trx_data()
2236
binlog_trx_data *trx_data=
2237
(binlog_trx_data*) thd_get_ha_data(this, binlog_hton);
2240
return(0); // Already set up
2242
trx_data= (binlog_trx_data*) my_malloc(sizeof(binlog_trx_data), MYF(MY_ZEROFILL));
2244
open_cached_file(&trx_data->trans_log, mysql_tmpdir,
2245
LOG_PREFIX, binlog_cache_size, MYF(MY_WME)))
2247
free((unsigned char*)trx_data);
2248
return(1); // Didn't manage to set it up
2250
thd_set_ha_data(this, binlog_hton, trx_data);
2252
trx_data= new (thd_get_ha_data(this, binlog_hton)) binlog_trx_data;
2258
Function to start a statement and optionally a transaction for the
2262
binlog_start_trans_and_stmt()
2266
This function does three things:
2267
- Start a transaction if not in autocommit mode or if a BEGIN
2268
statement has been seen.
2270
- Start a statement transaction to allow us to truncate the binary
2273
- Save the currrent binlog position so that we can roll back the
2274
statement by truncating the transaction log.
2276
We only update the saved position if the old one was undefined,
2277
the reason is that there are some cases (e.g., for CREATE-SELECT)
2278
where the position is saved twice (e.g., both in
2279
select_create::prepare() and THD::binlog_write_table_map()) , but
2280
we should use the first. This means that calls to this function
2281
can be used to start the statement before the first table map
2282
event, to include some extra events.
2286
THD::binlog_start_trans_and_stmt()
2288
binlog_trx_data *trx_data= (binlog_trx_data*) thd_get_ha_data(this, binlog_hton);
2290
if (trx_data == NULL ||
2291
trx_data->before_stmt_pos == MY_OFF_T_UNDEF)
2293
this->binlog_set_stmt_begin();
2294
if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
2295
trans_register_ha(this, true, binlog_hton);
2296
trans_register_ha(this, false, binlog_hton);
2298
Mark statement transaction as read/write. We never start
2299
a binary log transaction and keep it read-only,
2300
therefore it's best to mark the transaction read/write just
2301
at the same time we start it.
2302
Not necessary to mark the normal transaction read/write
2303
since the statement-level flag will be propagated automatically
2304
inside ha_commit_trans.
2306
ha_data[binlog_hton->slot].ha_info[0].set_trx_read_write();
2311
void THD::binlog_set_stmt_begin() {
2312
binlog_trx_data *trx_data=
2313
(binlog_trx_data*) thd_get_ha_data(this, binlog_hton);
2316
The call to binlog_trans_log_savepos() might create the trx_data
2317
structure, if it didn't exist before, so we save the position
2318
into an auto variable and then write it into the transaction
2319
data for the binary log (i.e., trx_data).
2322
binlog_trans_log_savepos(this, &pos);
2323
trx_data= (binlog_trx_data*) thd_get_ha_data(this, binlog_hton);
2324
trx_data->before_stmt_pos= pos;
2329
Write a table map to the binary log.
2332
int THD::binlog_write_table_map(Table *table, bool is_trans)
2336
/* Pre-conditions */
2337
assert(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2338
assert(table->s->table_map_id != UINT32_MAX);
2340
Table_map_log_event::flag_set const
2341
flags= Table_map_log_event::TM_NO_FLAGS;
2344
the_event(this, table, table->s->table_map_id, is_trans, flags);
2346
if (is_trans && binlog_table_maps == 0)
2347
binlog_start_trans_and_stmt();
2349
if ((error= mysql_bin_log.write(&the_event)))
2352
binlog_table_maps++;
2353
table->s->table_map_version= mysql_bin_log.table_map_version();
2358
THD::binlog_get_pending_rows_event() const
2360
binlog_trx_data *const trx_data=
2361
(binlog_trx_data*) thd_get_ha_data(this, binlog_hton);
2363
This is less than ideal, but here's the story: If there is no
2364
trx_data, prepare_pending_rows_event() has never been called
2365
(since the trx_data is set up there). In that case, we just return
2368
return trx_data ? trx_data->pending() : NULL;
2372
THD::binlog_set_pending_rows_event(Rows_log_event* ev)
2374
if (thd_get_ha_data(this, binlog_hton) == NULL)
2375
binlog_setup_trx_data();
2377
binlog_trx_data *const trx_data=
2378
(binlog_trx_data*) thd_get_ha_data(this, binlog_hton);
2381
trx_data->set_pending(ev);
1812
void DRIZZLE_BIN_LOG::start_union_events(Session *session, query_id_t query_id_param)
1814
assert(!session->binlog_evt_union.do_union);
1815
session->binlog_evt_union.do_union= true;
1816
session->binlog_evt_union.unioned_events= false;
1817
session->binlog_evt_union.unioned_events_trans= false;
1818
session->binlog_evt_union.first_query_id= query_id_param;
1821
void DRIZZLE_BIN_LOG::stop_union_events(Session *session)
1823
assert(session->binlog_evt_union.do_union);
1824
session->binlog_evt_union.do_union= false;
1827
bool DRIZZLE_BIN_LOG::is_query_in_union(Session *session, query_id_t query_id_param)
1829
return (session->binlog_evt_union.do_union &&
1830
query_id_param >= session->binlog_evt_union.first_query_id);
2386
1834
Moves the last bunch of rows from the pending Rows event to the binlog
2391
DRIZZLE_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
2392
Rows_log_event* event)
1839
DRIZZLE_BIN_LOG::flush_and_set_pending_rows_event(Session *, Rows_log_event*)
2394
assert(mysql_bin_log.is_open());
2398
binlog_trx_data *const trx_data=
2399
(binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
2403
if (Rows_log_event* pending= trx_data->pending())
2405
IO_CACHE *file= &log_file;
2408
Decide if we should write to the log file directly or to the
2411
if (pending->get_cache_stmt() || my_b_tell(&trx_data->trans_log))
2412
file= &trx_data->trans_log;
2415
If we are writing to the log file directly, we could avoid
2416
locking the log. This does not work since we need to step the
2417
m_table_map_version below, and that change has to be protected
2418
by the LOCK_log mutex.
2420
pthread_mutex_lock(&LOCK_log);
2423
Write pending event to log file or transaction cache
2425
if (pending->write(file))
2427
pthread_mutex_unlock(&LOCK_log);
2432
We step the table map version if we are writing an event
2433
representing the end of a statement. We do this regardless of
2434
wheather we write to the transaction cache or to directly to the
2437
In an ideal world, we could avoid stepping the table map version
2438
if we were writing to a transaction cache, since we could then
2439
reuse the table map that was written earlier in the transaction
2440
cache. This does not work since STMT_END_F implies closing all
2441
table mappings on the slave side.
2443
TODO: Find a solution so that table maps does not have to be
2444
written several times within a transaction.
2446
if (pending->get_flags(Rows_log_event::STMT_END_F))
2447
++m_table_map_version;
2451
if (file == &log_file)
2453
error= flush_and_sync();
2457
rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
2461
pthread_mutex_unlock(&LOCK_log);
2464
thd->binlog_set_pending_rows_event(event);
1841
assert(drizzle_bin_log.is_open());
2514
1889
"do the involved tables match (to be implemented)
2515
1890
binlog_[wild_]{do|ignore}_table?" (WL#1049)"
2517
const char *local_db= event_info->get_db();
2518
if ((thd && !(thd->options & OPTION_BIN_LOG)) ||
2519
(!binlog_filter->db_ok(local_db)))
1892
if (session && !(session->options & OPTION_BIN_LOG))
2521
1894
pthread_mutex_unlock(&LOCK_log);
2526
Should we write to the binlog cache or to the binlog on disk?
2527
Write to the binlog cache if:
2528
- it is already not empty (meaning we're in a transaction; note that the
2529
present event could be about a non-transactional table, but still we need
2530
to write to the binlog cache in that case to handle updates to mixed
2531
trans/non-trans table types the best possible in binlogging)
2532
- or if the event asks for it (cache_stmt == TRUE).
2534
if (opt_using_transactions && thd)
2536
if (thd->binlog_setup_trx_data())
2539
binlog_trx_data *const trx_data=
2540
(binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
2541
IO_CACHE *trans_log= &trx_data->trans_log;
2542
my_off_t trans_log_pos= my_b_tell(trans_log);
2543
if (event_info->get_cache_stmt() || trans_log_pos != 0)
2545
if (trans_log_pos == 0)
2546
thd->binlog_start_trans_and_stmt();
2550
TODO as Mats suggested, for all the cases above where we write to
2551
trans_log, it sounds unnecessary to lock LOCK_log. We should rather
2552
test first if we want to write to trans_log, and if not, lock
2558
No check for auto events flag here - this write method should
2559
never be called if auto-events are enabled
2563
1. Write first log events which describe the 'run environment'
2568
If row-based binlogging, Insert_id, Rand and other kind of "setting
2569
context" events are not needed.
2573
if (!thd->current_stmt_binlog_row_based)
2575
if (thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt)
2577
Intvar_log_event e(thd,(unsigned char) LAST_INSERT_ID_EVENT,
2578
thd->first_successful_insert_id_in_prev_stmt_for_binlog);
2582
if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
2585
If the auto_increment was second in a table's index (possible with
2586
MyISAM or BDB) (table->next_number_keypart != 0), such event is
2587
in fact not necessary. We could avoid logging it.
2589
Intvar_log_event e(thd, (unsigned char) INSERT_ID_EVENT,
2590
thd->auto_inc_intervals_in_cur_stmt_for_binlog.
2597
Rand_log_event e(thd,thd->rand_saved_seed1,thd->rand_saved_seed2);
2601
if (thd->user_var_events.elements)
2603
for (uint32_t i= 0; i < thd->user_var_events.elements; i++)
2605
BINLOG_USER_VAR_EVENT *user_var_event;
2606
get_dynamic(&thd->user_var_events,(unsigned char*) &user_var_event, i);
2607
User_var_log_event e(thd, user_var_event->user_var_event->name.str,
2608
user_var_event->user_var_event->name.length,
2609
user_var_event->value,
2610
user_var_event->length,
2611
user_var_event->type,
2612
user_var_event->charset_number);
2621
1899
Write the SQL command
3135
2406
bool flush_error_log()
3138
2409
if (opt_error_log)
3140
char err_renamed[FN_REFLEN], *end;
3141
end= strmake(err_renamed,log_error_file,FN_REFLEN-4);
3142
my_stpcpy(end, "-old");
3143
2411
pthread_mutex_lock(&LOCK_error_log);
3144
char err_temp[FN_REFLEN+4];
3146
On Windows is necessary a temporary file for to rename
3147
the current error file.
3149
strxmov(err_temp, err_renamed,"-tmp",NULL);
3150
(void) my_delete(err_temp, MYF(0));
3151
if (freopen(err_temp,"a+",stdout))
3155
unsigned char buf[IO_SIZE];
3157
freopen(err_temp,"a+",stderr);
3158
(void) my_delete(err_renamed, MYF(0));
3159
my_rename(log_error_file,err_renamed,MYF(0));
3160
if (freopen(log_error_file,"a+",stdout))
3161
freopen(log_error_file,"a+",stderr);
3163
if ((fd = my_open(err_temp, O_RDONLY, MYF(0))) >= 0)
3165
while ((bytes= my_read(fd, buf, IO_SIZE, MYF(0))) &&
3166
bytes != MY_FILE_ERROR)
3167
my_fwrite(stderr, buf, bytes, MYF(0));
3168
my_close(fd, MYF(0));
3170
(void) my_delete(err_temp, MYF(0));
2412
if (freopen(log_error_file,"a+",stdout)==NULL)
2414
if (freopen(log_error_file,"a+",stderr)==NULL)
3174
2416
pthread_mutex_unlock(&LOCK_error_log);
3186
Prints a printf style message to the error log and, under NT, to the
3189
This function prints the message into a buffer and then sends that buffer
3190
to other functions to write that message to other logging sources.
3192
@param event_type Type of event to write (Error, Warning, or Info)
3193
@param format Printf style format of message
3194
@param args va_list list of arguments for the message
3197
The function always returns 0. The return value is present in the
3198
signature to be compatible with other logging routines, which could
3199
return an error (e.g. logging to the log tables)
3201
static void print_buffer_to_file(enum loglevel level,
3202
int error_code __attribute__((unused)),
3204
size_t buffer_length __attribute__((unused)))
3210
pthread_mutex_lock(&LOCK_error_log);
3213
localtime_r(&skr, &tm_tmp);
3216
fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d [%s] %s\n",
3217
start->tm_year % 100,
3223
(level == ERROR_LEVEL ? "ERROR" : level == WARNING_LEVEL ?
3224
"Warning" : "Note"),
3229
pthread_mutex_unlock(&LOCK_error_log);
3234
int vprint_msg_to_log(enum loglevel level, const char *format, va_list args)
3238
int error_code= errno;
3240
length= vsnprintf(buff, sizeof(buff), format, args);
3242
print_buffer_to_file(level, error_code, buff, length);
3248
void sql_print_error(const char *format, ...)
3252
va_start(args, format);
3253
error_log_print(ERROR_LEVEL, format, args);
3260
void sql_print_warning(const char *format, ...)
3264
va_start(args, format);
3265
error_log_print(WARNING_LEVEL, format, args);
3272
void sql_print_information(const char *format, ...)
3276
va_start(args, format);
3277
error_log_print(INFORMATION_LEVEL, format, args);
2427
void sql_print_error(const char *format, ...)
2431
va_start(args, format);
2432
errmsg_vprintf (current_session, ERROR_LEVEL, format, args);
2439
void sql_print_warning(const char *format, ...)
2443
va_start(args, format);
2444
errmsg_vprintf (current_session, WARNING_LEVEL, format, args);
2451
void sql_print_information(const char *format, ...)
2455
va_start(args, format);
2456
errmsg_vprintf (current_session, INFORMATION_LEVEL, format, args);
3891
int TC_LOG_BINLOG::log_xid(THD *thd, my_xid xid)
3077
int TC_LOG_BINLOG::log_xid(Session *session, my_xid xid)
3893
Xid_log_event xle(thd, xid);
3894
binlog_trx_data *trx_data=
3895
(binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
3079
Xid_log_event xle(session, xid);
3080
/* TODO: Fix return type */
3897
3082
We always commit the entire transaction when writing an XID. Also
3898
3083
note that the return value is inverted.
3085
TODO: fix backasswards logic on this method
3900
return(!binlog_end_trans(thd, trx_data, &xle, true));
3088
return replicator_end_transaction(session, true, true) ? false : true;
3903
void TC_LOG_BINLOG::unlog(ulong cookie __attribute__((unused)),
3904
my_xid xid __attribute__((unused)))
3091
void TC_LOG_BINLOG::unlog(ulong, my_xid)
3906
3093
pthread_mutex_lock(&LOCK_prep_xids);
3907
3094
assert(prepared_xids > 0);