MySQL远程访问配置与常见问题解决指南

 更新时间:2026年04月28日 09:24:30   作者:code bean  
本文记录了一次MySQL远程连接过程中遇到的坑及其解决方案,主要包括基础命令行操作、远程访问配置、认证插件不兼容、IP被拉黑等问题,提出了解决方案,需要的朋友可以参考下

本文记录了一次完整的 MySQL 远程连接踩坑过程,涵盖基础命令行操作、认证插件报错、IP 被拉黑等问题及解决方案。

一、MySQL 基础命令行操作

1.1 登录与退出

# 本地登录(默认走 localhost)
mysql -u root -p
# 指定 IP 登录(走网络连接)
mysql -h 192.168.1.100 -u root -p
# 指定端口
mysql -h 192.168.1.100 -P 3306 -u root -p
# 退出
exit;
-- 或
quit;

1.2 用户管理

-- 查看所有用户
SELECT User, Host, plugin FROM mysql.user;
-- 创建本地用户
CREATE USER 'alice'@'localhost' IDENTIFIED BY '密码';
-- 创建远程用户(允许任意 IP)
CREATE USER 'bob'@'%' IDENTIFIED BY '密码';
-- 创建远程用户(只允许特定 IP)
CREATE USER 'charlie'@'192.168.1.50' IDENTIFIED BY '密码';
-- 修改密码
ALTER USER 'bob'@'%' IDENTIFIED BY '新密码';
-- 删除用户
DROP USER 'bob'@'%';
-- 刷新权限(修改后必须执行)
FLUSH PRIVILEGES;

1.3 权限管理

-- 授予所有权限
GRANT ALL PRIVILEGES ON *.* TO 'bob'@'%';

-- 授予特定数据库权限
GRANT ALL PRIVILEGES ON mydb.* TO 'bob'@'%';

-- 授予只读权限
GRANT SELECT ON mydb.* TO 'readonly'@'%';

-- 撤销权限
REVOKE ALL PRIVILEGES ON *.* FROM 'bob'@'%';

-- 查看用户权限
SHOW GRANTS FOR 'bob'@'%';

1.4 数据库与表操作

-- 创建数据库
CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 查看所有数据库
SHOW DATABASES;

-- 切换数据库
USE mydb;

-- 创建表
CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    email VARCHAR(100) UNIQUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 查看表结构
DESC users;
-- 或
SHOW CREATE TABLE users;

-- 插入数据
INSERT INTO users (name, email) VALUES ('张三', 'zhangsan@example.com');

-- 查询
SELECT * FROM users WHERE name LIKE '%张%';

-- 更新
UPDATE users SET email = 'new@example.com' WHERE id = 1;

-- 删除
DELETE FROM users WHERE id = 1;

1.5 服务管理(Linux)

# 启动
sudo systemctl start mysql
# 停止
sudo systemctl stop mysql
# 重启
sudo systemctl restart mysql
# 查看状态
sudo systemctl status mysql

二、远程访问配置

2.1 服务端配置

编辑 MySQL 配置文件:

  • Linux: /etc/mysql/mysql.conf.d/mysqld.cnf/etc/my.cnf
  • Windows: my.ini
# 允许所有网卡监听(默认 127.0.0.1 只监听本地)
bind-address = 0.0.0.0
# 或注释掉该行
# bind-address = 127.0.0.1

重启生效:

sudo systemctl restart mysql

2.2 防火墙放行

# UFW (Ubuntu/Debian)
sudo ufw allow 3306/tcp
# firewalld (CentOS/RHEL)
sudo firewall-cmd --permanent --add-port=3306/tcp
sudo firewall-cmd --reload
# 云服务器还需在安全组中放行 3306 端口

2.3 用户授权

-- 创建远程专用用户(推荐)
CREATE USER 'remote_user'@'%' IDENTIFIED BY '强密码';
GRANT ALL PRIVILEGES ON mydb.* TO 'remote_user'@'%';
FLUSH PRIVILEGES;

三、踩坑实录:认证插件与 IP 拉黑

3.1 环境背景

  • 服务端: MySQL 8.0(Linux 服务器)
  • 客户端: Windows C++ 程序,使用较老的 MySQL C API 库
  • 连接方式: mysql_real_connect(conn, "10.136.11.246", "root", ...)

3.2 第一坑:IP 被拉黑

报错信息:

mysql_real_connect failed: Host '10.136.26.183' is blocked because of many connection errors;
unblock with 'mysqladmin flush-hosts'

原因分析:
MySQL 有安全机制,当某个 IP 连续多次连接失败(默认阈值 100 次),会自动将该 IP 加入黑名单,防止暴力 破解。

解决方法:

# 服务端执行,清空黑名单
mysqladmin flush-hosts

或登录 MySQL 后:

FLUSH HOSTS;

3.3 第二坑:认证插件不兼容

报错信息:

mysql_real_connect failed: Authentication plugin 'caching_sha2_password' cannot be loaded: 找不到指定的模块。

原因分析:
MySQL 8.0 默认使用 caching_sha2_password 认证插件,但客户端(C++ 的 MySQL 库)版本太老,不支持这个插件。

根本区别:

MySQL 版本默认认证插件兼容性
5.7 及以前mysql_native_password老客户端都支持
8.0+caching_sha2_password需要新版客户端库

3.4 第三坑:ALTER USER 报错

报错信息:

ERROR 1396 (HY000): Operation ALTER USER failed for 'root'@'10.136.11.246'

原因分析:
MySQL 的用户是 用户名 + Host 的组合。查询发现系统中只有:

SELECT User, Host FROM mysql.user;

结果:

+------+-----------+
| User | Host      |
+------+-----------+
| root | %         |
| root | localhost |
+------+-----------+

'root'@'10.136.11.246' 这个用户根本不存在!

MySQL 用户匹配规则:

Host 值含义
localhost只允许本机 socket 连接
127.0.0.1只允许本机 TCP 连接
192.168.1.%允许该网段
10.136.11.246只允许该特定 IP
%允许任意 IP(最宽松)

注意localhost10.136.11.246

  • localhost127.0.0.1,不经过网卡
  • 10.136.11.246 是服务器的实际网卡 IP,走网络协议

四、完整解决过程

步骤 1:确认现有用户

SELECT User, Host, plugin FROM mysql.user WHERE User = 'root';

确认有 'root'@'%' 存在。

步骤 2:修改认证插件(服务端执行)

-- 修改已存在的 'root'@'%' 用户
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '你的密码';
FLUSH PRIVILEGES;

步骤 3:验证修改结果

SELECT User, Host, plugin FROM mysql.user WHERE User = 'root';

确认 'root'@'%'plugin 变为 mysql_native_password

步骤 4:清空 IP 黑名单

FLUSH HOSTS;

步骤 5:客户端连接测试

C++ 代码:

#include <mysql.h>
MYSQL* conn = mysql_init(nullptr);
if (!mysql_real_connect(conn, 
                        "10.136.11.246",  // 服务器 IP
                        "root",           // 用户名
                        "你的密码",        // 密码
                        "数据库名",        // 数据库
                        3306,             // 端口
                        nullptr, 0)) {
    printf("连接失败: %s\n", mysql_error(conn));
} else {
    printf("连接成功!\n");
}
mysql_close(conn);

五、其他解决方案对比

方案 A:改服务端认证方式(本文采用)

优点:客户端不用改,快速解决
缺点:安全性略降,新特性无法使用

-- 改单个用户
ALTER USER 'user'@'%' IDENTIFIED WITH mysql_native_password BY '密码';

-- 或改全局默认(my.cnf)
[mysqld]
default_authentication_plugin = mysql_native_password

方案 B:升级客户端库(推荐长期方案)

优点:支持最新特性,更安全
缺点:需要重新编译项目

  • 下载 MySQL Connector/C++ 8.0+: https://dev.mysql.com/downloads/connector/cpp/
  • 或更新 C API 的 libmysql.dll 到 8.0 版本

方案 C:使用 SSH 隧道(最安全)

# 本地建立隧道,把远程 3306 映射到本地 3307
ssh -L 3307:localhost:3306 user@服务器IP
# 然后 C++ 连接本地 3307,实际走的是加密 SSH
mysql_real_connect(conn, "127.0.0.1", "root", ..., 3307, ...);

优点:不暴露 3306 端口,全程加密
缺点:需要额外配置 SSH

六、安全建议

  1. 不要用 root 远程访问:创建专用账号,最小权限原则
  2. 限制 Host 范围:能用 192.168.1.% 就不要用 %
  3. 强密码 + SSL:生产环境必须配置 SSL 连接
  4. 修改默认端口:将 3306 改为其他端口,减少扫描
  5. fail2ban:自动封禁暴力 破解 IP

七、常用排查命令速查

-- 查看当前连接
SHOW PROCESSLIST;

-- 查看连接错误阈值
SHOW VARIABLES LIKE 'max_connect_errors';

-- 修改阈值(临时)
SET GLOBAL max_connect_errors = 1000;

-- 查看用户认证方式
SELECT User, Host, plugin, authentication_string FROM mysql.user;

-- 查看被拉黑的 IP(performance_schema 需开启)
SELECT * FROM performance_schema.host_cache WHERE SUM_CONNECT_ERRORS > 0;

总结

问题现象解决
IP 被拉黑Host is blockedFLUSH HOSTS;
认证插件不支持caching_sha2_password cannot be loadedmysql_native_password 或升级客户端
用户不存在Operation ALTER USER failedSELECT 查用户,确认 Host 正确
localhost vs IP连接方式不同,匹配的用户不同明确用 % 还是具体 IP

核心教训:MySQL 的用户是 用户名@Host 的组合,修改前务必先查清楚!

本文基于 MySQL 8.0 + Windows C++ 客户端的真实踩坑经历整理。

到此这篇关于MySQL远程访问配置与常见问题解决指南的文章就介绍到这了,更多相关MySQL远程访问配置与常见问题内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySQL 查询某个字段含有字母数字的值示例详解

    MySQL 查询某个字段含有字母数字的值示例详解

    在本文中,我们详细介绍了如何在 MySQL 中查询某个字段含有字母和数字的值,我们首先介绍了正则表达式的基础知识,然后通过五个具体示例展示了如何应用这些知识,通过这些示例,我们可以看到正则表达式在处理复杂字符串模式匹配时的强大功能,感兴趣的朋友跟随小编一起看看吧
    2024-05-05
  • 在JPA项目启动时如何新增MySQL字段

    在JPA项目启动时如何新增MySQL字段

    这篇文章主要介绍了在JPA项目启动时新增MySQL字段,本来用了JPA,直接实体类加参数就可以新增字段了,但是架不住垃圾项目在启动项目时会加载数据库SQL文件去插入数据,需要一些操作帮助修复,需要的朋友可以参考下
    2024-06-06
  • MySQL的 DDL和DML和DQL的基本语法详解

    MySQL的 DDL和DML和DQL的基本语法详解

    SQL语句,即结构化查询语言(Structured Query Language),是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统,这篇文章主要介绍了MySQL的 DDL和DML和DQL的基本语法,需要的朋友可以参考下
    2022-07-07
  • MySQLexplain之possible_keys、key及key_len详解

    MySQLexplain之possible_keys、key及key_len详解

    这篇文章主要介绍了MySQLexplain之possible_keys、key及key_len的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • mysql中InnoDB事务隔离的记录锁、间隙锁和临键锁

    mysql中InnoDB事务隔离的记录锁、间隙锁和临键锁

    mysql中InnoDB默认的事务隔离级别为可重复读(Repeated Read, RR),我们当下的所有介绍都是基于这个隔离级别为前提的,记录锁锁定索引关联的具体记录,间隙锁锁定间隔,防止间隔中被其他事务插入,临键锁锁定索引记录+间隔,防止幻读
    2023-12-12
  • MySQL sysdate()函数的具体使用

    MySQL sysdate()函数的具体使用

    本文主要介绍了MySQL sysdate()函数的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • 解决Win7 x64安装解压版mysql 5.7.18 winx64出现服务无法启动问题

    解决Win7 x64安装解压版mysql 5.7.18 winx64出现服务无法启动问题

    这篇文章主要介绍了解决Win7 x64安装解压版mysql 5.7.18 winx64出现服务无法启动问题,需要的朋友可以参考下
    2017-05-05
  • CentOS系统中MySQL5.1升级至5.5.36

    CentOS系统中MySQL5.1升级至5.5.36

    有相关测试数据说明从5.1到5.5+,MySQL性能会有明显的提升,具体的需要自己建立测试环境去实践下,今天我们就来操作下,并记录下来升级的具体步骤
    2017-07-07
  • MySQL对varchar类型数字进行排序的实现方法

    MySQL对varchar类型数字进行排序的实现方法

    这篇文章主要介绍了MySQL对varchar类型数字进行排序的实现方法,文中用的是CAST方法,MySQL CAST()函数用于将值从一种数据类型转换为另一种特定数据类型,并通过代码示例讲解的非常详细,需要的朋友可以参考下
    2024-04-04
  • DataGrip的MySQL数据导出和导入操作超详细指南

    DataGrip的MySQL数据导出和导入操作超详细指南

    很多时候我们会遇到需要将本机数据库数据导出或者其他数据库数据的导入操作,这篇文章主要给大家介绍了关于DataGrip的MySQL数据导出和导入操作超详细指南,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2024-04-04

最新评论