MySQL操作偶发性乱码问题分析
公司用的MySQL时有保存读取数据乱码现象,该问题在表现上是随机性的发生,感觉上没有特定规律,前一次好的操作下一次执行可能就会有乱码现象了,但是真的是没有规律吗?
于是乎针对这个问题花了一些时间做分析,查看代码,每一次连接数据库后都立马使用set names utf8;操作设置了使用的字符集,每次SQL操作传入的字符串都应该没有问题。
但是乱码问题确实存在在那边,为了尝试使这个问题再现,配合数据库的慢查询日志发现在发生乱码操作的时常伴随着慢查询SQL,猜测会不会是连续好多个SQL,由于某个SQL执行时间过长或操作失败后影响到后面的操作从而产生乱码数据呢?
- 分析猜测
- 验证猜测
使用php连接MySQL数据库后,使用set names utf8 设置数据库使用的字符集,当某个操作失败后会导致set names utf8; 失效,虽然后面的SQL仍然能操作,但是已经没有了set names utf8的设置,导致前后字符集不一致,从而引发乱码现象。
在本机连接mysql -u root -p 连接到数据库,执行set names utf8; 先用select 选一行有中文的数据显示,然后放在那边不动,过n就后,在将这个sql执行一遍,发现
ERROR 2006 (HY000): MySQL server has gone away No connection. Trying to reconnect... Connection id: 289 Current database: xxx
然后选择出来的结果中原先正常显示中文的变为 ???? 了,乱码问题可以再现了。
产生问题的原因就是mysql在丢失数据库链接后会自动重新连接,但是第一次连接设置的set names utf8;就没有了,从而在重连接后的SQL操作使用的字符集不一致,乱码产生。
(为了减少等待时间,可以在my.cnf中设置connect_timeout=5,这样在5秒后就可以看到上面的这个现象)
问题发现了就要解决,php在使用mysql中对mysql的操作做了封装,这样我们在每一次 query 查询之前都先执行一个 set names utf8;命令,保障每一次查询和更新操作都是用的utf8字符集。
希望发现的这个点是产生乱码问题的根本,这么处理后可以解决乱码的问题。
Popularity: 5% [?]