当前位置: 首页 > news >正文

申请域名后怎样建设网站怎么做淘宝客网站

申请域名后怎样建设网站,怎么做淘宝客网站,wordpress 外网访问,官方网站百度一下文章目录 1. MySql保证主备一致1.1 MySQL 主备的基本原理1.2 binlog 的三种格式对比1.3 循环复制问题 2. MySql保证高可用2.1 主备延迟2.2 主备延迟的来源2.3 可靠性优先策略2.4 可用性优先策略 3. 备库为何会延迟很久-备库并行复制能力3.1 MySQL 5.6 版本的并行复制策略3.2 Ma… 文章目录 1. MySql保证主备一致1.1 MySQL 主备的基本原理1.2 binlog 的三种格式对比1.3 循环复制问题 2. MySql保证高可用2.1 主备延迟2.2 主备延迟的来源2.3 可靠性优先策略2.4 可用性优先策略 3. 备库为何会延迟很久-备库并行复制能力3.1 MySQL 5.6 版本的并行复制策略3.2 MariaDB 的并行复制策略3.3 MySQL 5.7 的并行复制策略3.4 MySQL 5.7.22 的并行复制策略 1. MySql保证主备一致 binlog 可以用来归档也可以用来做主备同步但它的内容是什么样的呢 为什么备库执行了 binlog 就可以跟主库保持一致了呢 1.1 MySQL 主备的基本原理 图 1 MySQL 主备切换流程 在状态 1 中客户端的读写都直接访问节点 A而节点 B 是 A 的备库只是将 A 的更新都同步过来到本地执行。这样可以保持节点 B 和 A 的数据是相同的。 当需要切换的时候就切成状态 2。这时候客户端读写访问的都是节点 B而节点 A 是 B 的备库。 在状态 1 中虽然节点 B 没有被直接访问但是依然建议你把节点 B也就是备库设置成只读readonly模式。原因如下: 有时候一些运营类的查询语句会被放到备库上去查设置为只读可以防止误操作防止切换逻辑有 bug比如切换过程中出现双写造成主备不一致可以用 readonly 状态来判断节点的角色。 readonly 设置对超级 (super) 权限用户是无效的而用于同步更新的线程就拥有超级权限。 节点 A 到 B 这条线的内部流程是什么样的。 图 2 中画出的就是一个 update 语句在节点 A 执行然后同步到节点 B 的完整流程图。 图 2 主备流程图 可以看到主库接收到客户端的更新请求后执行内部事务的更新逻辑同时写 binlog。 备库 B 跟主库 A 之间维持了一个长连接。主库 A 内部有一个线程专门用于服务备库 B 的这个长连接。 一个事务日志同步的完整过程是这样的 在备库 B 上通过 change master 命令设置主库 A 的 IP、端口、用户名、密码以及要从哪个位置开始请求 binlog这个位置包含文件名和日志偏移量。在备库 B 上执行 start slave 命令这时候备库会启动两个线程就是图中的 io_thread 和 sql_thread。其中 io_thread 负责与主库建立连接。主库 A 校验完用户名、密码后开始按照备库 B 传过来的位置从本地读取 binlog发给 B。备库 B 拿到 binlog 后写到本地文件称为中转日志relay log。sql_thread 读取中转日志解析出日志里的命令并执行。 1.2 binlog 的三种格式对比 binlog三种格式 statementrowmixed 为了便于描述 binlog 的这三种格式间的区别我创建了一个表并初始化几行数据。 mysql CREATE TABLE t (id int(11) NOT NULL,a int(11) DEFAULT NULL,t_modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (id),KEY a (a),KEY t_modified(t_modified) ) ENGINEInnoDB;insert into t values(1,1,2018-11-13); insert into t values(2,2,2018-11-12); insert into t values(3,3,2018-11-11); insert into t values(4,4,2018-11-10); insert into t values(5,5,2018-11-09);在表中删除一行数据的话来看看这个 delete 语句的 binlog 是怎么记录的。 -- 这个语句包含注释如果你用 MySQL 客户端来做这个实验的话要记得加 -c 参数否则客户端会自动去掉注释。 mysql delete from t /*comment*/ where a4 and t_modified2018-11-10 limit 1;当 binlog_formatstatement 时 binlog 里面记录的就是 SQL 语句的原文。可以用下列语句查看binlog内容 mysql show binlog events in master.000001;图 3 statement 格式 binlog 示例 图 3 的输出结果 第一行 SET SESSION.GTID_NEXTANONYMOUS’可以先忽略是主备切换内容第二行是一个 BEGIN跟第四行的 commit 对应表示中间是一个事务第三行就是真实执行的语句了。可以看到在真实执行的 delete 命令之前还有一个“use ‘test’”命令。这条命令不是我们主动执行的而是 MySQL 根据当前要操作的表所在的数据库自行添加的。这样做可以保证日志传到备库去执行的时候不论当前的工作线程在哪个库里都能够正确地更新到 test 库的表 t。use test’命令之后的 delete 语句就是我们输入的 SQL 原文了。可以看到binlog“忠实”地记录了 SQL 命令甚至连注释也一并记录了。最后一行是一个 COMMIT。可以看到里面写着 xid61。 为了说明 statement 和 row 格式的区别看一下这条 delete 命令的执行效果图 运行这条 delete 命令产生了一个 warning原因是当前 binlog 设置的是 statement 格式并且语句中有 limit所以这个命令可能是 unsafe 的。 这是因为 delete 带 limit很可能会出现主备数据不一致的情况: 如果 delete 语句使用的是索引 a那么会根据索引 a 找到第一个满足条件的行也就是说删除的是 a4 这一行但如果使用的是索引 t_modified那么删除的就是 t_modified2018-11-09’也就是 a5 这一行。 由于 statement 格式下记录到 binlog 里的是语句原文因此可能会出现这样一种情况 在主库执行这条 SQL 语句的时候用的是索引 a而在备库执行这条 SQL 语句的时候却使用了索引 t_modified。因此MySQL 认为这样写是有风险的。 ** binlog 的格式改为 binlog_format‘row’** 图 5 row 格式 binlog 示例 与 statement 格式的 binlog 相比前后的 BEGIN 和 COMMIT 是一样的。 但是row 格式的 binlog 里没有了 SQL 语句的原文而是替换成了两个 eventTable_map 和 Delete_rows。 Table_map event用于说明接下来要操作的表是 test 库的表 t;Delete_rows event用于定义删除的行为。 通过图 5 是看不到详细信息的还需要借助 mysqlbinlog 工具用下面这个命令解析和查看 binlog 中的内容 mysqlbinlog -vv data/master.000001 --start-position8900;图 6 row 格式 binlog 示例的详细信息 从这个图中可以看到以下信息 server id 1表示这个事务是在 server_id1 的这个库上执行的。每个 event 都有 CRC32 的值这是因为参数 binlog_checksum 设置成了 CRC32。Table_map event 跟在图 5 中看到的相同显示了接下来要打开的表map 到数字 226。现在我们这条 SQL 语句只操作了一张表如果要操作多张表呢每个表都有一个对应的 Table_map event、都会 map 到一个单独的数字用于区分对不同表的操作。在 mysqlbinlog 的命令中使用了 -vv 参数是为了把内容都解析出来所以从结果里面可以看到各个字段的值比如14、 24 这些值。binlog_row_image 的默认配置是 FULL因此 Delete_event 里面包含了删掉的行的所有字段的值。如果把 binlog_row_image 设置为 MINIMAL则只会记录必要的信息在这个例子里就是只会记录 id4 这个信息。最后的 Xid event用于表示事务被正确地提交了。 当 binlog_format 使用 row 格式的时候binlog 里面记录了真实删除行的主键 id这样 binlog 传到备库去的时候就肯定会删除 id4 的行不会有主备删除不同行的问题。 为什么会有 mixed 格式的 binlog 推论过程是这样的 因为有些 statement 格式的 binlog 可能会导致主备不一致所以要使用 row 格式。但 row 格式的缺点是很占空间。比如你用一个 delete 语句删掉 10 万行数据用 statement 的话就是一个 SQL 语句被记录到 binlog 中占用几十个字节的空间。但如果用 row 格式的 binlog就要把这 10 万条记录都写到 binlog 中。这样做不仅会占用更大的空间同时写 binlog 也要耗费 IO 资源影响执行速度。所以MySQL 就取了个折中方案也就是有了 mixed 格式的 binlog。mixed 格式的意思是MySQL 自己会判断这条 SQL 语句是否可能引起主备不一致如果有可能就用 row 格式否则就用 statement 格式。 mixed 格式可以利用 statment 格式的优点同时又避免了数据不一致的风险。 越来越多的场景要求把 MySQL 的 binlog 格式设置成 row。这么做的理由有很多我来给你举一个可以直接看出来的好处恢复数据 分别从 delete、insert 和 update 这三种 SQL 语句的角度来看看数据恢复的问题。 通过图 6 可以看出来即使执行的是 delete 语句row 格式的 binlog 也会把被删掉的行的整行信息保存起来。所以如果在执行完一条 delete 语句以后发现删错数据了可以直接把 binlog 中记录的 delete 语句转成 insert把被错删的数据插入回去就可以恢复了。 如果是执行错了 insert 语句呢那就更直接了。row 格式下insert 语句的 binlog 里会记录所有的字段信息这些信息可以用来精确定位刚刚被插入的那一行。这时直接把 insert 语句转成 delete 语句删除掉这被误插入的一行数据就可以了。 如果执行的是 update 语句的话binlog 里面会记录修改前整行的数据和修改后的整行数据。所以如果误执行了 update 语句的话只需要把这个 event 前后的两行信息对调一下再去数据库里面执行就能恢复这个更新操作了。 mysql insert into t values(10,10, now());上面的SQL,如果把 binlog 格式设置为 mixedMySQL 会把它记录为 row 格式还是 statement 格式呢 图 7 mixed 格式和 now() 可以看到MySQL 用的居然是 statement 格式。如果这个 binlog 过了 1 分钟才传给备库的话那主备的数据不就不一致了吗 用 mysqlbinlog 工具来看看: 图 8 TIMESTAMP 命令 原来 binlog 在记录 event 的时候多记了一条命令SET TIMESTAMP1546103491。它用 SET TIMESTAMP 命令约定了接下来的 now() 函数的返回时间。不论这个 binlog 是 1 分钟之后被备库执行还是 3 天后用来恢复这个库的备份这个 insert 语句插入的行值都是固定的 用 binlog 来恢复数据的标准做法是用 mysqlbinlog 工具解析出来然后把解析结果整个发给 MySQL 执行。类似下面的命令 mysqlbinlog master.000001 --start-position2738 --stop-position2973 | mysql -h127.0.0.1 -P13000 -u$user -p$pwd;这个命令的意思是将 master.000001 文件里面从第 2738 字节到第 2973 字节中间这段内容解析出来放到 MySQL 去执行。 1.3 循环复制问题 图 9 MySQL 主备切换流程 – 双 M 结构 对比图 9 和图 1可以发现双 M 结构和 M-S 结构其实区别只是多了一条线 即节点 A 和 B 之间总是互为主备关系。这样在切换的时候就不用再修改主备关系。 问题 业务逻辑在节点 A 上更新了一条语句然后再把生成的 binlog 发给节点 B节点 B 执行完这条更新语句后也会生成 binlog。建议你把参数 log_slave_updates 设置为 on表示备库执行 relay log 后生成 binlog。 那么如果节点 A 同时是节点 B 的备库相当于又把节点 B 新生成的 binlog 拿过来执行了一次然后节点 A 和 B 间会不断地循环执行这个更新语句也就是循环复制了。这个要怎么解决呢 MySQL 在 binlog 中记录了这个命令第一次执行时所在实例的 server id。 因此我们可以用下面的逻辑来解决两个节点间的循环复制的问题 规定两个库的 server id 必须不同如果相同则它们之间不能设定为主备关系一个备库接到 binlog 并在重放的过程中生成与原 binlog 的 server id 相同的新的 binlog每个库在收到从自己的主库发过来的日志后先判断 server id如果跟自己的相同表示这个日志是自己生成的就直接丢弃这个日志。 2. MySql保证高可用 图 1 MySQL 主备切换流程 – 双 M 结构 2.1 主备延迟 与数据同步有关的时间点主要包括以下三个 主库 A 执行完成一个事务写入 binlog把这个时刻记为 T1;之后传给备库 B把备库 B 接收完这个 binlog 的时刻记为 T2;备库 B 执行完成这个事务我们把这个时刻记为 T3。 所谓主备延迟就是同一个事务在备库执行完成的时间和主库执行完成的时间之间的差值也就是 T3-T1 可以在备库上执行 show slave status 命令它的返回结果里面会显示 seconds_behind_master用于表示当前备库延迟了多少秒。 seconds_behind_master(精度是秒) 的计算方法是这样的 每个事务的 binlog 里面都有一个时间字段用于记录主库上写入的时间备库取出当前正在执行的事务的时间字段的值计算它与当前系统时间的差值得到 seconds_behind_master。 如果主备库机器的系统时间设置不一致会不会导致主备延迟的值不准 不会的。因为备库连接到主库的时候会通过执行 SELECT UNIX_TIMESTAMP() 函数来获得当前主库的系统时间。如果这时候发现主库的系统时间与自己不一致备库在执行 seconds_behind_master 计算的时候会自动扣掉这个差值。 在网络正常的时候日志从主库传给备库所需的时间是很短的即 T2-T1 的值是非常小的。也就是说网络正常情况下主备延迟的主要来源是备库接收完 binlog 和执行完这个事务之间的时间差。 所以说主备延迟最直接的表现是备库消费中转日志relay log的速度比主库生产 binlog 的速度要慢。 2.2 主备延迟的来源 首先有些部署条件下备库所在机器的性能要比主库所在的机器性能差。 更新请求对 IOPS 的压力在主库和备库上是无差别的。所以做这种部署时一般都会将备库设置为“非双 1”的模式。 实际上更新过程中也会触发大量的读操作。所以当备库主机上的多个备库都在争抢资源的时候就可能会导致主备延迟了 因为主备可能发生切换备库随时可能变成主库所以主备库选用相同规格的机器并且做对称部署是现在比较常见的情况。 问题1做了对称部署以后还可能会有延迟。这是为什么呢 备库的压力大。一般的想法是主库既然提供了写能力那么备库可以提供一些读能力。或者一些运营后台需要的分析语句不能影响正常业务所以只能在备库上跑。反而忽视了备库的压力控制。结果就是备库上的查询耗费了大量的 CPU 资源影响了同步速度造成主备延迟。 处理 一主多从。除了备库外可以多接几个从库让这些从库来分担读的压力。(一般采用这种方式)通过 binlog 输出到外部系统比如 Hadoop 这类系统让外部系统提供统计类查询的能力。 问题2采用了一主多从保证备库的压力不会超过主库还有什么情况可能导致主备延迟吗 大事务。因为主库上必须等事务执行完成才会写入 binlog再传给备库。所以如果一个主库上的语句执行 10 分钟那这个事务很可能就会导致从库延迟 10 分钟。 不要一次性地用 delete 语句删除太多数据。其实这就是一个典型的大事务场景。大表 DDL。处理方案就是计划内的 DDL建议使用 gh-ost 方案 问题3如果主库上也不做大事务了还有什么原因会导致主备延迟吗 备库的并行复制能力。 2.3 可靠性优先策略 在图 1 的双 M 结构下从状态 1 到状态 2 切换的详细过程是这样的 判断备库 B 现在的 seconds_behind_master如果小于某个值比如 5 秒继续下一步否则持续重试这一步把主库 A 改成只读状态即把 readonly 设置为 true判断备库 B 的 seconds_behind_master 的值直到这个值变成 0 为止(较耗时)把备库 B 改成可读写状态也就是把 readonly 设置为 false把业务请求切到备库 B。 图 2 MySQL 可靠性优先主备切换流程 备注图中的 SBM是 seconds_behind_master 参数的简写。 这个切换流程中是有不可用时间的。因为在步骤 2 之后主库 A 和备库 B 都处于 readonly 状态也就是说这时系统处于不可写状态直到步骤 5 完成后才能恢复。 系统的不可用时间是由这个数据可靠性优先的策略决定的。也可以选择可用性优先的策略来把这个不可用时间几乎降为 0。 2.4 可用性优先策略 如果强行把步骤 4、5 调整到最开始执行也就是说不等主备数据同步直接把连接切到备库 B并且让备库 B 可以读写那么系统几乎就没有不可用时间了。这个切换流程暂时称作可用性优先流程。 这个切换流程的代价就是可能出现数据不一致的情况。 例子 假设有一个表 t mysql CREATE TABLE t (id int(11) unsigned NOT NULL AUTO_INCREMENT,c int(11) unsigned DEFAULT NULL,PRIMARY KEY (id) ) ENGINEInnoDB;insert into t(c) values(1),(2),(3);表定义了一个自增主键 id初始化数据后主库和备库上都是 3 行数据。接下来业务人员要继续在表 t 上执行两条插入语句的命令依次是 insert into t(c) values(4); insert into t(c) values(5);假设现在主库上其他的数据表有大量的更新导致主备延迟达到 5 秒。在插入一条 c4 的语句后发起了主备切换。 下图是可用性优先策略且 binlog_formatmixed 时的切换流程和数据结果。 图 3 可用性优先策略且 binlog_formatmixed 分析下这个切换流程 步骤 2 中主库 A 执行完 insert 语句插入了一行数据4,4之后开始进行主备切换。步骤 3 中由于主备之间有 5 秒的延迟所以备库 B 还没来得及应用“插入 c4”这个中转日志就开始接收客户端“插入 c5”的命令。步骤 4 中备库 B 插入了一行数据4,5并且把这个 binlog 发给主库 A。步骤 5 中备库 B 执行“插入 c4”这个中转日志插入了一行数据5,4。而直接在备库 B 执行的“插入 c5”这个语句传到主库 A就插入了一行新数据5,5。 最后的结果就是主库 A 和备库 B 上出现了两行不一致的数据。可以看到这个数据不一致是由可用性优先流程导致的。 如果还是用可用性优先策略但设置 binlog_formatrow情况又会怎样呢 因为 row 格式在记录 binlog 的时候会记录新插入的行的所有字段值所以最后只会有一行不一致。而且两边的主备同步的应用线程会报错 duplicate key error 并停止。也就是说这种情况下备库 B 的 (5,4) 和主库 A 的 (5,5) 这两行数据都不会被对方执行。 图 4 可用性优先策略且 binlog_formatrow 结论 使用 row 格式的 binlog 时数据不一致的问题更容易被发现。而使用 mixed 或者 statement 格式的 binlog 时数据很可能悄悄地就不一致了。如果你过了很久才发现数据不一致的问题很可能这时的数据不一致已经不可查或者连带造成了更多的数据逻辑不一致。主备切换的可用性优先策略会导致数据不一致。因此大多数情况下都建议使用可靠性优先策略。毕竟对数据服务来说的话数据的可靠性一般还是要优于可用性的。 按照可靠性优先的思路异常切换会是什么效果 假设主库 A 和备库 B 间的主备延迟是 30 分钟这时候主库 A 掉电了HA 系统要切换 B 作为主库。在主动切换的时候可以等到主备延迟小于 5 秒的时候再启动切换但这时候已经别无选择了。 图 5 可靠性优先策略主库不可用 采用可靠性优先策略的话就必须得等到备库 B 的 seconds_behind_master0 之后才能切换。 但现在的情况比刚刚更严重并不是系统只读、不可写的问题了而是系统处于完全不可用的状态。因为主库 A 掉电后我们的连接还没有切到备库 B。 能不能直接切换到备库 B但是保持 B 只读呢 这样也不行。因为这段时间内中转日志还没有应用完成如果直接发起主备切换客户端查询看不到之前执行完成的事务会认为有“数据丢失”。虽然随着中转日志的继续应用这些数据会恢复回来但是对于一些业务来说查询到“暂时丢失数据的状态”也是不能被接受的。 在满足数据可靠性的前提下MySQL 高可用系统的可用性是依赖于主备延迟的。延迟的时间越小在主库故障的时候服务恢复需要的时间就越短可用性就越高。 思考 一般现在的数据库运维系统都有备库延迟监控其实就是在备库上执行 show slave status采集 seconds_behind_master 的值。假设现在你看到你维护的一个备库它的延迟监控的图像类似图 6是一个 45°斜向上的线段你觉得可能是什么原因导致呢你又会怎么去确认这个原因呢 备库的同步在这段时间完全被堵住了。 产生这种现象典型的场景主要包括两种 一种是大事务包括大表 DDL、一个事务操作很多行还有一种情况比较隐蔽就是备库起了一个长事务 3. 备库为何会延迟很久-备库并行复制能力 介绍了几种可能导致备库延迟的原因。这些场景里不论是偶发性的查询压力还是备份对备库延迟的影响一般是分钟级的而且在备库恢复正常以后都能够追上来。 图 1 主备流程图 图中黑色的两个箭头。 一个箭头代表了客户端写入主库另一箭头代表的是备库上 sql_thread 执行中转日志relay log。 如果用箭头的粗细来代表并行度的话那么真实情况就如图 1 所示第一个箭头要明显粗于第二个箭头。 在主库上影响并发度的原因是各种锁。由于 InnoDB 引擎支持行锁除了所有并发事务都在更新同一行热点行这种极端场景外它对业务并发度的支持还是很友好的。所以在性能测试的时候会发现并发压测线程 32 就比单线程时总体吞吐量高。 而日志在备库上的执行就是图中备库上 sql_thread 更新数据 (DATA) 的逻辑。如果是用单线程的话就会导致备库应用日志不够快造成主备延迟。 在官方的 5.6 版本之前MySQL 只支持单线程复制由此在主库并发高、TPS 高时就会出现严重的主备延迟问题。 MySQL 多线程复制的演进过程 图 2 多线程模型 图 2 中coordinator 就是原来的 sql_thread, 不过现在它不再直接更新数据了只负责读取中转日志和分发事务。 真正更新日志的变成了 worker 线程。而 work 线程的个数就是由参数 slave_parallel_workers 决定的。根据经验这个值设置为 8~16 之间最好32 核物理机的情况毕竟备库还有可能要提供读查询不能把 CPU 都吃光了。 问题1 事务能不能按照轮询的方式分发给各个 worker也就是第一个事务分给 worker_1第二个事务发给 worker_2 呢 回答 其实是不行的。因为事务被分发给 worker 以后不同的 worker 就独立执行了。 但是由于 CPU 的调度策略很可能第二个事务最终比第一个事务先执行。而如果这时候刚好这两个事务更新的是同一行也就意味着同一行上的两个事务在主库和备库上的执行顺序相反会导致主备不一致的问题。 问题2 同一个事务的多个更新语句能不能分给不同的 worker 来执行呢 回答 也不行。举个例子一个事务更新了表 t1 和表 t2 中的各一行如果这两条更新语句被分到不同 worker 的话虽然最终的结果是主备一致的但如果表 t1 执行完成的瞬间备库上有一个查询就会看到这个事务“更新了一半的结果”破坏了事务逻辑的隔离性。 所以coordinator 在分发的时候需要满足以下这两个基本要求 不能造成更新覆盖。这就要求更新同一行的两个事务必须被分发到同一个 worker 中。同一个事务不能被拆开必须放到同一个 worker 中。 各个版本的多线程复制都遵循了这两条基本原则。 3.1 MySQL 5.6 版本的并行复制策略 官方 MySQL5.6 版本支持了并行复制只是支持的粒度是按库并行。用于决定分发策略的 hash 表里key 就是数据库。这个策略的并行效果取决于压力模型。如果在主库上有多个 DB并且各个 DB 的压力均衡使用这个策略的效果会很好。 每个 worker 线程对应一个 hash 表用于保存当前正在这个 worker 的“执行队列”里的事务所涉及的表。hash 表的 key 是“库名”value 是一个数字表示队列中有多少个事务修改这个表。 在有事务分配给 worker 时事务里面涉及的表会被加到对应的 hash 表中。worker 执行完成后这个表会被从 hash 表中去掉。图 3 中hash_table_1 表示现在 worker_1 的“待执行事务队列”里有 4 个事务涉及到 db1.t1 表有 1 个事务涉及到 db2.t2 表hash_table_2 表示现在 worker_2 中有一个事务会更新到表 t3 的数据。 优势 构造 hash 值的时候很快只需要库名而且一个实例上 DB 数也不会很多不会出现需要构造 100 万个项这种情况。不要求 binlog 的格式。因为 statement 格式的 binlog 也可以很容易拿到库名。 但是如果你的主库上的表都放在同一个 DB 里面这个策略就没有效果了或者如果不同 DB 的热点不同比如一个是业务逻辑库一个是系统配置库那也起不到并行的效果。 理论上可以创建不同的 DB把相同热度的表均匀分到这些不同的 DB 中强行使用这个策略。不过由于需要特地移动数据这个策略用得并不多 3.2 MariaDB 的并行复制策略 redo log 组提交 (group commit) 优化 MariaDB 的并行复制策略利用的就是这个特性 能够在同一组里提交的事务一定不会修改同一行主库上可以并行执行的事务备库上也一定是可以并行执行的。 在实现上MariaDB 是这么做的 在一组里面一起提交的事务有一个相同的 commit_id下一组就是 commit_id1commit_id 直接写到 binlog 里面传到备库应用的时候相同 commit_id 的事务分发到多个 worker 执行这一组全部执行完成后coordinator 再去取下一批。 这个策略有一个问题它并没有实现“真正的模拟主库并发度”这个目标。在主库上一组事务在 commit 的时候下一组事务是同时处于“执行中”状态的。 如图 5 所示假设了三组事务在主库的执行情况你可以看到在 trx1、trx2 和 trx3 提交的时候trx4、trx5 和 trx6 是在执行的。这样在第一组事务提交完成的时候下一组事务很快就会进入 commit 状态。 图 5 主库并行事务 按照 MariaDB 的并行复制策略备库上的执行效果如图 6 所示。 图 6 MariaDB 并行复制备库并行效果 在备库上执行的时候要等第一组事务完全执行完成后第二组事务才能开始执行这样系统的吞吐量就不够。 另外这个方案很容易被大事务拖后腿。假设 trx2 是一个超大事务那么在备库应用的时候trx1 和 trx3 执行完成后就只能等 trx2 完全执行完成下一组才能开始执行。这段时间只有一个 worker 线程在工作是对资源的浪费。 不过即使如此这个策略仍然是一个很漂亮的创新。因为它对原系统的改造非常少实现也很优雅。 3.3 MySQL 5.7 的并行复制策略 在 MariaDB 并行复制实现之后官方的 MySQL5.7 版本也提供了类似的功能由参数 slave-parallel-type 来控制并行复制策略 配置为 DATABASE表示使用 MySQL 5.6 版本的按库并行策略配置为 LOGICAL_CLOCK表示的就是类似 MariaDB 的策略。不过MySQL 5.7 这个策略针对并行度做了优化。 问题 同时处于“执行状态”的所有事务是不是可以并行 回答 不能。因为这里面可能有由于锁冲突而处于锁等待状态的事务。如果这些事务在备库上被分配到不同的 worker就会出现备库跟主库不一致的情况。 上面提到的 MariaDB 这个策略的核心是“所有处于 commit”状态的事务可以并行。事务处于 commit 状态表示已经通过了锁冲突的检验了。 两阶段提交过程中不用等到 commit 阶段只要能够到达 redo log prepare 阶段就表示事务已经通过锁冲突的检验了。 因此MySQL 5.7 并行复制策略的思想是 同时处于 prepare 状态的事务在备库执行时是可以并行的处于 prepare 状态的事务与处于 commit 状态的事务之间在备库执行时也是可以并行的。 讲 binlog 的组提交的时候介绍过两个参数 binlog_group_commit_sync_delay 参数表示延迟多少微秒后才调用 fsync;binlog_group_commit_sync_no_delay_count 参数表示累积多少次以后才调用 fsync。 这两个参数是用于故意拉长 binlog 从 write 到 fsync 的时间以此减少 binlog 的写盘次数。在 MySQL 5.7 的并行复制策略里它们可以用来制造更多的“同时处于 prepare 阶段的事务”。这样就增加了备库复制的并行度。 也就是说这两个参数既可以“故意”让主库提交得慢些又可以让备库执行得快些。在 MySQL 5.7 处理备库延迟的时候可以考虑调整这两个参数值来达到提升备库复制并发度的目的。 3.4 MySQL 5.7.22 的并行复制策略 基于 WRITESET 的并行复制。 新增了一个参数 binlog-transaction-dependency-tracking用来控制是否启用这个新策略。这个参数的可选值有以下三种。 COMMIT_ORDER表示的就是前面介绍的根据同时进入 prepare 和 commit 来判断是否可以并行的策略。WRITESET表示的是对于事务涉及更新的每一行计算出这一行的 hash 值组成集合 writeset。如果两个事务没有操作相同的行也就是说它们的 writeset 没有交集就可以并行。WRITESET_SESSION是在 WRITESET 的基础上多了一个约束即在主库上同一个线程先后执行的两个事务在备库执行的时候要保证相同的先后顺序。 当然为了唯一标识这个 hash 值是通过“库名 表名 索引名 值”计算出来的。如果一个表上除了有主键索引外还有其他唯一索引那么对于每个唯一索引insert 语句对应的 writeset 就要多增加一个 hash 值。 MySQL 官方的这个实现还是有很大的优势 writeset 是在主库生成后直接写入到 binlog 里面的这样在备库执行的时候不需要解析 binlog 内容event 里的行数据节省了很多计算量不需要把整个事务的 binlog 都扫一遍才能决定分发到哪个 worker更省内存由于备库的分发策略不依赖于 binlog 内容所以 binlog 是 statement 格式也是可以的。 因此MySQL 5.7.22 的并行复制策略在通用性上还是有保证的。 对于“表上没主键”和“外键约束”的场景WRITESET 策略也是没法并行的也会暂时退化为单线程模型。 来自 林晓斌《MySql实战45讲》
http://www.hkea.cn/news/14564180/

相关文章:

  • 网站建设风格有哪些德尔普的网站建设的价格
  • 做网站赚钱吗.red域名做网站好不好
  • 厦门营销网站建设桂林市风尚网络科技有限公司
  • 四川短视频seo优化网站河南建筑材料价格信息网
  • saas建站平台介绍郑州有名的做网页的公司
  • 网站设计厂推荐门户网站建设公司
  • 海南省建设执业中心网站网站建设_网站设计_app制作
  • 免费做计算机题的网站手机麻将软件定制开发
  • 乡土文化网站怎么做戴尔网站建设和维护
  • 公司网站内容更新该怎么做肥城网站建设哪家好
  • 公司的官方网站的作用网站建设合同规范
  • 今天开始做魔王免费观看网站开发公司是什么
  • 网站服务器租用有什么好织梦如何做移动网站
  • 阳光家园广州网站为网站做seo
  • 北京网站优化公司哪里稳定天空在线网站建设
  • nginx 网站开发人才网站的会计账如何做
  • 做设计有哪些接私活的网站长沙市城市建设档案馆网站
  • 哪个网站企业邮箱最好怎么制作一个游戏app
  • 用python做 网站论坛如何在word里做网站
  • 网站开发设计总结上海开发小程序
  • 最大的开源网站天津seo建站
  • 网站建设属于现代服务吗三合一网站一般多少钱
  • 福清网站建设专家xp做网站
  • 宁夏高端网站建设创建自己网站的步骤
  • 校考前做试题的网站培训网站源码wordpress
  • 哪个网站做数学题赚钱宁波建设检测
  • 公司网站SEO优化哪个做得好做外贸学习网站
  • 做婚纱的网站网站程序设置主页面
  • 东莞市建设网站首页设计学分类
  • owasp 网站开发wordpress播放