Server IP : 172.67.216.182 / Your IP : 108.162.227.119 Web Server : Apache System : Linux krdc-ubuntu-s-2vcpu-4gb-amd-blr1-01.localdomain 5.15.0-142-generic #152-Ubuntu SMP Mon May 19 10:54:31 UTC 2025 x86_64 User : www ( 1000) PHP Version : 7.4.33 Disable Function : passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /www/server/mysql/src/libbinlogevents/include/ |
Upload File : |
/* Copyright (c) 2014, 2023, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, as published by the Free Software Foundation. This program is also distributed with certain software (including but not limited to OpenSSL) that is licensed under separate terms, as designated in a particular file or component or in included license documentation. The authors of MySQL hereby grant you an additional permission to link the program and your derivative works with the separately licensed software that they have included with MySQL. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0, for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** @addtogroup Replication @{ @file rows_event.h @brief Contains the classes representing events which are used for row based replication. In row-based replication, the master writes events to the binary log that indicate how individual table rows are changed. */ #ifndef ROWS_EVENT_INCLUDED #define ROWS_EVENT_INCLUDED #include "control_events.h" #include "table_id.h" #include <vector> /** 1 byte length, 1 byte format Length is total length in bytes, including 2 byte header Length values 0 and 1 are currently invalid and reserved. */ #define EXTRA_ROW_INFO_LEN_OFFSET 0 #define EXTRA_ROW_INFO_FORMAT_OFFSET 1 #define EXTRA_ROW_INFO_HDR_BYTES 2 #define EXTRA_ROW_INFO_MAX_PAYLOAD (255 - EXTRA_ROW_INFO_HDR_BYTES) #define ROWS_MAPID_OFFSET 0 #define ROWS_FLAGS_OFFSET 6 #define ROWS_VHLEN_OFFSET 8 #define ROWS_V_TAG_LEN 1 #define ROWS_V_EXTRAINFO_TAG 0 namespace binary_log { /** @class Table_map_event In row-based mode, every row operation event is preceded by a Table_map_event which maps a table definition to a number. The table definition consists of database name, table name, and column definitions. @section Table_map_event_binary_format Binary Format The Post-Header has the following components: <table> <caption>Post-Header for Table_map_event</caption> <tr> <th>Name</th> <th>Format</th> <th>Description</th> </tr> <tr> <td>table_id</td> <td>6 bytes unsigned integer</td> <td>The number that identifies the table.</td> </tr> <tr> <td>flags</td> <td>2 byte bitfield</td> <td>Reserved for future use; currently always 0.</td> </tr> </table> The Body has the following components: <table> <caption>Body for Table_map_event</caption> <tr> <th>Name</th> <th>Format</th> <th>Description</th> </tr> <tr> <td>database_name</td> <td>one byte string length, followed by null-terminated string</td> <td>The name of the database in which the table resides. The name is represented as a one byte unsigned integer representing the number of bytes in the name, followed by length bytes containing the database name, followed by a terminating 0 byte. (Note the redundancy in the representation of the length.) </td> </tr> <tr> <td>table_name</td> <td>one byte string length, followed by null-terminated string</td> <td>The name of the table, encoded the same way as the database name above.</td> </tr> <tr> <td>column_count</td> <td>@ref packed_integer "Packed Integer"</td> <td>The number of columns in the table, represented as a packed variable-length integer.</td> </tr> <tr> <td>column_type</td> <td>List of column_count 1 byte enumeration values</td> <td>The type of each column in the table, listed from left to right. Each byte is mapped to a column type according to the enumeration type enum_field_types defined in mysql_com.h. The mapping of types to numbers is listed in the table @ref Table_table_map_event_column_types "below" (along with description of the associated metadata field). </td> </tr> <tr> <td>metadata_length</td> <td>@ref packed_integer "Packed Integer"</td> <td>The length of the following metadata block</td> </tr> <tr> <td>metadata</td> <td>list of metadata for each column</td> <td>For each column from left to right, a chunk of data who's length and semantics depends on the type of the column. The length and semantics for the metadata for each column are listed in the table @ref Table_table_map_event_column_types "below".</td> </tr> <tr> <td>null_bits</td> <td>column_count bits, rounded up to nearest byte</td> <td>For each column, a bit indicating whether data in the column can be NULL or not. The number of bytes needed for this is int((column_count + 7) / 8). The flag for the first column from the left is in the least-significant bit of the first byte, the second is in the second least significant bit of the first byte, the ninth is in the least significant bit of the second byte, and so on. </td> </tr> </table> The table below lists all column types, along with the numerical identifier for it and the size and interpretation of meta-data used to describe the type. @anchor Table_table_map_event_column_types <table> <caption>Table_map_event column types: numerical identifier and metadata</caption> <tr> <th>Name</th> <th>Identifier</th> <th>Size of metadata in bytes</th> <th>Description of metadata</th> </tr> <tr> <td>MYSQL_TYPE_DECIMAL</td><td>0</td> <td>0</td> <td>No column metadata.</td> </tr> <tr> <td>MYSQL_TYPE_TINY</td><td>1</td> <td>0</td> <td>No column metadata.</td> </tr> <tr> <td>MYSQL_TYPE_SHORT</td><td>2</td> <td>0</td> <td>No column metadata.</td> </tr> <tr> <td>MYSQL_TYPE_LONG</td><td>3</td> <td>0</td> <td>No column metadata.</td> </tr> <tr> <td>MYSQL_TYPE_FLOAT</td><td>4</td> <td>1 byte</td> <td>1 byte unsigned integer, representing the "pack_length", which is equal to sizeof(float) on the server from which the event originates.</td> </tr> <tr> <td>MYSQL_TYPE_DOUBLE</td><td>5</td> <td>1 byte</td> <td>1 byte unsigned integer, representing the "pack_length", which is equal to sizeof(double) on the server from which the event originates.</td> </tr> <tr> <td>MYSQL_TYPE_NULL</td><td>6</td> <td>0</td> <td>No column metadata.</td> </tr> <tr> <td>MYSQL_TYPE_TIMESTAMP</td><td>7</td> <td>0</td> <td>No column metadata.</td> </tr> <tr> <td>MYSQL_TYPE_LONGLONG</td><td>8</td> <td>0</td> <td>No column metadata.</td> </tr> <tr> <td>MYSQL_TYPE_INT24</td><td>9</td> <td>0</td> <td>No column metadata.</td> </tr> <tr> <td>MYSQL_TYPE_DATE</td><td>10</td> <td>0</td> <td>No column metadata.</td> </tr> <tr> <td>MYSQL_TYPE_TIME</td><td>11</td> <td>0</td> <td>No column metadata.</td> </tr> <tr> <td>MYSQL_TYPE_DATETIME</td><td>12</td> <td>0</td> <td>No column metadata.</td> </tr> <tr> <td>MYSQL_TYPE_YEAR</td><td>13</td> <td>0</td> <td>No column metadata.</td> </tr> <tr> <td><i>MYSQL_TYPE_NEWDATE</i></td><td><i>14</i></td> <td>–</td> <td><i>This enumeration value is only used internally and cannot exist in a binlog.</i></td> </tr> <tr> <td>MYSQL_TYPE_VARCHAR</td><td>15</td> <td>2 bytes</td> <td>2 byte unsigned integer representing the maximum length of the string.</td> </tr> <tr> <td>MYSQL_TYPE_BIT</td><td>16</td> <td>2 bytes</td> <td>A 1 byte unsigned int representing the length in bits of the bitfield (0 to 64), followed by a 1 byte unsigned int representing the number of bytes occupied by the bitfield. The number of bytes is either int((length + 7) / 8) or int(length / 8). </td> </tr> <tr> <td>MYSQL_TYPE_NEWDECIMAL</td><td>246</td> <td>2 bytes</td> <td>A 1 byte unsigned int representing the precision, followed by a 1 byte unsigned int representing the number of decimals.</td> </tr> <tr> <td><i>MYSQL_TYPE_ENUM</i></td><td><i>247</i></td> <td>–</td> <td><i>This enumeration value is only used internally and cannot exist in a binlog.</i></td> </tr> <tr> <td><i>MYSQL_TYPE_SET</i></td><td><i>248</i></td> <td>–</td> <td><i>This enumeration value is only used internally and cannot exist in a binlog.</i></td> </tr> <tr> <td>MYSQL_TYPE_TINY_BLOB</td><td>249</td> <td>–</td> <td><i>This enumeration value is only used internally and cannot exist in a binlog.</i></td> </tr> <tr> <td><i>MYSQL_TYPE_MEDIUM_BLOB</i></td><td><i>250</i></td> <td>–</td> <td><i>This enumeration value is only used internally and cannot exist in a binlog.</i></td> </tr> <tr> <td><i>MYSQL_TYPE_LONG_BLOB</i></td><td><i>251</i></td> <td>–</td> <td><i>This enumeration value is only used internally and cannot exist in a binlog.</i></td> </tr> <tr> <td>MYSQL_TYPE_BLOB</td><td>252</td> <td>1 byte</td> <td>The pack length, i.e., the number of bytes needed to represent the length of the blob: 1, 2, 3, or 4.</td> </tr> <tr> <td>MYSQL_TYPE_VAR_STRING</td><td>253</td> <td>2 bytes</td> <td>This is used to store both strings and enumeration values. The first byte is a enumeration value storing the <i>real type</i>, which may be either MYSQL_TYPE_VAR_STRING or MYSQL_TYPE_ENUM. The second byte is a 1 byte unsigned integer representing the field size, i.e., the number of bytes needed to store the length of the string.</td> </tr> <tr> <td>MYSQL_TYPE_STRING</td><td>254</td> <td>2 bytes</td> <td>The first byte is always MYSQL_TYPE_VAR_STRING (i.e., 253). The second byte is the field size, i.e., the number of bytes in the representation of size of the string: 3 or 4.</td> </tr> <tr> <td>MYSQL_TYPE_GEOMETRY</td><td>255</td> <td>1 byte</td> <td>The pack length, i.e., the number of bytes needed to represent the length of the geometry: 1, 2, 3, or 4.</td> </tr> </table> */ class Table_map_event: public Binary_log_event { public: /** Constants representing offsets */ enum Table_map_event_offset { /** TM = "Table Map" */ TM_MAPID_OFFSET= 0, TM_FLAGS_OFFSET= 6 }; typedef uint16_t flag_set; /** <pre> The buffer layout for fixed data part is as follows: +-----------------------------------+ | table_id | Reserved for future use| +-----------------------------------+ </pre> <pre> The buffer layout for variable data part is as follows: +---------------------------------------------------------------------------+ | db len | db name | table len| table name | no of cols | array of col types| +---------------------------------------------------------------------------+ +---------------------------------------------+ | metadata len | metadata block | m_null_bits | +---------------------------------------------+ </pre> @param buf Contains the serialized event. @param length Length of the serialized event. @param description_event An FDE event, used to get the following information -binlog_version -server_version -post_header_len -common_header_len The content of this object depends on the binlog-version currently in use. */ Table_map_event(const char *buf, unsigned int event_len, const Format_description_event *description_event); Table_map_event(const Table_id& tid, unsigned long colcnt, const char *dbnam, size_t dblen, const char *tblnam, size_t tbllen) : Binary_log_event(TABLE_MAP_EVENT), m_table_id(tid), m_data_size(0), m_dbnam(""), m_dblen(dblen), m_tblnam(""), m_tbllen(tbllen), m_colcnt(colcnt), m_field_metadata_size(0), m_field_metadata(0), m_null_bits(0) { if (dbnam) m_dbnam= std::string(dbnam, m_dblen); if (tblnam) m_tblnam= std::string(tblnam, m_tbllen); } virtual ~Table_map_event(); /** Event post header contents */ Table_id m_table_id; flag_set m_flags; size_t m_data_size; /** event data size */ /** Event body contents */ std::string m_dbnam; size_t m_dblen; std::string m_tblnam; size_t m_tbllen; unsigned long m_colcnt; unsigned char* m_coltype; /** The size of field metadata buffer set by calling save_field_metadata() */ unsigned long m_field_metadata_size; unsigned char* m_field_metadata; /** field metadata */ unsigned char* m_null_bits; Table_map_event() : Binary_log_event(TABLE_MAP_EVENT), m_coltype(0), m_field_metadata_size(0), m_field_metadata(0), m_null_bits(0) {} unsigned long long get_table_id() { return m_table_id.id(); } std::string get_table_name() { return m_tblnam; } std::string get_db_name() { return m_dbnam; } #ifndef HAVE_MYSYS void print_event_info(std::ostream& info); void print_long_info(std::ostream& info); #endif }; /** @class Rows_event Common base class for all row-containing binary log events. RESPONSIBILITIES - Provide an interface for adding an individual row to the event. @section Rows_event_binary_format Binary Format The Post-Header has the following components: <table> <caption>Post-Header for Rows_event</caption> <tr> <th>Name</th> <th>Format</th> <th>Description</th> </tr> <tr> <td>table_id</td> <td>6 bytes unsigned integer</td> <td>The number that identifies the table</td> </tr> <tr> <td>flags</td> <td>2 byte bitfield</td> <td>Reserved for future use; currently always 0.</td> </tr> </table> The Body has the following components: <table> <caption>Body for Rows_event</caption> <tr> <th>Name</th> <th>Format</th> <th>Description</th> </tr> <tr> <td>var_header_len</td> <td>packed integer</td> <td>Represents the number of columns in the table</td> </tr> <tr> <td>width</td> <td>Bitfield, variable sized</td> <td>Indicates 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. </td> </tr> <tr> <td>extra_row_data</td> <td>unsigned char pointer</td> <td>Pointer to extra row data if any. If non null, first byte is length</td> </tr> <tr> <td>columns_before_image</td> <td>vector of elements of type uint8_t</td> <td>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.</td> </tr> <tr> <td>columns_after_image</td> <td>vector of elements of type uint8_t</td> <td>variable-sized (for UPDATE_ROWS_EVENT only). Bit-field indicating whether each column is used in the UPDATE_ROWS_EVENT and WRITE_ROWS_EVENT after-image; one bit per column. For this field, the amount of storage required for N columns is INT((N + 7) / 8) bytes. @verbatim +-------------------------------------------------------+ | Event Type | Cols_before_image | Cols_after_image | +-------------------------------------------------------+ | DELETE | Deleted row | NULL | | INSERT | NULL | Inserted row | | UPDATE | Old row | Updated row | +-------------------------------------------------------+ @end verbatim </td> </tr> <tr> <td>row</td> <td>vector of elements of type uint8_t</td> <td> A sequence of zero or more rows. The end is determined by the size of the event. Each row has the following format: - A 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 is INT((N + 7) / 8) bytes. - 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). @verbatim For example, if a INSERT statement inserts into 4 columns of a table, N= 4 (in the formula above). length of bitmask= (4 + 7) / 8 = 1 Number of fields in the row= 4. +------------------------------------------------+ |Null_bit_mask(4)|field-1|field-2|field-3|field 4| +------------------------------------------------+ @endverbatim </td> </tr> */ class Rows_event: public Binary_log_event { public: /** These definitions allow to combine the flags into an appropriate flag set using the normal bitwise operators. The implicit conversion from an enum-constant to an integer is accepted by the compiler, which is then used to set the real set of flags. */ enum enum_flag { /** Last event of a statement */ STMT_END_F = (1U << 0), /** Value of the OPTION_NO_FOREIGN_KEY_CHECKS flag in thd->options */ NO_FOREIGN_KEY_CHECKS_F = (1U << 1), /** Value of the OPTION_RELAXED_UNIQUE_CHECKS flag in thd->options */ RELAXED_UNIQUE_CHECKS_F = (1U << 2), /** Indicates that rows in this event are complete, that is contain values for all columns of the table. */ COMPLETE_ROWS_F = (1U << 3) }; /** Constructs an event directly. The members are assigned default values. @param type_arg Type of ROW_EVENT. Expected types are: - WRITE_ROWS_EVENT, WRITE_ROWS_EVENT_V1, PRE_GA_WRITE_ROWS_EVENT, - UPDATE_ROWS_EVENT, UPDATE_ROWS_EVENT_V1, PRE_GA_UPDATE_ROWS_EVENT, - DELETE_ROWS_EVENT, DELETE_ROWS_EVENT_V1, PRE_GA_DELETE_ROWS_EVENT */ explicit Rows_event(Log_event_type type_arg) : Binary_log_event(type_arg), m_table_id(0), m_width(0), m_extra_row_data(0), columns_before_image(0), columns_after_image(0), row(0) {} /** The constructor is responsible for decoding the event contained in the buffer. <pre> The buffer layout for fixed data part is as follows +------------------------------------+ | table_id | reserved for future use | +------------------------------------+ </pre> <pre> The buffer layout for variable data part is as follows +------------------------------------------------------------------+ | var_header_len | column_before_image | columns_after_image | row | +------------------------------------------------------------------+ </pre> @param buf Contains the serialized event. @param length Length of the serialized event. @param description_event An FDE event, used to get the following information -binlog_version -server_version -post_header_len -common_header_len The content of this object depends on the binlog-version currently in use. */ Rows_event(const char *buf, unsigned int event_len, const Format_description_event *description_event); virtual ~Rows_event(); protected: Log_event_type m_type; /** Actual event type */ /** Post header content */ Table_id m_table_id; uint16_t m_flags; /** Flags for row-level events */ /* Body of the event */ unsigned long m_width; /** The width of the columns bitmap */ uint32_t n_bits_len; /** value determined by (m_width + 7) / 8 */ uint16_t var_header_len; unsigned char* m_extra_row_data; std::vector<uint8_t> columns_before_image; std::vector<uint8_t> columns_after_image; std::vector<uint8_t> row; public: unsigned long long get_table_id() const { return m_table_id.id(); } enum_flag get_flags() const { return static_cast<enum_flag>(m_flags); } uint32_t get_null_bits_len() const { return n_bits_len; } unsigned long get_width() const { return m_width; } static std::string get_flag_string(enum_flag flag) { std::string str= ""; if (flag & STMT_END_F) str.append(" Last event of the statement"); if (flag & NO_FOREIGN_KEY_CHECKS_F) str.append(" No foreign Key checks"); if (flag & RELAXED_UNIQUE_CHECKS_F) str.append(" No unique key checks"); if (flag & COMPLETE_ROWS_F) str.append(" Complete Rows"); if (flag & ~(STMT_END_F | NO_FOREIGN_KEY_CHECKS_F | RELAXED_UNIQUE_CHECKS_F | COMPLETE_ROWS_F)) str.append("Unknown Flag"); return str; } #ifndef HAVE_MYSYS void print_event_info(std::ostream& info); void print_long_info(std::ostream& info); #endif template <class Iterator_value_type> friend class Row_event_iterator; }; /** @class Write_rows_event Log row insertions. The event contain several insert/update rows for a table. Note that each event contains only rows for one table. @section Write_rows_event_binary_format Binary Format */ class Write_rows_event : public virtual Rows_event { public: Write_rows_event(const char *buf, unsigned int event_len, const Format_description_event *description_event) : Rows_event(buf, event_len, description_event) { this->header()->type_code= m_type; }; Write_rows_event() : Rows_event(WRITE_ROWS_EVENT) {} }; /** @class Update_rows_event Log row updates with a before image. The event contain several update rows for a table. Note that each event contains only rows for one table. Also note that the row data consists of pairs of row data: one row for the old data and one row for the new data. @section Update_rows_event_binary_format Binary Format */ class Update_rows_event : public virtual Rows_event { public: Update_rows_event(const char *buf, unsigned int event_len, const Format_description_event *description_event) : Rows_event(buf, event_len, description_event) { this->header()->type_code= m_type; } Update_rows_event() : Rows_event(UPDATE_ROWS_EVENT) {} }; /** @class Delete_rows_event Log row deletions. The event contain several delete rows for a table. Note that each event contains only rows for one table. RESPONSIBILITIES - Act as a container for rows that has been deleted on the master and should be deleted on the slave. @section Delete_rows_event_binary_format Binary Format */ class Delete_rows_event : public virtual Rows_event { public: Delete_rows_event(const char *buf, unsigned int event_len, const Format_description_event *description_event) : Rows_event(buf, event_len, description_event) { this->header()->type_code= m_type; } Delete_rows_event() : Rows_event(DELETE_ROWS_EVENT) {} }; /** @class Rows_query_event Rows query event type, which is a subclass of the Ignorable_event, to record the original query for the rows events in RBR. This event can be used to display the original query as comments by SHOW BINLOG EVENTS query, or mysqlbinlog client when the --verbose option is given twice @section Rows_query_var_event_binary_format Binary Format The Post-Header for this event type is empty. The Body has one component: <table> <caption>Body for Rows_query_event</caption> <tr> <th>Name</th> <th>Format</th> <th>Description</th> </tr> <tr> <td>m_rows_query</td> <td>char array</td> <td>Records the original query executed in RBR </td> </tr> </table> */ class Rows_query_event: public virtual Ignorable_event { public: /** It is used to write the original query in the binlog file in case of RBR when the session flag binlog_rows_query_log_events is set. <pre> The buffer layout is as follows: +------------------------------------+ | The original query executed in RBR | +------------------------------------+ @param buf Contains the serialized event. @param length Length of the serialized event. @param description_event An FDE event, used to get the following information -binlog_version -server_version -post_header_len -common_header_len The content of this object depends on the binlog-version currently in use. */ Rows_query_event(const char *buf, unsigned int event_len, const Format_description_event *descr_event); /** It is the minimal constructor, and all it will do is set the type_code as ROWS_QUERY_LOG_EVENT in the header object in Binary_log_event. */ Rows_query_event() : Ignorable_event(ROWS_QUERY_LOG_EVENT), m_rows_query(0) {} virtual ~Rows_query_event(); protected: char *m_rows_query; }; } /** @} (end of group Replication) */ #endif /* ROWS_EVENT_INCLUDED */