469
469
Log_event::Log_event()
472
Log_event::Log_event(THD* thd_arg, uint16_t flags_arg, bool using_trans)
473
:log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg), thd(thd_arg)
472
Log_event::Log_event(Session* session_arg, uint16_t flags_arg, bool using_trans)
473
:log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg), session(session_arg)
475
server_id= thd->server_id;
476
when= thd->start_time;
475
server_id= session->server_id;
476
when= session->start_time;
477
477
cache_stmt= using_trans;
482
482
This minimal constructor is for when you are not even sure that there
483
is a valid THD. For example in the server when we are shutting down or
483
is a valid Session. For example in the server when we are shutting down or
484
484
flushing logs after receiving a SIGHUP (then we must write a Rotate to
485
the binlog but we have no THD, so we need this minimal constructor).
485
the binlog but we have no Session, so we need this minimal constructor).
488
488
Log_event::Log_event()
489
489
:temp_buf(0), exec_time(0), flags(0), cache_stmt(0),
492
492
server_id= ::server_id;
1283
1283
Query_log_event::Query_log_event()
1284
thd_arg - thread handle
1284
session_arg - thread handle
1285
1285
query_arg - array of char representing the query
1286
1286
query_length - size of the `query_arg' array
1287
1287
using_trans - there is a modified transactional table
1288
1288
suppress_use - suppress the generation of 'USE' statements
1289
killed_status_arg - an optional with default to THD::KILLED_NO_VALUE
1289
killed_status_arg - an optional with default to Session::KILLED_NO_VALUE
1290
1290
if the value is different from the default, the arg
1291
is set to the current thd->killed value.
1292
A caller might need to masquerade thd->killed with
1291
is set to the current session->killed value.
1292
A caller might need to masquerade session->killed with
1293
Session::NOT_KILLED.
1295
1295
Creates an event for binlogging
1296
1296
The value for local `killed_status' can be supplied by caller.
1298
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
1298
Query_log_event::Query_log_event(Session* session_arg, const char* query_arg,
1299
1299
ulong query_length, bool using_trans,
1300
1300
bool suppress_use,
1301
THD::killed_state killed_status_arg)
1303
(thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F :
1301
Session::killed_state killed_status_arg)
1302
:Log_event(session_arg,
1303
(session_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F :
1305
1305
(suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
1307
data_buf(0), query(query_arg), catalog(thd_arg->catalog),
1308
db(thd_arg->db), q_len((uint32_t) query_length),
1309
thread_id(thd_arg->thread_id),
1307
data_buf(0), query(query_arg), catalog(session_arg->catalog),
1308
db(session_arg->db), q_len((uint32_t) query_length),
1309
thread_id(session_arg->thread_id),
1310
1310
/* save the original thread id; we already know the server id */
1311
slave_proxy_id(thd_arg->variables.pseudo_thread_id),
1311
slave_proxy_id(session_arg->variables.pseudo_thread_id),
1312
1312
flags2_inited(1), sql_mode_inited(1), charset_inited(1),
1314
auto_increment_increment(thd_arg->variables.auto_increment_increment),
1315
auto_increment_offset(thd_arg->variables.auto_increment_offset),
1316
lc_time_names_number(thd_arg->variables.lc_time_names->number),
1314
auto_increment_increment(session_arg->variables.auto_increment_increment),
1315
auto_increment_offset(session_arg->variables.auto_increment_offset),
1316
lc_time_names_number(session_arg->variables.lc_time_names->number),
1317
1317
charset_database_number(0)
1319
1319
time_t end_time;
1321
if (killed_status_arg == THD::KILLED_NO_VALUE)
1322
killed_status_arg= thd_arg->killed;
1321
if (killed_status_arg == Session::KILLED_NO_VALUE)
1322
killed_status_arg= session_arg->killed;
1325
(killed_status_arg == THD::NOT_KILLED) ?
1326
(thd_arg->is_error() ? thd_arg->main_da.sql_errno() : 0) :
1327
(thd_arg->killed_errno());
1325
(killed_status_arg == Session::NOT_KILLED) ?
1326
(session_arg->is_error() ? session_arg->main_da.sql_errno() : 0) :
1327
(session_arg->killed_errno());
1329
1329
time(&end_time);
1330
exec_time = (ulong) (end_time - thd_arg->start_time);
1330
exec_time = (ulong) (end_time - session_arg->start_time);
1332
1332
@todo this means that if we have no catalog, then it is replicated
1333
1333
as an existing catalog of length zero. is that safe? /sven
1335
1335
catalog_len = (catalog) ? (uint32_t) strlen(catalog) : 0;
1336
1336
/* status_vars_len is set just before writing the event */
1337
1337
db_len = (db) ? (uint32_t) strlen(db) : 0;
1338
if (thd_arg->variables.collation_database != thd_arg->db_charset)
1339
charset_database_number= thd_arg->variables.collation_database->number;
1338
if (session_arg->variables.collation_database != session_arg->db_charset)
1339
charset_database_number= session_arg->variables.collation_database->number;
1342
1342
If we don't use flags2 for anything else than options contained in
1343
thd_arg->options, it would be more efficient to flags2=thd_arg->options
1343
session_arg->options, it would be more efficient to flags2=session_arg->options
1344
1344
(OPTIONS_WRITTEN_TO_BIN_LOG would be used only at reading time).
1345
1345
But it's likely that we don't want to use 32 bits for 3 bits; in the future
1346
1346
we will probably want to reclaim the 29 bits. So we need the &.
1348
flags2= (uint32_t) (thd_arg->options & OPTIONS_WRITTEN_TO_BIN_LOG);
1349
assert(thd_arg->variables.character_set_client->number < 256*256);
1350
assert(thd_arg->variables.collation_connection->number < 256*256);
1351
assert(thd_arg->variables.collation_server->number < 256*256);
1352
assert(thd_arg->variables.character_set_client->mbminlen == 1);
1353
int2store(charset, thd_arg->variables.character_set_client->number);
1354
int2store(charset+2, thd_arg->variables.collation_connection->number);
1355
int2store(charset+4, thd_arg->variables.collation_server->number);
1356
if (thd_arg->time_zone_used)
1348
flags2= (uint32_t) (session_arg->options & OPTIONS_WRITTEN_TO_BIN_LOG);
1349
assert(session_arg->variables.character_set_client->number < 256*256);
1350
assert(session_arg->variables.collation_connection->number < 256*256);
1351
assert(session_arg->variables.collation_server->number < 256*256);
1352
assert(session_arg->variables.character_set_client->mbminlen == 1);
1353
int2store(charset, session_arg->variables.character_set_client->number);
1354
int2store(charset+2, session_arg->variables.collation_connection->number);
1355
int2store(charset+4, session_arg->variables.collation_server->number);
1356
if (session_arg->time_zone_used)
1359
1359
Note that our event becomes dependent on the Time_zone object
1360
1360
representing the time zone. Fortunately such objects are never deleted
1361
1361
or changed during mysqld's lifetime.
1363
time_zone_len= thd_arg->variables.time_zone->get_name()->length();
1364
time_zone_str= thd_arg->variables.time_zone->get_name()->ptr();
1363
time_zone_len= session_arg->variables.time_zone->get_name()->length();
1364
time_zone_str= session_arg->variables.time_zone->get_name()->ptr();
1367
1367
time_zone_len= 0;
1649
1649
LEX_STRING new_db;
1650
1650
int expected_error,actual_error= 0;
1652
Colleagues: please never free(thd->catalog) in MySQL. This would
1653
lead to bugs as here thd->catalog is a part of an alloced block,
1652
Colleagues: please never free(session->catalog) in MySQL. This would
1653
lead to bugs as here session->catalog is a part of an alloced block,
1654
1654
not an entire alloced block (see
1655
Query_log_event::do_apply_event()). Same for thd->db. Thank
1655
Query_log_event::do_apply_event()). Same for session->db. Thank
1658
thd->catalog= catalog_len ? (char *) catalog : (char *)"";
1658
session->catalog= catalog_len ? (char *) catalog : (char *)"";
1659
1659
new_db.length= db_len;
1660
1660
new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
1661
thd->set_db(new_db.str, new_db.length); /* allocates a copy of 'db' */
1662
thd->variables.auto_increment_increment= auto_increment_increment;
1663
thd->variables.auto_increment_offset= auto_increment_offset;
1661
session->set_db(new_db.str, new_db.length); /* allocates a copy of 'db' */
1662
session->variables.auto_increment_increment= auto_increment_increment;
1663
session->variables.auto_increment_offset= auto_increment_offset;
1666
1666
InnoDB internally stores the master log position it has executed so far,
1687
1687
::do_apply_event(), then the companion SET also have so
1688
1688
we don't need to reset_one_shot_variables().
1690
if (rpl_filter->db_ok(thd->db))
1690
if (rpl_filter->db_ok(session->db))
1692
thd->set_time((time_t)when);
1693
thd->query_length= q_len_arg;
1694
thd->query= (char*)query_arg;
1692
session->set_time((time_t)when);
1693
session->query_length= q_len_arg;
1694
session->query= (char*)query_arg;
1695
1695
pthread_mutex_lock(&LOCK_thread_count);
1696
thd->query_id = next_query_id();
1696
session->query_id = next_query_id();
1697
1697
pthread_mutex_unlock(&LOCK_thread_count);
1698
thd->variables.pseudo_thread_id= thread_id; // for temp tables
1698
session->variables.pseudo_thread_id= thread_id; // for temp tables
1700
1700
if (ignored_error_code((expected_error= error_code)) ||
1701
!check_expected_error(thd,rli,expected_error))
1701
!check_expected_error(session,rli,expected_error))
1703
1703
if (flags2_inited)
1705
all bits of thd->options which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG
1705
all bits of session->options which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG
1706
1706
must take their value from flags2.
1708
thd->options= flags2|(thd->options & ~OPTIONS_WRITTEN_TO_BIN_LOG);
1708
session->options= flags2|(session->options & ~OPTIONS_WRITTEN_TO_BIN_LOG);
1709
1709
if (time_zone_len)
1711
1711
String tmp(time_zone_str, time_zone_len, &my_charset_bin);
1712
if (!(thd->variables.time_zone= my_tz_find(thd, &tmp)))
1712
if (!(session->variables.time_zone= my_tz_find(session, &tmp)))
1714
1714
my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), tmp.c_ptr());
1715
thd->variables.time_zone= global_system_variables.time_zone;
1715
session->variables.time_zone= global_system_variables.time_zone;
1716
1716
goto compare_errors;
1719
1719
if (lc_time_names_number)
1721
if (!(thd->variables.lc_time_names=
1721
if (!(session->variables.lc_time_names=
1722
1722
my_locale_by_number(lc_time_names_number)))
1724
1724
my_printf_error(ER_UNKNOWN_ERROR,
1725
1725
"Unknown locale: '%d'", MYF(0), lc_time_names_number);
1726
thd->variables.lc_time_names= &my_locale_en_US;
1726
session->variables.lc_time_names= &my_locale_en_US;
1727
1727
goto compare_errors;
1731
thd->variables.lc_time_names= &my_locale_en_US;
1731
session->variables.lc_time_names= &my_locale_en_US;
1732
1732
if (charset_database_number)
1734
1734
const CHARSET_INFO *cs;
1739
1739
my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
1740
1740
goto compare_errors;
1742
thd->variables.collation_database= cs;
1742
session->variables.collation_database= cs;
1745
thd->variables.collation_database= thd->db_charset;
1745
session->variables.collation_database= session->db_charset;
1747
1747
/* Execute the query (note that we bypass dispatch_command()) */
1748
1748
const char* found_semicolon= NULL;
1749
mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
1750
log_slow_statement(thd);
1749
mysql_parse(session, session->query, session->query_length, &found_semicolon);
1750
log_slow_statement(session);
1805
1805
else if (expected_error == actual_error ||
1806
1806
ignored_error_code(actual_error))
1808
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
1809
thd->killed= THD::NOT_KILLED;
1808
clear_all_errors(session, const_cast<Relay_log_info*>(rli));
1809
session->killed= Session::NOT_KILLED;
1812
1812
Other cases: mostly we expected no error and get one.
1814
else if (thd->is_slave_error || thd->is_fatal_error)
1814
else if (session->is_slave_error || session->is_fatal_error)
1816
1816
rli->report(ERROR_LEVEL, actual_error,
1817
1817
_("Error '%s' on query. Default database: '%s'. Query: '%s'"),
1818
(actual_error ? thd->main_da.message() :
1818
(actual_error ? session->main_da.message() :
1819
1819
_("unexpected success or fatal error")),
1820
print_slave_db_safe(thd->db), query_arg);
1821
thd->is_slave_error= 1;
1820
print_slave_db_safe(session->db), query_arg);
1821
session->is_slave_error= 1;
1848
1848
pthread_mutex_lock(&LOCK_thread_count);
1850
Probably we have set thd->query, thd->db, thd->catalog to point to places
1850
Probably we have set session->query, session->db, session->catalog to point to places
1851
1851
in the data_buf of this event. Now the event is going to be deleted
1852
probably, so data_buf will be freed, so the thd->... listed above will be
1852
probably, so data_buf will be freed, so the session->... listed above will be
1853
1853
pointers to freed memory.
1854
1854
So we must set them to 0, so that those bad pointers values are not later
1855
1855
used. Note that "cleanup" queries like automatic DROP TEMPORARY Table
1856
1856
don't suffer from these assignments to 0 as DROP TEMPORARY
1857
1857
Table uses the db.table syntax.
1860
thd->set_db(NULL, 0); /* will free the current database */
1861
thd->query= 0; // just to be sure
1862
thd->query_length= 0;
1859
session->catalog= 0;
1860
session->set_db(NULL, 0); /* will free the current database */
1861
session->query= 0; // just to be sure
1862
session->query_length= 0;
1863
1863
pthread_mutex_unlock(&LOCK_thread_count);
1864
close_thread_tables(thd);
1864
close_thread_tables(session);
1866
1866
As a disk space optimization, future masters will not log an event for
1867
1867
LAST_INSERT_ID() if that function returned 0 (and thus they will be able
1868
to replace the THD::stmt_depends_on_first_successful_insert_id_in_prev_stmt
1869
variable by (THD->first_successful_insert_id_in_prev_stmt > 0) ; with the
1868
to replace the Session::stmt_depends_on_first_successful_insert_id_in_prev_stmt
1869
variable by (Session->first_successful_insert_id_in_prev_stmt > 0) ; with the
1870
1870
resetting below we are ready to support that.
1872
thd->first_successful_insert_id_in_prev_stmt_for_binlog= 0;
1873
thd->first_successful_insert_id_in_prev_stmt= 0;
1874
thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
1875
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
1876
return thd->is_slave_error;
1872
session->first_successful_insert_id_in_prev_stmt_for_binlog= 0;
1873
session->first_successful_insert_id_in_prev_stmt= 0;
1874
session->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
1875
free_root(session->mem_root,MYF(MY_KEEP_PREALLOC));
1876
return session->is_slave_error;
1879
1879
int Query_log_event::do_update_pos(Relay_log_info *rli)
2600
2600
Load_log_event::Load_log_event()
2603
Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
2603
Load_log_event::Load_log_event(Session *session_arg, sql_exchange *ex,
2604
2604
const char *db_arg, const char *table_name_arg,
2605
2605
List<Item> &fields_arg,
2606
2606
enum enum_duplicates handle_dup,
2607
2607
bool ignore, bool using_trans)
2609
thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0,
2608
:Log_event(session_arg,
2609
session_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0,
2611
thread_id(thd_arg->thread_id),
2612
slave_proxy_id(thd_arg->variables.pseudo_thread_id),
2611
thread_id(session_arg->thread_id),
2612
slave_proxy_id(session_arg->variables.pseudo_thread_id),
2613
2613
num_fields(0),fields(0),
2614
2614
field_lens(0),field_block_len(0),
2615
2615
table_name(table_name_arg ? table_name_arg : ""),
2818
2818
LEX_STRING new_db;
2819
2819
new_db.length= db_len;
2820
2820
new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
2821
thd->set_db(new_db.str, new_db.length);
2822
assert(thd->query == 0);
2823
thd->query_length= 0; // Should not be needed
2824
thd->is_slave_error= 0;
2825
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
2821
session->set_db(new_db.str, new_db.length);
2822
assert(session->query == 0);
2823
session->query_length= 0; // Should not be needed
2824
session->is_slave_error= 0;
2825
clear_all_errors(session, const_cast<Relay_log_info*>(rli));
2827
2827
/* see Query_log_event::do_apply_event() and BUG#13360 */
2828
2828
assert(!rli->m_table_map.count());
2865
2865
::do_apply_event(), then the companion SET also have so
2866
2866
we don't need to reset_one_shot_variables().
2868
if (rpl_filter->db_ok(thd->db))
2868
if (rpl_filter->db_ok(session->db))
2870
thd->set_time((time_t)when);
2870
session->set_time((time_t)when);
2871
2871
pthread_mutex_lock(&LOCK_thread_count);
2872
thd->query_id = next_query_id();
2872
session->query_id = next_query_id();
2873
2873
pthread_mutex_unlock(&LOCK_thread_count);
2875
Initing thd->row_count is not necessary in theory as this variable has no
2875
Initing session->row_count is not necessary in theory as this variable has no
2876
2876
influence in the case of the slave SQL thread (it is used to generate a
2877
2877
"data truncated" warning but which is absorbed and never gets to the
2878
2878
error log); still we init it to avoid a Valgrind message.
2880
drizzle_reset_errors(thd, 0);
2880
drizzle_reset_errors(session, 0);
2882
2882
TableList tables;
2883
2883
memset(&tables, 0, sizeof(tables));
2884
tables.db= thd->strmake(thd->db, thd->db_length);
2884
tables.db= session->strmake(session->db, session->db_length);
2885
2885
tables.alias = tables.table_name = (char*) table_name;
2886
2886
tables.lock_type = TL_WRITE;
2887
2887
tables.updating= 1;
2889
2889
// the table will be opened in mysql_load
2890
if (rpl_filter->is_on() && !rpl_filter->tables_ok(thd->db, &tables))
2890
if (rpl_filter->is_on() && !rpl_filter->tables_ok(session->db, &tables))
2892
2892
// TODO: this is a bug - this needs to be moved to the I/O thread
2905
2905
Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST
2906
2906
and written to slave's binlog if binlogging is on.
2908
if (!(load_data_query= (char *)thd->alloc(get_query_buffer_length() + 1)))
2908
if (!(load_data_query= (char *)session->alloc(get_query_buffer_length() + 1)))
2911
This will set thd->fatal_error in case of OOM. So we surely will notice
2911
This will set session->fatal_error in case of OOM. So we surely will notice
2912
2912
that something is wrong.
2917
print_query(false, load_data_query, &end, (char **)&thd->lex->fname_start,
2918
(char **)&thd->lex->fname_end);
2917
print_query(false, load_data_query, &end, (char **)&session->lex->fname_start,
2918
(char **)&session->lex->fname_end);
2920
thd->query_length= end - load_data_query;
2921
thd->query= load_data_query;
2920
session->query_length= end - load_data_query;
2921
session->query= load_data_query;
2923
2923
if (sql_ex.opt_flags & REPLACE_FLAG)
2947
2947
handle_dup= DUP_ERROR;
2950
We need to set thd->lex->sql_command and thd->lex->duplicates
2950
We need to set session->lex->sql_command and session->lex->duplicates
2951
2951
since InnoDB tests these variables to decide if this is a LOAD
2952
2952
DATA ... REPLACE INTO ... statement even though mysql_parse()
2953
2953
is not called. This is not needed in 5.0 since there the LOAD
2954
2954
DATA ... statement is replicated using mysql_parse(), which
2955
sets the thd->lex fields correctly.
2955
sets the session->lex fields correctly.
2957
thd->lex->sql_command= SQLCOM_LOAD;
2958
thd->lex->duplicates= handle_dup;
2957
session->lex->sql_command= SQLCOM_LOAD;
2958
session->lex->duplicates= handle_dup;
2960
2960
sql_exchange ex((char*)fname, sql_ex.opt_flags & DUMPFILE_FLAG);
2961
2961
String field_term(sql_ex.field_term,sql_ex.field_term_len,log_cs);
2976
2976
ex.skip_lines = skip_lines;
2977
2977
List<Item> field_list;
2978
thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
2979
set_fields(tables.db, field_list, &thd->lex->select_lex.context);
2980
thd->variables.pseudo_thread_id= thread_id;
2978
session->lex->select_lex.context.resolve_in_table_list_only(&tables);
2979
set_fields(tables.db, field_list, &session->lex->select_lex.context);
2980
session->variables.pseudo_thread_id= thread_id;
2983
// mysql_load will use thd->net to read the file
2984
thd->net.vio = net->vio;
2983
// mysql_load will use session->net to read the file
2984
session->net.vio = net->vio;
2986
2986
Make sure the client does not get confused about the packet sequence
2988
thd->net.pkt_nr = net->pkt_nr;
2988
session->net.pkt_nr = net->pkt_nr;
2991
2991
It is safe to use tmp_list twice because we are not going to
2992
2992
update it inside mysql_load().
2994
2994
List<Item> tmp_list;
2995
if (mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list,
2995
if (mysql_load(session, &ex, &tables, field_list, tmp_list, tmp_list,
2996
2996
handle_dup, ignore, net != 0))
2997
thd->is_slave_error= 1;
2998
if (thd->cuted_fields)
2997
session->is_slave_error= 1;
2998
if (session->cuted_fields)
3000
3000
/* log_pos is the position of the LOAD event in the master log */
3001
3001
sql_print_warning(_("Slave: load data infile on table '%s' at "
3026
const char *remember_db= thd->db;
3025
session->net.vio = 0;
3026
const char *remember_db= session->db;
3027
3027
pthread_mutex_lock(&LOCK_thread_count);
3029
thd->set_db(NULL, 0); /* will free the current database */
3031
thd->query_length= 0;
3028
session->catalog= 0;
3029
session->set_db(NULL, 0); /* will free the current database */
3031
session->query_length= 0;
3032
3032
pthread_mutex_unlock(&LOCK_thread_count);
3033
close_thread_tables(thd);
3033
close_thread_tables(session);
3035
if (thd->is_slave_error)
3035
if (session->is_slave_error)
3037
3037
/* this err/sql_errno code is copy-paste from net_send_error() */
3038
3038
const char *err;
3040
if (thd->is_error())
3040
if (session->is_error())
3042
err= thd->main_da.message();
3043
sql_errno= thd->main_da.sql_errno();
3042
err= session->main_da.message();
3043
sql_errno= session->main_da.sql_errno();
3051
3051
_("Error '%s' running LOAD DATA INFILE on table '%s'. "
3052
3052
"Default database: '%s'"),
3053
3053
err, (char*)table_name, print_slave_db_safe(remember_db));
3054
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
3054
free_root(session->mem_root,MYF(MY_KEEP_PREALLOC));
3057
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
3057
free_root(session->mem_root,MYF(MY_KEEP_PREALLOC));
3059
if (thd->is_fatal_error)
3059
if (session->is_fatal_error)
3062
3062
snprintf(buf, sizeof(buf),
3190
3190
rli->notify_group_relay_log_name_update();
3191
3191
rli->group_relay_log_pos= rli->event_relay_log_pos;
3193
Reset thd->options and sql_mode etc, because this could be the signal of
3193
Reset session->options and sql_mode etc, because this could be the signal of
3194
3194
a master's downgrade from 5.0 to 4.0.
3195
3195
However, no need to reset description_event_for_exec: indeed, if the next
3196
3196
master is 5.0 (even 5.0.1) we will soon get a Format_desc; if the next
3197
3197
master is 4.0 then the events are in the slave's format (conversion).
3199
set_slave_thread_options(thd);
3200
thd->variables.auto_increment_increment=
3201
thd->variables.auto_increment_offset= 1;
3199
set_slave_thread_options(session);
3200
session->variables.auto_increment_increment=
3201
session->variables.auto_increment_offset= 1;
3203
3203
pthread_mutex_unlock(&rli->data_lock);
3204
3204
pthread_cond_broadcast(&rli->data_cond);
3448
3448
int Xid_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
3450
return end_trans(thd, COMMIT);
3450
return end_trans(session, COMMIT);
3453
3453
Log_event::enum_skip_reason
3454
3454
Xid_log_event::do_shall_skip(Relay_log_info *rli)
3456
3456
if (rli->slave_skip_counter > 0) {
3457
thd->options&= ~OPTION_BEGIN;
3457
session->options&= ~OPTION_BEGIN;
3458
3458
return(Log_event::EVENT_SKIP_COUNT);
3460
3460
return(Log_event::do_shall_skip(rli));
3698
3698
Item_func_set_user_var can't substitute something else on its place =>
3699
3699
0 can be passed as last argument (reference on item)
3701
e.fix_fields(thd, 0);
3701
e.fix_fields(session, 0);
3703
3703
A variable can just be considered as a table with
3704
3704
a single record and with a single column. Thus, like
3705
3705
a column value, it could always have IMPLICIT derivation.
3707
3707
e.update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT, 0);
3708
free_root(thd->mem_root,0);
3708
free_root(session->mem_root,0);
3872
3872
Create_file_log_event::
3873
Create_file_log_event(THD* thd_arg, sql_exchange* ex,
3873
Create_file_log_event(Session* session_arg, sql_exchange* ex,
3874
3874
const char* db_arg, const char* table_name_arg,
3875
3875
List<Item>& fields_arg, enum enum_duplicates handle_dup,
3877
3877
unsigned char* block_arg, uint32_t block_len_arg, bool using_trans)
3878
:Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, ignore,
3878
:Load_log_event(session_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, ignore,
3880
3880
fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg),
3881
file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
3881
file_id(session_arg->file_id = mysql_bin_log.next_file_id())
3883
3883
sql_ex.force_new_format();
4015
4015
memset(&file, 0, sizeof(file));
4016
4016
fname_buf= my_stpcpy(proc_info, "Making temp file ");
4017
4017
ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info");
4018
thd->set_proc_info(proc_info);
4018
session->set_proc_info(proc_info);
4019
4019
my_delete(fname_buf, MYF(0)); // old copy may exist already
4020
4020
if ((fd= my_create(fname_buf, CREATE_MODE,
4021
4021
O_WRONLY | O_EXCL,
4081
4081
Append_block_log_event ctor
4084
Append_block_log_event::Append_block_log_event(THD *thd_arg,
4084
Append_block_log_event::Append_block_log_event(Session *session_arg,
4085
4085
const char *db_arg,
4086
4086
unsigned char *block_arg,
4087
4087
uint32_t block_len_arg,
4088
4088
bool using_trans)
4089
:Log_event(thd_arg,0, using_trans), block(block_arg),
4090
block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg)
4089
:Log_event(session_arg,0, using_trans), block(block_arg),
4090
block_len(block_len_arg), file_id(session_arg->file_id), db(db_arg)
4426
4426
**************************************************************************/
4428
4428
Begin_load_query_log_event::
4429
Begin_load_query_log_event(THD* thd_arg, const char* db_arg, unsigned char* block_arg,
4429
Begin_load_query_log_event(Session* session_arg, const char* db_arg, unsigned char* block_arg,
4430
4430
uint32_t block_len_arg, bool using_trans)
4431
:Append_block_log_event(thd_arg, db_arg, block_arg, block_len_arg,
4431
:Append_block_log_event(session_arg, db_arg, block_arg, block_len_arg,
4434
file_id= thd_arg->file_id= mysql_bin_log.next_file_id();
4434
file_id= session_arg->file_id= mysql_bin_log.next_file_id();
4468
4468
Execute_load_query_log_event::
4469
Execute_load_query_log_event(THD *thd_arg, const char* query_arg,
4469
Execute_load_query_log_event(Session *session_arg, const char* query_arg,
4470
4470
ulong query_length_arg, uint32_t fn_pos_start_arg,
4471
4471
uint32_t fn_pos_end_arg,
4472
4472
enum_load_dup_handling dup_handling_arg,
4473
4473
bool using_trans, bool suppress_use,
4474
THD::killed_state killed_err_arg):
4475
Query_log_event(thd_arg, query_arg, query_length_arg, using_trans,
4474
Session::killed_state killed_err_arg):
4475
Query_log_event(session_arg, query_arg, query_length_arg, using_trans,
4476
4476
suppress_use, killed_err_arg),
4477
file_id(thd_arg->file_id), fn_pos_start(fn_pos_start_arg),
4477
file_id(session_arg->file_id), fn_pos_start(fn_pos_start_arg),
4478
4478
fn_pos_end(fn_pos_end_arg), dup_handling(dup_handling_arg)
4697
4697
Rows_log_event member functions
4698
4698
**************************************************************************/
4700
Rows_log_event::Rows_log_event(THD *thd_arg, Table *tbl_arg, ulong tid,
4700
Rows_log_event::Rows_log_event(Session *session_arg, Table *tbl_arg, ulong tid,
4701
4701
MY_BITMAP const *cols, bool is_transactional)
4702
: Log_event(thd_arg, 0, is_transactional),
4702
: Log_event(session_arg, 0, is_transactional),
4703
4703
m_row_count(0),
4704
4704
m_table(tbl_arg),
4705
4705
m_table_id(tid),
4933
4933
assert(get_flags(STMT_END_F));
4935
4935
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
4936
close_thread_tables(thd);
4936
close_thread_tables(session);
4937
session->clear_error();
4942
'thd' has been set by exec_relay_log_event(), just before calling
4942
'session' has been set by exec_relay_log_event(), just before calling
4943
4943
do_apply_event(). We still check here to prevent future coding
4946
assert(rli->sql_thd == thd);
4946
assert(rli->sql_session == session);
4949
4949
If there is no locks taken, this is the first binrow event seen
4971
4971
if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
4972
thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
4972
session->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
4974
thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
4974
session->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
4976
4976
if (get_flags(RELAXED_UNIQUE_CHECKS_F))
4977
thd->options|= OPTION_RELAXED_UNIQUE_CHECKS;
4977
session->options|= OPTION_RELAXED_UNIQUE_CHECKS;
4979
thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
4979
session->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
4980
4980
/* A small test to verify that objects have consistent types */
4981
assert(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
4984
while ((error= lock_tables(thd, rli->tables_to_lock,
4981
assert(sizeof(session->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
4984
while ((error= lock_tables(session, rli->tables_to_lock,
4985
4985
rli->tables_to_lock_count, &need_reopen)))
4987
4987
if (!need_reopen)
4989
if (thd->is_slave_error || thd->is_fatal_error)
4989
if (session->is_slave_error || session->is_fatal_error)
4992
4992
Error reporting borrowed from Query_log_event with many excessive
4993
4993
simplifications (we don't honour --slave-skip-errors)
4995
uint32_t actual_error= thd->main_da.sql_errno();
4995
uint32_t actual_error= session->main_da.sql_errno();
4996
4996
rli->report(ERROR_LEVEL, actual_error,
4997
4997
_("Error '%s' in %s event: when locking tables"),
4999
? thd->main_da.message()
4999
? session->main_da.message()
5000
5000
: _("unexpected success or fatal error")),
5001
5001
get_type_str());
5002
thd->is_fatal_error= 1;
5002
session->is_fatal_error= 1;
5024
5024
NOTE: For this new scheme there should be no pending event:
5025
5025
need to add code to assert that is the case.
5027
thd->binlog_flush_pending_rows_event(false);
5027
session->binlog_flush_pending_rows_event(false);
5028
5028
TableList *tables= rli->tables_to_lock;
5029
close_tables_for_reopen(thd, &tables);
5029
close_tables_for_reopen(session, &tables);
5031
5031
uint32_t tables_count= rli->tables_to_lock_count;
5032
if ((error= open_tables(thd, &tables, &tables_count, 0)))
5032
if ((error= open_tables(session, &tables, &tables_count, 0)))
5034
if (thd->is_slave_error || thd->is_fatal_error)
5034
if (session->is_slave_error || session->is_fatal_error)
5037
5037
Error reporting borrowed from Query_log_event with many excessive
5038
5038
simplifications (we don't honour --slave-skip-errors)
5040
uint32_t actual_error= thd->main_da.sql_errno();
5040
uint32_t actual_error= session->main_da.sql_errno();
5041
5041
rli->report(ERROR_LEVEL, actual_error,
5042
5042
_("Error '%s' on reopening tables"),
5044
? thd->main_da.message()
5044
? session->main_da.message()
5045
5045
: _("unexpected success or fatal error")));
5046
thd->is_slave_error= 1;
5046
session->is_slave_error= 1;
5048
5048
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
5113
5113
TIMESTAMP column to a table with one.
5114
5114
So we call set_time(), like in SBR. Presently it changes nothing.
5116
thd->set_time((time_t)when);
5116
session->set_time((time_t)when);
5118
5118
There are a few flags that are replicated with each row event.
5119
5119
Make sure to set/clear them before executing the main body of
5122
5122
if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
5123
thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
5123
session->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
5125
thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
5125
session->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
5127
5127
if (get_flags(RELAXED_UNIQUE_CHECKS_F))
5128
thd->options|= OPTION_RELAXED_UNIQUE_CHECKS;
5128
session->options|= OPTION_RELAXED_UNIQUE_CHECKS;
5130
thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
5130
session->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
5132
5132
if (slave_allow_batching)
5133
thd->options|= OPTION_ALLOW_BATCH;
5133
session->options|= OPTION_ALLOW_BATCH;
5135
thd->options&= ~OPTION_ALLOW_BATCH;
5135
session->options&= ~OPTION_ALLOW_BATCH;
5137
5137
/* A small test to verify that objects have consistent types */
5138
assert(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
5138
assert(sizeof(session->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
5141
5141
Now we are in a statement and will stay in a statement until we
5256
5256
if (rli->tables_to_lock && get_flags(STMT_END_F))
5257
5257
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
5258
5258
/* reset OPTION_ALLOW_BATCH as not affect later events */
5259
thd->options&= ~OPTION_ALLOW_BATCH;
5259
session->options&= ~OPTION_ALLOW_BATCH;
5262
5262
{ /* error has occured during the transaction */
5263
slave_rows_error_report(ERROR_LEVEL, error, rli, thd, table,
5263
slave_rows_error_report(ERROR_LEVEL, error, rli, session, table,
5264
5264
get_type_str(), RPL_LOG_NAME, (ulong) log_pos);
5359
5359
are involved, commit the transaction and flush the pending event to the
5362
error= ha_autocommit_or_rollback(thd, 0);
5362
error= ha_autocommit_or_rollback(session, 0);
5365
5365
Now what if this is not a transactional engine? we still need to
5366
5366
flush the pending event to the binlog; we did it with
5367
thd->binlog_flush_pending_rows_event(). Note that we imitate
5367
session->binlog_flush_pending_rows_event(). Note that we imitate
5368
5368
what is done for real queries: a call to
5369
5369
ha_autocommit_or_rollback() (sometimes only if involves a
5370
5370
transactional engine), and a call to be sure to have the pending
5374
thd->reset_current_stmt_binlog_row_based();
5374
session->reset_current_stmt_binlog_row_based();
5376
rli->cleanup_context(thd, 0);
5376
rli->cleanup_context(session, 0);
5377
5377
if (error == 0)
5384
5384
rli->stmt_done(log_pos, when);
5387
Clear any errors pushed in thd->net.last_err* if for example "no key
5387
Clear any errors pushed in session->net.last_err* if for example "no key
5388
5388
found" (as this is allowed). This is a safety measure; apparently
5389
5389
those errors (e.g. when executing a Delete_rows_log_event of a
5390
5390
non-existing row, like in rpl_row_mystery22.test,
5391
thd->net.last_error = "Can't find record in 't1'" and last_errno=1032)
5391
session->net.last_error = "Can't find record in 't1'" and last_errno=1032)
5392
5392
do not become visible. We still prefer to wipe them out.
5394
session->clear_error();
5397
5397
rli->report(ERROR_LEVEL, error,
5532
5532
Mats says tbl->s lives longer than this event so it's ok to copy pointers
5533
5533
(tbl->s->db etc) and not pointer content.
5535
Table_map_log_event::Table_map_log_event(THD *thd, Table *tbl, ulong tid,
5535
Table_map_log_event::Table_map_log_event(Session *session, Table *tbl, ulong tid,
5536
5536
bool is_transactional __attribute__((unused)),
5537
5537
uint16_t flags)
5538
: Log_event(thd, 0, true),
5538
: Log_event(session, 0, true),
5540
5540
m_dbnam(tbl->s->db.str),
5541
5541
m_dblen(m_dbnam ? tbl->s->db.length : 0),
5765
open_tables() reads the contents of thd->lex, so they must be
5765
open_tables() reads the contents of session->lex, so they must be
5766
5766
initialized, so we should call lex_start(); to be even safer, we
5767
5767
call mysql_init_query() which does a more complete set of inits.
5770
mysql_reset_thd_for_next_command(thd);
5770
mysql_reset_session_for_next_command(session);
5772
5772
Check if the slave is set to use SBR. If so, it should switch
5773
5773
to using RBR until the end of the "statement", i.e., next
5774
5774
STMT_END_F or next error.
5776
if (!thd->current_stmt_binlog_row_based &&
5777
mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
5776
if (!session->current_stmt_binlog_row_based &&
5777
mysql_bin_log.is_open() && (session->options & OPTION_BIN_LOG))
5779
thd->set_current_stmt_binlog_row_based();
5779
session->set_current_stmt_binlog_row_based();
5787
5787
The creation of a new TableList is used to up-cast the
5788
5788
table_list consisting of RPL_TableList items. This will work
5789
5789
since the only case where the argument to open_tables() is
5790
changed, is when thd->lex->query_tables == table_list, i.e.,
5790
changed, is when session->lex->query_tables == table_list, i.e.,
5791
5791
when the statement requires prelocking. Since this is not
5792
5792
executed when a statement is executed, this case will not occur.
5793
5793
As a precaution, an assertion is added to ensure that the bad
5798
5798
of the pointer to make sure that it's not lost.
5800
5800
uint32_t count;
5801
assert(thd->lex->query_tables != table_list);
5801
assert(session->lex->query_tables != table_list);
5802
5802
TableList *tmp_table_list= table_list;
5803
if ((error= open_tables(thd, &tmp_table_list, &count, 0)))
5803
if ((error= open_tables(session, &tmp_table_list, &count, 0)))
5805
if (thd->is_slave_error || thd->is_fatal_error)
5805
if (session->is_slave_error || session->is_fatal_error)
5808
5808
Error reporting borrowed from Query_log_event with many excessive
5809
5809
simplifications (we don't honour --slave-skip-errors)
5811
uint32_t actual_error= thd->main_da.sql_errno();
5811
uint32_t actual_error= session->main_da.sql_errno();
5812
5812
rli->report(ERROR_LEVEL, actual_error,
5813
5813
_("Error '%s' on opening table `%s`.`%s`"),
5815
? thd->main_da.message()
5815
? session->main_da.message()
5816
5816
: _("unexpected success or fatal error")),
5817
5817
table_list->db, table_list->table_name);
5818
thd->is_slave_error= 1;
5818
session->is_slave_error= 1;
5940
5940
Constructor used to build an event for writing to the binary log.
5942
Write_rows_log_event::Write_rows_log_event(THD *thd_arg, Table *tbl_arg,
5942
Write_rows_log_event::Write_rows_log_event(Session *session_arg, Table *tbl_arg,
5944
5944
bool is_transactional)
5945
: Rows_log_event(thd_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional)
5945
: Rows_log_event(session_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional)
6605
6605
Constructor used to build an event for writing to the binary log.
6608
Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, Table *tbl_arg,
6608
Delete_rows_log_event::Delete_rows_log_event(Session *session_arg, Table *tbl_arg,
6610
6610
bool is_transactional)
6611
: Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
6611
: Rows_log_event(session_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
6682
6682
Constructor used to build an event for writing to the binary log.
6684
Update_rows_log_event::Update_rows_log_event(THD *thd_arg, Table *tbl_arg,
6684
Update_rows_log_event::Update_rows_log_event(Session *session_arg, Table *tbl_arg,
6686
6686
bool is_transactional)
6687
: Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
6687
: Rows_log_event(session_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
6689
6689
init(tbl_arg->write_set);