-
Luis Soares authored
INVOLVED The HASH_SCAN lookup mechanism was not working properly. This mechanism works as follow: (i) For each before image in an Update_rows_log_event or Delete_rows_log_event, it hashes this image and saves its coordinates on an hash table. If it is an Update_rows_log_event, it also saves the coordinates of the after image. (ii) Then the table is scanned once, and each record fetched from the physical table is hashed and looked up on the hash table. If the lookup succeeds, then the changes are applied. And this is fine. Unfortunately, when a field contains a NULL value, the engine may return garbage as the field content. Then the hash of the physical record will not match the hash calculated from the (Delete_|Update_)rows_log_event. This makes the applier assume that it cannot find the record to apply and stop. This patch fixes this, by discarding from the hash calculation those fields that are marked as NULL. This is the bulk of the fix. Additionally, this patch also: (i) fixes the limitation of not considering BLOBs and BIT fields as part of the hash calculation. They had not been considered since their data may not be stored inside the record itself, but on a different memory area. We circumvent this by getting the value explicitly through the member function: val_str. Similar pattern may be found in the function: mysql_checksum_table. (ii) Fixes some comments and indentation. (iii) Refactors a few parts in do_hash_scan_and_update_record (splits it into two simpler member functions). (iv) Fixes a potential issue with the fact that we unpack the before image on top of previous unpacked data, thus might have implications with partial rows. We call prepare_record before we unpack now. (v) Removes unnecessary memory structures for after image positions that are not used.
Luis Soares authoredINVOLVED The HASH_SCAN lookup mechanism was not working properly. This mechanism works as follow: (i) For each before image in an Update_rows_log_event or Delete_rows_log_event, it hashes this image and saves its coordinates on an hash table. If it is an Update_rows_log_event, it also saves the coordinates of the after image. (ii) Then the table is scanned once, and each record fetched from the physical table is hashed and looked up on the hash table. If the lookup succeeds, then the changes are applied. And this is fine. Unfortunately, when a field contains a NULL value, the engine may return garbage as the field content. Then the hash of the physical record will not match the hash calculated from the (Delete_|Update_)rows_log_event. This makes the applier assume that it cannot find the record to apply and stop. This patch fixes this, by discarding from the hash calculation those fields that are marked as NULL. This is the bulk of the fix. Additionally, this patch also: (i) fixes the limitation of not considering BLOBs and BIT fields as part of the hash calculation. They had not been considered since their data may not be stored inside the record itself, but on a different memory area. We circumvent this by getting the value explicitly through the member function: val_str. Similar pattern may be found in the function: mysql_checksum_table. (ii) Fixes some comments and indentation. (iii) Refactors a few parts in do_hash_scan_and_update_record (splits it into two simpler member functions). (iv) Fixes a potential issue with the fact that we unpack the before image on top of previous unpacked data, thus might have implications with partial rows. We call prepare_record before we unpack now. (v) Removes unnecessary memory structures for after image positions that are not used.
Loading