当前位置: 首页 > 工具软件 > goInception > 使用案例 >

goinception执行逻辑

翟黎明
2023-12-01
Time                 Id Command    Argument
2021-08-30T00:01:20.435547+08:00	    5 Quit
2021-08-30T00:42:57.625528+08:00	    6 Connect	admin@10.4.45.58 on  using TCP/IP
2021-08-30T00:42:57.625652+08:00	    6 Query	SET NAMES utf8mb4
2021-08-30T00:42:57.625767+08:00	    6 Query	SET autocommit=1
2021-08-30T00:42:57.625957+08:00	    6 Query	show variables like 'log_bin'
2021-08-30T00:42:57.626816+08:00	    7 Connect	ro_query@10.4.45.58 on  using TCP/IP
2021-08-30T00:42:57.626939+08:00	    7 Query	SET NAMES utf8mb4
2021-08-30T00:42:57.627049+08:00	    7 Query	SET autocommit=1
2021-08-30T00:42:57.627287+08:00	    6 Query	show variables where Variable_name in
	('innodb_large_prefix','version','sql_mode','lower_case_table_names','wsrep_on',
	'explicit_defaults_for_timestamp','enforce_gtid_consistency','gtid_mode')
2021-08-30T00:42:57.628055+08:00	    6 Query	show databases like 'sbtest'
2021-08-30T00:42:57.628396+08:00	    6 Query	USE `sbtest`
2021-08-30T00:42:57.628727+08:00	    6 Query	SHOW FULL FIELDS FROM `sbtest`.`t2`
2021-08-30T00:42:57.637130+08:00	    6 Query	SHOW INDEX FROM `sbtest`.`t2`
2021-08-30T00:42:57.637544+08:00	    6 Query	EXPLAIN delete from t2 where id ='2'
2021-08-30T00:42:57.637876+08:00	    6 Query	show variables like 'read_only'
2021-08-30T00:42:57.638399+08:00	    6 Query	show variables like 'log_bin'
2021-08-30T00:42:57.638932+08:00	    6 Query	show variables like 'binlog_format'
2021-08-30T00:42:57.639456+08:00	    6 Query	show variables like 'binlog_row_image'
2021-08-30T00:42:57.640024+08:00	    6 Query	use sbtest
2021-08-30T00:42:57.640184+08:00	    6 Query	select connection_id()
2021-08-30T00:42:57.640353+08:00	    6 Query	SHOW MASTER STATUS
2021-08-30T00:42:57.640612+08:00	    6 Query	delete from t2 where id ='2'
2021-08-30T00:42:57.640862+08:00	    6 Query	SHOW MASTER STATUS
2021-08-30T00:42:57.641080+08:00	    7 Query	create database if not exists inception
2021-08-30T00:42:57.641667+08:00	    7 Query	CREATE TABLE if not exists inception.statistic(id bigint auto_increment primary key, optime timestamp not null default current_timestamp, usedb int not null default 0, deleting int not null default 0, inserting int not null default 0, updating int not null default 0, selecting int not null default 0, altertable int not null default 0, renaming int not null default 0, createindex int not null default 0, dropindex int not null default 0, addcolumn int not null default 0, dropcolumn int not null default 0, changecolumn int not null default 0, alteroption int not null default 0, alterconvert int not null default 0, createtable int not null default 0, droptable int not null default 0, createdb int not null default 0, truncating int not null default 0 )ENGINE INNODB DEFAULT CHARSET UTF8
2021-08-30T00:42:57.644396+08:00	    7 Prepare	INSERT INTO inception.statistic ( usedb, deleting, inserting, updating,
		selecting, altertable, renaming, createindex, dropindex, addcolumn,
		dropcolumn, changecolumn, alteroption, alterconvert,
		createtable, droptable, CREATEDB, truncating)
	VALUES(?, ?, ?, ?, ?,
	       ?, ?, ?, ?, ?,
	       ?, ?, ?, ?, ?,
	       ?, ?, ?)
2021-08-30T00:42:57.644440+08:00	    7 Execute	INSERT INTO inception.statistic ( usedb, deleting, inserting, updating,
		selecting, altertable, renaming, createindex, dropindex, addcolumn,
		dropcolumn, changecolumn, alteroption, alterconvert,
		createtable, droptable, CREATEDB, truncating)
	VALUES(1, 1, 0, 0, 0,
	       0, 0, 0, 0, 0,
	       0, 0, 0, 0, 0,
	       0, 0, 0)
2021-08-30T00:42:57.645052+08:00	    7 Close stmt
2021-08-30T00:42:57.645271+08:00	    7 Query	create database if not exists `10_4_45_58_33071_sbtest`
2021-08-30T00:42:57.645717+08:00	    7 Query	CREATE TABLE if not exists `10_4_45_58_33071_sbtest`.`t2`(id bigint auto_increment primary key, rollback_statement mediumtext, opid_time varchar(50)) ENGINE INNODB DEFAULT CHARSET UTF8MB4
2021-08-30T00:42:57.646525+08:00	    7 Query	CREATE TABLE  `10_4_45_58_33071_sbtest`.`$_$Inception_backup_information$_$`(opid_time varchar(50),start_binlog_file varchar(512),start_binlog_pos int,end_binlog_file varchar(512),end_binlog_pos int,sql_statement mediumtext,host VARCHAR(64),dbname VARCHAR(64),tablename VARCHAR(64),port INT,time TIMESTAMP,type VARCHAR(20),PRIMARY KEY(opid_time))ENGINE INNODB DEFAULT CHARSET UTF8MB4
2021-08-30T00:42:57.647005+08:00	    7 Query	select DATA_TYPE from information_schema.columns
					where table_schema='10_4_45_58_33071_sbtest' and table_name='$_$Inception_backup_information$_$' and column_name='sql_statement'
2021-08-30T00:42:57.647749+08:00	    7 Prepare	insert into `10_4_45_58_33071_sbtest`.`$_$Inception_backup_information$_$` values(?,?,?,?,?,?,?,?,?,?,NOW(),?)
2021-08-30T00:42:57.647805+08:00	    7 Execute	insert into `10_4_45_58_33071_sbtest`.`$_$Inception_backup_information$_$` values('1630255377_6_00000001','','0','','0','delete from t2 where id =\\\'2\\\'','10.4.45.58','sbtest','t2','33071',NOW(),'DELETE')
2021-08-30T00:42:57.648193+08:00	    7 Close stmt
2021-08-30T00:42:57.648319+08:00	    7 Quit
2021-08-30T00:42:57.648389+08:00	    6 Quit

一、审核阶段

  goInception在收到sql语句后,先会解析注释中的远程数据库配置,并建立连接;

  • 如果开启了备份功能,则会检查binlog日志是否开启
  • 判断语法开始位置,必须以 inception_magic_start 语法开始
  • 开始逐行解析,并进行语法树解析,失败时返回
  • 解析到use db,会通过show databases判断数据库是否存在
  • 解析到create table…,接下来进行建表的校验
  • 判断库、表是否存在
  • 表名、列名长度校验,关键字校验
  • 存储引擎校验,表/列的字符集和注释校验
  • 列名重复性校验
  • 自增列个数校验,自增列列名校验,起始值校验
  • 外键校验,分区表校验
  • 列类型校验,部分类型有设置开关,开启后才能使用,char也会建议改为varchar类型
  • 默认值校验,日期格式校验
    not null约束校验
  • 索引名校验,前缀校验,长度校验,表索引个数,索引列数,索引列重复性校验
  • 上面列出了大部分会进行的逻辑校验
  • 解析到insert into table1 …,接下来进行insert的校验
  • 判断表、列是否存在
  • 判断insert列数和值列表是否一致
  • 检查不为null的列,是否指定了null
  • 检查列是否重复指定
  • 如果使用了insert select语法,会审核select语法是否有不存在的表或列
  • 解析到inception_magic_commit,判断所有的审核是否成功,如果有错误时,直接返回,而有警告时会判断是否开启了忽略警告的参数,以判断是否进行下一步

二、执行阶段

  • 只有在审核成功时(或有警告但启用了忽略),才会进入执行阶段
    有些语法是不会执行的,其在审核阶段已经执行,比如desc table;语法
    接下来继续说明执行阶段:

  • 在执行阶段,DDL语句和DML语句走不同的逻辑,其中DML通过binlog解析实现回滚,而DDL语句根据语法树规则直接生成逆向SQL即可

    • DML:在开始执行和执行完成时,记录binlog位置
    • DDL和DML:开始执行,并在执行失败时记录失败原因并结束执行操作,成功时记录受影响行数
  • 执行中可能想要执行KILL以中止执行,可查看 KILL操作说明

三、备份阶段

  • DDL的备份是保存自动生成的逆向SQL语句
  • DML的备份是根据执行前后记录的binlog位置和线程号,模拟从库的形式获取binlog信息,并做事件解析
  • 解析binlog日志要求binlog格式必须为ROW模式,该模式也会有备份前检查和自动设置,因此可能需要SUPER权限
  • 在解析过binlog后,会生成逆向的SQL语句,并异步批量写入备份库
    在回滚语句写入完成后,所有操作执行完成,并返回结果给客户端。
 类似资料: