当前位置:   article > 正文

Flink CDC 详解 Flink CDC介绍

flink cdc
目录


一、CDC 简介 ?

什么是 CDC ?

CDC 是 Change Data Capture(变更数据获取)的简称。核心思想是,监测并捕获数据库的变动(包括数据或数据表的插入、更新以及删除等),将这些变更按发生的顺序完整记录下来,写入到消息中间件中以供其他服务进行订阅及消费。

CDC 的种类

CDC 主要分为基于查询和基于 Binlog 两种方式,我们主要了解一下这两种之间的区别:

基于查询的 CDC基于 Binlog 的 CDC
开源产品Sqoop、Kafka JDBC SourceCanal、Maxwell、Debezium
执行模式BatchStreaming
是否可以捕获所有数据变化
延迟性高延迟低延迟
是否增加数据库压力

关于 Flink-CDC

Flink 社区开发了 flink-cdc-connectors 组件,这是一个可以直接从 MySQL、PostgreSQL 等数据库直接读取全量数据和增量变更数据的 source 组件。

目前也已开源,开源地址:GitHub - ververica/flink-cdc-connectors: CDC Connectors for Apache Flink®

bin logbinary log,二进制日志文件,也叫作变更日志(update log),是MySQL中比较重要的日志,和运维息息相关。它记录了所有更新数据库的语句(如DDL和 DML语句)并以二进制的形式保存在磁盘中,但是不包含没有修改任何数据的语句(如数据查询语句select、show等)。

bin log是逻辑日志,记录的是执行语句的逻辑,和redisAOP日志类似,会按顺序记录所有涉及更新数据的逻辑操作。

主要作用:

  • 数据恢复:MySQL可以通过bin log恢复某一时刻的误操作的数据,是DBA常打交道的日志。
  • 数据复制:MySQL的数据备份、集群高可用、读写分离都是基于bin log的重放实现的。

bin log的作用

记录格式

binlog日志有三种格式:statementrowmixed,对比如下:

格式含义优点缺点
statement基于SQL语句的复制,记录的是更新数据操作的SQL语句,这些语句同步时会被其他节点执行,如update T set time=NOW() where id = 1;不需要记录数据的变化,减少了bin log文件大小,减少IO负担。SQL中包含了每次执行结果不一致的函数、触发器时,同步数据时会造成不一致。
row基于行的复制,5.1.5版本支持的格式,记录了数据被更改的具体值,如update T set time=1687843346000 where id = 1;日志会清晰记录每条数据被修改的详细情况,保证了数据的一致性。每条数据的更改被详细记录,如整表删除,alter表等操作涉及的数据行都会记录,ROW格式会产生大量日志。
mixed混合模式,5.1.8版本开始,以上两种格式的混合版,对于DDL只对SQL语句进行记录,对DML操作则会进行判断,如果判断会造成主从不一致,就会采用row格式记录,反之则用statement格式记录。既节省空间,又提高数据库性能,保证数据同步时的一致性。无法对误操作数据进行单独恢复。

写入时机

什么时候写bin log?

事务执行过程中,会先把日志写到binlog cache中去,事务提交时,才把binglog cache写到binlog文件中去(刷盘)。binlog cache是为了保证一个事务的所有操作能够一次性写入bin log不被拆开而设置的缓存,binlog cache大小受binlog_cache_size参数控制。

binlog写入时机

上图binlog cache写到bin log日志文件的过程包含了writefsync两步操作:

  • write是把日志写到文件系统缓存中,这一步是系统为了提高文件IO效率;
  • fsync是把数据持久化到日志文件中去。

什么时候执行write和fsync?

写入策略受sync_binlog参数控制,默认0。

sync_binlog=0:表示每次提交事务都只write,由操作系统自行判断什么时候执行fsync

优点:性能提升;

缺点:但是如果机器宕机,page cache里的bin log会丢失。

sync_binlog=0

sync_binlog=N:表示每次提交事务都只write,积攒N个事务后才执行fsync

优点:机器宕机只丢失N个事务的bin log

缺点:如果N设置的很小可能会出现IO瓶颈,需要适当调整N的大小。

sync_binlog=N

两阶段提交

MySQL在执行更新操作的过程中,会记录两种日志:redo logbinlog,都是以事务为单位:

  • redo log是物理日志,记录内容是“在某个数据页上做了什么修改”,属于InnoDB存储引擎层,在事务过程中是不断写入的。
  • bin log 是逻辑日志,记录内容是语句的原始逻辑,属于Server层,只在事务提交时才写入。

redo log和bin log写入时机不同

redo log与bin log会出现什么问题?

对于如下SQL

update T set c = 1 where id = 2;

在执行过程中一直在写redo log,但是当事务提交时,才开始写bin log,如果此时MySQL系统崩溃,bin log还未来得及写入。

redo log与binlog会出现的问题

此时MySQL系统重启发现redo log有记录,主库通过redo log恢复了c值为1,而从库通过bin log同步数据之后c值为2,这就造成了主从数据同步的不一致,这是不允许的。

出现不一致

如何解决

为了解决两份日志之间的逻辑一致问题,InnoDB存储引擎使用两阶段提交方案。

两阶段提交:将redo log的写入操作拆成了两个步骤preparecommit进行,在事务执行期间,写入的redo log标记为prepare阶段,待事务提交且bin log写入成功时,才将redo log标记为commit阶段。

两阶段提交

情况1:写入bin log时发生异常

使用两阶段提交后,写入 bin log时发生异常也不会有影响,因为 MySQL在使用 redo log恢复时,发下 redo log还处于 prepare阶段,而且此时没有 bin log,认为该事务操作尚未完成提交,会回滚此操作。

mysql重启恢复

情况2:redo log在commit阶段发生异常

虽然 MySQL重启后发现 redo log是处于 prepare阶段,但是能通过事务 id找到了对应的 bin log记录,所以 MySQL认为此事务执行是完整的,就会提交事务恢复数据。

redo log在commit阶段发生异常

bin log相关操作

查看日志开启情况

  1. mysql> show variables like'%log_bin%';
  2. +---------------------------------+-------+
  3. | Variable_name | Value |
  4. +---------------------------------+-------+
  5. | log_bin | OFF |
  6. | log_bin_basename | |
  7. | log_bin_index | |
  8. | log_bin_trust_function_creators | OFF |
  9. | log_bin_use_v1_row_events | OFF |
  10. | sql_log_bin | ON |
  11. +---------------------------------+-------+
  12. mysql> show variables like'%log_bin%';
  13. +---------------------------------+----------------------------------------------------------------------+
  14. | Variable_name | Value |
  15. +---------------------------------+----------------------------------------------------------------------+
  16. | log_bin | ON |
  17. | log_bin_basename | C:\ProgramData\MySQL\MySQL Server 8.0\Data\SC-202010081028-bin |
  18. | log_bin_index | C:\ProgramData\MySQL\MySQL Server 8.0\Data\SC-202010081028-bin.index |
  19. | log_bin_trust_function_creators | OFF |
  20. | log_bin_use_v1_row_events | OFF |
  21. | sql_log_bin | ON |
  22. +---------------------------------+----------------------------------------------------------------------+

bin log日志设置

修改MySQL的 my.cnf(linux) 或my.ini(windows)文件可以设置二进制日志的相关参数:

  1. [mysqld]
  2. #启用二进制日志
  3. log-bin=SC-bin
  4. binlog_expire_logs_seconds=600
  5. max_binlog_size=100M

查看日志文件列表和大小

MySQL服务每重新启动一次 ,文件后缀的数字就会+1,如果日志长度超过了  max_binlog_size 的上限(默认是1GB),也会创建一个新的日志文件。
  1. mysql> SHOW BINARY LOGS;
  2. +----------------------------+-----------+-----------+
  3. | Log_name | File_size | Encrypted |
  4. +----------------------------+-----------+-----------+
  5. | SC-202010081028-bin.000634 | 179 | No |
  6. | SC-202010081028-bin.000635 | 156 | No |
  7. +----------------------------+-----------+-----------+

查看bin log记录的默认格式

  1. mysql> show variables like 'binlog_format';
  2. +---------------+-------+
  3. | Variable_name | Value |
  4. +---------------+-------+
  5. | binlog_format | ROW |
  6. +---------------+-------+
  7. 1 row in set (0.05 sec)
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/473048
推荐阅读
相关标签
  

闽ICP备14008679号