MariaDB 这个东西,第一次接触的人十有八九是被 MySQL 折腾过来的。要么是公司服务器上跑着一套老业务不敢动,要么是课程设计里要求用开源数据库,要么就是单纯受够了某天醒来发现授权政策又变了的焦虑。我自己最早也是从 MySQL 5.5 一路用到 5.7,后来因为一次项目迁移才正式把主力环境切到 MariaDB,从那之后就没换回去过。这篇东西不讲虚的,就从零开始把安装和安全初始化这两件事讲透——包括版本怎么选、包管理器和官方源怎么取舍、默认认证插件埋的坑在哪、mysql_secure_installation到底帮你做了什么又漏了什么、以及在真实生产环境里我会额外补哪些加固动作。适合刚上手数据库的新人,也适合用了几年 MySQL 想平稳过渡的老手,看完至少能自己独立搭出一套可以对外提供服务、且不会第二天就被扫库的实例。
1. 为什么值得认真考虑 MariaDB 而不是直接装 MySQL
1.1 它到底是个什么东西
MariaDB 是从 MySQL 分支出来的开源关系型数据库,主导者是 MySQL 的最初作者 Michael Widenius。当年 MySQL 被 Sun 收购、Sun 又被 Oracle 收走之后,社区担心开源协议的走向,于是基于 MySQL 的代码分出了一条独立的线,取名 Maria(他女儿的名字)。这件事的时间点在 2009 年前后,到今天已经迭代了十几个大版本。关键在于,它不是简单复制一份代码改个名字,而是在兼容 MySQL 协议和 SQL 语法的前提下,自己往前走了很多路——比如 Aria 存储引擎、ColumnStore 列式存储、Galera Cluster 多主同步、以及更激进的内核优化。
对普通使用者来说,最直接的感受是三条:协议兼容,绝大多数 MySQL 客户端和驱动可以直连;语法兼容,绝大部分 SQL 语句不用改;运维习惯兼容,配置文件格式、命令行工具、权限模型基本一致。所以迁移成本相对低,这也是为什么很多课程设计和中小项目会直接选它。
1.2 选它还是选 MySQL,我的判断逻辑
我不想把这事说成非此即彼。选型这事要看场景,我把常见的几种情况列一下,你可以对号入座。
| 场景 | 我的建议 | 理由 |
|---|---|---|
| 个人学习、课程设计 | MariaDB | 安装包干净、无额外商业授权顾虑、社区文档全 |
| 中小型 Web 后端 | MariaDB | 单机性能足够,主从复制方案成熟 |
| 需要多主同步写入 | MariaDB + Galera | 内置集群方案,不用额外买中间件 |
| 团队已有大量 MySQL 运维经验 | 二者皆可 | 兼容度高,切换成本主要在细节 |
| 依赖特定 MySQL 专有特性 | 谨慎评估 | 少数企业版功能不通用 |
我要强调的是,MariaDB 和 MySQL 在 5.5 时代几乎是同源的,但从 5.7 往后两边都在各自演化,差异点逐渐变多。比如 JSON 类型的实现细节、窗口函数的语法边缘情况、以及认证插件的默认行为,都有微妙区别。所以我个人的习惯是:新项目从零起步,优先 MariaDB;存量系统要迁移,先做兼容性测试再动。
1.3 那些被热词带偏的误区
网上搜"mariadb 下载安装教程",能刷出来一大堆内容,但质量参差不齐。最常见的几个误区我提前点破。
第一个误区是"装完就能用"。实际上装完只是第一步,默认配置里为了兼容性留了不少口子,直接暴露在公网就是等着被扫。第二个误区是"密码设了就安全了"。密码只是第一道门,用户权限、监听地址、认证插件、日志审计这些叠加起来才构成防线。第三个误区是"版本越新越好"。新版本确实有性能改进,但也可能引入你还没摸清的默认行为变化,生产环境我更倾向于选 LTS 性质的稳定版本,而不是刚发的短期版本。
提示:判断一个 MariaDB 版本是否适合生产,看它的维护周期而不是版本号大小。短期版本迭代快但支持期短,稳定版本更新慢但更值得托付。
2. 装之前先把地基打牢:环境确认与版本决策
2.1 操作系统与硬件前提
开工前先把环境摸清楚,这一步偷懒后面全是麻烦。要确认的东西不多,但每一项都值得认真对待。
- 操作系统发行版和版本号,是 Debian 系还是 RHEL 系,这决定了你用 apt 还是 dnf/yum。
- 系统架构,x86_64 还是 ARM64。现在 ARM 服务器越来越常见,尤其云厂商的性价比机型,选包的时候一定要对上是 arm64 还是 amd64。
- 内存和磁盘。内存决定
innodb_buffer_pool_size的上限,磁盘决定你数据目录放哪、要不要单独挂载。 - 是否已有其他数据库实例在跑。如果 3306 端口已经被占用,要么改端口,要么先停掉旧实例。
- 防火墙和 SELinux 状态。这两个经常是"装完连不上"的元凶。
系统架构这一项特别容易被忽略。我自己就吃过一次亏,在一台 ARM 服务器上照着 x86 的教程去装官方仓库包,结果源里根本没有对应架构的包,卡了半小时才反应过来。所以下载或配置源之前,先跑一句uname -m,看清楚再动手。
2.2 版本选择的具体方法
MariaDB 的版本号是「主版本.次版本.补丁版本」这种格式,比如 10.11.6、11.4.2。主版本号跨越通常意味着有不兼容变更,次版本号一般是功能增强,补丁版本就是修 bug。
挑选时我的做法是:
- 先看官方维护周期表,找当前处于长期支持状态的版本。
- 再确认这个版本在你所用发行版的官方仓库里有没有现成包。
- 如果仓库版本太旧,就去配置 MariaDB 官方仓库源。
- 最后在测试机上跑一遍安装和启动,确认没有依赖冲突再上生产。
为什么不直接用系统自带的?因为发行版仓库里的版本经常滞后,比如系统自带 10.3,而你需要用到的某个复制特性在 10.6 才有。这时候配官方源更合适。但反过来,如果你只是本地学习,系统自带的足够用,还省去了配源的麻烦。
2.3 安装方式的三种路线对比
安装方式大致三条路,各有取舍,我用表格摊开说。
| 方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 发行版仓库 | 学习、快速验证 | 一条命令搞定,依赖自动处理 | 版本可能偏旧 |
| 官方 APT/YUM 源 | 生产、需要指定版本 | 版本新、可控、可升级 | 需要额外配源和密钥 |
| 二进制 tar 包 | 精细控制、离线环境 | 目录自定义、不污染系统 | 手动配置多、升级麻烦 |
选哪条路线取决于你的目标。纯学习我劝你走第一条,别一上来就折腾二进制包,光初始化脚本就能劝退一半人。生产环境我推荐第二条,配好源之后升级和回滚都比较清晰。第三条留给有特殊目录需求或者完全离线部署的场景。
3. 三条安装路线的完整实操记录
3.1 Debian / Ubuntu 系:apt 一条命令起步
先更新索引,再安装服务端和客户端两个包。服务端负责跑实例,客户端负责连进去操作,两个都装上省事。
sudo apt update sudo apt install -y mariadb-server mariadb-client装完之后服务一般是自动启动并设置为开机自启的。检查一下状态:
sudo systemctl status mariadb正常的话会看到active (running)。如果没起来,先别急着改配置,用journalctl -u mariadb -n 50看最近日志,八成是数据目录权限或者端口占用。
想用官方最新版的话,得先跑官方提供的仓库配置脚本,它会自动检测你的发行版并把源写进去:
curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash sudo apt update sudo apt install -y mariadb-server这一步要注意,脚本会往系统里加 GPG 密钥和源地址,装在公司机器上之前最好确认合规。另外它能识别代号,如果你的系统版本太老或者太新还没被收录,可能就配不上,这时候退回用系统仓库更稳。
3.2 RHEL / CentOS / Rocky 系:dnf 与仓库文件
RHEL 系现在主流是 dnf,老系统还是 yum,命令基本通用。
sudo dnf install -y mariadb-server mariadb sudo systemctl enable --now mariadb用官方源的话,需要手动写一个仓库文件放到/etc/yum.repos.d/下面,把 baseurl 指向官方路径,导入 GPG key,然后再安装。这个过程比 Debian 系繁琐,我通常只在必须锁版本的时候才走这条路。
这里有个坑要提醒:某些精简版系统默认没装mariadb-server对应的依赖组,直接装会报找不到包。解决办法是先启用对应的模块或者在仓库配置里放开,再重试。别以为是网络问题,大概率是仓库本身没启用。
3.3 二进制包安装:目录自定义与 systemd 托管
二进制包适合想把数据目录放到独立盘的情况。拿到 tar.gz 之后,解压到比如/usr/local/mariadb,然后跑自带的初始化脚本。
sudo mkdir -p /usr/local/mariadb sudo tar -xzf mariadb-*.tar.gz -C /usr/local/mariadb --strip-components=1 cd /usr/local/mariadb sudo ./scripts/mariadb-install-db --user=mysql --basedir=/usr/local/mariadb --datadir=/data/mysqlmariadb-install-db这个脚本会初始化数据目录、生成系统表。早期版本叫mysql_install_db,新版已经改名,看到老教程里的旧名字别困惑,是同一个东西的演化。
初始化完还要写一个 systemd unit 文件,把 ExecStart 指向你的mariadbd可执行文件,指定 basedir 和 datadir。这一步我踩过坑:datadir 的属主和属组必须和运行用户一致,否则启动时会因为权限不足直接退出,日志里会写Can't create/write to file。
[Unit] Description=MariaDB custom instance After=network.target [Service] Type=simple User=mysql Group=mysql ExecStart=/usr/local/mariadb/bin/mariadbd --defaults-file=/usr/local/mariadb/etc/my.cnf Restart=on-failure [Install] WantedBy=multi-user.target放到/etc/systemd/system/mariadb-custom.service,然后systemctl daemon-reload再启动。二进制路线的麻烦点就在这些手工活,但换来的是目录和参数的完全掌控。
4. 安全初始化:比跑个脚本更该做的事
4.1 mysql_secure_installation 到底干了什么
装完 MariaDB 第一件事,几乎所有人的教程都会让你跑这个脚本。但很多人是闭着眼一路回车,根本不知道它问了什么。我把它的动作拆开讲。
- 询问是否设置 root 密码。MariaDB 新版本默认 root 用的是 unix_socket 认证,意思是只要你是系统 root 用户,不用密码就能进。这个机制本地方便,但如果你后面要远程管理,就得改。
- 询问是否删除匿名用户。匿名用户是个历史遗留,允许无账号连接,必须删。
- 询问是否禁止 root 远程登录。除非你有明确需求,否则禁止。
- 询问是否删除 test 数据库。test 库默认任何用户都能访问,删掉。
- 询问是否刷新权限表。让它刷。
脚本本身没毛病,但它只覆盖了基础几项。跑完之后,你的实例大概达到了"及格线",离"安全"还有一段距离。
4.2 默认认证插件带来的连接困惑
这是新手最容易卡住的地方。你在本地以 root 身份跑mariadb能进去,但换成密码登录就报Access denied,原因就是 unix_socket 插件在做主。
要改的话,进到库里执行:
ALTER USER 'root'@'localhost' IDENTIFIED VIA mysql_native_password USING PASSWORD('你的新密码'); FLUSH PRIVILEGES;mysql_native_password是兼容性最好的认证方式,很多老客户端驱动只认它。如果你追求更强,可以用ed25519插件,但前提是客户端也要支持,否则又是一轮连不上的排查。我的建议是:面向内部应用的账号用 native_password,等客户端链路确认支持再考虑升级加密方式。
注意:改认证方式之前先开一个已登录的会话别关,万一改错了还能从旧会话里救回来。这是我被自己锁在门外之后养成的习惯。
4.3 用户权限的最小化实践
安全的核心原则是"能给多少给多少,不多给一分"。生产上绝对不要用 root 跑业务。
正确做法是为每个应用单独建账号,只给它需要的库和表的权限。
CREATE USER 'app_user'@'10.0.1.%' IDENTIFIED BY '强密码'; GRANT SELECT, INSERT, UPDATE, DELETE ON app_db.* TO 'app_user'@'10.0.1.%'; FLUSH PRIVILEGES;几点细节值得说:
- 主机部分能写具体网段就别写
%,%意味着任何来源都能尝试,风险大。 - 只授予 CRUD 就别给 DDL 权限,避免应用误删表结构。
- 需要远程管理的话单独建运维账号,和业务账号分开。
- 定期用
SELECT user, host FROM mysql.user清理不再使用的账号。
如果想看某个账号到底有哪些权限,可以跑SHOW GRANTS FOR 'app_user'@'10.0.1.%',一目了然。这个命令我建议写进例行巡检,很多越权问题是权限膨胀累积出来的。
4.4 监听地址与配置文件加固
默认配置里bind-address有时候是0.0.0.0,意思是监听所有网卡。如果你的数据库需要被其他机器访问,就限制到内网地址;如果只是本机应用用,直接改成127.0.0.1,从网络层就掐掉外部连接的可能。
配置文件位置分两种:
- Debian 系:
/etc/mysql/mariadb.conf.d/50-server.cnf - RHEL 系:
/etc/my.cnf.d/server.cnf
我通常会在里面额外加上这些:
[mysqld] bind-address = 127.0.0.1 local-infile = 0 max_connect_errors = 1000 skip-name-resolve = 1 character-set-server = utf8mb4 collation-server = utf8mb4_general_ci逐条说说理由。local-infile = 0关掉本地文件读取,防止有人利用 LOAD DATA 读取服务器上的任意文件。max_connect_errors是防止暴力尝试的连接失败计数。skip-name-resolve跳过 DNS 反查,既提速也避免因反查失败导致的连接拒绝。字符集统一成 utf8mb4,是为了能正常存 emoji 和四字节字符,这个坑不踩一次不会记得。
改完配置记得systemctl restart mariadb,然后确认服务起来了再走人。
5. 踩坑实录:安装和初始化阶段的典型故障排查
5.1 启动失败怎么快速定位
数据库起不来,先别慌,按顺序查。
第一步看状态:systemctl status mariadb,它会告诉你退出码和大致方向。第二步看日志:journalctl -u mariadb -n 100或者直接读错误日志文件。第三步看端口:ss -tlnp | grep 3306,确认是不是被占用。第四步看权限:数据目录的属主是不是 mysql。
我把常见现象和解法整理成表,遇到问题直接对号入座。
| 现象 | 可能原因 | 处理办法 |
|---|---|---|
| 服务反复重启 | 数据目录权限错误 | chown -R mysql:mysql /var/lib/mysql |
| 端口被占用 | 已有实例在跑 | 停旧实例或改端口 |
| 启动即退出 | 配置文件语法错 | 用mariadbd --help --verbose验证配置 |
| 连接被拒绝 | 监听地址不对 | 检查 bind-address |
| 认证失败 | 插件不匹配 | 确认账号认证方式 |
5.2 忘记 root 密码怎么重置
这事谁都遇到过。核心思路是让数据库以跳过权限检查的方式启动一次,改完密码再正常重启。
sudo systemctl stop mariadb sudo mariadbd --skip-grant-tables --skip-networking &然后另开一个终端进库,更新密码,再恢复正常启动。注意--skip-networking很重要,它保证这期间不接受网络连接,避免被人趁虚而入。
FLUSH PRIVILEGES; ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';改完杀掉临时进程,systemctl start mariadb,用新密码验证。整个过程我建议在维护窗口做,别在业务高峰动。
5.3 我个人的几条加固心得
最后分享几个文档里不常写、但我觉得挺有用的习惯。
第一,初始化完成后立刻备份一份/etc/mysql目录和mysql.user表的导出,改坏了能快速回滚。第二,把skip-name-resolve打开之后,账号的主机部分就不能写域名了,只能写 IP 或网段,这点改之前要想清楚。第三,密码强度别自己拍脑袋,MariaDB 有密码校验插件可以装,cracklib_password_check或者simple_password_check都行,用插件管比靠自觉靠谱。
第四,也是我踩得最深的一次:给账号授权时网段写大了。当时为了图省事写了个%,结果某天看到日志里有大量来自陌生地址的登录尝试,虽然没被破,但吓出一身冷汗。从那以后我所有账号都精确到具体网段,能本机的绝不开放远程。
再补一句,如果你有多台机器要做数据同步,主从复制的配置顺序很关键:先做主库的账号授权和 binlog 配置,再做从库指向,别反过来。反过来做会因为找不到同步账号一直报错。这个细节我下次单独写一篇来讲,涉及到的参数和坑更多。
到这里,一台装好且做完基本安全初始化的 MariaDB 就能投入使用了。剩下的事——备份策略、监控告警、慢查询分析——是在这个地基上继续盖楼,一步步来就行。