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