MariaDB 常见问题

FreeGuideOnline 最新 2026-07-15

sql ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码'; FLUSH PRIVILEGES;

- 全新安装时跳过权限表登录后修改(适用于忘记密码场景):
1. 停止服务
2. 启动时添加 `--skip-grant-tables` 参数
3. 登录后执行 `FLUSH PRIVILEGES;` 再修改密码

### MariaDB 的配置文件 my.cnf 在哪里?
- 搜索顺序(Linux):
`/etc/my.cnf` → `/etc/mysql/my.cnf` → `~/.my.cnf`
- 通过命令查看加载位置:
`mysqld --verbose --help | grep -A 1 "Default options"`
- 自定义配置文件可放在 `/etc/mysql/mariadb.conf.d/` 目录下(`.cnf` 后缀)

## 连接与网络
### 远程连接被拒绝:Host 'xxx' is not allowed to connect
- 原因:用户未授权远程访问
- 解决办法:
```sql
-- 允许某 IP 连接
GRANT ALL PRIVILEGES ON *.* TO '用户名'@'192.168.1.100' IDENTIFIED BY '密码';
-- 允许所有远程连接(不安全)
GRANT ALL PRIVILEGES ON *.* TO '用户名'@'%' IDENTIFIED BY '密码';
FLUSH PRIVILEGES;
  • 同时确保防火墙开放3306端口,并且配置文件中 bind-address 不为 127.0.0.1

如何修改 MariaDB 的默认端口?

  • 编辑配置文件 /etc/my.cnf[mysqld] 节下添加:
    port = 3307
    
  • 重启服务生效。注意客户端连接时需使用 -P 指定新端口,如 mysql -P 3307 -u root -p

用户与权限

创建用户并授予数据库权限的正确方式

-- 创建用户
CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'password';
-- 授予特定数据库全部权限
GRANT ALL PRIVILEGES ON mydb.* TO 'newuser'@'localhost';
-- 授予所有数据库的只读权限
GRANT SELECT ON *.* TO 'newuser'@'localhost';
FLUSH PRIVILEGES;
  • 务必指定 @'host' 部分,localhost 指本地连接,% 指任何主机

忘记 root 密码怎么办?

  1. 停止 MariaDB 服务
  2. 使用安全模式启动,跳过权限验证: sudo mysqld_safe --skip-grant-tables &
  3. 无密码登录:mysql -u root
  4. 更新密码并刷新权限:
    FLUSH PRIVILEGES;
    ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';
    
  5. 退出后正常重启服务

SQL 与功能常见问题

MariaDB 与 MySQL 完全兼容吗?

  • MariaDB 是 MySQL 的二进制替换版,大部分情况下完全兼容
  • 版本对应:MariaDB 10.4 ≈ MySQL 8.0 功能,10.3 ≈ 5.7
  • 差异:
    • 存储引擎:MariaDB 默认使用 Aria 作为内部临时表引擎,而 MySQL 为 TempTable
    • 一些系统变量名不同:例如 wait_timeout 等相同
    • JSON 与窗口函数支持从 MariaDB 10.2+ 开始
    • 自增序列、虚拟列等细节存在差异
  • 迁移建议:使用 mysql_upgrade 检查升级,通过 show variables 比对差异

如何查看数据库或表的大小?

-- 查看所有数据库大小
SELECT table_schema AS 'Database',
       ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS 'Size (MB)'
FROM information_schema.tables
GROUP BY table_schema;

-- 查看某库中表的大小
SELECT table_name AS 'Table',
       ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'Size (MB)'
FROM information_schema.tables
WHERE table_schema = '数据库名'
ORDER BY (data_length + index_length) DESC;

慢查询日志如何开启与分析?

  1. 开启日志(临时):
    SET GLOBAL slow_query_log = 1;
    SET GLOBAL long_query_time = 2;  -- 超过2秒记录
    SET GLOBAL slow_query_log_file = '/var/log/mysql/mariadb-slow.log';
    
  2. 永久配置需写入 my.cnf:
    slow_query_log = 1
    long_query_time = 2
    slow_query_log_file = /var/log/mysql/mariadb-slow.log
    
  3. 分析工具:mysqldumpslow 命令,或第三方工具如 pt-query-digest

性能与优化

如何优化一个慢查询?

  • 使用 EXPLAIN SELECT ... 查看执行计划,确认是否使用索引
  • 创建合适索引:CREATE INDEX idx_col ON table(column);
  • 避免 SELECT *,只取需要的列
  • 优化 JOIN 顺序,小表驱动大表
  • 使用查询缓存(10.3 前默认开启,10.4 后移除,建议使用应用层缓存)

InnoDB 缓冲池大小如何调整?

  • 缓冲池缓存数据和索引,建议设置为物理内存的 50% ~ 70%(专用数据库服务器)
  • 查看当前大小:SELECT @@innodb_buffer_pool_size;
  • 动态调整(需权限):
    SET GLOBAL innodb_buffer_pool_size = 4294967296;  -- 4G
    
  • 永久修改:my.cnfinnodb_buffer_pool_size = 4G ,重启生效

备份与恢复

使用 mysqldump 备份单个数据库及恢复

# 备份(包含存储过程和事件)
mysqldump -u root -p --routines --events --single-transaction 数据库名 > backup.sql

# 恢复
mysql -u root -p 数据库名 < backup.sql

如何一次性备份所有数据库?

mysqldump -u root -p --all-databases --single-transaction --routines --events > all_backup.sql
  • 使用 --single-transaction 对 InnoDB 表实现一致性非锁定备份
  • 恢复时直接 mysql -u root -p < all_backup.sql 即可

升级与迁移

从 MySQL 迁移到 MariaDB 需要注意什么?

  • 兼容性检查:MariaDB 官网提供兼容性矩阵,10.x 系列兼容 MySQL 5.7/8.0
  • 备份数据:
    mysqldump --all-databases --add-drop-database --routines --events > mysql_full_backup.sql