MariaDB

来自 ArchWiki

MariaDB 是一个可靠、高性能且功能齐全的数据库服务器,旨在成为 MySQL 的“始终免费、向后兼容、即插即用”的替代品。自 2013 年以来,MariaDB 一直是 Arch Linux 的 MySQL 默认实现。[1]

安装

MariaDB 是 Arch Linux 中 MySQL 的默认实现,通过 mariadb 软件包提供。

提示
  • 如果数据库(位于 /var/lib/mysql)位于 Btrfs 文件系统上,您应该在创建任何数据库之前考虑禁用该目录的 写时复制 (CoW)
  • 如果数据库位于 ZFS 文件系统上,您应该在创建任何数据库之前查阅 ZFS#数据库

安装 mariadb,并在启动 mariadb.service 之前运行以下命令

# mariadb-install-db --user=mysql --basedir=/usr --datadir=/var/lib/mysql
提示: 如果您使用 /var/lib/mysql 以外的目录作为数据目录,则需要在 /etc/my.cnf.d/server.cnf[mariadb] 部分下设置 datadir=您的数据目录

现在可以启动和/或启用 mariadb.service

注意: 在继续之前,建议提高 MariaDB 初始安装的安全性

为了简化管理,您可能需要安装一个前端

配置

默认情况下,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

警告: 在更改字符集之前,请务必先创建备份。
注意
  • mariadb 软件包已经使用 utf8mb4 作为字符集,utf8mb4_unicode_ci 作为排序规则。使用默认(字符)设置的用户可能希望跳过本节。
  • 推荐使用 UTF8MB4 而不是 UTF-8,因为它允许完全的 Unicode 支持 [2] [3]

追加以下值到位于 /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
警告: 运行此命令后,请注意 TCP 端口 3306 仍将打开,但会拒绝连接并显示错误消息。要阻止 MySQL 监听外部接口,请参阅#仅监听环回地址#仅通过 Unix 套接字启用本地访问部分。

仅监听环回地址

默认情况下,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 服务器,请考虑使用 Secure ShellVNCVPN

要允许远程访问 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;

如果需要,您可以将 '%' 通配符更改为特定主机。密码可以与用户的主密码不同。

配置对 home 目录的访问

出于安全原因,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-upgrade,因为 MariaDB 无法启动

检查、优化和修复数据库

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 Backup

名为 Holland Backup 的基于 Python 的软件包允许自动化所有备份工作。它支持直接 mysqldump、LVM 快照到 tar 文件 (mysqllvm)、带有 mysqldump 的 LVM 快照 (mysqldump-lvm) 和 xtrabackup 方法来提取数据。Holland 框架支持多种选项,并且高度可配置,以解决几乎任何备份情况。

主要的 hollandAURholland-commonAUR 软件包提供核心框架;子软件包之一(holland-mysqldumpAURholland-mysqllvmAUR 和/或 holland-xtrabackupAUR)必须安装才能完全运行。每种方法的示例配置都在 /usr/share/doc/holland/examples/ 目录中,可以复制到 /etc/holland/backupsets/,以及使用 holland mk-config 命令为命名的提供程序生成基本配置。

故障排除

无法运行 mariadb-upgrade,因为 MariaDB 无法启动

尝试在独立模式下运行 MariaDB

# mariadbd-safe --datadir=/var/lib/mysql/

然后运行

# mariadb-upgrade -u root -p

重置 root 密码

  1. 停止 mariadb.service
  2. 使用安全功能启动 MariaDB 服务器
    # mariadbd-safe --skip-grant-tables --skip-networking &
  3. 连接到它
    # mariadb -u root
  4. 更改 root 密码
    MariaDB [mysql]> FLUSH PRIVILEGES;
    MariaDB [mysql]> ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';
    MariaDB [mysql]> exit
    
  5. 杀死正在运行的 mariadbd* 进程
    # kill $(cat /var/lib/mysql/$HOSTNAME.pid)
  6. 启动 mariadb.service

检查和修复所有表

检查和自动修复所有数据库中的所有表,查看更多

# mariadb-check -A --auto-repair -u root -p

优化所有表

强制优化所有表,自动修复可能出现的表错误。

# mariadb-check -A --auto-repair -f -o -u root -p

在 ZFS 上运行时出现 OS 错误 22

如果在 ZFS 上使用 MySQL 数据库,可能会发生错误 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 命令的参数来登录。
警告: 此行为被认为是危险的,因为您的密码可能会泄露,例如泄露到日志中。仅在紧急情况下使用它,并且不要忘记之后立即更改密码。
$ mariadb -u user -p"some-very-strong-password"

MariaDB 二进制日志占用大量磁盘空间

此文章或章节已过时。

原因: /etc/my.cnf.d/my.cnf 不再存在(在 Talk:MariaDB#“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 放置文件来增加文件描述符的数量,例如

/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 之前,redo 日志被不必要地拆分为多个文件。[4]

切勿移除旧的二进制日志 /var/lib/mysql/ib_logfile*

要解决此问题,请安装 MariaDB 10.4。启动它并使其进行干净的关闭。发生这种情况后,您可以再次升级到 10.5。如果指定了 MariaDB 的另一个版本,则同样适用。

表 'mysql.xxx' 在引擎中不存在

症状:运行 mariadb-upgrademariadb-check 时,它返回一个或多个如下错误

Table 'mysql.xxx' does not exist in engine

其中“xxx”通常是 mysql 数据库中的系统表。

修复步骤:

  1. 在 MariaDB ${DATADIR}</nowiki> 之外创建备份目录,例如在 $HOME/mariadb_backup 中。
  2. 将有问题的 ${DATADIR}/mysql/xxx.{frm,ibd}</nowiki> 文件复制到备份目录。xxx.ibd 可能不存在。
  3. mariadb 提示符下使用 DROP TABLE mysql.xxx 删除表。
  4. 运行 mariadb-check。成功后,文件 xxx.frmxxx.ibd 应该会再次创建。
  5. 如果需要,重新运行 mariadb-upgrade。您可能需要 --force 选项。

参见