MySQL 8.4.2
Source Code Documentation
|
Go to the source code of this file.
Classes | |
class | Bit_stream_base< T, UT > |
Template base class of Bit_reader / Bit_writer. More... | |
class | Bit_writer |
Auxiliary class to write a stream of bits to a memory location. More... | |
class | Bit_reader |
Auxiliary class to read or write a stream of bits to a memory location. More... | |
Enumerations | |
enum class | enum_row_image_type { WRITE_AI , UPDATE_BI , UPDATE_AI , DELETE_BI } |
Functions | |
size_t | pack_row (TABLE *table, MY_BITMAP const *cols, uchar *row_data, const uchar *data, enum_row_image_type row_image_type, ulonglong value_options=0) |
Pack a record of data for a table into a format suitable for the binary log. More... | |
bool | unpack_row (Relay_log_info const *rli, TABLE *table, uint const source_column_count, uchar const *const row_data, MY_BITMAP const *column_image, uchar const **const row_image_end_p, uchar const *const event_end, enum_row_image_type row_image_type, bool event_has_value_options, bool only_seek) |
Unpack a row image (either before-image or after-image) into table->record [0]. More... | |
const uchar * | translate_beginning_of_raw_data (const uchar *raw_data, MY_BITMAP const *column_image, size_t column_count, Bit_reader &null_bits, table_def *tabledef, bool source_has_gipk, bool replica_has_gipk) |
Return a pointer within a row event's row data, to the data of the first column that exists on the replica. More... | |
int | prepare_record (TABLE *const table, const MY_BITMAP *cols, const bool check) |
Fills table->record [0] with default values. More... | |
|
strong |
size_t pack_row | ( | TABLE * | table, |
MY_BITMAP const * | columns_in_image, | ||
uchar * | row_data, | ||
const uchar * | record, | ||
enum_row_image_type | row_image_type, | ||
ulonglong | value_options | ||
) |
Pack a record of data for a table into a format suitable for the binary log.
The format for a row where N columns are included in the image is the following:
+-----------+----------+----------+ +----------+ | null_bits | column_1 | column_2 | ... | column_N | +-----------+----------+----------+ +----------+
Where
columns_in_image
bitmap.table | Table describing the format of the record |
columns_in_image | Bitmap with a set bit for each column that should be stored in the row. |
row_data | Pointer to memory where row will be written |
record | Pointer to record retrieved from the engine. |
row_image_type | The type of image: before-image or after-image, for a Write/Update/Delete event. |
value_options | The value of @session.binlog_row_value_options |
row_data
. Fills table->record
[0] with default values.
First restore_record()
is called to restore the default values for the record concerning the given table. Then, if check
is true, a check is performed to see if fields have the default value or can be NULL. Otherwise an error is reported.
table | Table whose record[0] buffer is prepared. |
cols | bitmap with a set bit for each column that should be stored in a row. |
check | Specifies if lack of default error needs checking. |
Save a reference to the original write set bitmaps. We will need this to restore the bitmaps at the end.
Just to be sure that tmp_set is currently not in use as the write_set already.
Set table->write_set bits for all the columns as they will be checked in set_default() function.
const uchar * translate_beginning_of_raw_data | ( | const uchar * | raw_data, |
MY_BITMAP const * | column_image, | ||
size_t | column_count, | ||
Bit_reader & | null_bits, | ||
table_def * | tabledef, | ||
bool | source_has_gipk, | ||
bool | replica_has_gipk | ||
) |
Return a pointer within a row event's row data, to the data of the first column that exists on the replica.
This skips the 'null bits' field, which precedes the column definitions in the row image. In case a GIPK exists in the event but not in this replica's table definition, it skips the GIPK too.
raw_data | The data received from the source |
column_image | The column bitmap |
column_count | The number of column in the image bitmap |
null_bits | The bits that are null |
tabledef | The source table definition structure |
source_has_gipk | If the source table has a GIPK |
replica_has_gipk | If the replica table has a GIPK |
bool unpack_row | ( | Relay_log_info const * | rli, |
TABLE * | table, | ||
uint const | source_column_count, | ||
uchar const *const | row_data, | ||
MY_BITMAP const * | column_image, | ||
uchar const **const | row_image_end_p, | ||
uchar const *const | event_end, | ||
enum_row_image_type | row_image_type, | ||
bool | event_has_value_options, | ||
bool | only_seek | ||
) |
Unpack a row image (either before-image or after-image) into table->record
[0].
The row is assumed to only consist of the fields for which the corresponding bit in bitset column_image
is set; the other parts of the record are left alone.
If the replica table has more columns than the source table, then the extra columns are not touched by this function. If the source table has more columns than the replica table, then the position is moved to after the extra columns, but the values are not used.
If the replica has a GIPK and the source does not, then the extra column is not touched by this function. If the source table has a GIPK and the replica does not, then the position is shifted forward by 1.
The layout of a row is:
For WRITE_ROWS_EVENT: +-----------—+ | after-image | +-----------—+
For DELETE_ROWS_EVENT: +-----------—+ | before-image | +-----------—+
For UPDATE_ROWS_EVENT: +-----------—+----------—+ | before-image | after-image | +-----------—+----------—+
For PARTIAL_UPDATE_ROWS_EVENT: +-----------—+-----------—+----------—+ | before-image | shared-image | after-image | +-----------—+-----------—+----------—+
Both when reading the before-image and when reading the after-image it is necessary to know the partialness of JSON columns: when reading the before-image, before looking up the row in the table, we need to set the column in the table's 'read_set' (even if the column was not in the before-image), in order to guarantee that the storage engine reads that column, so that there is any base document that the diff can be applied on. When reading the after-image, we need to know which columns are partial so that we can correctly parse the data for that column.
Therefore, when this function parses the before-image of a PARTIAL_UPDATE_ROWS_LOG_EVENT, it reads both the before-image and the shared-image, but leaves the read position after the before-image. So when it parses the after-image of a PARTIAL_UPDATE_ROWS_LOG_EVENT, the read position is at the beginning of the shared-image, so it parses both the shared-image and the after-image.
[in] | rli | Applier execution context |
[in,out] | table | Table to unpack into |
[in] | source_column_count | Number of columns that the source had in its table |
[in] | row_data | Beginning of the row image |
[in] | column_image | Pointer to a bit vector where the N'th bit is 0 for columns that are not included in the event, and 1 for columns that are included in the event. |
[out] | row_image_end_p | If this function returns successfully, it sets row_image_end to point to the next byte after the row image that it has read. |
[in] | event_end | Pointer to the end of the event. |
[in] | row_image_type | The type of row image that we are going to read: WRITE_AI, UPDATE_BI, UPDATE_AI, or DELETE_BI. |
[in] | event_has_value_options | true for PARTIAL_UPDATE_ROWS_EVENT, false for UPDATE_ROWS_EVENT. |
only_seek | If true, this is a seek operation rather than a read operation. It will only compute the row_image_end_p pointer, and not read anything into the table and not apply any JSON diffs. (This is used in HASH_SCAN, which (1) unpacks and hashes the before-image for all rows in the event, (2)vscans the table, and for each matching row it (3) unpacks the after-image and applies on the table. In step (1) it needs to unpack the after-image too, in order to move the read position forwards, and then it should use only_seek=true. This is an optimization, but more importantly, when the after-image contains partial JSON, the partial JSON cannot be applied in step (1) since there is no JSON document to apply it on.) |
Calling reset just in case one is unpacking on top a record with data.
This could probably go into set_null() but doing so, (i) triggers assertion in other parts of the code at the moment; (ii) it would make us reset the field, always when setting null, which right now doesn't seem needed anywhere else except here.
TODO: maybe in the future we should consider moving the reset to make it part of set_null. But then the assertions triggered need to be addressed/revisited.