1. 问题描述

今天有一台服务器运行Rails项目遇到MySQL报错Character set ‘utf8mb4’ is not a compiled character set and is not specified in the ‘/usr/share/mysql/charsets/Index.xml’ file

详细异常如下:

[[email protected] production]$ rails c
:linux
Character set 'utf8mb4' is not a compiled character set and is not specified in the '/usr/share/mysql/charsets/Index.xml' file
/home/blogbin/.rvm/gems/[email protected]/gems/mysql2-0.3.20/lib/mysql2/client.rb:70:in `connect': Can't initialize character set utf8mb4 (path: /usr/share/mysql/charsets/) (Mysql2::Error)
	from /home/blogbin/.rvm/gems/[email protected]/gems/mysql2-0.3.20/lib/mysql2/client.rb:70:in `initialize'
....

2. 分析过程

Google搜索异常信息,网上建议有两种解决方案:

按以上两种方案处理后,问题依旧没有解决,还是出现同样的错误。

同样Rails项目代码运行在另外一台服务器s3-blogbins,可以正常运行。

这两台服务器先后安装过多个MySQL版本,5.1.x,5.5.x都有。

仔细思考后,感觉问题还是出在mysql2 gem依赖的MySQL软件包版本过低。

最终发现s1-blogbins的mysql2使用MySQL仍为5.1.x( /usr/lib64/mysql)

检查过程如下:

# 确定mysql2安装目录
[[email protected] production]$ bundle show mysql2
:linux
/home/blogbin/.rvm/gems/[email protected]/gems/mysql2-0.3.20
[[email protected] production]$

# 检查mysql2使用MySQL目录
[[email protected] production]$ cat /home/blogbin/.rvm/gems/[email protected]/gems/mysql2-0.3.20/ext/mysql2/Makefile | grep LIBRUBYARG_SHARED
LIBRUBYARG_SHARED = -Wl,-R -Wl,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)
LIBS = $(LIBRUBYARG_SHARED) -L/usr/lib64/mysql -lmysqlclient -lpthread -lm -lrt -ldl  -lpthread -lrt -ldl -lcrypt -lm   -lc

# 检查MySQL版本
[[email protected] production]$ /usr/lib64/mysql/mysql_config --version
5.1.73

3. 解决过程

# 卸载mysql2 gem所有版本
[[email protected] production]$ gem uninstall mysql2

# 强制bundle install mysql2使用正确的MySQL本/usr/local/mysql/bin/mysql_config
# 参见https://github.com/brianmario/mysql2#configuration-options
# https://coderwall.com/p/7v4wbw/bundle-config-passing-parameters-to-your-gems-installation
[[email protected] production]$ bundle config build.mysql2 --with-mysql-config=/usr/local/mysql/bin/mysql_config

# 运行bundle重新安装mysql2 gem
[[email protected] production]$ bundle

# 最后检查mysql2 gem是否正确依赖/usr/local/lib/mysql
[[email protected] production]$ cat /home/blogbin/.rvm/gems/[email protected]/gems/mysql2-0.3.20/ext/mysql2/Makefile | grep LIBRUBYARG_SHARED
LIBRUBYARG_SHARED = -Wl,-R -Wl,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)
LIBS = $(LIBRUBYARG_SHARED) -L/usr/local/lib/mysql -lmysqlclient -lpthread -lm -lrt -ldl  -lpthread -lrt -ldl -lcrypt -lm   -lc

重新运行rails项目,可以正常启动。

References

brianmario/mysql2: A modern, simple and very fast Mysql library for Ruby – binding to libmysql
https://github.com/brianmario/mysql2

阿里云 Rails 项目调整 RDS MySQL 编码为 utf8mb4 的详细步骤 · Ruby China
https://ruby-china.org/topics/24693

Character set ‘utf8mb4’ is not a compiled character set – 乐沙弥的世界 – CSDN博客
http://blog.csdn.net/leshami/article/details/42024217

ruby on rails – How can I pass a parameter for gem installation when I run bundle install? – Stack Overflow
https://stackoverflow.com/questions/5167829/how-can-i-pass-a-parameter-for-gem-installation-when-i-run-bundle-install/5167881

Bundle config: Passing parameters to your gems installation (Example)
https://coderwall.com/p/7v4wbw/bundle-config-passing-parameters-to-your-gems-installation

打赏

Leave a Reply

Your email address will not be published. Required fields are marked *