MySQL · 答疑释惑· lower_case_table_names 使用问题

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 背景 在MySQL中,表是和操作系统中的文件对应的,而文件名在有的操作系统下是区分大小写的(比如linux),有的是不区分大小写(比如Windows),表名与文件名的大小写对应关系,MySQL 是通过 lower_case_table_names 这个变量来控制的。 这个变量的有效取值是0,1,

背景

在MySQL中,表是和操作系统中的文件对应的,而文件名在有的操作系统下是区分大小写的(比如linux),有的是不区分大小写(比如Windows),表名与文件名的大小写对应关系,MySQL 是通过 lower_case_table_names 这个变量来控制的。

这个变量的有效取值是0,1,2,按照官方文档 的解释:

0表示,表在文件系统存储的时候,对应的文件名是按建表时指定的大小写存的,MySQL 内部对表名的比较也是区分大小写的;
1表示,表在文件系统存储的时候,对应的文件名都小写的,MySQL 内部对表名的比较是转成小写的,即不区分大小写;
2表示,表在文件系统存储的时候,对应的文件名是按建表时指定的大小写存的,但是 MySQL 内部对表名的比较是转成小写的,即不区分大小写。

0适用于区分大小写的系统,1都适用,2适用于不区分大小写的系统。

如果在开始使用MySQL选定了一个合适的值后,就不要改变,不然的话在之后使用中就会出现问题。

问题描述

这里给出一个在使用过程中改变 lower_case_table_names 导致 drop database 失败的案例。因为lower_case_table_names是个只读变量,只能在启动时指定参数设置值,或者 gdb 挂上去直接改内存。

首先在启动 mysqld 的时候,指定 lower_case_table_names = 0,我们执行这样的语句:

 

查看对应数据库目录下的表文件:

 

然后重启mysqld,指定 lower_case_table_names =1,执行删除db1

 

可以看到删库语句执行失败,我们再看下数据库目录下的表文件

 

可以看到,大写的 T3 和 T4 表没有被删掉,为什么呢?

问题分析

mysqld 在执行 drop database 操作的时候,是调用 mysql_rm_db 这个函数,在删除时先把db下的所有表都删掉,然后再把db删掉。为了找出对应db下的所有表,mysqld 是通过遍历数据库目录下的文件来做的,具体是用 find_db_tables_and_rm_known_files 这个函数,遍历数据库目录下的所有文件,然后构造出要 drop 的table列表,然而在构造删除列表过程中,会有这样一个判断:

 

意思就是如果lower_case_table_names非0的话,就把 table_name 转成小写的,T3 和 T4 就被转成 t3 和 t4,这样生成的 table_list 中的对应的表是 t1,t2,t3,t4。之后拿着这样的 table_list 通过 mysql_rm_table_no_locks 一个个删表,这样就只把t1,t2 给删了,t3和t4不存在,并且删表时的逻辑是带有 if exists 的,所以也不会报错。

在list表都删除完后,调用rm_dir_w_symlink来删除db目录,此时db1目录下还有 T3 T4 对应的文件,这个函数会调用系统的 rmdir 函数,而当目录非空的时候,rmdir是执行失败的。

所以我们看到最终的错误提示 Error dropping database (can't rmdir './db1', errno: 39)

建议

上面的问题是改变 lower_case_table_names 导致 drop database 失败,其实还有许多其它的因为lower_case_table_names值改变导致的问题,比如主备库本来这个值本来是一致的,如果只改主库的值的话,就会导致备库复制中断,报找不到表的问题,或者本来是不区分大小写的,应用里的写的SQL语句有大写表名,也有小写表名,之后改成区分大小写,就会导致应用出错。

所以建议是:

  • 不要轻易的改变lower_case_table_names的值,如果真要改的话,要先检查下已有的表是否有大小写的问题,保证目前的表名和要改的模式是一致的,比如从区分大小写改为不区分大小写,那就不应该有大写表存在,如果有的话,要先把大写表rename成小写的,如果本来有共存同名的大写表和小写表,就要想办法去掉一个。
  • 应用不要依赖于 mysql 的表名转换机制,应用里的sql语句应该和表名一致,在不区分大小写的时候,应用里对同一个表的使用,不要既有大写表名,也有小写表名。
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
存储 SQL 监控
【七天深入MySQL实战营】答疑汇总Day1 MySQL MGR 8.0 高可用实战
【开营第一课,MySQL MGR 8.0 高可用实战】 讲师:沃趣科技 MySQL DBA张彦东老师。 课程内容:掌握集群架构和数据同步原理;掌握集群性能分析和流量控制;掌握MGR使用场景和常见高可用方案。 答疑汇总:特感谢班委@李敏 同学
|
4月前
|
存储 关系型数据库 MySQL
mysql8卸载重新安装并配置lower_case_table_names=1
mysql8卸载重新安装并配置lower_case_table_names=1
66 0
|
关系型数据库 MySQL Linux
docker安装Mysql8.0的坑之lower_case_table_names
docker安装Mysql8.0的坑之lower_case_table_names
1679 0
docker安装Mysql8.0的坑之lower_case_table_names
|
存储 关系型数据库 MySQL
【MySQL】lower_case_table_names参数详解
简介: lower_case_table_names 是mysql设置大小写是否敏感的一个参数。
840 0
|
存储 SQL AliSQL
【七天深入MySQL实战营】答疑汇总Day7 MySQL分支 - AliSQL 的性能优化实战
【最后一课】【MySQL分支 - AliSQL 的性能优化实战】 讲师:黄忠,阿里云资深技术专家。 课程内容:深入介绍AliSQL的几个核心通用性能优化技术;抽丝剥茧,带你整体学习从问题提出到解决方案落地全过程。 答疑汇总:特别感谢班委@陈亮 同学
|
SQL 监控 Oracle
【七天深入MySQL实战营】答疑汇总Day6 MySQL表和索引优化实战
【开营第六课】【MySQL表和索引优化实战】 讲师:田杰,阿里云高级运维专家。 课程内容:InnoDB表和索引设计最佳实践;索引设计的分析与优化。 答疑汇总:特别感谢班委@李敏 同学
|
SQL 缓存 运维
【七天深入MySQL实战营】答疑汇总Day5 MySQL 开发规约实战
【开营第五课】【MySQL 开发规约实战】 讲师:芦火,阿里云运维专家。 课程内容:SQL语句编写规范;事务的使用与优化;开发中的常见问题与最佳实践。 答疑汇总:特别感谢班委@陈亮 同学
|
SQL 存储 缓存
【七天深入MySQL实战营】答疑汇总Day4 MySQL查询优化实战
【开营第四课】【 MySQL查询优化实战】 讲师:苏坡,袋鼠云高级数据库工程师。 课程内容:核心概念及原理;优化流程思路;常见场景下的优化。 答疑汇总:特别感谢班委@李敏 同学
|
缓存 监控 druid
【七天深入MySQL实战营】答疑汇总Day3 MySQL Java 开发实战
【开营第三课,MySQL Java 开发实战】 讲师:义泊,阿里云技术专家。 课程内容:深入浅出ORM框架MyBatis;连接池框架HikariCP和druid的剖析和最佳实践;Java应用性能问题诊断技巧。 答疑汇总:特别感谢班委@陈亮 同学
|
存储 缓存 NoSQL
【七天深入MySQL实战营】答疑汇总Day2 MySQL 高并发场景实战
【开营第二课,MySQL 高并发场景实战】 讲师: 凌洛,阿里云数据库解决方案专家。 课程内容:高并发场景下MySQL数据库的技术挑战;如何用RDS MySQL支撑高并发业务;高并发场景数据库运维最佳实践。 答疑汇总:特别感谢班委@李敏 同学

相关产品

  • 云数据库 RDS MySQL 版