为啥阿里巴巴不建议MySQL使用Text类型?( 四 )

可以看到主要耗时在updating这一步,IO输出次数16392次,在并发的表上通过id做update,也会变得很慢 。
group_concat也会导致查询报错在业务开发当中,经常有类似这样的需求,需要根据每个省份可以定点医保单位名称,通常实现如下:
select group_concat(dru_name) from t_drugstore group by province;其中内置group_concat返回一个聚合的string,最大长度由参数group_concat_max_len(Maximum allowed result length in bytes for the GROUP_CONCAT())决定,默认是1024,一般都太短了,开发要求改长一点,例如1024000 。
当group_concat返回的结果集的大小超过max_allowed_packet限制的时候,程序会报错,这一点要额外注意 。
MySQL内置的log表MySQL中的日志表mysql.general_log和mysql.slow_log,如果开启审计audit功能,同时log_output=TABLE,就会有mysql.audit_log表,结构跟mysql.general_log大同小异 。
分别看一下他们的表结构
CREATE TABLE `general_log` (`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),`user_host` mediumtext NOT NULL,`thread_id` bigint(21) unsigned NOT NULL,`server_id` int(10) unsigned NOT NULL,`command_type` varchar(64) NOT NULL,`argument` mediumblob NOT NULL) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log'CREATE TABLE `slow_log` (`start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),`user_host` mediumtext NOT NULL,`query_time` time(6) NOT NULL,`lock_time` time(6) NOT NULL,`rows_sent` int(11) NOT NULL,`rows_examined` int(11) NOT NULL,`db` varchar(512) NOT NULL,`last_insert_id` int(11) NOT NULL,`insert_id` int(11) NOT NULL,`server_id` int(10) unsigned NOT NULL,`sql_text` mediumblob NOT NULL,`thread_id` bigint(21) unsigned NOT NULL) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='Slow log'mysql.general_log记录的是经过MySQL Server处理的所有的SQL,包括后端和用户的,insert比较频繁,同时argument mediumblob NOT NULL,对MySQL Server性能有影响的,一般我们在dev环境为了跟踪排查问题,可以开启general_log,Production环境禁止开启general_log,可以开启audit_log,它是在general_log的基础上做了一些filter,比如我只需要业务账号发起的所有的SQL,这个很有用的,很多时候需要分析某一段时间内哪个SQL的QPS,TPS比较高 。
mysql.slow_log记录的是执行超过long_query_time的所有SQL,如果遵循MySQL开发规范,slow query不会太多,但是开启了log_queries_not_using_indexes=ON就会有好多full table scan的SQL被记录,这时slow_log表会很大,对于RDS来说,一般只保留一天的数据,在频繁insert into slow_log的时候,做truncate table slow_log去清理slow_log会导致MDL,影响MySQL稳定性 。
建议将log_output=FILE,开启slow_log, audit_log,这样就会将slow_log,audit_log写入文件,通过Go API处理这些文件将数据写入分布式列式数据库clickhouse中做统计分析 。
Text改造建议使用es存储在MySQL中,一般log表会存储text类型保存request或response类的数据,用于接口调用失败时去手动排查问题,使用频繁的很低 。可以考虑写入本地log file,通过filebeat抽取到es中,按天索引,根据数据保留策略进行清理 。
使用对象存储有些业务场景表用到TEXT,BLOB类型,存储的一些图片信息,比如商品的图片,更新频率比较低,可以考虑使用对象存储,例如阿里云的OSS,AWS的S3都可以,能够方便且高效的实现这类需求 。
总结由于MySQL是单进程多线程模型,一个SQL语句无法利用多个cpu core去执行,这也就决定了MySQL比较适合OLTP(特点:大量用户访问、逻辑读,索引扫描,返回少量数据,SQL简单)业务系统,同时要针对MySQL去制定一些建模规范和开发规范,尽量避免使用Text类型,它不但消耗大量的网络和IO带宽,同时在该表上的DML操作都会变得很慢 。
另外建议将复杂的统计分析类的SQL,建议迁移到实时数仓OLAP中,例如目前使用比较多的clickhouse,里云的ADB,AWS的Redshift都可以,做到OLTP和OLAP类业务SQL分离,保证业务系统的稳定性 。

【为啥阿里巴巴不建议MySQL使用Text类型?】


推荐阅读