跳转至内容

MariaDB

来自 ArchWiki

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

安装

MariaDB 是 Arch Linux 中 MySQL 的默认实现,由 mariadbmariadb-lts 软件包提供。

提示
  • 如果数据库(位于 /var/lib/mysql)位于 Btrfs 文件系统上,则在软件包安装期间会自动禁用 写时复制 (CoW) 属性。这是通过 MariaDB 软件包提供的 systemd-tmpfiles(8) 配置文件(/usr/lib/tmpfiles.d/mariadb.conf)完成的,该文件在 MySQL 数据目录上设置了 +C (NOCOW) 属性。不再需要手动干预。
  • 如果数据库位于 ZFS 文件系统上,在创建任何数据库之前,您应咨询 ZFS#Databases

安装 mariadbmariadb-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

现在可以启动和/或启用 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 服务器,请考虑使用 SSHVNCVPN

要允许远程访问 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 框架支持多种选项,并且高度可配置,可以解决几乎所有的备份情况。

主要的 hollandAURholland-commonAUR 软件包提供了核心框架;必须安装其中一个子软件包(holland-mysqldumpAURholland-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 密码

  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 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 命令来登录。
警告: 这种行为被认为是危险的,因为您的密码可能会泄漏(例如泄漏到日志中)。仅在紧急情况下使用,并且不要忘记事后立即更改密码。
$ mariadb -u user -p"some-very-strong-password"

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

本文或本章节已过时。

原因: /etc/my.cnf.d/my.cnf 不再存在(讨论请见 Talk:MariaDB#Mistakes in "MariaDB binary logs are taking up huge disk space"

默认情况下,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-upgrademariadb-check 时,返回一个或多个类似如下的错误

Table 'mysql.xxx' does not exist in engine

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

修复步骤:

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

参见

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.