mysql同步字符集故障处理

mysql同步字符集故障处理
      
       近期发现,我的mysql数据库主从同步停止了,在从机slave status里面发现报告如下错误:

[ERROR] Slave SQL: Column 1 of table 'DB.t_tb' cannot be converted from type 'varchar(180)' to type 'varchar(60)', Internal MariaDB error code: 1677
140912 11:50:57 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'binlog.000031' position 523817727

对此问题,起初我以为是版本bug,利用skip忽略一下问题试试:

stop slave;
SET GLOBAL sql_slave_skip_counter = 1;
start slave;

但过后不久,又会出现如此问题,我就开始怀疑是我主从数据库的设置问题了,肯定是有什么不同的地方,导致的如此错误,后来想到了字符集的问题,进库查看一番:

MariaDB [(none)]> show global variables like '%char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |
| character_set_connection | latin1                     |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | latin1                     |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

MariaDB [(none)]> show variables like '%char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

果不其然,就是字符集的问题。 造成此问题的原因是 我的MariaDB是RPM包安装的,默认字体是latin1,而UTF8中文占用字节是不同的,从而造成以上的错误,下面是通过char_length() 和leng()不同字符集的对照表。


函数 char_length()  length()

char_length 统计字符的个数

CHAR(30)在UTF-8字符集下,最多可以写入几个英文(ASCII码)  -- 30个英文字符
CHAR(30)在UTF-8字符集下,最多可以写入几个中文字符 --- 30个中文字符
CHAR(30),UTF-8字符集,存储了30个汉字,字节数应该是:90个字节
CHAR(30),UTF-8字符集,存储了30个英文,字节数应该是:30个字节
CHAR(30),GBK字符集,存储了30个汉字,字节数应该是:60个字节
CHAR(30),GBK字符集,存储了30个英文,字节数应该是:30个字节
CHAR(30),LATIN1字符集,存储了15个汉字,字节数应该是:30个字节
CHAR(30),LATIN1字符集,存储了30个英文,字节数应该是:30个字节


第一次处理这种问题,心里也没跟,所以在操作之前 mysqldump了一下(建议),这样会比较稳妥。

下面是处理过程:

MariaDB [(none)]> show global variables like '%char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |
| character_set_connection | latin1                     |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | latin1                     |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

MariaDB [(none)]> set global character_set_server='utf8';
Query OK, 0 rows affected (0.02 sec)

MariaDB [(none)]> set global character_set_database='utf8';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> set global character_set_connection='utf8';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> set global character_set_client='utf8';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> set global character_set_results='utf8';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> show global variables like '%char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.01 sec)

全局变量修改好了,下面进入数据库里面去修改:

MariaDB [(none)]> use member
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [member]> show variables like '%char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)


下面是处理语句:

set variables character_set_server='utf8'; 

alter database DB_name default character set utf8; 


处理完毕,进数据库查看,数据一切ok,一直数据库里面没出现乱码的原因是,我在创建数据库的时候,默认使用了UTF8字体,所以一直没出现问题。

以上为动态修改,还有种方法,那就是在mysql的my.cnf里面加上:
character_set_server = utf8
default-character-set = utf8 

加入这种设置,会保证你重启mysql之后不会变回去,不然重启之后有可能还是最初默认的字符集。

对于数据库,字符集也是比较重要的一个环节,rpm安装,yum安装mysql的情况下容易被大家忽略,在此提醒大家每次搭建数据库的时候一定要关注一下。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值