You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4639 lines
155 KiB

26 years ago
26 years ago
26 years ago
26 years ago
BUG#32407: Impossible to do point-in-time recovery from older binlog Problem: it is unsafe to read base64-printed events without first reading the Format_description_log_event (FD). Currently, mysqlbinlog cannot print the FD. As a side effect, another bug has also been fixed: When mysqlbinlog --start-position=X was specified, no ROLLBACK was printed. I changed this, so that ROLLBACK is always printed. This patch does several things: - Format_description_log_event (FD) now print themselves in base64 format. - mysqlbinlog is now able to print FD events. It has three modes: --base64-output=auto Print row events in base64 output, and print FD event. The FD event is printed even if it is outside the range specified with --start-position, because it would not be safe to read row events otherwise. This is the default. --base64-output=always Like --base64-output=auto, but also print base64 output for query events. This is like the old --base64-output flag, which is also a shorthand for --base64-output=always --base64-output=never Never print base64 output, generate error if row events occur in binlog. This is useful to suppress the FD event in binlogs known not to contain row events (e.g., because BINLOG statement is unsafe, requires root privileges, is not SQL, etc) - the BINLOG statement now handles FD events correctly, by setting the thread's rli's relay log's description_event_for_exec to the loaded event. In fact, executing a BINLOG statement is almost the same as reading an event from a relay log. Before my patch, the code for this was separated (exec_relay_log_event in slave.cc executes events from the relay log, mysql_client_binlog_statement in sql_binlog.cc executes BINLOG statements). I needed to augment mysql_client_binlog_statement to do parts of what exec_relay_log_event does. Hence, I did a small refactoring and moved parts of exec_relay_log_event to a new function, which I named apply_event_and_update_pos. apply_event_and_update_pos is called both from exec_relay_log_event and from mysql_client_binlog_statement. - When a non-FD event is executed in a BINLOG statement, without previously executing a FD event in a BINLOG statement, it generates an error, because that's unsafe. I took a new error code for that: ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS. In order to get a decent error message containing the name of the event, I added the class method char* Log_event::get_type_str(Log_event_type type), which returns a string name for the given Log_event_type. This is just like the existing char* Log_event::get_type_str(), except it is a class method that takes the log event type as parameter. I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(), so that names of old rows event are properly printed. - When reading an event, I added a check that the event type is known by the current Format_description_log_event. Without this, it may crash on bad input (and I was struck by this several times). - I patched the following test cases, which all contain BINLOG statements for row events which must be preceded by BINLOG statements for FD events: - rpl_bug31076 While I was here, I fixed some small things in log_event.cc: - replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places - replaced return by DBUG_VOID_RETURN in one place - The name of the logfile can be '-' to indicate stdin. Before my patch, the code just checked if the first character is '-'; now it does a full strcmp(). Probably, all arguments that begin with a - are already handled somewhere else as flags, but I still think it is better that the code reflects what it is supposed to do, with as little dependencies as possible on other parts of the code. If we one day implement that all command line arguments after -- are files (as most unix tools do), then we need this. I also fixed the following in slave.cc: - next_event() was declared twice, and queue_event was not static but should be static (not used outside the file).
18 years ago
26 years ago
26 years ago
26 years ago
BUG#22864 (Rollback following CREATE... SELECT discards 'CREATE TABLE' from log): When row-based logging is used, the CREATE-SELECT is written as two parts: as a CREATE TABLE statement and as the rows for the table. For both transactional and non-transactional tables, the CREATE TABLE statement was written to the transaction cache, as were the rows, and on statement end, the entire transaction cache was written to the binary log if the table was non-transactional. For transactional tables, the events were kept in the transaction cache until end of transaction (or statement that were not part of a transaction). For the case when AUTOCOMMIT=0 and we are creating a transactional table using a create select, we would then keep the CREATE TABLE statement and the rows for the CREATE-SELECT, while executing the following statements. On a rollback, the transaction cache would then be cleared, which would also remove the CREATE TABLE statement. Hence no table would be created on the slave, while there is an empty table on the master. This relates to BUG#22865 where the table being created exists on the master, but not on the slave during insertion of rows into the newly created table. This occurs since the CREATE TABLE statement were still in the transaction cache until the statement finished executing, and possibly longer if the table was transactional. This patch changes the behaviour of the CREATE-SELECT statement by adding an implicit commit at the end of the statement when creating non-temporary tables. Hence, non-temporary tables will be written to the binary log on completion, and in the even of AUTOCOMMIT=0, a new transaction will be started. Temporary tables do not commit an ongoing transaction: neither as a pre- not a post-commit. The events for both transactional and non-transactional tables are saved in the transaction cache, and written to the binary log at end of the statement.
19 years ago
26 years ago
BUG#32407: Impossible to do point-in-time recovery from older binlog Problem: it is unsafe to read base64-printed events without first reading the Format_description_log_event (FD). Currently, mysqlbinlog cannot print the FD. As a side effect, another bug has also been fixed: When mysqlbinlog --start-position=X was specified, no ROLLBACK was printed. I changed this, so that ROLLBACK is always printed. This patch does several things: - Format_description_log_event (FD) now print themselves in base64 format. - mysqlbinlog is now able to print FD events. It has three modes: --base64-output=auto Print row events in base64 output, and print FD event. The FD event is printed even if it is outside the range specified with --start-position, because it would not be safe to read row events otherwise. This is the default. --base64-output=always Like --base64-output=auto, but also print base64 output for query events. This is like the old --base64-output flag, which is also a shorthand for --base64-output=always --base64-output=never Never print base64 output, generate error if row events occur in binlog. This is useful to suppress the FD event in binlogs known not to contain row events (e.g., because BINLOG statement is unsafe, requires root privileges, is not SQL, etc) - the BINLOG statement now handles FD events correctly, by setting the thread's rli's relay log's description_event_for_exec to the loaded event. In fact, executing a BINLOG statement is almost the same as reading an event from a relay log. Before my patch, the code for this was separated (exec_relay_log_event in slave.cc executes events from the relay log, mysql_client_binlog_statement in sql_binlog.cc executes BINLOG statements). I needed to augment mysql_client_binlog_statement to do parts of what exec_relay_log_event does. Hence, I did a small refactoring and moved parts of exec_relay_log_event to a new function, which I named apply_event_and_update_pos. apply_event_and_update_pos is called both from exec_relay_log_event and from mysql_client_binlog_statement. - When a non-FD event is executed in a BINLOG statement, without previously executing a FD event in a BINLOG statement, it generates an error, because that's unsafe. I took a new error code for that: ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS. In order to get a decent error message containing the name of the event, I added the class method char* Log_event::get_type_str(Log_event_type type), which returns a string name for the given Log_event_type. This is just like the existing char* Log_event::get_type_str(), except it is a class method that takes the log event type as parameter. I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(), so that names of old rows event are properly printed. - When reading an event, I added a check that the event type is known by the current Format_description_log_event. Without this, it may crash on bad input (and I was struck by this several times). - I patched the following test cases, which all contain BINLOG statements for row events which must be preceded by BINLOG statements for FD events: - rpl_bug31076 While I was here, I fixed some small things in log_event.cc: - replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places - replaced return by DBUG_VOID_RETURN in one place - The name of the logfile can be '-' to indicate stdin. Before my patch, the code just checked if the first character is '-'; now it does a full strcmp(). Probably, all arguments that begin with a - are already handled somewhere else as flags, but I still think it is better that the code reflects what it is supposed to do, with as little dependencies as possible on other parts of the code. If we one day implement that all command line arguments after -- are files (as most unix tools do), then we need this. I also fixed the following in slave.cc: - next_event() was declared twice, and queue_event was not static but should be static (not used outside the file).
18 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
24 years ago
23 years ago
23 years ago
24 years ago
24 years ago
23 years ago
23 years ago
23 years ago
26 years ago
26 years ago
23 years ago
23 years ago
WL#3817: Simplify string / memory area types and make things more consistent (first part) The following type conversions was done: - Changed byte to uchar - Changed gptr to uchar* - Change my_string to char * - Change my_size_t to size_t - Change size_s to size_t Removed declaration of byte, gptr, my_string, my_size_t and size_s. Following function parameter changes was done: - All string functions in mysys/strings was changed to use size_t instead of uint for string lengths. - All read()/write() functions changed to use size_t (including vio). - All protocoll functions changed to use size_t instead of uint - Functions that used a pointer to a string length was changed to use size_t* - Changed malloc(), free() and related functions from using gptr to use void * as this requires fewer casts in the code and is more in line with how the standard functions work. - Added extra length argument to dirname_part() to return the length of the created string. - Changed (at least) following functions to take uchar* as argument: - db_dump() - my_net_write() - net_write_command() - net_store_data() - DBUG_DUMP() - decimal2bin() & bin2decimal() - Changed my_compress() and my_uncompress() to use size_t. Changed one argument to my_uncompress() from a pointer to a value as we only return one value (makes function easier to use). - Changed type of 'pack_data' argument to packfrm() to avoid casts. - Changed in readfrm() and writefrom(), ha_discover and handler::discover() the type for argument 'frmdata' to uchar** to avoid casts. - Changed most Field functions to use uchar* instead of char* (reduced a lot of casts). - Changed field->val_xxx(xxx, new_ptr) to take const pointers. Other changes: - Removed a lot of not needed casts - Added a few new cast required by other changes - Added some cast to my_multi_malloc() arguments for safety (as string lengths needs to be uint, not size_t). - Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done explicitely as this conflict was often hided by casting the function to hash_get_key). - Changed some buffers to memory regions to uchar* to avoid casts. - Changed some string lengths from uint to size_t. - Changed field->ptr to be uchar* instead of char*. This allowed us to get rid of a lot of casts. - Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar - Include zlib.h in some files as we needed declaration of crc32() - Changed MY_FILE_ERROR to be (size_t) -1. - Changed many variables to hold the result of my_read() / my_write() to be size_t. This was needed to properly detect errors (which are returned as (size_t) -1). - Removed some very old VMS code - Changed packfrm()/unpackfrm() to not be depending on uint size (portability fix) - Removed windows specific code to restore cursor position as this causes slowdown on windows and we should not mix read() and pread() calls anyway as this is not thread safe. Updated function comment to reflect this. Changed function that depended on original behavior of my_pwrite() to itself restore the cursor position (one such case). - Added some missing checking of return value of malloc(). - Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow. - Changed type of table_def::m_size from my_size_t to ulong to reflect that m_size is the number of elements in the array, not a string/memory length. - Moved THD::max_row_length() to table.cc (as it's not depending on THD). Inlined max_row_length_blob() into this function. - More function comments - Fixed some compiler warnings when compiled without partitions. - Removed setting of LEX_STRING() arguments in declaration (portability fix). - Some trivial indentation/variable name changes. - Some trivial code simplifications: - Replaced some calls to alloc_root + memcpy to use strmake_root()/strdup_root(). - Changed some calls from memdup() to strmake() (Safety fix) - Simpler loops in client-simple.c
19 years ago
WL#3817: Simplify string / memory area types and make things more consistent (first part) The following type conversions was done: - Changed byte to uchar - Changed gptr to uchar* - Change my_string to char * - Change my_size_t to size_t - Change size_s to size_t Removed declaration of byte, gptr, my_string, my_size_t and size_s. Following function parameter changes was done: - All string functions in mysys/strings was changed to use size_t instead of uint for string lengths. - All read()/write() functions changed to use size_t (including vio). - All protocoll functions changed to use size_t instead of uint - Functions that used a pointer to a string length was changed to use size_t* - Changed malloc(), free() and related functions from using gptr to use void * as this requires fewer casts in the code and is more in line with how the standard functions work. - Added extra length argument to dirname_part() to return the length of the created string. - Changed (at least) following functions to take uchar* as argument: - db_dump() - my_net_write() - net_write_command() - net_store_data() - DBUG_DUMP() - decimal2bin() & bin2decimal() - Changed my_compress() and my_uncompress() to use size_t. Changed one argument to my_uncompress() from a pointer to a value as we only return one value (makes function easier to use). - Changed type of 'pack_data' argument to packfrm() to avoid casts. - Changed in readfrm() and writefrom(), ha_discover and handler::discover() the type for argument 'frmdata' to uchar** to avoid casts. - Changed most Field functions to use uchar* instead of char* (reduced a lot of casts). - Changed field->val_xxx(xxx, new_ptr) to take const pointers. Other changes: - Removed a lot of not needed casts - Added a few new cast required by other changes - Added some cast to my_multi_malloc() arguments for safety (as string lengths needs to be uint, not size_t). - Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done explicitely as this conflict was often hided by casting the function to hash_get_key). - Changed some buffers to memory regions to uchar* to avoid casts. - Changed some string lengths from uint to size_t. - Changed field->ptr to be uchar* instead of char*. This allowed us to get rid of a lot of casts. - Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar - Include zlib.h in some files as we needed declaration of crc32() - Changed MY_FILE_ERROR to be (size_t) -1. - Changed many variables to hold the result of my_read() / my_write() to be size_t. This was needed to properly detect errors (which are returned as (size_t) -1). - Removed some very old VMS code - Changed packfrm()/unpackfrm() to not be depending on uint size (portability fix) - Removed windows specific code to restore cursor position as this causes slowdown on windows and we should not mix read() and pread() calls anyway as this is not thread safe. Updated function comment to reflect this. Changed function that depended on original behavior of my_pwrite() to itself restore the cursor position (one such case). - Added some missing checking of return value of malloc(). - Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow. - Changed type of table_def::m_size from my_size_t to ulong to reflect that m_size is the number of elements in the array, not a string/memory length. - Moved THD::max_row_length() to table.cc (as it's not depending on THD). Inlined max_row_length_blob() into this function. - More function comments - Fixed some compiler warnings when compiled without partitions. - Removed setting of LEX_STRING() arguments in declaration (portability fix). - Some trivial indentation/variable name changes. - Some trivial code simplifications: - Replaced some calls to alloc_root + memcpy to use strmake_root()/strdup_root(). - Changed some calls from memdup() to strmake() (Safety fix) - Simpler loops in client-simple.c
19 years ago
26 years ago
25 years ago
25 years ago
26 years ago
25 years ago
25 years ago
25 years ago
26 years ago
26 years ago
25 years ago
25 years ago
25 years ago
25 years ago
26 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
26 years ago
26 years ago
23 years ago
21 years ago
23 years ago
23 years ago
26 years ago
21 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
Prevent bugs by making DBUG_* expressions syntactically equivalent to a single statement. --- Bug#24795: SHOW PROFILE Profiling is only partially functional on some architectures. Where there is no getrusage() system call, presently Null values are returned where it would be required. Notably, Windows needs some love applied to make it as useful. Syntax this adds: SHOW PROFILES SHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n] where "n" is an integer and "types" is zero or many (comma-separated) of "CPU" "MEMORY" (not presently supported) "BLOCK IO" "CONTEXT SWITCHES" "PAGE FAULTS" "IPC" "SWAPS" "SOURCE" "ALL" It also adds a session variable (boolean) "profiling", set to "no" by default, and (integer) profiling_history_size, set to 15 by default. This patch abstracts setting THDs' "proc_info" behind a macro that can be used as a hook into the profiling code when profiling support is compiled in. All future code in this line should use that mechanism for setting thd->proc_info. --- Tests are now set to omit the statistics. --- Adds an Information_schema table, "profiling" for access to "show profile" data. --- Merge zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community-3--bug24795 into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community --- Fix merge problems. --- Fixed one bug in the query_source being NULL. Updated test results. --- Include more thorough profiling tests. Improve support for prepared statements. Use session-specific query IDs, starting at zero. --- Selecting from I_S.profiling is no longer quashed in profiling, as requested by Giuseppe. Limit the size of captured query text. No longer log queries that are zero length.
19 years ago
25 years ago
26 years ago
Prevent bugs by making DBUG_* expressions syntactically equivalent to a single statement. --- Bug#24795: SHOW PROFILE Profiling is only partially functional on some architectures. Where there is no getrusage() system call, presently Null values are returned where it would be required. Notably, Windows needs some love applied to make it as useful. Syntax this adds: SHOW PROFILES SHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n] where "n" is an integer and "types" is zero or many (comma-separated) of "CPU" "MEMORY" (not presently supported) "BLOCK IO" "CONTEXT SWITCHES" "PAGE FAULTS" "IPC" "SWAPS" "SOURCE" "ALL" It also adds a session variable (boolean) "profiling", set to "no" by default, and (integer) profiling_history_size, set to 15 by default. This patch abstracts setting THDs' "proc_info" behind a macro that can be used as a hook into the profiling code when profiling support is compiled in. All future code in this line should use that mechanism for setting thd->proc_info. --- Tests are now set to omit the statistics. --- Adds an Information_schema table, "profiling" for access to "show profile" data. --- Merge zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community-3--bug24795 into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community --- Fix merge problems. --- Fixed one bug in the query_source being NULL. Updated test results. --- Include more thorough profiling tests. Improve support for prepared statements. Use session-specific query IDs, starting at zero. --- Selecting from I_S.profiling is no longer quashed in profiling, as requested by Giuseppe. Limit the size of captured query text. No longer log queries that are zero length.
19 years ago
Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE corrupts a MERGE table Bug 26867 - LOCK TABLES + REPAIR + merge table result in memory/cpu hogging Bug 26377 - Deadlock with MERGE and FLUSH TABLE Bug 25038 - Waiting TRUNCATE Bug 25700 - merge base tables get corrupted by optimize/analyze/repair table Bug 30275 - Merge tables: flush tables or unlock tables causes server to crash Bug 19627 - temporary merge table locking Bug 27660 - Falcon: merge table possible Bug 30273 - merge tables: Can't lock file (errno: 155) The problems were: Bug 26379 - Combination of FLUSH TABLE and REPAIR TABLE corrupts a MERGE table 1. A thread trying to lock a MERGE table performs busy waiting while REPAIR TABLE or a similar table administration task is ongoing on one or more of its MyISAM tables. 2. A thread trying to lock a MERGE table performs busy waiting until all threads that did REPAIR TABLE or similar table administration tasks on one or more of its MyISAM tables in LOCK TABLES segments do UNLOCK TABLES. The difference against problem #1 is that the busy waiting takes place *after* the administration task. It is terminated by UNLOCK TABLES only. 3. Two FLUSH TABLES within a LOCK TABLES segment can invalidate the lock. This does *not* require a MERGE table. The first FLUSH TABLES can be replaced by any statement that requires other threads to reopen the table. In 5.0 and 5.1 a single FLUSH TABLES can provoke the problem. Bug 26867 - LOCK TABLES + REPAIR + merge table result in memory/cpu hogging Trying DML on a MERGE table, which has a child locked and repaired by another thread, made an infinite loop in the server. Bug 26377 - Deadlock with MERGE and FLUSH TABLE Locking a MERGE table and its children in parent-child order and flushing the child deadlocked the server. Bug 25038 - Waiting TRUNCATE Truncating a MERGE child, while the MERGE table was in use, let the truncate fail instead of waiting for the table to become free. Bug 25700 - merge base tables get corrupted by optimize/analyze/repair table Repairing a child of an open MERGE table corrupted the child. It was necessary to FLUSH the child first. Bug 30275 - Merge tables: flush tables or unlock tables causes server to crash Flushing and optimizing locked MERGE children crashed the server. Bug 19627 - temporary merge table locking Use of a temporary MERGE table with non-temporary children could corrupt the children. Temporary tables are never locked. So we do now prohibit non-temporary chidlren of a temporary MERGE table. Bug 27660 - Falcon: merge table possible It was possible to create a MERGE table with non-MyISAM children. Bug 30273 - merge tables: Can't lock file (errno: 155) This was a Windows-only bug. Table administration statements sometimes failed with "Can't lock file (errno: 155)". These bugs are fixed by a new implementation of MERGE table open. When opening a MERGE table in open_tables() we do now add the child tables to the list of tables to be opened by open_tables() (the "query_list"). The children are not opened in the handler at this stage. After opening the parent, open_tables() opens each child from the now extended query_list. When the last child is opened, we remove the children from the query_list again and attach the children to the parent. This behaves similar to the old open. However it does not open the MyISAM tables directly, but grabs them from the already open children. When closing a MERGE table in close_thread_table() we detach the children only. Closing of the children is done implicitly because they are in thd->open_tables. For more detail see the comment at the top of ha_myisammrg.cc. Changed from open_ltable() to open_and_lock_tables() in all places that can be relevant for MERGE tables. The latter can handle tables added to the list on the fly. When open_ltable() was used in a loop over a list of tables, the list must be temporarily terminated after every table for open_and_lock_tables(). table_list->required_type is set to FRMTYPE_TABLE to avoid open of special tables. Handling of derived tables is suppressed. These details are handled by the new function open_n_lock_single_table(), which has nearly the same signature as open_ltable() and can replace it in most cases. In reopen_tables() some of the tables open by a thread can be closed and reopened. When a MERGE child is affected, the parent must be closed and reopened too. Closing of the parent is forced before the first child is closed. Reopen happens in the order of thd->open_tables. MERGE parents do not attach their children automatically at open. This is done after all tables are reopened. So all children are open when attaching them. Special lock handling like mysql_lock_abort() or mysql_lock_remove() needs to be suppressed for MERGE children or forwarded to the parent. This depends on the situation. In loops over all open tables one suppresses child lock handling. When a single table is touched, forwarding is done. Behavioral changes: =================== This patch changes the behavior of temporary MERGE tables. Temporary MERGE must have temporary children. The old behavior was wrong. A temporary table is not locked. Hence even non-temporary children were not locked. See Bug 19627 - temporary merge table locking. You cannot change the union list of a non-temporary MERGE table when LOCK TABLES is in effect. The following does *not* work: CREATE TABLE m1 ... ENGINE=MRG_MYISAM ...; LOCK TABLES t1 WRITE, t2 WRITE, m1 WRITE; ALTER TABLE m1 ... UNION=(t1,t2) ...; However, you can do this with a temporary MERGE table. You cannot create a MERGE table with CREATE ... SELECT, neither as a temporary MERGE table, nor as a non-temporary MERGE table. CREATE TABLE m1 ... ENGINE=MRG_MYISAM ... SELECT ...; Gives error message: table is not BASE TABLE.
18 years ago
WL#3984 (Revise locking of mysql.general_log and mysql.slow_log) Bug#25422 (Hang with log tables) Bug 17876 (Truncating mysql.slow_log in a SP after using cursor locks the thread) Bug 23044 (Warnings on flush of a log table) Bug 29129 (Resetting general_log while the GLOBAL READ LOCK is set causes a deadlock) Prior to this fix, the server would hang when performing concurrent ALTER TABLE or TRUNCATE TABLE statements against the LOG TABLES, which are mysql.general_log and mysql.slow_log. The root cause traces to the following code: in sql_base.cc, open_table() if (table->in_use != thd) { /* wait_for_condition will unlock LOCK_open for us */ wait_for_condition(thd, &LOCK_open, &COND_refresh); } The problem with this code is that the current implementation of the LOGGER creates 'fake' THD objects, like - Log_to_csv_event_handler::general_log_thd - Log_to_csv_event_handler::slow_log_thd which are not associated to a real thread running in the server, so that waiting for these non-existing threads to release table locks cause the dead lock. In general, the design of Log_to_csv_event_handler does not fit into the general architecture of the server, so that the concept of general_log_thd and slow_log_thd has to be abandoned: - this implementation does not work with table locking - it will not work with commands like SHOW PROCESSLIST - having the log tables always opened does not integrate well with DDL operations / FLUSH TABLES / SET GLOBAL READ_ONLY With this patch, the fundamental design of the LOGGER has been changed to: - always open and close a log table when writing a log - remove totally the usage of fake THD objects - clarify how locking of log tables is implemented in general. See WL#3984 for details related to the new locking design. Additional changes (misc bugs exposed and fixed): 1) mysqldump which would ignore some tables in dump_all_tables_in_db(), but forget to ignore the same in dump_all_views_in_db(). 2) mysqldump would also issue an empty "LOCK TABLE" command when all the tables to lock are to be ignored (numrows == 0), instead of not issuing the query. 3) Internal errors handlers could intercept errors but not warnings (see sql_error.cc). 4) Implementing a nested call to open tables, for the performance schema tables, exposed an existing bug in remove_table_from_cache(), which would perform: in_use->some_tables_deleted=1; against another thread, without any consideration about thread locking. This call inside remove_table_from_cache() was not required anyway, since calling mysql_lock_abort() takes care of aborting -- cleanly -- threads that might hold a lock on a table. This line (in_use->some_tables_deleted=1) has been removed.
19 years ago
25 years ago
25 years ago
Prevent bugs by making DBUG_* expressions syntactically equivalent to a single statement. --- Bug#24795: SHOW PROFILE Profiling is only partially functional on some architectures. Where there is no getrusage() system call, presently Null values are returned where it would be required. Notably, Windows needs some love applied to make it as useful. Syntax this adds: SHOW PROFILES SHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n] where "n" is an integer and "types" is zero or many (comma-separated) of "CPU" "MEMORY" (not presently supported) "BLOCK IO" "CONTEXT SWITCHES" "PAGE FAULTS" "IPC" "SWAPS" "SOURCE" "ALL" It also adds a session variable (boolean) "profiling", set to "no" by default, and (integer) profiling_history_size, set to 15 by default. This patch abstracts setting THDs' "proc_info" behind a macro that can be used as a hook into the profiling code when profiling support is compiled in. All future code in this line should use that mechanism for setting thd->proc_info. --- Tests are now set to omit the statistics. --- Adds an Information_schema table, "profiling" for access to "show profile" data. --- Merge zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community-3--bug24795 into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community --- Fix merge problems. --- Fixed one bug in the query_source being NULL. Updated test results. --- Include more thorough profiling tests. Improve support for prepared statements. Use session-specific query IDs, starting at zero. --- Selecting from I_S.profiling is no longer quashed in profiling, as requested by Giuseppe. Limit the size of captured query text. No longer log queries that are zero length.
19 years ago
25 years ago
21 years ago
26 years ago
25 years ago
26 years ago
Prevent bugs by making DBUG_* expressions syntactically equivalent to a single statement. --- Bug#24795: SHOW PROFILE Profiling is only partially functional on some architectures. Where there is no getrusage() system call, presently Null values are returned where it would be required. Notably, Windows needs some love applied to make it as useful. Syntax this adds: SHOW PROFILES SHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n] where "n" is an integer and "types" is zero or many (comma-separated) of "CPU" "MEMORY" (not presently supported) "BLOCK IO" "CONTEXT SWITCHES" "PAGE FAULTS" "IPC" "SWAPS" "SOURCE" "ALL" It also adds a session variable (boolean) "profiling", set to "no" by default, and (integer) profiling_history_size, set to 15 by default. This patch abstracts setting THDs' "proc_info" behind a macro that can be used as a hook into the profiling code when profiling support is compiled in. All future code in this line should use that mechanism for setting thd->proc_info. --- Tests are now set to omit the statistics. --- Adds an Information_schema table, "profiling" for access to "show profile" data. --- Merge zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community-3--bug24795 into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community --- Fix merge problems. --- Fixed one bug in the query_source being NULL. Updated test results. --- Include more thorough profiling tests. Improve support for prepared statements. Use session-specific query IDs, starting at zero. --- Selecting from I_S.profiling is no longer quashed in profiling, as requested by Giuseppe. Limit the size of captured query text. No longer log queries that are zero length.
19 years ago
25 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
25 years ago
25 years ago
26 years ago
23 years ago
23 years ago
26 years ago
26 years ago
26 years ago
23 years ago
23 years ago
26 years ago
WL#3817: Simplify string / memory area types and make things more consistent (first part) The following type conversions was done: - Changed byte to uchar - Changed gptr to uchar* - Change my_string to char * - Change my_size_t to size_t - Change size_s to size_t Removed declaration of byte, gptr, my_string, my_size_t and size_s. Following function parameter changes was done: - All string functions in mysys/strings was changed to use size_t instead of uint for string lengths. - All read()/write() functions changed to use size_t (including vio). - All protocoll functions changed to use size_t instead of uint - Functions that used a pointer to a string length was changed to use size_t* - Changed malloc(), free() and related functions from using gptr to use void * as this requires fewer casts in the code and is more in line with how the standard functions work. - Added extra length argument to dirname_part() to return the length of the created string. - Changed (at least) following functions to take uchar* as argument: - db_dump() - my_net_write() - net_write_command() - net_store_data() - DBUG_DUMP() - decimal2bin() & bin2decimal() - Changed my_compress() and my_uncompress() to use size_t. Changed one argument to my_uncompress() from a pointer to a value as we only return one value (makes function easier to use). - Changed type of 'pack_data' argument to packfrm() to avoid casts. - Changed in readfrm() and writefrom(), ha_discover and handler::discover() the type for argument 'frmdata' to uchar** to avoid casts. - Changed most Field functions to use uchar* instead of char* (reduced a lot of casts). - Changed field->val_xxx(xxx, new_ptr) to take const pointers. Other changes: - Removed a lot of not needed casts - Added a few new cast required by other changes - Added some cast to my_multi_malloc() arguments for safety (as string lengths needs to be uint, not size_t). - Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done explicitely as this conflict was often hided by casting the function to hash_get_key). - Changed some buffers to memory regions to uchar* to avoid casts. - Changed some string lengths from uint to size_t. - Changed field->ptr to be uchar* instead of char*. This allowed us to get rid of a lot of casts. - Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar - Include zlib.h in some files as we needed declaration of crc32() - Changed MY_FILE_ERROR to be (size_t) -1. - Changed many variables to hold the result of my_read() / my_write() to be size_t. This was needed to properly detect errors (which are returned as (size_t) -1). - Removed some very old VMS code - Changed packfrm()/unpackfrm() to not be depending on uint size (portability fix) - Removed windows specific code to restore cursor position as this causes slowdown on windows and we should not mix read() and pread() calls anyway as this is not thread safe. Updated function comment to reflect this. Changed function that depended on original behavior of my_pwrite() to itself restore the cursor position (one such case). - Added some missing checking of return value of malloc(). - Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow. - Changed type of table_def::m_size from my_size_t to ulong to reflect that m_size is the number of elements in the array, not a string/memory length. - Moved THD::max_row_length() to table.cc (as it's not depending on THD). Inlined max_row_length_blob() into this function. - More function comments - Fixed some compiler warnings when compiled without partitions. - Removed setting of LEX_STRING() arguments in declaration (portability fix). - Some trivial indentation/variable name changes. - Some trivial code simplifications: - Replaced some calls to alloc_root + memcpy to use strmake_root()/strdup_root(). - Changed some calls from memdup() to strmake() (Safety fix) - Simpler loops in client-simple.c
19 years ago
WL#3817: Simplify string / memory area types and make things more consistent (first part) The following type conversions was done: - Changed byte to uchar - Changed gptr to uchar* - Change my_string to char * - Change my_size_t to size_t - Change size_s to size_t Removed declaration of byte, gptr, my_string, my_size_t and size_s. Following function parameter changes was done: - All string functions in mysys/strings was changed to use size_t instead of uint for string lengths. - All read()/write() functions changed to use size_t (including vio). - All protocoll functions changed to use size_t instead of uint - Functions that used a pointer to a string length was changed to use size_t* - Changed malloc(), free() and related functions from using gptr to use void * as this requires fewer casts in the code and is more in line with how the standard functions work. - Added extra length argument to dirname_part() to return the length of the created string. - Changed (at least) following functions to take uchar* as argument: - db_dump() - my_net_write() - net_write_command() - net_store_data() - DBUG_DUMP() - decimal2bin() & bin2decimal() - Changed my_compress() and my_uncompress() to use size_t. Changed one argument to my_uncompress() from a pointer to a value as we only return one value (makes function easier to use). - Changed type of 'pack_data' argument to packfrm() to avoid casts. - Changed in readfrm() and writefrom(), ha_discover and handler::discover() the type for argument 'frmdata' to uchar** to avoid casts. - Changed most Field functions to use uchar* instead of char* (reduced a lot of casts). - Changed field->val_xxx(xxx, new_ptr) to take const pointers. Other changes: - Removed a lot of not needed casts - Added a few new cast required by other changes - Added some cast to my_multi_malloc() arguments for safety (as string lengths needs to be uint, not size_t). - Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done explicitely as this conflict was often hided by casting the function to hash_get_key). - Changed some buffers to memory regions to uchar* to avoid casts. - Changed some string lengths from uint to size_t. - Changed field->ptr to be uchar* instead of char*. This allowed us to get rid of a lot of casts. - Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar - Include zlib.h in some files as we needed declaration of crc32() - Changed MY_FILE_ERROR to be (size_t) -1. - Changed many variables to hold the result of my_read() / my_write() to be size_t. This was needed to properly detect errors (which are returned as (size_t) -1). - Removed some very old VMS code - Changed packfrm()/unpackfrm() to not be depending on uint size (portability fix) - Removed windows specific code to restore cursor position as this causes slowdown on windows and we should not mix read() and pread() calls anyway as this is not thread safe. Updated function comment to reflect this. Changed function that depended on original behavior of my_pwrite() to itself restore the cursor position (one such case). - Added some missing checking of return value of malloc(). - Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow. - Changed type of table_def::m_size from my_size_t to ulong to reflect that m_size is the number of elements in the array, not a string/memory length. - Moved THD::max_row_length() to table.cc (as it's not depending on THD). Inlined max_row_length_blob() into this function. - More function comments - Fixed some compiler warnings when compiled without partitions. - Removed setting of LEX_STRING() arguments in declaration (portability fix). - Some trivial indentation/variable name changes. - Some trivial code simplifications: - Replaced some calls to alloc_root + memcpy to use strmake_root()/strdup_root(). - Changed some calls from memdup() to strmake() (Safety fix) - Simpler loops in client-simple.c
19 years ago
WL#3817: Simplify string / memory area types and make things more consistent (first part) The following type conversions was done: - Changed byte to uchar - Changed gptr to uchar* - Change my_string to char * - Change my_size_t to size_t - Change size_s to size_t Removed declaration of byte, gptr, my_string, my_size_t and size_s. Following function parameter changes was done: - All string functions in mysys/strings was changed to use size_t instead of uint for string lengths. - All read()/write() functions changed to use size_t (including vio). - All protocoll functions changed to use size_t instead of uint - Functions that used a pointer to a string length was changed to use size_t* - Changed malloc(), free() and related functions from using gptr to use void * as this requires fewer casts in the code and is more in line with how the standard functions work. - Added extra length argument to dirname_part() to return the length of the created string. - Changed (at least) following functions to take uchar* as argument: - db_dump() - my_net_write() - net_write_command() - net_store_data() - DBUG_DUMP() - decimal2bin() & bin2decimal() - Changed my_compress() and my_uncompress() to use size_t. Changed one argument to my_uncompress() from a pointer to a value as we only return one value (makes function easier to use). - Changed type of 'pack_data' argument to packfrm() to avoid casts. - Changed in readfrm() and writefrom(), ha_discover and handler::discover() the type for argument 'frmdata' to uchar** to avoid casts. - Changed most Field functions to use uchar* instead of char* (reduced a lot of casts). - Changed field->val_xxx(xxx, new_ptr) to take const pointers. Other changes: - Removed a lot of not needed casts - Added a few new cast required by other changes - Added some cast to my_multi_malloc() arguments for safety (as string lengths needs to be uint, not size_t). - Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done explicitely as this conflict was often hided by casting the function to hash_get_key). - Changed some buffers to memory regions to uchar* to avoid casts. - Changed some string lengths from uint to size_t. - Changed field->ptr to be uchar* instead of char*. This allowed us to get rid of a lot of casts. - Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar - Include zlib.h in some files as we needed declaration of crc32() - Changed MY_FILE_ERROR to be (size_t) -1. - Changed many variables to hold the result of my_read() / my_write() to be size_t. This was needed to properly detect errors (which are returned as (size_t) -1). - Removed some very old VMS code - Changed packfrm()/unpackfrm() to not be depending on uint size (portability fix) - Removed windows specific code to restore cursor position as this causes slowdown on windows and we should not mix read() and pread() calls anyway as this is not thread safe. Updated function comment to reflect this. Changed function that depended on original behavior of my_pwrite() to itself restore the cursor position (one such case). - Added some missing checking of return value of malloc(). - Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow. - Changed type of table_def::m_size from my_size_t to ulong to reflect that m_size is the number of elements in the array, not a string/memory length. - Moved THD::max_row_length() to table.cc (as it's not depending on THD). Inlined max_row_length_blob() into this function. - More function comments - Fixed some compiler warnings when compiled without partitions. - Removed setting of LEX_STRING() arguments in declaration (portability fix). - Some trivial indentation/variable name changes. - Some trivial code simplifications: - Replaced some calls to alloc_root + memcpy to use strmake_root()/strdup_root(). - Changed some calls from memdup() to strmake() (Safety fix) - Simpler loops in client-simple.c
19 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
WL#3817: Simplify string / memory area types and make things more consistent (first part) The following type conversions was done: - Changed byte to uchar - Changed gptr to uchar* - Change my_string to char * - Change my_size_t to size_t - Change size_s to size_t Removed declaration of byte, gptr, my_string, my_size_t and size_s. Following function parameter changes was done: - All string functions in mysys/strings was changed to use size_t instead of uint for string lengths. - All read()/write() functions changed to use size_t (including vio). - All protocoll functions changed to use size_t instead of uint - Functions that used a pointer to a string length was changed to use size_t* - Changed malloc(), free() and related functions from using gptr to use void * as this requires fewer casts in the code and is more in line with how the standard functions work. - Added extra length argument to dirname_part() to return the length of the created string. - Changed (at least) following functions to take uchar* as argument: - db_dump() - my_net_write() - net_write_command() - net_store_data() - DBUG_DUMP() - decimal2bin() & bin2decimal() - Changed my_compress() and my_uncompress() to use size_t. Changed one argument to my_uncompress() from a pointer to a value as we only return one value (makes function easier to use). - Changed type of 'pack_data' argument to packfrm() to avoid casts. - Changed in readfrm() and writefrom(), ha_discover and handler::discover() the type for argument 'frmdata' to uchar** to avoid casts. - Changed most Field functions to use uchar* instead of char* (reduced a lot of casts). - Changed field->val_xxx(xxx, new_ptr) to take const pointers. Other changes: - Removed a lot of not needed casts - Added a few new cast required by other changes - Added some cast to my_multi_malloc() arguments for safety (as string lengths needs to be uint, not size_t). - Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done explicitely as this conflict was often hided by casting the function to hash_get_key). - Changed some buffers to memory regions to uchar* to avoid casts. - Changed some string lengths from uint to size_t. - Changed field->ptr to be uchar* instead of char*. This allowed us to get rid of a lot of casts. - Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar - Include zlib.h in some files as we needed declaration of crc32() - Changed MY_FILE_ERROR to be (size_t) -1. - Changed many variables to hold the result of my_read() / my_write() to be size_t. This was needed to properly detect errors (which are returned as (size_t) -1). - Removed some very old VMS code - Changed packfrm()/unpackfrm() to not be depending on uint size (portability fix) - Removed windows specific code to restore cursor position as this causes slowdown on windows and we should not mix read() and pread() calls anyway as this is not thread safe. Updated function comment to reflect this. Changed function that depended on original behavior of my_pwrite() to itself restore the cursor position (one such case). - Added some missing checking of return value of malloc(). - Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow. - Changed type of table_def::m_size from my_size_t to ulong to reflect that m_size is the number of elements in the array, not a string/memory length. - Moved THD::max_row_length() to table.cc (as it's not depending on THD). Inlined max_row_length_blob() into this function. - More function comments - Fixed some compiler warnings when compiled without partitions. - Removed setting of LEX_STRING() arguments in declaration (portability fix). - Some trivial indentation/variable name changes. - Some trivial code simplifications: - Replaced some calls to alloc_root + memcpy to use strmake_root()/strdup_root(). - Changed some calls from memdup() to strmake() (Safety fix) - Simpler loops in client-simple.c
19 years ago
26 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
23 years ago
23 years ago
26 years ago
26 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
26 years ago
Fixed compiler warnings Fixed compile-pentium64 scripts Fixed wrong estimate of update_with_key_prefix in sql-bench Merge bk-internal.mysql.com:/home/bk/mysql-5.1 into mysql.com:/home/my/mysql-5.1 Fixed unsafe define of uint4korr() Fixed that --extern works with mysql-test-run.pl Small trivial cleanups This also fixes a bug in counting number of rows that are updated when we have many simultanous queries Move all connection handling and command exectuion main loop from sql_parse.cc to sql_connection.cc Split handle_one_connection() into reusable sub functions. Split create_new_thread() into reusable sub functions. Added thread_scheduler; Preliminary interface code for future thread_handling code. Use 'my_thread_id' for internal thread id's Make thr_alarm_kill() to depend on thread_id instead of thread Make thr_abort_locks_for_thread() depend on thread_id instead of thread In store_globals(), set my_thread_var->id to be thd->thread_id. Use my_thread_var->id as basis for my_thread_name() The above changes makes the connection we have between THD and threads more soft. Added a lot of DBUG_PRINT() and DBUG_ASSERT() functions Fixed compiler warnings Fixed core dumps when running with --debug Removed setting of signal masks (was never used) Made event code call pthread_exit() (portability fix) Fixed that event code doesn't call DBUG_xxx functions before my_thread_init() is called. Made handling of thread_id and thd->variables.pseudo_thread_id uniform. Removed one common 'not freed memory' warning from mysqltest Fixed a couple of usage of not initialized warnings (unlikely cases) Suppress compiler warnings from bdb and (for the moment) warnings from ndb
19 years ago
26 years ago
26 years ago
26 years ago
26 years ago
Prevent bugs by making DBUG_* expressions syntactically equivalent to a single statement. --- Bug#24795: SHOW PROFILE Profiling is only partially functional on some architectures. Where there is no getrusage() system call, presently Null values are returned where it would be required. Notably, Windows needs some love applied to make it as useful. Syntax this adds: SHOW PROFILES SHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n] where "n" is an integer and "types" is zero or many (comma-separated) of "CPU" "MEMORY" (not presently supported) "BLOCK IO" "CONTEXT SWITCHES" "PAGE FAULTS" "IPC" "SWAPS" "SOURCE" "ALL" It also adds a session variable (boolean) "profiling", set to "no" by default, and (integer) profiling_history_size, set to 15 by default. This patch abstracts setting THDs' "proc_info" behind a macro that can be used as a hook into the profiling code when profiling support is compiled in. All future code in this line should use that mechanism for setting thd->proc_info. --- Tests are now set to omit the statistics. --- Adds an Information_schema table, "profiling" for access to "show profile" data. --- Merge zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community-3--bug24795 into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community --- Fix merge problems. --- Fixed one bug in the query_source being NULL. Updated test results. --- Include more thorough profiling tests. Improve support for prepared statements. Use session-specific query IDs, starting at zero. --- Selecting from I_S.profiling is no longer quashed in profiling, as requested by Giuseppe. Limit the size of captured query text. No longer log queries that are zero length.
19 years ago
Prevent bugs by making DBUG_* expressions syntactically equivalent to a single statement. --- Bug#24795: SHOW PROFILE Profiling is only partially functional on some architectures. Where there is no getrusage() system call, presently Null values are returned where it would be required. Notably, Windows needs some love applied to make it as useful. Syntax this adds: SHOW PROFILES SHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n] where "n" is an integer and "types" is zero or many (comma-separated) of "CPU" "MEMORY" (not presently supported) "BLOCK IO" "CONTEXT SWITCHES" "PAGE FAULTS" "IPC" "SWAPS" "SOURCE" "ALL" It also adds a session variable (boolean) "profiling", set to "no" by default, and (integer) profiling_history_size, set to 15 by default. This patch abstracts setting THDs' "proc_info" behind a macro that can be used as a hook into the profiling code when profiling support is compiled in. All future code in this line should use that mechanism for setting thd->proc_info. --- Tests are now set to omit the statistics. --- Adds an Information_schema table, "profiling" for access to "show profile" data. --- Merge zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community-3--bug24795 into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community --- Fix merge problems. --- Fixed one bug in the query_source being NULL. Updated test results. --- Include more thorough profiling tests. Improve support for prepared statements. Use session-specific query IDs, starting at zero. --- Selecting from I_S.profiling is no longer quashed in profiling, as requested by Giuseppe. Limit the size of captured query text. No longer log queries that are zero length.
19 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
25 years ago
25 years ago
26 years ago
26 years ago
26 years ago
26 years ago
WL#3817: Simplify string / memory area types and make things more consistent (first part) The following type conversions was done: - Changed byte to uchar - Changed gptr to uchar* - Change my_string to char * - Change my_size_t to size_t - Change size_s to size_t Removed declaration of byte, gptr, my_string, my_size_t and size_s. Following function parameter changes was done: - All string functions in mysys/strings was changed to use size_t instead of uint for string lengths. - All read()/write() functions changed to use size_t (including vio). - All protocoll functions changed to use size_t instead of uint - Functions that used a pointer to a string length was changed to use size_t* - Changed malloc(), free() and related functions from using gptr to use void * as this requires fewer casts in the code and is more in line with how the standard functions work. - Added extra length argument to dirname_part() to return the length of the created string. - Changed (at least) following functions to take uchar* as argument: - db_dump() - my_net_write() - net_write_command() - net_store_data() - DBUG_DUMP() - decimal2bin() & bin2decimal() - Changed my_compress() and my_uncompress() to use size_t. Changed one argument to my_uncompress() from a pointer to a value as we only return one value (makes function easier to use). - Changed type of 'pack_data' argument to packfrm() to avoid casts. - Changed in readfrm() and writefrom(), ha_discover and handler::discover() the type for argument 'frmdata' to uchar** to avoid casts. - Changed most Field functions to use uchar* instead of char* (reduced a lot of casts). - Changed field->val_xxx(xxx, new_ptr) to take const pointers. Other changes: - Removed a lot of not needed casts - Added a few new cast required by other changes - Added some cast to my_multi_malloc() arguments for safety (as string lengths needs to be uint, not size_t). - Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done explicitely as this conflict was often hided by casting the function to hash_get_key). - Changed some buffers to memory regions to uchar* to avoid casts. - Changed some string lengths from uint to size_t. - Changed field->ptr to be uchar* instead of char*. This allowed us to get rid of a lot of casts. - Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar - Include zlib.h in some files as we needed declaration of crc32() - Changed MY_FILE_ERROR to be (size_t) -1. - Changed many variables to hold the result of my_read() / my_write() to be size_t. This was needed to properly detect errors (which are returned as (size_t) -1). - Removed some very old VMS code - Changed packfrm()/unpackfrm() to not be depending on uint size (portability fix) - Removed windows specific code to restore cursor position as this causes slowdown on windows and we should not mix read() and pread() calls anyway as this is not thread safe. Updated function comment to reflect this. Changed function that depended on original behavior of my_pwrite() to itself restore the cursor position (one such case). - Added some missing checking of return value of malloc(). - Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow. - Changed type of table_def::m_size from my_size_t to ulong to reflect that m_size is the number of elements in the array, not a string/memory length. - Moved THD::max_row_length() to table.cc (as it's not depending on THD). Inlined max_row_length_blob() into this function. - More function comments - Fixed some compiler warnings when compiled without partitions. - Removed setting of LEX_STRING() arguments in declaration (portability fix). - Some trivial indentation/variable name changes. - Some trivial code simplifications: - Replaced some calls to alloc_root + memcpy to use strmake_root()/strdup_root(). - Changed some calls from memdup() to strmake() (Safety fix) - Simpler loops in client-simple.c
19 years ago
26 years ago
26 years ago
25 years ago
25 years ago
26 years ago
26 years ago
26 years ago
WL#3817: Simplify string / memory area types and make things more consistent (first part) The following type conversions was done: - Changed byte to uchar - Changed gptr to uchar* - Change my_string to char * - Change my_size_t to size_t - Change size_s to size_t Removed declaration of byte, gptr, my_string, my_size_t and size_s. Following function parameter changes was done: - All string functions in mysys/strings was changed to use size_t instead of uint for string lengths. - All read()/write() functions changed to use size_t (including vio). - All protocoll functions changed to use size_t instead of uint - Functions that used a pointer to a string length was changed to use size_t* - Changed malloc(), free() and related functions from using gptr to use void * as this requires fewer casts in the code and is more in line with how the standard functions work. - Added extra length argument to dirname_part() to return the length of the created string. - Changed (at least) following functions to take uchar* as argument: - db_dump() - my_net_write() - net_write_command() - net_store_data() - DBUG_DUMP() - decimal2bin() & bin2decimal() - Changed my_compress() and my_uncompress() to use size_t. Changed one argument to my_uncompress() from a pointer to a value as we only return one value (makes function easier to use). - Changed type of 'pack_data' argument to packfrm() to avoid casts. - Changed in readfrm() and writefrom(), ha_discover and handler::discover() the type for argument 'frmdata' to uchar** to avoid casts. - Changed most Field functions to use uchar* instead of char* (reduced a lot of casts). - Changed field->val_xxx(xxx, new_ptr) to take const pointers. Other changes: - Removed a lot of not needed casts - Added a few new cast required by other changes - Added some cast to my_multi_malloc() arguments for safety (as string lengths needs to be uint, not size_t). - Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done explicitely as this conflict was often hided by casting the function to hash_get_key). - Changed some buffers to memory regions to uchar* to avoid casts. - Changed some string lengths from uint to size_t. - Changed field->ptr to be uchar* instead of char*. This allowed us to get rid of a lot of casts. - Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar - Include zlib.h in some files as we needed declaration of crc32() - Changed MY_FILE_ERROR to be (size_t) -1. - Changed many variables to hold the result of my_read() / my_write() to be size_t. This was needed to properly detect errors (which are returned as (size_t) -1). - Removed some very old VMS code - Changed packfrm()/unpackfrm() to not be depending on uint size (portability fix) - Removed windows specific code to restore cursor position as this causes slowdown on windows and we should not mix read() and pread() calls anyway as this is not thread safe. Updated function comment to reflect this. Changed function that depended on original behavior of my_pwrite() to itself restore the cursor position (one such case). - Added some missing checking of return value of malloc(). - Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow. - Changed type of table_def::m_size from my_size_t to ulong to reflect that m_size is the number of elements in the array, not a string/memory length. - Moved THD::max_row_length() to table.cc (as it's not depending on THD). Inlined max_row_length_blob() into this function. - More function comments - Fixed some compiler warnings when compiled without partitions. - Removed setting of LEX_STRING() arguments in declaration (portability fix). - Some trivial indentation/variable name changes. - Some trivial code simplifications: - Replaced some calls to alloc_root + memcpy to use strmake_root()/strdup_root(). - Changed some calls from memdup() to strmake() (Safety fix) - Simpler loops in client-simple.c
19 years ago
26 years ago
25 years ago
26 years ago
25 years ago
26 years ago
26 years ago
26 years ago
25 years ago
26 years ago
26 years ago
25 years ago
25 years ago
26 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
BUG#32407: Impossible to do point-in-time recovery from older binlog Problem: it is unsafe to read base64-printed events without first reading the Format_description_log_event (FD). Currently, mysqlbinlog cannot print the FD. As a side effect, another bug has also been fixed: When mysqlbinlog --start-position=X was specified, no ROLLBACK was printed. I changed this, so that ROLLBACK is always printed. This patch does several things: - Format_description_log_event (FD) now print themselves in base64 format. - mysqlbinlog is now able to print FD events. It has three modes: --base64-output=auto Print row events in base64 output, and print FD event. The FD event is printed even if it is outside the range specified with --start-position, because it would not be safe to read row events otherwise. This is the default. --base64-output=always Like --base64-output=auto, but also print base64 output for query events. This is like the old --base64-output flag, which is also a shorthand for --base64-output=always --base64-output=never Never print base64 output, generate error if row events occur in binlog. This is useful to suppress the FD event in binlogs known not to contain row events (e.g., because BINLOG statement is unsafe, requires root privileges, is not SQL, etc) - the BINLOG statement now handles FD events correctly, by setting the thread's rli's relay log's description_event_for_exec to the loaded event. In fact, executing a BINLOG statement is almost the same as reading an event from a relay log. Before my patch, the code for this was separated (exec_relay_log_event in slave.cc executes events from the relay log, mysql_client_binlog_statement in sql_binlog.cc executes BINLOG statements). I needed to augment mysql_client_binlog_statement to do parts of what exec_relay_log_event does. Hence, I did a small refactoring and moved parts of exec_relay_log_event to a new function, which I named apply_event_and_update_pos. apply_event_and_update_pos is called both from exec_relay_log_event and from mysql_client_binlog_statement. - When a non-FD event is executed in a BINLOG statement, without previously executing a FD event in a BINLOG statement, it generates an error, because that's unsafe. I took a new error code for that: ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS. In order to get a decent error message containing the name of the event, I added the class method char* Log_event::get_type_str(Log_event_type type), which returns a string name for the given Log_event_type. This is just like the existing char* Log_event::get_type_str(), except it is a class method that takes the log event type as parameter. I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(), so that names of old rows event are properly printed. - When reading an event, I added a check that the event type is known by the current Format_description_log_event. Without this, it may crash on bad input (and I was struck by this several times). - I patched the following test cases, which all contain BINLOG statements for row events which must be preceded by BINLOG statements for FD events: - rpl_bug31076 While I was here, I fixed some small things in log_event.cc: - replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places - replaced return by DBUG_VOID_RETURN in one place - The name of the logfile can be '-' to indicate stdin. Before my patch, the code just checked if the first character is '-'; now it does a full strcmp(). Probably, all arguments that begin with a - are already handled somewhere else as flags, but I still think it is better that the code reflects what it is supposed to do, with as little dependencies as possible on other parts of the code. If we one day implement that all command line arguments after -- are files (as most unix tools do), then we need this. I also fixed the following in slave.cc: - next_event() was declared twice, and queue_event was not static but should be static (not used outside the file).
18 years ago
BUG#32407: Impossible to do point-in-time recovery from older binlog Problem: it is unsafe to read base64-printed events without first reading the Format_description_log_event (FD). Currently, mysqlbinlog cannot print the FD. As a side effect, another bug has also been fixed: When mysqlbinlog --start-position=X was specified, no ROLLBACK was printed. I changed this, so that ROLLBACK is always printed. This patch does several things: - Format_description_log_event (FD) now print themselves in base64 format. - mysqlbinlog is now able to print FD events. It has three modes: --base64-output=auto Print row events in base64 output, and print FD event. The FD event is printed even if it is outside the range specified with --start-position, because it would not be safe to read row events otherwise. This is the default. --base64-output=always Like --base64-output=auto, but also print base64 output for query events. This is like the old --base64-output flag, which is also a shorthand for --base64-output=always --base64-output=never Never print base64 output, generate error if row events occur in binlog. This is useful to suppress the FD event in binlogs known not to contain row events (e.g., because BINLOG statement is unsafe, requires root privileges, is not SQL, etc) - the BINLOG statement now handles FD events correctly, by setting the thread's rli's relay log's description_event_for_exec to the loaded event. In fact, executing a BINLOG statement is almost the same as reading an event from a relay log. Before my patch, the code for this was separated (exec_relay_log_event in slave.cc executes events from the relay log, mysql_client_binlog_statement in sql_binlog.cc executes BINLOG statements). I needed to augment mysql_client_binlog_statement to do parts of what exec_relay_log_event does. Hence, I did a small refactoring and moved parts of exec_relay_log_event to a new function, which I named apply_event_and_update_pos. apply_event_and_update_pos is called both from exec_relay_log_event and from mysql_client_binlog_statement. - When a non-FD event is executed in a BINLOG statement, without previously executing a FD event in a BINLOG statement, it generates an error, because that's unsafe. I took a new error code for that: ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS. In order to get a decent error message containing the name of the event, I added the class method char* Log_event::get_type_str(Log_event_type type), which returns a string name for the given Log_event_type. This is just like the existing char* Log_event::get_type_str(), except it is a class method that takes the log event type as parameter. I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(), so that names of old rows event are properly printed. - When reading an event, I added a check that the event type is known by the current Format_description_log_event. Without this, it may crash on bad input (and I was struck by this several times). - I patched the following test cases, which all contain BINLOG statements for row events which must be preceded by BINLOG statements for FD events: - rpl_bug31076 While I was here, I fixed some small things in log_event.cc: - replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places - replaced return by DBUG_VOID_RETURN in one place - The name of the logfile can be '-' to indicate stdin. Before my patch, the code just checked if the first character is '-'; now it does a full strcmp(). Probably, all arguments that begin with a - are already handled somewhere else as flags, but I still think it is better that the code reflects what it is supposed to do, with as little dependencies as possible on other parts of the code. If we one day implement that all command line arguments after -- are files (as most unix tools do), then we need this. I also fixed the following in slave.cc: - next_event() was declared twice, and queue_event was not static but should be static (not used outside the file).
18 years ago
BUG#32407: Impossible to do point-in-time recovery from older binlog Problem: it is unsafe to read base64-printed events without first reading the Format_description_log_event (FD). Currently, mysqlbinlog cannot print the FD. As a side effect, another bug has also been fixed: When mysqlbinlog --start-position=X was specified, no ROLLBACK was printed. I changed this, so that ROLLBACK is always printed. This patch does several things: - Format_description_log_event (FD) now print themselves in base64 format. - mysqlbinlog is now able to print FD events. It has three modes: --base64-output=auto Print row events in base64 output, and print FD event. The FD event is printed even if it is outside the range specified with --start-position, because it would not be safe to read row events otherwise. This is the default. --base64-output=always Like --base64-output=auto, but also print base64 output for query events. This is like the old --base64-output flag, which is also a shorthand for --base64-output=always --base64-output=never Never print base64 output, generate error if row events occur in binlog. This is useful to suppress the FD event in binlogs known not to contain row events (e.g., because BINLOG statement is unsafe, requires root privileges, is not SQL, etc) - the BINLOG statement now handles FD events correctly, by setting the thread's rli's relay log's description_event_for_exec to the loaded event. In fact, executing a BINLOG statement is almost the same as reading an event from a relay log. Before my patch, the code for this was separated (exec_relay_log_event in slave.cc executes events from the relay log, mysql_client_binlog_statement in sql_binlog.cc executes BINLOG statements). I needed to augment mysql_client_binlog_statement to do parts of what exec_relay_log_event does. Hence, I did a small refactoring and moved parts of exec_relay_log_event to a new function, which I named apply_event_and_update_pos. apply_event_and_update_pos is called both from exec_relay_log_event and from mysql_client_binlog_statement. - When a non-FD event is executed in a BINLOG statement, without previously executing a FD event in a BINLOG statement, it generates an error, because that's unsafe. I took a new error code for that: ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS. In order to get a decent error message containing the name of the event, I added the class method char* Log_event::get_type_str(Log_event_type type), which returns a string name for the given Log_event_type. This is just like the existing char* Log_event::get_type_str(), except it is a class method that takes the log event type as parameter. I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(), so that names of old rows event are properly printed. - When reading an event, I added a check that the event type is known by the current Format_description_log_event. Without this, it may crash on bad input (and I was struck by this several times). - I patched the following test cases, which all contain BINLOG statements for row events which must be preceded by BINLOG statements for FD events: - rpl_bug31076 While I was here, I fixed some small things in log_event.cc: - replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places - replaced return by DBUG_VOID_RETURN in one place - The name of the logfile can be '-' to indicate stdin. Before my patch, the code just checked if the first character is '-'; now it does a full strcmp(). Probably, all arguments that begin with a - are already handled somewhere else as flags, but I still think it is better that the code reflects what it is supposed to do, with as little dependencies as possible on other parts of the code. If we one day implement that all command line arguments after -- are files (as most unix tools do), then we need this. I also fixed the following in slave.cc: - next_event() was declared twice, and queue_event was not static but should be static (not used outside the file).
18 years ago
BUG#32407: Impossible to do point-in-time recovery from older binlog Problem: it is unsafe to read base64-printed events without first reading the Format_description_log_event (FD). Currently, mysqlbinlog cannot print the FD. As a side effect, another bug has also been fixed: When mysqlbinlog --start-position=X was specified, no ROLLBACK was printed. I changed this, so that ROLLBACK is always printed. This patch does several things: - Format_description_log_event (FD) now print themselves in base64 format. - mysqlbinlog is now able to print FD events. It has three modes: --base64-output=auto Print row events in base64 output, and print FD event. The FD event is printed even if it is outside the range specified with --start-position, because it would not be safe to read row events otherwise. This is the default. --base64-output=always Like --base64-output=auto, but also print base64 output for query events. This is like the old --base64-output flag, which is also a shorthand for --base64-output=always --base64-output=never Never print base64 output, generate error if row events occur in binlog. This is useful to suppress the FD event in binlogs known not to contain row events (e.g., because BINLOG statement is unsafe, requires root privileges, is not SQL, etc) - the BINLOG statement now handles FD events correctly, by setting the thread's rli's relay log's description_event_for_exec to the loaded event. In fact, executing a BINLOG statement is almost the same as reading an event from a relay log. Before my patch, the code for this was separated (exec_relay_log_event in slave.cc executes events from the relay log, mysql_client_binlog_statement in sql_binlog.cc executes BINLOG statements). I needed to augment mysql_client_binlog_statement to do parts of what exec_relay_log_event does. Hence, I did a small refactoring and moved parts of exec_relay_log_event to a new function, which I named apply_event_and_update_pos. apply_event_and_update_pos is called both from exec_relay_log_event and from mysql_client_binlog_statement. - When a non-FD event is executed in a BINLOG statement, without previously executing a FD event in a BINLOG statement, it generates an error, because that's unsafe. I took a new error code for that: ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS. In order to get a decent error message containing the name of the event, I added the class method char* Log_event::get_type_str(Log_event_type type), which returns a string name for the given Log_event_type. This is just like the existing char* Log_event::get_type_str(), except it is a class method that takes the log event type as parameter. I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(), so that names of old rows event are properly printed. - When reading an event, I added a check that the event type is known by the current Format_description_log_event. Without this, it may crash on bad input (and I was struck by this several times). - I patched the following test cases, which all contain BINLOG statements for row events which must be preceded by BINLOG statements for FD events: - rpl_bug31076 While I was here, I fixed some small things in log_event.cc: - replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places - replaced return by DBUG_VOID_RETURN in one place - The name of the logfile can be '-' to indicate stdin. Before my patch, the code just checked if the first character is '-'; now it does a full strcmp(). Probably, all arguments that begin with a - are already handled somewhere else as flags, but I still think it is better that the code reflects what it is supposed to do, with as little dependencies as possible on other parts of the code. If we one day implement that all command line arguments after -- are files (as most unix tools do), then we need this. I also fixed the following in slave.cc: - next_event() was declared twice, and queue_event was not static but should be static (not used outside the file).
18 years ago
BUG#32407: Impossible to do point-in-time recovery from older binlog Problem: it is unsafe to read base64-printed events without first reading the Format_description_log_event (FD). Currently, mysqlbinlog cannot print the FD. As a side effect, another bug has also been fixed: When mysqlbinlog --start-position=X was specified, no ROLLBACK was printed. I changed this, so that ROLLBACK is always printed. This patch does several things: - Format_description_log_event (FD) now print themselves in base64 format. - mysqlbinlog is now able to print FD events. It has three modes: --base64-output=auto Print row events in base64 output, and print FD event. The FD event is printed even if it is outside the range specified with --start-position, because it would not be safe to read row events otherwise. This is the default. --base64-output=always Like --base64-output=auto, but also print base64 output for query events. This is like the old --base64-output flag, which is also a shorthand for --base64-output=always --base64-output=never Never print base64 output, generate error if row events occur in binlog. This is useful to suppress the FD event in binlogs known not to contain row events (e.g., because BINLOG statement is unsafe, requires root privileges, is not SQL, etc) - the BINLOG statement now handles FD events correctly, by setting the thread's rli's relay log's description_event_for_exec to the loaded event. In fact, executing a BINLOG statement is almost the same as reading an event from a relay log. Before my patch, the code for this was separated (exec_relay_log_event in slave.cc executes events from the relay log, mysql_client_binlog_statement in sql_binlog.cc executes BINLOG statements). I needed to augment mysql_client_binlog_statement to do parts of what exec_relay_log_event does. Hence, I did a small refactoring and moved parts of exec_relay_log_event to a new function, which I named apply_event_and_update_pos. apply_event_and_update_pos is called both from exec_relay_log_event and from mysql_client_binlog_statement. - When a non-FD event is executed in a BINLOG statement, without previously executing a FD event in a BINLOG statement, it generates an error, because that's unsafe. I took a new error code for that: ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS. In order to get a decent error message containing the name of the event, I added the class method char* Log_event::get_type_str(Log_event_type type), which returns a string name for the given Log_event_type. This is just like the existing char* Log_event::get_type_str(), except it is a class method that takes the log event type as parameter. I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(), so that names of old rows event are properly printed. - When reading an event, I added a check that the event type is known by the current Format_description_log_event. Without this, it may crash on bad input (and I was struck by this several times). - I patched the following test cases, which all contain BINLOG statements for row events which must be preceded by BINLOG statements for FD events: - rpl_bug31076 While I was here, I fixed some small things in log_event.cc: - replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places - replaced return by DBUG_VOID_RETURN in one place - The name of the logfile can be '-' to indicate stdin. Before my patch, the code just checked if the first character is '-'; now it does a full strcmp(). Probably, all arguments that begin with a - are already handled somewhere else as flags, but I still think it is better that the code reflects what it is supposed to do, with as little dependencies as possible on other parts of the code. If we one day implement that all command line arguments after -- are files (as most unix tools do), then we need this. I also fixed the following in slave.cc: - next_event() was declared twice, and queue_event was not static but should be static (not used outside the file).
18 years ago
BUG#32407: Impossible to do point-in-time recovery from older binlog Problem: it is unsafe to read base64-printed events without first reading the Format_description_log_event (FD). Currently, mysqlbinlog cannot print the FD. As a side effect, another bug has also been fixed: When mysqlbinlog --start-position=X was specified, no ROLLBACK was printed. I changed this, so that ROLLBACK is always printed. This patch does several things: - Format_description_log_event (FD) now print themselves in base64 format. - mysqlbinlog is now able to print FD events. It has three modes: --base64-output=auto Print row events in base64 output, and print FD event. The FD event is printed even if it is outside the range specified with --start-position, because it would not be safe to read row events otherwise. This is the default. --base64-output=always Like --base64-output=auto, but also print base64 output for query events. This is like the old --base64-output flag, which is also a shorthand for --base64-output=always --base64-output=never Never print base64 output, generate error if row events occur in binlog. This is useful to suppress the FD event in binlogs known not to contain row events (e.g., because BINLOG statement is unsafe, requires root privileges, is not SQL, etc) - the BINLOG statement now handles FD events correctly, by setting the thread's rli's relay log's description_event_for_exec to the loaded event. In fact, executing a BINLOG statement is almost the same as reading an event from a relay log. Before my patch, the code for this was separated (exec_relay_log_event in slave.cc executes events from the relay log, mysql_client_binlog_statement in sql_binlog.cc executes BINLOG statements). I needed to augment mysql_client_binlog_statement to do parts of what exec_relay_log_event does. Hence, I did a small refactoring and moved parts of exec_relay_log_event to a new function, which I named apply_event_and_update_pos. apply_event_and_update_pos is called both from exec_relay_log_event and from mysql_client_binlog_statement. - When a non-FD event is executed in a BINLOG statement, without previously executing a FD event in a BINLOG statement, it generates an error, because that's unsafe. I took a new error code for that: ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS. In order to get a decent error message containing the name of the event, I added the class method char* Log_event::get_type_str(Log_event_type type), which returns a string name for the given Log_event_type. This is just like the existing char* Log_event::get_type_str(), except it is a class method that takes the log event type as parameter. I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(), so that names of old rows event are properly printed. - When reading an event, I added a check that the event type is known by the current Format_description_log_event. Without this, it may crash on bad input (and I was struck by this several times). - I patched the following test cases, which all contain BINLOG statements for row events which must be preceded by BINLOG statements for FD events: - rpl_bug31076 While I was here, I fixed some small things in log_event.cc: - replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places - replaced return by DBUG_VOID_RETURN in one place - The name of the logfile can be '-' to indicate stdin. Before my patch, the code just checked if the first character is '-'; now it does a full strcmp(). Probably, all arguments that begin with a - are already handled somewhere else as flags, but I still think it is better that the code reflects what it is supposed to do, with as little dependencies as possible on other parts of the code. If we one day implement that all command line arguments after -- are files (as most unix tools do), then we need this. I also fixed the following in slave.cc: - next_event() was declared twice, and queue_event was not static but should be static (not used outside the file).
18 years ago
BUG#32407: Impossible to do point-in-time recovery from older binlog Problem: it is unsafe to read base64-printed events without first reading the Format_description_log_event (FD). Currently, mysqlbinlog cannot print the FD. As a side effect, another bug has also been fixed: When mysqlbinlog --start-position=X was specified, no ROLLBACK was printed. I changed this, so that ROLLBACK is always printed. This patch does several things: - Format_description_log_event (FD) now print themselves in base64 format. - mysqlbinlog is now able to print FD events. It has three modes: --base64-output=auto Print row events in base64 output, and print FD event. The FD event is printed even if it is outside the range specified with --start-position, because it would not be safe to read row events otherwise. This is the default. --base64-output=always Like --base64-output=auto, but also print base64 output for query events. This is like the old --base64-output flag, which is also a shorthand for --base64-output=always --base64-output=never Never print base64 output, generate error if row events occur in binlog. This is useful to suppress the FD event in binlogs known not to contain row events (e.g., because BINLOG statement is unsafe, requires root privileges, is not SQL, etc) - the BINLOG statement now handles FD events correctly, by setting the thread's rli's relay log's description_event_for_exec to the loaded event. In fact, executing a BINLOG statement is almost the same as reading an event from a relay log. Before my patch, the code for this was separated (exec_relay_log_event in slave.cc executes events from the relay log, mysql_client_binlog_statement in sql_binlog.cc executes BINLOG statements). I needed to augment mysql_client_binlog_statement to do parts of what exec_relay_log_event does. Hence, I did a small refactoring and moved parts of exec_relay_log_event to a new function, which I named apply_event_and_update_pos. apply_event_and_update_pos is called both from exec_relay_log_event and from mysql_client_binlog_statement. - When a non-FD event is executed in a BINLOG statement, without previously executing a FD event in a BINLOG statement, it generates an error, because that's unsafe. I took a new error code for that: ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS. In order to get a decent error message containing the name of the event, I added the class method char* Log_event::get_type_str(Log_event_type type), which returns a string name for the given Log_event_type. This is just like the existing char* Log_event::get_type_str(), except it is a class method that takes the log event type as parameter. I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(), so that names of old rows event are properly printed. - When reading an event, I added a check that the event type is known by the current Format_description_log_event. Without this, it may crash on bad input (and I was struck by this several times). - I patched the following test cases, which all contain BINLOG statements for row events which must be preceded by BINLOG statements for FD events: - rpl_bug31076 While I was here, I fixed some small things in log_event.cc: - replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places - replaced return by DBUG_VOID_RETURN in one place - The name of the logfile can be '-' to indicate stdin. Before my patch, the code just checked if the first character is '-'; now it does a full strcmp(). Probably, all arguments that begin with a - are already handled somewhere else as flags, but I still think it is better that the code reflects what it is supposed to do, with as little dependencies as possible on other parts of the code. If we one day implement that all command line arguments after -- are files (as most unix tools do), then we need this. I also fixed the following in slave.cc: - next_event() was declared twice, and queue_event was not static but should be static (not used outside the file).
18 years ago
BUG#32407: Impossible to do point-in-time recovery from older binlog Problem: it is unsafe to read base64-printed events without first reading the Format_description_log_event (FD). Currently, mysqlbinlog cannot print the FD. As a side effect, another bug has also been fixed: When mysqlbinlog --start-position=X was specified, no ROLLBACK was printed. I changed this, so that ROLLBACK is always printed. This patch does several things: - Format_description_log_event (FD) now print themselves in base64 format. - mysqlbinlog is now able to print FD events. It has three modes: --base64-output=auto Print row events in base64 output, and print FD event. The FD event is printed even if it is outside the range specified with --start-position, because it would not be safe to read row events otherwise. This is the default. --base64-output=always Like --base64-output=auto, but also print base64 output for query events. This is like the old --base64-output flag, which is also a shorthand for --base64-output=always --base64-output=never Never print base64 output, generate error if row events occur in binlog. This is useful to suppress the FD event in binlogs known not to contain row events (e.g., because BINLOG statement is unsafe, requires root privileges, is not SQL, etc) - the BINLOG statement now handles FD events correctly, by setting the thread's rli's relay log's description_event_for_exec to the loaded event. In fact, executing a BINLOG statement is almost the same as reading an event from a relay log. Before my patch, the code for this was separated (exec_relay_log_event in slave.cc executes events from the relay log, mysql_client_binlog_statement in sql_binlog.cc executes BINLOG statements). I needed to augment mysql_client_binlog_statement to do parts of what exec_relay_log_event does. Hence, I did a small refactoring and moved parts of exec_relay_log_event to a new function, which I named apply_event_and_update_pos. apply_event_and_update_pos is called both from exec_relay_log_event and from mysql_client_binlog_statement. - When a non-FD event is executed in a BINLOG statement, without previously executing a FD event in a BINLOG statement, it generates an error, because that's unsafe. I took a new error code for that: ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS. In order to get a decent error message containing the name of the event, I added the class method char* Log_event::get_type_str(Log_event_type type), which returns a string name for the given Log_event_type. This is just like the existing char* Log_event::get_type_str(), except it is a class method that takes the log event type as parameter. I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(), so that names of old rows event are properly printed. - When reading an event, I added a check that the event type is known by the current Format_description_log_event. Without this, it may crash on bad input (and I was struck by this several times). - I patched the following test cases, which all contain BINLOG statements for row events which must be preceded by BINLOG statements for FD events: - rpl_bug31076 While I was here, I fixed some small things in log_event.cc: - replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places - replaced return by DBUG_VOID_RETURN in one place - The name of the logfile can be '-' to indicate stdin. Before my patch, the code just checked if the first character is '-'; now it does a full strcmp(). Probably, all arguments that begin with a - are already handled somewhere else as flags, but I still think it is better that the code reflects what it is supposed to do, with as little dependencies as possible on other parts of the code. If we one day implement that all command line arguments after -- are files (as most unix tools do), then we need this. I also fixed the following in slave.cc: - next_event() was declared twice, and queue_event was not static but should be static (not used outside the file).
18 years ago
BUG#32407: Impossible to do point-in-time recovery from older binlog Problem: it is unsafe to read base64-printed events without first reading the Format_description_log_event (FD). Currently, mysqlbinlog cannot print the FD. As a side effect, another bug has also been fixed: When mysqlbinlog --start-position=X was specified, no ROLLBACK was printed. I changed this, so that ROLLBACK is always printed. This patch does several things: - Format_description_log_event (FD) now print themselves in base64 format. - mysqlbinlog is now able to print FD events. It has three modes: --base64-output=auto Print row events in base64 output, and print FD event. The FD event is printed even if it is outside the range specified with --start-position, because it would not be safe to read row events otherwise. This is the default. --base64-output=always Like --base64-output=auto, but also print base64 output for query events. This is like the old --base64-output flag, which is also a shorthand for --base64-output=always --base64-output=never Never print base64 output, generate error if row events occur in binlog. This is useful to suppress the FD event in binlogs known not to contain row events (e.g., because BINLOG statement is unsafe, requires root privileges, is not SQL, etc) - the BINLOG statement now handles FD events correctly, by setting the thread's rli's relay log's description_event_for_exec to the loaded event. In fact, executing a BINLOG statement is almost the same as reading an event from a relay log. Before my patch, the code for this was separated (exec_relay_log_event in slave.cc executes events from the relay log, mysql_client_binlog_statement in sql_binlog.cc executes BINLOG statements). I needed to augment mysql_client_binlog_statement to do parts of what exec_relay_log_event does. Hence, I did a small refactoring and moved parts of exec_relay_log_event to a new function, which I named apply_event_and_update_pos. apply_event_and_update_pos is called both from exec_relay_log_event and from mysql_client_binlog_statement. - When a non-FD event is executed in a BINLOG statement, without previously executing a FD event in a BINLOG statement, it generates an error, because that's unsafe. I took a new error code for that: ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS. In order to get a decent error message containing the name of the event, I added the class method char* Log_event::get_type_str(Log_event_type type), which returns a string name for the given Log_event_type. This is just like the existing char* Log_event::get_type_str(), except it is a class method that takes the log event type as parameter. I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(), so that names of old rows event are properly printed. - When reading an event, I added a check that the event type is known by the current Format_description_log_event. Without this, it may crash on bad input (and I was struck by this several times). - I patched the following test cases, which all contain BINLOG statements for row events which must be preceded by BINLOG statements for FD events: - rpl_bug31076 While I was here, I fixed some small things in log_event.cc: - replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places - replaced return by DBUG_VOID_RETURN in one place - The name of the logfile can be '-' to indicate stdin. Before my patch, the code just checked if the first character is '-'; now it does a full strcmp(). Probably, all arguments that begin with a - are already handled somewhere else as flags, but I still think it is better that the code reflects what it is supposed to do, with as little dependencies as possible on other parts of the code. If we one day implement that all command line arguments after -- are files (as most unix tools do), then we need this. I also fixed the following in slave.cc: - next_event() was declared twice, and queue_event was not static but should be static (not used outside the file).
18 years ago
26 years ago
BUG#32407: Impossible to do point-in-time recovery from older binlog Problem: it is unsafe to read base64-printed events without first reading the Format_description_log_event (FD). Currently, mysqlbinlog cannot print the FD. As a side effect, another bug has also been fixed: When mysqlbinlog --start-position=X was specified, no ROLLBACK was printed. I changed this, so that ROLLBACK is always printed. This patch does several things: - Format_description_log_event (FD) now print themselves in base64 format. - mysqlbinlog is now able to print FD events. It has three modes: --base64-output=auto Print row events in base64 output, and print FD event. The FD event is printed even if it is outside the range specified with --start-position, because it would not be safe to read row events otherwise. This is the default. --base64-output=always Like --base64-output=auto, but also print base64 output for query events. This is like the old --base64-output flag, which is also a shorthand for --base64-output=always --base64-output=never Never print base64 output, generate error if row events occur in binlog. This is useful to suppress the FD event in binlogs known not to contain row events (e.g., because BINLOG statement is unsafe, requires root privileges, is not SQL, etc) - the BINLOG statement now handles FD events correctly, by setting the thread's rli's relay log's description_event_for_exec to the loaded event. In fact, executing a BINLOG statement is almost the same as reading an event from a relay log. Before my patch, the code for this was separated (exec_relay_log_event in slave.cc executes events from the relay log, mysql_client_binlog_statement in sql_binlog.cc executes BINLOG statements). I needed to augment mysql_client_binlog_statement to do parts of what exec_relay_log_event does. Hence, I did a small refactoring and moved parts of exec_relay_log_event to a new function, which I named apply_event_and_update_pos. apply_event_and_update_pos is called both from exec_relay_log_event and from mysql_client_binlog_statement. - When a non-FD event is executed in a BINLOG statement, without previously executing a FD event in a BINLOG statement, it generates an error, because that's unsafe. I took a new error code for that: ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS. In order to get a decent error message containing the name of the event, I added the class method char* Log_event::get_type_str(Log_event_type type), which returns a string name for the given Log_event_type. This is just like the existing char* Log_event::get_type_str(), except it is a class method that takes the log event type as parameter. I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(), so that names of old rows event are properly printed. - When reading an event, I added a check that the event type is known by the current Format_description_log_event. Without this, it may crash on bad input (and I was struck by this several times). - I patched the following test cases, which all contain BINLOG statements for row events which must be preceded by BINLOG statements for FD events: - rpl_bug31076 While I was here, I fixed some small things in log_event.cc: - replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places - replaced return by DBUG_VOID_RETURN in one place - The name of the logfile can be '-' to indicate stdin. Before my patch, the code just checked if the first character is '-'; now it does a full strcmp(). Probably, all arguments that begin with a - are already handled somewhere else as flags, but I still think it is better that the code reflects what it is supposed to do, with as little dependencies as possible on other parts of the code. If we one day implement that all command line arguments after -- are files (as most unix tools do), then we need this. I also fixed the following in slave.cc: - next_event() was declared twice, and queue_event was not static but should be static (not used outside the file).
18 years ago
BUG#32407: Impossible to do point-in-time recovery from older binlog Problem: it is unsafe to read base64-printed events without first reading the Format_description_log_event (FD). Currently, mysqlbinlog cannot print the FD. As a side effect, another bug has also been fixed: When mysqlbinlog --start-position=X was specified, no ROLLBACK was printed. I changed this, so that ROLLBACK is always printed. This patch does several things: - Format_description_log_event (FD) now print themselves in base64 format. - mysqlbinlog is now able to print FD events. It has three modes: --base64-output=auto Print row events in base64 output, and print FD event. The FD event is printed even if it is outside the range specified with --start-position, because it would not be safe to read row events otherwise. This is the default. --base64-output=always Like --base64-output=auto, but also print base64 output for query events. This is like the old --base64-output flag, which is also a shorthand for --base64-output=always --base64-output=never Never print base64 output, generate error if row events occur in binlog. This is useful to suppress the FD event in binlogs known not to contain row events (e.g., because BINLOG statement is unsafe, requires root privileges, is not SQL, etc) - the BINLOG statement now handles FD events correctly, by setting the thread's rli's relay log's description_event_for_exec to the loaded event. In fact, executing a BINLOG statement is almost the same as reading an event from a relay log. Before my patch, the code for this was separated (exec_relay_log_event in slave.cc executes events from the relay log, mysql_client_binlog_statement in sql_binlog.cc executes BINLOG statements). I needed to augment mysql_client_binlog_statement to do parts of what exec_relay_log_event does. Hence, I did a small refactoring and moved parts of exec_relay_log_event to a new function, which I named apply_event_and_update_pos. apply_event_and_update_pos is called both from exec_relay_log_event and from mysql_client_binlog_statement. - When a non-FD event is executed in a BINLOG statement, without previously executing a FD event in a BINLOG statement, it generates an error, because that's unsafe. I took a new error code for that: ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS. In order to get a decent error message containing the name of the event, I added the class method char* Log_event::get_type_str(Log_event_type type), which returns a string name for the given Log_event_type. This is just like the existing char* Log_event::get_type_str(), except it is a class method that takes the log event type as parameter. I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(), so that names of old rows event are properly printed. - When reading an event, I added a check that the event type is known by the current Format_description_log_event. Without this, it may crash on bad input (and I was struck by this several times). - I patched the following test cases, which all contain BINLOG statements for row events which must be preceded by BINLOG statements for FD events: - rpl_bug31076 While I was here, I fixed some small things in log_event.cc: - replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places - replaced return by DBUG_VOID_RETURN in one place - The name of the logfile can be '-' to indicate stdin. Before my patch, the code just checked if the first character is '-'; now it does a full strcmp(). Probably, all arguments that begin with a - are already handled somewhere else as flags, but I still think it is better that the code reflects what it is supposed to do, with as little dependencies as possible on other parts of the code. If we one day implement that all command line arguments after -- are files (as most unix tools do), then we need this. I also fixed the following in slave.cc: - next_event() was declared twice, and queue_event was not static but should be static (not used outside the file).
18 years ago
BUG#32407: Impossible to do point-in-time recovery from older binlog Problem: it is unsafe to read base64-printed events without first reading the Format_description_log_event (FD). Currently, mysqlbinlog cannot print the FD. As a side effect, another bug has also been fixed: When mysqlbinlog --start-position=X was specified, no ROLLBACK was printed. I changed this, so that ROLLBACK is always printed. This patch does several things: - Format_description_log_event (FD) now print themselves in base64 format. - mysqlbinlog is now able to print FD events. It has three modes: --base64-output=auto Print row events in base64 output, and print FD event. The FD event is printed even if it is outside the range specified with --start-position, because it would not be safe to read row events otherwise. This is the default. --base64-output=always Like --base64-output=auto, but also print base64 output for query events. This is like the old --base64-output flag, which is also a shorthand for --base64-output=always --base64-output=never Never print base64 output, generate error if row events occur in binlog. This is useful to suppress the FD event in binlogs known not to contain row events (e.g., because BINLOG statement is unsafe, requires root privileges, is not SQL, etc) - the BINLOG statement now handles FD events correctly, by setting the thread's rli's relay log's description_event_for_exec to the loaded event. In fact, executing a BINLOG statement is almost the same as reading an event from a relay log. Before my patch, the code for this was separated (exec_relay_log_event in slave.cc executes events from the relay log, mysql_client_binlog_statement in sql_binlog.cc executes BINLOG statements). I needed to augment mysql_client_binlog_statement to do parts of what exec_relay_log_event does. Hence, I did a small refactoring and moved parts of exec_relay_log_event to a new function, which I named apply_event_and_update_pos. apply_event_and_update_pos is called both from exec_relay_log_event and from mysql_client_binlog_statement. - When a non-FD event is executed in a BINLOG statement, without previously executing a FD event in a BINLOG statement, it generates an error, because that's unsafe. I took a new error code for that: ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS. In order to get a decent error message containing the name of the event, I added the class method char* Log_event::get_type_str(Log_event_type type), which returns a string name for the given Log_event_type. This is just like the existing char* Log_event::get_type_str(), except it is a class method that takes the log event type as parameter. I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(), so that names of old rows event are properly printed. - When reading an event, I added a check that the event type is known by the current Format_description_log_event. Without this, it may crash on bad input (and I was struck by this several times). - I patched the following test cases, which all contain BINLOG statements for row events which must be preceded by BINLOG statements for FD events: - rpl_bug31076 While I was here, I fixed some small things in log_event.cc: - replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places - replaced return by DBUG_VOID_RETURN in one place - The name of the logfile can be '-' to indicate stdin. Before my patch, the code just checked if the first character is '-'; now it does a full strcmp(). Probably, all arguments that begin with a - are already handled somewhere else as flags, but I still think it is better that the code reflects what it is supposed to do, with as little dependencies as possible on other parts of the code. If we one day implement that all command line arguments after -- are files (as most unix tools do), then we need this. I also fixed the following in slave.cc: - next_event() was declared twice, and queue_event was not static but should be static (not used outside the file).
18 years ago
BUG#32407: Impossible to do point-in-time recovery from older binlog Problem: it is unsafe to read base64-printed events without first reading the Format_description_log_event (FD). Currently, mysqlbinlog cannot print the FD. As a side effect, another bug has also been fixed: When mysqlbinlog --start-position=X was specified, no ROLLBACK was printed. I changed this, so that ROLLBACK is always printed. This patch does several things: - Format_description_log_event (FD) now print themselves in base64 format. - mysqlbinlog is now able to print FD events. It has three modes: --base64-output=auto Print row events in base64 output, and print FD event. The FD event is printed even if it is outside the range specified with --start-position, because it would not be safe to read row events otherwise. This is the default. --base64-output=always Like --base64-output=auto, but also print base64 output for query events. This is like the old --base64-output flag, which is also a shorthand for --base64-output=always --base64-output=never Never print base64 output, generate error if row events occur in binlog. This is useful to suppress the FD event in binlogs known not to contain row events (e.g., because BINLOG statement is unsafe, requires root privileges, is not SQL, etc) - the BINLOG statement now handles FD events correctly, by setting the thread's rli's relay log's description_event_for_exec to the loaded event. In fact, executing a BINLOG statement is almost the same as reading an event from a relay log. Before my patch, the code for this was separated (exec_relay_log_event in slave.cc executes events from the relay log, mysql_client_binlog_statement in sql_binlog.cc executes BINLOG statements). I needed to augment mysql_client_binlog_statement to do parts of what exec_relay_log_event does. Hence, I did a small refactoring and moved parts of exec_relay_log_event to a new function, which I named apply_event_and_update_pos. apply_event_and_update_pos is called both from exec_relay_log_event and from mysql_client_binlog_statement. - When a non-FD event is executed in a BINLOG statement, without previously executing a FD event in a BINLOG statement, it generates an error, because that's unsafe. I took a new error code for that: ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS. In order to get a decent error message containing the name of the event, I added the class method char* Log_event::get_type_str(Log_event_type type), which returns a string name for the given Log_event_type. This is just like the existing char* Log_event::get_type_str(), except it is a class method that takes the log event type as parameter. I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(), so that names of old rows event are properly printed. - When reading an event, I added a check that the event type is known by the current Format_description_log_event. Without this, it may crash on bad input (and I was struck by this several times). - I patched the following test cases, which all contain BINLOG statements for row events which must be preceded by BINLOG statements for FD events: - rpl_bug31076 While I was here, I fixed some small things in log_event.cc: - replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places - replaced return by DBUG_VOID_RETURN in one place - The name of the logfile can be '-' to indicate stdin. Before my patch, the code just checked if the first character is '-'; now it does a full strcmp(). Probably, all arguments that begin with a - are already handled somewhere else as flags, but I still think it is better that the code reflects what it is supposed to do, with as little dependencies as possible on other parts of the code. If we one day implement that all command line arguments after -- are files (as most unix tools do), then we need this. I also fixed the following in slave.cc: - next_event() was declared twice, and queue_event was not static but should be static (not used outside the file).
18 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
BUG#32407: Impossible to do point-in-time recovery from older binlog Problem: it is unsafe to read base64-printed events without first reading the Format_description_log_event (FD). Currently, mysqlbinlog cannot print the FD. As a side effect, another bug has also been fixed: When mysqlbinlog --start-position=X was specified, no ROLLBACK was printed. I changed this, so that ROLLBACK is always printed. This patch does several things: - Format_description_log_event (FD) now print themselves in base64 format. - mysqlbinlog is now able to print FD events. It has three modes: --base64-output=auto Print row events in base64 output, and print FD event. The FD event is printed even if it is outside the range specified with --start-position, because it would not be safe to read row events otherwise. This is the default. --base64-output=always Like --base64-output=auto, but also print base64 output for query events. This is like the old --base64-output flag, which is also a shorthand for --base64-output=always --base64-output=never Never print base64 output, generate error if row events occur in binlog. This is useful to suppress the FD event in binlogs known not to contain row events (e.g., because BINLOG statement is unsafe, requires root privileges, is not SQL, etc) - the BINLOG statement now handles FD events correctly, by setting the thread's rli's relay log's description_event_for_exec to the loaded event. In fact, executing a BINLOG statement is almost the same as reading an event from a relay log. Before my patch, the code for this was separated (exec_relay_log_event in slave.cc executes events from the relay log, mysql_client_binlog_statement in sql_binlog.cc executes BINLOG statements). I needed to augment mysql_client_binlog_statement to do parts of what exec_relay_log_event does. Hence, I did a small refactoring and moved parts of exec_relay_log_event to a new function, which I named apply_event_and_update_pos. apply_event_and_update_pos is called both from exec_relay_log_event and from mysql_client_binlog_statement. - When a non-FD event is executed in a BINLOG statement, without previously executing a FD event in a BINLOG statement, it generates an error, because that's unsafe. I took a new error code for that: ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS. In order to get a decent error message containing the name of the event, I added the class method char* Log_event::get_type_str(Log_event_type type), which returns a string name for the given Log_event_type. This is just like the existing char* Log_event::get_type_str(), except it is a class method that takes the log event type as parameter. I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(), so that names of old rows event are properly printed. - When reading an event, I added a check that the event type is known by the current Format_description_log_event. Without this, it may crash on bad input (and I was struck by this several times). - I patched the following test cases, which all contain BINLOG statements for row events which must be preceded by BINLOG statements for FD events: - rpl_bug31076 While I was here, I fixed some small things in log_event.cc: - replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places - replaced return by DBUG_VOID_RETURN in one place - The name of the logfile can be '-' to indicate stdin. Before my patch, the code just checked if the first character is '-'; now it does a full strcmp(). Probably, all arguments that begin with a - are already handled somewhere else as flags, but I still think it is better that the code reflects what it is supposed to do, with as little dependencies as possible on other parts of the code. If we one day implement that all command line arguments after -- are files (as most unix tools do), then we need this. I also fixed the following in slave.cc: - next_event() was declared twice, and queue_event was not static but should be static (not used outside the file).
18 years ago
20 years ago
25 years ago
26 years ago
26 years ago
26 years ago
26 years ago
25 years ago
25 years ago
Prevent bugs by making DBUG_* expressions syntactically equivalent to a single statement. --- Bug#24795: SHOW PROFILE Profiling is only partially functional on some architectures. Where there is no getrusage() system call, presently Null values are returned where it would be required. Notably, Windows needs some love applied to make it as useful. Syntax this adds: SHOW PROFILES SHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n] where "n" is an integer and "types" is zero or many (comma-separated) of "CPU" "MEMORY" (not presently supported) "BLOCK IO" "CONTEXT SWITCHES" "PAGE FAULTS" "IPC" "SWAPS" "SOURCE" "ALL" It also adds a session variable (boolean) "profiling", set to "no" by default, and (integer) profiling_history_size, set to 15 by default. This patch abstracts setting THDs' "proc_info" behind a macro that can be used as a hook into the profiling code when profiling support is compiled in. All future code in this line should use that mechanism for setting thd->proc_info. --- Tests are now set to omit the statistics. --- Adds an Information_schema table, "profiling" for access to "show profile" data. --- Merge zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community-3--bug24795 into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community --- Fix merge problems. --- Fixed one bug in the query_source being NULL. Updated test results. --- Include more thorough profiling tests. Improve support for prepared statements. Use session-specific query IDs, starting at zero. --- Selecting from I_S.profiling is no longer quashed in profiling, as requested by Giuseppe. Limit the size of captured query text. No longer log queries that are zero length.
19 years ago
Prevent bugs by making DBUG_* expressions syntactically equivalent to a single statement. --- Bug#24795: SHOW PROFILE Profiling is only partially functional on some architectures. Where there is no getrusage() system call, presently Null values are returned where it would be required. Notably, Windows needs some love applied to make it as useful. Syntax this adds: SHOW PROFILES SHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n] where "n" is an integer and "types" is zero or many (comma-separated) of "CPU" "MEMORY" (not presently supported) "BLOCK IO" "CONTEXT SWITCHES" "PAGE FAULTS" "IPC" "SWAPS" "SOURCE" "ALL" It also adds a session variable (boolean) "profiling", set to "no" by default, and (integer) profiling_history_size, set to 15 by default. This patch abstracts setting THDs' "proc_info" behind a macro that can be used as a hook into the profiling code when profiling support is compiled in. All future code in this line should use that mechanism for setting thd->proc_info. --- Tests are now set to omit the statistics. --- Adds an Information_schema table, "profiling" for access to "show profile" data. --- Merge zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community-3--bug24795 into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community --- Fix merge problems. --- Fixed one bug in the query_source being NULL. Updated test results. --- Include more thorough profiling tests. Improve support for prepared statements. Use session-specific query IDs, starting at zero. --- Selecting from I_S.profiling is no longer quashed in profiling, as requested by Giuseppe. Limit the size of captured query text. No longer log queries that are zero length.
19 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
Prevent bugs by making DBUG_* expressions syntactically equivalent to a single statement. --- Bug#24795: SHOW PROFILE Profiling is only partially functional on some architectures. Where there is no getrusage() system call, presently Null values are returned where it would be required. Notably, Windows needs some love applied to make it as useful. Syntax this adds: SHOW PROFILES SHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n] where "n" is an integer and "types" is zero or many (comma-separated) of "CPU" "MEMORY" (not presently supported) "BLOCK IO" "CONTEXT SWITCHES" "PAGE FAULTS" "IPC" "SWAPS" "SOURCE" "ALL" It also adds a session variable (boolean) "profiling", set to "no" by default, and (integer) profiling_history_size, set to 15 by default. This patch abstracts setting THDs' "proc_info" behind a macro that can be used as a hook into the profiling code when profiling support is compiled in. All future code in this line should use that mechanism for setting thd->proc_info. --- Tests are now set to omit the statistics. --- Adds an Information_schema table, "profiling" for access to "show profile" data. --- Merge zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community-3--bug24795 into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community --- Fix merge problems. --- Fixed one bug in the query_source being NULL. Updated test results. --- Include more thorough profiling tests. Improve support for prepared statements. Use session-specific query IDs, starting at zero. --- Selecting from I_S.profiling is no longer quashed in profiling, as requested by Giuseppe. Limit the size of captured query text. No longer log queries that are zero length.
19 years ago
25 years ago
Prevent bugs by making DBUG_* expressions syntactically equivalent to a single statement. --- Bug#24795: SHOW PROFILE Profiling is only partially functional on some architectures. Where there is no getrusage() system call, presently Null values are returned where it would be required. Notably, Windows needs some love applied to make it as useful. Syntax this adds: SHOW PROFILES SHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n] where "n" is an integer and "types" is zero or many (comma-separated) of "CPU" "MEMORY" (not presently supported) "BLOCK IO" "CONTEXT SWITCHES" "PAGE FAULTS" "IPC" "SWAPS" "SOURCE" "ALL" It also adds a session variable (boolean) "profiling", set to "no" by default, and (integer) profiling_history_size, set to 15 by default. This patch abstracts setting THDs' "proc_info" behind a macro that can be used as a hook into the profiling code when profiling support is compiled in. All future code in this line should use that mechanism for setting thd->proc_info. --- Tests are now set to omit the statistics. --- Adds an Information_schema table, "profiling" for access to "show profile" data. --- Merge zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community-3--bug24795 into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community --- Fix merge problems. --- Fixed one bug in the query_source being NULL. Updated test results. --- Include more thorough profiling tests. Improve support for prepared statements. Use session-specific query IDs, starting at zero. --- Selecting from I_S.profiling is no longer quashed in profiling, as requested by Giuseppe. Limit the size of captured query text. No longer log queries that are zero length.
19 years ago
26 years ago
Prevent bugs by making DBUG_* expressions syntactically equivalent to a single statement. --- Bug#24795: SHOW PROFILE Profiling is only partially functional on some architectures. Where there is no getrusage() system call, presently Null values are returned where it would be required. Notably, Windows needs some love applied to make it as useful. Syntax this adds: SHOW PROFILES SHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n] where "n" is an integer and "types" is zero or many (comma-separated) of "CPU" "MEMORY" (not presently supported) "BLOCK IO" "CONTEXT SWITCHES" "PAGE FAULTS" "IPC" "SWAPS" "SOURCE" "ALL" It also adds a session variable (boolean) "profiling", set to "no" by default, and (integer) profiling_history_size, set to 15 by default. This patch abstracts setting THDs' "proc_info" behind a macro that can be used as a hook into the profiling code when profiling support is compiled in. All future code in this line should use that mechanism for setting thd->proc_info. --- Tests are now set to omit the statistics. --- Adds an Information_schema table, "profiling" for access to "show profile" data. --- Merge zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community-3--bug24795 into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community --- Fix merge problems. --- Fixed one bug in the query_source being NULL. Updated test results. --- Include more thorough profiling tests. Improve support for prepared statements. Use session-specific query IDs, starting at zero. --- Selecting from I_S.profiling is no longer quashed in profiling, as requested by Giuseppe. Limit the size of captured query text. No longer log queries that are zero length.
19 years ago
Prevent bugs by making DBUG_* expressions syntactically equivalent to a single statement. --- Bug#24795: SHOW PROFILE Profiling is only partially functional on some architectures. Where there is no getrusage() system call, presently Null values are returned where it would be required. Notably, Windows needs some love applied to make it as useful. Syntax this adds: SHOW PROFILES SHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n] where "n" is an integer and "types" is zero or many (comma-separated) of "CPU" "MEMORY" (not presently supported) "BLOCK IO" "CONTEXT SWITCHES" "PAGE FAULTS" "IPC" "SWAPS" "SOURCE" "ALL" It also adds a session variable (boolean) "profiling", set to "no" by default, and (integer) profiling_history_size, set to 15 by default. This patch abstracts setting THDs' "proc_info" behind a macro that can be used as a hook into the profiling code when profiling support is compiled in. All future code in this line should use that mechanism for setting thd->proc_info. --- Tests are now set to omit the statistics. --- Adds an Information_schema table, "profiling" for access to "show profile" data. --- Merge zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community-3--bug24795 into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community --- Fix merge problems. --- Fixed one bug in the query_source being NULL. Updated test results. --- Include more thorough profiling tests. Improve support for prepared statements. Use session-specific query IDs, starting at zero. --- Selecting from I_S.profiling is no longer quashed in profiling, as requested by Giuseppe. Limit the size of captured query text. No longer log queries that are zero length.
19 years ago
26 years ago
25 years ago
A fix and a test case for Bug#19022 "Memory bug when switching db during trigger execution" Bug#17199 "Problem when view calls function from another database." Bug#18444 "Fully qualified stored function names don't work correctly in SELECT statements" Documentation note: this patch introduces a change in behaviour of prepared statements. This patch adds a few new invariants with regard to how THD::db should be used. These invariants should be preserved in future: - one should never refer to THD::db by pointer and always make a deep copy (strmake, strdup) - one should never compare two databases by pointer, but use strncmp or my_strncasecmp - TABLE_LIST object table->db should be always initialized in the parser or by creator of the object. For prepared statements it means that if the current database is changed after a statement is prepared, the database that was current at prepare remains active. This also means that you can not prepare a statement that implicitly refers to the current database if the latter is not set. This is not documented, and therefore needs documentation. This is NOT a change in behavior for almost all SQL statements except: - ALTER TABLE t1 RENAME t2 - OPTIMIZE TABLE t1 - ANALYZE TABLE t1 - TRUNCATE TABLE t1 -- until this patch t1 or t2 could be evaluated at the first execution of prepared statement. CURRENT_DATABASE() still works OK and is evaluated at every execution of prepared statement. Note, that in stored routines this is not an issue as the default database is the database of the stored procedure and "use" statement is prohibited in stored routines. This patch makes obsolete the use of check_db_used (it was never used in the old code too) and all other places that check for table->db and assign it from THD::db if it's NULL, except the parser. How this patch was created: THD::{db,db_length} were replaced with a LEX_STRING, THD::db. All the places that refer to THD::{db,db_length} were manually checked and: - if the place uses thd->db by pointer, it was fixed to make a deep copy - if a place compared two db pointers, it was fixed to compare them by value (via strcmp/my_strcasecmp, whatever was approproate) Then this intermediate patch was used to write a smaller patch that does the same thing but without a rename. TODO in 5.1: - remove check_db_used - deploy THD::set_db in mysql_change_db See also comments to individual files.
20 years ago
Prevent bugs by making DBUG_* expressions syntactically equivalent to a single statement. --- Bug#24795: SHOW PROFILE Profiling is only partially functional on some architectures. Where there is no getrusage() system call, presently Null values are returned where it would be required. Notably, Windows needs some love applied to make it as useful. Syntax this adds: SHOW PROFILES SHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n] where "n" is an integer and "types" is zero or many (comma-separated) of "CPU" "MEMORY" (not presently supported) "BLOCK IO" "CONTEXT SWITCHES" "PAGE FAULTS" "IPC" "SWAPS" "SOURCE" "ALL" It also adds a session variable (boolean) "profiling", set to "no" by default, and (integer) profiling_history_size, set to 15 by default. This patch abstracts setting THDs' "proc_info" behind a macro that can be used as a hook into the profiling code when profiling support is compiled in. All future code in this line should use that mechanism for setting thd->proc_info. --- Tests are now set to omit the statistics. --- Adds an Information_schema table, "profiling" for access to "show profile" data. --- Merge zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community-3--bug24795 into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community --- Fix merge problems. --- Fixed one bug in the query_source being NULL. Updated test results. --- Include more thorough profiling tests. Improve support for prepared statements. Use session-specific query IDs, starting at zero. --- Selecting from I_S.profiling is no longer quashed in profiling, as requested by Giuseppe. Limit the size of captured query text. No longer log queries that are zero length.
19 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
26 years ago
26 years ago
26 years ago
25 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
Prevent bugs by making DBUG_* expressions syntactically equivalent to a single statement. --- Bug#24795: SHOW PROFILE Profiling is only partially functional on some architectures. Where there is no getrusage() system call, presently Null values are returned where it would be required. Notably, Windows needs some love applied to make it as useful. Syntax this adds: SHOW PROFILES SHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n] where "n" is an integer and "types" is zero or many (comma-separated) of "CPU" "MEMORY" (not presently supported) "BLOCK IO" "CONTEXT SWITCHES" "PAGE FAULTS" "IPC" "SWAPS" "SOURCE" "ALL" It also adds a session variable (boolean) "profiling", set to "no" by default, and (integer) profiling_history_size, set to 15 by default. This patch abstracts setting THDs' "proc_info" behind a macro that can be used as a hook into the profiling code when profiling support is compiled in. All future code in this line should use that mechanism for setting thd->proc_info. --- Tests are now set to omit the statistics. --- Adds an Information_schema table, "profiling" for access to "show profile" data. --- Merge zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community-3--bug24795 into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community --- Fix merge problems. --- Fixed one bug in the query_source being NULL. Updated test results. --- Include more thorough profiling tests. Improve support for prepared statements. Use session-specific query IDs, starting at zero. --- Selecting from I_S.profiling is no longer quashed in profiling, as requested by Giuseppe. Limit the size of captured query text. No longer log queries that are zero length.
19 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
21 years ago
A fix and a test case for Bug#19022 "Memory bug when switching db during trigger execution" Bug#17199 "Problem when view calls function from another database." Bug#18444 "Fully qualified stored function names don't work correctly in SELECT statements" Documentation note: this patch introduces a change in behaviour of prepared statements. This patch adds a few new invariants with regard to how THD::db should be used. These invariants should be preserved in future: - one should never refer to THD::db by pointer and always make a deep copy (strmake, strdup) - one should never compare two databases by pointer, but use strncmp or my_strncasecmp - TABLE_LIST object table->db should be always initialized in the parser or by creator of the object. For prepared statements it means that if the current database is changed after a statement is prepared, the database that was current at prepare remains active. This also means that you can not prepare a statement that implicitly refers to the current database if the latter is not set. This is not documented, and therefore needs documentation. This is NOT a change in behavior for almost all SQL statements except: - ALTER TABLE t1 RENAME t2 - OPTIMIZE TABLE t1 - ANALYZE TABLE t1 - TRUNCATE TABLE t1 -- until this patch t1 or t2 could be evaluated at the first execution of prepared statement. CURRENT_DATABASE() still works OK and is evaluated at every execution of prepared statement. Note, that in stored routines this is not an issue as the default database is the database of the stored procedure and "use" statement is prohibited in stored routines. This patch makes obsolete the use of check_db_used (it was never used in the old code too) and all other places that check for table->db and assign it from THD::db if it's NULL, except the parser. How this patch was created: THD::{db,db_length} were replaced with a LEX_STRING, THD::db. All the places that refer to THD::{db,db_length} were manually checked and: - if the place uses thd->db by pointer, it was fixed to make a deep copy - if a place compared two db pointers, it was fixed to compare them by value (via strcmp/my_strcasecmp, whatever was approproate) Then this intermediate patch was used to write a smaller patch that does the same thing but without a rename. TODO in 5.1: - remove check_db_used - deploy THD::set_db in mysql_change_db See also comments to individual files.
20 years ago
Prevent bugs by making DBUG_* expressions syntactically equivalent to a single statement. --- Bug#24795: SHOW PROFILE Profiling is only partially functional on some architectures. Where there is no getrusage() system call, presently Null values are returned where it would be required. Notably, Windows needs some love applied to make it as useful. Syntax this adds: SHOW PROFILES SHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n] where "n" is an integer and "types" is zero or many (comma-separated) of "CPU" "MEMORY" (not presently supported) "BLOCK IO" "CONTEXT SWITCHES" "PAGE FAULTS" "IPC" "SWAPS" "SOURCE" "ALL" It also adds a session variable (boolean) "profiling", set to "no" by default, and (integer) profiling_history_size, set to 15 by default. This patch abstracts setting THDs' "proc_info" behind a macro that can be used as a hook into the profiling code when profiling support is compiled in. All future code in this line should use that mechanism for setting thd->proc_info. --- Tests are now set to omit the statistics. --- Adds an Information_schema table, "profiling" for access to "show profile" data. --- Merge zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community-3--bug24795 into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community --- Fix merge problems. --- Fixed one bug in the query_source being NULL. Updated test results. --- Include more thorough profiling tests. Improve support for prepared statements. Use session-specific query IDs, starting at zero. --- Selecting from I_S.profiling is no longer quashed in profiling, as requested by Giuseppe. Limit the size of captured query text. No longer log queries that are zero length.
19 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
23 years ago
25 years ago
23 years ago
23 years ago
WL#3817: Simplify string / memory area types and make things more consistent (first part) The following type conversions was done: - Changed byte to uchar - Changed gptr to uchar* - Change my_string to char * - Change my_size_t to size_t - Change size_s to size_t Removed declaration of byte, gptr, my_string, my_size_t and size_s. Following function parameter changes was done: - All string functions in mysys/strings was changed to use size_t instead of uint for string lengths. - All read()/write() functions changed to use size_t (including vio). - All protocoll functions changed to use size_t instead of uint - Functions that used a pointer to a string length was changed to use size_t* - Changed malloc(), free() and related functions from using gptr to use void * as this requires fewer casts in the code and is more in line with how the standard functions work. - Added extra length argument to dirname_part() to return the length of the created string. - Changed (at least) following functions to take uchar* as argument: - db_dump() - my_net_write() - net_write_command() - net_store_data() - DBUG_DUMP() - decimal2bin() & bin2decimal() - Changed my_compress() and my_uncompress() to use size_t. Changed one argument to my_uncompress() from a pointer to a value as we only return one value (makes function easier to use). - Changed type of 'pack_data' argument to packfrm() to avoid casts. - Changed in readfrm() and writefrom(), ha_discover and handler::discover() the type for argument 'frmdata' to uchar** to avoid casts. - Changed most Field functions to use uchar* instead of char* (reduced a lot of casts). - Changed field->val_xxx(xxx, new_ptr) to take const pointers. Other changes: - Removed a lot of not needed casts - Added a few new cast required by other changes - Added some cast to my_multi_malloc() arguments for safety (as string lengths needs to be uint, not size_t). - Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done explicitely as this conflict was often hided by casting the function to hash_get_key). - Changed some buffers to memory regions to uchar* to avoid casts. - Changed some string lengths from uint to size_t. - Changed field->ptr to be uchar* instead of char*. This allowed us to get rid of a lot of casts. - Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar - Include zlib.h in some files as we needed declaration of crc32() - Changed MY_FILE_ERROR to be (size_t) -1. - Changed many variables to hold the result of my_read() / my_write() to be size_t. This was needed to properly detect errors (which are returned as (size_t) -1). - Removed some very old VMS code - Changed packfrm()/unpackfrm() to not be depending on uint size (portability fix) - Removed windows specific code to restore cursor position as this causes slowdown on windows and we should not mix read() and pread() calls anyway as this is not thread safe. Updated function comment to reflect this. Changed function that depended on original behavior of my_pwrite() to itself restore the cursor position (one such case). - Added some missing checking of return value of malloc(). - Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow. - Changed type of table_def::m_size from my_size_t to ulong to reflect that m_size is the number of elements in the array, not a string/memory length. - Moved THD::max_row_length() to table.cc (as it's not depending on THD). Inlined max_row_length_blob() into this function. - More function comments - Fixed some compiler warnings when compiled without partitions. - Removed setting of LEX_STRING() arguments in declaration (portability fix). - Some trivial indentation/variable name changes. - Some trivial code simplifications: - Replaced some calls to alloc_root + memcpy to use strmake_root()/strdup_root(). - Changed some calls from memdup() to strmake() (Safety fix) - Simpler loops in client-simple.c
19 years ago
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
BUG#32407: Impossible to do point-in-time recovery from older binlog Problem: it is unsafe to read base64-printed events without first reading the Format_description_log_event (FD). Currently, mysqlbinlog cannot print the FD. As a side effect, another bug has also been fixed: When mysqlbinlog --start-position=X was specified, no ROLLBACK was printed. I changed this, so that ROLLBACK is always printed. This patch does several things: - Format_description_log_event (FD) now print themselves in base64 format. - mysqlbinlog is now able to print FD events. It has three modes: --base64-output=auto Print row events in base64 output, and print FD event. The FD event is printed even if it is outside the range specified with --start-position, because it would not be safe to read row events otherwise. This is the default. --base64-output=always Like --base64-output=auto, but also print base64 output for query events. This is like the old --base64-output flag, which is also a shorthand for --base64-output=always --base64-output=never Never print base64 output, generate error if row events occur in binlog. This is useful to suppress the FD event in binlogs known not to contain row events (e.g., because BINLOG statement is unsafe, requires root privileges, is not SQL, etc) - the BINLOG statement now handles FD events correctly, by setting the thread's rli's relay log's description_event_for_exec to the loaded event. In fact, executing a BINLOG statement is almost the same as reading an event from a relay log. Before my patch, the code for this was separated (exec_relay_log_event in slave.cc executes events from the relay log, mysql_client_binlog_statement in sql_binlog.cc executes BINLOG statements). I needed to augment mysql_client_binlog_statement to do parts of what exec_relay_log_event does. Hence, I did a small refactoring and moved parts of exec_relay_log_event to a new function, which I named apply_event_and_update_pos. apply_event_and_update_pos is called both from exec_relay_log_event and from mysql_client_binlog_statement. - When a non-FD event is executed in a BINLOG statement, without previously executing a FD event in a BINLOG statement, it generates an error, because that's unsafe. I took a new error code for that: ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS. In order to get a decent error message containing the name of the event, I added the class method char* Log_event::get_type_str(Log_event_type type), which returns a string name for the given Log_event_type. This is just like the existing char* Log_event::get_type_str(), except it is a class method that takes the log event type as parameter. I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(), so that names of old rows event are properly printed. - When reading an event, I added a check that the event type is known by the current Format_description_log_event. Without this, it may crash on bad input (and I was struck by this several times). - I patched the following test cases, which all contain BINLOG statements for row events which must be preceded by BINLOG statements for FD events: - rpl_bug31076 While I was here, I fixed some small things in log_event.cc: - replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places - replaced return by DBUG_VOID_RETURN in one place - The name of the logfile can be '-' to indicate stdin. Before my patch, the code just checked if the first character is '-'; now it does a full strcmp(). Probably, all arguments that begin with a - are already handled somewhere else as flags, but I still think it is better that the code reflects what it is supposed to do, with as little dependencies as possible on other parts of the code. If we one day implement that all command line arguments after -- are files (as most unix tools do), then we need this. I also fixed the following in slave.cc: - next_event() was declared twice, and queue_event was not static but should be static (not used outside the file).
18 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
23 years ago
23 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
23 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
Bug#46013: rpl_extraColmaster_myisam fails on pb2 Bug#45243: crash on win in sql thread clear_tables_to_lock() -> free() Bug#45242: crash on win in mysql_close() -> free() Bug#45238: rpl_slave_skip, rpl_change_master failed (lost connection) for STOP SLAVE Bug#46030: rpl_truncate_3innodb causes server crash on windows Bug#46014: rpl_stm_reset_slave crashes the server sporadically in pb2 When killing a user session on the server, it's necessary to interrupt (notify) the thread associated with the session that the connection is being killed so that the thread is woken up if waiting for I/O. On a few platforms (Mac, Windows and HP-UX) where the SIGNAL_WITH_VIO_CLOSE flag is defined, this interruption procedure is to asynchronously close the underlying socket of the connection. In order to enable this schema, each connection serving thread registers its VIO (I/O interface) so that other threads can access it and close the connection. But only the owner thread of the VIO might delete it as to guarantee that other threads won't see freed memory (the thread unregisters the VIO before deleting it). A side note: closing the socket introduces a harmless race that might cause a thread attempt to read from a closed socket, but this is deemed acceptable. The problem is that this infrastructure was meant to only be used by server threads, but the slave I/O thread was registering the VIO of a mysql handle (a client API structure that represents a connection to another server instance) as a active connection of the thread. But under some circumstances such as network failures, the client API might destroy the VIO associated with a handle at will, yet the VIO wouldn't be properly unregistered. This could lead to accesses to freed data if a thread attempted to kill a slave I/O thread whose connection was already broken. There was a attempt to work around this by checking whether the socket was being interrupted, but this hack didn't work as intended due to the aforementioned race -- attempting to read from the socket would yield a "bad file descriptor" error. The solution is to add a hook to the client API that is called from the client code before the VIO of a handle is deleted. This hook allows the slave I/O thread to detach the active vio so it does not point to freed memory.
17 years ago
Bug#46013: rpl_extraColmaster_myisam fails on pb2 Bug#45243: crash on win in sql thread clear_tables_to_lock() -> free() Bug#45242: crash on win in mysql_close() -> free() Bug#45238: rpl_slave_skip, rpl_change_master failed (lost connection) for STOP SLAVE Bug#46030: rpl_truncate_3innodb causes server crash on windows Bug#46014: rpl_stm_reset_slave crashes the server sporadically in pb2 When killing a user session on the server, it's necessary to interrupt (notify) the thread associated with the session that the connection is being killed so that the thread is woken up if waiting for I/O. On a few platforms (Mac, Windows and HP-UX) where the SIGNAL_WITH_VIO_CLOSE flag is defined, this interruption procedure is to asynchronously close the underlying socket of the connection. In order to enable this schema, each connection serving thread registers its VIO (I/O interface) so that other threads can access it and close the connection. But only the owner thread of the VIO might delete it as to guarantee that other threads won't see freed memory (the thread unregisters the VIO before deleting it). A side note: closing the socket introduces a harmless race that might cause a thread attempt to read from a closed socket, but this is deemed acceptable. The problem is that this infrastructure was meant to only be used by server threads, but the slave I/O thread was registering the VIO of a mysql handle (a client API structure that represents a connection to another server instance) as a active connection of the thread. But under some circumstances such as network failures, the client API might destroy the VIO associated with a handle at will, yet the VIO wouldn't be properly unregistered. This could lead to accesses to freed data if a thread attempted to kill a slave I/O thread whose connection was already broken. There was a attempt to work around this by checking whether the socket was being interrupted, but this hack didn't work as intended due to the aforementioned race -- attempting to read from the socket would yield a "bad file descriptor" error. The solution is to add a hook to the client API that is called from the client code before the VIO of a handle is deleted. This hook allows the slave I/O thread to detach the active vio so it does not point to freed memory.
17 years ago
23 years ago
23 years ago
23 years ago
23 years ago
26 years ago
26 years ago
23 years ago
23 years ago
26 years ago
26 years ago
26 years ago
26 years ago
23 years ago
WL#3817: Simplify string / memory area types and make things more consistent (first part) The following type conversions was done: - Changed byte to uchar - Changed gptr to uchar* - Change my_string to char * - Change my_size_t to size_t - Change size_s to size_t Removed declaration of byte, gptr, my_string, my_size_t and size_s. Following function parameter changes was done: - All string functions in mysys/strings was changed to use size_t instead of uint for string lengths. - All read()/write() functions changed to use size_t (including vio). - All protocoll functions changed to use size_t instead of uint - Functions that used a pointer to a string length was changed to use size_t* - Changed malloc(), free() and related functions from using gptr to use void * as this requires fewer casts in the code and is more in line with how the standard functions work. - Added extra length argument to dirname_part() to return the length of the created string. - Changed (at least) following functions to take uchar* as argument: - db_dump() - my_net_write() - net_write_command() - net_store_data() - DBUG_DUMP() - decimal2bin() & bin2decimal() - Changed my_compress() and my_uncompress() to use size_t. Changed one argument to my_uncompress() from a pointer to a value as we only return one value (makes function easier to use). - Changed type of 'pack_data' argument to packfrm() to avoid casts. - Changed in readfrm() and writefrom(), ha_discover and handler::discover() the type for argument 'frmdata' to uchar** to avoid casts. - Changed most Field functions to use uchar* instead of char* (reduced a lot of casts). - Changed field->val_xxx(xxx, new_ptr) to take const pointers. Other changes: - Removed a lot of not needed casts - Added a few new cast required by other changes - Added some cast to my_multi_malloc() arguments for safety (as string lengths needs to be uint, not size_t). - Fixed all calls to hash-get-key functions to use size_t*. (Needed to be done explicitely as this conflict was often hided by casting the function to hash_get_key). - Changed some buffers to memory regions to uchar* to avoid casts. - Changed some string lengths from uint to size_t. - Changed field->ptr to be uchar* instead of char*. This allowed us to get rid of a lot of casts. - Some changes from true -> TRUE, false -> FALSE, unsigned char -> uchar - Include zlib.h in some files as we needed declaration of crc32() - Changed MY_FILE_ERROR to be (size_t) -1. - Changed many variables to hold the result of my_read() / my_write() to be size_t. This was needed to properly detect errors (which are returned as (size_t) -1). - Removed some very old VMS code - Changed packfrm()/unpackfrm() to not be depending on uint size (portability fix) - Removed windows specific code to restore cursor position as this causes slowdown on windows and we should not mix read() and pread() calls anyway as this is not thread safe. Updated function comment to reflect this. Changed function that depended on original behavior of my_pwrite() to itself restore the cursor position (one such case). - Added some missing checking of return value of malloc(). - Changed definition of MOD_PAD_CHAR_TO_FULL_LENGTH to avoid 'long' overflow. - Changed type of table_def::m_size from my_size_t to ulong to reflect that m_size is the number of elements in the array, not a string/memory length. - Moved THD::max_row_length() to table.cc (as it's not depending on THD). Inlined max_row_length_blob() into this function. - More function comments - Fixed some compiler warnings when compiled without partitions. - Removed setting of LEX_STRING() arguments in declaration (portability fix). - Some trivial indentation/variable name changes. - Some trivial code simplifications: - Replaced some calls to alloc_root + memcpy to use strmake_root()/strdup_root(). - Changed some calls from memdup() to strmake() (Safety fix) - Simpler loops in client-simple.c
19 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
This will be pushed only after I fix the testsuite. This is the main commit for Worklog tasks: * A more dynamic binlog format which allows small changes (1064) * Log session variables in Query_log_event (1063) Below 5.0 means 5.0.0. MySQL 5.0 is able to replicate FOREIGN_KEY_CHECKS, UNIQUE_KEY_CHECKS (for speed), SQL_AUTO_IS_NULL, SQL_MODE. Not charsets (WL#1062), not some vars (I can only think of SQL_SELECT_LIMIT, which deserves a special treatment). Note that this works for queries, except LOAD DATA INFILE (for this it would have to wait for Dmitri's push of WL#874, which in turns waits for the present push, so... the deadlock must be broken!). Note that when Dmitri pushes WL#874 in 5.0.1, 5.0.0 won't be able to replicate a LOAD DATA INFILE from 5.0.1. Apart from that, the new binlog format is designed so that it can tolerate a little variation in the events (so that a 5.0.0 slave could replicate a 5.0.1 master, except for LOAD DATA INFILE unfortunately); that is, when I later add replication of charsets it should break nothing. And when I later add a UID to every event, it should break nothing. The main change brought by this patch is a new type of event, Format_description_log_event, which describes some lengthes in other event types. This event is needed for the master/slave/mysqlbinlog to understand a 5.0 log. Thanks to this event, we can later add more bytes to the header of every event without breaking compatibility. Inside Query_log_event, we have some additional dynamic format, as every Query_log_event can have a different number of status variables, stored as pairs (code, value); that's how SQL_MODE and session variables and catalog are stored. Like this, we can later add count of affected rows, charsets... and we can have options --don't-log-count-affected-rows if we want. MySQL 5.0 is able to run on 4.x relay logs, 4.x binlogs. Upgrading a 4.x master to 5.0 is ok (no need to delete binlogs), upgrading a 4.x slave to 5.0 is ok (no need to delete relay logs); so both can be "hot" upgrades. Upgrading a 3.23 master to 5.0 requires as much as upgrading it to 4.0. 3.23 and 4.x can't be slaves of 5.0. So downgrading from 5.0 to 4.x may be complicated. Log_event::log_pos is now the position of the end of the event, which is more useful than the position of the beginning. We take care about compatibility with <5.0 (in which log_pos is the beginning). I added a short test for replication of SQL_MODE and some other variables. TODO: - after committing this, merge the latest 5.0 into it - fix all tests - update the manual with upgrade notes.
22 years ago
23 years ago
23 years ago
23 years ago
23 years ago
Fix for BUG#24432 "INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values". When in an INSERT ON DUPLICATE KEY UPDATE, using an autoincrement column, we inserted some autogenerated values and also updated some rows, some autogenerated values were not used (for example, even if 10 was the largest autoinc value in the table at the start of the statement, 12 could be the first autogenerated value inserted by the statement, instead of 11). One autogenerated value was lost per updated row. Led to exhausting the range of the autoincrement column faster. Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12. This bug breaks replication from a pre-5.0.24 master. But the present bugfix, as it makes INSERT ON DUP KEY UPDATE behave like pre-5.0.24, breaks replication from a [5.0.24,5.0.34] master to a fixed (5.0.36) slave! To warn users against this when they upgrade their slave, as agreed with the support team, we add code for a fixed slave to detect that it is connected to a buggy master in a situation (INSERT ON DUP KEY UPDATE into autoinc column) likely to break replication, in which case it cannot replicate so stops and prints a message to the slave's error log and to SHOW SLAVE STATUS. For 5.0.36->[5.0.24,5.0.34] replication we cannot warn as master does not know the slave's version (but we always recommended to users to have slave at least as new as master). As agreed with support, I'll also ask for an alert to be put into the MySQL Network Monitoring and Advisory Service.
19 years ago
Fix for BUG#24432 "INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values". When in an INSERT ON DUPLICATE KEY UPDATE, using an autoincrement column, we inserted some autogenerated values and also updated some rows, some autogenerated values were not used (for example, even if 10 was the largest autoinc value in the table at the start of the statement, 12 could be the first autogenerated value inserted by the statement, instead of 11). One autogenerated value was lost per updated row. Led to exhausting the range of the autoincrement column faster. Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12. This bug breaks replication from a pre-5.0.24 master. But the present bugfix, as it makes INSERT ON DUP KEY UPDATE behave like pre-5.0.24, breaks replication from a [5.0.24,5.0.34] master to a fixed (5.0.36) slave! To warn users against this when they upgrade their slave, as agreed with the support team, we add code for a fixed slave to detect that it is connected to a buggy master in a situation (INSERT ON DUP KEY UPDATE into autoinc column) likely to break replication, in which case it cannot replicate so stops and prints a message to the slave's error log and to SHOW SLAVE STATUS. For 5.0.36->[5.0.24,5.0.34] replication we cannot warn as master does not know the slave's version (but we always recommended to users to have slave at least as new as master). As agreed with support, I'll also ask for an alert to be put into the MySQL Network Monitoring and Advisory Service.
19 years ago
BUG#33029 5.0 to 5.1 replication fails on dup key when inserting using a trig in SP For all 5.0 and up to 5.1.12 exclusive, when a stored routine or trigger caused an INSERT into an AUTO_INCREMENT column, the generated AUTO_INCREMENT value should not be written into the binary log, which means if a statement does not generate AUTO_INCREMENT value itself, there will be no Intvar event (SET INSERT_ID) associated with it even if one of the stored routine or trigger caused generation of such a value. And meanwhile, when executing a stored routine or trigger, it would ignore the INSERT_ID value even if there is a INSERT_ID value available set by a SET INSERT_ID statement. Starting from MySQL 5.1.12, the generated AUTO_INCREMENT value is written into the binary log, and the value will be used if available when executing the stored routine or trigger. Prior fix of this bug in MySQL 5.0 and prior MySQL 5.1.12 (referenced as the buggy versions in the text below), when a statement that generates AUTO_INCREMENT value by the top statement was executed in the body of a SP, all statements in the SP after this statement would be treated as if they had generated AUTO_INCREMENT by the top statement. When a statement that did not generate AUTO_INCREMENT value by the top statement but by a function/trigger called by it, an erroneous Intvar event would be associated with the statement, this erroneous INSERT_ID value wouldn't cause problem when replicating between masters and slaves of 5.0.x or prior 5.1.12, because the erroneous INSERT_ID value was not used when executing functions/triggers. But when replicating from buggy versions to 5.1.12 or newer, which will use the INSERT_ID value in functions/triggers, the erroneous value will be used, which would cause duplicate entry error and cause the slave to stop. The patch for 5.1 fixed it to ignore the SET INSERT_ID value when executing functions/triggers if it is replicating from a master of buggy versions, another patch for 5.0 fixed it not to generate the erroneous Intvar event.
18 years ago
Fix for BUG#24432 "INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values". When in an INSERT ON DUPLICATE KEY UPDATE, using an autoincrement column, we inserted some autogenerated values and also updated some rows, some autogenerated values were not used (for example, even if 10 was the largest autoinc value in the table at the start of the statement, 12 could be the first autogenerated value inserted by the statement, instead of 11). One autogenerated value was lost per updated row. Led to exhausting the range of the autoincrement column faster. Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12. This bug breaks replication from a pre-5.0.24 master. But the present bugfix, as it makes INSERT ON DUP KEY UPDATE behave like pre-5.0.24, breaks replication from a [5.0.24,5.0.34] master to a fixed (5.0.36) slave! To warn users against this when they upgrade their slave, as agreed with the support team, we add code for a fixed slave to detect that it is connected to a buggy master in a situation (INSERT ON DUP KEY UPDATE into autoinc column) likely to break replication, in which case it cannot replicate so stops and prints a message to the slave's error log and to SHOW SLAVE STATUS. For 5.0.36->[5.0.24,5.0.34] replication we cannot warn as master does not know the slave's version (but we always recommended to users to have slave at least as new as master). As agreed with support, I'll also ask for an alert to be put into the MySQL Network Monitoring and Advisory Service.
19 years ago
Fix for BUG#24432 "INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values". When in an INSERT ON DUPLICATE KEY UPDATE, using an autoincrement column, we inserted some autogenerated values and also updated some rows, some autogenerated values were not used (for example, even if 10 was the largest autoinc value in the table at the start of the statement, 12 could be the first autogenerated value inserted by the statement, instead of 11). One autogenerated value was lost per updated row. Led to exhausting the range of the autoincrement column faster. Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12. This bug breaks replication from a pre-5.0.24 master. But the present bugfix, as it makes INSERT ON DUP KEY UPDATE behave like pre-5.0.24, breaks replication from a [5.0.24,5.0.34] master to a fixed (5.0.36) slave! To warn users against this when they upgrade their slave, as agreed with the support team, we add code for a fixed slave to detect that it is connected to a buggy master in a situation (INSERT ON DUP KEY UPDATE into autoinc column) likely to break replication, in which case it cannot replicate so stops and prints a message to the slave's error log and to SHOW SLAVE STATUS. For 5.0.36->[5.0.24,5.0.34] replication we cannot warn as master does not know the slave's version (but we always recommended to users to have slave at least as new as master). As agreed with support, I'll also ask for an alert to be put into the MySQL Network Monitoring and Advisory Service.
19 years ago
BUG#33029 5.0 to 5.1 replication fails on dup key when inserting using a trig in SP For all 5.0 and up to 5.1.12 exclusive, when a stored routine or trigger caused an INSERT into an AUTO_INCREMENT column, the generated AUTO_INCREMENT value should not be written into the binary log, which means if a statement does not generate AUTO_INCREMENT value itself, there will be no Intvar event (SET INSERT_ID) associated with it even if one of the stored routine or trigger caused generation of such a value. And meanwhile, when executing a stored routine or trigger, it would ignore the INSERT_ID value even if there is a INSERT_ID value available set by a SET INSERT_ID statement. Starting from MySQL 5.1.12, the generated AUTO_INCREMENT value is written into the binary log, and the value will be used if available when executing the stored routine or trigger. Prior fix of this bug in MySQL 5.0 and prior MySQL 5.1.12 (referenced as the buggy versions in the text below), when a statement that generates AUTO_INCREMENT value by the top statement was executed in the body of a SP, all statements in the SP after this statement would be treated as if they had generated AUTO_INCREMENT by the top statement. When a statement that did not generate AUTO_INCREMENT value by the top statement but by a function/trigger called by it, an erroneous Intvar event would be associated with the statement, this erroneous INSERT_ID value wouldn't cause problem when replicating between masters and slaves of 5.0.x or prior 5.1.12, because the erroneous INSERT_ID value was not used when executing functions/triggers. But when replicating from buggy versions to 5.1.12 or newer, which will use the INSERT_ID value in functions/triggers, the erroneous value will be used, which would cause duplicate entry error and cause the slave to stop. The patch for 5.1 fixed it to ignore the SET INSERT_ID value when executing functions/triggers if it is replicating from a master of buggy versions, another patch for 5.0 fixed it not to generate the erroneous Intvar event.
18 years ago
Fix for BUG#24432 "INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values". When in an INSERT ON DUPLICATE KEY UPDATE, using an autoincrement column, we inserted some autogenerated values and also updated some rows, some autogenerated values were not used (for example, even if 10 was the largest autoinc value in the table at the start of the statement, 12 could be the first autogenerated value inserted by the statement, instead of 11). One autogenerated value was lost per updated row. Led to exhausting the range of the autoincrement column faster. Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12. This bug breaks replication from a pre-5.0.24 master. But the present bugfix, as it makes INSERT ON DUP KEY UPDATE behave like pre-5.0.24, breaks replication from a [5.0.24,5.0.34] master to a fixed (5.0.36) slave! To warn users against this when they upgrade their slave, as agreed with the support team, we add code for a fixed slave to detect that it is connected to a buggy master in a situation (INSERT ON DUP KEY UPDATE into autoinc column) likely to break replication, in which case it cannot replicate so stops and prints a message to the slave's error log and to SHOW SLAVE STATUS. For 5.0.36->[5.0.24,5.0.34] replication we cannot warn as master does not know the slave's version (but we always recommended to users to have slave at least as new as master). As agreed with support, I'll also ask for an alert to be put into the MySQL Network Monitoring and Advisory Service.
19 years ago
Fix for BUG#24432 "INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values". When in an INSERT ON DUPLICATE KEY UPDATE, using an autoincrement column, we inserted some autogenerated values and also updated some rows, some autogenerated values were not used (for example, even if 10 was the largest autoinc value in the table at the start of the statement, 12 could be the first autogenerated value inserted by the statement, instead of 11). One autogenerated value was lost per updated row. Led to exhausting the range of the autoincrement column faster. Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12. This bug breaks replication from a pre-5.0.24 master. But the present bugfix, as it makes INSERT ON DUP KEY UPDATE behave like pre-5.0.24, breaks replication from a [5.0.24,5.0.34] master to a fixed (5.0.36) slave! To warn users against this when they upgrade their slave, as agreed with the support team, we add code for a fixed slave to detect that it is connected to a buggy master in a situation (INSERT ON DUP KEY UPDATE into autoinc column) likely to break replication, in which case it cannot replicate so stops and prints a message to the slave's error log and to SHOW SLAVE STATUS. For 5.0.36->[5.0.24,5.0.34] replication we cannot warn as master does not know the slave's version (but we always recommended to users to have slave at least as new as master). As agreed with support, I'll also ask for an alert to be put into the MySQL Network Monitoring and Advisory Service.
19 years ago
BUG#33029 5.0 to 5.1 replication fails on dup key when inserting using a trig in SP For all 5.0 and up to 5.1.12 exclusive, when a stored routine or trigger caused an INSERT into an AUTO_INCREMENT column, the generated AUTO_INCREMENT value should not be written into the binary log, which means if a statement does not generate AUTO_INCREMENT value itself, there will be no Intvar event (SET INSERT_ID) associated with it even if one of the stored routine or trigger caused generation of such a value. And meanwhile, when executing a stored routine or trigger, it would ignore the INSERT_ID value even if there is a INSERT_ID value available set by a SET INSERT_ID statement. Starting from MySQL 5.1.12, the generated AUTO_INCREMENT value is written into the binary log, and the value will be used if available when executing the stored routine or trigger. Prior fix of this bug in MySQL 5.0 and prior MySQL 5.1.12 (referenced as the buggy versions in the text below), when a statement that generates AUTO_INCREMENT value by the top statement was executed in the body of a SP, all statements in the SP after this statement would be treated as if they had generated AUTO_INCREMENT by the top statement. When a statement that did not generate AUTO_INCREMENT value by the top statement but by a function/trigger called by it, an erroneous Intvar event would be associated with the statement, this erroneous INSERT_ID value wouldn't cause problem when replicating between masters and slaves of 5.0.x or prior 5.1.12, because the erroneous INSERT_ID value was not used when executing functions/triggers. But when replicating from buggy versions to 5.1.12 or newer, which will use the INSERT_ID value in functions/triggers, the erroneous value will be used, which would cause duplicate entry error and cause the slave to stop. The patch for 5.1 fixed it to ignore the SET INSERT_ID value when executing functions/triggers if it is replicating from a master of buggy versions, another patch for 5.0 fixed it not to generate the erroneous Intvar event.
18 years ago
Fix for BUG#24432 "INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values". When in an INSERT ON DUPLICATE KEY UPDATE, using an autoincrement column, we inserted some autogenerated values and also updated some rows, some autogenerated values were not used (for example, even if 10 was the largest autoinc value in the table at the start of the statement, 12 could be the first autogenerated value inserted by the statement, instead of 11). One autogenerated value was lost per updated row. Led to exhausting the range of the autoincrement column faster. Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12. This bug breaks replication from a pre-5.0.24 master. But the present bugfix, as it makes INSERT ON DUP KEY UPDATE behave like pre-5.0.24, breaks replication from a [5.0.24,5.0.34] master to a fixed (5.0.36) slave! To warn users against this when they upgrade their slave, as agreed with the support team, we add code for a fixed slave to detect that it is connected to a buggy master in a situation (INSERT ON DUP KEY UPDATE into autoinc column) likely to break replication, in which case it cannot replicate so stops and prints a message to the slave's error log and to SHOW SLAVE STATUS. For 5.0.36->[5.0.24,5.0.34] replication we cannot warn as master does not know the slave's version (but we always recommended to users to have slave at least as new as master). As agreed with support, I'll also ask for an alert to be put into the MySQL Network Monitoring and Advisory Service.
19 years ago
Manual merge from 5.0-rpl, of fixes for: 1) BUG#25507 "multi-row insert delayed + auto increment causes duplicate key entries on slave" (two concurrrent connections doing multi-row INSERT DELAYED to insert into an auto_increment column, caused replication slave to stop with "duplicate key error" (and binlog was wrong), and BUG#26116 "If multi-row INSERT DELAYED has errors, statement-based binlogging breaks" (the binlog was not accounting for all rows inserted, or slave could stop). The fix is that: in statement-based binlogging, a multi-row INSERT DELAYED is silently converted to a non-delayed INSERT. This is supposed to not affect many 5.1 users as in 5.1, the default binlog format is "mixed", which does not have the bug (the bug is only with binlog_format=STATEMENT). We should document how the system delayed_insert thread decides of its binlog format (which is not modified by this patch): this decision is taken when the thread is created and holds until it is terminated (is not affected by any later change via SET GLOBAL BINLOG_FORMAT). It is also not affected by the binlog format of the connection which issues INSERT DELAYED (this binlog format does not affect how the row will be binlogged). If one wants to change the binlog format of its server with SET GLOBAL BINLOG_FORMAT, it should do FLUSH TABLES to be sure all delayed_insert threads terminate and thus new threads are created, taking into account the new format. 2) BUG#24432 "INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values". When in an INSERT ON DUPLICATE KEY UPDATE, using an autoincrement column, we inserted some autogenerated values and also updated some rows, some autogenerated values were not used (for example, even if 10 was the largest autoinc value in the table at the start of the statement, 12 could be the first autogenerated value inserted by the statement, instead of 11). One autogenerated value was lost per updated row. Led to exhausting the range of the autoincrement column faster. Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12. This bug breaks replication from a pre-5.0.24/pre-5.1.12 master. But the present bugfix, as it makes INSERT ON DUP KEY UPDATE behave like pre-5.0.24/pre-5.1.12, breaks replication from a [5.0.24,5.0.34]/[5.1.12,5.1.15] master to a fixed (5.0.36/5.1.16) slave! To warn users against this when they upgrade their slave, as agreed with the support team, we add code for a fixed slave to detect that it is connected to a buggy master in a situation (INSERT ON DUP KEY UPDATE into autoinc column) likely to break replication, in which case it cannot replicate so stops and prints a message to the slave's error log and to SHOW SLAVE STATUS. For 5.0.36->[5.0.24,5.0.34] replication or 5.1.16->[5.1.12,5.1.15] replication we cannot warn as master does not know the slave's version (but we always recommended to users to have slave at least as new as master). As agreed with support, I have asked for an alert to be put into the MySQL Network Monitoring and Advisory Service. 3) note that I'll re-enable rpl_insert_id as soon as 5.1-rpl gets the changes from the main 5.1.
19 years ago
Manual merge from 5.0-rpl, of fixes for: 1) BUG#25507 "multi-row insert delayed + auto increment causes duplicate key entries on slave" (two concurrrent connections doing multi-row INSERT DELAYED to insert into an auto_increment column, caused replication slave to stop with "duplicate key error" (and binlog was wrong), and BUG#26116 "If multi-row INSERT DELAYED has errors, statement-based binlogging breaks" (the binlog was not accounting for all rows inserted, or slave could stop). The fix is that: in statement-based binlogging, a multi-row INSERT DELAYED is silently converted to a non-delayed INSERT. This is supposed to not affect many 5.1 users as in 5.1, the default binlog format is "mixed", which does not have the bug (the bug is only with binlog_format=STATEMENT). We should document how the system delayed_insert thread decides of its binlog format (which is not modified by this patch): this decision is taken when the thread is created and holds until it is terminated (is not affected by any later change via SET GLOBAL BINLOG_FORMAT). It is also not affected by the binlog format of the connection which issues INSERT DELAYED (this binlog format does not affect how the row will be binlogged). If one wants to change the binlog format of its server with SET GLOBAL BINLOG_FORMAT, it should do FLUSH TABLES to be sure all delayed_insert threads terminate and thus new threads are created, taking into account the new format. 2) BUG#24432 "INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values". When in an INSERT ON DUPLICATE KEY UPDATE, using an autoincrement column, we inserted some autogenerated values and also updated some rows, some autogenerated values were not used (for example, even if 10 was the largest autoinc value in the table at the start of the statement, 12 could be the first autogenerated value inserted by the statement, instead of 11). One autogenerated value was lost per updated row. Led to exhausting the range of the autoincrement column faster. Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12. This bug breaks replication from a pre-5.0.24/pre-5.1.12 master. But the present bugfix, as it makes INSERT ON DUP KEY UPDATE behave like pre-5.0.24/pre-5.1.12, breaks replication from a [5.0.24,5.0.34]/[5.1.12,5.1.15] master to a fixed (5.0.36/5.1.16) slave! To warn users against this when they upgrade their slave, as agreed with the support team, we add code for a fixed slave to detect that it is connected to a buggy master in a situation (INSERT ON DUP KEY UPDATE into autoinc column) likely to break replication, in which case it cannot replicate so stops and prints a message to the slave's error log and to SHOW SLAVE STATUS. For 5.0.36->[5.0.24,5.0.34] replication or 5.1.16->[5.1.12,5.1.15] replication we cannot warn as master does not know the slave's version (but we always recommended to users to have slave at least as new as master). As agreed with support, I have asked for an alert to be put into the MySQL Network Monitoring and Advisory Service. 3) note that I'll re-enable rpl_insert_id as soon as 5.1-rpl gets the changes from the main 5.1.
19 years ago
Fix for BUG#24432 "INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values". When in an INSERT ON DUPLICATE KEY UPDATE, using an autoincrement column, we inserted some autogenerated values and also updated some rows, some autogenerated values were not used (for example, even if 10 was the largest autoinc value in the table at the start of the statement, 12 could be the first autogenerated value inserted by the statement, instead of 11). One autogenerated value was lost per updated row. Led to exhausting the range of the autoincrement column faster. Bug introduced by fix of BUG#20188; present since 5.0.24 and 5.1.12. This bug breaks replication from a pre-5.0.24 master. But the present bugfix, as it makes INSERT ON DUP KEY UPDATE behave like pre-5.0.24, breaks replication from a [5.0.24,5.0.34] master to a fixed (5.0.36) slave! To warn users against this when they upgrade their slave, as agreed with the support team, we add code for a fixed slave to detect that it is connected to a buggy master in a situation (INSERT ON DUP KEY UPDATE into autoinc column) likely to break replication, in which case it cannot replicate so stops and prints a message to the slave's error log and to SHOW SLAVE STATUS. For 5.0.36->[5.0.24,5.0.34] replication we cannot warn as master does not know the slave's version (but we always recommended to users to have slave at least as new as master). As agreed with support, I'll also ask for an alert to be put into the MySQL Network Monitoring and Advisory Service.
19 years ago
BUG#33029 5.0 to 5.1 replication fails on dup key when inserting using a trig in SP For all 5.0 and up to 5.1.12 exclusive, when a stored routine or trigger caused an INSERT into an AUTO_INCREMENT column, the generated AUTO_INCREMENT value should not be written into the binary log, which means if a statement does not generate AUTO_INCREMENT value itself, there will be no Intvar event (SET INSERT_ID) associated with it even if one of the stored routine or trigger caused generation of such a value. And meanwhile, when executing a stored routine or trigger, it would ignore the INSERT_ID value even if there is a INSERT_ID value available set by a SET INSERT_ID statement. Starting from MySQL 5.1.12, the generated AUTO_INCREMENT value is written into the binary log, and the value will be used if available when executing the stored routine or trigger. Prior fix of this bug in MySQL 5.0 and prior MySQL 5.1.12 (referenced as the buggy versions in the text below), when a statement that generates AUTO_INCREMENT value by the top statement was executed in the body of a SP, all statements in the SP after this statement would be treated as if they had generated AUTO_INCREMENT by the top statement. When a statement that did not generate AUTO_INCREMENT value by the top statement but by a function/trigger called by it, an erroneous Intvar event would be associated with the statement, this erroneous INSERT_ID value wouldn't cause problem when replicating between masters and slaves of 5.0.x or prior 5.1.12, because the erroneous INSERT_ID value was not used when executing functions/triggers. But when replicating from buggy versions to 5.1.12 or newer, which will use the INSERT_ID value in functions/triggers, the erroneous value will be used, which would cause duplicate entry error and cause the slave to stop. The patch for 5.1 fixed it to ignore the SET INSERT_ID value when executing functions/triggers if it is replicating from a master of buggy versions, another patch for 5.0 fixed it not to generate the erroneous Intvar event.
18 years ago
BUG#33029 5.0 to 5.1 replication fails on dup key when inserting using a trig in SP For all 5.0 and up to 5.1.12 exclusive, when a stored routine or trigger caused an INSERT into an AUTO_INCREMENT column, the generated AUTO_INCREMENT value should not be written into the binary log, which means if a statement does not generate AUTO_INCREMENT value itself, there will be no Intvar event (SET INSERT_ID) associated with it even if one of the stored routine or trigger caused generation of such a value. And meanwhile, when executing a stored routine or trigger, it would ignore the INSERT_ID value even if there is a INSERT_ID value available set by a SET INSERT_ID statement. Starting from MySQL 5.1.12, the generated AUTO_INCREMENT value is written into the binary log, and the value will be used if available when executing the stored routine or trigger. Prior fix of this bug in MySQL 5.0 and prior MySQL 5.1.12 (referenced as the buggy versions in the text below), when a statement that generates AUTO_INCREMENT value by the top statement was executed in the body of a SP, all statements in the SP after this statement would be treated as if they had generated AUTO_INCREMENT by the top statement. When a statement that did not generate AUTO_INCREMENT value by the top statement but by a function/trigger called by it, an erroneous Intvar event would be associated with the statement, this erroneous INSERT_ID value wouldn't cause problem when replicating between masters and slaves of 5.0.x or prior 5.1.12, because the erroneous INSERT_ID value was not used when executing functions/triggers. But when replicating from buggy versions to 5.1.12 or newer, which will use the INSERT_ID value in functions/triggers, the erroneous value will be used, which would cause duplicate entry error and cause the slave to stop. The patch for 5.1 fixed it to ignore the SET INSERT_ID value when executing functions/triggers if it is replicating from a master of buggy versions, another patch for 5.0 fixed it not to generate the erroneous Intvar event.
18 years ago
26 years ago
26 years ago
BUG#32407: Impossible to do point-in-time recovery from older binlog Problem: it is unsafe to read base64-printed events without first reading the Format_description_log_event (FD). Currently, mysqlbinlog cannot print the FD. As a side effect, another bug has also been fixed: When mysqlbinlog --start-position=X was specified, no ROLLBACK was printed. I changed this, so that ROLLBACK is always printed. This patch does several things: - Format_description_log_event (FD) now print themselves in base64 format. - mysqlbinlog is now able to print FD events. It has three modes: --base64-output=auto Print row events in base64 output, and print FD event. The FD event is printed even if it is outside the range specified with --start-position, because it would not be safe to read row events otherwise. This is the default. --base64-output=always Like --base64-output=auto, but also print base64 output for query events. This is like the old --base64-output flag, which is also a shorthand for --base64-output=always --base64-output=never Never print base64 output, generate error if row events occur in binlog. This is useful to suppress the FD event in binlogs known not to contain row events (e.g., because BINLOG statement is unsafe, requires root privileges, is not SQL, etc) - the BINLOG statement now handles FD events correctly, by setting the thread's rli's relay log's description_event_for_exec to the loaded event. In fact, executing a BINLOG statement is almost the same as reading an event from a relay log. Before my patch, the code for this was separated (exec_relay_log_event in slave.cc executes events from the relay log, mysql_client_binlog_statement in sql_binlog.cc executes BINLOG statements). I needed to augment mysql_client_binlog_statement to do parts of what exec_relay_log_event does. Hence, I did a small refactoring and moved parts of exec_relay_log_event to a new function, which I named apply_event_and_update_pos. apply_event_and_update_pos is called both from exec_relay_log_event and from mysql_client_binlog_statement. - When a non-FD event is executed in a BINLOG statement, without previously executing a FD event in a BINLOG statement, it generates an error, because that's unsafe. I took a new error code for that: ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENTS. In order to get a decent error message containing the name of the event, I added the class method char* Log_event::get_type_str(Log_event_type type), which returns a string name for the given Log_event_type. This is just like the existing char* Log_event::get_type_str(), except it is a class method that takes the log event type as parameter. I also added PRE_GA_*_ROWS_LOG_EVENT to Log_event::get_type_str(), so that names of old rows event are properly printed. - When reading an event, I added a check that the event type is known by the current Format_description_log_event. Without this, it may crash on bad input (and I was struck by this several times). - I patched the following test cases, which all contain BINLOG statements for row events which must be preceded by BINLOG statements for FD events: - rpl_bug31076 While I was here, I fixed some small things in log_event.cc: - replaced hard-coded 4 by EVENT_TYPE_OFFSET in 3 places - replaced return by DBUG_VOID_RETURN in one place - The name of the logfile can be '-' to indicate stdin. Before my patch, the code just checked if the first character is '-'; now it does a full strcmp(). Probably, all arguments that begin with a - are already handled somewhere else as flags, but I still think it is better that the code reflects what it is supposed to do, with as little dependencies as possible on other parts of the code. If we one day implement that all command line arguments after -- are files (as most unix tools do), then we need this. I also fixed the following in slave.cc: - next_event() was declared twice, and queue_event was not static but should be static (not used outside the file).
18 years ago
  1. /*
  2. Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
  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. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program; if not, write to the Free Software
  12. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  13. */
  14. /**
  15. @addtogroup Replication
  16. @{
  17. @file
  18. @brief Code to run the io thread and the sql thread on the
  19. replication slave.
  20. */
  21. #include "mysql_priv.h"
  22. #include <mysql.h>
  23. #include <myisam.h>
  24. #include "slave.h"
  25. #include "rpl_mi.h"
  26. #include "rpl_rli.h"
  27. #include "sql_repl.h"
  28. #include "rpl_filter.h"
  29. #include "repl_failsafe.h"
  30. #include <thr_alarm.h>
  31. #include <my_dir.h>
  32. #include <sql_common.h>
  33. #include <errmsg.h>
  34. #include <mysqld_error.h>
  35. #include <mysys_err.h>
  36. #ifdef HAVE_REPLICATION
  37. #include "rpl_tblmap.h"
  38. #include "debug_sync.h"
  39. #define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
  40. #define MAX_SLAVE_RETRY_PAUSE 5
  41. bool use_slave_mask = 0;
  42. MY_BITMAP slave_error_mask;
  43. char slave_skip_error_names[SHOW_VAR_FUNC_BUFF_SIZE];
  44. typedef bool (*CHECK_KILLED_FUNC)(THD*,void*);
  45. char* slave_load_tmpdir = 0;
  46. Master_info *active_mi= 0;
  47. my_bool replicate_same_server_id;
  48. ulonglong relay_log_space_limit = 0;
  49. /*
  50. When slave thread exits, we need to remember the temporary tables so we
  51. can re-use them on slave start.
  52. TODO: move the vars below under Master_info
  53. */
  54. int disconnect_slave_event_count = 0, abort_slave_event_count = 0;
  55. int events_till_abort = -1;
  56. enum enum_slave_reconnect_actions
  57. {
  58. SLAVE_RECON_ACT_REG= 0,
  59. SLAVE_RECON_ACT_DUMP= 1,
  60. SLAVE_RECON_ACT_EVENT= 2,
  61. SLAVE_RECON_ACT_MAX
  62. };
  63. enum enum_slave_reconnect_messages
  64. {
  65. SLAVE_RECON_MSG_WAIT= 0,
  66. SLAVE_RECON_MSG_KILLED_WAITING= 1,
  67. SLAVE_RECON_MSG_AFTER= 2,
  68. SLAVE_RECON_MSG_FAILED= 3,
  69. SLAVE_RECON_MSG_COMMAND= 4,
  70. SLAVE_RECON_MSG_KILLED_AFTER= 5,
  71. SLAVE_RECON_MSG_MAX
  72. };
  73. static const char *reconnect_messages[SLAVE_RECON_ACT_MAX][SLAVE_RECON_MSG_MAX]=
  74. {
  75. {
  76. "Waiting to reconnect after a failed registration on master",
  77. "Slave I/O thread killed while waitnig to reconnect after a failed \
  78. registration on master",
  79. "Reconnecting after a failed registration on master",
  80. "failed registering on master, reconnecting to try again, \
  81. log '%s' at position %s",
  82. "COM_REGISTER_SLAVE",
  83. "Slave I/O thread killed during or after reconnect"
  84. },
  85. {
  86. "Waiting to reconnect after a failed binlog dump request",
  87. "Slave I/O thread killed while retrying master dump",
  88. "Reconnecting after a failed binlog dump request",
  89. "failed dump request, reconnecting to try again, log '%s' at position %s",
  90. "COM_BINLOG_DUMP",
  91. "Slave I/O thread killed during or after reconnect"
  92. },
  93. {
  94. "Waiting to reconnect after a failed master event read",
  95. "Slave I/O thread killed while waiting to reconnect after a failed read",
  96. "Reconnecting after a failed master event read",
  97. "Slave I/O thread: Failed reading log event, reconnecting to retry, \
  98. log '%s' at position %s",
  99. "",
  100. "Slave I/O thread killed during or after a reconnect done to recover from \
  101. failed read"
  102. }
  103. };
  104. typedef enum { SLAVE_THD_IO, SLAVE_THD_SQL} SLAVE_THD_TYPE;
  105. static int process_io_rotate(Master_info* mi, Rotate_log_event* rev);
  106. static int process_io_create_file(Master_info* mi, Create_file_log_event* cev);
  107. static bool wait_for_relay_log_space(Relay_log_info* rli);
  108. static inline bool io_slave_killed(THD* thd,Master_info* mi);
  109. static inline bool sql_slave_killed(THD* thd,Relay_log_info* rli);
  110. static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type);
  111. static void print_slave_skip_errors(void);
  112. static int safe_connect(THD* thd, MYSQL* mysql, Master_info* mi);
  113. static int safe_reconnect(THD* thd, MYSQL* mysql, Master_info* mi,
  114. bool suppress_warnings);
  115. static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi,
  116. bool reconnect, bool suppress_warnings);
  117. static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
  118. void* thread_killed_arg);
  119. static int request_table_dump(MYSQL* mysql, const char* db, const char* table);
  120. static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
  121. const char* table_name, bool overwrite);
  122. static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi);
  123. static Log_event* next_event(Relay_log_info* rli);
  124. static int queue_event(Master_info* mi,const char* buf,ulong event_len);
  125. static int terminate_slave_thread(THD *thd,
  126. pthread_mutex_t *term_lock,
  127. pthread_cond_t *term_cond,
  128. volatile uint *slave_running,
  129. bool skip_lock);
  130. static bool check_io_slave_killed(THD *thd, Master_info *mi, const char *info);
  131. /*
  132. Find out which replications threads are running
  133. SYNOPSIS
  134. init_thread_mask()
  135. mask Return value here
  136. mi master_info for slave
  137. inverse If set, returns which threads are not running
  138. IMPLEMENTATION
  139. Get a bit mask for which threads are running so that we can later restart
  140. these threads.
  141. RETURN
  142. mask If inverse == 0, running threads
  143. If inverse == 1, stopped threads
  144. */
  145. void init_thread_mask(int* mask,Master_info* mi,bool inverse)
  146. {
  147. bool set_io = mi->slave_running, set_sql = mi->rli.slave_running;
  148. register int tmp_mask=0;
  149. DBUG_ENTER("init_thread_mask");
  150. if (set_io)
  151. tmp_mask |= SLAVE_IO;
  152. if (set_sql)
  153. tmp_mask |= SLAVE_SQL;
  154. if (inverse)
  155. tmp_mask^= (SLAVE_IO | SLAVE_SQL);
  156. *mask = tmp_mask;
  157. DBUG_VOID_RETURN;
  158. }
  159. /*
  160. lock_slave_threads()
  161. */
  162. void lock_slave_threads(Master_info* mi)
  163. {
  164. DBUG_ENTER("lock_slave_threads");
  165. //TODO: see if we can do this without dual mutex
  166. pthread_mutex_lock(&mi->run_lock);
  167. pthread_mutex_lock(&mi->rli.run_lock);
  168. DBUG_VOID_RETURN;
  169. }
  170. /*
  171. unlock_slave_threads()
  172. */
  173. void unlock_slave_threads(Master_info* mi)
  174. {
  175. DBUG_ENTER("unlock_slave_threads");
  176. //TODO: see if we can do this without dual mutex
  177. pthread_mutex_unlock(&mi->rli.run_lock);
  178. pthread_mutex_unlock(&mi->run_lock);
  179. DBUG_VOID_RETURN;
  180. }
  181. /* Initialize slave structures */
  182. int init_slave()
  183. {
  184. DBUG_ENTER("init_slave");
  185. /*
  186. This is called when mysqld starts. Before client connections are
  187. accepted. However bootstrap may conflict with us if it does START SLAVE.
  188. So it's safer to take the lock.
  189. */
  190. pthread_mutex_lock(&LOCK_active_mi);
  191. /*
  192. TODO: re-write this to interate through the list of files
  193. for multi-master
  194. */
  195. active_mi= new Master_info;
  196. /*
  197. If --slave-skip-errors=... was not used, the string value for the
  198. system variable has not been set up yet. Do it now.
  199. */
  200. if (!use_slave_mask)
  201. {
  202. print_slave_skip_errors();
  203. }
  204. /*
  205. If master_host is not specified, try to read it from the master_info file.
  206. If master_host is specified, create the master_info file if it doesn't
  207. exists.
  208. */
  209. if (!active_mi)
  210. {
  211. sql_print_error("Failed to allocate memory for the master info structure");
  212. goto err;
  213. }
  214. if (init_master_info(active_mi,master_info_file,relay_log_info_file,
  215. !master_host, (SLAVE_IO | SLAVE_SQL)))
  216. {
  217. sql_print_error("Failed to initialize the master info structure");
  218. goto err;
  219. }
  220. if (server_id && !master_host && active_mi->host[0])
  221. master_host= active_mi->host;
  222. /* If server id is not set, start_slave_thread() will say it */
  223. if (master_host && !opt_skip_slave_start)
  224. {
  225. if (start_slave_threads(1 /* need mutex */,
  226. 0 /* no wait for start*/,
  227. active_mi,
  228. master_info_file,
  229. relay_log_info_file,
  230. SLAVE_IO | SLAVE_SQL))
  231. {
  232. sql_print_error("Failed to create slave threads");
  233. goto err;
  234. }
  235. }
  236. pthread_mutex_unlock(&LOCK_active_mi);
  237. DBUG_RETURN(0);
  238. err:
  239. pthread_mutex_unlock(&LOCK_active_mi);
  240. DBUG_RETURN(1);
  241. }
  242. /**
  243. Convert slave skip errors bitmap into a printable string.
  244. */
  245. static void print_slave_skip_errors(void)
  246. {
  247. /*
  248. To be safe, we want 10 characters of room in the buffer for a number
  249. plus terminators. Also, we need some space for constant strings.
  250. 10 characters must be sufficient for a number plus {',' | '...'}
  251. plus a NUL terminator. That is a max 6 digit number.
  252. */
  253. const size_t MIN_ROOM= 10;
  254. DBUG_ENTER("print_slave_skip_errors");
  255. DBUG_ASSERT(sizeof(slave_skip_error_names) > MIN_ROOM);
  256. DBUG_ASSERT(MAX_SLAVE_ERROR <= 999999); // 6 digits
  257. if (!use_slave_mask || bitmap_is_clear_all(&slave_error_mask))
  258. {
  259. /* purecov: begin tested */
  260. memcpy(slave_skip_error_names, STRING_WITH_LEN("OFF"));
  261. /* purecov: end */
  262. }
  263. else if (bitmap_is_set_all(&slave_error_mask))
  264. {
  265. /* purecov: begin tested */
  266. memcpy(slave_skip_error_names, STRING_WITH_LEN("ALL"));
  267. /* purecov: end */
  268. }
  269. else
  270. {
  271. char *buff= slave_skip_error_names;
  272. char *bend= buff + sizeof(slave_skip_error_names);
  273. int errnum;
  274. for (errnum= 0; errnum < MAX_SLAVE_ERROR; errnum++)
  275. {
  276. if (bitmap_is_set(&slave_error_mask, errnum))
  277. {
  278. if (buff + MIN_ROOM >= bend)
  279. break; /* purecov: tested */
  280. buff= int10_to_str(errnum, buff, 10);
  281. *buff++= ',';
  282. }
  283. }
  284. if (buff != slave_skip_error_names)
  285. buff--; // Remove last ','
  286. if (errnum < MAX_SLAVE_ERROR)
  287. {
  288. /* Couldn't show all errors */
  289. buff= strmov(buff, "..."); /* purecov: tested */
  290. }
  291. *buff=0;
  292. }
  293. DBUG_PRINT("init", ("error_names: '%s'", slave_skip_error_names));
  294. DBUG_VOID_RETURN;
  295. }
  296. /*
  297. Init function to set up array for errors that should be skipped for slave
  298. SYNOPSIS
  299. init_slave_skip_errors()
  300. arg List of errors numbers to skip, separated with ','
  301. NOTES
  302. Called from get_options() in mysqld.cc on start-up
  303. */
  304. void init_slave_skip_errors(const char* arg)
  305. {
  306. const char *p;
  307. DBUG_ENTER("init_slave_skip_errors");
  308. if (bitmap_init(&slave_error_mask,0,MAX_SLAVE_ERROR,0))
  309. {
  310. fprintf(stderr, "Badly out of memory, please check your system status\n");
  311. exit(1);
  312. }
  313. use_slave_mask = 1;
  314. for (;my_isspace(system_charset_info,*arg);++arg)
  315. /* empty */;
  316. if (!my_strnncoll(system_charset_info,(uchar*)arg,4,(const uchar*)"all",4))
  317. {
  318. bitmap_set_all(&slave_error_mask);
  319. print_slave_skip_errors();
  320. DBUG_VOID_RETURN;
  321. }
  322. for (p= arg ; *p; )
  323. {
  324. long err_code;
  325. if (!(p= str2int(p, 10, 0, LONG_MAX, &err_code)))
  326. break;
  327. if (err_code < MAX_SLAVE_ERROR)
  328. bitmap_set_bit(&slave_error_mask,(uint)err_code);
  329. while (!my_isdigit(system_charset_info,*p) && *p)
  330. p++;
  331. }
  332. /* Convert slave skip errors bitmap into a printable string. */
  333. print_slave_skip_errors();
  334. DBUG_VOID_RETURN;
  335. }
  336. static void set_thd_in_use_temporary_tables(Relay_log_info *rli)
  337. {
  338. TABLE *table;
  339. for (table= rli->save_temporary_tables ; table ; table= table->next)
  340. table->in_use= rli->sql_thd;
  341. }
  342. int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock)
  343. {
  344. DBUG_ENTER("terminate_slave_threads");
  345. if (!mi->inited)
  346. DBUG_RETURN(0); /* successfully do nothing */
  347. int error,force_all = (thread_mask & SLAVE_FORCE_ALL);
  348. pthread_mutex_t *sql_lock = &mi->rli.run_lock, *io_lock = &mi->run_lock;
  349. if (thread_mask & (SLAVE_SQL|SLAVE_FORCE_ALL))
  350. {
  351. DBUG_PRINT("info",("Terminating SQL thread"));
  352. mi->rli.abort_slave=1;
  353. if ((error=terminate_slave_thread(mi->rli.sql_thd, sql_lock,
  354. &mi->rli.stop_cond,
  355. &mi->rli.slave_running,
  356. skip_lock)) &&
  357. !force_all)
  358. DBUG_RETURN(error);
  359. }
  360. if (thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL))
  361. {
  362. DBUG_PRINT("info",("Terminating IO thread"));
  363. mi->abort_slave=1;
  364. if ((error=terminate_slave_thread(mi->io_thd, io_lock,
  365. &mi->stop_cond,
  366. &mi->slave_running,
  367. skip_lock)) &&
  368. !force_all)
  369. DBUG_RETURN(error);
  370. }
  371. DBUG_RETURN(0);
  372. }
  373. /**
  374. Wait for a slave thread to terminate.
  375. This function is called after requesting the thread to terminate
  376. (by setting @c abort_slave member of @c Relay_log_info or @c
  377. Master_info structure to 1). Termination of the thread is
  378. controlled with the the predicate <code>*slave_running</code>.
  379. Function will acquire @c term_lock before waiting on the condition
  380. unless @c skip_lock is true in which case the mutex should be owned
  381. by the caller of this function and will remain acquired after
  382. return from the function.
  383. @param term_lock
  384. Associated lock to use when waiting for @c term_cond
  385. @param term_cond
  386. Condition that is signalled when the thread has terminated
  387. @param slave_running
  388. Pointer to predicate to check for slave thread termination
  389. @param skip_lock
  390. If @c true the lock will not be acquired before waiting on
  391. the condition. In this case, it is assumed that the calling
  392. function acquires the lock before calling this function.
  393. @retval 0 All OK ER_SLAVE_NOT_RUNNING otherwise.
  394. @note If the executing thread has to acquire term_lock (skip_lock
  395. is false), the negative running status does not represent
  396. any issue therefore no error is reported.
  397. */
  398. static int
  399. terminate_slave_thread(THD *thd,
  400. pthread_mutex_t *term_lock,
  401. pthread_cond_t *term_cond,
  402. volatile uint *slave_running,
  403. bool skip_lock)
  404. {
  405. DBUG_ENTER("terminate_slave_thread");
  406. if (!skip_lock)
  407. {
  408. pthread_mutex_lock(term_lock);
  409. }
  410. else
  411. {
  412. safe_mutex_assert_owner(term_lock);
  413. }
  414. if (!*slave_running)
  415. {
  416. if (!skip_lock)
  417. {
  418. /*
  419. if run_lock (term_lock) is acquired locally then either
  420. slave_running status is fine
  421. */
  422. pthread_mutex_unlock(term_lock);
  423. DBUG_RETURN(0);
  424. }
  425. else
  426. {
  427. DBUG_RETURN(ER_SLAVE_NOT_RUNNING);
  428. }
  429. }
  430. DBUG_ASSERT(thd != 0);
  431. THD_CHECK_SENTRY(thd);
  432. /*
  433. Is is critical to test if the slave is running. Otherwise, we might
  434. be referening freed memory trying to kick it
  435. */
  436. while (*slave_running) // Should always be true
  437. {
  438. int error;
  439. DBUG_PRINT("loop", ("killing slave thread"));
  440. pthread_mutex_lock(&thd->LOCK_thd_data);
  441. #ifndef DONT_USE_THR_ALARM
  442. /*
  443. Error codes from pthread_kill are:
  444. EINVAL: invalid signal number (can't happen)
  445. ESRCH: thread already killed (can happen, should be ignored)
  446. */
  447. IF_DBUG(int err= ) pthread_kill(thd->real_id, thr_client_alarm);
  448. DBUG_ASSERT(err != EINVAL);
  449. #endif
  450. thd->awake(THD::NOT_KILLED);
  451. pthread_mutex_unlock(&thd->LOCK_thd_data);
  452. /*
  453. There is a small chance that slave thread might miss the first
  454. alarm. To protect againts it, resend the signal until it reacts
  455. */
  456. struct timespec abstime;
  457. set_timespec(abstime,2);
  458. error= pthread_cond_timedwait(term_cond, term_lock, &abstime);
  459. DBUG_ASSERT(error == ETIMEDOUT || error == 0);
  460. }
  461. DBUG_ASSERT(*slave_running == 0);
  462. if (!skip_lock)
  463. pthread_mutex_unlock(term_lock);
  464. DBUG_RETURN(0);
  465. }
  466. int start_slave_thread(pthread_handler h_func, pthread_mutex_t *start_lock,
  467. pthread_mutex_t *cond_lock,
  468. pthread_cond_t *start_cond,
  469. volatile uint *slave_running,
  470. volatile ulong *slave_run_id,
  471. Master_info* mi,
  472. bool high_priority)
  473. {
  474. pthread_t th;
  475. ulong start_id;
  476. DBUG_ENTER("start_slave_thread");
  477. DBUG_ASSERT(mi->inited);
  478. if (start_lock)
  479. pthread_mutex_lock(start_lock);
  480. if (!server_id)
  481. {
  482. if (start_cond)
  483. pthread_cond_broadcast(start_cond);
  484. if (start_lock)
  485. pthread_mutex_unlock(start_lock);
  486. sql_print_error("Server id not set, will not start slave");
  487. DBUG_RETURN(ER_BAD_SLAVE);
  488. }
  489. if (*slave_running)
  490. {
  491. if (start_cond)
  492. pthread_cond_broadcast(start_cond);
  493. if (start_lock)
  494. pthread_mutex_unlock(start_lock);
  495. DBUG_RETURN(ER_SLAVE_MUST_STOP);
  496. }
  497. start_id= *slave_run_id;
  498. DBUG_PRINT("info",("Creating new slave thread"));
  499. if (high_priority)
  500. my_pthread_attr_setprio(&connection_attrib,CONNECT_PRIOR);
  501. if (pthread_create(&th, &connection_attrib, h_func, (void*)mi))
  502. {
  503. if (start_lock)
  504. pthread_mutex_unlock(start_lock);
  505. DBUG_RETURN(ER_SLAVE_THREAD);
  506. }
  507. if (start_cond && cond_lock) // caller has cond_lock
  508. {
  509. THD* thd = current_thd;
  510. while (start_id == *slave_run_id)
  511. {
  512. DBUG_PRINT("sleep",("Waiting for slave thread to start"));
  513. const char* old_msg = thd->enter_cond(start_cond,cond_lock,
  514. "Waiting for slave thread to start");
  515. pthread_cond_wait(start_cond, cond_lock);
  516. thd->exit_cond(old_msg);
  517. pthread_mutex_lock(cond_lock); // re-acquire it as exit_cond() released
  518. if (thd->killed)
  519. {
  520. if (start_lock)
  521. pthread_mutex_unlock(start_lock);
  522. DBUG_RETURN(thd->killed_errno());
  523. }
  524. }
  525. }
  526. if (start_lock)
  527. pthread_mutex_unlock(start_lock);
  528. DBUG_RETURN(0);
  529. }
  530. /*
  531. start_slave_threads()
  532. NOTES
  533. SLAVE_FORCE_ALL is not implemented here on purpose since it does not make
  534. sense to do that for starting a slave--we always care if it actually
  535. started the threads that were not previously running
  536. */
  537. int start_slave_threads(bool need_slave_mutex, bool wait_for_start,
  538. Master_info* mi, const char* master_info_fname,
  539. const char* slave_info_fname, int thread_mask)
  540. {
  541. pthread_mutex_t *lock_io=0,*lock_sql=0,*lock_cond_io=0,*lock_cond_sql=0;
  542. pthread_cond_t* cond_io=0,*cond_sql=0;
  543. int error=0;
  544. DBUG_ENTER("start_slave_threads");
  545. if (need_slave_mutex)
  546. {
  547. lock_io = &mi->run_lock;
  548. lock_sql = &mi->rli.run_lock;
  549. }
  550. if (wait_for_start)
  551. {
  552. cond_io = &mi->start_cond;
  553. cond_sql = &mi->rli.start_cond;
  554. lock_cond_io = &mi->run_lock;
  555. lock_cond_sql = &mi->rli.run_lock;
  556. }
  557. if (thread_mask & SLAVE_IO)
  558. error=start_slave_thread(handle_slave_io,lock_io,lock_cond_io,
  559. cond_io,
  560. &mi->slave_running, &mi->slave_run_id,
  561. mi, 1); //high priority, to read the most possible
  562. if (!error && (thread_mask & SLAVE_SQL))
  563. {
  564. error=start_slave_thread(handle_slave_sql,lock_sql,lock_cond_sql,
  565. cond_sql,
  566. &mi->rli.slave_running, &mi->rli.slave_run_id,
  567. mi, 0);
  568. if (error)
  569. terminate_slave_threads(mi, thread_mask & SLAVE_IO, !need_slave_mutex);
  570. }
  571. DBUG_RETURN(error);
  572. }
  573. #ifdef NOT_USED_YET
  574. static int end_slave_on_walk(Master_info* mi, uchar* /*unused*/)
  575. {
  576. DBUG_ENTER("end_slave_on_walk");
  577. end_master_info(mi);
  578. DBUG_RETURN(0);
  579. }
  580. #endif
  581. /*
  582. Release slave threads at time of executing shutdown.
  583. SYNOPSIS
  584. end_slave()
  585. */
  586. void end_slave()
  587. {
  588. DBUG_ENTER("end_slave");
  589. /*
  590. This is called when the server terminates, in close_connections().
  591. It terminates slave threads. However, some CHANGE MASTER etc may still be
  592. running presently. If a START SLAVE was in progress, the mutex lock below
  593. will make us wait until slave threads have started, and START SLAVE
  594. returns, then we terminate them here.
  595. */
  596. pthread_mutex_lock(&LOCK_active_mi);
  597. if (active_mi)
  598. {
  599. /*
  600. TODO: replace the line below with
  601. list_walk(&master_list, (list_walk_action)end_slave_on_walk,0);
  602. once multi-master code is ready.
  603. */
  604. terminate_slave_threads(active_mi,SLAVE_FORCE_ALL);
  605. }
  606. pthread_mutex_unlock(&LOCK_active_mi);
  607. DBUG_VOID_RETURN;
  608. }
  609. /**
  610. Free all resources used by slave threads at time of executing shutdown.
  611. The routine must be called after all possible users of @c active_mi
  612. have left.
  613. SYNOPSIS
  614. close_active_mi()
  615. */
  616. void close_active_mi()
  617. {
  618. pthread_mutex_lock(&LOCK_active_mi);
  619. if (active_mi)
  620. {
  621. end_master_info(active_mi);
  622. delete active_mi;
  623. active_mi= 0;
  624. }
  625. pthread_mutex_unlock(&LOCK_active_mi);
  626. }
  627. static bool io_slave_killed(THD* thd, Master_info* mi)
  628. {
  629. DBUG_ENTER("io_slave_killed");
  630. DBUG_ASSERT(mi->io_thd == thd);
  631. DBUG_ASSERT(mi->slave_running); // tracking buffer overrun
  632. DBUG_RETURN(mi->abort_slave || abort_loop || thd->killed);
  633. }
  634. static bool sql_slave_killed(THD* thd, Relay_log_info* rli)
  635. {
  636. DBUG_ENTER("sql_slave_killed");
  637. DBUG_ASSERT(rli->sql_thd == thd);
  638. DBUG_ASSERT(rli->slave_running == 1);// tracking buffer overrun
  639. if (abort_loop || thd->killed || rli->abort_slave)
  640. {
  641. /*
  642. The transaction should always be binlogged if OPTION_KEEP_LOG is set
  643. (it implies that something can not be rolled back). And such case
  644. should be regarded similarly as modifing a non-transactional table
  645. because retrying of the transaction will lead to an error or inconsistency
  646. as well.
  647. Example: OPTION_KEEP_LOG is set if a temporary table is created or dropped.
  648. */
  649. if (rli->abort_slave && rli->is_in_group() &&
  650. (thd->transaction.all.modified_non_trans_table ||
  651. (thd->options & OPTION_KEEP_LOG)))
  652. DBUG_RETURN(0);
  653. /*
  654. If we are in an unsafe situation (stopping could corrupt replication),
  655. we give one minute to the slave SQL thread of grace before really
  656. terminating, in the hope that it will be able to read more events and
  657. the unsafe situation will soon be left. Note that this one minute starts
  658. from the last time anything happened in the slave SQL thread. So it's
  659. really one minute of idleness, we don't timeout if the slave SQL thread
  660. is actively working.
  661. */
  662. if (rli->last_event_start_time == 0)
  663. DBUG_RETURN(1);
  664. DBUG_PRINT("info", ("Slave SQL thread is in an unsafe situation, giving "
  665. "it some grace period"));
  666. if (difftime(time(0), rli->last_event_start_time) > 60)
  667. {
  668. rli->report(ERROR_LEVEL, 0,
  669. "SQL thread had to stop in an unsafe situation, in "
  670. "the middle of applying updates to a "
  671. "non-transactional table without any primary key. "
  672. "There is a risk of duplicate updates when the slave "
  673. "SQL thread is restarted. Please check your tables' "
  674. "contents after restart.");
  675. DBUG_RETURN(1);
  676. }
  677. }
  678. DBUG_RETURN(0);
  679. }
  680. /*
  681. skip_load_data_infile()
  682. NOTES
  683. This is used to tell a 3.23 master to break send_file()
  684. */
  685. void skip_load_data_infile(NET *net)
  686. {
  687. DBUG_ENTER("skip_load_data_infile");
  688. (void)net_request_file(net, "/dev/null");
  689. (void)my_net_read(net); // discard response
  690. (void)net_write_command(net, 0, (uchar*) "", 0, (uchar*) "", 0); // ok
  691. DBUG_VOID_RETURN;
  692. }
  693. bool net_request_file(NET* net, const char* fname)
  694. {
  695. DBUG_ENTER("net_request_file");
  696. DBUG_RETURN(net_write_command(net, 251, (uchar*) fname, strlen(fname),
  697. (uchar*) "", 0));
  698. }
  699. /*
  700. From other comments and tests in code, it looks like
  701. sometimes Query_log_event and Load_log_event can have db == 0
  702. (see rewrite_db() above for example)
  703. (cases where this happens are unclear; it may be when the master is 3.23).
  704. */
  705. const char *print_slave_db_safe(const char* db)
  706. {
  707. DBUG_ENTER("*print_slave_db_safe");
  708. DBUG_RETURN((db ? db : ""));
  709. }
  710. int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
  711. const char *default_val)
  712. {
  713. uint length;
  714. DBUG_ENTER("init_strvar_from_file");
  715. if ((length=my_b_gets(f,var, max_size)))
  716. {
  717. char* last_p = var + length -1;
  718. if (*last_p == '\n')
  719. *last_p = 0; // if we stopped on newline, kill it
  720. else
  721. {
  722. /*
  723. If we truncated a line or stopped on last char, remove all chars
  724. up to and including newline.
  725. */
  726. int c;
  727. while (((c=my_b_get(f)) != '\n' && c != my_b_EOF)) ;
  728. }
  729. DBUG_RETURN(0);
  730. }
  731. else if (default_val)
  732. {
  733. strmake(var, default_val, max_size-1);
  734. DBUG_RETURN(0);
  735. }
  736. DBUG_RETURN(1);
  737. }
  738. int init_intvar_from_file(int* var, IO_CACHE* f, int default_val)
  739. {
  740. char buf[32];
  741. DBUG_ENTER("init_intvar_from_file");
  742. if (my_b_gets(f, buf, sizeof(buf)))
  743. {
  744. *var = atoi(buf);
  745. DBUG_RETURN(0);
  746. }
  747. else if (default_val)
  748. {
  749. *var = default_val;
  750. DBUG_RETURN(0);
  751. }
  752. DBUG_RETURN(1);
  753. }
  754. /*
  755. Check if the error is caused by network.
  756. @param[in] errorno Number of the error.
  757. RETURNS:
  758. TRUE network error
  759. FALSE not network error
  760. */
  761. bool is_network_error(uint errorno)
  762. {
  763. if (errorno == CR_CONNECTION_ERROR ||
  764. errorno == CR_CONN_HOST_ERROR ||
  765. errorno == CR_SERVER_GONE_ERROR ||
  766. errorno == CR_SERVER_LOST ||
  767. errorno == ER_CON_COUNT_ERROR ||
  768. errorno == ER_SERVER_SHUTDOWN)
  769. return TRUE;
  770. return FALSE;
  771. }
  772. /*
  773. Note that we rely on the master's version (3.23, 4.0.14 etc) instead of
  774. relying on the binlog's version. This is not perfect: imagine an upgrade
  775. of the master without waiting that all slaves are in sync with the master;
  776. then a slave could be fooled about the binlog's format. This is what happens
  777. when people upgrade a 3.23 master to 4.0 without doing RESET MASTER: 4.0
  778. slaves are fooled. So we do this only to distinguish between 3.23 and more
  779. recent masters (it's too late to change things for 3.23).
  780. RETURNS
  781. 0 ok
  782. 1 error
  783. 2 transient network problem, the caller should try to reconnect
  784. */
  785. static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi)
  786. {
  787. char err_buff[MAX_SLAVE_ERRMSG];
  788. const char* errmsg= 0;
  789. int err_code= 0;
  790. MYSQL_RES *master_res= 0;
  791. MYSQL_ROW master_row;
  792. DBUG_ENTER("get_master_version_and_clock");
  793. /*
  794. Free old description_event_for_queue (that is needed if we are in
  795. a reconnection).
  796. */
  797. delete mi->rli.relay_log.description_event_for_queue;
  798. mi->rli.relay_log.description_event_for_queue= 0;
  799. if (!my_isdigit(&my_charset_bin,*mysql->server_version))
  800. {
  801. errmsg = "Master reported unrecognized MySQL version";
  802. err_code= ER_SLAVE_FATAL_ERROR;
  803. sprintf(err_buff, ER(err_code), errmsg);
  804. }
  805. else
  806. {
  807. /*
  808. Note the following switch will bug when we have MySQL branch 30 ;)
  809. */
  810. switch (*mysql->server_version)
  811. {
  812. case '0':
  813. case '1':
  814. case '2':
  815. errmsg = "Master reported unrecognized MySQL version";
  816. err_code= ER_SLAVE_FATAL_ERROR;
  817. sprintf(err_buff, ER(err_code), errmsg);
  818. break;
  819. case '3':
  820. mi->rli.relay_log.description_event_for_queue= new
  821. Format_description_log_event(1, mysql->server_version);
  822. break;
  823. case '4':
  824. mi->rli.relay_log.description_event_for_queue= new
  825. Format_description_log_event(3, mysql->server_version);
  826. break;
  827. default:
  828. /*
  829. Master is MySQL >=5.0. Give a default Format_desc event, so that we can
  830. take the early steps (like tests for "is this a 3.23 master") which we
  831. have to take before we receive the real master's Format_desc which will
  832. override this one. Note that the Format_desc we create below is garbage
  833. (it has the format of the *slave*); it's only good to help know if the
  834. master is 3.23, 4.0, etc.
  835. */
  836. mi->rli.relay_log.description_event_for_queue= new
  837. Format_description_log_event(4, mysql->server_version);
  838. break;
  839. }
  840. }
  841. /*
  842. This does not mean that a 5.0 slave will be able to read a 6.0 master; but
  843. as we don't know yet, we don't want to forbid this for now. If a 5.0 slave
  844. can't read a 6.0 master, this will show up when the slave can't read some
  845. events sent by the master, and there will be error messages.
  846. */
  847. if (errmsg)
  848. goto err;
  849. /* as we are here, we tried to allocate the event */
  850. if (!mi->rli.relay_log.description_event_for_queue)
  851. {
  852. errmsg= "default Format_description_log_event";
  853. err_code= ER_SLAVE_CREATE_EVENT_FAILURE;
  854. sprintf(err_buff, ER(err_code), errmsg);
  855. goto err;
  856. }
  857. /*
  858. Compare the master and slave's clock. Do not die if master's clock is
  859. unavailable (very old master not supporting UNIX_TIMESTAMP()?).
  860. */
  861. DBUG_EXECUTE_IF("dbug.before_get_UNIX_TIMESTAMP",
  862. {
  863. const char act[]=
  864. "now "
  865. "wait_for signal.get_unix_timestamp";
  866. DBUG_ASSERT(opt_debug_sync_timeout > 0);
  867. DBUG_ASSERT(!debug_sync_set_action(current_thd,
  868. STRING_WITH_LEN(act)));
  869. };);
  870. master_res= NULL;
  871. if (!mysql_real_query(mysql, STRING_WITH_LEN("SELECT UNIX_TIMESTAMP()")) &&
  872. (master_res= mysql_store_result(mysql)) &&
  873. (master_row= mysql_fetch_row(master_res)))
  874. {
  875. mi->clock_diff_with_master=
  876. (long) (time((time_t*) 0) - strtoul(master_row[0], 0, 10));
  877. }
  878. else if (is_network_error(mysql_errno(mysql)))
  879. {
  880. mi->report(WARNING_LEVEL, mysql_errno(mysql),
  881. "Get master clock failed with error: %s", mysql_error(mysql));
  882. goto network_err;
  883. }
  884. else
  885. {
  886. mi->clock_diff_with_master= 0; /* The "most sensible" value */
  887. sql_print_warning("\"SELECT UNIX_TIMESTAMP()\" failed on master, "
  888. "do not trust column Seconds_Behind_Master of SHOW "
  889. "SLAVE STATUS. Error: %s (%d)",
  890. mysql_error(mysql), mysql_errno(mysql));
  891. }
  892. if (master_res)
  893. {
  894. mysql_free_result(master_res);
  895. master_res= NULL;
  896. }
  897. /*
  898. Check that the master's server id and ours are different. Because if they
  899. are equal (which can result from a simple copy of master's datadir to slave,
  900. thus copying some my.cnf), replication will work but all events will be
  901. skipped.
  902. Do not die if SHOW VARIABLES LIKE 'SERVER_ID' fails on master (very old
  903. master?).
  904. Note: we could have put a @@SERVER_ID in the previous SELECT
  905. UNIX_TIMESTAMP() instead, but this would not have worked on 3.23 masters.
  906. */
  907. DBUG_EXECUTE_IF("dbug.before_get_SERVER_ID",
  908. {
  909. const char act[]=
  910. "now "
  911. "wait_for signal.get_server_id";
  912. DBUG_ASSERT(opt_debug_sync_timeout > 0);
  913. DBUG_ASSERT(!debug_sync_set_action(current_thd,
  914. STRING_WITH_LEN(act)));
  915. };);
  916. master_res= NULL;
  917. master_row= NULL;
  918. if (!mysql_real_query(mysql,
  919. STRING_WITH_LEN("SHOW VARIABLES LIKE 'SERVER_ID'")) &&
  920. (master_res= mysql_store_result(mysql)) &&
  921. (master_row= mysql_fetch_row(master_res)))
  922. {
  923. if ((::server_id == strtoul(master_row[1], 0, 10)) &&
  924. !mi->rli.replicate_same_server_id)
  925. {
  926. errmsg= "The slave I/O thread stops because master and slave have equal \
  927. MySQL server ids; these ids must be different for replication to work (or \
  928. the --replicate-same-server-id option must be used on slave but this does \
  929. not always make sense; please check the manual before using it).";
  930. err_code= ER_SLAVE_FATAL_ERROR;
  931. sprintf(err_buff, ER(err_code), errmsg);
  932. goto err;
  933. }
  934. }
  935. else if (mysql_errno(mysql))
  936. {
  937. if (is_network_error(mysql_errno(mysql)))
  938. {
  939. mi->report(WARNING_LEVEL, mysql_errno(mysql),
  940. "Get master SERVER_ID failed with error: %s", mysql_error(mysql));
  941. goto network_err;
  942. }
  943. /* Fatal error */
  944. errmsg= "The slave I/O thread stops because a fatal error is encountered \
  945. when it try to get the value of SERVER_ID variable from master.";
  946. err_code= mysql_errno(mysql);
  947. sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
  948. goto err;
  949. }
  950. else if (!master_row && master_res)
  951. {
  952. mi->report(WARNING_LEVEL, ER_UNKNOWN_SYSTEM_VARIABLE,
  953. "Unknown system variable 'SERVER_ID' on master, \
  954. maybe it is a *VERY OLD MASTER*.");
  955. }
  956. if (master_res)
  957. {
  958. mysql_free_result(master_res);
  959. master_res= NULL;
  960. }
  961. /*
  962. Check that the master's global character_set_server and ours are the same.
  963. Not fatal if query fails (old master?).
  964. Note that we don't check for equality of global character_set_client and
  965. collation_connection (neither do we prevent their setting in
  966. set_var.cc). That's because from what I (Guilhem) have tested, the global
  967. values of these 2 are never used (new connections don't use them).
  968. We don't test equality of global collation_database either as it's is
  969. going to be deprecated (made read-only) in 4.1 very soon.
  970. The test is only relevant if master < 5.0.3 (we'll test only if it's older
  971. than the 5 branch; < 5.0.3 was alpha...), as >= 5.0.3 master stores
  972. charset info in each binlog event.
  973. We don't do it for 3.23 because masters <3.23.50 hang on
  974. SELECT @@unknown_var (BUG#7965 - see changelog of 3.23.50). So finally we
  975. test only if master is 4.x.
  976. */
  977. /* redundant with rest of code but safer against later additions */
  978. if (*mysql->server_version == '3')
  979. goto err;
  980. if (*mysql->server_version == '4')
  981. {
  982. master_res= NULL;
  983. if (!mysql_real_query(mysql,
  984. STRING_WITH_LEN("SELECT @@GLOBAL.COLLATION_SERVER")) &&
  985. (master_res= mysql_store_result(mysql)) &&
  986. (master_row= mysql_fetch_row(master_res)))
  987. {
  988. if (strcmp(master_row[0], global_system_variables.collation_server->name))
  989. {
  990. errmsg= "The slave I/O thread stops because master and slave have \
  991. different values for the COLLATION_SERVER global variable. The values must \
  992. be equal for the Statement-format replication to work";
  993. err_code= ER_SLAVE_FATAL_ERROR;
  994. sprintf(err_buff, ER(err_code), errmsg);
  995. goto err;
  996. }
  997. }
  998. else if (is_network_error(mysql_errno(mysql)))
  999. {
  1000. mi->report(WARNING_LEVEL, mysql_errno(mysql),
  1001. "Get master COLLATION_SERVER failed with error: %s", mysql_error(mysql));
  1002. goto network_err;
  1003. }
  1004. else if (mysql_errno(mysql) != ER_UNKNOWN_SYSTEM_VARIABLE)
  1005. {
  1006. /* Fatal error */
  1007. errmsg= "The slave I/O thread stops because a fatal error is encountered \
  1008. when it try to get the value of COLLATION_SERVER global variable from master.";
  1009. err_code= mysql_errno(mysql);
  1010. sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
  1011. goto err;
  1012. }
  1013. else
  1014. mi->report(WARNING_LEVEL, ER_UNKNOWN_SYSTEM_VARIABLE,
  1015. "Unknown system variable 'COLLATION_SERVER' on master, \
  1016. maybe it is a *VERY OLD MASTER*. *NOTE*: slave may experience \
  1017. inconsistency if replicated data deals with collation.");
  1018. if (master_res)
  1019. {
  1020. mysql_free_result(master_res);
  1021. master_res= NULL;
  1022. }
  1023. }
  1024. /*
  1025. Perform analogous check for time zone. Theoretically we also should
  1026. perform check here to verify that SYSTEM time zones are the same on
  1027. slave and master, but we can't rely on value of @@system_time_zone
  1028. variable (it is time zone abbreviation) since it determined at start
  1029. time and so could differ for slave and master even if they are really
  1030. in the same system time zone. So we are omiting this check and just
  1031. relying on documentation. Also according to Monty there are many users
  1032. who are using replication between servers in various time zones. Hence
  1033. such check will broke everything for them. (And now everything will
  1034. work for them because by default both their master and slave will have
  1035. 'SYSTEM' time zone).
  1036. This check is only necessary for 4.x masters (and < 5.0.4 masters but
  1037. those were alpha).
  1038. */
  1039. if (*mysql->server_version == '4')
  1040. {
  1041. master_res= NULL;
  1042. if (!mysql_real_query(mysql, STRING_WITH_LEN("SELECT @@GLOBAL.TIME_ZONE")) &&
  1043. (master_res= mysql_store_result(mysql)) &&
  1044. (master_row= mysql_fetch_row(master_res)))
  1045. {
  1046. if (strcmp(master_row[0],
  1047. global_system_variables.time_zone->get_name()->ptr()))
  1048. {
  1049. errmsg= "The slave I/O thread stops because master and slave have \
  1050. different values for the TIME_ZONE global variable. The values must \
  1051. be equal for the Statement-format replication to work";
  1052. err_code= ER_SLAVE_FATAL_ERROR;
  1053. sprintf(err_buff, ER(err_code), errmsg);
  1054. goto err;
  1055. }
  1056. }
  1057. else if (is_network_error(mysql_errno(mysql)))
  1058. {
  1059. mi->report(WARNING_LEVEL, mysql_errno(mysql),
  1060. "Get master TIME_ZONE failed with error: %s", mysql_error(mysql));
  1061. goto network_err;
  1062. }
  1063. else
  1064. {
  1065. /* Fatal error */
  1066. errmsg= "The slave I/O thread stops because a fatal error is encountered \
  1067. when it try to get the value of TIME_ZONE global variable from master.";
  1068. err_code= mysql_errno(mysql);
  1069. sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
  1070. goto err;
  1071. }
  1072. if (master_res)
  1073. {
  1074. mysql_free_result(master_res);
  1075. master_res= NULL;
  1076. }
  1077. }
  1078. err:
  1079. if (errmsg)
  1080. {
  1081. if (master_res)
  1082. mysql_free_result(master_res);
  1083. DBUG_ASSERT(err_code != 0);
  1084. mi->report(ERROR_LEVEL, err_code, "%s", err_buff);
  1085. DBUG_RETURN(1);
  1086. }
  1087. DBUG_RETURN(0);
  1088. network_err:
  1089. if (master_res)
  1090. mysql_free_result(master_res);
  1091. DBUG_RETURN(2);
  1092. }
  1093. /*
  1094. Used by fetch_master_table (used by LOAD TABLE tblname FROM MASTER and LOAD
  1095. DATA FROM MASTER). Drops the table (if 'overwrite' is true) and recreates it
  1096. from the dump. Honours replication inclusion/exclusion rules.
  1097. db must be non-zero (guarded by assertion).
  1098. RETURN VALUES
  1099. 0 success
  1100. 1 error
  1101. */
  1102. static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
  1103. const char* table_name, bool overwrite)
  1104. {
  1105. ulong packet_len;
  1106. char *query, *save_db;
  1107. uint32 save_db_length;
  1108. Vio* save_vio;
  1109. HA_CHECK_OPT check_opt;
  1110. TABLE_LIST tables;
  1111. int error= 1;
  1112. handler *file;
  1113. ulonglong save_options;
  1114. NET *net= &mysql->net;
  1115. const char *found_semicolon= NULL;
  1116. DBUG_ENTER("create_table_from_dump");
  1117. packet_len= my_net_read(net); // read create table statement
  1118. if (packet_len == packet_error)
  1119. {
  1120. my_message(ER_MASTER_NET_READ, ER(ER_MASTER_NET_READ), MYF(0));
  1121. DBUG_RETURN(1);
  1122. }
  1123. if (net->read_pos[0] == 255) // error from master
  1124. {
  1125. char *err_msg;
  1126. err_msg= (char*) net->read_pos + ((mysql->server_capabilities &
  1127. CLIENT_PROTOCOL_41) ?
  1128. 3+SQLSTATE_LENGTH+1 : 3);
  1129. my_error(ER_MASTER, MYF(0), err_msg);
  1130. DBUG_RETURN(1);
  1131. }
  1132. thd->command = COM_TABLE_DUMP;
  1133. if (!(query = thd->strmake((char*) net->read_pos, packet_len)))
  1134. {
  1135. sql_print_error("create_table_from_dump: out of memory");
  1136. my_message(ER_GET_ERRNO, "Out of memory", MYF(0));
  1137. DBUG_RETURN(1);
  1138. }
  1139. thd->set_query(query, packet_len);
  1140. thd->is_slave_error = 0;
  1141. bzero((char*) &tables,sizeof(tables));
  1142. tables.db = (char*)db;
  1143. tables.alias= tables.table_name= (char*)table_name;
  1144. /* Drop the table if 'overwrite' is true */
  1145. if (overwrite)
  1146. {
  1147. if (mysql_rm_table(thd,&tables,1,0)) /* drop if exists */
  1148. {
  1149. sql_print_error("create_table_from_dump: failed to drop the table");
  1150. goto err;
  1151. }
  1152. else
  1153. {
  1154. /* Clear the OK result of mysql_rm_table(). */
  1155. thd->main_da.reset_diagnostics_area();
  1156. }
  1157. }
  1158. /* Create the table. We do not want to log the "create table" statement */
  1159. save_options = thd->options;
  1160. thd->options &= ~ (OPTION_BIN_LOG);
  1161. thd_proc_info(thd, "Creating table from master dump");
  1162. // save old db in case we are creating in a different database
  1163. save_db = thd->db;
  1164. save_db_length= thd->db_length;
  1165. thd->db = (char*)db;
  1166. DBUG_ASSERT(thd->db != 0);
  1167. thd->db_length= strlen(thd->db);
  1168. /* run create table */
  1169. mysql_parse(thd, thd->query(), packet_len, &found_semicolon);
  1170. thd->db = save_db; // leave things the way the were before
  1171. thd->db_length= save_db_length;
  1172. thd->options = save_options;
  1173. if (thd->is_slave_error)
  1174. goto err; // mysql_parse took care of the error send
  1175. thd_proc_info(thd, "Opening master dump table");
  1176. thd->main_da.reset_diagnostics_area(); /* cleanup from CREATE_TABLE */
  1177. /*
  1178. Note: If this function starts to fail for MERGE tables,
  1179. change the next two lines to these:
  1180. tables.table= NULL; // was set by mysql_rm_table()
  1181. if (!open_n_lock_single_table(thd, &tables, TL_WRITE))
  1182. */
  1183. tables.lock_type = TL_WRITE;
  1184. if (!open_ltable(thd, &tables, TL_WRITE, 0))
  1185. {
  1186. sql_print_error("create_table_from_dump: could not open created table");
  1187. goto err;
  1188. }
  1189. file = tables.table->file;
  1190. thd_proc_info(thd, "Reading master dump table data");
  1191. /* Copy the data file */
  1192. if (file->net_read_dump(net))
  1193. {
  1194. my_message(ER_MASTER_NET_READ, ER(ER_MASTER_NET_READ), MYF(0));
  1195. sql_print_error("create_table_from_dump: failed in\
  1196. handler::net_read_dump()");
  1197. goto err;
  1198. }
  1199. check_opt.init();
  1200. check_opt.flags|= T_VERY_SILENT | T_CALC_CHECKSUM | T_QUICK;
  1201. thd_proc_info(thd, "Rebuilding the index on master dump table");
  1202. /*
  1203. We do not want repair() to spam us with messages
  1204. just send them to the error log, and report the failure in case of
  1205. problems.
  1206. */
  1207. save_vio = thd->net.vio;
  1208. thd->net.vio = 0;
  1209. /* Rebuild the index file from the copied data file (with REPAIR) */
  1210. error=file->ha_repair(thd,&check_opt) != 0;
  1211. thd->net.vio = save_vio;
  1212. if (error)
  1213. my_error(ER_INDEX_REBUILD, MYF(0), tables.table->s->table_name.str);
  1214. err:
  1215. close_thread_tables(thd);
  1216. DBUG_RETURN(error);
  1217. }
  1218. int fetch_master_table(THD *thd, const char *db_name, const char *table_name,
  1219. Master_info *mi, MYSQL *mysql, bool overwrite)
  1220. {
  1221. int error= 1;
  1222. const char *errmsg=0;
  1223. bool called_connected= (mysql != NULL);
  1224. DBUG_ENTER("fetch_master_table");
  1225. DBUG_PRINT("enter", ("db_name: '%s' table_name: '%s'",
  1226. db_name,table_name));
  1227. if (!called_connected)
  1228. {
  1229. if (!(mysql = mysql_init(NULL)))
  1230. {
  1231. DBUG_RETURN(1);
  1232. }
  1233. if (connect_to_master(thd, mysql, mi))
  1234. {
  1235. my_error(ER_CONNECT_TO_MASTER, MYF(0), mysql_error(mysql));
  1236. /*
  1237. We need to clear the active VIO since, theoretically, somebody
  1238. might issue an awake() on this thread. If we are then in the
  1239. middle of closing and destroying the VIO inside the
  1240. mysql_close(), we will have a problem.
  1241. */
  1242. #ifdef SIGNAL_WITH_VIO_CLOSE
  1243. thd->clear_active_vio();
  1244. #endif
  1245. mysql_close(mysql);
  1246. DBUG_RETURN(1);
  1247. }
  1248. if (thd->killed)
  1249. goto err;
  1250. }
  1251. if (request_table_dump(mysql, db_name, table_name))
  1252. {
  1253. error= ER_UNKNOWN_ERROR;
  1254. errmsg= "Failed on table dump request";
  1255. goto err;
  1256. }
  1257. if (create_table_from_dump(thd, mysql, db_name,
  1258. table_name, overwrite))
  1259. goto err; // create_table_from_dump have sent the error already
  1260. error = 0;
  1261. err:
  1262. if (!called_connected)
  1263. mysql_close(mysql);
  1264. if (errmsg && thd->vio_ok())
  1265. my_message(error, errmsg, MYF(0));
  1266. DBUG_RETURN(test(error)); // Return 1 on error
  1267. }
  1268. static bool wait_for_relay_log_space(Relay_log_info* rli)
  1269. {
  1270. bool slave_killed=0;
  1271. Master_info* mi = rli->mi;
  1272. const char *save_proc_info;
  1273. THD* thd = mi->io_thd;
  1274. DBUG_ENTER("wait_for_relay_log_space");
  1275. pthread_mutex_lock(&rli->log_space_lock);
  1276. save_proc_info= thd->enter_cond(&rli->log_space_cond,
  1277. &rli->log_space_lock,
  1278. "\
  1279. Waiting for the slave SQL thread to free enough relay log space");
  1280. while (rli->log_space_limit < rli->log_space_total &&
  1281. !(slave_killed=io_slave_killed(thd,mi)) &&
  1282. !rli->ignore_log_space_limit)
  1283. pthread_cond_wait(&rli->log_space_cond, &rli->log_space_lock);
  1284. thd->exit_cond(save_proc_info);
  1285. DBUG_RETURN(slave_killed);
  1286. }
  1287. /*
  1288. Builds a Rotate from the ignored events' info and writes it to relay log.
  1289. SYNOPSIS
  1290. write_ignored_events_info_to_relay_log()
  1291. thd pointer to I/O thread's thd
  1292. mi
  1293. DESCRIPTION
  1294. Slave I/O thread, going to die, must leave a durable trace of the
  1295. ignored events' end position for the use of the slave SQL thread, by
  1296. calling this function. Only that thread can call it (see assertion).
  1297. */
  1298. static void write_ignored_events_info_to_relay_log(THD *thd, Master_info *mi)
  1299. {
  1300. Relay_log_info *rli= &mi->rli;
  1301. pthread_mutex_t *log_lock= rli->relay_log.get_log_lock();
  1302. DBUG_ENTER("write_ignored_events_info_to_relay_log");
  1303. DBUG_ASSERT(thd == mi->io_thd);
  1304. pthread_mutex_lock(log_lock);
  1305. if (rli->ign_master_log_name_end[0])
  1306. {
  1307. DBUG_PRINT("info",("writing a Rotate event to track down ignored events"));
  1308. Rotate_log_event *ev= new Rotate_log_event(rli->ign_master_log_name_end,
  1309. 0, rli->ign_master_log_pos_end,
  1310. Rotate_log_event::DUP_NAME);
  1311. rli->ign_master_log_name_end[0]= 0;
  1312. /* can unlock before writing as slave SQL thd will soon see our Rotate */
  1313. pthread_mutex_unlock(log_lock);
  1314. if (likely((bool)ev))
  1315. {
  1316. ev->server_id= 0; // don't be ignored by slave SQL thread
  1317. if (unlikely(rli->relay_log.append(ev)))
  1318. mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
  1319. ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
  1320. "failed to write a Rotate event"
  1321. " to the relay log, SHOW SLAVE STATUS may be"
  1322. " inaccurate");
  1323. rli->relay_log.harvest_bytes_written(&rli->log_space_total);
  1324. if (flush_master_info(mi, TRUE, TRUE))
  1325. sql_print_error("Failed to flush master info file");
  1326. delete ev;
  1327. }
  1328. else
  1329. mi->report(ERROR_LEVEL, ER_SLAVE_CREATE_EVENT_FAILURE,
  1330. ER(ER_SLAVE_CREATE_EVENT_FAILURE),
  1331. "Rotate_event (out of memory?),"
  1332. " SHOW SLAVE STATUS may be inaccurate");
  1333. }
  1334. else
  1335. pthread_mutex_unlock(log_lock);
  1336. DBUG_VOID_RETURN;
  1337. }
  1338. int register_slave_on_master(MYSQL* mysql, Master_info *mi,
  1339. bool *suppress_warnings)
  1340. {
  1341. uchar buf[1024], *pos= buf;
  1342. uint report_host_len, report_user_len=0, report_password_len=0;
  1343. DBUG_ENTER("register_slave_on_master");
  1344. *suppress_warnings= FALSE;
  1345. if (!report_host)
  1346. DBUG_RETURN(0);
  1347. report_host_len= strlen(report_host);
  1348. if (report_user)
  1349. report_user_len= strlen(report_user);
  1350. if (report_password)
  1351. report_password_len= strlen(report_password);
  1352. /* 30 is a good safety margin */
  1353. if (report_host_len + report_user_len + report_password_len + 30 >
  1354. sizeof(buf))
  1355. DBUG_RETURN(0); // safety
  1356. int4store(pos, server_id); pos+= 4;
  1357. pos= net_store_data(pos, (uchar*) report_host, report_host_len);
  1358. pos= net_store_data(pos, (uchar*) report_user, report_user_len);
  1359. pos= net_store_data(pos, (uchar*) report_password, report_password_len);
  1360. int2store(pos, (uint16) report_port); pos+= 2;
  1361. int4store(pos, rpl_recovery_rank); pos+= 4;
  1362. /* The master will fill in master_id */
  1363. int4store(pos, 0); pos+= 4;
  1364. if (simple_command(mysql, COM_REGISTER_SLAVE, buf, (size_t) (pos- buf), 0))
  1365. {
  1366. if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
  1367. {
  1368. *suppress_warnings= TRUE; // Suppress reconnect warning
  1369. }
  1370. else if (!check_io_slave_killed(mi->io_thd, mi, NULL))
  1371. {
  1372. char buf[256];
  1373. my_snprintf(buf, sizeof(buf), "%s (Errno: %d)", mysql_error(mysql),
  1374. mysql_errno(mysql));
  1375. mi->report(ERROR_LEVEL, ER_SLAVE_MASTER_COM_FAILURE,
  1376. ER(ER_SLAVE_MASTER_COM_FAILURE), "COM_REGISTER_SLAVE", buf);
  1377. }
  1378. DBUG_RETURN(1);
  1379. }
  1380. DBUG_RETURN(0);
  1381. }
  1382. /**
  1383. Execute a SHOW SLAVE STATUS statement.
  1384. @param thd Pointer to THD object for the client thread executing the
  1385. statement.
  1386. @param mi Pointer to Master_info object for the IO thread.
  1387. @retval FALSE success
  1388. @retval TRUE failure
  1389. */
  1390. bool show_master_info(THD* thd, Master_info* mi)
  1391. {
  1392. // TODO: fix this for multi-master
  1393. List<Item> field_list;
  1394. Protocol *protocol= thd->protocol;
  1395. DBUG_ENTER("show_master_info");
  1396. field_list.push_back(new Item_empty_string("Slave_IO_State",
  1397. 14));
  1398. field_list.push_back(new Item_empty_string("Master_Host",
  1399. sizeof(mi->host)));
  1400. field_list.push_back(new Item_empty_string("Master_User",
  1401. sizeof(mi->user)));
  1402. field_list.push_back(new Item_return_int("Master_Port", 7,
  1403. MYSQL_TYPE_LONG));
  1404. field_list.push_back(new Item_return_int("Connect_Retry", 10,
  1405. MYSQL_TYPE_LONG));
  1406. field_list.push_back(new Item_empty_string("Master_Log_File",
  1407. FN_REFLEN));
  1408. field_list.push_back(new Item_return_int("Read_Master_Log_Pos", 10,
  1409. MYSQL_TYPE_LONGLONG));
  1410. field_list.push_back(new Item_empty_string("Relay_Log_File",
  1411. FN_REFLEN));
  1412. field_list.push_back(new Item_return_int("Relay_Log_Pos", 10,
  1413. MYSQL_TYPE_LONGLONG));
  1414. field_list.push_back(new Item_empty_string("Relay_Master_Log_File",
  1415. FN_REFLEN));
  1416. field_list.push_back(new Item_empty_string("Slave_IO_Running", 3));
  1417. field_list.push_back(new Item_empty_string("Slave_SQL_Running", 3));
  1418. field_list.push_back(new Item_empty_string("Replicate_Do_DB", 20));
  1419. field_list.push_back(new Item_empty_string("Replicate_Ignore_DB", 20));
  1420. field_list.push_back(new Item_empty_string("Replicate_Do_Table", 20));
  1421. field_list.push_back(new Item_empty_string("Replicate_Ignore_Table", 23));
  1422. field_list.push_back(new Item_empty_string("Replicate_Wild_Do_Table", 24));
  1423. field_list.push_back(new Item_empty_string("Replicate_Wild_Ignore_Table",
  1424. 28));
  1425. field_list.push_back(new Item_return_int("Last_Errno", 4, MYSQL_TYPE_LONG));
  1426. field_list.push_back(new Item_empty_string("Last_Error", 20));
  1427. field_list.push_back(new Item_return_int("Skip_Counter", 10,
  1428. MYSQL_TYPE_LONG));
  1429. field_list.push_back(new Item_return_int("Exec_Master_Log_Pos", 10,
  1430. MYSQL_TYPE_LONGLONG));
  1431. field_list.push_back(new Item_return_int("Relay_Log_Space", 10,
  1432. MYSQL_TYPE_LONGLONG));
  1433. field_list.push_back(new Item_empty_string("Until_Condition", 6));
  1434. field_list.push_back(new Item_empty_string("Until_Log_File", FN_REFLEN));
  1435. field_list.push_back(new Item_return_int("Until_Log_Pos", 10,
  1436. MYSQL_TYPE_LONGLONG));
  1437. field_list.push_back(new Item_empty_string("Master_SSL_Allowed", 7));
  1438. field_list.push_back(new Item_empty_string("Master_SSL_CA_File",
  1439. sizeof(mi->ssl_ca)));
  1440. field_list.push_back(new Item_empty_string("Master_SSL_CA_Path",
  1441. sizeof(mi->ssl_capath)));
  1442. field_list.push_back(new Item_empty_string("Master_SSL_Cert",
  1443. sizeof(mi->ssl_cert)));
  1444. field_list.push_back(new Item_empty_string("Master_SSL_Cipher",
  1445. sizeof(mi->ssl_cipher)));
  1446. field_list.push_back(new Item_empty_string("Master_SSL_Key",
  1447. sizeof(mi->ssl_key)));
  1448. field_list.push_back(new Item_return_int("Seconds_Behind_Master", 10,
  1449. MYSQL_TYPE_LONGLONG));
  1450. field_list.push_back(new Item_empty_string("Master_SSL_Verify_Server_Cert",
  1451. 3));
  1452. field_list.push_back(new Item_return_int("Last_IO_Errno", 4, MYSQL_TYPE_LONG));
  1453. field_list.push_back(new Item_empty_string("Last_IO_Error", 20));
  1454. field_list.push_back(new Item_return_int("Last_SQL_Errno", 4, MYSQL_TYPE_LONG));
  1455. field_list.push_back(new Item_empty_string("Last_SQL_Error", 20));
  1456. if (protocol->send_fields(&field_list,
  1457. Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
  1458. DBUG_RETURN(TRUE);
  1459. if (mi->host[0])
  1460. {
  1461. DBUG_PRINT("info",("host is set: '%s'", mi->host));
  1462. String *packet= &thd->packet;
  1463. protocol->prepare_for_resend();
  1464. /*
  1465. slave_running can be accessed without run_lock but not other
  1466. non-volotile members like mi->io_thd, which is guarded by the mutex.
  1467. */
  1468. pthread_mutex_lock(&mi->run_lock);
  1469. protocol->store(mi->io_thd ? mi->io_thd->proc_info : "", &my_charset_bin);
  1470. pthread_mutex_unlock(&mi->run_lock);
  1471. pthread_mutex_lock(&mi->data_lock);
  1472. pthread_mutex_lock(&mi->rli.data_lock);
  1473. pthread_mutex_lock(&mi->err_lock);
  1474. pthread_mutex_lock(&mi->rli.err_lock);
  1475. protocol->store(mi->host, &my_charset_bin);
  1476. protocol->store(mi->user, &my_charset_bin);
  1477. protocol->store((uint32) mi->port);
  1478. protocol->store((uint32) mi->connect_retry);
  1479. protocol->store(mi->master_log_name, &my_charset_bin);
  1480. protocol->store((ulonglong) mi->master_log_pos);
  1481. protocol->store(mi->rli.group_relay_log_name +
  1482. dirname_length(mi->rli.group_relay_log_name),
  1483. &my_charset_bin);
  1484. protocol->store((ulonglong) mi->rli.group_relay_log_pos);
  1485. protocol->store(mi->rli.group_master_log_name, &my_charset_bin);
  1486. protocol->store(mi->slave_running == MYSQL_SLAVE_RUN_CONNECT ?
  1487. "Yes" : "No", &my_charset_bin);
  1488. protocol->store(mi->rli.slave_running ? "Yes":"No", &my_charset_bin);
  1489. protocol->store(rpl_filter->get_do_db());
  1490. protocol->store(rpl_filter->get_ignore_db());
  1491. char buf[256];
  1492. String tmp(buf, sizeof(buf), &my_charset_bin);
  1493. rpl_filter->get_do_table(&tmp);
  1494. protocol->store(&tmp);
  1495. rpl_filter->get_ignore_table(&tmp);
  1496. protocol->store(&tmp);
  1497. rpl_filter->get_wild_do_table(&tmp);
  1498. protocol->store(&tmp);
  1499. rpl_filter->get_wild_ignore_table(&tmp);
  1500. protocol->store(&tmp);
  1501. protocol->store(mi->rli.last_error().number);
  1502. protocol->store(mi->rli.last_error().message, &my_charset_bin);
  1503. protocol->store((uint32) mi->rli.slave_skip_counter);
  1504. protocol->store((ulonglong) mi->rli.group_master_log_pos);
  1505. protocol->store((ulonglong) mi->rli.log_space_total);
  1506. protocol->store(
  1507. mi->rli.until_condition==Relay_log_info::UNTIL_NONE ? "None":
  1508. ( mi->rli.until_condition==Relay_log_info::UNTIL_MASTER_POS? "Master":
  1509. "Relay"), &my_charset_bin);
  1510. protocol->store(mi->rli.until_log_name, &my_charset_bin);
  1511. protocol->store((ulonglong) mi->rli.until_log_pos);
  1512. #ifdef HAVE_OPENSSL
  1513. protocol->store(mi->ssl? "Yes":"No", &my_charset_bin);
  1514. #else
  1515. protocol->store(mi->ssl? "Ignored":"No", &my_charset_bin);
  1516. #endif
  1517. protocol->store(mi->ssl_ca, &my_charset_bin);
  1518. protocol->store(mi->ssl_capath, &my_charset_bin);
  1519. protocol->store(mi->ssl_cert, &my_charset_bin);
  1520. protocol->store(mi->ssl_cipher, &my_charset_bin);
  1521. protocol->store(mi->ssl_key, &my_charset_bin);
  1522. /*
  1523. Seconds_Behind_Master: if SQL thread is running and I/O thread is
  1524. connected, we can compute it otherwise show NULL (i.e. unknown).
  1525. */
  1526. if ((mi->slave_running == MYSQL_SLAVE_RUN_CONNECT) &&
  1527. mi->rli.slave_running)
  1528. {
  1529. long time_diff= ((long)(time(0) - mi->rli.last_master_timestamp)
  1530. - mi->clock_diff_with_master);
  1531. /*
  1532. Apparently on some systems time_diff can be <0. Here are possible
  1533. reasons related to MySQL:
  1534. - the master is itself a slave of another master whose time is ahead.
  1535. - somebody used an explicit SET TIMESTAMP on the master.
  1536. Possible reason related to granularity-to-second of time functions
  1537. (nothing to do with MySQL), which can explain a value of -1:
  1538. assume the master's and slave's time are perfectly synchronized, and
  1539. that at slave's connection time, when the master's timestamp is read,
  1540. it is at the very end of second 1, and (a very short time later) when
  1541. the slave's timestamp is read it is at the very beginning of second
  1542. 2. Then the recorded value for master is 1 and the recorded value for
  1543. slave is 2. At SHOW SLAVE STATUS time, assume that the difference
  1544. between timestamp of slave and rli->last_master_timestamp is 0
  1545. (i.e. they are in the same second), then we get 0-(2-1)=-1 as a result.
  1546. This confuses users, so we don't go below 0: hence the max().
  1547. last_master_timestamp == 0 (an "impossible" timestamp 1970) is a
  1548. special marker to say "consider we have caught up".
  1549. */
  1550. protocol->store((longlong)(mi->rli.last_master_timestamp ?
  1551. max(0, time_diff) : 0));
  1552. }
  1553. else
  1554. {
  1555. protocol->store_null();
  1556. }
  1557. protocol->store(mi->ssl_verify_server_cert? "Yes":"No", &my_charset_bin);
  1558. // Last_IO_Errno
  1559. protocol->store(mi->last_error().number);
  1560. // Last_IO_Error
  1561. protocol->store(mi->last_error().message, &my_charset_bin);
  1562. // Last_SQL_Errno
  1563. protocol->store(mi->rli.last_error().number);
  1564. // Last_SQL_Error
  1565. protocol->store(mi->rli.last_error().message, &my_charset_bin);
  1566. pthread_mutex_unlock(&mi->rli.err_lock);
  1567. pthread_mutex_unlock(&mi->err_lock);
  1568. pthread_mutex_unlock(&mi->rli.data_lock);
  1569. pthread_mutex_unlock(&mi->data_lock);
  1570. if (my_net_write(&thd->net, (uchar*) thd->packet.ptr(), packet->length()))
  1571. DBUG_RETURN(TRUE);
  1572. }
  1573. my_eof(thd);
  1574. DBUG_RETURN(FALSE);
  1575. }
  1576. void set_slave_thread_options(THD* thd)
  1577. {
  1578. DBUG_ENTER("set_slave_thread_options");
  1579. /*
  1580. It's nonsense to constrain the slave threads with max_join_size; if a
  1581. query succeeded on master, we HAVE to execute it. So set
  1582. OPTION_BIG_SELECTS. Setting max_join_size to HA_POS_ERROR is not enough
  1583. (and it's not needed if we have OPTION_BIG_SELECTS) because an INSERT
  1584. SELECT examining more than 4 billion rows would still fail (yes, because
  1585. when max_join_size is 4G, OPTION_BIG_SELECTS is automatically set, but
  1586. only for client threads.
  1587. */
  1588. ulonglong options= thd->options | OPTION_BIG_SELECTS;
  1589. if (opt_log_slave_updates)
  1590. options|= OPTION_BIN_LOG;
  1591. else
  1592. options&= ~OPTION_BIN_LOG;
  1593. thd->options= options;
  1594. thd->variables.completion_type= 0;
  1595. DBUG_VOID_RETURN;
  1596. }
  1597. void set_slave_thread_default_charset(THD* thd, Relay_log_info const *rli)
  1598. {
  1599. DBUG_ENTER("set_slave_thread_default_charset");
  1600. thd->variables.character_set_client=
  1601. global_system_variables.character_set_client;
  1602. thd->variables.collation_connection=
  1603. global_system_variables.collation_connection;
  1604. thd->variables.collation_server=
  1605. global_system_variables.collation_server;
  1606. thd->update_charset();
  1607. /*
  1608. We use a const cast here since the conceptual (and externally
  1609. visible) behavior of the function is to set the default charset of
  1610. the thread. That the cache has to be invalidated is a secondary
  1611. effect.
  1612. */
  1613. const_cast<Relay_log_info*>(rli)->cached_charset_invalidate();
  1614. DBUG_VOID_RETURN;
  1615. }
  1616. /*
  1617. init_slave_thread()
  1618. */
  1619. static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
  1620. {
  1621. DBUG_ENTER("init_slave_thread");
  1622. #if !defined(DBUG_OFF)
  1623. int simulate_error= 0;
  1624. #endif
  1625. thd->system_thread = (thd_type == SLAVE_THD_SQL) ?
  1626. SYSTEM_THREAD_SLAVE_SQL : SYSTEM_THREAD_SLAVE_IO;
  1627. thd->security_ctx->skip_grants();
  1628. my_net_init(&thd->net, 0);
  1629. /*
  1630. Adding MAX_LOG_EVENT_HEADER_LEN to the max_allowed_packet on all
  1631. slave threads, since a replication event can become this much larger
  1632. than the corresponding packet (query) sent from client to master.
  1633. */
  1634. thd->variables.max_allowed_packet= global_system_variables.max_allowed_packet
  1635. + MAX_LOG_EVENT_HEADER; /* note, incr over the global not session var */
  1636. thd->slave_thread = 1;
  1637. thd->enable_slow_log= opt_log_slow_slave_statements;
  1638. set_slave_thread_options(thd);
  1639. thd->client_capabilities = CLIENT_LOCAL_FILES;
  1640. pthread_mutex_lock(&LOCK_thread_count);
  1641. thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
  1642. pthread_mutex_unlock(&LOCK_thread_count);
  1643. DBUG_EXECUTE_IF("simulate_io_slave_error_on_init",
  1644. simulate_error|= (1 << SLAVE_THD_IO););
  1645. DBUG_EXECUTE_IF("simulate_sql_slave_error_on_init",
  1646. simulate_error|= (1 << SLAVE_THD_SQL););
  1647. #if !defined(DBUG_OFF)
  1648. if (init_thr_lock() || thd->store_globals() || simulate_error & (1<< thd_type))
  1649. #else
  1650. if (init_thr_lock() || thd->store_globals())
  1651. #endif
  1652. {
  1653. thd->cleanup();
  1654. DBUG_RETURN(-1);
  1655. }
  1656. lex_start(thd);
  1657. if (thd_type == SLAVE_THD_SQL)
  1658. thd_proc_info(thd, "Waiting for the next event in relay log");
  1659. else
  1660. thd_proc_info(thd, "Waiting for master update");
  1661. thd->version=refresh_version;
  1662. thd->set_time();
  1663. DBUG_RETURN(0);
  1664. }
  1665. static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
  1666. void* thread_killed_arg)
  1667. {
  1668. int nap_time;
  1669. thr_alarm_t alarmed;
  1670. DBUG_ENTER("safe_sleep");
  1671. thr_alarm_init(&alarmed);
  1672. time_t start_time= my_time(0);
  1673. time_t end_time= start_time+sec;
  1674. while ((nap_time= (int) (end_time - start_time)) > 0)
  1675. {
  1676. ALARM alarm_buff;
  1677. /*
  1678. The only reason we are asking for alarm is so that
  1679. we will be woken up in case of murder, so if we do not get killed,
  1680. set the alarm so it goes off after we wake up naturally
  1681. */
  1682. thr_alarm(&alarmed, 2 * nap_time, &alarm_buff);
  1683. sleep(nap_time);
  1684. thr_end_alarm(&alarmed);
  1685. if ((*thread_killed)(thd,thread_killed_arg))
  1686. DBUG_RETURN(1);
  1687. start_time= my_time(0);
  1688. }
  1689. DBUG_RETURN(0);
  1690. }
  1691. static int request_dump(MYSQL* mysql, Master_info* mi,
  1692. bool *suppress_warnings)
  1693. {
  1694. uchar buf[FN_REFLEN + 10];
  1695. int len;
  1696. int binlog_flags = 0; // for now
  1697. char* logname = mi->master_log_name;
  1698. DBUG_ENTER("request_dump");
  1699. *suppress_warnings= FALSE;
  1700. // TODO if big log files: Change next to int8store()
  1701. int4store(buf, (ulong) mi->master_log_pos);
  1702. int2store(buf + 4, binlog_flags);
  1703. int4store(buf + 6, server_id);
  1704. len = (uint) strlen(logname);
  1705. memcpy(buf + 10, logname,len);
  1706. if (simple_command(mysql, COM_BINLOG_DUMP, buf, len + 10, 1))
  1707. {
  1708. /*
  1709. Something went wrong, so we will just reconnect and retry later
  1710. in the future, we should do a better error analysis, but for
  1711. now we just fill up the error log :-)
  1712. */
  1713. if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
  1714. *suppress_warnings= TRUE; // Suppress reconnect warning
  1715. else
  1716. sql_print_error("Error on COM_BINLOG_DUMP: %d %s, will retry in %d secs",
  1717. mysql_errno(mysql), mysql_error(mysql),
  1718. master_connect_retry);
  1719. DBUG_RETURN(1);
  1720. }
  1721. DBUG_RETURN(0);
  1722. }
  1723. static int request_table_dump(MYSQL* mysql, const char* db, const char* table)
  1724. {
  1725. uchar buf[1024], *p = buf;
  1726. DBUG_ENTER("request_table_dump");
  1727. uint table_len = (uint) strlen(table);
  1728. uint db_len = (uint) strlen(db);
  1729. if (table_len + db_len > sizeof(buf) - 2)
  1730. {
  1731. sql_print_error("request_table_dump: Buffer overrun");
  1732. DBUG_RETURN(1);
  1733. }
  1734. *p++ = db_len;
  1735. memcpy(p, db, db_len);
  1736. p += db_len;
  1737. *p++ = table_len;
  1738. memcpy(p, table, table_len);
  1739. if (simple_command(mysql, COM_TABLE_DUMP, buf, p - buf + table_len, 1))
  1740. {
  1741. sql_print_error("request_table_dump: Error sending the table dump \
  1742. command");
  1743. DBUG_RETURN(1);
  1744. }
  1745. DBUG_RETURN(0);
  1746. }
  1747. /*
  1748. Read one event from the master
  1749. SYNOPSIS
  1750. read_event()
  1751. mysql MySQL connection
  1752. mi Master connection information
  1753. suppress_warnings TRUE when a normal net read timeout has caused us to
  1754. try a reconnect. We do not want to print anything to
  1755. the error log in this case because this a anormal
  1756. event in an idle server.
  1757. RETURN VALUES
  1758. 'packet_error' Error
  1759. number Length of packet
  1760. */
  1761. static ulong read_event(MYSQL* mysql, Master_info *mi, bool* suppress_warnings)
  1762. {
  1763. ulong len;
  1764. DBUG_ENTER("read_event");
  1765. *suppress_warnings= FALSE;
  1766. /*
  1767. my_real_read() will time us out
  1768. We check if we were told to die, and if not, try reading again
  1769. */
  1770. #ifndef DBUG_OFF
  1771. if (disconnect_slave_event_count && !(mi->events_till_disconnect--))
  1772. DBUG_RETURN(packet_error);
  1773. #endif
  1774. len = cli_safe_read(mysql);
  1775. if (len == packet_error || (long) len < 1)
  1776. {
  1777. if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
  1778. {
  1779. /*
  1780. We are trying a normal reconnect after a read timeout;
  1781. we suppress prints to .err file as long as the reconnect
  1782. happens without problems
  1783. */
  1784. *suppress_warnings= TRUE;
  1785. }
  1786. else
  1787. sql_print_error("Error reading packet from server: %s ( server_errno=%d)",
  1788. mysql_error(mysql), mysql_errno(mysql));
  1789. DBUG_RETURN(packet_error);
  1790. }
  1791. /* Check if eof packet */
  1792. if (len < 8 && mysql->net.read_pos[0] == 254)
  1793. {
  1794. sql_print_information("Slave: received end packet from server, apparent "
  1795. "master shutdown: %s",
  1796. mysql_error(mysql));
  1797. DBUG_RETURN(packet_error);
  1798. }
  1799. DBUG_PRINT("exit", ("len: %lu net->read_pos[4]: %d",
  1800. len, mysql->net.read_pos[4]));
  1801. DBUG_RETURN(len - 1);
  1802. }
  1803. /*
  1804. Check if the current error is of temporary nature of not.
  1805. Some errors are temporary in nature, such as
  1806. ER_LOCK_DEADLOCK and ER_LOCK_WAIT_TIMEOUT. Ndb also signals
  1807. that the error is temporary by pushing a warning with the error code
  1808. ER_GET_TEMPORARY_ERRMSG, if the originating error is temporary.
  1809. */
  1810. static int has_temporary_error(THD *thd)
  1811. {
  1812. DBUG_ENTER("has_temporary_error");
  1813. DBUG_EXECUTE_IF("all_errors_are_temporary_errors",
  1814. if (thd->main_da.is_error())
  1815. {
  1816. thd->clear_error();
  1817. my_error(ER_LOCK_DEADLOCK, MYF(0));
  1818. });
  1819. /*
  1820. If there is no message in THD, we can't say if it's a temporary
  1821. error or not. This is currently the case for Incident_log_event,
  1822. which sets no message. Return FALSE.
  1823. */
  1824. if (!thd->is_error())
  1825. DBUG_RETURN(0);
  1826. /*
  1827. Temporary error codes:
  1828. currently, InnoDB deadlock detected by InnoDB or lock
  1829. wait timeout (innodb_lock_wait_timeout exceeded
  1830. */
  1831. if (thd->main_da.sql_errno() == ER_LOCK_DEADLOCK ||
  1832. thd->main_da.sql_errno() == ER_LOCK_WAIT_TIMEOUT)
  1833. DBUG_RETURN(1);
  1834. #ifdef HAVE_NDB_BINLOG
  1835. /*
  1836. currently temporary error set in ndbcluster
  1837. */
  1838. List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
  1839. MYSQL_ERROR *err;
  1840. while ((err= it++))
  1841. {
  1842. DBUG_PRINT("info", ("has warning %d %s", err->code, err->msg));
  1843. switch (err->code)
  1844. {
  1845. case ER_GET_TEMPORARY_ERRMSG:
  1846. DBUG_RETURN(1);
  1847. default:
  1848. break;
  1849. }
  1850. }
  1851. #endif
  1852. DBUG_RETURN(0);
  1853. }
  1854. /**
  1855. Applies the given event and advances the relay log position.
  1856. In essence, this function does:
  1857. @code
  1858. ev->apply_event(rli);
  1859. ev->update_pos(rli);
  1860. @endcode
  1861. But it also does some maintainance, such as skipping events if
  1862. needed and reporting errors.
  1863. If the @c skip flag is set, then it is tested whether the event
  1864. should be skipped, by looking at the slave_skip_counter and the
  1865. server id. The skip flag should be set when calling this from a
  1866. replication thread but not set when executing an explicit BINLOG
  1867. statement.
  1868. @retval 0 OK.
  1869. @retval 1 Error calling ev->apply_event().
  1870. @retval 2 No error calling ev->apply_event(), but error calling
  1871. ev->update_pos().
  1872. */
  1873. int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli)
  1874. {
  1875. int exec_res= 0;
  1876. DBUG_ENTER("apply_event_and_update_pos");
  1877. DBUG_PRINT("exec_event",("%s(type_code: %d; server_id: %d)",
  1878. ev->get_type_str(), ev->get_type_code(),
  1879. ev->server_id));
  1880. DBUG_PRINT("info", ("thd->options: %s%s; rli->last_event_start_time: %lu",
  1881. FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT),
  1882. FLAGSTR(thd->options, OPTION_BEGIN),
  1883. (ulong) rli->last_event_start_time));
  1884. /*
  1885. Execute the event to change the database and update the binary
  1886. log coordinates, but first we set some data that is needed for
  1887. the thread.
  1888. The event will be executed unless it is supposed to be skipped.
  1889. Queries originating from this server must be skipped. Low-level
  1890. events (Format_description_log_event, Rotate_log_event,
  1891. Stop_log_event) from this server must also be skipped. But for
  1892. those we don't want to modify 'group_master_log_pos', because
  1893. these events did not exist on the master.
  1894. Format_description_log_event is not completely skipped.
  1895. Skip queries specified by the user in 'slave_skip_counter'. We
  1896. can't however skip events that has something to do with the log
  1897. files themselves.
  1898. Filtering on own server id is extremely important, to ignore
  1899. execution of events created by the creation/rotation of the relay
  1900. log (remember that now the relay log starts with its Format_desc,
  1901. has a Rotate etc).
  1902. */
  1903. thd->server_id = ev->server_id; // use the original server id for logging
  1904. thd->set_time(); // time the query
  1905. thd->lex->current_select= 0;
  1906. if (!ev->when)
  1907. ev->when= my_time(0);
  1908. ev->thd = thd; // because up to this point, ev->thd == 0
  1909. int reason= ev->shall_skip(rli);
  1910. if (reason == Log_event::EVENT_SKIP_COUNT)
  1911. --rli->slave_skip_counter;
  1912. pthread_mutex_unlock(&rli->data_lock);
  1913. if (reason == Log_event::EVENT_SKIP_NOT)
  1914. exec_res= ev->apply_event(rli);
  1915. #ifndef DBUG_OFF
  1916. /*
  1917. This only prints information to the debug trace.
  1918. TODO: Print an informational message to the error log?
  1919. */
  1920. static const char *const explain[] = {
  1921. // EVENT_SKIP_NOT,
  1922. "not skipped",
  1923. // EVENT_SKIP_IGNORE,
  1924. "skipped because event should be ignored",
  1925. // EVENT_SKIP_COUNT
  1926. "skipped because event skip counter was non-zero"
  1927. };
  1928. DBUG_PRINT("info", ("OPTION_BEGIN: %d; IN_STMT: %d",
  1929. thd->options & OPTION_BEGIN ? 1 : 0,
  1930. rli->get_flag(Relay_log_info::IN_STMT)));
  1931. DBUG_PRINT("skip_event", ("%s event was %s",
  1932. ev->get_type_str(), explain[reason]));
  1933. #endif
  1934. DBUG_PRINT("info", ("apply_event error = %d", exec_res));
  1935. if (exec_res == 0)
  1936. {
  1937. int error= ev->update_pos(rli);
  1938. #ifdef HAVE_purify
  1939. if (!rli->is_fake)
  1940. #endif
  1941. {
  1942. #ifndef DBUG_OFF
  1943. char buf[22];
  1944. #endif
  1945. DBUG_PRINT("info", ("update_pos error = %d", error));
  1946. DBUG_PRINT("info", ("group %s %s",
  1947. llstr(rli->group_relay_log_pos, buf),
  1948. rli->group_relay_log_name));
  1949. DBUG_PRINT("info", ("event %s %s",
  1950. llstr(rli->event_relay_log_pos, buf),
  1951. rli->event_relay_log_name));
  1952. }
  1953. /*
  1954. The update should not fail, so print an error message and
  1955. return an error code.
  1956. TODO: Replace this with a decent error message when merged
  1957. with BUG#24954 (which adds several new error message).
  1958. */
  1959. if (error)
  1960. {
  1961. char buf[22];
  1962. rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR,
  1963. "It was not possible to update the positions"
  1964. " of the relay log information: the slave may"
  1965. " be in an inconsistent state."
  1966. " Stopped in %s position %s",
  1967. rli->group_relay_log_name,
  1968. llstr(rli->group_relay_log_pos, buf));
  1969. DBUG_RETURN(2);
  1970. }
  1971. }
  1972. DBUG_RETURN(exec_res ? 1 : 0);
  1973. }
  1974. /**
  1975. Top-level function for executing the next event from the relay log.
  1976. This function reads the event from the relay log, executes it, and
  1977. advances the relay log position. It also handles errors, etc.
  1978. This function may fail to apply the event for the following reasons:
  1979. - The position specfied by the UNTIL condition of the START SLAVE
  1980. command is reached.
  1981. - It was not possible to read the event from the log.
  1982. - The slave is killed.
  1983. - An error occurred when applying the event, and the event has been
  1984. tried slave_trans_retries times. If the event has been retried
  1985. fewer times, 0 is returned.
  1986. - init_master_info or init_relay_log_pos failed. (These are called
  1987. if a failure occurs when applying the event.)
  1988. - An error occurred when updating the binlog position.
  1989. @retval 0 The event was applied.
  1990. @retval 1 The event was not applied.
  1991. */
  1992. static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
  1993. {
  1994. DBUG_ENTER("exec_relay_log_event");
  1995. /*
  1996. We acquire this mutex since we need it for all operations except
  1997. event execution. But we will release it in places where we will
  1998. wait for something for example inside of next_event().
  1999. */
  2000. pthread_mutex_lock(&rli->data_lock);
  2001. Log_event * ev = next_event(rli);
  2002. DBUG_ASSERT(rli->sql_thd==thd);
  2003. if (sql_slave_killed(thd,rli))
  2004. {
  2005. pthread_mutex_unlock(&rli->data_lock);
  2006. delete ev;
  2007. DBUG_RETURN(1);
  2008. }
  2009. if (ev)
  2010. {
  2011. int exec_res;
  2012. /*
  2013. This tests if the position of the beginning of the current event
  2014. hits the UNTIL barrier.
  2015. */
  2016. if (rli->until_condition != Relay_log_info::UNTIL_NONE &&
  2017. rli->is_until_satisfied(thd, ev))
  2018. {
  2019. char buf[22];
  2020. sql_print_information("Slave SQL thread stopped because it reached its"
  2021. " UNTIL position %s", llstr(rli->until_pos(), buf));
  2022. /*
  2023. Setting abort_slave flag because we do not want additional message about
  2024. error in query execution to be printed.
  2025. */
  2026. rli->abort_slave= 1;
  2027. pthread_mutex_unlock(&rli->data_lock);
  2028. delete ev;
  2029. DBUG_RETURN(1);
  2030. }
  2031. exec_res= apply_event_and_update_pos(ev, thd, rli);
  2032. /*
  2033. Format_description_log_event should not be deleted because it will be
  2034. used to read info about the relay log's format; it will be deleted when
  2035. the SQL thread does not need it, i.e. when this thread terminates.
  2036. */
  2037. if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
  2038. {
  2039. DBUG_PRINT("info", ("Deleting the event after it has been executed"));
  2040. delete ev;
  2041. }
  2042. /*
  2043. update_log_pos failed: this should not happen, so we don't
  2044. retry.
  2045. */
  2046. if (exec_res == 2)
  2047. DBUG_RETURN(1);
  2048. if (slave_trans_retries)
  2049. {
  2050. int UNINIT_VAR(temp_err);
  2051. if (exec_res && (temp_err= has_temporary_error(thd)))
  2052. {
  2053. const char *errmsg;
  2054. /*
  2055. We were in a transaction which has been rolled back because of a
  2056. temporary error;
  2057. let's seek back to BEGIN log event and retry it all again.
  2058. Note, if lock wait timeout (innodb_lock_wait_timeout exceeded)
  2059. there is no rollback since 5.0.13 (ref: manual).
  2060. We have to not only seek but also
  2061. a) init_master_info(), to seek back to hot relay log's start for later
  2062. (for when we will come back to this hot log after re-processing the
  2063. possibly existing old logs where BEGIN is: check_binlog_magic() will
  2064. then need the cache to be at position 0 (see comments at beginning of
  2065. init_master_info()).
  2066. b) init_relay_log_pos(), because the BEGIN may be an older relay log.
  2067. */
  2068. if (rli->trans_retries < slave_trans_retries)
  2069. {
  2070. if (init_master_info(rli->mi, 0, 0, 0, SLAVE_SQL))
  2071. sql_print_error("Failed to initialize the master info structure");
  2072. else if (init_relay_log_pos(rli,
  2073. rli->group_relay_log_name,
  2074. rli->group_relay_log_pos,
  2075. 1, &errmsg, 1))
  2076. sql_print_error("Error initializing relay log position: %s",
  2077. errmsg);
  2078. else
  2079. {
  2080. exec_res= 0;
  2081. rli->cleanup_context(thd, 1);
  2082. /* chance for concurrent connection to get more locks */
  2083. safe_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
  2084. (CHECK_KILLED_FUNC)sql_slave_killed, (void*)rli);
  2085. pthread_mutex_lock(&rli->data_lock); // because of SHOW STATUS
  2086. rli->trans_retries++;
  2087. rli->retried_trans++;
  2088. pthread_mutex_unlock(&rli->data_lock);
  2089. DBUG_PRINT("info", ("Slave retries transaction "
  2090. "rli->trans_retries: %lu", rli->trans_retries));
  2091. }
  2092. }
  2093. else
  2094. sql_print_error("Slave SQL thread retried transaction %lu time(s) "
  2095. "in vain, giving up. Consider raising the value of "
  2096. "the slave_transaction_retries variable.",
  2097. slave_trans_retries);
  2098. }
  2099. else if ((exec_res && !temp_err) ||
  2100. (opt_using_transactions &&
  2101. rli->group_relay_log_pos == rli->event_relay_log_pos))
  2102. {
  2103. /*
  2104. Only reset the retry counter if the entire group succeeded
  2105. or failed with a non-transient error. On a successful
  2106. event, the execution will proceed as usual; in the case of a
  2107. non-transient error, the slave will stop with an error.
  2108. */
  2109. rli->trans_retries= 0; // restart from fresh
  2110. DBUG_PRINT("info", ("Resetting retry counter, rli->trans_retries: %lu",
  2111. rli->trans_retries));
  2112. }
  2113. }
  2114. DBUG_RETURN(exec_res);
  2115. }
  2116. pthread_mutex_unlock(&rli->data_lock);
  2117. rli->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_READ_FAILURE,
  2118. ER(ER_SLAVE_RELAY_LOG_READ_FAILURE), "\
  2119. Could not parse relay log event entry. The possible reasons are: the master's \
  2120. binary log is corrupted (you can check this by running 'mysqlbinlog' on the \
  2121. binary log), the slave's relay log is corrupted (you can check this by running \
  2122. 'mysqlbinlog' on the relay log), a network problem, or a bug in the master's \
  2123. or slave's MySQL code. If you want to check the master's binary log or slave's \
  2124. relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' \
  2125. on this slave.\
  2126. ");
  2127. DBUG_RETURN(1);
  2128. }
  2129. static bool check_io_slave_killed(THD *thd, Master_info *mi, const char *info)
  2130. {
  2131. if (io_slave_killed(thd, mi))
  2132. {
  2133. if (info && global_system_variables.log_warnings)
  2134. sql_print_information("%s", info);
  2135. return TRUE;
  2136. }
  2137. return FALSE;
  2138. }
  2139. /**
  2140. @brief Try to reconnect slave IO thread.
  2141. @details Terminates current connection to master, sleeps for
  2142. @c mi->connect_retry msecs and initiates new connection with
  2143. @c safe_reconnect(). Variable pointed by @c retry_count is increased -
  2144. if it exceeds @c master_retry_count then connection is not re-established
  2145. and function signals error.
  2146. Unless @c suppres_warnings is TRUE, a warning is put in the server error log
  2147. when reconnecting. The warning message and messages used to report errors
  2148. are taken from @c messages array. In case @c master_retry_count is exceeded,
  2149. no messages are added to the log.
  2150. @param[in] thd Thread context.
  2151. @param[in] mysql MySQL connection.
  2152. @param[in] mi Master connection information.
  2153. @param[in,out] retry_count Number of attempts to reconnect.
  2154. @param[in] suppress_warnings TRUE when a normal net read timeout
  2155. has caused to reconnecting.
  2156. @param[in] messages Messages to print/log, see
  2157. reconnect_messages[] array.
  2158. @retval 0 OK.
  2159. @retval 1 There was an error.
  2160. */
  2161. static int try_to_reconnect(THD *thd, MYSQL *mysql, Master_info *mi,
  2162. uint *retry_count, bool suppress_warnings,
  2163. const char *messages[SLAVE_RECON_MSG_MAX])
  2164. {
  2165. mi->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT;
  2166. thd->proc_info= messages[SLAVE_RECON_MSG_WAIT];
  2167. #ifdef SIGNAL_WITH_VIO_CLOSE
  2168. thd->clear_active_vio();
  2169. #endif
  2170. end_server(mysql);
  2171. if ((*retry_count)++)
  2172. {
  2173. if (*retry_count > master_retry_count)
  2174. return 1; // Don't retry forever
  2175. safe_sleep(thd, mi->connect_retry, (CHECK_KILLED_FUNC) io_slave_killed,
  2176. (void *) mi);
  2177. }
  2178. if (check_io_slave_killed(thd, mi, messages[SLAVE_RECON_MSG_KILLED_WAITING]))
  2179. return 1;
  2180. thd->proc_info = messages[SLAVE_RECON_MSG_AFTER];
  2181. if (!suppress_warnings)
  2182. {
  2183. char buf[256], llbuff[22];
  2184. my_snprintf(buf, sizeof(buf), messages[SLAVE_RECON_MSG_FAILED],
  2185. IO_RPL_LOG_NAME, llstr(mi->master_log_pos, llbuff));
  2186. /*
  2187. Raise a warining during registering on master/requesting dump.
  2188. Log a message reading event.
  2189. */
  2190. if (messages[SLAVE_RECON_MSG_COMMAND][0])
  2191. {
  2192. mi->report(WARNING_LEVEL, ER_SLAVE_MASTER_COM_FAILURE,
  2193. ER(ER_SLAVE_MASTER_COM_FAILURE),
  2194. messages[SLAVE_RECON_MSG_COMMAND], buf);
  2195. }
  2196. else
  2197. {
  2198. sql_print_information("%s", buf);
  2199. }
  2200. }
  2201. if (safe_reconnect(thd, mysql, mi, 1) || io_slave_killed(thd, mi))
  2202. {
  2203. if (global_system_variables.log_warnings)
  2204. sql_print_information("%s", messages[SLAVE_RECON_MSG_KILLED_AFTER]);
  2205. return 1;
  2206. }
  2207. return 0;
  2208. }
  2209. /**
  2210. Slave IO thread entry point.
  2211. @param arg Pointer to Master_info struct that holds information for
  2212. the IO thread.
  2213. @return Always 0.
  2214. */
  2215. pthread_handler_t handle_slave_io(void *arg)
  2216. {
  2217. THD *thd; // needs to be first for thread_stack
  2218. MYSQL *mysql;
  2219. Master_info *mi = (Master_info*)arg;
  2220. Relay_log_info *rli= &mi->rli;
  2221. char llbuff[22];
  2222. uint retry_count;
  2223. bool suppress_warnings;
  2224. int ret;
  2225. #ifndef DBUG_OFF
  2226. uint retry_count_reg= 0, retry_count_dump= 0, retry_count_event= 0;
  2227. #endif
  2228. // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
  2229. my_thread_init();
  2230. DBUG_ENTER("handle_slave_io");
  2231. DBUG_ASSERT(mi->inited);
  2232. mysql= NULL ;
  2233. retry_count= 0;
  2234. pthread_mutex_lock(&mi->run_lock);
  2235. /* Inform waiting threads that slave has started */
  2236. mi->slave_run_id++;
  2237. #ifndef DBUG_OFF
  2238. mi->events_till_disconnect = disconnect_slave_event_count;
  2239. #endif
  2240. thd= new THD; // note that contructor of THD uses DBUG_ !
  2241. THD_CHECK_SENTRY(thd);
  2242. DBUG_ASSERT(mi->io_thd == 0);
  2243. mi->io_thd = thd;
  2244. pthread_detach_this_thread();
  2245. thd->thread_stack= (char*) &thd; // remember where our stack is
  2246. mi->clear_error();
  2247. if (init_slave_thread(thd, SLAVE_THD_IO))
  2248. {
  2249. pthread_cond_broadcast(&mi->start_cond);
  2250. pthread_mutex_unlock(&mi->run_lock);
  2251. sql_print_error("Failed during slave I/O thread initialization");
  2252. goto err;
  2253. }
  2254. pthread_mutex_lock(&LOCK_thread_count);
  2255. threads.append(thd);
  2256. pthread_mutex_unlock(&LOCK_thread_count);
  2257. mi->slave_running = 1;
  2258. mi->abort_slave = 0;
  2259. pthread_mutex_unlock(&mi->run_lock);
  2260. pthread_cond_broadcast(&mi->start_cond);
  2261. DBUG_PRINT("master_info",("log_file_name: '%s' position: %s",
  2262. mi->master_log_name,
  2263. llstr(mi->master_log_pos,llbuff)));
  2264. if (!(mi->mysql = mysql = mysql_init(NULL)))
  2265. {
  2266. mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
  2267. ER(ER_SLAVE_FATAL_ERROR), "error in mysql_init()");
  2268. goto err;
  2269. }
  2270. thd_proc_info(thd, "Connecting to master");
  2271. // we can get killed during safe_connect
  2272. if (!safe_connect(thd, mysql, mi))
  2273. {
  2274. sql_print_information("Slave I/O thread: connected to master '%s@%s:%d',"
  2275. "replication started in log '%s' at position %s",
  2276. mi->user, mi->host, mi->port,
  2277. IO_RPL_LOG_NAME,
  2278. llstr(mi->master_log_pos,llbuff));
  2279. /*
  2280. Adding MAX_LOG_EVENT_HEADER_LEN to the max_packet_size on the I/O
  2281. thread, since a replication event can become this much larger than
  2282. the corresponding packet (query) sent from client to master.
  2283. */
  2284. mysql->net.max_packet_size= thd->net.max_packet_size+= MAX_LOG_EVENT_HEADER;
  2285. }
  2286. else
  2287. {
  2288. sql_print_information("Slave I/O thread killed while connecting to master");
  2289. goto err;
  2290. }
  2291. connected:
  2292. DBUG_EXECUTE_IF("dbug.before_get_running_status_yes",
  2293. {
  2294. const char act[]=
  2295. "now "
  2296. "wait_for signal.io_thread_let_running";
  2297. DBUG_ASSERT(opt_debug_sync_timeout > 0);
  2298. DBUG_ASSERT(!debug_sync_set_action(thd,
  2299. STRING_WITH_LEN(act)));
  2300. };);
  2301. // TODO: the assignment below should be under mutex (5.0)
  2302. mi->slave_running= MYSQL_SLAVE_RUN_CONNECT;
  2303. thd->slave_net = &mysql->net;
  2304. thd_proc_info(thd, "Checking master version");
  2305. ret= get_master_version_and_clock(mysql, mi);
  2306. if (ret == 1)
  2307. /* Fatal error */
  2308. goto err;
  2309. if (ret == 2)
  2310. {
  2311. if (check_io_slave_killed(mi->io_thd, mi, "Slave I/O thread killed"
  2312. "while calling get_master_version_and_clock(...)"))
  2313. goto err;
  2314. suppress_warnings= FALSE;
  2315. /* Try to reconnect because the error was caused by a transient network problem */
  2316. if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
  2317. reconnect_messages[SLAVE_RECON_ACT_REG]))
  2318. goto err;
  2319. goto connected;
  2320. }
  2321. if (mi->rli.relay_log.description_event_for_queue->binlog_version > 1)
  2322. {
  2323. /*
  2324. Register ourselves with the master.
  2325. */
  2326. thd_proc_info(thd, "Registering slave on master");
  2327. if (register_slave_on_master(mysql, mi, &suppress_warnings))
  2328. {
  2329. if (!check_io_slave_killed(thd, mi, "Slave I/O thread killed "
  2330. "while registering slave on master"))
  2331. {
  2332. sql_print_error("Slave I/O thread couldn't register on master");
  2333. if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
  2334. reconnect_messages[SLAVE_RECON_ACT_REG]))
  2335. goto err;
  2336. }
  2337. else
  2338. goto err;
  2339. goto connected;
  2340. }
  2341. DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_REG",
  2342. if (!retry_count_reg)
  2343. {
  2344. retry_count_reg++;
  2345. sql_print_information("Forcing to reconnect slave I/O thread");
  2346. if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
  2347. reconnect_messages[SLAVE_RECON_ACT_REG]))
  2348. goto err;
  2349. goto connected;
  2350. });
  2351. }
  2352. DBUG_PRINT("info",("Starting reading binary log from master"));
  2353. while (!io_slave_killed(thd,mi))
  2354. {
  2355. thd_proc_info(thd, "Requesting binlog dump");
  2356. if (request_dump(mysql, mi, &suppress_warnings))
  2357. {
  2358. sql_print_error("Failed on request_dump()");
  2359. if (check_io_slave_killed(thd, mi, "Slave I/O thread killed while \
  2360. requesting master dump") ||
  2361. try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
  2362. reconnect_messages[SLAVE_RECON_ACT_DUMP]))
  2363. goto err;
  2364. goto connected;
  2365. }
  2366. DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_DUMP",
  2367. if (!retry_count_dump)
  2368. {
  2369. retry_count_dump++;
  2370. sql_print_information("Forcing to reconnect slave I/O thread");
  2371. if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
  2372. reconnect_messages[SLAVE_RECON_ACT_DUMP]))
  2373. goto err;
  2374. goto connected;
  2375. });
  2376. DBUG_ASSERT(mi->last_error().number == 0);
  2377. while (!io_slave_killed(thd,mi))
  2378. {
  2379. ulong event_len;
  2380. /*
  2381. We say "waiting" because read_event() will wait if there's nothing to
  2382. read. But if there's something to read, it will not wait. The
  2383. important thing is to not confuse users by saying "reading" whereas
  2384. we're in fact receiving nothing.
  2385. */
  2386. thd_proc_info(thd, "Waiting for master to send event");
  2387. event_len= read_event(mysql, mi, &suppress_warnings);
  2388. if (check_io_slave_killed(thd, mi, "Slave I/O thread killed while \
  2389. reading event"))
  2390. goto err;
  2391. DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_EVENT",
  2392. if (!retry_count_event)
  2393. {
  2394. retry_count_event++;
  2395. sql_print_information("Forcing to reconnect slave I/O thread");
  2396. if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
  2397. reconnect_messages[SLAVE_RECON_ACT_EVENT]))
  2398. goto err;
  2399. goto connected;
  2400. });
  2401. if (event_len == packet_error)
  2402. {
  2403. uint mysql_error_number= mysql_errno(mysql);
  2404. switch (mysql_error_number) {
  2405. case CR_NET_PACKET_TOO_LARGE:
  2406. sql_print_error("\
  2407. Log entry on master is longer than max_allowed_packet (%ld) on \
  2408. slave. If the entry is correct, restart the server with a higher value of \
  2409. max_allowed_packet",
  2410. thd->variables.max_allowed_packet);
  2411. mi->report(ERROR_LEVEL, ER_NET_PACKET_TOO_LARGE,
  2412. "%s", ER(ER_NET_PACKET_TOO_LARGE));
  2413. goto err;
  2414. case ER_MASTER_FATAL_ERROR_READING_BINLOG:
  2415. mi->report(ERROR_LEVEL, ER_MASTER_FATAL_ERROR_READING_BINLOG,
  2416. ER(ER_MASTER_FATAL_ERROR_READING_BINLOG),
  2417. mysql_error_number, mysql_error(mysql));
  2418. goto err;
  2419. case ER_OUT_OF_RESOURCES:
  2420. sql_print_error("\
  2421. Stopping slave I/O thread due to out-of-memory error from master");
  2422. mi->report(ERROR_LEVEL, ER_OUT_OF_RESOURCES,
  2423. "%s", ER(ER_OUT_OF_RESOURCES));
  2424. goto err;
  2425. }
  2426. if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
  2427. reconnect_messages[SLAVE_RECON_ACT_EVENT]))
  2428. goto err;
  2429. goto connected;
  2430. } // if (event_len == packet_error)
  2431. retry_count=0; // ok event, reset retry counter
  2432. thd_proc_info(thd, "Queueing master event to the relay log");
  2433. if (queue_event(mi,(const char*)mysql->net.read_pos + 1,
  2434. event_len))
  2435. {
  2436. mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
  2437. ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
  2438. "could not queue event from master");
  2439. goto err;
  2440. }
  2441. if (flush_master_info(mi, TRUE, TRUE))
  2442. {
  2443. sql_print_error("Failed to flush master info file");
  2444. goto err;
  2445. }
  2446. /*
  2447. See if the relay logs take too much space.
  2448. We don't lock mi->rli.log_space_lock here; this dirty read saves time
  2449. and does not introduce any problem:
  2450. - if mi->rli.ignore_log_space_limit is 1 but becomes 0 just after (so
  2451. the clean value is 0), then we are reading only one more event as we
  2452. should, and we'll block only at the next event. No big deal.
  2453. - if mi->rli.ignore_log_space_limit is 0 but becomes 1 just after (so
  2454. the clean value is 1), then we are going into wait_for_relay_log_space()
  2455. for no reason, but this function will do a clean read, notice the clean
  2456. value and exit immediately.
  2457. */
  2458. #ifndef DBUG_OFF
  2459. {
  2460. char llbuf1[22], llbuf2[22];
  2461. DBUG_PRINT("info", ("log_space_limit=%s log_space_total=%s \
  2462. ignore_log_space_limit=%d",
  2463. llstr(rli->log_space_limit,llbuf1),
  2464. llstr(rli->log_space_total,llbuf2),
  2465. (int) rli->ignore_log_space_limit));
  2466. }
  2467. #endif
  2468. if (rli->log_space_limit && rli->log_space_limit <
  2469. rli->log_space_total &&
  2470. !rli->ignore_log_space_limit)
  2471. if (wait_for_relay_log_space(rli))
  2472. {
  2473. sql_print_error("Slave I/O thread aborted while waiting for relay \
  2474. log space");
  2475. goto err;
  2476. }
  2477. }
  2478. }
  2479. // error = 0;
  2480. err:
  2481. // print the current replication position
  2482. sql_print_information("Slave I/O thread exiting, read up to log '%s', position %s",
  2483. IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff));
  2484. thd->set_query(NULL, 0);
  2485. thd->reset_db(NULL, 0);
  2486. if (mysql)
  2487. {
  2488. /*
  2489. Here we need to clear the active VIO before closing the
  2490. connection with the master. The reason is that THD::awake()
  2491. might be called from terminate_slave_thread() because somebody
  2492. issued a STOP SLAVE. If that happends, the close_active_vio()
  2493. can be called in the middle of closing the VIO associated with
  2494. the 'mysql' object, causing a crash.
  2495. */
  2496. #ifdef SIGNAL_WITH_VIO_CLOSE
  2497. thd->clear_active_vio();
  2498. #endif
  2499. mysql_close(mysql);
  2500. mi->mysql=0;
  2501. }
  2502. write_ignored_events_info_to_relay_log(thd, mi);
  2503. thd_proc_info(thd, "Waiting for slave mutex on exit");
  2504. pthread_mutex_lock(&mi->run_lock);
  2505. /* Forget the relay log's format */
  2506. delete mi->rli.relay_log.description_event_for_queue;
  2507. mi->rli.relay_log.description_event_for_queue= 0;
  2508. // TODO: make rpl_status part of Master_info
  2509. change_rpl_status(RPL_ACTIVE_SLAVE,RPL_IDLE_SLAVE);
  2510. DBUG_ASSERT(thd->net.buff != 0);
  2511. net_end(&thd->net); // destructor will not free it, because net.vio is 0
  2512. close_thread_tables(thd);
  2513. pthread_mutex_lock(&LOCK_thread_count);
  2514. THD_CHECK_SENTRY(thd);
  2515. delete thd;
  2516. pthread_mutex_unlock(&LOCK_thread_count);
  2517. mi->abort_slave= 0;
  2518. mi->slave_running= 0;
  2519. mi->io_thd= 0;
  2520. /*
  2521. Note: the order of the two following calls (first broadcast, then unlock)
  2522. is important. Otherwise a killer_thread can execute between the calls and
  2523. delete the mi structure leading to a crash! (see BUG#25306 for details)
  2524. */
  2525. pthread_cond_broadcast(&mi->stop_cond); // tell the world we are done
  2526. DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5););
  2527. pthread_mutex_unlock(&mi->run_lock);
  2528. DBUG_LEAVE; // Must match DBUG_ENTER()
  2529. my_thread_end();
  2530. pthread_exit(0);
  2531. return 0; // Avoid compiler warnings
  2532. }
  2533. /*
  2534. Check the temporary directory used by commands like
  2535. LOAD DATA INFILE.
  2536. */
  2537. static
  2538. int check_temp_dir(char* tmp_file)
  2539. {
  2540. int fd;
  2541. MY_DIR *dirp;
  2542. char tmp_dir[FN_REFLEN];
  2543. size_t tmp_dir_size;
  2544. DBUG_ENTER("check_temp_dir");
  2545. /*
  2546. Get the directory from the temporary file.
  2547. */
  2548. dirname_part(tmp_dir, tmp_file, &tmp_dir_size);
  2549. /*
  2550. Check if the directory exists.
  2551. */
  2552. if (!(dirp=my_dir(tmp_dir,MYF(MY_WME))))
  2553. DBUG_RETURN(1);
  2554. my_dirend(dirp);
  2555. /*
  2556. Check permissions to create a file.
  2557. */
  2558. if ((fd= my_create(tmp_file, CREATE_MODE,
  2559. O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
  2560. MYF(MY_WME))) < 0)
  2561. DBUG_RETURN(1);
  2562. /*
  2563. Clean up.
  2564. */
  2565. my_close(fd, MYF(0));
  2566. my_delete(tmp_file, MYF(0));
  2567. DBUG_RETURN(0);
  2568. }
  2569. /**
  2570. Slave SQL thread entry point.
  2571. @param arg Pointer to Relay_log_info object that holds information
  2572. for the SQL thread.
  2573. @return Always 0.
  2574. */
  2575. pthread_handler_t handle_slave_sql(void *arg)
  2576. {
  2577. THD *thd; /* needs to be first for thread_stack */
  2578. char llbuff[22],llbuff1[22];
  2579. char saved_log_name[FN_REFLEN];
  2580. char saved_master_log_name[FN_REFLEN];
  2581. my_off_t UNINIT_VAR(saved_log_pos);
  2582. my_off_t UNINIT_VAR(saved_master_log_pos);
  2583. my_off_t saved_skip= 0;
  2584. Relay_log_info* rli = &((Master_info*)arg)->rli;
  2585. const char *errmsg;
  2586. // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
  2587. my_thread_init();
  2588. DBUG_ENTER("handle_slave_sql");
  2589. DBUG_ASSERT(rli->inited);
  2590. pthread_mutex_lock(&rli->run_lock);
  2591. DBUG_ASSERT(!rli->slave_running);
  2592. errmsg= 0;
  2593. #ifndef DBUG_OFF
  2594. rli->events_till_abort = abort_slave_event_count;
  2595. #endif
  2596. thd = new THD; // note that contructor of THD uses DBUG_ !
  2597. thd->thread_stack = (char*)&thd; // remember where our stack is
  2598. rli->sql_thd= thd;
  2599. /* Inform waiting threads that slave has started */
  2600. rli->slave_run_id++;
  2601. rli->slave_running = 1;
  2602. pthread_detach_this_thread();
  2603. if (init_slave_thread(thd, SLAVE_THD_SQL))
  2604. {
  2605. /*
  2606. TODO: this is currently broken - slave start and change master
  2607. will be stuck if we fail here
  2608. */
  2609. pthread_cond_broadcast(&rli->start_cond);
  2610. pthread_mutex_unlock(&rli->run_lock);
  2611. rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
  2612. "Failed during slave thread initialization");
  2613. goto err;
  2614. }
  2615. thd->init_for_queries();
  2616. thd->temporary_tables = rli->save_temporary_tables; // restore temp tables
  2617. set_thd_in_use_temporary_tables(rli); // (re)set sql_thd in use for saved temp tables
  2618. pthread_mutex_lock(&LOCK_thread_count);
  2619. threads.append(thd);
  2620. pthread_mutex_unlock(&LOCK_thread_count);
  2621. /*
  2622. We are going to set slave_running to 1. Assuming slave I/O thread is
  2623. alive and connected, this is going to make Seconds_Behind_Master be 0
  2624. i.e. "caught up". Even if we're just at start of thread. Well it's ok, at
  2625. the moment we start we can think we are caught up, and the next second we
  2626. start receiving data so we realize we are not caught up and
  2627. Seconds_Behind_Master grows. No big deal.
  2628. */
  2629. rli->abort_slave = 0;
  2630. pthread_mutex_unlock(&rli->run_lock);
  2631. pthread_cond_broadcast(&rli->start_cond);
  2632. /*
  2633. Reset errors for a clean start (otherwise, if the master is idle, the SQL
  2634. thread may execute no Query_log_event, so the error will remain even
  2635. though there's no problem anymore). Do not reset the master timestamp
  2636. (imagine the slave has caught everything, the STOP SLAVE and START SLAVE:
  2637. as we are not sure that we are going to receive a query, we want to
  2638. remember the last master timestamp (to say how many seconds behind we are
  2639. now.
  2640. But the master timestamp is reset by RESET SLAVE & CHANGE MASTER.
  2641. */
  2642. rli->clear_error();
  2643. //tell the I/O thread to take relay_log_space_limit into account from now on
  2644. pthread_mutex_lock(&rli->log_space_lock);
  2645. rli->ignore_log_space_limit= 0;
  2646. pthread_mutex_unlock(&rli->log_space_lock);
  2647. rli->trans_retries= 0; // start from "no error"
  2648. DBUG_PRINT("info", ("rli->trans_retries: %lu", rli->trans_retries));
  2649. if (init_relay_log_pos(rli,
  2650. rli->group_relay_log_name,
  2651. rli->group_relay_log_pos,
  2652. 1 /*need data lock*/, &errmsg,
  2653. 1 /*look for a description_event*/))
  2654. {
  2655. rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
  2656. "Error initializing relay log position: %s", errmsg);
  2657. goto err;
  2658. }
  2659. THD_CHECK_SENTRY(thd);
  2660. #ifndef DBUG_OFF
  2661. {
  2662. char llbuf1[22], llbuf2[22];
  2663. DBUG_PRINT("info", ("my_b_tell(rli->cur_log)=%s rli->event_relay_log_pos=%s",
  2664. llstr(my_b_tell(rli->cur_log),llbuf1),
  2665. llstr(rli->event_relay_log_pos,llbuf2)));
  2666. DBUG_ASSERT(rli->event_relay_log_pos >= BIN_LOG_HEADER_SIZE);
  2667. /*
  2668. Wonder if this is correct. I (Guilhem) wonder if my_b_tell() returns the
  2669. correct position when it's called just after my_b_seek() (the questionable
  2670. stuff is those "seek is done on next read" comments in the my_b_seek()
  2671. source code).
  2672. The crude reality is that this assertion randomly fails whereas
  2673. replication seems to work fine. And there is no easy explanation why it
  2674. fails (as we my_b_seek(rli->event_relay_log_pos) at the very end of
  2675. init_relay_log_pos() called above). Maybe the assertion would be
  2676. meaningful if we held rli->data_lock between the my_b_seek() and the
  2677. DBUG_ASSERT().
  2678. */
  2679. #ifdef SHOULD_BE_CHECKED
  2680. DBUG_ASSERT(my_b_tell(rli->cur_log) == rli->event_relay_log_pos);
  2681. #endif
  2682. }
  2683. #endif
  2684. DBUG_ASSERT(rli->sql_thd == thd);
  2685. DBUG_PRINT("master_info",("log_file_name: %s position: %s",
  2686. rli->group_master_log_name,
  2687. llstr(rli->group_master_log_pos,llbuff)));
  2688. if (global_system_variables.log_warnings)
  2689. sql_print_information("Slave SQL thread initialized, starting replication in \
  2690. log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME,
  2691. llstr(rli->group_master_log_pos,llbuff),rli->group_relay_log_name,
  2692. llstr(rli->group_relay_log_pos,llbuff1));
  2693. if (check_temp_dir(rli->slave_patternload_file))
  2694. {
  2695. rli->report(ERROR_LEVEL, thd->main_da.sql_errno(),
  2696. "Unable to use slave's temporary directory %s - %s",
  2697. slave_load_tmpdir, thd->main_da.message());
  2698. goto err;
  2699. }
  2700. /* execute init_slave variable */
  2701. if (sys_init_slave.value_length)
  2702. {
  2703. execute_init_command(thd, &sys_init_slave, &LOCK_sys_init_slave);
  2704. if (thd->is_slave_error)
  2705. {
  2706. rli->report(ERROR_LEVEL, thd->main_da.sql_errno(),
  2707. "Slave SQL thread aborted. Can't execute init_slave query");
  2708. goto err;
  2709. }
  2710. }
  2711. /*
  2712. First check until condition - probably there is nothing to execute. We
  2713. do not want to wait for next event in this case.
  2714. */
  2715. pthread_mutex_lock(&rli->data_lock);
  2716. if (rli->slave_skip_counter)
  2717. {
  2718. strmake(saved_log_name, rli->group_relay_log_name, FN_REFLEN - 1);
  2719. strmake(saved_master_log_name, rli->group_master_log_name, FN_REFLEN - 1);
  2720. saved_log_pos= rli->group_relay_log_pos;
  2721. saved_master_log_pos= rli->group_master_log_pos;
  2722. saved_skip= rli->slave_skip_counter;
  2723. }
  2724. if (rli->until_condition != Relay_log_info::UNTIL_NONE &&
  2725. rli->is_until_satisfied(thd, NULL))
  2726. {
  2727. char buf[22];
  2728. sql_print_information("Slave SQL thread stopped because it reached its"
  2729. " UNTIL position %s", llstr(rli->until_pos(), buf));
  2730. pthread_mutex_unlock(&rli->data_lock);
  2731. goto err;
  2732. }
  2733. pthread_mutex_unlock(&rli->data_lock);
  2734. /* Read queries from the IO/THREAD until this thread is killed */
  2735. while (!sql_slave_killed(thd,rli))
  2736. {
  2737. thd_proc_info(thd, "Reading event from the relay log");
  2738. DBUG_ASSERT(rli->sql_thd == thd);
  2739. THD_CHECK_SENTRY(thd);
  2740. if (saved_skip && rli->slave_skip_counter == 0)
  2741. {
  2742. sql_print_information("'SQL_SLAVE_SKIP_COUNTER=%ld' executed at "
  2743. "relay_log_file='%s', relay_log_pos='%ld', master_log_name='%s', "
  2744. "master_log_pos='%ld' and new position at "
  2745. "relay_log_file='%s', relay_log_pos='%ld', master_log_name='%s', "
  2746. "master_log_pos='%ld' ",
  2747. (ulong) saved_skip, saved_log_name, (ulong) saved_log_pos,
  2748. saved_master_log_name, (ulong) saved_master_log_pos,
  2749. rli->group_relay_log_name, (ulong) rli->group_relay_log_pos,
  2750. rli->group_master_log_name, (ulong) rli->group_master_log_pos);
  2751. saved_skip= 0;
  2752. }
  2753. if (exec_relay_log_event(thd,rli))
  2754. {
  2755. DBUG_PRINT("info", ("exec_relay_log_event() failed"));
  2756. // do not scare the user if SQL thread was simply killed or stopped
  2757. if (!sql_slave_killed(thd,rli))
  2758. {
  2759. /*
  2760. retrieve as much info as possible from the thd and, error
  2761. codes and warnings and print this to the error log as to
  2762. allow the user to locate the error
  2763. */
  2764. uint32 const last_errno= rli->last_error().number;
  2765. if (thd->is_error())
  2766. {
  2767. char const *const errmsg= thd->main_da.message();
  2768. DBUG_PRINT("info",
  2769. ("thd->main_da.sql_errno()=%d; rli->last_error.number=%d",
  2770. thd->main_da.sql_errno(), last_errno));
  2771. if (last_errno == 0)
  2772. {
  2773. /*
  2774. This function is reporting an error which was not reported
  2775. while executing exec_relay_log_event().
  2776. */
  2777. rli->report(ERROR_LEVEL, thd->main_da.sql_errno(), "%s", errmsg);
  2778. }
  2779. else if (last_errno != thd->main_da.sql_errno())
  2780. {
  2781. /*
  2782. * An error was reported while executing exec_relay_log_event()
  2783. * however the error code differs from what is in the thread.
  2784. * This function prints out more information to help finding
  2785. * what caused the problem.
  2786. */
  2787. sql_print_error("Slave (additional info): %s Error_code: %d",
  2788. errmsg, thd->main_da.sql_errno());
  2789. }
  2790. }
  2791. /* Print any warnings issued */
  2792. List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
  2793. MYSQL_ERROR *err;
  2794. /*
  2795. Added controlled slave thread cancel for replication
  2796. of user-defined variables.
  2797. */
  2798. bool udf_error = false;
  2799. while ((err= it++))
  2800. {
  2801. if (err->code == ER_CANT_OPEN_LIBRARY)
  2802. udf_error = true;
  2803. sql_print_warning("Slave: %s Error_code: %d",err->msg, err->code);
  2804. }
  2805. if (udf_error)
  2806. sql_print_error("Error loading user-defined library, slave SQL "
  2807. "thread aborted. Install the missing library, and restart the "
  2808. "slave SQL thread with \"SLAVE START\". We stopped at log '%s' "
  2809. "position %s", RPL_LOG_NAME, llstr(rli->group_master_log_pos,
  2810. llbuff));
  2811. else
  2812. sql_print_error("\
  2813. Error running query, slave SQL thread aborted. Fix the problem, and restart \
  2814. the slave SQL thread with \"SLAVE START\". We stopped at log \
  2815. '%s' position %s", RPL_LOG_NAME, llstr(rli->group_master_log_pos, llbuff));
  2816. }
  2817. goto err;
  2818. }
  2819. }
  2820. /* Thread stopped. Print the current replication position to the log */
  2821. sql_print_information("Slave SQL thread exiting, replication stopped in log "
  2822. "'%s' at position %s",
  2823. RPL_LOG_NAME, llstr(rli->group_master_log_pos,llbuff));
  2824. err:
  2825. /*
  2826. Some events set some playgrounds, which won't be cleared because thread
  2827. stops. Stopping of this thread may not be known to these events ("stop"
  2828. request is detected only by the present function, not by events), so we
  2829. must "proactively" clear playgrounds:
  2830. */
  2831. thd->clear_error();
  2832. rli->cleanup_context(thd, 1);
  2833. /*
  2834. Some extra safety, which should not been needed (normally, event deletion
  2835. should already have done these assignments (each event which sets these
  2836. variables is supposed to set them to 0 before terminating)).
  2837. */
  2838. thd->catalog= 0;
  2839. thd->set_query(NULL, 0);
  2840. thd->reset_db(NULL, 0);
  2841. thd_proc_info(thd, "Waiting for slave mutex on exit");
  2842. pthread_mutex_lock(&rli->run_lock);
  2843. /* We need data_lock, at least to wake up any waiting master_pos_wait() */
  2844. pthread_mutex_lock(&rli->data_lock);
  2845. DBUG_ASSERT(rli->slave_running == 1); // tracking buffer overrun
  2846. /* When master_pos_wait() wakes up it will check this and terminate */
  2847. rli->slave_running= 0;
  2848. /* Forget the relay log's format */
  2849. delete rli->relay_log.description_event_for_exec;
  2850. rli->relay_log.description_event_for_exec= 0;
  2851. /* Wake up master_pos_wait() */
  2852. pthread_mutex_unlock(&rli->data_lock);
  2853. DBUG_PRINT("info",("Signaling possibly waiting master_pos_wait() functions"));
  2854. pthread_cond_broadcast(&rli->data_cond);
  2855. rli->ignore_log_space_limit= 0; /* don't need any lock */
  2856. /* we die so won't remember charset - re-update them on next thread start */
  2857. rli->cached_charset_invalidate();
  2858. rli->save_temporary_tables = thd->temporary_tables;
  2859. /*
  2860. TODO: see if we can do this conditionally in next_event() instead
  2861. to avoid unneeded position re-init
  2862. */
  2863. thd->temporary_tables = 0; // remove tempation from destructor to close them
  2864. DBUG_ASSERT(thd->net.buff != 0);
  2865. net_end(&thd->net); // destructor will not free it, because we are weird
  2866. DBUG_ASSERT(rli->sql_thd == thd);
  2867. THD_CHECK_SENTRY(thd);
  2868. rli->sql_thd= 0;
  2869. set_thd_in_use_temporary_tables(rli); // (re)set sql_thd in use for saved temp tables
  2870. pthread_mutex_lock(&LOCK_thread_count);
  2871. THD_CHECK_SENTRY(thd);
  2872. delete thd;
  2873. pthread_mutex_unlock(&LOCK_thread_count);
  2874. /*
  2875. Note: the order of the broadcast and unlock calls below (first broadcast, then unlock)
  2876. is important. Otherwise a killer_thread can execute between the calls and
  2877. delete the mi structure leading to a crash! (see BUG#25306 for details)
  2878. */
  2879. pthread_cond_broadcast(&rli->stop_cond);
  2880. DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5););
  2881. pthread_mutex_unlock(&rli->run_lock); // tell the world we are done
  2882. DBUG_LEAVE; // Must match DBUG_ENTER()
  2883. my_thread_end();
  2884. pthread_exit(0);
  2885. return 0; // Avoid compiler warnings
  2886. }
  2887. /*
  2888. process_io_create_file()
  2889. */
  2890. static int process_io_create_file(Master_info* mi, Create_file_log_event* cev)
  2891. {
  2892. int error = 1;
  2893. ulong num_bytes;
  2894. bool cev_not_written;
  2895. THD *thd = mi->io_thd;
  2896. NET *net = &mi->mysql->net;
  2897. DBUG_ENTER("process_io_create_file");
  2898. if (unlikely(!cev->is_valid()))
  2899. DBUG_RETURN(1);
  2900. if (!rpl_filter->db_ok(cev->db))
  2901. {
  2902. skip_load_data_infile(net);
  2903. DBUG_RETURN(0);
  2904. }
  2905. DBUG_ASSERT(cev->inited_from_old);
  2906. thd->file_id = cev->file_id = mi->file_id++;
  2907. thd->server_id = cev->server_id;
  2908. cev_not_written = 1;
  2909. if (unlikely(net_request_file(net,cev->fname)))
  2910. {
  2911. sql_print_error("Slave I/O: failed requesting download of '%s'",
  2912. cev->fname);
  2913. goto err;
  2914. }
  2915. /*
  2916. This dummy block is so we could instantiate Append_block_log_event
  2917. once and then modify it slightly instead of doing it multiple times
  2918. in the loop
  2919. */
  2920. {
  2921. Append_block_log_event aev(thd,0,0,0,0);
  2922. for (;;)
  2923. {
  2924. if (unlikely((num_bytes=my_net_read(net)) == packet_error))
  2925. {
  2926. sql_print_error("Network read error downloading '%s' from master",
  2927. cev->fname);
  2928. goto err;
  2929. }
  2930. if (unlikely(!num_bytes)) /* eof */
  2931. {
  2932. /* 3.23 master wants it */
  2933. net_write_command(net, 0, (uchar*) "", 0, (uchar*) "", 0);
  2934. /*
  2935. If we wrote Create_file_log_event, then we need to write
  2936. Execute_load_log_event. If we did not write Create_file_log_event,
  2937. then this is an empty file and we can just do as if the LOAD DATA
  2938. INFILE had not existed, i.e. write nothing.
  2939. */
  2940. if (unlikely(cev_not_written))
  2941. break;
  2942. Execute_load_log_event xev(thd,0,0);
  2943. xev.log_pos = cev->log_pos;
  2944. if (unlikely(mi->rli.relay_log.append(&xev)))
  2945. {
  2946. mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
  2947. ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
  2948. "error writing Exec_load event to relay log");
  2949. goto err;
  2950. }
  2951. mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
  2952. break;
  2953. }
  2954. if (unlikely(cev_not_written))
  2955. {
  2956. cev->block = net->read_pos;
  2957. cev->block_len = num_bytes;
  2958. if (unlikely(mi->rli.relay_log.append(cev)))
  2959. {
  2960. mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
  2961. ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
  2962. "error writing Create_file event to relay log");
  2963. goto err;
  2964. }
  2965. cev_not_written=0;
  2966. mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
  2967. }
  2968. else
  2969. {
  2970. aev.block = net->read_pos;
  2971. aev.block_len = num_bytes;
  2972. aev.log_pos = cev->log_pos;
  2973. if (unlikely(mi->rli.relay_log.append(&aev)))
  2974. {
  2975. mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
  2976. ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
  2977. "error writing Append_block event to relay log");
  2978. goto err;
  2979. }
  2980. mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total) ;
  2981. }
  2982. }
  2983. }
  2984. error=0;
  2985. err:
  2986. DBUG_RETURN(error);
  2987. }
  2988. /*
  2989. Start using a new binary log on the master
  2990. SYNOPSIS
  2991. process_io_rotate()
  2992. mi master_info for the slave
  2993. rev The rotate log event read from the binary log
  2994. DESCRIPTION
  2995. Updates the master info with the place in the next binary
  2996. log where we should start reading.
  2997. Rotate the relay log to avoid mixed-format relay logs.
  2998. NOTES
  2999. We assume we already locked mi->data_lock
  3000. RETURN VALUES
  3001. 0 ok
  3002. 1 Log event is illegal
  3003. */
  3004. static int process_io_rotate(Master_info *mi, Rotate_log_event *rev)
  3005. {
  3006. DBUG_ENTER("process_io_rotate");
  3007. safe_mutex_assert_owner(&mi->data_lock);
  3008. if (unlikely(!rev->is_valid()))
  3009. DBUG_RETURN(1);
  3010. /* Safe copy as 'rev' has been "sanitized" in Rotate_log_event's ctor */
  3011. memcpy(mi->master_log_name, rev->new_log_ident, rev->ident_len+1);
  3012. mi->master_log_pos= rev->pos;
  3013. DBUG_PRINT("info", ("master_log_pos: '%s' %lu",
  3014. mi->master_log_name, (ulong) mi->master_log_pos));
  3015. #ifndef DBUG_OFF
  3016. /*
  3017. If we do not do this, we will be getting the first
  3018. rotate event forever, so we need to not disconnect after one.
  3019. */
  3020. if (disconnect_slave_event_count)
  3021. mi->events_till_disconnect++;
  3022. #endif
  3023. /*
  3024. If description_event_for_queue is format <4, there is conversion in the
  3025. relay log to the slave's format (4). And Rotate can mean upgrade or
  3026. nothing. If upgrade, it's to 5.0 or newer, so we will get a Format_desc, so
  3027. no need to reset description_event_for_queue now. And if it's nothing (same
  3028. master version as before), no need (still using the slave's format).
  3029. */
  3030. if (mi->rli.relay_log.description_event_for_queue->binlog_version >= 4)
  3031. {
  3032. delete mi->rli.relay_log.description_event_for_queue;
  3033. /* start from format 3 (MySQL 4.0) again */
  3034. mi->rli.relay_log.description_event_for_queue= new
  3035. Format_description_log_event(3);
  3036. }
  3037. /*
  3038. Rotate the relay log makes binlog format detection easier (at next slave
  3039. start or mysqlbinlog)
  3040. */
  3041. DBUG_RETURN(rotate_relay_log(mi) /* will take the right mutexes */);
  3042. }
  3043. /*
  3044. Reads a 3.23 event and converts it to the slave's format. This code was
  3045. copied from MySQL 4.0.
  3046. */
  3047. static int queue_binlog_ver_1_event(Master_info *mi, const char *buf,
  3048. ulong event_len)
  3049. {
  3050. const char *errmsg = 0;
  3051. ulong inc_pos;
  3052. bool ignore_event= 0;
  3053. char *tmp_buf = 0;
  3054. Relay_log_info *rli= &mi->rli;
  3055. DBUG_ENTER("queue_binlog_ver_1_event");
  3056. /*
  3057. If we get Load event, we need to pass a non-reusable buffer
  3058. to read_log_event, so we do a trick
  3059. */
  3060. if (buf[EVENT_TYPE_OFFSET] == LOAD_EVENT)
  3061. {
  3062. if (unlikely(!(tmp_buf=(char*)my_malloc(event_len+1,MYF(MY_WME)))))
  3063. {
  3064. mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
  3065. ER(ER_SLAVE_FATAL_ERROR), "Memory allocation failed");
  3066. DBUG_RETURN(1);
  3067. }
  3068. memcpy(tmp_buf,buf,event_len);
  3069. /*
  3070. Create_file constructor wants a 0 as last char of buffer, this 0 will
  3071. serve as the string-termination char for the file's name (which is at the
  3072. end of the buffer)
  3073. We must increment event_len, otherwise the event constructor will not see
  3074. this end 0, which leads to segfault.
  3075. */
  3076. tmp_buf[event_len++]=0;
  3077. int4store(tmp_buf+EVENT_LEN_OFFSET, event_len);
  3078. buf = (const char*)tmp_buf;
  3079. }
  3080. /*
  3081. This will transform LOAD_EVENT into CREATE_FILE_EVENT, ask the master to
  3082. send the loaded file, and write it to the relay log in the form of
  3083. Append_block/Exec_load (the SQL thread needs the data, as that thread is not
  3084. connected to the master).
  3085. */
  3086. Log_event *ev = Log_event::read_log_event(buf,event_len, &errmsg,
  3087. mi->rli.relay_log.description_event_for_queue);
  3088. if (unlikely(!ev))
  3089. {
  3090. sql_print_error("Read invalid event from master: '%s',\
  3091. master could be corrupt but a more likely cause of this is a bug",
  3092. errmsg);
  3093. my_free((char*) tmp_buf, MYF(MY_ALLOW_ZERO_PTR));
  3094. DBUG_RETURN(1);
  3095. }
  3096. pthread_mutex_lock(&mi->data_lock);
  3097. ev->log_pos= mi->master_log_pos; /* 3.23 events don't contain log_pos */
  3098. switch (ev->get_type_code()) {
  3099. case STOP_EVENT:
  3100. ignore_event= 1;
  3101. inc_pos= event_len;
  3102. break;
  3103. case ROTATE_EVENT:
  3104. if (unlikely(process_io_rotate(mi,(Rotate_log_event*)ev)))
  3105. {
  3106. delete ev;
  3107. pthread_mutex_unlock(&mi->data_lock);
  3108. DBUG_RETURN(1);
  3109. }
  3110. inc_pos= 0;
  3111. break;
  3112. case CREATE_FILE_EVENT:
  3113. /*
  3114. Yes it's possible to have CREATE_FILE_EVENT here, even if we're in
  3115. queue_old_event() which is for 3.23 events which don't comprise
  3116. CREATE_FILE_EVENT. This is because read_log_event() above has just
  3117. transformed LOAD_EVENT into CREATE_FILE_EVENT.
  3118. */
  3119. {
  3120. /* We come here when and only when tmp_buf != 0 */
  3121. DBUG_ASSERT(tmp_buf != 0);
  3122. inc_pos=event_len;
  3123. ev->log_pos+= inc_pos;
  3124. int error = process_io_create_file(mi,(Create_file_log_event*)ev);
  3125. delete ev;
  3126. mi->master_log_pos += inc_pos;
  3127. DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
  3128. pthread_mutex_unlock(&mi->data_lock);
  3129. my_free((char*)tmp_buf, MYF(0));
  3130. DBUG_RETURN(error);
  3131. }
  3132. default:
  3133. inc_pos= event_len;
  3134. break;
  3135. }
  3136. if (likely(!ignore_event))
  3137. {
  3138. if (ev->log_pos)
  3139. /*
  3140. Don't do it for fake Rotate events (see comment in
  3141. Log_event::Log_event(const char* buf...) in log_event.cc).
  3142. */
  3143. ev->log_pos+= event_len; /* make log_pos be the pos of the end of the event */
  3144. if (unlikely(rli->relay_log.append(ev)))
  3145. {
  3146. delete ev;
  3147. pthread_mutex_unlock(&mi->data_lock);
  3148. DBUG_RETURN(1);
  3149. }
  3150. rli->relay_log.harvest_bytes_written(&rli->log_space_total);
  3151. }
  3152. delete ev;
  3153. mi->master_log_pos+= inc_pos;
  3154. DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
  3155. pthread_mutex_unlock(&mi->data_lock);
  3156. DBUG_RETURN(0);
  3157. }
  3158. /*
  3159. Reads a 4.0 event and converts it to the slave's format. This code was copied
  3160. from queue_binlog_ver_1_event(), with some affordable simplifications.
  3161. */
  3162. static int queue_binlog_ver_3_event(Master_info *mi, const char *buf,
  3163. ulong event_len)
  3164. {
  3165. const char *errmsg = 0;
  3166. ulong inc_pos;
  3167. char *tmp_buf = 0;
  3168. Relay_log_info *rli= &mi->rli;
  3169. DBUG_ENTER("queue_binlog_ver_3_event");
  3170. /* read_log_event() will adjust log_pos to be end_log_pos */
  3171. Log_event *ev = Log_event::read_log_event(buf,event_len, &errmsg,
  3172. mi->rli.relay_log.description_event_for_queue);
  3173. if (unlikely(!ev))
  3174. {
  3175. sql_print_error("Read invalid event from master: '%s',\
  3176. master could be corrupt but a more likely cause of this is a bug",
  3177. errmsg);
  3178. my_free((char*) tmp_buf, MYF(MY_ALLOW_ZERO_PTR));
  3179. DBUG_RETURN(1);
  3180. }
  3181. pthread_mutex_lock(&mi->data_lock);
  3182. switch (ev->get_type_code()) {
  3183. case STOP_EVENT:
  3184. goto err;
  3185. case ROTATE_EVENT:
  3186. if (unlikely(process_io_rotate(mi,(Rotate_log_event*)ev)))
  3187. {
  3188. delete ev;
  3189. pthread_mutex_unlock(&mi->data_lock);
  3190. DBUG_RETURN(1);
  3191. }
  3192. inc_pos= 0;
  3193. break;
  3194. default:
  3195. inc_pos= event_len;
  3196. break;
  3197. }
  3198. if (unlikely(rli->relay_log.append(ev)))
  3199. {
  3200. delete ev;
  3201. pthread_mutex_unlock(&mi->data_lock);
  3202. DBUG_RETURN(1);
  3203. }
  3204. rli->relay_log.harvest_bytes_written(&rli->log_space_total);
  3205. delete ev;
  3206. mi->master_log_pos+= inc_pos;
  3207. err:
  3208. DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
  3209. pthread_mutex_unlock(&mi->data_lock);
  3210. DBUG_RETURN(0);
  3211. }
  3212. /*
  3213. queue_old_event()
  3214. Writes a 3.23 or 4.0 event to the relay log, after converting it to the 5.0
  3215. (exactly, slave's) format. To do the conversion, we create a 5.0 event from
  3216. the 3.23/4.0 bytes, then write this event to the relay log.
  3217. TODO:
  3218. Test this code before release - it has to be tested on a separate
  3219. setup with 3.23 master or 4.0 master
  3220. */
  3221. static int queue_old_event(Master_info *mi, const char *buf,
  3222. ulong event_len)
  3223. {
  3224. DBUG_ENTER("queue_old_event");
  3225. switch (mi->rli.relay_log.description_event_for_queue->binlog_version)
  3226. {
  3227. case 1:
  3228. DBUG_RETURN(queue_binlog_ver_1_event(mi,buf,event_len));
  3229. case 3:
  3230. DBUG_RETURN(queue_binlog_ver_3_event(mi,buf,event_len));
  3231. default: /* unsupported format; eg version 2 */
  3232. DBUG_PRINT("info",("unsupported binlog format %d in queue_old_event()",
  3233. mi->rli.relay_log.description_event_for_queue->binlog_version));
  3234. DBUG_RETURN(1);
  3235. }
  3236. }
  3237. /*
  3238. queue_event()
  3239. If the event is 3.23/4.0, passes it to queue_old_event() which will convert
  3240. it. Otherwise, writes a 5.0 (or newer) event to the relay log. Then there is
  3241. no format conversion, it's pure read/write of bytes.
  3242. So a 5.0.0 slave's relay log can contain events in the slave's format or in
  3243. any >=5.0.0 format.
  3244. */
  3245. static int queue_event(Master_info* mi,const char* buf, ulong event_len)
  3246. {
  3247. int error= 0;
  3248. ulong inc_pos;
  3249. Relay_log_info *rli= &mi->rli;
  3250. pthread_mutex_t *log_lock= rli->relay_log.get_log_lock();
  3251. DBUG_ENTER("queue_event");
  3252. LINT_INIT(inc_pos);
  3253. if (mi->rli.relay_log.description_event_for_queue->binlog_version<4 &&
  3254. buf[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT /* a way to escape */)
  3255. DBUG_RETURN(queue_old_event(mi,buf,event_len));
  3256. LINT_INIT(inc_pos);
  3257. pthread_mutex_lock(&mi->data_lock);
  3258. switch (buf[EVENT_TYPE_OFFSET]) {
  3259. case STOP_EVENT:
  3260. /*
  3261. We needn't write this event to the relay log. Indeed, it just indicates a
  3262. master server shutdown. The only thing this does is cleaning. But
  3263. cleaning is already done on a per-master-thread basis (as the master
  3264. server is shutting down cleanly, it has written all DROP TEMPORARY TABLE
  3265. prepared statements' deletion are TODO only when we binlog prep stmts).
  3266. We don't even increment mi->master_log_pos, because we may be just after
  3267. a Rotate event. Btw, in a few milliseconds we are going to have a Start
  3268. event from the next binlog (unless the master is presently running
  3269. without --log-bin).
  3270. */
  3271. goto err;
  3272. case ROTATE_EVENT:
  3273. {
  3274. Rotate_log_event rev(buf,event_len,mi->rli.relay_log.description_event_for_queue);
  3275. if (unlikely(process_io_rotate(mi,&rev)))
  3276. {
  3277. error= 1;
  3278. goto err;
  3279. }
  3280. /*
  3281. Now the I/O thread has just changed its mi->master_log_name, so
  3282. incrementing mi->master_log_pos is nonsense.
  3283. */
  3284. inc_pos= 0;
  3285. break;
  3286. }
  3287. case FORMAT_DESCRIPTION_EVENT:
  3288. {
  3289. /*
  3290. Create an event, and save it (when we rotate the relay log, we will have
  3291. to write this event again).
  3292. */
  3293. /*
  3294. We are the only thread which reads/writes description_event_for_queue.
  3295. The relay_log struct does not move (though some members of it can
  3296. change), so we needn't any lock (no rli->data_lock, no log lock).
  3297. */
  3298. Format_description_log_event* tmp;
  3299. const char* errmsg;
  3300. if (!(tmp= (Format_description_log_event*)
  3301. Log_event::read_log_event(buf, event_len, &errmsg,
  3302. mi->rli.relay_log.description_event_for_queue)))
  3303. {
  3304. error= 2;
  3305. goto err;
  3306. }
  3307. delete mi->rli.relay_log.description_event_for_queue;
  3308. mi->rli.relay_log.description_event_for_queue= tmp;
  3309. /*
  3310. Though this does some conversion to the slave's format, this will
  3311. preserve the master's binlog format version, and number of event types.
  3312. */
  3313. /*
  3314. If the event was not requested by the slave (the slave did not ask for
  3315. it), i.e. has end_log_pos=0, we do not increment mi->master_log_pos
  3316. */
  3317. inc_pos= uint4korr(buf+LOG_POS_OFFSET) ? event_len : 0;
  3318. DBUG_PRINT("info",("binlog format is now %d",
  3319. mi->rli.relay_log.description_event_for_queue->binlog_version));
  3320. }
  3321. break;
  3322. default:
  3323. inc_pos= event_len;
  3324. break;
  3325. }
  3326. /*
  3327. If this event is originating from this server, don't queue it.
  3328. We don't check this for 3.23 events because it's simpler like this; 3.23
  3329. will be filtered anyway by the SQL slave thread which also tests the
  3330. server id (we must also keep this test in the SQL thread, in case somebody
  3331. upgrades a 4.0 slave which has a not-filtered relay log).
  3332. ANY event coming from ourselves can be ignored: it is obvious for queries;
  3333. for STOP_EVENT/ROTATE_EVENT/START_EVENT: these cannot come from ourselves
  3334. (--log-slave-updates would not log that) unless this slave is also its
  3335. direct master (an unsupported, useless setup!).
  3336. */
  3337. pthread_mutex_lock(log_lock);
  3338. if ((uint4korr(buf + SERVER_ID_OFFSET) == ::server_id) &&
  3339. !mi->rli.replicate_same_server_id)
  3340. {
  3341. /*
  3342. Do not write it to the relay log.
  3343. a) We still want to increment mi->master_log_pos, so that we won't
  3344. re-read this event from the master if the slave IO thread is now
  3345. stopped/restarted (more efficient if the events we are ignoring are big
  3346. LOAD DATA INFILE).
  3347. b) We want to record that we are skipping events, for the information of
  3348. the slave SQL thread, otherwise that thread may let
  3349. rli->group_relay_log_pos stay too small if the last binlog's event is
  3350. ignored.
  3351. But events which were generated by this slave and which do not exist in
  3352. the master's binlog (i.e. Format_desc, Rotate & Stop) should not increment
  3353. mi->master_log_pos.
  3354. */
  3355. if (buf[EVENT_TYPE_OFFSET]!=FORMAT_DESCRIPTION_EVENT &&
  3356. buf[EVENT_TYPE_OFFSET]!=ROTATE_EVENT &&
  3357. buf[EVENT_TYPE_OFFSET]!=STOP_EVENT)
  3358. {
  3359. mi->master_log_pos+= inc_pos;
  3360. memcpy(rli->ign_master_log_name_end, mi->master_log_name, FN_REFLEN);
  3361. DBUG_ASSERT(rli->ign_master_log_name_end[0]);
  3362. rli->ign_master_log_pos_end= mi->master_log_pos;
  3363. }
  3364. rli->relay_log.signal_update(); // the slave SQL thread needs to re-check
  3365. DBUG_PRINT("info", ("master_log_pos: %lu, event originating from the same server, ignored",
  3366. (ulong) mi->master_log_pos));
  3367. }
  3368. else
  3369. {
  3370. /* write the event to the relay log */
  3371. if (likely(!(rli->relay_log.appendv(buf,event_len,0))))
  3372. {
  3373. mi->master_log_pos+= inc_pos;
  3374. DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
  3375. rli->relay_log.harvest_bytes_written(&rli->log_space_total);
  3376. }
  3377. else
  3378. error= 3;
  3379. rli->ign_master_log_name_end[0]= 0; // last event is not ignored
  3380. }
  3381. pthread_mutex_unlock(log_lock);
  3382. err:
  3383. pthread_mutex_unlock(&mi->data_lock);
  3384. DBUG_PRINT("info", ("error: %d", error));
  3385. DBUG_RETURN(error);
  3386. }
  3387. void end_relay_log_info(Relay_log_info* rli)
  3388. {
  3389. DBUG_ENTER("end_relay_log_info");
  3390. if (!rli->inited)
  3391. DBUG_VOID_RETURN;
  3392. if (rli->info_fd >= 0)
  3393. {
  3394. end_io_cache(&rli->info_file);
  3395. (void) my_close(rli->info_fd, MYF(MY_WME));
  3396. rli->info_fd = -1;
  3397. }
  3398. if (rli->cur_log_fd >= 0)
  3399. {
  3400. end_io_cache(&rli->cache_buf);
  3401. (void)my_close(rli->cur_log_fd, MYF(MY_WME));
  3402. rli->cur_log_fd = -1;
  3403. }
  3404. rli->inited = 0;
  3405. rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
  3406. rli->relay_log.harvest_bytes_written(&rli->log_space_total);
  3407. /*
  3408. Delete the slave's temporary tables from memory.
  3409. In the future there will be other actions than this, to ensure persistance
  3410. of slave's temp tables after shutdown.
  3411. */
  3412. rli->close_temporary_tables();
  3413. DBUG_VOID_RETURN;
  3414. }
  3415. /**
  3416. Hook to detach the active VIO before closing a connection handle.
  3417. The client API might close the connection (and associated data)
  3418. in case it encounters a unrecoverable (network) error. This hook
  3419. is called from the client code before the VIO handle is deleted
  3420. allows the thread to detach the active vio so it does not point
  3421. to freed memory.
  3422. Other calls to THD::clear_active_vio throughout this module are
  3423. redundant due to the hook but are left in place for illustrative
  3424. purposes.
  3425. */
  3426. extern "C" void slave_io_thread_detach_vio()
  3427. {
  3428. #ifdef SIGNAL_WITH_VIO_CLOSE
  3429. THD *thd= current_thd;
  3430. if (thd && thd->slave_thread)
  3431. thd->clear_active_vio();
  3432. #endif
  3433. }
  3434. /*
  3435. Try to connect until successful or slave killed
  3436. SYNPOSIS
  3437. safe_connect()
  3438. thd Thread handler for slave
  3439. mysql MySQL connection handle
  3440. mi Replication handle
  3441. RETURN
  3442. 0 ok
  3443. # Error
  3444. */
  3445. static int safe_connect(THD* thd, MYSQL* mysql, Master_info* mi)
  3446. {
  3447. DBUG_ENTER("safe_connect");
  3448. DBUG_RETURN(connect_to_master(thd, mysql, mi, 0, 0));
  3449. }
  3450. /*
  3451. SYNPOSIS
  3452. connect_to_master()
  3453. IMPLEMENTATION
  3454. Try to connect until successful or slave killed or we have retried
  3455. master_retry_count times
  3456. */
  3457. static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi,
  3458. bool reconnect, bool suppress_warnings)
  3459. {
  3460. int slave_was_killed;
  3461. int last_errno= -2; // impossible error
  3462. ulong err_count=0;
  3463. char llbuff[22];
  3464. DBUG_ENTER("connect_to_master");
  3465. #ifndef DBUG_OFF
  3466. mi->events_till_disconnect = disconnect_slave_event_count;
  3467. #endif
  3468. ulong client_flag= CLIENT_REMEMBER_OPTIONS;
  3469. if (opt_slave_compressed_protocol)
  3470. client_flag=CLIENT_COMPRESS; /* We will use compression */
  3471. mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *) &slave_net_timeout);
  3472. mysql_options(mysql, MYSQL_OPT_READ_TIMEOUT, (char *) &slave_net_timeout);
  3473. #ifdef HAVE_OPENSSL
  3474. if (mi->ssl)
  3475. {
  3476. mysql_ssl_set(mysql,
  3477. mi->ssl_key[0]?mi->ssl_key:0,
  3478. mi->ssl_cert[0]?mi->ssl_cert:0,
  3479. mi->ssl_ca[0]?mi->ssl_ca:0,
  3480. mi->ssl_capath[0]?mi->ssl_capath:0,
  3481. mi->ssl_cipher[0]?mi->ssl_cipher:0);
  3482. mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
  3483. &mi->ssl_verify_server_cert);
  3484. }
  3485. #endif
  3486. mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset_info->csname);
  3487. /* This one is not strictly needed but we have it here for completeness */
  3488. mysql_options(mysql, MYSQL_SET_CHARSET_DIR, (char *) charsets_dir);
  3489. while (!(slave_was_killed = io_slave_killed(thd,mi)) &&
  3490. (reconnect ? mysql_reconnect(mysql) != 0 :
  3491. mysql_real_connect(mysql, mi->host, mi->user, mi->password, 0,
  3492. mi->port, 0, client_flag) == 0))
  3493. {
  3494. /* Don't repeat last error */
  3495. if ((int)mysql_errno(mysql) != last_errno)
  3496. {
  3497. last_errno=mysql_errno(mysql);
  3498. suppress_warnings= 0;
  3499. mi->report(ERROR_LEVEL, last_errno,
  3500. "error %s to master '%s@%s:%d'"
  3501. " - retry-time: %d retries: %lu",
  3502. (reconnect ? "reconnecting" : "connecting"),
  3503. mi->user, mi->host, mi->port,
  3504. mi->connect_retry, master_retry_count);
  3505. }
  3506. /*
  3507. By default we try forever. The reason is that failure will trigger
  3508. master election, so if the user did not set master_retry_count we
  3509. do not want to have election triggered on the first failure to
  3510. connect
  3511. */
  3512. if (++err_count == master_retry_count)
  3513. {
  3514. slave_was_killed=1;
  3515. if (reconnect)
  3516. change_rpl_status(RPL_ACTIVE_SLAVE,RPL_LOST_SOLDIER);
  3517. break;
  3518. }
  3519. safe_sleep(thd,mi->connect_retry,(CHECK_KILLED_FUNC)io_slave_killed,
  3520. (void*)mi);
  3521. }
  3522. if (!slave_was_killed)
  3523. {
  3524. mi->clear_error(); // clear possible left over reconnect error
  3525. if (reconnect)
  3526. {
  3527. if (!suppress_warnings && global_system_variables.log_warnings)
  3528. sql_print_information("Slave: connected to master '%s@%s:%d',\
  3529. replication resumed in log '%s' at position %s", mi->user,
  3530. mi->host, mi->port,
  3531. IO_RPL_LOG_NAME,
  3532. llstr(mi->master_log_pos,llbuff));
  3533. }
  3534. else
  3535. {
  3536. change_rpl_status(RPL_IDLE_SLAVE,RPL_ACTIVE_SLAVE);
  3537. general_log_print(thd, COM_CONNECT_OUT, "%s@%s:%d",
  3538. mi->user, mi->host, mi->port);
  3539. }
  3540. #ifdef SIGNAL_WITH_VIO_CLOSE
  3541. thd->set_active_vio(mysql->net.vio);
  3542. #endif
  3543. }
  3544. mysql->reconnect= 1;
  3545. DBUG_PRINT("exit",("slave_was_killed: %d", slave_was_killed));
  3546. DBUG_RETURN(slave_was_killed);
  3547. }
  3548. /*
  3549. safe_reconnect()
  3550. IMPLEMENTATION
  3551. Try to connect until successful or slave killed or we have retried
  3552. master_retry_count times
  3553. */
  3554. static int safe_reconnect(THD* thd, MYSQL* mysql, Master_info* mi,
  3555. bool suppress_warnings)
  3556. {
  3557. DBUG_ENTER("safe_reconnect");
  3558. DBUG_RETURN(connect_to_master(thd, mysql, mi, 1, suppress_warnings));
  3559. }
  3560. /*
  3561. Store the file and position where the execute-slave thread are in the
  3562. relay log.
  3563. SYNOPSIS
  3564. flush_relay_log_info()
  3565. rli Relay log information
  3566. NOTES
  3567. - As this is only called by the slave thread, we don't need to
  3568. have a lock on this.
  3569. - If there is an active transaction, then we don't update the position
  3570. in the relay log. This is to ensure that we re-execute statements
  3571. if we die in the middle of an transaction that was rolled back.
  3572. - As a transaction never spans binary logs, we don't have to handle the
  3573. case where we do a relay-log-rotation in the middle of the transaction.
  3574. If this would not be the case, we would have to ensure that we
  3575. don't delete the relay log file where the transaction started when
  3576. we switch to a new relay log file.
  3577. TODO
  3578. - Change the log file information to a binary format to avoid calling
  3579. longlong2str.
  3580. RETURN VALUES
  3581. 0 ok
  3582. 1 write error
  3583. */
  3584. bool flush_relay_log_info(Relay_log_info* rli)
  3585. {
  3586. bool error=0;
  3587. DBUG_ENTER("flush_relay_log_info");
  3588. if (unlikely(rli->no_storage))
  3589. DBUG_RETURN(0);
  3590. IO_CACHE *file = &rli->info_file;
  3591. char buff[FN_REFLEN*2+22*2+4], *pos;
  3592. my_b_seek(file, 0L);
  3593. pos=strmov(buff, rli->group_relay_log_name);
  3594. *pos++='\n';
  3595. pos=longlong2str(rli->group_relay_log_pos, pos, 10);
  3596. *pos++='\n';
  3597. pos=strmov(pos, rli->group_master_log_name);
  3598. *pos++='\n';
  3599. pos=longlong2str(rli->group_master_log_pos, pos, 10);
  3600. *pos='\n';
  3601. if (my_b_write(file, (uchar*) buff, (size_t) (pos-buff)+1))
  3602. error=1;
  3603. if (flush_io_cache(file))
  3604. error=1;
  3605. /* Flushing the relay log is done by the slave I/O thread */
  3606. DBUG_RETURN(error);
  3607. }
  3608. /*
  3609. Called when we notice that the current "hot" log got rotated under our feet.
  3610. */
  3611. static IO_CACHE *reopen_relay_log(Relay_log_info *rli, const char **errmsg)
  3612. {
  3613. DBUG_ENTER("reopen_relay_log");
  3614. DBUG_ASSERT(rli->cur_log != &rli->cache_buf);
  3615. DBUG_ASSERT(rli->cur_log_fd == -1);
  3616. IO_CACHE *cur_log = rli->cur_log=&rli->cache_buf;
  3617. if ((rli->cur_log_fd=open_binlog(cur_log,rli->event_relay_log_name,
  3618. errmsg)) <0)
  3619. DBUG_RETURN(0);
  3620. /*
  3621. We want to start exactly where we was before:
  3622. relay_log_pos Current log pos
  3623. pending Number of bytes already processed from the event
  3624. */
  3625. rli->event_relay_log_pos= max(rli->event_relay_log_pos, BIN_LOG_HEADER_SIZE);
  3626. my_b_seek(cur_log,rli->event_relay_log_pos);
  3627. DBUG_RETURN(cur_log);
  3628. }
  3629. /**
  3630. Reads next event from the relay log. Should be called from the
  3631. slave IO thread.
  3632. @param rli Relay_log_info structure for the slave IO thread.
  3633. @return The event read, or NULL on error. If an error occurs, the
  3634. error is reported through the sql_print_information() or
  3635. sql_print_error() functions.
  3636. */
  3637. static Log_event* next_event(Relay_log_info* rli)
  3638. {
  3639. Log_event* ev;
  3640. IO_CACHE* cur_log = rli->cur_log;
  3641. pthread_mutex_t *log_lock = rli->relay_log.get_log_lock();
  3642. const char* errmsg=0;
  3643. THD* thd = rli->sql_thd;
  3644. DBUG_ENTER("next_event");
  3645. DBUG_ASSERT(thd != 0);
  3646. #ifndef DBUG_OFF
  3647. if (abort_slave_event_count && !rli->events_till_abort--)
  3648. DBUG_RETURN(0);
  3649. #endif
  3650. /*
  3651. For most operations we need to protect rli members with data_lock,
  3652. so we assume calling function acquired this mutex for us and we will
  3653. hold it for the most of the loop below However, we will release it
  3654. whenever it is worth the hassle, and in the cases when we go into a
  3655. pthread_cond_wait() with the non-data_lock mutex
  3656. */
  3657. safe_mutex_assert_owner(&rli->data_lock);
  3658. while (!sql_slave_killed(thd,rli))
  3659. {
  3660. /*
  3661. We can have two kinds of log reading:
  3662. hot_log:
  3663. rli->cur_log points at the IO_CACHE of relay_log, which
  3664. is actively being updated by the I/O thread. We need to be careful
  3665. in this case and make sure that we are not looking at a stale log that
  3666. has already been rotated. If it has been, we reopen the log.
  3667. The other case is much simpler:
  3668. We just have a read only log that nobody else will be updating.
  3669. */
  3670. bool hot_log;
  3671. if ((hot_log = (cur_log != &rli->cache_buf)))
  3672. {
  3673. DBUG_ASSERT(rli->cur_log_fd == -1); // foreign descriptor
  3674. pthread_mutex_lock(log_lock);
  3675. /*
  3676. Reading xxx_file_id is safe because the log will only
  3677. be rotated when we hold relay_log.LOCK_log
  3678. */
  3679. if (rli->relay_log.get_open_count() != rli->cur_log_old_open_count)
  3680. {
  3681. // The master has switched to a new log file; Reopen the old log file
  3682. cur_log=reopen_relay_log(rli, &errmsg);
  3683. pthread_mutex_unlock(log_lock);
  3684. if (!cur_log) // No more log files
  3685. goto err;
  3686. hot_log=0; // Using old binary log
  3687. }
  3688. }
  3689. /*
  3690. As there is no guarantee that the relay is open (for example, an I/O
  3691. error during a write by the slave I/O thread may have closed it), we
  3692. have to test it.
  3693. */
  3694. if (!my_b_inited(cur_log))
  3695. goto err;
  3696. #ifndef DBUG_OFF
  3697. {
  3698. /* This is an assertion which sometimes fails, let's try to track it */
  3699. char llbuf1[22], llbuf2[22];
  3700. DBUG_PRINT("info", ("my_b_tell(cur_log)=%s rli->event_relay_log_pos=%s",
  3701. llstr(my_b_tell(cur_log),llbuf1),
  3702. llstr(rli->event_relay_log_pos,llbuf2)));
  3703. DBUG_ASSERT(my_b_tell(cur_log) >= BIN_LOG_HEADER_SIZE);
  3704. DBUG_ASSERT(my_b_tell(cur_log) == rli->event_relay_log_pos);
  3705. }
  3706. #endif
  3707. /*
  3708. Relay log is always in new format - if the master is 3.23, the
  3709. I/O thread will convert the format for us.
  3710. A problem: the description event may be in a previous relay log. So if
  3711. the slave has been shutdown meanwhile, we would have to look in old relay
  3712. logs, which may even have been deleted. So we need to write this
  3713. description event at the beginning of the relay log.
  3714. When the relay log is created when the I/O thread starts, easy: the
  3715. master will send the description event and we will queue it.
  3716. But if the relay log is created by new_file(): then the solution is:
  3717. MYSQL_BIN_LOG::open() will write the buffered description event.
  3718. */
  3719. if ((ev=Log_event::read_log_event(cur_log,0,
  3720. rli->relay_log.description_event_for_exec)))
  3721. {
  3722. DBUG_ASSERT(thd==rli->sql_thd);
  3723. /*
  3724. read it while we have a lock, to avoid a mutex lock in
  3725. inc_event_relay_log_pos()
  3726. */
  3727. rli->future_event_relay_log_pos= my_b_tell(cur_log);
  3728. if (hot_log)
  3729. pthread_mutex_unlock(log_lock);
  3730. DBUG_RETURN(ev);
  3731. }
  3732. DBUG_ASSERT(thd==rli->sql_thd);
  3733. if (opt_reckless_slave) // For mysql-test
  3734. cur_log->error = 0;
  3735. if (cur_log->error < 0)
  3736. {
  3737. errmsg = "slave SQL thread aborted because of I/O error";
  3738. if (hot_log)
  3739. pthread_mutex_unlock(log_lock);
  3740. goto err;
  3741. }
  3742. if (!cur_log->error) /* EOF */
  3743. {
  3744. /*
  3745. On a hot log, EOF means that there are no more updates to
  3746. process and we must block until I/O thread adds some and
  3747. signals us to continue
  3748. */
  3749. if (hot_log)
  3750. {
  3751. /*
  3752. We say in Seconds_Behind_Master that we have "caught up". Note that
  3753. for example if network link is broken but I/O slave thread hasn't
  3754. noticed it (slave_net_timeout not elapsed), then we'll say "caught
  3755. up" whereas we're not really caught up. Fixing that would require
  3756. internally cutting timeout in smaller pieces in network read, no
  3757. thanks. Another example: SQL has caught up on I/O, now I/O has read
  3758. a new event and is queuing it; the false "0" will exist until SQL
  3759. finishes executing the new event; it will be look abnormal only if
  3760. the events have old timestamps (then you get "many", 0, "many").
  3761. Transient phases like this can be fixed with implemeting
  3762. Heartbeat event which provides the slave the status of the
  3763. master at time the master does not have any new update to send.
  3764. Seconds_Behind_Master would be zero only when master has no
  3765. more updates in binlog for slave. The heartbeat can be sent
  3766. in a (small) fraction of slave_net_timeout. Until it's done
  3767. rli->last_master_timestamp is temporarely (for time of
  3768. waiting for the following event) reset whenever EOF is
  3769. reached.
  3770. */
  3771. time_t save_timestamp= rli->last_master_timestamp;
  3772. rli->last_master_timestamp= 0;
  3773. DBUG_ASSERT(rli->relay_log.get_open_count() ==
  3774. rli->cur_log_old_open_count);
  3775. if (rli->ign_master_log_name_end[0])
  3776. {
  3777. /* We generate and return a Rotate, to make our positions advance */
  3778. DBUG_PRINT("info",("seeing an ignored end segment"));
  3779. ev= new Rotate_log_event(rli->ign_master_log_name_end,
  3780. 0, rli->ign_master_log_pos_end,
  3781. Rotate_log_event::DUP_NAME);
  3782. rli->ign_master_log_name_end[0]= 0;
  3783. pthread_mutex_unlock(log_lock);
  3784. if (unlikely(!ev))
  3785. {
  3786. errmsg= "Slave SQL thread failed to create a Rotate event "
  3787. "(out of memory?), SHOW SLAVE STATUS may be inaccurate";
  3788. goto err;
  3789. }
  3790. ev->server_id= 0; // don't be ignored by slave SQL thread
  3791. DBUG_RETURN(ev);
  3792. }
  3793. /*
  3794. We can, and should release data_lock while we are waiting for
  3795. update. If we do not, show slave status will block
  3796. */
  3797. pthread_mutex_unlock(&rli->data_lock);
  3798. /*
  3799. Possible deadlock :
  3800. - the I/O thread has reached log_space_limit
  3801. - the SQL thread has read all relay logs, but cannot purge for some
  3802. reason:
  3803. * it has already purged all logs except the current one
  3804. * there are other logs than the current one but they're involved in
  3805. a transaction that finishes in the current one (or is not finished)
  3806. Solution :
  3807. Wake up the possibly waiting I/O thread, and set a boolean asking
  3808. the I/O thread to temporarily ignore the log_space_limit
  3809. constraint, because we do not want the I/O thread to block because of
  3810. space (it's ok if it blocks for any other reason (e.g. because the
  3811. master does not send anything). Then the I/O thread stops waiting
  3812. and reads more events.
  3813. The SQL thread decides when the I/O thread should take log_space_limit
  3814. into account again : ignore_log_space_limit is reset to 0
  3815. in purge_first_log (when the SQL thread purges the just-read relay
  3816. log), and also when the SQL thread starts. We should also reset
  3817. ignore_log_space_limit to 0 when the user does RESET SLAVE, but in
  3818. fact, no need as RESET SLAVE requires that the slave
  3819. be stopped, and the SQL thread sets ignore_log_space_limit to 0 when
  3820. it stops.
  3821. */
  3822. pthread_mutex_lock(&rli->log_space_lock);
  3823. // prevent the I/O thread from blocking next times
  3824. rli->ignore_log_space_limit= 1;
  3825. /*
  3826. If the I/O thread is blocked, unblock it. Ok to broadcast
  3827. after unlock, because the mutex is only destroyed in
  3828. ~Relay_log_info(), i.e. when rli is destroyed, and rli will
  3829. not be destroyed before we exit the present function.
  3830. */
  3831. pthread_mutex_unlock(&rli->log_space_lock);
  3832. pthread_cond_broadcast(&rli->log_space_cond);
  3833. // Note that wait_for_update unlocks lock_log !
  3834. rli->relay_log.wait_for_update(rli->sql_thd, 1);
  3835. // re-acquire data lock since we released it earlier
  3836. pthread_mutex_lock(&rli->data_lock);
  3837. rli->last_master_timestamp= save_timestamp;
  3838. continue;
  3839. }
  3840. /*
  3841. If the log was not hot, we need to move to the next log in
  3842. sequence. The next log could be hot or cold, we deal with both
  3843. cases separately after doing some common initialization
  3844. */
  3845. end_io_cache(cur_log);
  3846. DBUG_ASSERT(rli->cur_log_fd >= 0);
  3847. my_close(rli->cur_log_fd, MYF(MY_WME));
  3848. rli->cur_log_fd = -1;
  3849. if (relay_log_purge)
  3850. {
  3851. /*
  3852. purge_first_log will properly set up relay log coordinates in rli.
  3853. If the group's coordinates are equal to the event's coordinates
  3854. (i.e. the relay log was not rotated in the middle of a group),
  3855. we can purge this relay log too.
  3856. We do ulonglong and string comparisons, this may be slow but
  3857. - purging the last relay log is nice (it can save 1GB of disk), so we
  3858. like to detect the case where we can do it, and given this,
  3859. - I see no better detection method
  3860. - purge_first_log is not called that often
  3861. */
  3862. if (rli->relay_log.purge_first_log
  3863. (rli,
  3864. rli->group_relay_log_pos == rli->event_relay_log_pos
  3865. && !strcmp(rli->group_relay_log_name,rli->event_relay_log_name)))
  3866. {
  3867. errmsg = "Error purging processed logs";
  3868. goto err;
  3869. }
  3870. }
  3871. else
  3872. {
  3873. /*
  3874. If hot_log is set, then we already have a lock on
  3875. LOCK_log. If not, we have to get the lock.
  3876. According to Sasha, the only time this code will ever be executed
  3877. is if we are recovering from a bug.
  3878. */
  3879. if (rli->relay_log.find_next_log(&rli->linfo, !hot_log))
  3880. {
  3881. errmsg = "error switching to the next log";
  3882. goto err;
  3883. }
  3884. rli->event_relay_log_pos = BIN_LOG_HEADER_SIZE;
  3885. strmake(rli->event_relay_log_name,rli->linfo.log_file_name,
  3886. sizeof(rli->event_relay_log_name)-1);
  3887. flush_relay_log_info(rli);
  3888. }
  3889. /*
  3890. Now we want to open this next log. To know if it's a hot log (the one
  3891. being written by the I/O thread now) or a cold log, we can use
  3892. is_active(); if it is hot, we use the I/O cache; if it's cold we open
  3893. the file normally. But if is_active() reports that the log is hot, this
  3894. may change between the test and the consequence of the test. So we may
  3895. open the I/O cache whereas the log is now cold, which is nonsense.
  3896. To guard against this, we need to have LOCK_log.
  3897. */
  3898. DBUG_PRINT("info",("hot_log: %d",hot_log));
  3899. if (!hot_log) /* if hot_log, we already have this mutex */
  3900. pthread_mutex_lock(log_lock);
  3901. if (rli->relay_log.is_active(rli->linfo.log_file_name))
  3902. {
  3903. #ifdef EXTRA_DEBUG
  3904. if (global_system_variables.log_warnings)
  3905. sql_print_information("next log '%s' is currently active",
  3906. rli->linfo.log_file_name);
  3907. #endif
  3908. rli->cur_log= cur_log= rli->relay_log.get_log_file();
  3909. rli->cur_log_old_open_count= rli->relay_log.get_open_count();
  3910. DBUG_ASSERT(rli->cur_log_fd == -1);
  3911. /*
  3912. When the SQL thread is [stopped and] (re)started the
  3913. following may happen:
  3914. 1. Log was hot at stop time and remains hot at restart
  3915. SQL thread reads again from hot_log (SQL thread was
  3916. reading from the active log when it was stopped and the
  3917. very same log is still active on SQL thread restart).
  3918. In this case, my_b_seek is performed on cur_log, while
  3919. cur_log points to relay_log.get_log_file();
  3920. 2. Log was hot at stop time but got cold before restart
  3921. The log was hot when SQL thread stopped, but it is not
  3922. anymore when the SQL thread restarts.
  3923. In this case, the SQL thread reopens the log, using
  3924. cache_buf, ie, cur_log points to &cache_buf, and thence
  3925. its coordinates are reset.
  3926. 3. Log was already cold at stop time
  3927. The log was not hot when the SQL thread stopped, and, of
  3928. course, it will not be hot when it restarts.
  3929. In this case, the SQL thread opens the cold log again,
  3930. using cache_buf, ie, cur_log points to &cache_buf, and
  3931. thence its coordinates are reset.
  3932. 4. Log was hot at stop time, DBA changes to previous cold
  3933. log and restarts SQL thread
  3934. The log was hot when the SQL thread was stopped, but the
  3935. user changed the coordinates of the SQL thread to
  3936. restart from a previous cold log.
  3937. In this case, at start time, cur_log points to a cold
  3938. log, opened using &cache_buf as cache, and coordinates
  3939. are reset. However, as it moves on to the next logs, it
  3940. will eventually reach the hot log. If the hot log is the
  3941. same at the time the SQL thread was stopped, then
  3942. coordinates were not reset - the cur_log will point to
  3943. relay_log.get_log_file(), and not a freshly opened
  3944. IO_CACHE through cache_buf. For this reason we need to
  3945. deploy a my_b_seek before calling check_binlog_magic at
  3946. this point of the code (see: BUG#55263 for more
  3947. details).
  3948. NOTES:
  3949. - We must keep the LOCK_log to read the 4 first bytes, as
  3950. this is a hot log (same as when we call read_log_event()
  3951. above: for a hot log we take the mutex).
  3952. - Because of scenario #4 above, we need to have a
  3953. my_b_seek here. Otherwise, we might hit the assertion
  3954. inside check_binlog_magic.
  3955. */
  3956. my_b_seek(cur_log, (my_off_t) 0);
  3957. if (check_binlog_magic(cur_log,&errmsg))
  3958. {
  3959. if (!hot_log) pthread_mutex_unlock(log_lock);
  3960. goto err;
  3961. }
  3962. if (!hot_log) pthread_mutex_unlock(log_lock);
  3963. continue;
  3964. }
  3965. if (!hot_log) pthread_mutex_unlock(log_lock);
  3966. /*
  3967. if we get here, the log was not hot, so we will have to open it
  3968. ourselves. We are sure that the log is still not hot now (a log can get
  3969. from hot to cold, but not from cold to hot). No need for LOCK_log.
  3970. */
  3971. #ifdef EXTRA_DEBUG
  3972. if (global_system_variables.log_warnings)
  3973. sql_print_information("next log '%s' is not active",
  3974. rli->linfo.log_file_name);
  3975. #endif
  3976. // open_binlog() will check the magic header
  3977. if ((rli->cur_log_fd=open_binlog(cur_log,rli->linfo.log_file_name,
  3978. &errmsg)) <0)
  3979. goto err;
  3980. }
  3981. else
  3982. {
  3983. /*
  3984. Read failed with a non-EOF error.
  3985. TODO: come up with something better to handle this error
  3986. */
  3987. if (hot_log)
  3988. pthread_mutex_unlock(log_lock);
  3989. sql_print_error("Slave SQL thread: I/O error reading \
  3990. event(errno: %d cur_log->error: %d)",
  3991. my_errno,cur_log->error);
  3992. // set read position to the beginning of the event
  3993. my_b_seek(cur_log,rli->event_relay_log_pos);
  3994. /* otherwise, we have had a partial read */
  3995. errmsg = "Aborting slave SQL thread because of partial event read";
  3996. break; // To end of function
  3997. }
  3998. }
  3999. if (!errmsg && global_system_variables.log_warnings)
  4000. {
  4001. sql_print_information("Error reading relay log event: %s",
  4002. "slave SQL thread was killed");
  4003. DBUG_RETURN(0);
  4004. }
  4005. err:
  4006. if (errmsg)
  4007. sql_print_error("Error reading relay log event: %s", errmsg);
  4008. DBUG_RETURN(0);
  4009. }
  4010. /*
  4011. Rotate a relay log (this is used only by FLUSH LOGS; the automatic rotation
  4012. because of size is simpler because when we do it we already have all relevant
  4013. locks; here we don't, so this function is mainly taking locks).
  4014. Returns nothing as we cannot catch any error (MYSQL_BIN_LOG::new_file()
  4015. is void).
  4016. */
  4017. int rotate_relay_log(Master_info* mi)
  4018. {
  4019. DBUG_ENTER("rotate_relay_log");
  4020. Relay_log_info* rli= &mi->rli;
  4021. int error= 0;
  4022. /*
  4023. We need to test inited because otherwise, new_file() will attempt to lock
  4024. LOCK_log, which may not be inited (if we're not a slave).
  4025. */
  4026. if (!rli->inited)
  4027. {
  4028. DBUG_PRINT("info", ("rli->inited == 0"));
  4029. goto end;
  4030. }
  4031. /* If the relay log is closed, new_file() will do nothing. */
  4032. if ((error= rli->relay_log.new_file()))
  4033. goto end;
  4034. /*
  4035. We harvest now, because otherwise BIN_LOG_HEADER_SIZE will not immediately
  4036. be counted, so imagine a succession of FLUSH LOGS and assume the slave
  4037. threads are started:
  4038. relay_log_space decreases by the size of the deleted relay log, but does
  4039. not increase, so flush-after-flush we may become negative, which is wrong.
  4040. Even if this will be corrected as soon as a query is replicated on the
  4041. slave (because the I/O thread will then call harvest_bytes_written() which
  4042. will harvest all these BIN_LOG_HEADER_SIZE we forgot), it may give strange
  4043. output in SHOW SLAVE STATUS meanwhile. So we harvest now.
  4044. If the log is closed, then this will just harvest the last writes, probably
  4045. 0 as they probably have been harvested.
  4046. */
  4047. rli->relay_log.harvest_bytes_written(&rli->log_space_total);
  4048. end:
  4049. DBUG_RETURN(error);
  4050. }
  4051. /**
  4052. Detects, based on master's version (as found in the relay log), if master
  4053. has a certain bug.
  4054. @param rli Relay_log_info which tells the master's version
  4055. @param bug_id Number of the bug as found in bugs.mysql.com
  4056. @param report bool report error message, default TRUE
  4057. @param pred Predicate function that will be called with @c param to
  4058. check for the bug. If the function return @c true, the bug is present,
  4059. otherwise, it is not.
  4060. @param param State passed to @c pred function.
  4061. @return TRUE if master has the bug, FALSE if it does not.
  4062. */
  4063. bool rpl_master_has_bug(const Relay_log_info *rli, uint bug_id, bool report,
  4064. bool (*pred)(const void *), const void *param)
  4065. {
  4066. struct st_version_range_for_one_bug {
  4067. uint bug_id;
  4068. const uchar introduced_in[3]; // first version with bug
  4069. const uchar fixed_in[3]; // first version with fix
  4070. };
  4071. static struct st_version_range_for_one_bug versions_for_all_bugs[]=
  4072. {
  4073. {24432, { 5, 0, 24 }, { 5, 0, 38 } },
  4074. {24432, { 5, 1, 12 }, { 5, 1, 17 } },
  4075. {33029, { 5, 0, 0 }, { 5, 0, 58 } },
  4076. {33029, { 5, 1, 0 }, { 5, 1, 12 } },
  4077. {37426, { 5, 1, 0 }, { 5, 1, 26 } },
  4078. };
  4079. const uchar *master_ver=
  4080. rli->relay_log.description_event_for_exec->server_version_split;
  4081. DBUG_ASSERT(sizeof(rli->relay_log.description_event_for_exec->server_version_split) == 3);
  4082. for (uint i= 0;
  4083. i < sizeof(versions_for_all_bugs)/sizeof(*versions_for_all_bugs);i++)
  4084. {
  4085. const uchar *introduced_in= versions_for_all_bugs[i].introduced_in,
  4086. *fixed_in= versions_for_all_bugs[i].fixed_in;
  4087. if ((versions_for_all_bugs[i].bug_id == bug_id) &&
  4088. (memcmp(introduced_in, master_ver, 3) <= 0) &&
  4089. (memcmp(fixed_in, master_ver, 3) > 0) &&
  4090. (pred == NULL || (*pred)(param)))
  4091. {
  4092. if (!report)
  4093. return TRUE;
  4094. // a short message for SHOW SLAVE STATUS (message length constraints)
  4095. my_printf_error(ER_UNKNOWN_ERROR, "master may suffer from"
  4096. " http://bugs.mysql.com/bug.php?id=%u"
  4097. " so slave stops; check error log on slave"
  4098. " for more info", MYF(0), bug_id);
  4099. // a verbose message for the error log
  4100. rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR,
  4101. "According to the master's version ('%s'),"
  4102. " it is probable that master suffers from this bug:"
  4103. " http://bugs.mysql.com/bug.php?id=%u"
  4104. " and thus replicating the current binary log event"
  4105. " may make the slave's data become different from the"
  4106. " master's data."
  4107. " To take no risk, slave refuses to replicate"
  4108. " this event and stops."
  4109. " We recommend that all updates be stopped on the"
  4110. " master and slave, that the data of both be"
  4111. " manually synchronized,"
  4112. " that master's binary logs be deleted,"
  4113. " that master be upgraded to a version at least"
  4114. " equal to '%d.%d.%d'. Then replication can be"
  4115. " restarted.",
  4116. rli->relay_log.description_event_for_exec->server_version,
  4117. bug_id,
  4118. fixed_in[0], fixed_in[1], fixed_in[2]);
  4119. return TRUE;
  4120. }
  4121. }
  4122. return FALSE;
  4123. }
  4124. /**
  4125. BUG#33029, For all 5.0 up to 5.0.58 exclusive, and 5.1 up to 5.1.12
  4126. exclusive, if one statement in a SP generated AUTO_INCREMENT value
  4127. by the top statement, all statements after it would be considered
  4128. generated AUTO_INCREMENT value by the top statement, and a
  4129. erroneous INSERT_ID value might be associated with these statement,
  4130. which could cause duplicate entry error and stop the slave.
  4131. Detect buggy master to work around.
  4132. */
  4133. bool rpl_master_erroneous_autoinc(THD *thd)
  4134. {
  4135. if (active_mi && active_mi->rli.sql_thd == thd)
  4136. {
  4137. Relay_log_info *rli= &active_mi->rli;
  4138. DBUG_EXECUTE_IF("simulate_bug33029", return TRUE;);
  4139. return rpl_master_has_bug(rli, 33029, FALSE, NULL, NULL);
  4140. }
  4141. return FALSE;
  4142. }
  4143. #ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
  4144. template class I_List_iterator<i_string>;
  4145. template class I_List_iterator<i_string_pair>;
  4146. #endif
  4147. /**
  4148. @} (end of group Replication)
  4149. */
  4150. #endif /* HAVE_REPLICATION */