前言
小伙伴们好,我是阿沐!最近呢,正筹备上云工作,需要考虑到很多场景;比如mongo、mysql、redis、splinx等等迁移工作,这就涉及到版本兼容问题;在迁移之前,阿沐迁移了mysql到其他容器中,发现迁移机器mysql版本号比较高5.7以上,就出现了sql语句兼容问题。所以趁机会整理了很久以前遇到的各种mysql常见问题跟掘金小伙伴们分享下。小伙伴们可以收藏起来哦,遇到常规错误可以快速查询解决~~~
1、localhost上的mysql无法连接
报错代码:
代码语言:javascript复制ERROR 2003 (HY000):Can’t connect to MySQL server on 'localhost' (10061)
报错原因:
代码语言:javascript复制① 很明显,localhost本机是存在的;但是它却没有提供mysql的服务供给使用
② 检查磁盘空间是否还有剩余可用空间,尽量保持有足够的磁盘空间可用
③ 查看mysql的负载能力,可能存在mysql的负载过高我们连接不上;一般是看processlist来看下具体线程和连接数运行情况:
1、show processlist只能列出当前100条,我们可以看到所有用户的连接情况
mysql> show processlist;
---- ----------------- ----------- ------ --------- ------- ------------------------ ------------------
| Id | User | Host | db | Command | Time | State | Info |
---- ----------------- ----------- ------ --------- ------- ------------------------ ------------------
| 4 | event_scheduler | localhost | NULL | Daemon | 30404 | Waiting on empty queue | NULL |
| 14 | root | localhost | NULL | Query | 0 | starting | show processlist |
---- ----------------- ----------- ------ --------- ------- ------------------------ ------------------
2 rows in set (0.00 sec)
2、查看全部的链接情况
mysql> show full processlist;
---- ----------------- ----------- ------ --------- ------- ------------------------ -----------------------
| Id | User | Host | db | Command | Time | State | Info |
---- ----------------- ----------- ------ --------- ------- ------------------------ -----------------------
| 4 | event_scheduler | localhost | NULL | Daemon | 30527 | Waiting on empty queue | NULL |
| 14 | root | localhost | NULL | Query | 0 | starting | show full processlist |
---- ----------------- ----------- ------ --------- ------- ------------------------ -----------------------
2 rows in set (0.00 sec)
# 注意,针对以上查看结果进行详细字段说明:
① Id 当用户登录mysql时,系统会为用户分配一个"connection_id",可以使用函数connection_id()来查看:
mysql> select connection_id();
-----------------
| connection_id() |
-----------------
| 14 | -- 系统分配的id为14
-----------------
1 row in set (0.01 sec)
② User 展示当前链接用户
③ Host 连接mysql的ip地址;可查到来源端口,同时可以跟踪出现问题语句的用户
④ db 连接数据库的名称
⑤ Command 当前链接执行的命令;query(查询)、sleep(休眠)、connect(连接)、daemon(守护进程)
⑥ Time 当前连接持续时长,单位时间是秒
⑦ State 展示当前连接的sql语句状态
⑧ Info 展示sql语句,对用来判断sql语句是否有问题很重要
问题解决方案:
代码语言:javascript复制① mysql未启动,则启动即可:
mac端:brew services start mysql mysql.server start
centos端: systemctl start mysqld.service service mysql start
其他:找到执行文件根目录执行 启动也ok
2、localhost/IP地址连接不上
报错代码:
代码语言:javascript复制➜ ~ mysql -uroot -p
Enter password:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
报错原因:
代码语言:javascript复制① 概述:用户root访问localhost/IP被拒绝访问
② 一般是数据库的用户名或者密码跟服务器上mysql设置的不一致,导致匹配失败
问题解决方案:
代码语言:javascript复制# 注意解决步骤:
① 查看mysql配置文件
② 查看 mysql 配置文件加载顺序
③ 修改配置文件跳过权限验证(skip-grant-tables)
④ 登录mysql客户端修改密码
注意mac版本方案:
① 查看mysql运行情况,看看在哪里
代码语言:javascript复制➜ ~ ps aux | grep mysql -- 查看mysql的运行进程 可以看到启动地址
amu 15262 0.0 4.9 4899000 407680 ?? S 1:14下午 0:01.18 /usr/local/opt/mysql/bin/mysqld
--basedir=/usr/local/opt/mysql
--datadir=/usr/local/var/mysql
--plugin-dir=/usr/local/opt/mysql/lib/plugin
--log-error=liyangyang.local.err
--pid-file=liyangyang.local.pid
--socket=/tmp/mysql.sock
② 查看mysql配置文件加载情况:
代码语言:javascript复制➜ ~ /usr/local/opt/mysql/bin/mysqld --verbose --help | grep -A 1 'Default options'
Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf /usr/local/etc/my.cnf ~/.my.cnf
# 概述:
① 服务器首先读取的是 /etc/my.cnf文件
② 如果前一个文件不存在则继续读/etc/mysql/my.cnf文件,依此类推往下寻找,一直到最后一个~/.my.cnf文件
③ 如果以上所有文件都不存在;则说明安装mysql之后未进行配置文件;可以自己编辑一份名为my.cnf;修改文件拥有者和所属组且赋予可执行权限即可
① mkdir /usr/local/mysql/etc
② vim /usr/local/mysql/etc/my.cnf -- 内容可以复制一份本地的配置文件即可
③ chown -R root:root /usr/local/mysql/etc/
④ chmod 755 /usr/local/mysql/etc/my.cnf
③ 查看mysql读取配置文件方法:
代码语言:javascript复制## 查看是否使用了指定目录的my.cnf
➜ ~ ps aux | grep mysql | grep 'my.cnf'
## 查看mysql默认读取my.cnf的目录
➜ ~ mysql --help | grep 'my.cnf'
order of preference, my.cnf, $MYSQL_TCP_PORT,
/etc/my.cnf /etc/mysql/my.cnf /usr/local/etc/my.cnf ~/.my.cnf
这些就是mysql默认会搜寻my.cnf的目录,顺序排前的优先;等同于上面搜索语句
④ 免密码登录并修改密码
代码语言:javascript复制### mysql 5.8版本之前的修改方法:
① 在mysql配置文件中,[mysqld]下添加一行,使其登录时跳过权限检查
[mysqld]
skip_grant_tables
② 重启mysql服务;登录mysql -uroot -p
### mysql5.8版本之后修改方法:
① 执行目录下执行,例如我本地运行地址:
/usr/local/opt/mysql/bin/mysqld -console --skip-grant-tables --shared-memory
② 新开启一个窗口:mysqld -uroot -p 直接回车(大家可以升级版本测试下)
### 以上操作完毕后 进度mysql终端,修改密码:
set password for root@localhost = '新密码';
或者
update user set authentication_string='新密码' where user='root';
或者
alter user 'root'@'localhost' identified with mysql_native_password by '新密码';
### 注意:刷新mysql相关权限
flush privileges;
### 最终流程:
mysql> update user set authentication_string='root' where user='root';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> set password for root@localhost = 'root';
Query OK, 0 rows affected (0.02 sec)
mysql> alter user 'root'@'localhost' identified with mysql_native_password by 'root';
Query OK, 0 rows affected (0.01 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
mysql> exit
Bye
此时再登录时我们的密码已经更新为root
3、无法连接mysql服务器
报错代码:
代码语言:javascript复制➜ ~ mysql -uroot -p
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
报错原因:
代码语言:javascript复制① mysql服务器没有开启
② mysql服务器开启了,但不能找到 socket 文件
概述mysql的连接方式:
代码语言:javascript复制mysql的登陆方式有两种,分别是socket和tcp/ip方式登陆
### socket(套接字)连接方式:
只能在mysql客户端和数据库实例在同一台服务器上的情况下使用(本地连接);
通常连接localhost是通过一个Unix域套接字文件进行,一般是/tmp/mysql.sock;
若套接字文件被删除了,本地客户就不能再连接了
### 登录实例后查询
mysql> show variables like 'socket';
--------------- -----------------
| Variable_name | Value |
--------------- -----------------
| socket | /tmp/mysql.sock |
--------------- -----------------
1 row in set (0.04 sec)
### 当然我们也可以通过socket文件登录数据库
➜ ~ mysql -uroot -proot -S /tmp/mysql.sock -- 用户名 密码 Socket文件路径地址(可不带默认)
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or g.
............. 省略部分
#### 注意事项:
mysql.sock必须是mysql中配置的文件且必须在/tmp下存在;若不存在则启动不了mysql
### TCP/IP连接方式:
➜ ~ mysql -uroot -proot -h 127.0.0.1 -- 用户名 密码 ip:port
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or g.
............. 省略部分
#### 说明概述
若通过tcp/ip地址连接mysql;它将先检查权限视图表,检测请求方的ip是否允许被连接
mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select host, user from user;
----------- ------------------
| host | user |
----------- ------------------
| localhost | mysql.infoschema |
| localhost | mysql.session |
| localhost | mysql.sys |
| localhost | root |
----------- ------------------
4 rows in set (0.00 sec)
① host 表示该用户只能通过localhost的ip访问此数据库
② host:% 表示任何ip都可以连接mysql实例
问题解决方案:
代码语言:javascript复制① 修改配置文件增加socket路径
➜ ~ vim /usr/local/etc/my.cnf
[mysqld]
socket=/tmp/mysql.sock
② 使用软连接将已经存在的mysql.sock软链到/tmp/mysql.sock
ln -s /usr/local/xxx/mysql.sock /tmp/mysql.sock
③ 最最最暴力解决方案;卸载mysql,mysql相关的全部删除;为了实践演示我本机mac删除卸载重装