排行
数据库百科
核心案例
行业报告
月度解读
大事记
产业图谱
中国数据库
向量数据库
时序数据库
实时数据库
搜索引擎
空间数据库
图数据库
数据仓库
大调查
2021年报告
2022年报告
年度数据库
2020年openGauss
2021年TiDB
2022年PolarDB
2023年OceanBase
首页
资讯
活动
大会
学习
课程中心
推荐优质内容、热门课程
学习路径
预设学习计划、达成学习目标
知识图谱
综合了解技术体系知识点
课程库
快速筛选、搜索相关课程
视频学习
专业视频分享技术知识
电子文档
快速搜索阅览技术文档
文档
问答
服务
智能助手小墨
关于数据库相关的问题,您都可以问我
数据库巡检平台
脚本采集百余项,在线智能分析总结
SQLRUN
在线数据库即时SQL运行平台
数据库实训平台
实操环境、开箱即用、一键连接
数据库管理服务
汇聚顶级数据库专家,具备多数据库运维能力
数据库百科
核心案例
行业报告
月度解读
大事记
产业图谱
我的订单
登录后可立即获得以下权益
免费培训课程
收藏优质文章
疑难问题解答
下载专业文档
签到免费抽奖
提升成长等级
立即登录
登录
注册
登录
注册
首页
资讯
活动
大会
课程
文档
排行
问答
我的订单
首页
专家团队
智能助手
在线工具
SQLRUN
在线数据库即时SQL运行平台
数据库在线实训平台
实操环境、开箱即用、一键连接
AWR分析
上传AWR报告,查看分析结果
SQL格式化
快速格式化绝大多数SQL语句
SQL审核
审核编写规范,提升执行效率
PLSQL解密
解密超4000字符的PL/SQL语句
OraC函数
查询Oracle C 函数的详细描述
智能助手小墨
关于数据库相关的问题,您都可以问我
精选案例
新闻资讯
云市场
登录后可立即获得以下权益
免费培训课程
收藏优质文章
疑难问题解答
下载专业文档
签到免费抽奖
提升成长等级
立即登录
登录
注册
登录
注册
首页
专家团队
智能助手
精选案例
新闻资讯
云市场
微信扫码
复制链接
新浪微博
分享数说
采集到收藏夹
分享到数说
首页
/
X侦探所事件簿 | MySQL的字符集实现
X侦探所事件簿 | MySQL的字符集实现
腾讯数据库技术
2023-06-01
602
#MySQL#
字符集实现
DATABASE MANAGEMENT
X侦探所事件簿
在前面的文章《X侦探所事件簿系列二 —— 关于字符集的秘密》中我们探索了MySQL字符集在CentOS系统下字符集变量作用和意义。这次,我们以5.7.36版本作为演示版本,探索一下MySQL内部字符集的实现,以此来从内部的视角来看看神秘的MySQL字符集是如何实现的,为源码爱好者提供一个简单的入门级接触。
#
字符集相关系统表
#
首先我们要了解MySQL的两个系统表,这两个表是在information_schema下,保存着charset相关信息的表(实际上在该schema下存在3个和charset相关的表,但记录重要信息的只有两个),他们分别是CHARACTER_SETS和COLLATIONS,前者是用于描述MySQL所支持的字符集及其信息,后者用于描述每个字符集所支持的字符排序规则(collation)。
CHARACTER_SETS
通过描述CHARACTER_SETS的
建
表元信息,我们得到如下相关信息。
其中字段的含义是如下:
这里我们看看一看GB2312这几个字符集在这个表中的内容,其他的字符集读者可以自己探索了解一下。
COLLATIONS
我们再看看COLLATIONS这张表,其定义如下:
其字段的含义如下:
这里我们看看一看GB2312这个字符集在这个表中的保存的内容:
小结
在这,留下一个疑问,为什么GB2312这个字符集,在CHARACTER_SETS有一条记录,在COLLATIONS这张表中有两条记录?
我们期待读者能给出自己的答案。
#
字符集实现代码
#
看完这两张表的定义和表中存储的数据,就可以根据这些信息了解一下MySQL内部的实现。
首先我们要了解的是用于保存字符集信息的结构CHARSET_INFO。
基本结构
在该结构中,保存了MySQL字符集所需的信息,包括charset的名字(诸如
GB
2312等)、charset在MySQL中的编号等。
知道有了CHARSET_INFO保存字符集信息,通过该结构,我们可以发现在这里,MySQL通过all_charsets存储支持的所有字符集(排序规则),通过default_charset_info来保存默认的字符集。
字符集的初始化
如上节找到字符集的存储对象,我们可能需要知道这些对象是如何被初始化的。
因为通过了解初始化的过程可以知道charset的信息来源。
在如下函数中我们可以看到all_charsets变量被初始化为0,那么极有可能在后续的操作中将被初始化为对应的字符集信息。
对该函数内的语句的浏览,我们发现在如下函数
系列
中,有疑似对各个字符集变量的初始化操作。
在该函数中使用各个不同的CHARSET_INFO对象。
在add_compiled_collation函数中将传入的CHARSET_INFO对象初始化到指定all_charsets的数组中的指定位置。
通过如上这三个函数我们知道all_charsets变量的初始化是通过一个个具体的charset对象完成,那么代码看到这里就会有个疑问,类似my_charset_latin1_german2_ci的变量是哪里来初始化的呢?
在进入到strings的源码目录我们会发现如下文件,这些文件中的代码将会提供答案给我们。
探索这些文件就会发现my_charset_latin1_german2_ci是在ctype-latin1.c源码文件中做了初始化变量的操作,这是一个全局变量的初始化。
在这里初始化了字符集名字,字符集排序规则名字(collation name)以及相关的重要信息。
小结
至此,我们介绍了字符集的初始化。
但是,这里会有一个疑问,为什么一个字符集结构CHARSET_INFO要初始化多次?
比如
GB
2312要初始化my_charset_big5_chinese_ci和my_charset_big5_bin两个变量?
这就和前面提到collation有关了(也就是在字符集的系统中小结提到的问题)。
这部分的对应关系我们留给读者自己探索,以期望读者能自己更进一步掌握相关的概念和源码。
连接时的字符集设置
以上讲了字符集在MySQL实例启动的初始化,我们再讲一下MySQL的client在连接时的字符集的问题。
在上图的MySQL通讯协议中,我们可以看到握手消息中有charset的信息,那么我们就从这里作为着手点进行代码的浏览。
首先在parse_client_handshake_packet函数中,我们找到这个charset的读取和使用位置,在41的协议版本下,我们通过读取一个字节的无符号整数得到字符集编码
charset_code
。
然后在定位这里通过charset_code来初始化连接的client charset,以下是对应的函数调用。
最终在这里,通过get_charset获取到字符集信息后,完成连接对象的字符集信息设置。
#
总结
#
至此,我们从外部了解描述MySQL字符集元信息的系统表,从内部介绍了字符集信
息的入门级别源码,这两者可以帮助读者从0基础入门字符集的源码学习。在未来我们会分享更多入门级别的源码帮助揭开MySQL的源码面纱。
-END-
mysql
字符编码
tdsql
源码
初始化
文章转载自
腾讯数据库技术
,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
领墨值
有奖问卷
意见反馈
客服小墨