Mysql双主架构及其异常

Mysql双主架构及其异常
2022-05-18T10:54:29.211484+08:00 124482968 [ERROR] Slave SQL for channel '': Worker 1 failed executing transaction '284aaa9b-ac5d-11ea-8559-005056814878:1025875055' at master log mysql-bin.001266, end_log_pos 254572627; Column 10 of table 'bi.zmmr0051' cannot be converted from type 'varchar(210(bytes))' to type 'varchar(300(bytes) utf8)', Error_code: 1677

  

1.mysql架构为mysql双主,master-1和master-2分别写入不同的表

2.mysql双主配置文件

[mysqld]#***********base***************basedir=/usr/local/mysqldatadir=/flex/mysql/data/mysql3306/varsocket=/flex/mysql/data/mysql3306/tmp/mysql.sockport=3306server-id=141  //master-1和master-2的server-id应不一样skip-name-resolveskip-slave-startlower_case_table_names=1transaction-isolation=READ-COMMITTEDdefault-time_zone = '+8:00'log_timestamps=SYSTEM##**********connection************max_connections=500max_connect_errors=100000max_user_connections=300####********binlog & relaylog********log-error=/flex/mysql/data/mysql3306/log/mysql.errlog_bin=/flex/mysql/data/mysql3306/var/mysql-binbinlog_cache_size=128kbinlog_stmt_cache_size=128kmax_binlog_cache_size=4Gmax_binlog_stmt_cache_size=4Gbinlog_format=rowexpire_logs_days=7max_binlog_size=500Msql_mode = STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTIONrelay_log_recovery=ONgtid-mode=onenforce-gtid-consistency=onslow_query_log=1slow_query_log_file=/flex/mysql/data/mysql3306/var/slow.loglong_query_time=2log_queries_not_using_indexes=ONlog-bin-trust-function-creators=1###*******character set**************character_set_server=utf8###*******ignore&&define repl database********#replicate-do-db=bireplicate-ignore-db=mysqlreplicate-ignore-db=information_schemareplicate-ignore-db=performance_schema##*************** buffer & timeout ***************innodb_buffer_pool_size=8G###*************** muti thread slave ***************slave_parallel_type =LOGICAL_CLOCKslave_parallel_workers=4master_info_repository=TABLErelay_log_info_repository=TABLEslave_preserve_commit_order     =1##*************** group commit ***************binlog_group_commit_sync_delay              =1binlog_group_commit_sync_no_delay_count     =1000sync_binlog=1innodb_flush_log_at_trx_commit=2###*********** innodb ***************innodb_undo_directory =/flex/mysql/data/mysql3306/var/undoinnodb_undo_log_truncate=oninnodb_max_undo_log_size=1024Minnodb_undo_tablespaces=3autocommit=1default_storage_engine              =InnoDBdefault_tmp_storage_engine          =InnoDBinternal_tmp_disk_storage_engine    =InnoDB###***********slave******************************log-slave-updates=1       //该值决定从库的relaylog是否同时计入binlog,为1是计入,为0是不记录,默认为0,如果从库作为其他数据库的主库应当开启,此参数和-log_bin结合使用,双主架构需设为1log-bin-trust-function-creators=1#[mysql]socket=/flex/mysql/data/mysql3306/tmp/mysql.sock

3.异常现象

开发通过navicate修改某张表的字段属性,由varchar(4) -->varchar(8)

导致异常:看字面意思就是对端节点无法执行type转化,但是实际上对端数据库修改成功

解决

经过了种种方法解决,均为成功,无奈和开发沟通,整库重建主主架构,才解决

2022-05-18T10:54:29.211484+08:00 124482968 [ERROR] Slave SQL for channel '': 
Worker 1 failed executing transaction '284aaa9b-ac5d-11ea-8559-005056814878:1025875055'
at master log mysql-bin.001266, end_log_pos 254572627; Column 10 of table 'bi.zmmr0051'
cannot be converted from type 'varchar(210(bytes))' to type 'varchar(300(bytes) utf8)', Error_code: 1677

4.GTID

此问题引发了我对GTID的又一轮理解,包括一些错误理解

mysql主主架构的同步原理:

1).Master-1 所有数据库变更写进 Binary Log, master-1库线程 Binlog Dump 把 Binary Log 内容发送到master-2库 上(master-2库被动接受数据,不是主动去获取)。
2).master-2 Io 线程读取 Master-1上 Binary Log 日志信息,把接受到的 Binary Log 日志写到本地中继日志 Relay Log
3).Slave Sql 线程读取 Ralay Log 日志内容写入本地数据库实例,并写入本地的binlog
4).binglog采用gtid具有全局唯一性,所以master-1不会二次执行

5.GTID的原理:

5.1 GTID 的概述:
1、全局事物标识:global transaction identifieds。

2、GTID 事物是全局唯一性的,且一个事务对应一个 GTID。

3、一个 GTID 在一个服务器上只执行一次,避免重复执行导致数据混乱或者主从不一致。

4、GTID 用来代替classic的复制方法,不在使用 binlog+pos 开启复制。而是使用 master_auto_postion=1 的方式自动匹配 GTID 断点进行复制。

5、MySQL-5.6.5 开始支持的,MySQL-5.6.10 后开始完善。

6、在传统的 slave 端,binlog 是不用开启的,但是在 GTID 中,slave 端的 binlog 是必须开启的,目的是记录执行过的 GTID(强制);但是从 5.7.5 版本开始无需在 GTID 模式启用参数 log_slave_updates

5.2 GTID 的组成部分:

GTID = source_id:transaction_id

source_id 正常即是 server_uuid,在第一次启动时生成(函数 generate_server_uuid),并持久化到 DATADIR/auto.cnf 文件里。

transaction_id 是顺序化的序列号(sequence number),在每台 MySQL 服务器上都是从 1 开始自增长的序列,是事务的唯一标识。例如:3E11FA47-71CA-11E1-9E33-C80AA9429562:23

GTID 的集合(GTIDs)可以用 source_id+transaction_id 范围表示,例如:3E11FA47-71CA-11E1-9E33-C80AA9429562:1-18

复杂一点的:如果这组 GTIDs 来自不同的 source_id,各组 source_id 之间用逗号分隔;如果事务序号有多个范围区间,各组范围之间用冒号分隔,例如:3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5:11-18,2C256447-3F0D-431B-9A12-575BB20C1507:1-27

5.3 GTID 如何产生
GTID 的生成受 gtid_next 控制

在 Master 上,gtid_next 是默认的 AUTOMATIC,即 GTID 在每次事务提交时自动生成。它从当前已执行的 GTID 集合(即 gtid_executed)中,找一个大于 0 的未使用的最小值作为下个事务 GTID。同时将 GTID 写入到 binlog(set gtid_next 记录),在实际的更新事务记录之前。

在 Slave 上,从 binlog 先读取到主库的 GTID(即 set gtid_next 记录),而后执行的事务采用该 GTID。

5.4 GTID 相关的变量

GTID_EXECUTED#表示已经在该实例上执行过的事务; 执行 RESET MASTER 会将该变量置空; 我们还可以通过设置 GTID_NEXT 在执行一个空事务,来影响 GTID_EXECUTEDGTID_PURGED#已经被删除了 binlog 的事务,它是 GTID_EXECUTED 的子集,只有在 GTID_EXECUTED 为空时才能设置该变量,修改 GTID_PURGED 会同时更新 GTID_EXECUTED 和 GTID_PURGED 的值。GTID_OWNED#表示正在执行的事务的 gtid 以及对应的线程 ID。GTID_NEXT#SESSION 级别变量,表示下一个将被使用的 GTID。

5.5 GTID 的工作原理

master 更新数据时,会在事务前产生 GTID,`一同记录到 binlog 日志中`。slave 端的 i/o 线程将变更的 binlog,写入到本地的 relay log 中,读取值是根据`gitd_next变量`,告诉我们slave下一个执行哪个GTID。sql 线程从 relay log 中获取 GTID,然后对比 slave 端的 binlog 是否有记录。如果有记录,说明该 GTID 的事务已经执行,slave 会忽略。如果没有记录,slave 就会从 relay log 中执行该 GTID 的事务,并记录到 binlog。在解析过程中会判断是否有主键,如果没有二级索引就用全部扫描。

5.6 pos 与 GTID 有什么区别

两者都是日志文件里事件的一个标志,如果将整个 mysql 集群看作一个整体,pos就是局部的,GTID 就是全局的.mysql 节点的集群,一主两从,在 master,slave1,slave2 日志文件里的 pos,都各不相同,就是一个 event,在 master 的日志里,pos 可能是 700,而在 slave1,slave2 里,pos 可能就是 300,400 了,因为众多 slave 也可能不是同时加入集群的,不是从同一个位置进行同步.而 GTID,在 master,slave1,slave2 各自的日志文件里,同一个 event 的 GTID 值都是一样的.

5.7 查看binlog

查看binlog列表

root@localhost : b:34: >show binary logs;+------------------+-----------+| Log_name         | File_size |+------------------+-----------+| mysql-bin.000001 |  15275772 |+------------------+-----------+ 

查看binlog的信息

mysql-bin.000001 15275772 Gtid 141 15275837 SET @@SESSION.GTID_NEXT= '627a78ad-d67f-11ec-8d41-005056a6b4be:31' //GTID
mysql-bin.000001 15275837 Query 141 15275900 BEGIN
mysql-bin.000001 15275900 Table_map 141 15275946 table_id: 111 (bi.t3)
mysql-bin.000001 15275946 Write_rows 141 15275999 table_id: 111 flags: STMT_END_F
mysql-bin.000001 15275999 Xid 141 15276030 COMMIT /* xid=120 */ 

5.8 event是什么

二进制日志的最小记录单位

对于DDL,DCL,一个语句就是一个event

对于DML语句来讲:例如以下列子,就被分为了4个event

begin;

DML1

DML2

commit;

event的组成

开始位置(#at 157)+事件内容+结束位置(下一个#at 890,或者是end_log_pos 890)

 

免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部