跳转到内容

MariaDB

来自 Arch Linux 中文维基

MariaDB 是一个可靠的、高性能的、功能全面的数据库,旨在为用户提供长期免费、向下兼容能直接替代MySQL的数据库服务。自2013年起,MariaDB就被Arch Linux当作官方默认的MySQL实现[1]


安装[编辑 | 编辑源代码]

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

提示:
  • 如果数据库 (位于 /var/lib/mysql) 运行在 Btrfs 分区之上, 你应当在创建数据库之前禁用 Copy-on-Write 特性。
  • 如果数据库运行在 ZFS 分区之上, 你应该在创建数据库之前参阅 ZFS#Databases

安装 mariadb 软件包之后,你必须在启动 mariadb.service 之前运行下面这条命令:

# mariadb-install-db --user=mysql --basedir=/usr --datadir=/var/lib/mysql

然后 enable 或者 start mariadb.service

提示:如果数据目录使用的不是 /var/lib/mysql,需要在 /etc/my.cnf.d/server.cnf 文件的 [mysqld] 部分设置 datadir=<数据目录>
注意:在继续之前,建议 提高 MariaDB 安装的初始安全性

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

配置[编辑 | 编辑源代码]

默认情况下,root 用户和运行服务器的用户都可以管理数据库。

要管理服务器,可以以运行服务器的用户身份运行 mariadb

[mysql]$ mariadb

或者以 root 身份运行:

# mariadb

添加用户[编辑 | 编辑源代码]

以下是创建一个密码为'some_pass'的'monty'用户的示例,并赋予 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 为扩展名的配置文件,以确保升级时保留您的配置。

根据您想要进行的更改范围(系统范围、仅用户...),使用相应的文件。有关更多信息,请参阅知识库中的[此条目](https://mariadb.com/kb/en/library/configuring-mariadb-with-option-files/)。

启用自动补全[编辑 | 编辑源代码]

注意:启用这项功能会增加客户端启动时间。

MySQL 默认禁用客户端自动补全功能。要在整个系统中启用它,编辑 /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 以应用更改。更改字符集不会改变现有表格格式,只会影响新创建的表格以及检索数据的协议交互。

参见#Maintenance 以优化和检查数据库健康状况。

使用内存作为临时文件存放点[编辑 | 编辑源代码]

MySQL 存储临时文件的目录名是 tmpdir

创建一个临时目录:

# mkdir -pv /var/lib/mysqltmp
# chown mysql:mysql /var/lib/mysqltmp

通过命令找出 mysql 的 id 和 gid:

$ id mysql
uid=27(mysql) gid=27(mysql) groups=27(mysql)

添加 tmpfs/etc/fstab 中:

 tmpfs   /var/lib/mysqltmp   tmpfs   rw,gid=27,uid=27,size=100M,mode=0750,noatime   0 0

将以下配置添加到 /etc/mysql/my.cnfmysqld 组下:

 tmpdir      = /var/lib/mysqltmp

Stop mariadb.service, mount /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 sockets 和网络访问。如果只需要在本地主机上使用 MariaDB,则可以通过不在 TCP 端口 3306 上监听,而是仅在 Unix sockets 上监听来提高安全性。要实现这一点,请在/etc/my.cnf.d/server.cnf文件中添加以下行:

[mariadb]
skip-networking

您仍然可以像以前一样在本地登录,但只能使用 Unix 套接字。

授权远程访问[编辑 | 编辑源代码]

警告:这不被视为最佳实践,因为可能会引起安全问题。如果你想要从网络内/外的另一台主机上管理 MariaDB 服务器,请考虑使用安全外壳协议(Secure Shell),虚拟网络计算机(VNC)虚拟专用网络(VPN)

要允许远程访问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 的 .service 文件通过 ProtectHome=true 禁止 MariaDB 访问 /home/root/run/user 目录内的文件。datadir 必须要放在以上文件夹之外,并且由 mysql 用户和用户组 所有。 如果要改变这个设置,可以根据以下链接创建一个替代的 service 文件:[4]

维护[编辑 | 编辑源代码]

大版本升级时升级数据库[编辑 | 编辑源代码]

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)。以下是一些常用命令:

要检查所有数据库中的所有表:

备份[编辑 | 编辑源代码]

有各种各样的工具和策略可以备份你的数据库。

如果你正在使用默认的 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 命令为指定的提供者生成基本配置。

故障排除[编辑 | 编辑源代码]

执行 mysql_upgrade 后 MySQL 不能启动[编辑 | 编辑源代码]

试试安全模式下运行的 MySQL:

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

然后再运行:

# mariadb-upgrade -u root -p

重置 root 密码[编辑 | 编辑源代码]

  1. 停止 mariadb.service.
  2. 用安全方式启动服务:
    # 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

OS error 22 when running on ZFS[编辑 | 编辑源代码]

如果您正在使用 ZFS 并且遇见了如下错误

InnoDB: Operating system error number 22 in a file operation.

那么就需要修改 /etc/mysql/my.cnf 中的设置来禁用 aio_writes

[mariadb]
...
innodb_use_native_aio = 0

无法通过命令行登录, 但是 phpmyadmin 正常工作[编辑 | 编辑源代码]

当使用了超长 (>80) 的密码后,这个问题有可能发生。 mariadb 的命令行不能在 readline 模式中处理那么多的字符。 所以如果打算使用推荐的密码输入方式:

$ mariadb -u user -p
Password:

不妨考虑更换一个长度短一点的密码。

注意:您依然可以通过在命令行参数中指定密码来登录
$ mysql -u <user> -p"some-very-strong-password"
警告:但这样做很危险,因为您的密码很可能会泄漏到某个地方,例如,日志。只有当遇到紧急情况才能考虑这么做,并且事后不要忘记更改密码。

MySQL 日志文件占用太多空间[编辑 | 编辑源代码]

本文或本节内容已经过时。

原因: /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[编辑 | 编辑源代码]

要使用 OpenRC 启动 MariaDB,您需要在 MySQL 配置文件 /etc/my.cnf.d/my.cnf[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 之前,redo log 被不必要地分割成多个文件。[5]

千万不要删除旧的二进制日志 /var/lib/mysql/ib_logfile*

要解决此问题,请安装 MariaDB 10.4。启动它并让它进行干净的关闭。之后,您可以再次升级到 10.5。如果指定了其他版本的 MariaDB,同样适用。

Table 'mysql.xxx' does not exist in engine[编辑 | 编辑源代码]

症状:运行 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 选项。

更多资源[编辑 | 编辑源代码]