周五下班前同事要一个权限账号搭建 maxwell,结果导致复制环境不同步。

故障现象

收到报警,当前复制环境复制不同步。看了下报错很诡异

1
2
190801 18:16:04 [ERROR] Slave SQL: Error 'Character set '#45' is not a compiled character set and is not specified in the '/usr/local/mysql/share/charsets/Index.xml' file' on query. Default database: 'maxwell'. Query: 'CREATE DATABASE IF NOT EXISTS `maxwell`', Error_code: 22
190801 18:16:04 [Warning] Slave: Character set '#45' is not a compiled character set and is not specified in the '/usr/local/mysql/share/charsets/Index.xml' file Error_code: 22

 大体看了下是个字符集问题,因为当天急着赶火车,一直没时间好好看这个问题,今天办完事,从火车站直接跑到公司处理下这个故障。

定位

出现这个问题的原因是因为 slave 用了5.1的老版本 mysql,在这个版本中出现了从 master 中携带过来的“意外”字符集,而 slave 这个5.1的版本还没出现这种字符集。去 master 看了下当时的binlog ,确实是,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# at 399078
#190801 18:16:06 server id 11243327 end_log_pos 399183 Query thread_id=86609906 exec_time=0 error_code=0
SET TIMESTAMP=1564654566/*!*/;
SET @@session.sql_mode=2097152/*!*/;
/*!\C utf8mb4 *//*!*/;
SET @@session.character_set_client=45,@@session.collation_connection=45,@@session.collation_server=33/*!*/;
CREATE DATABASE IF NOT EXISTS `maxwell`
/*!*/;
# at 399183
#190801 18:16:06 server id 11243327 end_log_pos 399821 Query thread_id=86609906 exec_time=0 error_code=0
use maxwell/*!*/;
SET TIMESTAMP=1564654566/*!*/;
CREATE TABLE IF NOT EXISTS `schemas` (
id int unsigned auto_increment NOT NULL primary key,
binlog_file varchar(255),
binlog_position int unsigned,
last_heartbeat_read bigint null default 0,
gtid_set varchar(4096),
base_schema_id int unsigned NULL default NULL,
deltas mediumtext charset 'utf8' NULL default NULL,
server_id int unsigned,
position_sha char(40) CHARACTER SET latin1 DEFAULT NULL,
charset varchar(255),
version smallint unsigned not null default 0,
deleted tinyint(1) not null default 0,
UNIQUE KEY `position_sha` (`position_sha`)
)

从 /!\C utf8mb4 //!/;
SET @@session.character_set_client=45,@@session.collation_connection=45,@@session.collation_server=33/!/;

可以看出,客户端字符集被设置成了utf8mb4,而这种字符集在 slave 的 5.1 版本中根本就没有。导致同步失败。

修复

针对这种问题,除了升级 slave 没有其他办法,而我们这个 slave 因为历史原因,难以升级。