尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Linux下MySQL从零搭建到生产落地完整指南

Linux下MySQL从零搭建到生产落地完整指南 Linux下搭建MySQL从零到能扛业务的完整实录在Linux上把MySQL跑起来这件事看起来特别“入门”随便一搜教程一大把。但我这些年帮人排查过不少数据库问题发现很多故障的根源恰恰是最初安装配置时埋下的雷——目录规划不合理、字符集没设对、密码策略没理清、防火墙/SELinux没放行甚至有人装完直接抡起root账号当业务账号用。这篇文章就围绕“linux搭建mysql”这件事把从版本选择、环境准备、正式安装、初始化配置、远程访问到日常备份的完整链路捋一遍最后附上我实际踩过的高频问题排查记录。这篇内容适合谁刚接触Linux想搭一套开发库的新人准备在服务器上部署生产环境MySQL的运维/后端同学以及想系统了解MySQL安装规范和注意细节的开发者。我尽量把“为什么这么做”也讲清楚不是单纯丢给你一串命令。1. 动手之前先把这几个关键问题想清楚1.1 该选哪个Linux发行版和MySQL版本先说结论我推荐 Rocky Linux 8 / 9 或 CentOS 7如果你是老机器MySQL 版本直接上 8.0别再新装 5.7。为什么MySQL 5.7 其实在2023年10月已经结束官方支持EOL这意味着之后发现的漏洞不会再打补丁合规审计都过不了。对于新项目直接上8.0是天经地义的选择。MySQL 8.0 相比5.7在很多方面是实打实的提升默认字符集就是utf8mb4不用再手动改来改去支持窗口函数和公用表表达式CTE写复杂统计SQL方便很多优化器更强了很多老SQL在8.0上跑得更快还有数据字典统一管理不再散落一堆.frm文件。操作系统层面Ubuntu和Debian也是常见选择但国内企业里CentOS系包括Rocky Linux、AlmaLinux的使用率还是最高的文档多、踩坑案例多、遇到问题好搜。所以我下面的实操以Rocky Linux 8为例CentOS 7的差异我会标注出来。1.2 机器配置和目录规划很多新手装MySQL根本不关心目录规划默认装完datadir在/var/lib/mysql日志在/var/log/mysqld.log一切看起来都正常。但等数据库跑起来数据量涨了系统盘满了那时候再迁移数据目录就很被动了。我给一个比较稳的目录规划方案数据目录/data/mysql独立挂载一块数据盘至少50G起SSD最好日志目录/data/mysql/logs可以和datadir放一起也可以单独分备份目录/data/backup/mysql尽量和数据库不在同一块磁盘上解释一下为什么坚持独立数据盘数据库是典型的随机读写负载如果和系统共用一块盘操作系统的日志写入、软件的临时文件都可能跟数据库抢IO。更关键的是系统盘万一出问题重装系统时数据盘可以拔下来挂到别的机器上抢救数据。我见过太多把数据库放在/根分区磁盘写满后MySQL直接拒写、甚至表损坏的案例都是血的教训。如果没有独立数据盘至少也要预留足够的根分区空间并且定期监控磁盘使用率。1.3 安装方式源码编译、二进制包、还是yum仓库MySQL在Linux上的安装方式主要有三种我直接说结论各有利弊但要分场景选源码编译安装适合有特殊定制需求的场景比如要打特殊补丁、要自定义编译参数。但对绝大多数人来说是三重折磨耗时长一台服务器编译2小时起步、依赖多缺哪个库都得装、升级麻烦。新人不建议碰。二进制免编译包把解压后的目录放到指定位置然后初始化数据目录就行。优点是灵活可以随意指定安装路径缺点是一切都要手动配环境变量、服务脚本、开机自启全要靠自己搞容易遗漏。yum/dnf仓库安装最推荐。官方仓库会处理好依赖关系和服务脚本后续小版本升级一条yum update就完事配置也集中在/etc/my.cnf里好找好改。2. 服务器初始化和环境准备2.1 系统基础配置主机名、时间同步、SELinux新装的Linux服务器建议先做三件基础事不然后面排查问题会很痛苦。第一设置主机名。执行hostnamectl set-hostname mysql-server然后编辑/etc/hosts把主机名和IP对应起来。这一步很关键因为MySQL在启动时会反解主机名如果你没配好hosts启动日志里会出现各种奇怪的DNS解析错误。第二确认时间同步。数据库对时间同步敏感度极高如果服务器时间漂移binlog里的时间戳、慢查询日志、事务时间全会乱套甚至会让你在排查问题时得出完全错误的结论。用chrony做时间同步yum install -y chrony systemctl enable --now chronyd chronyc sources -v看到输出的时间源状态是^* 就说明同步正常。第三SELinux的处理策略。这个在4.3节会详细讲这里先记住一点不要无脑setenforce 0关掉而是按需放行MySQL需要的端口和资源。2.2 配置MySQL官方yum源不要从第三方源安装MySQL版本混乱且质量没保障。一定要用MySQL官方源。Rocky Linux 8 / CentOS 8 使用如下命令dnf install -y https://dev.mysql.com/get/mysql80-community-release-el8-9.noarch.rpmCentOS 7则用el7的包yum install -y https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm装完以后验证一下仓库是否生效dnf repolist | grep mysql正常会看到mysql-community-server、mysql-community-client等仓库。如果服务器无法访问外网可以从能联网的机器上下载rpm包和所有依赖然后内网离线安装。离线安装的依赖列表比较长建议用yumdownloader带--resolve参数把依赖一次性拉下来。2.3 卸载系统自带的MariaDB很多Linux发行版默认带了MariaDB一套MySQL的社区分支。如果端口被它占用你启动MySQL时会报Port 3306 is already in use的错误或者安装时提示包冲突。检查是否装了MariaDBrpm -qa | grep mariadb有输出的话直接卸载yum remove -y mariadb*卸载后顺手检查一下3306端口是否被占用ss -lntp | grep 3306没输出就说明端口空闲。如果被其他进程占用确认不是重要服务后手动处理。3. 正式安装与初始化3.1 安装MySQL Community Server仓库配好了装起来就是一条命令的事dnf install -y mysql-community-server这个过程会自动安装mysql-community-client、mysql-community-libs等依赖大约需要下载几百兆的包取决于网速。安装完成以后先别急着启动做两件事。第一检查一下MySQL的版本mysql --version第二规划数据目录。如果按前面说的用/data/mysql作为数据目录需要先准备出来mkdir -p /data/mysql mkdir -p /data/mysql/logs mkdir -p /data/backup/mysql然后对数据目录做SELinux上下文标记这个很多教程都会漏掉semanage fcontext -a -t mysqld_db_t /data/mysql(/.*)? restorecon -Rv /data/mysql不做这一步的话SELinux开启时MySQL无法写数据目录启动会直接失败报错信息还是Permission denied特别迷惑。3.2 启动服务与临时密码处理准备好目录后修改/etc/my.cnf中的datadir指向然后启动[mysqld] datadir/data/mysql socket/var/lib/mysql/mysql.sock启动服务systemctl start mysqld systemctl enable mysqld第一次启动时MySQL会自动完成数据目录的初始化工作并且为root用户生成一个临时密码记录在日志文件里grep temporary password /var/log/mysqld.log输出的格式类似A temporary password is generated for rootlocalhost: xxxxxxxx。注意这个密码只在初始状态下有效登录后必须修改。注意这个日志位置如果你修改了log-error的配置要看对应的文件别找错地方。3.3 mysql_secure_installation安全初始化拿到临时密码后登录MySQLmysql -uroot -p登录成功后第一步就是改密码。MySQL 8.0默认密码策略是中等强度validate_password.policy为MEDIUM要求密码至少8位、包含大小写字母、数字和特殊字符。ALTER USER rootlocalhost IDENTIFIED BY YourStrongPssw0rd;如果只是本地开发环境想用简单密码也可以临时调低策略SET GLOBAL validate_password.policy LOW; SET GLOBAL validate_password.length 6; ALTER USER rootlocalhost IDENTIFIED BY 123456;但这只是图省事的做法生产环境千万别这么干。接下来运行官方自带的加固脚本mysql_secure_installation这个脚本是交互式的会依次问你是否设置密码验证插件VALIDATE PASSWORD COMPONENT——按需选择生产建议yes是否修改root密码——刚才已经改过可以选No是否删除匿名用户——必须Yes是否禁止root远程登录——生产环境建议Yes是否删除test测试数据库——必须Yes是否重新加载权限表——Yes这几项全选Yes就对了尤其是删除匿名用户和test库这是很多安全扫描工具必查的项不处理的话机器一上公网就可能被扫到漏洞。4. 核心配置与远程访问4.1 看懂my.cnf关键参数MySQL装好只是第一步真正决定性能的是/etc/my.cnf里的参数配置。很多新手直接用默认配置跑生产这其实挺危险的——MySQL默认配置是为了“能跑起来”而不是“跑得好”。我把最核心的几个参数列出来并说清楚每个参数的意义参数推荐值说明port3306MySQL监听端口生产环境可以改掉降低被扫描概率bind-address0.0.0.0或内网IP默认只监听127.0.0.1想远程访问必须改character-set-serverutf8mb4数据库默认字符集强烈建议utf8mb4collation-serverutf8mb4_unicode_ci排序规则和字符集配套max_connections500-2000最大连接数取决于并发量和机器配置innodb_buffer_pool_size物理内存的50%-70%InnoDB缓冲池大小这是MySQL性能的头号因素slow_query_logON开启慢查询日志定位性能瓶颈long_query_time2超过2秒的SQL记录到慢查询日志log_binmysql-bin二进制日志用于数据恢复和主从复制一个比较通用的配置文件模板如下[mysqld] port3306 bind-address0.0.0.0 datadir/data/mysql socket/var/lib/mysql/mysql.sock character-set-serverutf8mb4 collation-serverutf8mb4_unicode_ci max_connections800 max_connect_errors1000 innodb_buffer_pool_size4G innodb_log_file_size512M innodb_flush_log_at_trx_commit1 slow_query_logON slow_query_log_file/data/mysql/logs/slow.log long_query_time2 log_error/var/log/mysqld.log注意修改配置后需要重启MySQL生效systemctl restart mysqldinnodb_buffer_pool_size是InnoDB引擎用来缓存数据页和索引的内存区域。这个值设太小数据频繁读磁盘性能急剧下降设太大又可能导致内存不足触发系统OOM。经验值是物理内存的50%到70%。比如机器有8G内存设4G到5G都合理但前提是机器上没跑其他吃内存的服务。我见过一个经典错误机器8G内存只给buffer pool设了128M的默认值结果跑一个不算大的报表查询都要好几秒。调整到4G后同样的查询秒出。这个参数就是MySQL性能里最立竿见影的一个。4.2 创建业务账号和授权root账号权限太大不应该让业务代码直连。正确的做法是创建独立的应用账号只授予必要权限。假设我们要创建一个名为myapp的账号可以访问mydb库所有表CREATE USER myapp% IDENTIFIED BY AppPssw0rd2024; GRANT ALL PRIVILEGES ON mydb.* TO myapp%; FLUSH PRIVILEGES;这里的myapp%表示允许从任何主机连接mydb.*表示只对mydb库有权限。如果业务只跑在某一台应用服务器上更安全的是限制IP来源CREATE USER myapp192.168.1.100 IDENTIFIED BY AppPssw0rd2024;MySQL 8.0的账号授权要注意8.0不再支持GRANT语句中隐式创建用户必须先CREATE USER再GRANT这点和5.7及更早版本有区别。另外MySQL 8.0默认的认证插件是caching_sha2_password有些老版本客户端工具比如很早的Navicat版本连接时会报“Authentication plugin caching_sha2_password cannot be loaded”错误。解决办法可以创建用户时指定mysql_native_passwordCREATE USER myapp% IDENTIFIED WITH mysql_native_password BY AppPssw0rd2024;但我个人建议是升级客户端工具而不是降级认证方式——native_password在8.4中已经被标记废弃长远看还是要向caching_sha2_password迁移。4.3 防火墙和SELinux两个最容易被忽略的拦路虎很多人在服务器本地连MySQL都没问题一用Navicat或者别的客户端远程连接就连不上此时90%的可能是防火墙没放行3306端口剩下10%是SELinux拦截。先看防火墙。使用firewalld的机器执行firewall-cmd --permanent --add-port3306/tcp firewall-cmd --reload确认端口已经放行firewall-cmd --list-ports如果是纯内网环境可以限定来源IP只允许内网网段访问firewall-cmd --permanent --add-rich-rulerule familyipv4 source address192.168.0.0/16 port protocoltcp port3306 accept再讲SELinux。你可以先用getenforce查看当前状态。如果是Enforcing只放行防火墙还不够MySQL的网络连接和文件访问都可能被SELinux拦。前面2.1节说了不要一刀切关SELinux正确做法是只放行MySQL需要的权限setsebool -P mysqld_connect_any 1这个布尔值控制MySQL能否建立网络连接。另外还需要在SELinux里放行MySQL监听的端口semanage port -a -t mysqld_port_t -p tcp 3306前面在数据目录上做的restorecon也是SELinux相关操作。把这几步做完SELinux基本上不会成为MySQL的阻碍同时系统的整体安全策略还是保持开启的。5. 日常管理与运维要点5.1 服务管理与状态检查安装配置完以后日常打交道最多的是这些命令systemctl status mysqld # 查看服务状态 systemctl start mysqld # 启动 systemctl stop mysqld # 停止 systemctl restart mysqld # 重启 systemctl enable mysqld # 设置开机自启 systemctl is-enabled mysqld # 检查是否已设置开机自启确认MySQL确实在监听端口ss -lntp | grep 3306看到LISTEN状态说明服务正常。再试一下能不能登录mysql -uroot -p -e SELECT VERSION();能输出版本号就说明一切正常。5.2 慢查询日志与error log排查线上性能问题慢查询日志是第一个要看的。前面配置文件里已经开启了确认一下状态SHOW VARIABLES LIKE slow_query_log%; SHOW VARIABLES LIKE long_query_time%;在MySQL里也可以动态开启不需要重启SET GLOBAL slow_query_log ON; SET GLOBAL long_query_time 2;但注意动态设置重启后会失效想永久生效还是要把配置写进my.cnf。分析慢日志其实没必要用复杂的工具先直接看几条tail -50 /data/mysql/logs/slow.log每条慢日志会记录执行时间、锁等待时间、返回行数、扫描行数以及具体的SQL语句。看到扫描行数特别大或者执行时间特别长的就该去分析SQL了。error log的位置在/etc/my.cnf里配置默认是/var/log/mysqld.log。MySQL启动失败、连接异常断开、复制中断这些关键错误都会记录在这里。排查问题时第一时间打开它比网上乱搜高效得多。5.3 备份方案物理备份与逻辑备份说实话很多小团队根本没有备份策略或者只是偶尔手动导一下数据。但数据库一旦出问题备份就是最后的救命稻草。我强烈建议任何环境都要配置自动备份。最常用的两类备份方式逻辑备份用mysqldump简单可靠适合中小数据量mysqldump -uroot -p --single-transaction --master-data2 --routines --triggers --events mydb /data/backup/mysql/mydb_$(date %F).sql参数说明--single-transaction用于InnoDB表实现一致性快照备份不锁表--master-data2会在备份文件中记录binlog文件名和位置对后续搭建从库或做时间点恢复很有用--routines和--triggers用来备份存储过程、触发器和事件。恢复时执行mysql -uroot -p mydb /data/backup/mysql/mydb_2025-01-01.sql物理备份推荐Percona XtraBackup适合大数据量备份速度快支持增量备份。它直接拷贝数据文件但要求版本和MySQL兼容。装好以后备份命令xtrabackup --backup --target-dir/data/backup/mysql/inc1 -u root -p最后用crontab配置定时任务。比如每天凌晨2点做全量备份0 2 * * * mysqldump -uroot -ppassword --single-transaction --master-data2 mydb | gzip /data/backup/mysql/mydb_$(date \%F).sql.gz备份这件事最怕的是“备份了但恢复不了”。所以定期做一次恢复演练很重要把备份文件拷到测试机上实际恢复一遍确认备份可用。我见过不少团队备份文件堆了一大堆真到要恢复的时候才发现备份是坏的那比没有备份还让人崩溃。6. 常见问题排查实录6.1 六类高频问题速查表我把这些年遇到的高频问题整理成一个速查表方便你遇到问题时快速定位现象可能原因排查命令 / 解决方法启动失败日志报Permission deniedSELinux未放行数据目录执行restorecon -Rv /data/mysql或用semanage添加上下文本机能连远程连接被拒防火墙未放行3306bind-address未修改firewall-cmd --add-port3306/tcpmy.cnf中bind-address改为0.0.0.0远程连接报Cant connect (10060)云安全组未添加入站规则检查云平台安全组放行3306端口客户端报caching_sha2_password错误客户端版本太老不支持MySQL 8.0认证插件升级数据库客户端工具或临时改用mysql_native_password密码正确但登录报Access denied账号host类型不匹配检查SELECT user,host FROM mysql.user;确保登录来源在允许列表中启动成功但连3306没反应端口被占用或MySQL没监听ss -lntp | grep 3306看是否被mysqld监听6.2 忘记root密码怎么重置这个场景太常见了而且网上教程鱼龙混杂。我讲一个在MySQL 8.0下亲测有效的方法。先停掉MySQL服务systemctl stop mysqld然后以跳过授权表的方式启动mysqld_safe --skip-grant-tables --skip-networking 注意加上--skip-networking防止在无认证状态下被远程连接这是个安全细节。使用root直接登录不需要密码mysql -uroot然后重新加载授权表并修改密码FLUSH PRIVILEGES; ALTER USER rootlocalhost IDENTIFIED BY NewPssw0rd;重置完后重启MySQLsystemctl restart mysqld如果mysqld_safe启动方式不太好用也可以直接修改/etc/my.cnf在[mysqld]段下加一行skip-grant-tables重启服务改完密码后记得删除这一行再重启。6.3 中文乱码问题字符集必须用utf8mb4MySQL中文乱码的根子基本都在字符集不一致。现在MySQL 8.0默认字符集就是utf8mb4如果你是8.0版本且安装时没有特意改字符集那么这个问题基本不存在。但如果你用的是5.7或者默认配置没动过还是要检查一下SHOW VARIABLES LIKE character_set%;关键看character_set_server如果是latin1或者utf8就说明服务端字符集不对。修改my.cnf[mysqld] character-set-serverutf8mb4 collation-serverutf8mb4_unicode_ci同时确认客户端连接时也使用utf8mb4。在连接字符串里加上字符集参数比如JDBC连接串jdbc:mysql://localhost:3306/mydb?useUnicodetruecharacterEncodingutf8mb4顺带说一句utf8mb4和utf8的区别在于utf8mb4支持完整的Unicode字符集包括emoji和一些生僻字。utf8在MySQL里最多存3字节的字符遇到emoji这种占用4字节的就会报错。所以任何新项目无脑用utf8mb4就对了。7. Linux下MySQL的架构和工作原理速览既然标题是“linux搭建mysql”我觉得有必要顺带聊一下装好的MySQL在Linux上是怎么组织的。很多面试题也喜欢从这里切入。MySQL从架构上可以分成三层连接层、服务层和存储引擎层。连接层负责处理客户端的连接请求验证用户名密码建立线程来处理每个连接。这也是为什么max_connections参数重要——每个连接都要占用一个线程和一部分内存。服务层是MySQL的核心业务逻辑所在包括SQL解析器、查询优化器、缓存等。你写的SQL到了这里会被解析成语法树然后交给优化器生成执行计划决定用哪个索引、按什么顺序扫描表。存储引擎层是真正干活的。InnoDB是MySQL 8.0的默认引擎它的核心设计包括聚簇索引表数据本身按主键索引组织叶子节点直接存储行数据。这意味着主键查询效率极高但非主键索引的查询需要回表。缓冲池Buffer Pool把磁盘上的数据页缓存在内存中极大减少磁盘IO。这就是innodb_buffer_pool_size参数发挥作用的地方。redo log事务提交时先写redo logWAL机制保证即使数据库崩溃已提交的事务也可以恢复。undo log用于事务回滚和MVCC多版本控制。在Linux上MySQL的数据文件存放在datadir目录下InnoDB表的表结构定义和系统数据字典在MySQL 8.0中统一存储在数据字典中业务数据则存在每个表对应的.ibd文件中。了解这些原理有什么实际意义比如你看到一条SQL慢你能判断是索引问题还是buffer pool太小比如你备份时知道InnoDB支持在线备份配合--single-transaction能拿到一致性快照而不锁业务比如主从复制出问题了你知道要看binlog位置和relay log的状态。这些都不是纯理论消耗是实打实能用于日常运维判断的知识储备。回到安装这件事上装好MySQL只是万里长征第一步。把基础打牢——版本选对、目录合理、字符集正确、权限清晰、备份到位——数据库才能真正稳定可靠地为你服务。我在实际项目中还养成了一个习惯装完MySQL后把建库建账号的SQL、my.cnf配置、初始化过程全部整理成一份文档放进项目的wiki里。这样半年后新同事接手或者哪天上生产要再排一套环境直接照着文档操作不用重新摸索踩坑。最后再分享一个小技巧配置改完别急着大改特改一次只改一到两个参数观察一段时间的运行情况再决定下一步。数据库优化是渐进式的不是一蹴而就的事。
返回列表