MySQL Internals Binary Log
← Back to MySQL Internals overview page
[edit] The Binary Log
This chapter describes the MySQL binary log, which contains information about data modifications made to a MySQL server instance.
Most of the information here applies equally to the relay log used on replication slave servers because a relay log has the same format as a binary log.
[edit] Binary Log Overview
[Some information information in this section is derived from The Binary Log, in the MySQL Reference Manual.]
The binary log is a set of log files that contain information about data modifications made to a MySQL server instance. The log is enabled by starting the server with the --log-bin option.
The binary log was introduced in MySQL 3.23.14. It contains all statements that update data. It also contains statements that potentially could have updated it (for example, a DELETE which matched no rows), unless row-based logging is used. Statements are stored in the form of "events" that describe the modifications. The binary log also contains information about how long each statement took that updated data.
The binary log also contains some other metadata, including:
- Information about the state of the server that is needed to reproduce statements correctly
- Error codes
- Metadata needed for the maintenance of the binary llog itself (for example, rotate events)
The binary log is a trace of changes of the server's global state generated during its operation. The events that it contains describe changes of this state. More precisely, binary log events describe actions that can be used to reproduce the same changes of global state which have happened on server.
The binary log has two important purposes:
- For replication, the binary log is used on master replication servers as a record of the statements to be sent to slave servers. Many details of binary log format and handling are specific to this purpose. The master server sends the events contained in its binary log to its slaves, which execute those events to make the same data changes that were made on the master. A slave stores events received from the master in its relay log until they can be executed. The relay log has the same format as the binary log.
- Certain data recovery operations require use of the binary log. After a backup file has been restored, the events in the binary log that were recorded after the backup was made are re-executed. These events bring databases up to date from the point of the backup.
There are two types of binary logging:
- Statement-based logging: Events contain SQL statements that produce data changes (inserts, updates, deletes)
- Row-based logging: Events describe changes to individual rows
Mixed logging uses statement-based logging by default but switches to row-based logging automatically as necessary.
Row-based (and mixed) logging is available beginning with MySQL 5.1.
For more details about row-based logging, see #Row-Based Binary Logging.
The mysqlbinlog utility can be used to print binary or relay log contents in readable form.
[edit] High-Level Binary Log Structure and Contents
The binary log is a set of files that contain information about data modifications made to a MySQL server instance.
- The log consists of a set of binary log files, plus an index file.
- Each log file contains a 4-byte magic number, followed by a set of events that describe data modifications:
- The magic number bytes are 0xfe 0x62 0x69 0x6e = 0xfe 'b' 'i' 'n' (this is the
BINLOG_MAGICconstant inlog_event.h). - Each event contains header bytes followed by data bytes:
- The header bytes provide information about the type of event, when it was generated, by which server, and so forth.
- The data bytes provide information specific to the type of event, such as a particular data modification.
- The first event is a descriptor event that describes the format version of the file (the format used to write events in the file).
- The remaining events are interpreted according to the version.
- The final event is a log-rotation event that specifies the next binary log filename.
- The magic number bytes are 0xfe 0x62 0x69 0x6e = 0xfe 'b' 'i' 'n' (this is the
- The index file is a text file that lists the current binary log files.
The details about event structure have changed over time, which gives rise to different versions of the binary log format. Currently, there are three binary log format versions, described in #Binary Log Versions.
The log files are sequentially numbered using a .NNNNNN suffix. The index file has a suffix of .index. All files share a common basename. The default binary log file-naming basename is "HOSTNAME-bin". With the default basename, the binary log has files with names like this:
... HOSTNAME-bin.0000101 HOSTNAME-bin.0000102 HOSTNAME-bin.0000103 ... HOSTNAME-bin.index
Relay log file naming is similar to that of the binary log files. The default relay log file-naming basename is "HOSTNAME-relay". With the default basename, the relay log has files with names like this:
... HOSTNAME-relay.0000101 HOSTNAME-relay.0000102 HOSTNAME-relay.0000103 ... HOSTNAME-relay.index
[edit] Source Files Related to the Binary Log
This section describes the files in a MySQL source tree that are most relevent to binary log processing.
sql directory:
-
log.h/log.cc: The high-level binary logging mechanism for organizing events into a sequence so that it becomes a binary log. Routines for creating, writing, deleting binary log files.
-
log_event.h/log_event.cc: The low-level binary logging mechanism for serializing of values into records. The Log_event class and subclasses, for creating, writing, reading, printing, and applying events of every event type. Reading and writing here is at a low level, that is, serializing values into records.
-
rpl_constants.h: Contains codes forINCIDENT_EVENTincident types.
-
slave.cc: Contains some logic for processing binary logs in a replication slave (the IO and SQL threads).
-
rpl_injector.h/rpl_injector.cc: Contains the injector class that allows external insertions into the binary log. This is used for cluster replication binary logging.
-
rpl_record.h/rpl_record.cc: Utilities for encoding and decoding table rows into and out of the format used by row events.
-
rpl_tblmap.h/rpl_tblmap.cc: Contains a mapping from numbers to tables. The mapping is used by the row logging system to identify tables.
-
rpl_utility.h/rpl_utility.cc: Contains auxiliary classes and functions used forTable_map_events, and also an auxiliary class for smart pointers
-
sql_binlog.cc: Code to executeBINLOGstatements (the base64-encoded values thatmysqlbinlogprints when it sees row events).
-
sql_base.cc: The functiondecide_logging_format()that determines whether statements should be written to the binary log using row-based or statement-based format.
client directory:
-
mysqlbinlog.cc: The source for the mysqlbinlog utility that reads binary log files and displays them in text format. It shares some event-interpretation code with the server.
[edit] Source File Archaeological Notes
log_event_old.h/log_event_old.cc (present in MySQL 5.1.18 and up): Classes to read and execute old versions of the row log events:
-
Write_rows_log_event_old -
Update_rows_log_event_old -
Delete_rows_log_event_old
Prior to MySQL 5.1.17, those classes were known as:
-
Write_rows_log_event -
Update_rows_log_event -
Delete_rows_log_event
For information about the relationship of the Xxx_rows_log_event and Xxx_row_log_event_old classes, see #Event Classes and Types.
[edit] Generating Browsable Binary Log Information
Source files in the sql directory of a MySQL source tree or source distribution contain comments that can be processed with doxygen to generate HTML files that describe classes, files, and so forth. Those files can be viewed in your Web browser.
To generate the HTML files and view information about the classes related to binary logging, do this:
- In your MySQL source tree, change location to the sql directory:
- shell> cd sql
- Run doxygen to generate the HTML files. These commands create a subdirectory named html containing the HTML output:
- shell> doxygen -g
- shell> doxygen
- To view the top-level index page, load the
html/index.htmlfile into your browser. - To view the classes for binary logging, load the
html/class_log__event.htmlpage. TheLog_eventclass is the main event class, and the others inherit fromLog_event.
The pages also contain links that take you to other related pages.
For example, to navigate from index.html to class_log__event.html,
click on the Classes tab. On the next page, scroll down to Log_event
and click on it.
[edit] Event Classes and Types
Internally, the server uses C++ classes to represent binary log events. Prototypes are in log_event.h. Code for methods of these classes is in log_event.cc.
Log_event is the base class. Other more specific event subclasses
are derived from it. Type codes are associated with subclasses
because class instance contents are written to binary or relay
logs or are sent over the network from master to slave. In those
contexts, an event is just a sequence of bytes, not a class structure,
so a type code is needed to allow recognition of the event type
from the byte sequence.
An event byte sequence has a header part and a data part. The type code appears in the header part of each event.
The possible type codes for events are listed in the Log_event_type enumeration:
enum Log_event_type
{
UNKNOWN_EVENT= 0, START_EVENT_V3= 1, QUERY_EVENT= 2, STOP_EVENT= 3,
ROTATE_EVENT= 4, INTVAR_EVENT= 5, LOAD_EVENT= 6, SLAVE_EVENT= 7,
CREATE_FILE_EVENT= 8, APPEND_BLOCK_EVENT= 9, EXEC_LOAD_EVENT= 10,
DELETE_FILE_EVENT= 11, NEW_LOAD_EVENT= 12, RAND_EVENT= 13,
USER_VAR_EVENT= 14, FORMAT_DESCRIPTION_EVENT= 15, XID_EVENT= 16,
BEGIN_LOAD_QUERY_EVENT= 17, EXECUTE_LOAD_QUERY_EVENT= 18,
TABLE_MAP_EVENT = 19, PRE_GA_WRITE_ROWS_EVENT = 20,
PRE_GA_UPDATE_ROWS_EVENT = 21, PRE_GA_DELETE_ROWS_EVENT = 22,
WRITE_ROWS_EVENT = 23, UPDATE_ROWS_EVENT = 24,
DELETE_ROWS_EVENT = 25, INCIDENT_EVENT= 26,
HEARTBEAT_LOG_EVENT= 27,
ENUM_END_EVENT /* end marker */
};
The INTVAR_EVENT type has "subtypes," listed in the Int_event_type enumeration:
enum Int_event_type
{
INVALID_INT_EVENT = LAST_INSERT_ID_EVENT = INSERT_ID_EVENT = 2
};
The following table summarizes the relationship between event classes and type codes. Each class is derived from Log_event unless otherwise indicated. As can be seen, an event class is associated with a single type code in most cases, although there are some exceptions:
- Some classes are not associated with any type code because they are used only as a base class for which to derive subclasses or because they are never written to binary or relay logs or sent from master to slave. For example,
Log_eventhas no type code because it is used only as a base class. - A class may be associated with multiple type codes:
Load_log_eventmay contain a type code of eitherLOAD_EVENTorNEW_LOAD_EVENT.
| Value | Type Code | Class |
|---|---|---|
Log_event
| ||
Muted_query_log_event
| ||
Rows_log_event
| ||
Old_rows_log_event
| ||
| 0 | UNKNOWN_EVENT
| Unknown_log_event
|
| 1 | START_EVENT_V3
| Start_log_event_v3
|
| 2 | QUERY_EVENT
| Query_log_event
|
| 3 | STOP_EVENT
| Stop_log_event
|
| 4 | ROTATE_EVENT
| Rotate_log_event
|
| 5 | INTVAR_EVENT
| Intvar_log_event
|
| 6 | LOAD_EVENT
| Load_log_event
|
| 7 | SLAVE_EVENT
| Slave_log_event
|
| 8 | CREATE_FILE_EVENT
| Create_file_log_event
|
| 9 | APPEND_BLOCK_EVENT
| Append_block_log_event
|
| 10 | EXEC_LOAD_EVENT
| Execute_load_log_event
|
| 11 | DELETE_FILE_EVENT
| Delete_file_log_event
|
| 12 | NEW_LOAD_EVENT
| Load_log_event
|
| 13 | RAND_EVENT
| Rand_log_event
|
| 14 | USER_VAR_EVENT
| User_var_log_event
|
| 15 | FORMAT_DESCRIPTION_EVENT
| Format_description_log_event
|
| 16 | XID_EVENT
| Xid_log_event
|
| 17 | BEGIN_LOAD_QUERY_EVENT
| Begin_load_query_log_event
|
| 18 | EXECUTE_LOAD_QUERY_EVENT
| Execute_load_query_log_event
|
| 19 | TABLE_MAP_EVENT
| Table_map_log_event
|
| 20 | PRE_GA_WRITE_ROWS_EVENT
| Write_rows_log_event_old
|
| 21 | PRE_GA_UPDATE_ROWS_EVENT
| Update_rows_log_event_old
|
| 22 | PRE_GA_DELETE_ROWS_EVENT
| Delete_rows_log_event_old
|
| 23 | WRITE_ROWS_EVENT
| Write_rows_log_event
|
| 24 | UPDATE_ROWS_EVENT
| Update_rows_log_event
|
| 25 | DELETE_ROWS_EVENT
| Delete_rows_log_event
|
| 26 | INCIDENT_EVENT
| Incident_log_event
|
| 27 | HEARTBEAT_LOG_EVENT
| Heartbeat_log_event
|
[edit] Event Class Archaeological Notes
Despite the "V3" in the type code name,
START_EVENT_V3 currently is used as the type code not only for v3 start events, but also for v1 start events. The original symbol for type code 1 was START_EVENT in the format now known as v1. Later, when v3 was developed, type code 1 was reused and the symbol associated with it was renamed from START_EVENT to START_EVENT_V3. The start events for both v1 and v3 therefore have a type code of 1, although the event structures differ and must be distinguished by examining their contents.
Up to MySQL 5.1.17, event type codes from 20 to 22 were associated with symbols and classes as follows:
| Value | Type Code | Class |
|---|---|---|
| 20 | WRITE_ROWS_EVENT
| Write_rows_log_event
|
| 21 | UPDATE_ROWS_EVENT
| Update_rows_log_event
|
| 22 | DELETE_ROWS_EVENT
| Delete_rows_log_event
|
In 5.1.18, the symbols and classes were renamed:
| Value | Type Code | Class |
|---|---|---|
| 20 | PRE_GA_WRITE_ROWS_EVENT
| Write_rows_log_event_old
|
| 21 | PRE_GA_UPDATE_ROWS_EVENT
| Update_rows_log_event_old
|
| 22 | PRE_GA_DELETE_ROWS_EVENT
| Delete_rows_log_event_old
|
Also in 5.1.18, the original symbols were reused with different values and new implementations of the classes that used the original names:
| Value | Type Code | Class |
|---|---|---|
| 23 | WRITE_ROWS_EVENT
| Write_rows_log_event
|
| 24 | UPDATE_ROWS_EVENT
| Update_rows_log_event
|
| 25 | DELETE_ROWS_EVENT
| Delete_rows_log_event
|
Events with type codes 20 to 22 are obsolete now and appear only in binary logs created by servers from MySQL 5.1.5 to 5.1.17.
[edit] Event Meanings
The following descriptions briefly summarize the meaning of each event type:
-
UNKNOWN_EVENT
This event type should never occur. It is never written to a binary log. If an event is read from a binary log that cannot be recognized as something else, it is treated asUNKNOWN_EVENT. -
START_EVENT_V3
A descriptor event that is written to the beginning of the each binary log file. (In MySQL 4.0 and 4.1, this event is written only to the first binary log file that the server creates after startup.) This event is used in MySQL 3.23 through 4.1 and superseded in MySQL 5.0 byFORMAT_DESCRIPTION_EVENT. -
QUERY_EVENT
Written when an updating statement is done. -
STOP_EVENT
Written whenmysqldstops. -
ROTATE_EVENT
Written whenmysqldswitches to a new binary log file. This occurs when someone issues aFLUSH LOGSstatement or the current binary log file becomes too large. The maximum size is determined by max_binlog_size. -
INTVAR_EVENT
Written every time a statement uses anAUTO_INCREMENTcolumn or theLAST_INSERT_ID()function; precedes other events for the statement. This is written only before aQUERY_EVENTand is not used with row-based logging. AnINTVAR_EVENTis written with a "subtype" in the event data part:-
INSERT_ID_EVENTindicates the value to use for anAUTO_INCREMENTcolumn in the next statement. -
LAST_INSERT_ID_EVENTindicates the value to use for theLAST_INSERT_ID()function in the next statement.
-
-
LOAD_EVENT
Used forLOAD DATA INFILEstatements in MySQL 3.23. See #LOAD DATA INFILE Events. -
SLAVE_EVENT
Not used. -
CREATE_FILE_EVENT
Used forLOAD DATA INFILEstatements in MySQL 4.0 and 4.1. See #LOAD DATA INFILE Events. -
APPEND_BLOCK_EVENT
Used forLOAD DATA INFILEstatements as of MySQL 4.0. See #LOAD DATA INFILE Events. -
EXEC_LOAD_EVENT
Used forLOAD DATA INFILEstatements in 4.0 and 4.1. See #LOAD DATA INFILE Events. -
DELETE_FILE_EVENT
Used forLOAD DATA INFILEstatements as of MySQL 4.0. See #LOAD DATA INFILE Events. -
NEW_LOAD_EVENT
Used forLOAD DATA INFILEstatements in MySQL 4.0 and 4.1. See #LOAD DATA INFILE Events. -
RAND_EVENT
Written every time a statement uses theRAND()function; precedes other events for the statement. Indicates the seed values to use for generating a random number withRAND()in the next statement. This is written only before aQUERY_EVENTand is not used with row-based logging. -
USER_VAR_EVENT
Written every time a statement uses a user variable; precedes other events for the statement. Indicates the value to use for the user variable in the next statement. This is written only before aQUERY_EVENTand is not used with row-based logging. -
FORMAT_DESCRIPTION_EVENT
A descriptor event that is written to the beginning of the each binary log file. This event is used as of MySQL 5.0; it supersedesSTART_EVENT_V3. -
XID_EVENT
Generated for a commit of a transaction that modifies one or more tables of an XA-capable storage engine. Normal transactions are implemented by sending aQUERY_EVENTcontaining aBEGINstatement and aQUERY_EVENTcontaining aCOMMITstatement (or aROLLBACKstatement if the transaction is rolled back). -
BEGIN_LOAD_QUERY_EVENT
Used forLOAD DATA INFILEstatements as of MySQL 5.0. See #LOAD DATA INFILE Events. -
EXECUTE_LOAD_QUERY_EVENT
Used forLOAD DATA INFILEstatements as of MySQL 5.0. See #LOAD DATA INFILE Events. -
TABLE_MAP_EVENT
Used for row-based binary logging. This event precedes each row operation event. It maps a table definition to a number, where the table definition consists of database and table names and column definitions. The purpose of this event is to enable replication when a table has different definitions on the master and slave. Row operation events that belong to the same transaction may be grouped into sequences, in which case each such sequence of events begins with a sequence ofTABLE_MAP_EVENTevents: one per table used by events in the sequence. -
PRE_GA_WRITE_ROWS_EVENT
Obsolete version ofWRITE_ROWS_EVENT. -
PRE_GA_UPDATE_ROWS_EVENT
Obsolete version ofUPDATE_ROWS_EVENT. -
PRE_GA_DELETE_ROWS_EVENT
Obsolete version ofDELETE_ROWS_EVENT. -
WRITE_ROWS_EVENT
Used for row-based binary logging. This event logs inserts of rows in a single table. -
UPDATE_ROWS_EVENT
Used for row-based binary logging. This event logs updates of rows in a single table. -
DELETE_ROWS_EVENT
Used for row-based binary logging. This event logs deletions of rows in a single table. -
INCIDENT_EVENT
Used to log an out of the ordinary event that occurred on the master. It notifies the slave that something happened on the master that might cause data to be in an inconsistent state. -
HEARTBEAT_LOG_EVENT
Sent by a master to a slave to let the slave know that the master is still alive. Not written to log files.
[edit] Event Structure
This section describes the general properties of events as byte sequences as they are written to binary or relay log files.
All events have a common general structure consisting of an event header followed by event data:
+===================+ | event header | +===================+ | event data | +===================+
The details about what goes in the header and data parts have changed over time, which gives rise to different versions of the binary log format:
- v1: Used in MySQL 3.23
- v3: Used in MySQL 4.0.2 though 4.1
- v4: Used in MySQL 5.0 and up
A v2 format was used briefly (in early MySQL 4.0.x versions), but it is obsolete and no longer supported.
Some details of event structure are invariant across binary log versions; others depend on the version. Within any given version, different types of events vary in the structure of the data part.
The first event in a log file is special. It is a descriptor event that provides information such as the binary log version and the server version. The information in the descriptor event enables programs to determine which version of the binary log format applies to the file so that the remaining events in the file can be properly read and interpreted.
For details about the initial descriptor event and how to use it to determine the format of a binary log file, see #Binary Log Versions. For additional information about other types of events, see #Event Data for Specific Event Types.
The following event diagrams contain field descriptions written using these conventions:
- A field line has a name describing the contents of the field.
- The name is followed by two numbers in offset : length format, where offset is the 0-based offset (position) of the field within the event and length is the length of the field. Both values are given in bytes.
The overall structure for events in the different binary versions is shown here. The following sections describe the header and data parts in more detail.
v1 event structure:
+=====================================+ | event | timestamp 0 : 4 | | header +----------------------------+ | | type_code 4 : 1 | | +----------------------------+ | | server_id 5 : 4 | | +----------------------------+ | | event_length 9 : 4 | +=====================================+ | event | fixed part 13 : y | | data +----------------------------+ | | variable part | +=====================================+
header length = 13 bytes
data length = (event_length - 13) bytes
y is specific to the event type.
v3 event structure:
+=====================================+ | event | timestamp 0 : 4 | | header +----------------------------+ | | type_code 4 : 1 | | +----------------------------+ | | server_id 5 : 4 | | +----------------------------+ | | event_length 9 : 4 | | +----------------------------+ | | next_position 13 : 4 | | +----------------------------+ | | flags 17 : 2 | +=====================================+ | event | fixed part 19 : y | | data +----------------------------+ | | variable part | +=====================================+
header length = 19 bytes
data length = (event_length - 19) bytes
y is specific to the event type.
v4 event structure:
+=====================================+ | event | timestamp 0 : 4 | | header +----------------------------+ | | type_code 4 : 1 | | +----------------------------+ | | server_id 5 : 4 | | +----------------------------+ | | event_length 9 : 4 | | +----------------------------+ | | next_position 13 : 4 | | +----------------------------+ | | flags 17 : 2 | | +----------------------------+ | | extra_headers 19 : x-19 | +=====================================+ | event | fixed part x : y | | data +----------------------------+ | | variable part | +=====================================+
header length = x bytes
data length = (event_length - x) bytes
fixed data length = y bytes
variable data length = (event_length - (x + y)) bytes
x is given by the header_length field in the format description event (FDE). Currently, x is 19, so the extra_headers field is empty.
y is specific to the event type, and is given by the FDE. The fixed-part length is the same for all events of a given type, but may vary for different event types.
The fixed part of the event data is sometimes referred to as the "post-header" part. The variable part is sometimes referred to as the "payload" or "body."
For information about how to use the FDE to interpret v4 events, see #Binary Log Formats.
[edit] Event Content-Writing Conventions
Event contents are written using these conventions:
- Numbers are written in little-endian format (least significant byte first), unless otherwise indicated.
- Values that represent positions or lengths are given in bytes and should be considered unsigned.
- Some numbers are written as Packed Integers. The format is described later in this section.
- Strings are written in varying formats:
- A string may be written to a fixed-length field and null-padded (with 0x00 bytes) on the right.
- A variable-length string may be preceded by a length field that indicates the length of the string.
- Some variable-length strings are null-terminated; others are not. The descriptions for individual string fields indicates which is the case.
- For null-terminated strings that are preceded by a length field, the length does not include the terminating null byte, unless otherwise indicated.
- If there is a variable-length string at the end of an event and no length field precedes it, its length may be determined as the event length minus the length of the other fields in the event.
Some events use Packed Integers, a special format for efficient representation of unsigned integers. A Packed Integer has the capacity of storing up to 8-byte integers, while small integers still can use 1, 3, or 4 bytes. The value of the first byte determines how to read the number, according to the following table.
| First byte | Format |
|---|---|
| 0-250 | The first byte is the number (in the range 0-250). No additional bytes are used. |
| 252 | Two more bytes are used. The number is in the range 251-0xffff. |
| 253 | Three more bytes are used. The number is in the range 0xffff-0xffffff. |
| 254 | Eight more bytes are used. The number is in the range 0xffffff-0xffffffffffffffff. |
Packed Integer format derives from the "Length Coded Binary" representation used in the MySQL client/server network protocol (see MySQL Client/Server Protocol). That representation allows a first byte value of 251 to represent the SQL NULL value, but 251 is apparently unused for Packed Integers in the binary log.
[edit] Event Header Fields
Each event starts with a header of size LOG_EVENT_HEADER_LEN. The value of this constant is 13 in MySQL 3.23 (v1 format), and 19 in MySQL 4.0 and up (v3 format and up). The value is larger as of 4.0 because next position and flags fields were added to the header format then:
- v1: 13 bytes: timestamp + type code + server ID + event length
- v3: 19 bytes: v1 fields + next position + flags
- v4: 19 bytes or more: v3 fields + possibly other information
The header for any version is a superset of the header for all earlier versions:
- The first 13 bytes for v3 and v4 are the same as those for v1.
- The first 19 bytes for v4 are the same as those for v3.
Because the event header in a newer binary log format starts with the header of the old formats, headers in different formats are backward compatible.
v1 event header:
+============================+ | timestamp 0 : 4 | +----------------------------+ | type_code 4 : 1 | +----------------------------+ | server_id 5 : 4 | +----------------------------+ | event_length 9 : 4 | +============================+
The 13 bytes of the v1 header are also present in the header of all subsequent binary log versions.
v3 event header:
+============================+ | timestamp 0 : 4 | +----------------------------+ | type_code 4 : 1 | +----------------------------+ | server_id 5 : 4 | +----------------------------+ | event_length 9 : 4 | +----------------------------+ | next_position 13 : 4 | +----------------------------+ | flags 17 : 2 | +============================+
Compared to v1, the header in v3 and up contains two additional fields, for a total of 19 bytes.
v4 event header:
+============================+ | timestamp 0 : 4 | +----------------------------+ | type_code 4 : 1 | +----------------------------+ | server_id 5 : 4 | +----------------------------+ | event_length 9 : 4 | +----------------------------+ | next_position 13 : 4 | +----------------------------+ | flags 17 : 2 | +----------------------------+ | extra_headers 19 : x-19 | +============================+
The v4 format includes an extra_headers field; this is a mechanism for adding extra fields to the header without
breaking the format. This extension mechanism is implemented via the format description event that appears as the first event in the file. (See #Binary Log Versions for details.) Currently, x = 19, so the extra_headers field is empty; thus, the v4 header is the same as the v3 header.
Note: The extra_headers field does not appear in the FORMAT_DESCRIPTION_EVENT or ROTATE_EVENT header.
The offsets of several fields within the event header are available as constants in log_event.h:
-
EVENT_TYPE_OFFSET= 4 -
SERVER_ID_OFFSET= 5 -
EVENT_LEN_OFFSET= 9 -
LOG_POS_OFFSET= 13 -
FLAGS_OFFSET= 17
The header fields contain the following information:
- timestamp
4 bytes. This is the time at which the statement began executing. It is represented as the number of seconds since 1970 (UTC), like the TIMESTAMP SQL data type.
- type_code
1 byte. The type of event. 1 means START_EVENT_V3, 2 means QUERY_EVENT, and so forth. These numbers are defined in the enum Log_event_type enumeration in log_event.h. (See #Event Classes and Types.)
- server_id
4 bytes. The ID of the mysqld server that originally created the event. It comes from the server-id option that is set in the server configuration file for the purpose of replication. The server ID enables endless loops to be avoided when circular replication is used (with option --log-slave-updates on). Suppose that M1, M2, and M3 have server ID values of 1, 2, and 3, and that they are replicating in circular fashion: M1 is the master for M2, M2 is the master for M3, and M3 is that master for M1. The master/server relationships look like this:
M1---->M2 ^ | | | +--M3<-+
A client sends an INSERT statement to M1. This is executed on M1 and written to its binary log with an event server ID of 1. The event is sent to M2, which executes it and writes it to its binary log; the event is still written with server ID 1 because that is the ID of the server that originally created the event. The event is sent to M3, which executes it and writes it to its binary log, still with server ID 1. Finally, the event is sent to M1, which sees server ID = 1 and understands this event originated from itself and therefore must be ignored.
- event_length
4 bytes. The total size of this event. This includes both the header and data parts. Most events are less than 1000 bytes, except when using LOAD DATA INFILE (where events contain the loaded file, so they can be big).
- next_position (not present in v1 format)
4 bytes. The position of the next event in the master's binary log, as returned by tell(). In a binary log, this is just the position of the next event in the file. In a relay log, this is the position of the next event in the master's binlog. In other words, it is the position in the binary log where the next event was originally created. The value is copied as-is to the relay log. It is used on the slave, for SHOW SLAVE STATUS to be able to show coordinates of the last executed event in the master's coordinate system. If this value were not stored in the event, we could not know these coordinates because the slave cannot invoke tell() for the master's binary log.
In a binary log file, an identity should hold for every event: The position of the event in the file plus the value in the event length field should equal the value in the next position field. In a relay log file, this will not generally be true because events need not be written at the same position as in the original binary log file.
- flags (not present in v1 format)
2 bytes. The possible flag values are described at #Event Flags.
- extra_headers (not present in v1, v3 formats)
Variable-sized. The size of this field is determined by the format description event that occurs as the first event in the file. Currently, the size is 0, so, in effect, this field never actually occurs in any event. At such time as the size becomes non-zero, this field still will not appear in events of type FORMAT_DESCRIPTION_EVENT or ROTATE_EVENT.
[edit] Event Flags
Event headers for v3 format and up contain event flags in the two flag bytes at position FLAGS_OFFSET = 17. There are comments about these flags in log_event.h, in addition to the remarks in this section.
Current event flags:
-
LOG_EVENT_BINLOG_IN_USE_F= 0x1 (New in 5.0.3)
Used to indicate whether a binary log file was closed properly. This flag makes sense only forFORMAT_DESCRIPTION_EVENT. It is set when the event is written to the log file. When the log file is closed later, the flag is cleared. (This is the only case when MySQL modifies an already written part of a binary log file). -
LOG_EVENT_THREAD_SPECIFIC_F= 0x4 (New in 4.1.0)
Used only bymysqlbinlog(not by the replication code at all) to be able to deal properly with temporary tables.mysqlbinlogdisplays events from the binary log in printable format, so that you can feed the output intomysql(the command-line interpreter), to achieve incremental backup recovery. But suppose that the binary log is as follows, where two simultaneous threads used temporary tables with the same name (which is allowed because temporary tables are visible only in the thread which created them):
<thread id 1> CREATE TEMPORARY TABLE t (a INT); <thread id 2> CREATE TEMPORARY TABLE t (a INT);
In this case, simply feeding this into mysql will lead to a "table t already exists" error. This is why events that use temporary tables are marked with the flag, so that mysqlbinlog knows it has to set the pseudo_thread_id system variable before, like this:
SET PSEUDO_THREAD_ID=1; CREATE TEMPORARY TABLE t (a INT); SET PSEUDO_THREAD_ID=2; CREATE TEMPORARY TABLE t (a INT);
This way there is no confusion for the server that receives these statements. Always printing SET PSEUDO_THREAD_ID, even when temporary tables are not used, would cause no bug, it would just slow down.
-
LOG_EVENT_SUPPRESS_USE_F= 0x8 (New in 4.1.7)
Suppresses generation of a USE statement before the actual statement to be logged. This flag should be set for any event that does not need to have the default database set to function correctly, such as CREATE DATABASE and DROP DATABASE. This flag should only be used in exceptional circumstances because it introduces a significant change in behavior regarding the replication logic together with the--binlog-do-dband--replicate-do-dboptions. -
LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F= 0x10 (New in 5.1.4)
Causes the table map version internal to the binary log to be increased after the event has been written to the log.
Obsolete event flags:
-
LOG_EVENT_TIME_F(obsolete as of 4.1.1). This flag was never set. -
LOG_EVENT_FORCED_ROTATE_F(obsolete as of 4.1.1). This flag was set in events of typeROTATE_EVENTon the master, but was not used for anything useful
They are now commented out in log_event.h and their values are available for reuse or have already been reused. (But see the associated comments in log_event.h for various cautions!)
[edit] Event Data Fields (Event-Specific Information)
The structure of an event's data part depends on the event type:
- In v1 and v3, the event type entirely determines the data format
- In v4, interpretation of the data part depends on the event type in conjunction with information from the format description event. This is because v4 allows for an
extra headersfield, the size of which is defined in the format description event. In practice, theextra headersfield currently is empty.
The data part of an event consists of a fixed-size part and a variable-size part. Either or both parts may be empty, depending on the event type. (For example, a STOP_EVENT consists only of the header part; the fixed and variable data parts are both empty.)
The size of the event data part is the event size (contained in the header) minus the header size. The size of the fixed data part is a function of the event type. The size of the variable data part is the event size minus the size of the header, minus the size of the fixed data part.
The following principles hold across all events in a binary log file:
- The fixed part of the event data is the same size for all events of a given type.
- The variable part of the event data can differ in size among events of a given type.
For details about the fixed and variable parts of event data for different events, see #Event Data for Specific Event Types.
[edit] Event Data Field Notational Caveat
The fixed part of the event data goes under different names, depending on which source file, work log, bug report, etc. you are reading:
- Sometimes it is called the "fixed data" part, as in this discussion.
- Sometimes it is called the "post-headers" part.
- To make things notationally interesting, sometimes the fixed data part is referred to as the "event-specific headers" part of the event. That is, the word "header" is used in reference to a portion of the data part. One manifestation of this notational phenomenon appears in
log_event.h, where you will find the symbolLOG_EVENT_MINIMAL_HEADER_LENdefined as 19 (the header length for v3 and v4), plus other symbols with names of the formXXX_HEADER_LENfor different event types. The former symbol is the size of the event header (always 19). The latter symbols define the size of the fixed portion of the data part that is to be treated as the event-specific headers. For example,ROTATE_HEADER_LENis 8 because aROTATE_EVENThas an 8-byte field in the fixed data part that indicates the position in the next log file of the first event in that file.
The variable part of event data also goes under different names, such as the event "payload" or "body."
[edit] Binary Log Versions
There are several versions of the binary log file format:
- v1: Used in MySQL 3.23
- v3: Used in MySQL 4.0.2 though 4.1
- v4: Used in MySQL 5.0 and up
A v2 format was used briefly (in early MySQL 4.0.x versions), but it is obsolete and no longer supported.
Programs that process the binary log must be able to account for each of the supported binary log formats. This section describes how the server distinguishes each format to identify which one a binary log file uses. mysqlbinlog uses the same principles.
Important constants:
-
START_EVENT_V3= 1 -
FORMAT_DESCRIPTION_EVENT= 15 -
EVENT_TYPE_OFFSET= 4 -
EVENT_LEN_OFFSET= 9 -
ST_SERVER_VER_LEN= 50
A binary log file begins with a 4-byte magic number followed by an initial descriptor event that identifies the format of the file.
- In v1 and v3, this event is called a "start event."
- In v4, it is called a "format description event."
Elsewhere you may see either term used generically to refer collectively to both types of event. This discussion uses "descriptor event" as the collective term.
The header and data parts of the descriptor event for each binary log format version are shown following. The diagrams use the same conventions as those described earlier in #Event Structure.
v1 start event (size = 69 bytes):
+=====================================+ | event | timestamp 0 : 4 | | header +----------------------------+ | | type_code 4 : 1 | = START_EVENT_V3 = 1 | +----------------------------+ | | server_id 5 : 4 | | +----------------------------+ | | event_length 9 : 4 | = 69 +=====================================+ | event | binlog_version 13 : 2 | = 1 | data +----------------------------+ | | server_version 15 : 50 | | +----------------------------+ | | create_timestamp 65 : 4 | +=====================================+
v3 start event (size = 75 bytes):
+=====================================+ | event | timestamp 0 : 4 | | header +----------------------------+ | | type_code 4 : 1 | = START_EVENT_V3 = 1 | +----------------------------+ | | server_id 5 : 4 | | +----------------------------+ | | event_length 9 : 4 | = 75 | +----------------------------+ | | next_position 13 : 4 | | +----------------------------+ | | flags 17 : 2 | +=====================================+ | event | binlog_version 19 : 2 | = 3 | data +----------------------------+ | | server_version 21 : 50 | | +----------------------------+ | | create_timestamp 71 : 4 | +=====================================+
v4 format description event (size >= 91 bytes; the size is 76 + the number of event types):
+=====================================+ | event | timestamp 0 : 4 | | header +----------------------------+ | | type_code 4 : 1 | = FORMAT_DESCRIPTION_EVENT = 15 | +----------------------------+ | | server_id 5 : 4 | | +----------------------------+ | | event_length 9 : 4 | >= 91 | +----------------------------+ | | next_position 13 : 4 | | +----------------------------+ | | flags 17 : 2 | +=====================================+ | event | binlog_version 19 : 2 | = 4 | data +----------------------------+ | | server_version 21 : 50 | | +----------------------------+ | | create_timestamp 71 : 4 | | +----------------------------+ | | header_length 75 : 1 | | +----------------------------+ | | post-header 76 : n | = array of n bytes, one byte per event | | lengths for all | type that the server knows about | | event types | +=====================================+
In all binary log versions, the event data for the descriptor event begins with a common set of fields
- binlog_version
The binary log version number (1, 3, or 4).
- server_version
The server version as a string.
- create_timestamp
The creation timestamp, if non-zero, is the time in seconds when this event was created; it indicates the moment when the binary log was created. This field is actually of no value: If non-zero, it is redundant because it has the same value that is in the header timestamp.
Note: In practice, the creation timestamp field should be considered reserved for future use and programs should not rely on its value. This field may be commandeered in the future to serve another purpose.
The v4 format descriptor event data contains two additional fields that enable interpretation of other types of events:
- header_length
The length of the event header. This value includes the extra_headers field, so this header length - 19 yields the size of the extra_headers field.
Currently in v4, the header length (at offset 75) is 19, which means that in other events, no extra headers will follow the flags field. If in the future the header length is some value x > 19, then x-19 extra header bytes will appear in other events in the extra_headers field following the flags field.
Note: The FORMAT_DESCRIPTION_EVENT itself contains no extra_headers field. Suppose that the FDE did have a header_length field after the flags field. That would introduce this problem:
- The value of x is given in the
header_lengthfield, which occurs in a position later than where theextra_headersfield would be. - Until you know the value of x, you cannot know the exact offset of the
header_lengthfield.
In other words, you would need to know x to find the header_length field, but you cannot know x until you read the header_length field. (A circular dependency.) This means that the event extensibility mechanism afforded by the FDE does not apply to the FDE itself, which therefore is not itself extensible.
- post-header lengths
The lengths for the fixed data part of each event. This is an array that provides post-header lengths for all events beginning with START_EVENT_V3 (type code 1). The array includes no length for UNKNOWN_EVENT (type code 0).
[edit] Determining the Binary Log Version
Given any binary log file, the information in this section describes how to determine the format in which it is written.
Some important points about descriptor event formats:
- The v1 header fields are common to all formats. (v3 and v4 headers begin with the v1 header fields, and add
next_positionandflagsfields.) - The v3 and v4 headers contain the same fields. The data part for v3 and v4 differs, such that the v4 data part enables extensions to the format without having to modify the header.
- It would be possible to ascertain the binary log version simply by reading the two
binlog_versionbytes, were it not for the fact that these bytes occur at a different position in v1 compared to v3/v4 (position 13 versus 19). Therefore, it's necessary to determine whether the first event in a file represents a v1-format start event.
To determine the version of a binary log file, use the following procedure:
1) The file begins with a 4-byte magic number. Skip over that to get to the first event in the file (which in most cases is a start event or format description event).
2) From the first event, read two values:
- The 1-byte type code at position
EVENT_TYPE_OFFSET(4) within the event. - The 4-byte event length at position
EVENT_LEN_OFFSET(9) within the event.
3) If the type code is not START_EVENT_V3 or FORMAT_DESCRIPTION_EVENT, the file format is v3. (See Exceptional Condition 1 later in this section.)
4) If the type code is START_EVENT_V3 (1), check the event length. If
the length is less than 75, the file format is v1, and v3 otherwise. Why the value 75? Because that is the length of a v3 start event:
- header (19 bytes)
- binlog version (2 bytes)
- server version (
ST_SERVER_VER_LEN= 50 bytes) - timestamp (4 bytes)
Summing those lengths yields 19 + 2 + 50 + 4 = 75
Therefore, if the event is shorter than 75 bytes, it must be from a v1 file because that will have a shorter first event than a v3 file.
5) If the type code is FORMAT_DESCRIPTION_EVENT (15), the file format is v4.
The preceding steps describe the general binary log format-recognition principles. However, there are some exceptional conditions that must be accounted for:
Exceptional Condition 1: In MySQL 4.0 and 4.1, the initial event in a binary log file might not be a start event. This occurs because the server writes the start event only to the first binary log file that it creates after startup. For subsequent files, the server writes an event of type ROTATE_EVENT to the end of the current log file, closes it, and the begins the next file without writing a start event to it. If a log file begins with an event that is not START_EVENT_V3 or FORMAT_DESCRIPTION_EVENT, it can be assumed to be a v3 file because this behavior occurs only in MySQL 4.0 and 4.1, and all servers in those versions use v3 format.
Exceptional Condition 2: In MySQL 5.1 and 5.2, several early versions wrote binary log files using v4 format, but using different event numbers from those currently used in v4. Therefore, when the FDE is read and discovered to be v4, it is also necessary to read the server version, which is a string that occurs at position 21. If the version is one of those in the set of affected versions, event renumbering occurs such that events read from the file are mapped onto the current v4 event numbering.
[edit] Ensuring Compatibility of Future Binary Log Versions
To enable any future binary log formats to be correctly understood, the following conventions must hold:
a) The binary log file must start with a descriptor event
b) The descriptor event must start with a v3 header (19 bytes)
c) The 2 bytes following the header (at position 19) must contain the binary log format version number
With respect to the current formats, only a) holds for v1. However,
as indicated earlier, v1-format files can be recognized from the initial event in the file, by
a type code of START_EVENT_V3 and an event length less than 75.
The v4 format description event is designed so that it can handle future format updates. A new format with the same layout of event packets as in v4 but with additional fields in the header and post-headers can use this format description event to correctly describe itself. Actually, it is (theoretically) possible to have different "flavors" of v4 format that have different (larger) header lengths and even a different number of events.
The current code is written to handle this possibility. That is, any code that parses a binary log and discovers that it is v4 uses the header lengths as given by the format description event (thus potentially different lengths from the values hard-wired in the server code).
Note: Although headers of events in v4 format can
be longer than 19 bytes, the format description event is an exception.
Its header is always 19 bytes long to meet the preceding backward
compatibility requirements. That is, the FORMAT_DESCRIPTION_EVENT does not include an extra_headers field.
[edit] Event Data for Specific Event Types
The following sections provide details about what appears in the fixed and variable parts of the event data for each event type.
LOAD DATA INFILE statements have been associated over time with several different events. The event contents are detailed in this section, and #LOAD DATA INFILE Events provides a historical perspective on which events were used when.
Start_log_event_v3/START_EVENT_V3
This event occurs at the beginning of v1 or v3 binary log files. See #Binary Log Versions for how it is used.
In MySQL 4.0 and 4.1, such events are written only to the first binary log file that mysqld creates after startup. Log files created subsequently (when someone issues a FLUSH LOGS statement or the current binary log file becomes too large) do not contain this event. In MySQL 5.0 and up, all binary log files start with a FORMAT_DESCRIPTION_EVENT.
Fixed data part:
- 2 bytes. The binary log format version. This is 1 in MySQL 3.23 and 3 in MySQL 4.0 and 4.1. (In MySQL 5.0 and up,
FORMAT_DESCRIPTION_EVENTis used instead ofSTART_EVENT_V3.) - 50 bytes. The MySQL server's version (example: 4.0.14-debug-log), padded with 0x00 bytes on the right.
- 4 bytes. Timestamp in seconds when this event was created (this is the moment when the binary log was created). This value is redundant; the same value occurs in the
timestampheader field.
Variable data part:
- Empty
Query_log_event/QUERY_EVENT
Fixed data part:
- 4 bytes. The ID of the thread that issued this statement. Needed for temporary tables. This is also useful for a DBA for knowing who did what on the master.
- 4 bytes. The time in seconds that the statement took to execute. Only useful for inspection by the DBA.
- 1 byte. The length of the name of the database which was the default database when the statement was executed. This name appears later, in the variable data part. It is necessary for statements such as
INSERT INTO t VALUES(1)that don't specify the database and rely on the default database previously selected byUSE. - 2 bytes. The error code resulting from execution of the statement on the master. Error codes are defined in
include/mysqld_error.h. 0 means no error. How come statements with a non-zero error code can exist in the binary log? This is mainly due to the use of non-transactional tables within transactions. For example, if anINSERT ... SELECTfails after inserting 1000 rows into aMyISAMtable (for example, with a duplicate-key violation), we have to write this statement to the binary log, because it truly modified theMyISAMtable. For transactional tables, there should be no event with a non-zero error code (though it can happen, for example if the connection was interrupted (Control-C)). The slave checks the error code: After executing the statement itself, it compares the error code it got with the error code in the event, and if they are different it stops replicating (unless--slave-skip-errorswas used to ignore the error). - 2 bytes (not present in v1, v3). The length of the status variable block.
Variable part:
- Zero or more status variables (not present in v1, v3). Each status variable consists of one byte code identifying the variable stored, followed by the value of the variable. The format of the value is variable-specific, as described later.
- The default database name (null-terminated).
- The SQL statement. The slave knows the size of the other fields in the variable part (the sizes are given in the fixed data part), so by subtraction it can know the size of the statement.
Each entry in the status variable block has a code and a value, where the value format is as indicated in the following list. The list provides basic information about each variable. For additional details, see log_event.h.
-
Q_FLAGS2_CODE= 0. Value is a 4-byte bit-field. This variable is written only as of MySQL 5.0. -
Q_SQL_MODE_CODE= 1. Value is an 8-byte SQL mode value. -
Q_CATALOG_CODE= 2. Value is the catalog name: a length byte followed by that many bytes, plus a terminating null byte. This variable is present only in MySQL 5.0.0 to 5.0.3. It was replaced withQ_CATALOG_NZ_CODEin MySQL 5.0.4 because the terminating null is unnecessary. -
Q_AUTO_INCREMENT= 3. Value is two 2-byte unsigned integers representing theauto_increment_incrementandauto_increment_offsetsystem variables. This variable is present only if auto_increment is greater than 1. -
Q_CHARSET_CODE= 4. Value is three 2-byte unsigned integers representing thecharacter_set_client,collation_connection, andcollation_serversystem variables. -
Q_TIME_ZONE_CODE= 5. Value is the time zone name: a length byte followed by that many bytes. This variable is present only if the time zone string is non-empty. -
Q_CATALOG_NZ_CODE= 6. Value is the catalog name: a length byte followed by that many bytes. Value is alwaysstd. This variable is present only if the catalog name is non-empty. -
Q_LC_TIME_NAMES_CODE= 7. Value is thelc_time_namesnumber. This variable is present only if the value is not 0 (that is, not en_US). -
Q_CHARSET_DATABASE_CODE= 8. Value is a 2-byte unsigned integer representing thecollation_databasesystem variable. -
Q_TABLE_MAP_FOR_UPDATE_CODE= 9. Value is 8 bytes representing the table map to be updated by a multiple-table update statement. Each bit of this variable represents a table, and is set to 1 if the corresponding table is to be updated by the statement.
Table_map_for_update is used to evaluate the filter rules specified by --replicate-do-table / --replicate-ignore-table.
Stop_log_event/STOP_EVENT
A Stop_log_event is written under these circumstances:
- A master writes the event to the binary log when it shuts down
- A slave writes the event to the relay log when it shuts down or when a
RESET SLAVEstatement is executed
Fixed data part:
- Empty
Variable data part:
- Empty
Rotate_log_event/ROTATE_EVENT
When a binary log file exceeds a size limit, a ROTATE_EVENT is written at the end of the file that points to the next file in the squence. This event is information for the slave to know the name of the next binary log it is going to receive.
ROTATE_EVENT is generated locally and written to the binary log on the master. It is written to the relay log on the slave when FLUSH LOGS occurs, and when receiving a ROTATE_EVENT from the master. In the latter case, there will be two rotate events in total originating on different servers.
There are conditions under which the terminating log-rotation event does not occur. For example, the server might crash.
Fixed data part:
- 8 bytes. The position of the first event in the next log file. Always contains the number 4 (meaning the next event starts at position 4 in the next binary log). This field is not present in v1; presumably the value is assumed to be 4.
Variable data part:
- The name of the next binary log. The filename is not null-terminated. Its length is the event size minus the size of the fixed parts.
Intvar_log_event/INTVAR_EVENT
Fixed data part:
- Empty
Variable data part:
- 1 byte. A value indicating the variable type:
LAST_INSERT_ID_EVENT= 1 orINSERT_ID_EVENT= 2. - 8 bytes. An unsigned integer indicating the value to be used for the
LAST_INSERT_ID()invocation orAUTO_INCREMENTcolumn.
Load_log_event/LOAD_EVENT
This event is used for LOAD DATA INFILE statements. See also #LOAD DATA INFILE Events.
LOAD_EVENT shares the Load_log_event class with NEW_LOAD_EVENT. The primary difference is that LOAD_EVENT allows only single-character field and line option values, whereas NEW_LOAD_EVENT allows multiple-character values. Also, LOAD_EVENT has no file ID or data block because with this event, the slave asks the master to transfer the data file at event execution time.
The format for this event is more complicated than for others, because it contains information about many LOAD DATA INFILE statement clauses.
Fixed data part:
- 4 bytes. The ID of the thread on the master that issued this
LOAD DATA INFILEstatement. Needed for temporary tables. This is also useful for a DBA for knowing who did what on the master. - 4 bytes. The time in seconds which the
LOAD DATA INFILEtook for execution. Only useful for inspection by the DBA. - 4 bytes. The number of lines to skip at the beginning of the file (corresponds to the
IGNORE N LINESclause ofLOAD DATA INFILE). - 1 byte. The length of the name of the table to load.
- 1 byte. The length of the name of the database containing the table.
- 4 bytes. The number of columns to load (
(col_name,...)clause). Will be non-zero only if the columns to load were explicitly mentioned in the statement.
Variable data part:
- 1 byte. The field-terminating character (
FIELDS TERMINATED BYoption). - 1 byte. The field-enclosing character (
FIELDS ENCLOSED BYoption). - 1 byte. The line-terminating character (
LINES TERMINATED BYoption). - 1 byte. The line-starting character (
LINES STARTING BYoption). - 1 byte. The escaping character (
FIELDS ESCAPED BYoption). - 1 byte. Flags that indicate whether certain keywords are present in the statement:
-
DUMPFILE_FLAG=0x1 (unused; this flag appears to be a botch because it would apply toSELECT ... INTO OUTFILE, notLOAD DATA INFILE) -
OPT_ENCLOSED_FLAG= 0x2 (FIELD OPTIONALLY ENCLOSED BYoption) -
REPLACE_FLAG= 0x4 (LOAD DATA INFILE REPLACE) -
IGNORE_FLAG= 0x8 (LOAD DATA INFILE IGNORE)
-
- 1 byte. Flags that indicate whether each of the field and line options are empty. The low-order five bits are 1 to indicate an empty option (has a length of 0) or 0 to indicate a non-empty option (has a length of 1).
-
FIELD_TERM_EMPTY= 0x1 -
ENCLOSED_EMPTY= 0x2 -
LINE_TERM_EMPTY= 0x4 -
LINE_START_EMPTY= 0x8 -
ESCAPED_EMPTY= 0x10
-
- 1 byte. The length of the name of the first column to load.
- ...
- 1 byte. The length of the name of the last column to load.
- Variable-sized. The name of the first column to load (null-terminated).
- ...
- Variable-sized. The name of the last column to load (null-terminated).
- Variable-sized. The name of the table to load (null-terminated).
- Variable-sized. The name of the database that contains the table (null-terminated).
- Variable-sized. The name of the file that was loaded (the original name on the master, not the name of the temporary file created on the slave). The length of the data filename is the event size minus the size of all other parts.
Note: Because this event allows only single-character field and line option values, presumably LOAD DATA INFILE statements will not replicate correctly if any such option contains multiple characters.
Slave_log_event/SLAVE_EVENT
This event is never written, so it cannot exist in a binary log file. It was meant for failsafe replication, which has never been implemented.
Create_file_log_event/CREATE_FILE_EVENT
This event is used for LOAD DATA INFILE statements. See also #LOAD DATA INFILE Events.
This event tells the slave to create a temporary file and fill it with a first data block. Later, zero or more APPEND_BLOCK_EVENT events append blocks to this temporary file. EXEC_LOAD_EVENT tells the slave to load the temporary file into the table, or DELETE_FILE_EVENT tells the slave not to do the load and to delete the temporary file. DELETE_FILE_EVENT occurs when the LOAD DATA failed on the master: On the master we start to write loaded blocks to the binary log before the end of the statement. If for some reason there is an error, we must tell the slave to abort the load.
The format for this event is more complicated than for others, because it contains information about many LOAD DATA INFILE statement clauses.
Fixed data part:
- 4 bytes. The ID of the thread on the master that issued this
LOAD DATA INFILEstatement. Needed for temporary tables. This is also useful for a DBA for knowing who did what on the master.
Variable data part:
- 4 bytes. The time in seconds which the
LOAD DATA INFILEtook for execution. Only useful for inspection by the DBA. - 4 bytes. The number of lines to skip at the beginning of the file (corresponds to the
IGNORE N LINESclause ofLOAD DATA INFILE). - 1 byte. The length of the name of the table to load.
- 1 byte. The length of the name of the database containing the table.
- 4 bytes. The number of columns to load (
(col_name,...)clause). Will be non-zero only if the columns to load were explicitly mentioned in the statement. - 4 bytes. An ID for the data file. This is necessary in case several
LOAD DATA INFILEstatements occur in parallel on the master. In that case, the binary log may contain intermixed events for the statements. The ID resolves which file the blocks in eachAPPEND_BLOCK_EVENTmust be appended, and the file that must be loaded by theEXEC_LOAD_EVENTor deleted by theDELETE_FILE_EVENT. - 1 byte. The length of the field-terminating string (
FIELDS TERMINATED BYoption). - Variable-sized. The field-terminating string.
- 1 byte. The length of the field-enclosing string (
FIELDS ENCLOSED BYoption). - Variable-sized. The field-enclosing string.
- 1 byte. The length of the line-terminating string (
LINES TERMINATED BYoption). - Variable-sized. The line-terminating string.
- 1 byte. The length of the line-starting string (
LINES STARTING BYoption). - Variable-sized. The line-starting string.
- 1 byte. The length of the escaping string (
FIELDS ESCAPED BYoption). - Variable-sized. The escaping string.
- 1 byte. Flags that indicate whether certain keywords are present in the statement:
-
DUMPFILE_FLAG=0x1 (unused; this flag appears to be a botch because it would apply toSELECT ... INTO OUTFILE, notLOAD DATA INFILE) -
OPT_ENCLOSED_FLAG= 0x2 (FIELD OPTIONALLY ENCLOSED BYoption) -
REPLACE_FLAG= 0x4 (LOAD DATA INFILE REPLACE) -
IGNORE_FLAG= 0x8 (LOAD DATA INFILE IGNORE)
-
- 1 byte. The length of the name of the first column to load.
- ...
- 1 byte. The length of the name of the last column to load.
- Variable-sized. The name of the first column to load (null-terminated).
- ...
- Variable-sized. The name of the last column to load (null-terminated).
- Variable-sized. The name of the table to load (null-terminated).
- Variable-sized. The name of the database that contains the table (null-terminated).
- Variable-sized. The name of the file that was loaded (the original name on the master, not the name of the temporary file created on the slave) (null-terminated). The length of the data filename is not explicit in the event. However, it is null-terminated, so the length can be determined by reading to the null byte.
- Variable-sized. The block of raw data to load. If the file size exceeds a threshold, additional
APPEND_BLOCK_EVENTinstances will follow, each containing a data block. The size of the raw data is the event size minus the size of all other parts.
Append_block_log_event/APPEND_BLOCK_EVENT
This event is used for LOAD DATA INFILE statements. See also #LOAD DATA INFILE Events.
Contains data to be written to the data file for a LOAD DATA INFILE statement.
Fixed data part:
- 4 bytes. The ID of the file to append this block to.
Variable data part:
- The raw data to load. The raw data size is the event size minus the size of all the fixed event parts.
Execute_log_event/EXEC_LOAD_EVENT
This event is used for LOAD DATA INFILE statements. See also #LOAD DATA INFILE Events.
Indicates the end of a successful LOAD DATA INFILE statement and that the data file should be loaded.
Fixed data part:
- 4 bytes. The ID of the file to load.
Variable data part:
- Empty
Delete_file_log_event/DELETE_FILE_EVENT
This event is used for LOAD DATA INFILE statements. See also #LOAD DATA INFILE Events.
Indicates the end of an unsuccessful LOAD DATA INFILE statement and that the data file should not be loaded.
Fixed data part:
- 4 bytes. The ID of the file to be deleted.
Variable data part:
- Empty
Load_log_event/NEW_LOAD_EVENT
This event is used for LOAD DATA INFILE statements. See also #LOAD DATA INFILE Events.
The format for this event is more complicated than for others, because it contains information about many LOAD DATA INFILE statement clauses.
LOAD_EVENT shares the Load_log_event class with NEW_LOAD_EVENT. The primary difference is that LOAD_EVENT allows only single-character field and line option values, whereas NEW_LOAD_EVENT allows multiple-character values. Each of these is encoded as a length followed by a string rather than as a single character. Because of that, NEW_LOAD_DATA does not have the flags byte that indicates whether each option is empty.
Fixed data part:
- 4 bytes. The ID of the thread on the master that issued this
LOAD DATA INFILEstatement. Needed for temporary tables. This is also useful for a DBA for knowing who did what on the master. - 4 bytes. The time in seconds which the
LOAD DATA INFILEtook for execution. Only useful for inspection by the DBA. - 4 bytes. The number of lines to skip at the beginning of the file (corresponds to the
IGNORE N LINESclause ofLOAD DATA INFILE). - 1 byte. The length of the name of the table to load.
- 1 byte. The length of the name of the database containing the table.
- 4 bytes. The number of columns to load (
(col_name,...)clause). Will be non-zero only if the columns to load were explicitly mentioned in the statement.
Variable data part:
- 1 byte. The length of the field-terminating string (
FIELDS TERMINATED BYoption). - Variable-sized. The field-terminating string.
- 1 byte. The length of the field-enclosing string (
FIELDS ENCLOSED BYoption). - Variable-sized. The field-enclosing string.
- 1 byte. The length of the line-terminating string (
LINES TERMINATED BYoption). - Variable-sized. The line-terminating string.
- 1 byte. The length of the line-starting string (
LINES STARTING BYoption). - Variable-sized. The line-starting string.
- 1 byte. The length of the escaping string (
FIELDS ESCAPED BYoption). - Variable-sized. The escaping string.
- 1 byte. Flags that indicate whether certain keywords are present in the statement:
-
DUMPFILE_FLAG=0x1 (unused; this flag appears to be a botch because it would apply toSELECT ... INTO OUTFILE, notLOAD DATA INFILE) -
OPT_ENCLOSED_FLAG= 0x2 (FIELD OPTIONALLY ENCLOSED BYoption) -
REPLACE_FLAG= 0x4 (LOAD DATA INFILE REPLACE) -
IGNORE_FLAG= 0x8 (LOAD DATA INFILE IGNORE)
-
- 1 byte. The length of the name of the first column to load.
- ...
- 1 byte. The length of the name of the last column to load.
- Variable-sized. The name of the first column to load (null-terminated).
- ...
- Variable-sized. The name of the last column to load (null-terminated).
- Variable-sized. The name of the table to load (null-terminated).
- Variable-sized. The name of the database that contains the table (null-terminated).
- Variable-sized. The name of the file that was loaded (the original name on the master, not the name of the temporary file created on the slave). The length of the data filename is not explicit in the event. It is determined as the remaining characters to the end of the event.
There is no file ID or data block in the variable data part. The slave is supposed to request the file from the master in a separate connection.
Rand_log_event/RAND_EVENT
RAND() in MySQL generates a random number. A RAND_EVENT contains two seed values that set the rand_seed1 and rand_seed2 system variables that are used to compute the random number.
Fixed data part:
- Empty
Variable data part:
- 8 bytes. The value for the first seed.
- 8 bytes. The value for the second seed.
User_var_log_event/USER_VAR_EVENT
Fixed data part:
- Empty
Variable data part:
- 4 bytes. the size of the user variable name.
- The user variable name.
- 1 byte. Non-zero if the variable value is the SQL
NULLvalue, 0 otherwise. If this byte is 0, the following parts exist in the event. - 1 byte. The user variable type. The value corresponds to elements of
enum Item_resultdefined ininclude/mysql_com.h. - 4 bytes. The number of the character set for the user variable (needed for a string variable). The character set number is really a collation number that indicates a character set/collation pair.
- 4 bytes. The size of the user variable value (corresponds to member
val_lenof classItem_string). - Variable-sized. For a string variable, this is the string. For a float or integer variable, this is its value in 8 bytes.
Format_description_log_event/FORMAT_DESCRIPTION_EVENT
This event occurs at the beginning of v4 binary log files. See #Binary Log Versions for how it is used.
In MySQL 5.0 and up, all binary log files start with a FORMAT_DESCRIPTION_EVENT, but there will be a way to distinguish between a FORMAT_DESCRIPTION_EVENT created at mysqld startup and other FORMAT_DESCRIPTION_EVENT instances; such a distinction is needed because the first category of FORMAT_DESCRIPTION_EVENT (which means the master has started) should trigger some cleaning tasks on the slave. (Suppose the master died brutally and restarted: the slave must delete old replicated temporary tables.)
Fixed data part:
- 2 bytes. The binary log format version. This is 4 in MySQL 5.0 and up.
- 50 bytes. The MySQL server's version (example: 5.0.14-debug-log), padded with 0x00 bytes on the right.
- 4 bytes. Timestamp in seconds when this event was created (this is the moment when the binary log was created). This value is redundant; the same value occurs in the
timestampheader field. - 1 byte. The header length. This length - 19 gives the size of the
extra headersfield at the end of the header for other events. - Variable-sized. An array that indicates the post-header lengths for all event types. There is one byte per event type that the server knows about.
Variable data part:
- Empty
Xid_log_event/XID_EVENT
An XID event is generated for a commit of a transaction that modifies one or more tables of an XA-capable storage engine. Strictly speaking, Xid_log_event is used if thd->transaction.xid_state.xid.get_my_xid() returns non-zero.
Here is an example of how to generate an XID event (it occurs whether or not innodb_support_xa is enabled):
CREATE TABLE t1 (a INT) ENGINE = INNODB; START TRANSACTION; INSERT INTO t1 VALUES (1); COMMIT;
Fixed data part:
- Empty
Variable data part:
- 8 bytes. The XID transaction number.
Note: Contrary to all other numeric fields, the XID transaction number
is not always written in little-endian format. The bytes are copied unmodified
from memory to disk, so the format is machine-dependent. Hence, when
replicating from a little-endian to a big-endian machine (or vice versa), the numeric value of transaction numbers will differ. In
particular, the output of mysqlbinlog differs. This should
does not cause inconsistencies in replication because the only important
property of transaction numbers is that different transactions have
different numbers (relative order does not matter).
Begin_load_query_log_event/BEGIN_LOAD_QUERY_EVENT
This event is used for LOAD DATA INFILE statements. See also #LOAD DATA INFILE Events.
Fixed data part:
- 4 bytes. An ID for the data file. This is necessary in case several
LOAD DATA INFILEstatements occur in parallel on the master. In that case, the binary log may contain intermixed events for the statements. The ID resolves which file the blocks in eachAPPEND_BLOCK_EVENTmust be appended to, and the file that must be loaded by theEXEC_LOAD_QUERY_EVENTor deleted by theDELETE_FILE_EVENT.
Variable data part:
- Variable-sized. The first block of data to load. The size is the event size minus the size of all other fields in the event. If the file size exceeds a threshold, additional
APPEND_BLOCK_EVENTinstances will follow, each containing a data block.
Execute_load_query_log_event/EXECUTE_LOAD_QUERY_EVENT
This event is used for LOAD DATA INFILE statements. See also #LOAD DATA INFILE Events.
Indicates the end of a successful LOAD DATA INFILE statement and that the data file should be loaded. It is similar to QUERY_EVENT, but before executing the statement, it substitutes the original filename in the statement with the name of the slave-side temporary file. The first 13 bytes of the fixed data part are the same as for QUERY_EVENT, as is the initial status variable block in the variable data part. See the description of that event type for additional information.
Fixed data part:
- 4 bytes. The ID of the thread that issued this statement.
- 4 bytes. The time in seconds that the statement took to execute.
- 1 byte. The length of the name of the database which was the default database when the statement was executed.
- 2 bytes. The error code resulting from execution of the statement on the master.
- 2 bytes. The length of the status variable block.
- 4 bytes. The ID of the file to load.
- 4 bytes. The start position within the statement for filename substitution.
- 4 bytes. The end position within the statement for filename substitution.
- 1 byte. How to handle duplicates:
LOAD_DUP_ERROR= 0,LOAD_DUP_IGNORE= 1,LOAD_DUP_REPLACE= 2
Variable data part:
- Zero or more status variables. Each status variable consists of one byte identifying the variable stored, followed by the value of the variable.
- Variable-sized. The database name (null-terminated).
- The
LOAD DATA INFILEstatement. The length is the event size minus the size of all other fields.
Table_map_log_event/TABLE_MAP_EVENT
Used for row-based binary logging beginning with MySQL 5.1.5.
Fixed data part:
- 6 bytes. The table ID.
- 2 bytes. Reserved for future use.
Variable data part:
- 1 byte. The length of the database name.
- Variable-sized. The database name (null-terminated).
- 1 byte. The length of the table name.
- Variable-sized. The table name (null-terminated).
- Packed integer. The number of columns in the table.
- Variable-sized. An array of column types, one byte per column.
- Packed integer. The length of the metadata block.
- Variable-sized. The metadata block; see log_event.h for contents and format.
- Variable-sized. Bit-field indicating whether each column can be
NULL, one bit per column. For this field, the amount of storage required for N columns isINT((N+7)/8)bytes.
Write_rows_log_event_old/PRE_GA_WRITE_ROWS_EVENT
Used for row-based binary logging from MySQL 5.1.5 to 5.1.17, using the old implementation of Write_rows_log_event/WRITE_ROWS_EVENT. The structure is similar to that for the newer event.
Update_rows_log_event_old/PRE_GA_UPDATE_ROWS_EVENT
Used for row-based binary logging from MySQL 5.1.5 to 5.1.17, using the old implementation of Update_rows_log_event/UPDATE_ROWS_EVENT. The structure is similar to that for the newer event.
Delete_rows_log_event_old/PRE_GA_DELETE_ROWS_EVENT
Used for row-based binary logging from MySQL 5.1.5 to 5.1.17, using the old implementation of Delete_rows_log_event/DELETE_ROWS_EVENT. The structure is similar to that for the newer event.
Write_rows_log_event/WRITE_ROWS_EVENT
Used for row-based binary logging beginning with MySQL 5.1.18.
[TODO: following needs verification; it's guesswork]
Fixed data part:
- 6 bytes. The table ID.
- 2 bytes. Reserved for future use.
Variable data part:
- Packed integer. The number of columns in the table.
- Variable-sized. Bit-field indicating whether each column is used, one bit per column. For this field, the amount of storage required for N columns is
INT((N+7)/8)bytes. - Variable-sized (for
UPDATE_ROWS_LOG_EVENTonly). Bit-field indicating whether each column is used in theUPDATE_ROWS_LOG_EVENTafter-image; one bit per column. For this field, the amount of storage required for N columns isINT((N+7)/8)bytes. - Variable-sized. A sequence of zero or more rows. The end is determined by the size of the event. Each row has the following format:
- Variable-sized. Bit-field indicating whether each field in the row is
NULL. Only columns that are "used" according to the second field in the variable data part are listed here. If the second field in the variable data part has N one-bits, the amount of storage required for this field isINT((N+7)/8)bytes. - Variable-sized. The row-image, containing values of all table fields. This only lists table fields that are used (according to the second field of the variable data part) and non-
NULL(according to the previous field). In other words, the number of values listed here is equal to the number of zero bits in the previous field (not counting padding bits in the last byte).
The format of each value is described in thelog_event_print_value()function inlog_event.cc. - (for
UPDATE_ROWS_EVENTonly) the previous two fields are repeated, representing a second table row.
- Variable-sized. Bit-field indicating whether each field in the row is
For each row, the following is done:
- For
WRITE_ROWS_LOG_EVENT, the row described by the row-image is inserted. - For
DELETE_ROWS_LOG_EVENT, a row matching the given row-image is deleted. - For
UPDATE_ROWS_LOG_EVENT, a row matching the first row-image is removed, and the row described by the second row-image is inserted.
Update_rows_log_event/UPDATE_ROWS_EVENT
Used for row-based binary logging beginning with MySQL 5.1.18.
See the description for WRITE_ROWS_EVENT.
Delete_rows_log_event/DELETE_ROWS_EVENT
Used for row-based binary logging beginning with MySQL 5.1.18.
See the description for WRITE_ROWS_EVENT.
Incident_log_event/INCIDENT_EVENT
Fixed data part:
- 1 byte. The incident number.
- 1 byte. The message length.
Variable data part:
- The incident message, if present.
Incident number codes are listed in rpl_constant.h. The only code currently used is INCIDENT_LOST_EVENTS, which indicates that there may be lost events (a "gap") in the replication stream that requires databases to be resynchronized.
Heartbeat_log_event/HEARTBEAT_LOG_EVENT
A Heartbeat_log_event is sent by a master to a slave
to let the slave know that the master is still alive. Events of
this type do not appear in the binary or relay logs. They are
generated on a master server by the thread that dumps events and
sent straight to the slave without ever being written to the binary
log. The slave examines the event contents and then discards it without
writing it to the relay log.
Fixed data part:
- Empty
Variable data part:
- Empty
Muted_query_log_event
This is a subclass of Query_log_event that is not written to the log. It is used as a means of flushing a transaction without logging an event.
This event class was added in MySQL 5.0.23 and removed in 6.0.4. It was a solution to Bug#16206 that became unnecessary with the fix for Bug#29020.
[edit] LOAD DATA INFILE Events
LOAD DATA INFILE is not written to the binary log like other statements. It is written as one or more events in a packed format, not as a cleartext statement in the binary log. The events indicate what options are present in the statement and how to process the data file.
Historically, there seem to have been at least four event sequences for representing LOAD DATA INFILE operations.
1) In MySQL 3.23, there was only one event: Load_log_event (type code LOAD_EVENT = 6). Load_log_event only contains the filename, not the file itself. When the slave sees a Load_log_event, it requests that the master send the file in a separate connection. This has the drawback that the binary log is not self-contained: If the file has been removed on the master or the slave cannot access the master, the file transfer fails.
2) In MySQL 4.0.0, the file contents were included in the binary log. Several new event types were introduced: Create_file_log_event (type code CREATE_FILE_EVENT = 8), Append_block_log_event (type code APPEND_BLOCK_EVENT = 9), Execute_load_log_event (type code EXEC_LOAD_EVENT = 10), and Delete_file_log_event (type code DELETE_FILE_EVENT = 11). The event sequence is:
-
Create_file_log_event: 1 instance -
Append_block_log_event: 0 or more instances -
Execute_load_log_event(success) orDelete_file_log_event(failure): 1 instance
The Create_file_log_event contains the options to LOAD DATA INFILE. This was a design flaw since the file cannot be loaded until the Exec_load_log_event is seen. To work around this, the slave, when executing the Create_file_log_event, wrote the Create_file_log_event to a temporary file. When the Execute_load_log_event was seen, this temporary file was read back so that the LOAD DATA INFILE statement could be constructed.
Append_block_log_event is used for files larger than a threshold. In this case, the file is split and the pieces are sent in separate events. The threshold is around 2^17 = 131072 bytes.
CREATE_FILE_EVENT tells the slave to create a temporary file and fill it with a first data block. Later, zero or more APPEND_BLOCK_EVENT events append blocks to this temporary file. EXEC_LOAD_EVENT tells the slave to load the temporary file into the table, or DELETE_FILE_EVENT tells the slave not to do the load and to delete the temporary file. DELETE_FILE_EVENT occurs when the LOAD DATA failed on the master: On the master we start to write loaded blocks to the binary log before the end of the statement. If for some reason there is an error, we must tell the slave to abort the load.
MySQL 4.0.0 also introduced the NEW_LOAD_EVENT = 12 type code.
If a slave reads a NEW_LOAD_EVENT from a binlog, it will use it as a LOAD_EVENT (but allowing longer separator names). Lost in the mysteries of time is the knowledge of whether there was ever a server version capable of writing NEW_LOAD_EVENT.
3) The original Load_log_event used one character for each of the delimiters (FIELDS TERMINATED BY, and so forth). At an unknown point in the version history, the format was modified to allow multiple-character strings as separators. This uses the same class, Load_log_event, but has the type code NEW_LOAD_EVENT = 12. This affects Create_file_log_event, since that inherits from <code class="literal">Load_log_event. So the new feature in Load_log_event allows Create_file_log_event to use multiple-character delimiters.
[A guess for when this occurred would be MySQL 4.0.0: That is when the sql_ex structure that holds the single-character field/line options was renamed to old_sql_ex and a new sql_ex structure was created that allows multiple-character values.]
4) In 5.0.3, the event sequence was changed again with the addition of two new event types: Begin_load_query_log_event (type code BEGIN_LOAD_QUERY_EVENT = 17) and Execute_load_query_log_event (type code EXECUTE_LOAD_QUERY_EVENT = 18). The event sequence is:
-
Begin_load_query_log_event: 1 instance -
Append_block_log_event: 0 or more instances -
Execute_load_query_log_event(success) orDelete_file_log_event(failure): 1 instance
With the new sequence, information about the options to LOAD DATA INFILE is moved from the first event to the last event. Consequently, Begin_load_query_log_event is almost the same as Append_file_log_event (it contains only file data), whereas Execute_load_query_log_event contains the text of the LOAD DATA INFILE statement. The revised event sequence fixes the design flaw in the 4.0 format.
Also, the temp file that stores the parameters to LOAD DATA INFILE is not needed anymore. There is still a temp file containing all the data to be loaded.
Here is a concrete example (it applies to MySQL 4.0 and 4.1):
On the master we have a file named /m/tmp/u.txt that contains these lines:
>1,2,3 >4,5,6 >7,8,9 >10,11,12
And we issue this statement on the master while the default database is test:
load data infile '/m/tmp/u.txt' replace into table x fields terminated by ',' optionally enclosed by '"' escaped by '\\' lines starting by '>' terminated by '\n' ignore 2 lines (a,b,c);
Then in the master's binary log we have this CREATE_FILE_EVENT (hexadecimal dump):
00000180: db4f 153f 0801 0000 .........O.?.... 00000190: 006f 0000 0088 0100 0000 0004 0000 0000 .o.............. 000001a0: 0000 0002 0000 0001 0403 0000 0003 0000 ................ 000001b0: 0001 2c01 2201 0a01 3e01 5c06 0101 0161 ..,."...>.\....a 000001c0: 0062 0063 0078 0074 6573 7400 2f6d 2f74 .b.c.x.test./m/t 000001d0: 6d70 2f75 2e74 7874 003e 312c 322c 330a mp/u.txt.>1,2,3. 000001e0: 3e34 2c35 2c36 0a3e 372c 382c 390a 3e31 >4,5,6.>7,8,9.>1 000001f0: 302c 3131 2c31 32db 4f15 3f0a 0100 0000 0,11,12.O.?..... 00000200: 1700 0000 f701 0000 0000 0300 0000 ..............
- Line 180:
- Timestamp (db4f 153f)
- Event type (08)
- Server ID (01 0000 00)
- Line 190:
- Event size (6f 0000 00)
- Position in the binary log (88 0100 00) (that's 392 in decimal base)
- Flags (00 00)
- Thread ID (04 0000 00)
- Time it took (00 0000 00)
- Line 1a0:
- Number of lines to skip at the beginning of the file (02 0000 00)
- Length of the table name (01)
- Length of the database name (04)
- Number of columns to load (03 0000 00)
- The file ID (03 0000 00)
- Line 1b0:
- Length of the field terminating string (01)
- Field terminating string (2c = ,)
- Length of the field enclosing string (01)
- Field enclosing string (22 = ")
- Length of the line terminating string (01)
- Line terminating string (0a = newline)
- Length of the line starting string (01)
- Line starting string (3e = >)
- Length of the escaping string (01)
- Escaping string (5c = \)
- Flags (06) (that's
OPT_ENCLOSED_FLAG|REPLACE_FLAG) - Length of the name of the first column to load (01)
- Length of the name of the second column to load (01)
- Length of the name of the third column to load (01)
- Name of the first column to load (61 00 = "a")
- Line 1c0:
- Name of the second column to load (62 00 = "b")
- Name of the third column to load (63 00 = "c")
- Name of the table to load (78 00 = "x"), name of the database that contains the table (74 6573 7400 = "test")
- Name of the file on the master (2f6d 2f74 6d70 2f75 2e74 7874 00 = "/m/tmp/u.txt")
- Line 1d0 and following:
- Raw data to load (3e 312c 322c 330a 3e34 2c35 2c36 0a3e 372c 382c 390a 3e31 302c 3131 2c31 32)
The next byte in the file is the beginning of the EXEC_LOAD_EVENT event.
[edit] Row-Based Binary Logging
Originally, the binary log was written using statement-based logging. Row-based logging was added in MySQL 5.1.5.
- Statement-based logging: Events contain SQL statements that produce data changes (inserts, updates, deletes)
- Row-based logging: Events describe changes to individual rows
Several event types are used specific to row-based logging:
-
TABLE_MAP_EVENT -
WRITE_ROWS_EVENT -
UPDATE_ROWS_EVENT -
DELETE_ROWS_EVENT
It's common to refer to "row-based logging" (RBL) as "row-based replication" (RBR), but RBR is in fact a misnomer. Logging in this format can be done independent of whether the log is used for replication. That is, replication need not figure into the use of the binary log at all. Similar remarks apply to the terms "statement-based logging" (SBL) versus "statement-based replication" (SBR). Unfortunately, by now the RBR/SBR terminology is probably too well entrenched for there to be much hope of a return to the proper RBL/SBL terms, so I must content myself with including this nomenclatural screed here. :-)
[edit] Additional Resources
The following resources provide additional information on the structure, content, or use of the binary log.
- WL#3610: Multi-master upgrade 5.1. This worklog contains a long article on binary log file contents in the Low Level Design section.
- MySQL Internals Manual, Replication: Replication is based on the transfer of the binary log contents from master to slave.
- MySQL Reference Manual, The Binary Log
- MySQL Reference Manual, Replication Relay and Status Files
- MySQL Reference Manual, mysqlbinlog — Utility for Processing Binary Log Files