# MariaDB (简体中文)

From ArchWiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

相关文章

- phpMyAdmin
- Adminer
- JDBC and MySQL
- Open Database Connectivity

翻译状态：本文是 MySQL 的翻译。上次翻译日期：2016-06-07。如果英文版本有所更改，则您可以帮助同步翻译。

MySQL是一个可靠的、高性能的、功能全面的数据库，旨在为用户提供长期免费的、向下兼容的、可取代MySQL的数据库服务。

注意： 自2013年起，MariaDB就被Arch Linux当作官方默认的MySQL实现[1]。Oracle MySQL 已被移动到 AUR，推荐所有用户升级到 MariaDB。参见这条公告。

## 安装

Archlinux 选择的 MySQL 默认实现 被称为 MariaDB。

安装 mariadb、mariadb-libs。

其它实现有 percona-server 和 Oracle mysqlAUR。

提示：

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

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

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

注意： 出于安全考虑，systemd 的 .service 文件设置了 `ProtectHome=true` 来禁止 MariaDB 访问 `/home`、`/root` 和 `/run/user` 目录内的文件。`datadir` 必须要放在以上文件夹之外，并且由 `mysql` 用户和用户组 所有。 如果要改变这个设置，你可以根据以下链接创建一个替代的 service 文件：[2]

然后 enable 或者 start `mariadb.service`。

提示： 如果数据目录使用的不是 `/var/lib/mysql`，需要在 `/etc/my.cnf.d/server.cnf` 文件的 `[mysqld]` 部分设置 `datadir=<数据目录>`

用下面这个命令启动数据库级别的安全配置助手，来配置一些必要的安全选项：

    # mysql_secure_installation

为了简化管理过程，可用的管理前端有 dbeaver, mysql-workbench, Adminer 或 phpMyAdmin. mysql-workbench 和 MariaDB 并不完全兼容，但是可以执行基本任务。

### 升级

升级了 MySQL 并启动之后，要运行这条命令：

    # mysql_upgrade -u root -p

### 由 Oracle MySQL 升级到 MariaDB

想要切换的用户需要安装 mariadb 和 mariadb-clients，然后执行 `mysql_upgrade` 来迁移系统：

    # systemctl stop mysqld
    # pacman -S mariadb libmariadbclient mariadb-clients
    # systemctl start mysqld
    # mysql_upgrade -p

注意： 在重新启动守护进程前，请先删除 `/var/lib/mysql` 中的 `ib_logfile0`, `ib_logfile1` 以及 `aria_log_control`。

## 配置

一旦你启动了MySQL服务器，你最好增加一个root账号来维护你的MySQL用户和数据库。如上面的初始化脚本输出的信息里所述，有手动或自动完成两种方法 ── 可以运行命令来设置root账号的密码，或者运行安全安装脚本。

现在可以使用你偏好的交互方式来进行进一步配置。例如可以用MySQL的命令行工具，以root账号登录你的MySQL服务器：

    $ mysql -p -u root

注意： 默认密码为空，直接敲回车键登录

### 添加新用户

以下是创建一个密码为'some_pass'的'monty'用户的示例,并赋予 mydb 完全操作权限：

    $ mysql -u root -p

    MariaDB> CREATE USER 'monty'@'localhost' IDENTIFIED BY 'some_pass';
    MariaDB> GRANT ALL PRIVILEGES ON mydb.* TO 'monty'@'localhost';
    MariaDB> FLUSH PRIVILEGES;
    MariaDB> quit

### 配置文件

MariaDB 会按照以下顺序读取配置文件 (根据 `mysqld --help --verbose` 的输出):

    /etc/my.cnf /etc/my.cnf.d/ ~/.my.cnf

请根据你需要的配置作用范围(对系统, 对用户...)来修改对应的配置文件。 点击 这里 了解更多信息。

### 禁用远程访问

MySQL 服务器默认可从网络访问。如果只有本机需要 MySQL，可以通过不监听 TCP 端口 3306 来增强安全性。要拒绝远程连接，取消注释 `/etc/mysql/my.cnf` 中以下这行：

    skip-networking

你仍能从本机登录。

### 启用自动补全

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

MySQL 默认禁用客户端自动补全功能。要在整个系统中启用它，编辑 `/etc/my.cnf.d/mysql-clients.cnf`，在`mysql`下 添加 `auto-rehash`。注意：不要将`auto-rehash`写在`mysqld`下，下次客户端启动时就会启用自动补全。

### 为数据库使用 UTF-8 编码

在 `/etc/mysql/my.cnf` 的 `mysqld` 下, 添加:

    [mysqld]
    init_connect                = 'SET collation_connection = utf8_general_ci,NAMES utf8'
    collation_server            = utf8_general_ci
    character_set_client        = utf8
    character_set_server        = utf8

### 使用内存作为临时文件存放点

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)

添加到 `/etc/fstab` 中。

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

将以下配置添加到 `/etc/mysql/my.cnf` 的 `mysqld` 组下:

     tmpdir      = /var/lib/mysqltmp

然后重启系统以使配置生效。

## 备份

数据库可以转储到文件以简化备份。以下 shell 脚本会替你在脚本所在目录创建一个 `db_backup.gz` 文件，包含数据库的转储：

    #!/bin/bash

    THISDIR=$(dirname $(readlink -f "$0"))

    mysqldump --single-transaction --flush-logs --master-data=2 --all-databases \
     | gzip > $THISDIR/db_backup.gz
    echo 'purge master logs before date_sub(now(), interval 7 day);' | mysql

参见 MySQL 手册的官方 `mysqldump` 页面。

## 故障排除

### MySQL 守护进程无法启动

如果 MySQL 无法启动且日志文件中没有任何信息，你可能需要检查 `/var/lib/mysql` 和 `/var/lib/mysql/mysql` 目录中文件的权限。如果这些目录中文件的所有者不是 `mysql:mysql`，你应该这样做：

    # chown mysql:mysql /var/lib/mysql -R

如果你仍旧碰到了权限问题，确保已把 `my.cnf` 拷贝到 `/etc/` 目录：

    # cp /etc/mysql/my.cnf /etc/my.cnf

然后尝试重新启动守护进程。

如果文件 `/var/lib/mysql/hostname.err` 中有如下错误：

    [ERROR] Can't start server : Bind on unix socket: Permission denied
    [ERROR] Do you already have another mysqld server running on socket: /var/run/mysqld/mysqld.sock ?
    [ERROR] Aborting

`/var/run/mysqld` 的权限可能是罪魁祸首：

    # chown mysql:mysql /var/run/mysqld -R

如果运行 mysqld 时出现了如下错误：

    Fatal error: Can’t open and lock privilege tables: Table ‘mysql.host’ doesn’t exist

在 `/usr` 目录中运行下列命令来安装默认的表：

    # cd /usr
    # mysql_install_db --user=mysql --ldata=/var/lib/mysql/

### 执行 mysql_upgrade 后 MySQL 不能启动

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

    # mysqld_safe --datadir=/var/lib/mysql/

然后再运行:

    # mysql_upgrade -u root -p

### 重置 root 密码

从 MariaDB 10.4 之后，`mysql.global_priv` 取代了原来的 `mysql.user`，所以更改用户密码的操作需要改变

停止 mysqld 守护进程，再执行以下命令：

    # mysqld_safe --skip-grant-tables &

连接到 MySQL 服务器，执行以下命令：

    # mysql -u root mysql

修改 root 密码：

    mysql> set password for 'root'@'localhost' = password('MyNewPass');
    mysql> FLUSH PRIVILEGES;
    mysql> exit

再启动 mysqld 守护进程。

### 检查并修复所有数据表

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

    # mysqlcheck -A --auto-repair -u root -p

### 优化所有数据表

强制优化所有数据表，自动修复可能出现的数据表错误

    # mysqlcheck -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

    [mysqld]
    ...
    innodb_use_native_aio = 0

但如果后续的安装脚本因为上述问题出错，那么 MySQL/MariaDB 可能会处于非法的状态中。可以执行以下命令从非法状态中恢复：

    rm -rf /var/lib/mysql/*
    mysql_install_db --user=mysql --basedir=/usr --datadir=/var/lib/mysql
    chown -R mysql:mysql /var/lib/mysql &>/dev/null
    /usr/bin/systemd-tmpfiles --create mysql.conf

以上命令全部执行后，MySQL/MariaDB 应该就能正确安装了。

### 无法通过命令行登陆, 但是 phpmyadmin 正常工作

当使用了超长 (>70-75) 的密码后，这个问题有可能发生。 由于某些因素，5.5.36 版本的 mysql 的命令行不能在 readline 模式中处理那么多的字符。 所以如果打算使用推荐的密码输入方式：

    $ mysql -u <user> -p
    Password:

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

注意： 您依然可以通过在命令行参数中指定密码来登陆

    $ mysql -u <user> -p"<some-veryveryveryveryveryveryveryveryveryveryveryveryveryveryvery-long-and-veryveryveryveryveryveryveryveryveryvery-strong-password>"

警告： 但这样做很危险，因为您的密码很可能会泄漏到某个地方，例如，日志。只有当遇到紧急情况才能考虑这么做，并且事后不要忘记更改密码。

### MySQL 日志文件占用太多空间

默认情况下， mysqld 会在 `/var/lib/mysql` 下创建二进制日志文件。这在某些场景下是很有用的。但是这些日志文件也可能耗光您的硬盘空间。如果需要，您可以在 `/etc/mysql/my.cnf` 中注释掉以下两行来禁用日志：

    #log-bin=mysql-bin
    #binlog_format=mixed

或者限制 logfile 的大小：

    expire_logs_days = 10
    max_binlog_size  = 100M

另外，您也可以执行以下命令来清除 `/var/lib/mysql` 里的一些日志文件来释放硬盘空间：

    #mysql -u root -p"PASSWORD" -e "PURGE BINARY LOGS TO 'mysql-bin.0000xx';"

## 更多资源

- LAMP (简体中文) - Arch wiki 文章，涵盖安装 LAMP 服务器 (Linux Apache MySQL PHP)
- https://mariadb.org/ - Community-driven 实现
- https://www.mysql.com/ - Oracle 实现
- https://www.percona.com/software - Percona 实现
- MariaDB knowledge Base
- MySQL documentation
- PHP - ArchWiki article on PHP.
- MySQL Performance Tuning Scripts and Know-How

Category:

- Database management systems (简体中文)