我们都知道使用MySQL客户端来访问MySQL数据库时,会以一定的顺序读取不同位置的配置文件,但在一次做测试时,发现除了按照顺序读取默认的配置文件路径外,MySQL还有额外的读取配置文件的行为。如下是爱可生开源技术社区最近推送的一篇文章《技术分享 | mysql 客户端对配置文件的读取顺序》,就讲了这方面的一些问题,值得借鉴。

一、场景现象

在本地做测试时,发现一个奇怪的现象,当使用socket打算登录数据库,发现不指定用户时,默认并不是用的root用户登录,而是被修改为了bisal用户,

[root@test ~]# mysql -S /data/mysql/3306/data/mysqld.sock -p
Enter password:
ERROR 1045 (28000): Access denied for user 'bisal'@'127.0.0.1' (using password: NO)

通过观测当前MySQL客户端的默认参数行为,可以看到和报错一致,默认用户确实是变为了zhenxing,

[root@test ~]# mysql --help|egrep "user|host|port"-h, --host=name     Connect to host.-P, --port=#        Port number to use for connection or 0 for default to, in-u, --user=name     User for login if not current user.
host                              127.0.0.1
port                              3306
user                              bisal

第一反应是肯定是查看/etc/my.cnf文件中是否对默认用户做了配置,于是查看该配置文件的客户端配置参数,如下,

[client]
host            = 127.0.0.1
user            = root
port            = 3306[mysql]
host            = 127.0.0.1
user            = root
port            = 3306
prompt          = '\U[\d]> '

发现配置文件中的反而配置值是root用户,并没有对bisal用户做配置,看来读取的还不是这个配置文件,那是不是读取了其他配置文件呢,继续排查其他的配置文件。

二、排查思路

1、获取配置文件读取顺序

我们先打印出所有可能读取的配置文件及其读取的顺序做逐个排查,

## 查看mysql客户端读取配置文件的顺序
[root@test ~]# mysql --verbose --help|grep my.cnforder of preference, my.cnf, $MYSQL_TCP_PORT,
/etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf /data/mysql/3306/base/my.cnf ~/.my.cnf

2、排查/etc/my.cnf

/etc/my.cnf 在前面已经确认没有做相关配置,这里直接跳过。

3、排查/etc/mysql/my.cnf

查看/etc/mysql/my.cnf配置,发现不存在相关配置,排除,

[root@test ~]# cat /etc/mysql/my.cnf
cat: /etc/mysql/my.cnf: 没有那个文件或目录

4、排查/usr/local/mysql/etc/my.cnf

查看 /usr/local/mysql/etc/my.cnf 配置,发现不存在相关配置,排除

[root@test ~]# cat /usr/local/mysql/etc/my.cnf
cat: /usr/local/mysql/etc/my.cnf: 没有那个文件或目录

5、排查/data/mysql/3306/base/my.cnf

查看 /data/mysql/3306/base/my.cnf 配置,发现不存在相关配置,排除

[root@test ~]# cat /data/mysql/3306/base/my.cnf
cat: /data/mysql/3306/base/my.cnf: 没有那个文件或目录

6、排查~/.my.cnf

查看 ~/.my.cnf 依旧不存在相关配置,排除

[root@test ~]# cat ~/.my.cnf
cat: /root/.my.cnf: 没有那个文件或目录

至此按照mysql --verbose --help|grep my.cnf获取的配置文件读取路径都被排除,都未对用户bisal做配置。

7、使用no-defaults排除配置文件干扰

尝试用--no-defaults不读取任何配置文件排除配置文件的干扰,看是否会恢复正常,

[root@test ~]# mysql --help|grep no-defaults
--no-defaults           Don't read default options from any option file## 查看不读取配置文件时,客户端的默认值
[root@test ~]# mysql --no-defaults --help|egrep "user|host|port"-h, --host=name     Connect to host.-P, --port=#        Port number to use for connection or 0 for default to, in-u, --user=name     User for login if not current user.
host                              127.0.0.1
port                              3306
user                              bisal## 查看读取的所有客户端配置文件参数设置
[root@test ~]# mysql --print-defaults
mysql would have been started with the following arguments:
--host=127.0.0.1 --user=root --port=3306 --host=127.0.0.1 --user=root --port=3306 --prompt=\U[\d]>  --user=bisal --password=***** --host=127.0.0.1 --port=3306

从上面输出的结果来看,我们可以得到以下几个基本现象:

  • 即使指定--no-defaults不读取任何配置文件,这个user的默认值依旧是bisal用户。

  • 当输出--print-defaults获取实际运行值时,可以看到/etc/my.cnf下的[client],和[mysql]标签下的属性配置从上到下被正确获取。

  • 除了/etc/my.cnf外,在最后还有--user=bisal --password=***** --host=127.0.0.1 --port=3306这4个参数被额外添加到了命令最后。

P.S. MySQL客户端和服务端读取配置的原则都是文件读取从上到下,后面相同参数配置覆盖前面的参数。经过一系列的排除,依旧没找到这个默认值被修改的源头。

8、打印MySQL客户端的系统调用

使用strace直接观测MySQL客户端在执行时到底调用了哪些配置,以下是调用my.cnf相关配置的片段(对结果做了精简输出),

1. stat("/etc/my.cnf", {st_mode=S_IFREG|0644, st_size=195, ...}) = 0      = 3
2. stat("/etc/mysql/my.cnf", 0x7ffd56813180) = -1 ENOENT (No such file or directory)
3. stat("/usr/local/mysql/etc/my.cnf", 0x7ffd56813180) = -1 ENOENT (No such file or directory)
4. stat("/data/mysql/3306/base/my.cnf", 0x7ffd56813180) = -1 ENOENT (No such file or directory)
5. stat("/root/.my.cnf", 0x7ffd56813180)   = -1 ENOENT (No such file or directory)
6. stat("/root/.mylogin.cnf", {st_mode=S_IFREG|0600, st_size=336, ...}) = 0

通过以上调用顺序可以得到以下结论:

  • 1-5行的调用顺序与我们验证的逻辑基本一致。

  • 2-5行显示为No such file or directory与我们的验证结果一致。

  • 第6行输出,增加了一个对/root/.mylogin.cnf的读取操作,并且可以知道当前这个文件是确实存在的。

9、排查 /root/.mylogin.cnf

看到这个文件我们一般都知道,这个是mysql_config_editor工具用来配置login-path的生成的文件,我们可以用以下方式查看当前的配置信息,

[root@test ~]# mysql_config_editor print --all
[client]
user = "bisal"
password = *****
host = "127.0.0.1"
port = 3306

这里可以看到配置中有一个client标签的连接参数配置,配置的内容正好是我们文章开头显示的异常默认值,到这我们基本定位了造成这个奇怪现象的原因,出现这个故障场景的原因是刚好这台是测试环境曾经做过一些mysql_config_editor用法的测试,导致了该现象的发生。

三、场景总结

1、MySQL客户端除了会按照命令mysql --verbose --help|grep my.cnf输出的常规的顺序读取配置外,在最后还会额外的读取.mylogin.cnf文件中配置。

2、即使指定了--no-defaults,依旧会去读取.mylogin.cnf中的[client],[mysql]标签的配置值。

其中官方文档也在以下链接中给到了明确的说明(以下是关键描述片段),

https://dev.mysql.com/doc/refman/8.0/en/option-file-options.html

The mysql client reads [client] and [mysql] from other option files, and [client], [mysql], and [mypath] from the login path file.

Client programs read the login path file even when the --no-defaults option is used. This permits passwords to be specified in a safer way than on the command line even if --no-defaults is present.

个人猜测当时这么设计的目的是考虑如备份脚本等需要连接数据库时,为了防止非必要的参数文件的干扰,在指定了--no-defaults参数后依旧能使用到.mylogin.cnf文件中配置的加密密码,提升安全性。

这案例可能比较特殊,尤其是测到mysql_config_editor场景,但是这种排查问题的逻辑,通过指令"mysql --verbose --help|grep my.cnf",找到本机的默认配置文件顺序,一个个排除,是值得我们学习和借鉴的。

如果您认为这篇文章有些帮助,还请不吝点下文章末尾的"点赞"和"在看",或者直接转发pyq,

近期更新的文章:

《能不能算是PLSQL Developer的锅?》

《通过ASH分析Oracle数据库的历史性能问题》

《应用系统日志打印规范的实践之道》

《一个Oracle添加索引造成其他用户对此表的查询权限丢失的案例》

《你关电脑么?》

近期的热文:

《"红警"游戏开源代码带给我们的震撼》

文章分类和索引:

《公众号1000篇文章分类和索引》

MySQL客户端对配置文件读取顺序的问题场景相关推荐

  1. Mysql配置文件读取顺序

    一.MySQL读取配置文件的顺序 读取顺序:/etc/my.cnf > /etc/mysql/my.cnf > /usr/etc/my.cnf > ~/.my.cnf 命令验证: [ ...

  2. 读取txt原理_Mysql客户端任意文件读取学习

    前言 最近打了 DDCTF和 国赛,发现都考了一个知识点,也就是 MysqlLocalInfile客户端文件读取这个漏洞,下面来详细的学习一个这个漏洞. 漏洞形成原因 此漏洞形成的主要原因在于 LOA ...

  3. MySQL读取配置文件的顺序、启动方式、启动原理

    一.MySQL读取配置文件的顺序 读取顺序:/etc/my.cnf > /etc/mysql/my.cnf > /usr/etc/my.cnf > ~/.my.cnf 命令验证: [ ...

  4. 文件加载顺序_Springboot配置文件存放位置及读取顺序

    Springboot配置文件可以使用yml格式和properties格式,分别命名为application.yml和application.properties 存放目录 Springboot配置文件 ...

  5. php读取配置文件连接mysql数据库,MySQL教程--通过配置文件连接数据库操作详解

    这篇文章主要介绍了mysql 之通过配置文件链接数据库的相关资料,主要是一个单例饿汉式的获得数据库连接方法工具类的实现,需要的朋友可以参考下 mysql 之通过配置文件链接数据库 配置文件jdbc.p ...

  6. mysql 8服务配置文件my.ini 不生效_2、mysql的启动选项和配置文件介绍

    mysql服务端可以指定允许同时接入的客户端数量max-connections.客户端与服务器的通信方式.表的默认存储引擎default_storage_engine等等设置项,使得我们可以更加灵活地 ...

  7. mysql客户端工具_性能优化-理解 MySQL 体系结构(MySQL分库分表)

    实例和数据库 我们通常所说的 MySQL 数据库服务器由一个实例(instance)以及一个数据库(database)组成.实例包括一组后台进程/线程和许多内存结构,用于管理数据库:数据库由一组磁盘文 ...

  8. mysql 客户端_技术分享 | MySQL 客户端连不上(1045 错误)原因全解析

    作者:Carlos Tutte.Marcos Albe 翻译:管长龙 在我们学习 MySQL 或从事 MySQL DBA 工作期间,时常会遇到:"我尝试连接到 MySQL 并且收到1045 ...

  9. mysql客户端路由方式_20.3 在InnoDB 集群中 使用MySQL 路由

    本节介绍如何使用带有InnoDB集群的MySQL路由器来实现高可用性. 无论您是否部署了sanbox或生产群集,MySQL路由器都可以使用--bootstrap选项根据InnoDB群集的元数据进行自我 ...

最新文章

  1. 【直播回放】如何准备计算机视觉的面试?
  2. 使用application log 分析navigation target解析错误
  3. 字符串匹配的KMP算法(转)
  4. sparseTM的公式理解
  5. [HDU4635] Strongly connected
  6. Android Studio 报 非法字符: ‘\ufeff‘解决
  7. 如何通过VISIO来画网络拓扑图
  8. 一份完整的数据分析师成长书单
  9. 基于51单片机的秒表设计
  10. 从汉语与英语最常用字词,分析汉语与英语的异同(一)
  11. php的rsa密匙长度,PHP解决RSA公私密钥换行处理
  12. MAC上VSCode无Git源代码管理的解决办法
  13. Matplotlib绘制箱线图
  14. 电脑计算机软件硬盘不足,电脑提示磁盘空间不足怎么办
  15. 支付宝沙箱登录授权-应用签名失败
  16. win11系统前端IIS部署发布网站步骤
  17. 大气压随温度变化表_大气压与温度的关系
  18. 使用python 实现 微信好友 个性签名 并 制作 词云图
  19. wxpython动态实时绘图_wxPython 画图板
  20. 技术分享连载(八十七)

热门文章

  1. Sublime text3 + Verilator 实现自动语法检错
  2. 网站提交谷歌站长工具验证操作流程
  3. echarts.js实现雷达图
  4. java打印星型_使用java打印心型、圆形图案的实现代码
  5. 安卓令微软如坐针毡 WP8改进不断
  6. linux, sysrq,acpi,apci,uio,subsystem daemon
  7. 中学理化生实验考试考评系统(理化生实验考评教室)解决方案
  8. 【ACWing】665. 倍数
  9. 利用ref获取遍历出的元素或者组件,ref,:ref
  10. 潍坊美丽街景智慧公厕,诠释智慧城市的公共厕所如何建设 | 中期科技ZONTREE智慧公厕@快讯