在 Raspberry Pi OS Lite 220922 上安装 MariaDB

☁说起开源的关系数据库,大家都会想到 MySQL,但由于其最终被 Oracle收购,有闭源的风险,所以我的项目经常使用的是与其兼容的 MariaDB

安装

从软件仓库安装:

sudo apt-get install mariadb-server

等待安装完成后,查看其状态:

sudo systemctl status maraidb

发现其已经启动运行了,并且也加入Systemd中开机自启动了,这一点可以看出 Debian 比 RedHat/CentOS 更加自动化。

但实际上,我们往往需要自定义配置如字符集、排序、数据存储位置等等。

配置

50-client.cnf

sudo nano /etc/mysql/mariadb.conf.d/50-client.cnf

编辑内容如下:

[client]
# 字符集
default-character-set = utf8mb4

50-server.cnf

mkdir -p /data/mariadb
chown mysql:mysql /data/mariadb

sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf

编辑内容如下:

[mysqld]
# 如果是二进制压缩包解压方式安装,则需要明确指定基础目录
#basedir = /usr/lib/mysql

# 数据存储位置
datadir = /data/mariadb

# 注释掉下面这一行,本机之外可以访问
#bind-address = 127.0.0.1

# 注释掉下面这一行,仅通过 IP 地址访问
skip-name-resolve

# 字符集
character-set-server  = utf8mb4
collation-server      = utf8mb4_general_ci
init-connect          = 'SET NAMES utf8mb4'
skip-character-set-client-handshake

问题

改了配置后,重启服务,发现失败:

pi@raspberrypi:~ $ sudo systemctl restart mariadb
错误信息……
pi@raspberrypi:~ $ sudo systemctl status mariadb
● mariadb.service - MariaDB 10.5.18 database server
     Loaded: loaded (/lib/systemd/system/mariadb.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Sat 2023-01-14 09:48:28 CST; 1min 33s ago
       Docs: man:mariadbd(8)
             https://mariadb.com/kb/en/library/systemd/
    Process: 11129 ExecStartPre=/usr/bin/install -m 755 -o mysql -g root -d /var/run/mysqld (code=exited, status=0/SUCCESS)
    Process: 11130 ExecStartPre=/bin/sh -c systemctl unset-environment _WSREP_START_POSITION (code=exited, status=0/SUCCESS)
    Process: 11132 ExecStartPre=/bin/sh -c [ ! -e /usr/bin/galera_recovery ] && VAR= ||   VAR=`cd /usr/bin/..; /usr/bin/galera_recovery`; [ $? -eq 0 ]   && syst>
    Process: 11194 ExecStart=/usr/sbin/mariadbd $MYSQLD_OPTS $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION (code=exited, status=1/FAILURE)
   Main PID: 11194 (code=exited, status=1/FAILURE)
     Status: "MariaDB server is down"
        CPU: 383ms

Jan 14 09:48:28 raspberrypi mariadbd[11194]: 2023-01-14  9:48:28 0 [Note] Plugin 'FEEDBACK' is disabled.
Jan 14 09:48:28 raspberrypi mariadbd[11194]: 2023-01-14  9:48:28 0 [ERROR] Could not open mysql.plugin table: "Table 'mysql.plugin' doesn't exist". Some plugins>
Jan 14 09:48:28 raspberrypi mariadbd[11194]: 2023-01-14  9:48:28 1 [Warning] Failed to load slave replication state from table mysql.gtid_slave_pos: 1017: Can't>
Jan 14 09:48:28 raspberrypi mariadbd[11194]: 2023-01-14  9:48:28 0 [ERROR] Can't open and lock privilege tables: Table 'mysql.servers' doesn't exist
Jan 14 09:48:28 raspberrypi mariadbd[11194]: 2023-01-14  9:48:28 0 [Note] Server socket created on IP: '::'.
Jan 14 09:48:28 raspberrypi mariadbd[11194]: 2023-01-14  9:48:28 0 [ERROR] Fatal error: Can't open and lock privilege tables: Table 'mysql.db' doesn't exist
Jan 14 09:48:28 raspberrypi mariadbd[11194]: 2023-01-14  9:48:28 0 [ERROR] Aborting
Jan 14 09:48:28 raspberrypi systemd[1]: mariadb.service: Main process exited, code=exited, status=1/FAILURE
Jan 14 09:48:28 raspberrypi systemd[1]: mariadb.service: Failed with result 'exit-code'.
Jan 14 09:48:28 raspberrypi systemd[1]: Failed to start MariaDB 10.5.18 database server.

网上搜索 Could not open mysql.plugin table,发现是新的数据目录没有数据初始化导致,执行数据库初始化脚本:

pi@raspberrypi:~ $ sudo mysql_install_db --datadir=/data/mariadb --user=mysql
Installing MariaDB/MySQL system tables in '/data/mariadb' ...
2023-01-14  9:58:27 1 [Warning] Failed to load slave replication state from table mysql.gtid_slave_pos: 1017: Can't find file: './mysql/' (errno: 2 "No such file or directory")
OK

To start mysqld at boot time you have to copy
support-files/mysql.server to the right place for your system


Two all-privilege accounts were created.
One is root@localhost, it has no password, but you need to
be system 'root' user to connect. Use, for example, sudo mysql
The second is mysql@localhost, it has no password either, but
you need to be the system 'mysql' user to connect.
After connecting you can set the password, if you would need to be
able to connect as any of these users with a password and without sudo

See the MariaDB Knowledgebase at https://mariadb.com/kb

You can start the MariaDB daemon with:
cd '/usr' ; /usr/bin/mysqld_safe --datadir='/data/mariadb'

You can test the MariaDB daemon with mysql-test-run.pl
cd '/usr/mysql-test' ; perl mysql-test-run.pl

Please report any problems at https://mariadb.org/jira

The latest information about MariaDB is available at https://mariadb.org/.

Consider joining MariaDB's strong and vibrant community:
https://mariadb.org/get-involved/ 

然后启动、查看服务:

pi@raspberrypi:~ $ sudo systemctl start mariadb
pi@raspberrypi:~ $ sudo systemctl status mariadb
● mariadb.service - MariaDB 10.5.18 database server
     Loaded: loaded (/lib/systemd/system/mariadb.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2023-01-14 10:02:52 CST; 3min 2s ago
       Docs: man:mariadbd(8)
             https://mariadb.com/kb/en/library/systemd/
    Process: 18788 ExecStartPre=/usr/bin/install -m 755 -o mysql -g root -d /var/run/mysqld (code=exited, status=0/SUCCESS)
    Process: 18789 ExecStartPre=/bin/sh -c systemctl unset-environment _WSREP_START_POSITION (code=exited, status=0/SUCCESS)
    Process: 18791 ExecStartPre=/bin/sh -c [ ! -e /usr/bin/galera_recovery ] && VAR= ||   VAR=`cd /usr/bin/..; /usr/bin/galera_recovery`; [ $? -eq 0 ]   && syst>
    Process: 18877 ExecStartPost=/bin/sh -c systemctl unset-environment _WSREP_START_POSITION (code=exited, status=0/SUCCESS)
    Process: 18879 ExecStartPost=/etc/mysql/debian-start (code=exited, status=0/SUCCESS)
   Main PID: 18860 (mariadbd)
     Status: "Taking your SQL requests now..."
      Tasks: 10 (limit: 8986)
        CPU: 1.026s
     CGroup: /system.slice/mariadb.service
             └─18860 /usr/sbin/mariadbd

Jan 14 10:02:52 raspberrypi mariadbd[18860]: 2023-01-14 10:02:52 0 [Note] Added new Master_info '' to hash table
Jan 14 10:02:52 raspberrypi mariadbd[18860]: 2023-01-14 10:02:52 0 [Note] /usr/sbin/mariadbd: ready for connections.
Jan 14 10:02:52 raspberrypi mariadbd[18860]: Version: '10.5.18-MariaDB-0+deb11u1-log'  socket: '/run/mysqld/mysqld.sock'  port: 3306  Debian 11
Jan 14 10:02:52 raspberrypi systemd[1]: Started MariaDB 10.5.18 database server.
Jan 14 10:02:52 raspberrypi /etc/mysql/debian-start[18884]: Looking for 'mariadb' as: /usr/bin/mariadb
Jan 14 10:02:52 raspberrypi /etc/mysql/debian-start[18884]: Looking for 'mariadb-check' as: /usr/bin/mariadb-check
Jan 14 10:02:52 raspberrypi /etc/mysql/debian-start[18884]: This installation of MariaDB is already upgraded to 10.5.18-MariaDB.
Jan 14 10:02:52 raspberrypi /etc/mysql/debian-start[18884]: There is no need to run mysql_upgrade again for 10.5.18-MariaDB.
Jan 14 10:02:52 raspberrypi /etc/mysql/debian-start[18884]: You can use --force if you still want to run mysql_upgrade
Jan 14 10:04:46 raspberrypi mariadbd[18860]: 2023-01-14 10:04:46 39 [Warning] Access denied for user 'root'@'localhost'

成功了!

收尾

安全脚本

按照官网建议,还需要执行安全安装脚本:

pi@raspberrypi:~ $ sudo mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
haven't set the root password yet, you should just press enter here.

Enter current password for root (enter for none):
OK, successfully used password, moving on...

Setting the root password or using the unix_socket ensures that nobody
can log into the MariaDB root user without the proper authorisation.

You already have your root account protected, so you can safely answer 'n'.

Switch to unix_socket authentication [Y/n] n
 ... skipping.

You already have your root account protected, so you can safely answer 'n'.

Change the root password? [Y/n] y
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

创建用户

-- 远程登录
CREATE USER 'username'@'172.17.%' IDENTIFIED BY 'password';
-- 授权格式
GRANT privileges ON databasename.tablename TO 'username'@'172.17.%'[ WITH GRANT OPTION]
-- 读写权限
GRANT SELECT, INSERT ON test.user TO 'username'@'172.17.%';
-- 所有权限
GRANT ALL ON *.* TO 'username'@'172.17.%';

-- 本地登录
CREATE USER 'username'@localhost IDENTIFIED BY 'password';

-- 刷新权限
flush privileges;

验证

pi@raspberrypi:~ $ mysql -u root -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 40
Server version: 10.5.18-MariaDB-0+deb11u1-log Debian 11

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show variables like '%char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8mb4                    |
| character_set_connection | utf8mb4                    |
| character_set_database   | utf8mb4                    |
| character_set_filesystem | binary                     |
| character_set_results    | utf8mb4                    |
| character_set_server     | utf8mb4                    |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.004 sec)

MariaDB [(none)]> show variables like '%zone%';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone | CST    |
| time_zone        | SYSTEM |
+------------------+--------+
2 rows in set (0.003 sec)

MariaDB [(none)]> select now();
+---------------------+
| now()               |
+---------------------+
| 2023-01-14 10:05:16 |
+---------------------+
1 row in set (0.001 sec)

MariaDB [(none)]> exit
Bye