MariaDB
MariaDB 是一个可靠、高性能且功能齐全的数据库服务器,旨在成为 MySQL 的“始终免费、向后兼容、即插即用”的替代品。自 2013 年起,MariaDB 成为 Arch Linux 默认的 MySQL 实现。[1]
安装
MariaDB 是 Arch Linux 中 MySQL 的默认实现,由 mariadb 和 mariadb-lts 软件包提供。
- 如果数据库(位于
/var/lib/mysql)位于 Btrfs 文件系统上,则在软件包安装期间会自动禁用 写时复制 (CoW) 属性。这是通过 MariaDB 软件包提供的 systemd-tmpfiles(8) 配置文件(/usr/lib/tmpfiles.d/mariadb.conf)完成的,该文件在 MySQL 数据目录上设置了+C(NOCOW) 属性。不再需要手动干预。 - 如果数据库位于 ZFS 文件系统上,在创建任何数据库之前,您应咨询 ZFS#Databases。
安装 mariadb 或 mariadb-lts,并在启动 mariadb.service 之前运行以下命令
# mariadb-install-db --user=mysql --basedir=/usr --datadir=/var/lib/mysql
/var/lib/mysql 以外的路径,则需要在 /etc/my.cnf.d/server.cnf 的 [mariadb] 部分下设置 datadir=YOUR_DATADIR。为了简化管理,您可能需要安装一个前端。
配置
默认情况下,root 用户和运行服务器的用户都可以管理数据库。
要管理服务器,请以运行服务器的用户身份运行 mariadb
[mysql]$ mariadb
或者以 root 身份
# mariadb
添加用户
创建新用户分两步:创建用户;授予权限。在下面的示例中,创建了用户 monty,密码为 some_pass,然后被授予了数据库 mydb 的完全访问权限
# mariadb -u root -p
MariaDB> CREATE USER 'monty'@'localhost' IDENTIFIED BY 'some_pass'; MariaDB> GRANT ALL PRIVILEGES ON mydb.* TO 'monty'@'localhost'; MariaDB> quit
配置文件
MariaDB 配置选项按以下顺序读取(根据 mysqld --help --verbose | head -10 的输出)
/etc/my.cnf /etc/my.cnf.d/ ~/.my.cnf
在 /etc/my.cnf.d/ 中创建一个扩展名为 .cnf 的配置文件,以确保升级能保留您的配置。
根据您想要更改的范围(系统范围、仅限用户...),使用相应的文件。有关更多信息,请参阅知识库中的此条目。
启用自动补全
MariaDB 客户端补全功能默认处于禁用状态。要将其全局启用,请编辑 /etc/my.cnf.d/client.cnf,并在 client-mariadb 下添加 auto-rehash。注意,这不能放在 mysqld 下。下次运行 MariaDB 客户端时,补全功能将被启用。
使用 UTF8MB4
将以下值追加到位于 /etc/my.cnf.d/my.cnf 的主配置文件中
[client] default-character-set = utf8mb4 [mariadb] collation_server = utf8mb4_unicode_ci character_set_server = utf8mb4 [mariadb-client] default-character-set = utf8mb4
重启 mariadb.service 以应用更改。更改字符集不会改变现有的表格式,仅对新创建的表以及获取数据的协议交互产生影响。
请参阅 #维护 以优化和检查数据库健康状况。
为 tmpdir 使用 tmpfs
MariaDB 用于存储临时文件的目录称为 tmpdir。例如,它用于执行基于磁盘的大型排序,以及用于内部和显式的临时表。
创建具有适当权限的目录
# mkdir -pv /var/lib/mysqltmp # chown mysql:mysql /var/lib/mysqltmp
将以下 tmpfs 挂载添加到您的 /etc/fstab 文件中
tmpfs /var/lib/mysqltmp tmpfs rw,gid=mysql,uid=mysql,size=100M,mode=0750,noatime 0 0
添加到您的 /etc/my.cnf.d/server.cnf 文件的 mysqld 组下
tmpdir = /var/lib/mysqltmp
停止 mariadb.service,挂载 /var/lib/mysqltmp/,然后启动 mariadb.service。
时区表
尽管时区表是在安装过程中创建的,但它们不会自动填充。如果您打算在 SQL 查询中使用 CONVERT_TZ(),则需要填充这些表。
使用所有时区填充时区表
$ mariadb-tzinfo-to-sql /usr/share/zoneinfo | mariadb -u root -p mysql
(可选)您可以使用特定的时区文件来填充表
$ mariadb-tzinfo-to-sql timezone_file timezone_name | mariadb -u root -p mysql
安全
提升初始安全性
mariadb-secure-installation 命令将交互式地指导您完成多项推荐的安全措施,例如删除匿名帐户和删除测试数据库
# mariadb-secure-installation
仅在回环地址上监听
默认情况下,MariaDB 将在 0.0.0.0 地址上监听,这包括所有网络接口。为了限制 MariaDB 仅监听回环地址,请在 /etc/my.cnf.d/server.cnf 中添加以下行
[mariadb] bind-address = localhost
这将绑定到 127.0.0.1 和 ::1,并使 MariaDB 能够接收 IPv4 和 IPv6 连接。
仅通过 Unix 套接字进行本地访问
默认情况下,MariaDB 可通过 Unix 套接字和网络访问。如果 MariaDB 仅供 localhost 使用,您可以通过不监听 TCP 端口 3306 且仅监听 Unix 套接字来提高安全性。为此,请在 /etc/my.cnf.d/server.cnf 中添加以下行
[mariadb] skip-networking
您仍然可以像以前一样在本地登录,但只能使用 Unix 套接字。
授予远程访问权限
要允许远程访问 MariaDB 服务器,请确保 MariaDB 已启用网络且正在监听适当的接口。
授予任何 MariaDB 用户远程访问权限(以 root 为例)
# mariadb -u root -p
检查当前拥有远程访问权限的用户
SELECT User, Host FROM mysql.user WHERE Host <> 'localhost';
现在为您的用户(此处为 root)授予远程访问权限
GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.1.%' IDENTIFIED BY 'my_optional_remote_password' WITH GRANT OPTION;
您可以根据需要将 '%' 通配符更改为特定的主机。密码可以与用户的主密码不同。
配置对主目录的访问
出于安全原因,systemd 服务文件中包含 ProtectHome=true,这会阻止 MariaDB 访问 /home、/root 和 /run/user 层次结构下的文件。datadir 必须位于可访问的位置,并由 mysql 用户和组所有。
您可以按照此处所述,通过创建补充服务文件来修改此行为。
维护
在大版本更新时升级数据库
当 mariadb 发布主要版本更新时(例如从 mariadb-10.3.10-1 到 mariadb-10.9.4-1),明智的做法是升级系统数据库以使用新的服务器功能
# mariadb-upgrade -u root -p
要从 10.3.x 升级到 10.9.x
- 对 10.3.x 服务器执行正常关闭
- 升级软件包
- 针对正在运行的新守护进程运行
mariadb-upgrade(来自新版本软件包)
如果(新)守护进程无法启动,请参阅 #MariaDB 无法启动导致无法运行 mariadb-upgrade。
检查、优化和修复数据库
mariadb-clients 附带了 mariadb-check,可用于从 shell 检查、修复和优化数据库中的表。更多信息请参阅 mariadb-check(1)。下面列出了几个命令任务
检查所有数据库中的所有表
$ mariadb-check --all-databases -u root -p -c
分析所有数据库中的所有表
$ mariadb-check --all-databases -u root -p -a
修复所有数据库中的所有表
$ mariadb-check --all-databases -u root -p -r
优化所有数据库中的所有表
$ mariadb-check --all-databases -u root -p -o
备份
有各种工具和策略可以备份您的数据库。
如果您使用默认的 InnoDB 存储引擎,在线备份所有数据库同时进行时间点恢复(也称为“前滚”,即在需要恢复旧备份并重放自该备份以来发生的所有更改时)的一种建议方式是执行以下命令
$ mariadb-dump --single-transaction --flush-logs --events --routines --master-data=2 --all-databases -u root -p > all_databases.sql
这将提示输入MariaDB root 用户的密码,该密码在数据库#配置期间定义。
在命令行中指定密码强烈不推荐,因为它会通过 ps aux 或其他技术暴露给其他用户。相反,上述命令将提示输入该用户的密码,从而将其隐藏。
压缩
由于 SQL 表可能会变得非常大,建议将上述命令的输出通过管道传输到 压缩实用程序(如 xz(1))中
$ mariadb-dump --single-transaction --flush-logs --events --routines --master-data=2 --all-databases -u root -p | xz -z > all_databases.sql.xz
解压由此创建的备份并将其重新加载到服务器中,可以通过执行以下命令实现
$ xzcat all_databases.sql.xz | mariadb -u root -p
这将重新创建并重新填充之前备份的所有数据库(请参阅此条或此条)。
非交互式
如果您想设置用于 cron 作业或 systemd 定时器的非交互式备份脚本,请参阅选项文件和mariadb-dump的此示例。
基本上,您应该将以下部分添加到相关的配置文件中
[mariadb-dump] user=mysqluser password=secret
在此处提及用户是可选的,但这样做可以让您不必在命令行中提及它。如果您希望为包括 mariadb-client 在内的所有工具设置此项,请使用 [client] 组。
脚本示例
数据库可以转储到文件中以便于备份。以下 shell 脚本可以为您完成此操作,并在脚本所在目录中创建一个包含数据库转储的 db_backup.xz 文件
#!/bin/sh THISDIR=$(dirname $(readlink -f "$0")) mariadb-dump --single-transaction --flush-logs --events --routines --master-data=2 --all-databases \ | xz -z > $THISDIR/db_backup.xz echo 'purge master logs before date_sub(now(), interval 7 day);' | mariadb
另请参阅 MariaDB 手册中的官方 mariadb-dump 页面。
Holland 备份
一个名为 Holland Backup 的基于 Python 的软件包可以实现所有备份工作的自动化。它支持直接 mysqldump、LVM 快照到 tar 文件 (mysqllvm)、带有 mysqldump 的 LVM 快照 (mysqldump-lvm) 以及用于提取数据的 xtrabackup 方法。Holland 框架支持多种选项,并且高度可配置,可以解决几乎所有的备份情况。
主要的 hollandAUR 和 holland-commonAUR 软件包提供了核心框架;必须安装其中一个子软件包(holland-mysqldumpAUR、holland-mysqllvmAUR 和/或 holland-xtrabackupAUR)才能完全运行。每种方法配置示例位于 /usr/share/doc/holland/examples/ 目录,可以复制到 /etc/holland/backupsets/,也可以使用 holland mk-config 命令为指定的提供程序生成基本配置。
故障排除
MariaDB 无法启动导致无法运行 mariadb-upgrade
尝试在独立模式下运行 MariaDB
# mariadbd-safe --datadir=/var/lib/mysql/
然后运行
# mariadb-upgrade -u root -p
重置 root 密码
- 停止
mariadb.service。 - 启动带有安全功能的 MariaDB 服务器
# mariadbd-safe --skip-grant-tables --skip-networking &
- 连接到它
# mariadb -u root
- 更改 root 密码
MariaDB [mysql]> FLUSH PRIVILEGES; MariaDB [mysql]> ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password'; MariaDB [mysql]> exit
- 终止正在运行的 mariadbd* 进程
# kill $(cat /var/lib/mysql/$HOSTNAME.pid)
- 启动
mariadb.service。
检查并修复所有表
检查并自动修复所有数据库中的所有表,查看更多
# mariadb-check -A --auto-repair -u root -p
优化所有表
强制优化所有表,自动修复可能出现的表错误。
# mariadb-check -A --auto-repair -f -o -u root -p
在 ZFS 上运行时出现 OS error 22
如果将 MySQL 数据库放在 ZFS 上,可能会出现错误 InnoDB: Operating system error number 22 in a file operation。
一种解决方法是在 /etc/my.cnf.d/my.cnf 中禁用 aio_writes
/etc/my.cnf.d/my.cnf
[mariadb] innodb_use_native_aio = 0
无法通过 CLI 登录,但 phpmyadmin 工作正常
如果您使用的是较长(>80)的密码,可能会发生这种情况。mariadb CLI 无法处理 readline 模式下这么多的字符。因此,如果您计划使用推荐的密码输入模式
$ mariadb -u user -p
Password:
考虑将密码更改得短一些。
$ mariadb -u user -p"some-very-strong-password"
MariaDB 二进制日志占用了大量磁盘空间
默认情况下,mariadbd 在 /var/lib/mysql/mysql-bin.XXXXXX 创建二进制日志文件,编号递增。这些日志对于复制主服务器或数据恢复非常有用,但它们很容易占用大量磁盘空间。如果您不打算使用复制或数据恢复功能,可以通过注释掉 /etc/my.cnf.d/my.cnf 中的这些行,然后重启来禁用二进制日志记录
#log-bin=mysql-bin #binlog_format=mixed
或者,如果您想保留这些日志,但希望控制它们的大小并删除旧日志,您可以设置这些限制,然后重启
log-bin=mysql-bin expire_logs_days = 10 max_binlog_size = 100M
或者,存在一个 MariaDB 命令可以手动清除早于特定日志的日志。例如,您可能看到一个名为 mysql-bin.000023 的文件,并希望删除早于它的所有日志。只要设置了 log-bin=mysql-bin,您就可以运行
# mariadb -u root -p"PASSWORD" -e "PURGE BINARY LOGS TO 'mysql-bin.000023;"
OpenRC 无法启动 MariaDB
要将 MariaDB 与 OpenRC 一起使用,您需要在位于 /etc/my.cnf.d/my.cnf 的 MySQL 配置文件中的 [mariadb] 部分添加以下行。
user = mysql basedir = /usr datadir = /var/lib/mysql pid-file = /run/mysqld/mysql.pid
现在您应该可以使用以下命令启动 MariaDB
# rc-service mysql start
关于 max_open_files/table_open_cache 的限制更改警告
通过创建 systemd drop-in 文件(例如)来增加文件描述符的数量
/etc/systemd/system/mariadb.service.d/limit_nofile.conf
[Service] LimitNOFILE=8192
从 10.4 升级到 10.5 崩溃:“InnoDB: Upgrade after a crash is not supported. The redo log was created with MariaDB 10.4.x”
在 MariaDB 10.5 之前,重做日志被不必要地拆分为多个文件。[4]
永远不要将旧的二进制日志 /var/lib/mysql/ib_logfile* 移除。
要解决此问题,请安装 MariaDB 10.4。启动它并让它进行正常关闭。之后,您可以再次升级到 10.5。如果指定了其他版本的 MariaDB,也适用同样的方法。
表 'mysql.xxx' 在引擎中不存在
现象:运行 mariadb-upgrade 或 mariadb-check 时,返回一个或多个类似如下的错误
Table 'mysql.xxx' does not exist in engine
其中“xxx”通常是 mysql 数据库内部的系统表。
修复步骤:
- 在 MariaDB
${DATADIR}之外创建备份目录,例如在$HOME/mariadb_backup中。 - 将有问题的文件从
${DATADIR}/mysql/xxx.{frm,ibd}复制到备份目录。xxx.ibd可能不存在。 - 在
mariadb提示符下使用 DROP TABLE mysql.xxx 删除这些表。 - 运行 mariadb-check。如果成功,文件
xxx.frm和xxx.ibd应该被重新创建。 - 如果必要,重新运行 mariadb-upgrade。您可能需要 --force 选项。