数据库MySQL/MariaDB安装与基础调优过程
作者:计算机安禾
一、引言:装完就能用,但千万别直接用
在Ubuntu上安装MySQL只需一条命令:
sudo apt update && sudo apt install mysql-server -y
CentOS/RHEL上:
sudo dnf install mysql-server -y
安装完成后,MySQL默认已经启动。但如果你认为“装完就能直接用”,那就太危险了。默认安装的MySQL存在几个严重安全隐患:
- root用户可以无密码登录(部分版本)
- 存在匿名用户,任何人都有一定权限访问数据库
- 存在test数据库,所有人都能访问
在生产环境中,这几个问题中的任何一个都可能导致数据泄露。所以安装后的第一步,永远是安全初始化。
二、mysql_secure_install:安全初始化
MySQL提供了一个交互式脚本mysql_secure_installation,专门用来加固初始安装。运行:
sudo mysql_secure_installation
脚本会依次询问以下问题,这是最关键的部分,请仔细阅读每一项的说明:
问题一:配置密码验证插件
VALIDATE PASSWORD COMPONENT: Would you like to setup VALIDATE PASSWORD component?
这个插件会强制密码必须满足一定复杂度(长度、大小写、数字、特殊字符)。建议选择Yes(输入y)。如果这是个人学习环境、不想太复杂,也可以选No。
问题二:设置root密码
Please set the password for root here. New password: _ Re-enter new password: _
如果系统没有要求输入初始密码(如Ubuntu较新版本通过auth_socket而不是密码验证),系统会直接引导你设置新密码。如果提示输入当前密码而你完全不知道,查看本文最后的FAQ。
问题三:删除匿名用户
Remove anonymous users? (Press y|Y for Yes)
必须选Yes。匿名用户允许任何人无需账号就能连接数据库,是严重的安全漏洞。
问题四:禁止root远程登录
Disallow root login remotely? (Press y|Y for Yes)
强烈建议选Yes。root只允许本地(127.0.0.1)连接,即使数据库被暴露到公网,攻击者也连不上root。如果你的应用需要远程管理数据库,应该创建专门的远程用户而不是开放root。
问题五:删除test数据库
Remove test database and access to it? (Press y|Y for Yes)
选Yes。test数据库默认所有人可访问,没有任何保留价值。
问题六:重新加载权限表
Reload privilege tables now? (Press y|Y for Yes)
选Yes。让以上所有修改立即生效。
FAQ:忘记或不知道初始root密码怎么办?
Ubuntu新版本(18.04+)使用auth_socket插件认证root,在系统root用户下可以免密直接登录MySQL:
sudo mysql # 以系统root身份直接进入MySQL,无需密码
进入后可以修改认证方式和密码(参见第三步)。如果这条命令无效,需要用第14篇学过的单用户模式或--skip-grant-tables方式绕过认证,再重置密码。
三、用户与权限:给谁看什么,谁又能改什么
安全初始化之后,MySQL只保留了root用户。日常开发中,我们需要为每个应用创建独立的数据库和用户,并授予精确的最小权限。
3.1 登录MySQL
sudo mysql -u root -p # 输入安全初始化时设置的密码
MySQL的命令需要用;结束。看到提示符变成mysql>,就进入了MySQL交互界面。
3.2 创建数据库
-- 创建数据库(字符集设置为 utf8mb4,支持emoji等4字节字符) CREATE DATABASE myapp DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
两点说明:
utf8mb4是真正的UTF-8(MySQL的utf8是阉割版,只支持最多3字节字符)。任何新项目都应该用utf8mb4utf8mb4_unicode_ci中的ci代表大小写不敏感(case insensitive),适合大多数文本排序场景
3.3 创建用户并授权
-- 创建用户('用户名'@'允许从哪里连接') CREATE USER 'myapp_user'@'localhost' IDENTIFIED BY 'StrongPassword123!'; -- 授予权限(把 myapp 数据库的所有权限授予该用户) GRANT ALL PRIVILEGES ON myapp.* TO 'myapp_user'@'localhost'; -- 刷新权限表(让授权立即生效) FLUSH PRIVILEGES;
@后面的主机部分决定了这个账号从哪台机器可以连接:
| 写法 | 含义 | 使用场景 |
|---|---|---|
'user'@'localhost' | 只能从本机连接 | 应用和数据库在同一台机器上 |
'user'@'192.168.1.%' | 允许特定网段连接 | 应用在另一台服务器上,需远程访问 |
'user'@'%' | 允许任何IP连接 | 非常危险,尽量避免 |
权限最小化原则:不要动不动就ALL PRIVILEGES。如果应用只需要读写数据,不需要修改表结构,使用:
GRANT SELECT, INSERT, UPDATE, DELETE ON myapp.* TO 'myapp_user'@'localhost';
3.4 验证用户
-- 查看用户列表 SELECT user, host FROM mysql.user; -- 查看某用户的权限 SHOW GRANTS FOR 'myapp_user'@'localhost'; -- 退出MySQL EXIT;
然后用新用户测试连接:
mysql -u myapp_user -p -h 127.0.0.1
四、my.cnf调优:三个必须改的参数
MySQL的默认配置面向兼容性,而不是性能。在使用MySQL之前,至少调整以下三个参数。配置文件位置:
# Ubuntu/Debian sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf # CentOS/RHEL sudo vim /etc/my.cnf.d/mysql-server.cnf
在[mysqld]段下添加或修改参数,修改后重启生效:sudo systemctl restart mysql。
4.1 innodb_buffer_pool_size:内存的核心参数
[mysqld] innodb_buffer_pool_size = 1G
这个参数是MySQL调优最重要的参数,没有之一。
它的作用是:InnoDB用它来缓存数据页和索引。MySQL频繁读写的数据如果都缓存在这里,查询和写入就是内存速度;缓存不够就只能频繁读写磁盘,慢两到三个数量级。
设置多大合适?
| 服务器内存 | 建议值 | 说明 |
|---|---|---|
| 1GB | 512M | 最低建议,再小MySQL性能严重下降 |
| 2GB-4GB | 总内存 × 50% | 留一半给操作系统和应用程序 |
| 8GB+ | 总内存 × 70% | 数据库可以多吃内存 |
| 独服/大内存 | 总内存 × 80% | 上限,再多操作系统会换页 |
验证是否生效:
-- 进入MySQL后执行 SELECT @@innodb_buffer_pool_size/1024/1024 AS pool_size_MB;
输出应该接近你设置的值。
4.2 innodb_log_file_size:写入性能的关键
innodb_log_file_size = 256M
这个参数控制InnoDB的重做日志(redo log)大小。它的作用像一个“写入缓冲区”:数据修改先记录到重做日志,然后慢慢写入实际数据文件。
设置过小的症状:频繁的磁盘刷新,写入性能严重下降。设置过大的代价:崩溃恢复时间变长,但不会影响正常运行。
建议值:256MB到1GB之间。对于大多数应用,256MB是一个安全的起点。如果你有高并发写入场景,可以调到512MB或更大。
4.3 max_connections:最大连接数
max_connections = 200
MySQL默认最大连接数通常是151。对于Web应用,这个值经常不够用——每个PHP进程/Python线程都可能占用一个连接。如果达到上限,新请求会报Too many connections错误。
# 查看当前连接数 mysql -u root -p -e "SHOW STATUS LIKE 'Threads_connected';"
注意:连接数不是越大越好。每个连接占用内存(默认约2MB),200个连接可能占400MB内存。设置时确保:max_connections × 每个连接内存 不会耗尽服务器内存。
完整建议配置(2GB内存服务器):
[mysqld] innodb_buffer_pool_size = 1G innodb_log_file_size = 256M max_connections = 200 character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci
五、忘记密码怎么办?
如果你忘记了MySQL root密码,可以绕过认证重置:
# 1. 停止MySQL sudo systemctl stop mysql # 2. 跳过权限验证启动 sudo mysqld_safe --skip-grant-tables & # 3. 无密码登录 mysql -u root # 4. 在MySQL中重置密码 FLUSH PRIVILEGES; ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewStrongPassword123!'; # 5. 退出后正常启动 sudo pkill mysqld sudo systemctl start mysql
六、本篇小结
安全初始化(必做):
sudo mysql_secure_installation
依次确认:验证密码插件(按需)→ 设root密码 → 删匿名用户 → 禁用root远程登录 → 删test数据库 → 重载权限。
数据库和用户管理:
| 操作 | 命令 |
|---|---|
| 创建数据库 | CREATE DATABASE dbname CHARSET utf8mb4; |
| 创建用户 | CREATE USER 'user'@'host' IDENTIFIED BY 'password'; |
| 授权 | GRANT ALL ON dbname.* TO 'user'@'host'; |
| 查看权限 | SHOW GRANTS FOR 'user'@'host'; |
| 生效 | FLUSH PRIVILEGES; |
核心调优参数:
| 参数 | 建议值(2GB内存) | 作用 |
|---|---|---|
innodb_buffer_pool_size | 1G | 缓存数据和索引,最重要 |
innodb_log_file_size | 256M | 写入缓冲,影响写性能 |
max_connections | 200 | 最大连接数 |
动手练习
# 1. (如果是新环境)运行安全初始化 sudo mysql_secure_installation # 2. 创建练习数据库和用户 sudo mysql -u root -p
CREATE DATABASE testdb CHARSET utf8mb4; CREATE USER 'testuser'@'localhost' IDENTIFIED BY 'TestPass123!'; GRANT SELECT, INSERT, UPDATE, DELETE ON testdb.* TO 'testuser'@'localhost'; FLUSH PRIVILEGES; EXIT;
# 3. 用新用户连接测试 mysql -u testuser -p -h 127.0.0.1 # 在MySQL中查看自己有哪些权限 SHOW GRANTS FOR CURRENT_USER(); EXIT;
七、下篇预告
有了Web服务器(Nginx)和数据库(MySQL),开发团队还需要一个地方共享文件。下一篇我们将学习搭建FTP与Samba文件共享服务——FTP适合传统的文件传输,Samba则能让Linux目录直接出现在Windows的“网络邻居”中,拖拽上传就像操作本地文件夹。
延伸思考:敏感数据(如密码字段)应该直接存储在数据库里吗?绝对不要。即使用GRANT限制了用户权限,数据库文件被盗或SQL注入仍然可能暴露这些数据。正确的做法是存储密码的加盐哈希(如bcrypt),在应用层处理加密逻辑。数据库只管“存”,应用层负责“保护”。这也是纵深防御原则的一个体现。
到此这篇关于数据库MySQL/MariaDB安装与基础调优过程的文章就介绍到这了,更多相关MySQL MariaDB安装调试内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
