[MySQL 5.6] 5.6新参数slave_rows_search_algorithms

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用版 2核4GB 50GB
简介:

我们知道,MySQL有一个老问题,当表上无主键时,那么对于在该表上做的DML,如果是以ROW模式复制,则每一个行记录前镜像在备库都可能产生一次全表扫描(或者二级索引扫描),大多数情况下,这种开销都是非常不可接受的,并且产生大量的延迟。


在MySQL5.6中提供了一个新的参数:slave_rows_search_algorithms, 可以部分解决无主键表导致的复制延迟问题,其基本思路是对于在一个ROWS EVENT中的所有前镜像收集起来,然后在一次扫描全表时,判断HASH中的每一条记录进行更新。


测试:


首先来看看性能怎么样,我们使用sbtest表,并将其上面的主键及二级索引全部删除,表中有200万行数据

主库执行随机更新操作:

     update table sbtest2 set k = k +15 order by rand() limit  [$RECOR_NUM]; 

备库的最大延迟时间(基本等同执行时间)如下:

随机更新记录数

TABLE_SCAN,INDEX_SCAN

TABLE_SCAN,INDEX_SCAN,HASH_SCAN

10

26s

6s

20

51s

9s

40

96s

15s

60

147s

25s

80

187s

30s

100

228s

37s

可以看出来,该特性对于无主键表的复制延迟问题,还是有很大的帮助的。

如何使用:

slave_rows_search_algorithms的文档描述的非常清晰,该变量由三个值的组合组成:TABLE_SCAN,INDEX_SCAN, HASH_SCAN,使用组合包括:

TABLE_SCAN,INDEX_SCAN  (默认配置,表示如果有索引就用索引,否则使用全表扫描)

INDEX_SCAN,HASH_SCAN

TABLE_SCAN,HASH_SCAN

TABLE_SCAN,INDEX_SCAN,HASH_SCAN(等价于INDEX_SCAN, HASH_SCAN)

参数组合(摘自log_event.cc: 9633~9648)

  /*
    Decision table:
    - I  --> Index scan / search
    - T  --> Table scan
    - Hi --> Hash over index
    - Ht --> Hash over the entire table

    |--------------+-----------+------+------+------|
    | Index\Option | I , T , H | I, T | I, H | T, H |
    |--------------+-----------+------+------+------|
    | PK / UK      | I         | I    | I    | Hi   |
    | K            | Hi        | I    | Hi   | Hi   |
    | No Index     | Ht        | T    | Ht   | Ht   |
    |--------------+-----------+------+------+------|

  */

实现:

a.决定使用哪种scan方式:

函数:Rows_log_event::decide_row_lookup_algorithm_and_key

调用backtrace:

Rows_log_event::do_apply_event

     ->do_before_row_operations

          ->Rows_log_event::row_operations_scan_and_key_setup

                    ->Rows_log_event::decide_row_lookup_algorithm_and_key 

没啥好说的,根据上述的参数组合矩阵,来确定使用哪种scan策略,存储在rows log event对象的m_rows_lookup_algorithm中

另外这里也会去看看是否能够使用索引,以及使用哪个索引(this->m_key_index= search_key_in_table),

b.执行过程

在函数Rows_log_event::do_apply_event中,当确定了使用哪种scan策略后,就可以选择对应的接口函数:

11084     switch (m_rows_lookup_algorithm)
11085     {
11086       case ROW_LOOKUP_HASH_SCAN:
11087         do_apply_row_ptr= &Rows_log_event::do_hash_scan_and_update;
11088         break;
11089
11090       case ROW_LOOKUP_INDEX_SCAN:
11091         do_apply_row_ptr= &Rows_log_event::do_index_scan_and_update;
11092         break;
11093
11094       case ROW_LOOKUP_TABLE_SCAN:
11095         do_apply_row_ptr= &Rows_log_event::do_table_scan_and_update;
11096         break;
11097
11098       case ROW_LOOKUP_NOT_NEEDED:
11099         DBUG_ASSERT(get_general_type_code() == WRITE_ROWS_EVENT);
11100
11101         /* No need to scan for rows, just apply it */
11102         do_apply_row_ptr= &Rows_log_event::do_apply_row;
11103         break;
11104
11105       default:
11106         DBUG_ASSERT(0);
11107         error= 1;
11108         goto AFTER_MAIN_EXEC_ROW_LOOP;
11109         break;
11110     }

这里我们只关心Rows_log_event::do_hash_scan_and_update,主要做几件事

1.将当前行事件的记录前镜像和后镜像存储到一个hash中(Rows_log_event::do_hash_row);

hash表的结构定义在Hash_slave_rows类中

>>hash key的生成基于record[0],也就是前镜像;

>>前镜像记录的起始位置

>>前镜像记录的结束位置

对于hash scan,当有索引时(m_key_index<MAX_KEY),处理方式略微有些不一样:

在将记录加入到hash时,键值列被单独存储下来,存储在m_distinct_key_list中(Rows_log_event::add_key_to_distinct_keyset)

2.如果该EVENT中所有的行记录都解析完毕,开始执行SCAN && UPDATE (Rows_log_event::do_scan_and_update)

>>初始化表或者索引扫描(open_record_scan())

     对于索引,需要根据m_distinct_key_list初始化需要查询的键值iterator(m_itr)

>>在一个while循环中:

     |–>error= next_record_scan(i == 0);  //读取表或索引上的下一条记录

          |–>对于全表扫描,直接调用table->file->ha_rnd_next(table->record[0])扫描表记录

          |–>对于索引,第一次读是根据key搜索记录,下一次再调用next_record_scan时,先看下一条记录是否和当前m_key是否匹配,如果不匹配,将 m_key指向下一个m_itr,并根据m_key重读index,否则使用这个记录;

          这里看起来似乎有优化的余地,因为m_itr并不是有序的,它的成员取自m_distinct_key_list,并且也不会保证存储的Key完全不重复,从函数 add_key_to_distinct_keyset的逻辑可以看出来,每次加入一个新的key,仅仅和上一次的key做对比来判断是否重复,但实际上二级索引key在一个rows log event中可能是无序的,做一次排序 会不会有利于性能呢?(TODO)

     

     |–>根据读取到的记录构建key,查找hash,查看是否存在对应的entry(entry= m_hash.get(table, &m_cols))

     |–>如果存在entry,还需要把读取到的记录跟该entry对应的binlog中的行记录进行比较(防止hash collision),符合的话,则从hash中将其删除,并应用该更新(Rows_log_event::do_apply_row)

当发生错误,或者hash中记录删光后,结束扫描,从while退出

可见,对于没有索引的表而言,最多需要一次表扫描。


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
SQL 缓存 关系型数据库
Mysql第十四天,Mysql并发参数调整
Mysql第十四天,Mysql并发参数调整
38 0
|
1月前
|
SQL 关系型数据库 MySQL
在云数据仓库AnalyticDB MySQL版中,有几个参数可能影响SELECT查询的执行及其稳定性
在云数据仓库AnalyticDB MySQL版中,有几个参数可能影响SELECT查询的执行及其稳定性【1月更文挑战第16天】【1月更文挑战第80篇】
312 4
|
1月前
|
SQL 关系型数据库 MySQL
使用CTAS 把mysql 表同步数据 到hologres ,Flink有什么参数可以使hologres 的字段都小写吗?
使用CTAS 把mysql 表同步数据 到hologres ,Flink有什么参数可以使hologres 的字段都小写吗?
331 0
|
1月前
|
存储 关系型数据库 MySQL
RDS有哪些参数?都有什么作用?
RDS有哪些参数?都有什么作用?
80 0
|
1月前
|
缓存 关系型数据库 MySQL
MySQL Binlog--事务日志和BINLOG落盘参数对磁盘IO的影响
MySQL Binlog--事务日志和BINLOG落盘参数对磁盘IO的影响
65 0
|
1月前
|
存储 监控 关系型数据库
MySQL 参数innodb_read_io_threads
`innodb_read_io_threads` 是 MySQL 数据库中 InnoDB 存储引擎的一个配置参数,它用于指定后台线程池中用于处理读取 I/O 请求的线程数量。InnoDB 存储引擎负责管理数据库的物理存储和检索,是 MySQL 最常用的存储引擎之一。 ### 参数说明 - **名称**: `innodb_read_io_threads` - **默认值**: 4 - **范围**: 1 到 64 - **动态修改**: 不能动态修改(需要重启服务器) - **适用版本**: MySQL 5.6 及以上版本 ### 作用 `innodb_read_io_threads`
167 1
|
1月前
|
缓存 关系型数据库 MySQL
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
|
1月前
|
SQL 关系型数据库 MySQL
【Mysql】MYSQL参数max_allowed_packet 介绍
【Mysql】MYSQL参数max_allowed_packet 介绍
167 0
|
1月前
|
SQL 关系型数据库 MySQL
实时计算 Flink版产品使用合集之使用 MySQL CDC 进行数据同步时,设置 server_id 参数如何解决
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
15天前
|
存储 Oracle 关系型数据库
【MySQL技术内幕】3.1-参数文件
【MySQL技术内幕】3.1-参数文件
12 0