最近有客户从5.7升级到8.0,因为机房迁移到新建了8.0新的小版本时查询的时候报错表不存在;就很疑惑,明明升级到8.0后的版本是正常的,怎么迁移个机房,换个新的8.0小版本怎么就不行了呢,是不是这个8.0的小版本有问题哦?!
虽然很想吐槽,但是问题到底是怎么回事呢?
一、那么问题在哪呢
检查了客户新机房MySQL安装步骤发现,在新机房使用的rpm安装的8.0.33的时候使用的rpm安装的数据库 ,安装步骤如下:
1、rmp 安装mysql
2、使用msyqld 指定datadir初始化实例
3、修改配置文件/etc/my.cnf,增加lower_case_table_names=1配置,并修改datadir等目录及参数配置
4、systemctl 启动mysql实例
发现启动的时候报错lower_case_table_names=1参数和数据字段中元数据为0参数配置不一致导致实例无法启动,怎么会报错呢问题出在哪?
来让我们根据报错看下8.0版本官方关于lower_case_table_names参数的说明:
Command-Line Format --lower-case-table-names[=#]System Variable lower_case_table_namesScope Global Dynamic No SET_VARHint AppliesNo Type Integer Default Value (macOS) 2Default Value (Unix) 0Default Value (Windows) 1Minimum Value 0Maximum Value 2
It is prohibited to start the server with alower_case_table_namessetting that is different from the setting used when the server was initialized. The restriction is necessary because collations used by various data dictionary table fields are determined by the setting defined when the server is initialized, and restarting the server with a different setting would introduce inconsistencies with respect to how identifiers are ordered and compared.
从官方参数说明可以看到lower_case_table_names参数在linux及类unix系统中默认值是0,并且禁止在启动mysql的时候参数配置和初始化时不一致,也就说lower_case_table_names初始化后是无法通过修改配置文件进行修改的,这个地方是和5.7版本最大的区别。
正式这个原因导致了客户mysql实例无法启动,默认的参数0的行为导致了客户参杂了大小写的表名查询时报错表不存在。
二、lower_case_table_names 参数说明
其实官方说的很清楚:
If set to 0, table names are stored as specified and comparisons are case-sensitive. If set to 1, table names are stored in lowercase on disk and comparisons are not case-sensitive. If set to 2, table names are stored as given but compared in lowercase. This option also applies to database names and table aliases.
The default value of this variable is platform-dependent (see
lower_case_file_system). On Linux and other Unix-like systems, the default is0. On Windows the default value is1. On macOS, the default value is2. On Linux (and other Unix-like systems), setting the value to2is not supported; the server forces the value to0instead.You should not set
lower_case_table_namesto 0 if you are running MySQL on a system where the data directory resides on a case-insensitive file system (such as on Windows or macOS). It is an unsupported combination that could result in a hang condition when running anINSERT INTO ... SELECT ... FROMoperation with the wrongtbl_nametbl_namelettercase. WithMyISAM, accessing table names using different lettercases could cause index corruptionAn error message is printed and the server exits if you attempt to start the server with
--lower_case_table_names=0on a case-insensitive file systemThe setting of this variable affects the behavior of replication filtering options with regard to case sensitivity. For more information
如果设置为0,表名按指定方式存储,且比较时区分大小写。如果设置为1,表名在磁盘上以小写形式存储,且比较时不区分大小写。如果设置为2,表名按给定形式存储,但比较时按小写形式进行。此选项也适用于数据库名和表别名。
此变量的默认值取决于平台(请参阅lower_case_file_system)。在Linux和其他类Unix系统上,默认值为0。在Windows上,默认值为1。在macOS上,默认值为2。在Linux(和其他类Unix系统)上,不支持将该值设置为2;服务器会强制将该值设为0。
如果在数据目录所在的文件系统不区分大小写的系统(如Windows或macOS)上运行MySQL,则不应将lower_case_table_names设置为0;该配置无法支持,在使用错误的tbl_name大小写运行INSERT INTO ... SELECT ... FROM tbl_name操作时,可能会导致挂起情况。对于MyISAM,使用不同的大小写访问表名可能会导致索引损坏。
如果您尝试在不区分大小写的文件系统上使用--lower_case_table_names=0启动服务器,将打印一条错误消息,然后服务器退出。
此变量的设置同时会影响复制过滤选项在大小写敏感性方面的行为,在复制进行过滤的配置的时候需要特别注意lower_case_table_names的影响。
所有复制过滤选项遵循与MySQL服务器其他地方数据库和表名相同的大小写敏感规则,包括
lower_case_table_names系统变量的影响。
三、问题如何处理
那么碰到这个问题如何处理呢?
客户这个是机房迁移的测试环境,可以直接重新初始化然后导入数据,在初始化之前先修改配置文件即可。
大家从5.7升级到8.0或者安装8.0及以后的版本时特别要注意lower_case_table_names参数,一定要在初始化之前将配置写入配置文件,否则可能会出现大问题。
如果在生产中碰到怎么办,那肯定是业务测试不充分🤪




