在RHEL 7上使用SELinux设置MariaDB服务器

时间:2020-03-21 11:42:15  来源:igfitidea点击:

我们将安装和配置MariaDB服务器,并创建一个简单的数据库架构。
将介绍MariaDB备份和还原过程以及一些常见的MariaDB错误。

我们在本文中使用RHEL 7.0服务器,并将SELinux设置为强制模式。

MariaDB安装

安装MariaDB软件包,启用服务并允许传入连接到标准MySQL TCP端口3306。

# yum install -y mariadb mariadb-server
# systemctl enable mariadb && systemctl start mariadb
# firewall-cmd --permanent --add-service=mysql
# firewall-cmd --reload

使用mysql_secure_installation保护mariadb。
为数据库root用户设置密码,禁用远程root用户访问,并删除测试数据库和所有匿名用户。

# mysql_secure_installation

重新启动服务:

# systemctl restart mariadb

通过执行简单的SQL查询来测试root登录:

# mysql -uroot -ppassword -e "select @@version; show databases"
+----------------+
| @@version      |
+----------------+
| 5.5.35-MariaDB |
+----------------+
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+

配置MariaDB

对于小型测试系统,有一个方便的示例配置文件/usr/share/mysql/my-small.cnf,可以用作基本模板。
文件" /usr/share/mysql/my-innodb-heavy-4G.cnf"充满了有用的注释,可以在需要复杂设置的情况下使用。

更改MariaDB端口

我们将默认的MariaDB端口从3306更改为5506。

打开文件" /etc/my.cnf"进行编辑,并添加以下行:

[mysqld]
port = 5506

允许防火墙访问新端口:

# firewall-cmd --permanent --add-port=5506/tcp
# firewall-cmd --reload

告诉SELinux允许MariaDB绑定到TCP端口5506:

# semanage port -a -t mysqld_port_t 5506 -p tcp

最后,重新启动服务:

# systemctl restart mariadb

校验:

# ss -nlp | grep 5506
tcp    LISTEN  0 50  *:5506 *:* users:(("mysqld",5665,13))

更改MariaDB数据目录

首先停止MariaDB服务:

# systemctl stop mariadb

创建一个新目录"/mariadb_data"以存储数据文件并将所有权更改为mysql:

# mkdir /mariadb_data
# chown mysql:mysql /mariadb_data

将现有内容复制到新位置:

# cp -Rp /var/lib/mysql/* /mariadb_data/

/mariadb_data下的所有内容添加SELinux文件上下文:

# semanage fcontext -a -t mysqld_db_t "/mariadb_data(/.*)?"
# restorecon -Rv /mariadb_data

打开文件" /etc/my.cnf"进行编辑,然后更改数据目录以指向新位置:

#datadir=/var/lib/mysql
datadir = /mariadb_data

启动服务:

# systemctl start mariadb

校验:

# mysql -uroot -ppassword -e 'SHOW VARIABLES WHERE Variable_Name = "datadir"'
+---------------+----------------+
| Variable_name | Value          |
+---------------+----------------+
| datadir       | /mariadb_data/|
+---------------+----------------+

更改收听地址

我们希望启用通过所有IP地址(IPv4和IPv6)的访问。
添加以下文件/etc/my.cnf

bind-address = ::

请注意,将其保留为空白将仅启用通过IPv4的访问。
也可以指定一个特定的IP地址。

如果我们要禁用所有网络通信,则可以将skip-networking = 1添加到配置文件中。

重新启动mariadb服务并验证:

# ss -nlp | grep 5506
tcp LISTEN 0 50 :::5506 :::* users:(("mysqld",7064,13))

将表存储为单独的文件

以某种方式配置MariaDB,以便将每个InnoDB表(包括其索引)存储为单独的.ibd数据文件。
这样,ibdata1将不会变大。

将以下内容添加到文件" /etc/my.cnf"并重新启动服务:

[mysqld]
innodb-file-per-table=1

请注意,MariaDB 5.6默认情况下启用每表innodb-file-per-table。

增加最大允许的数据包大小

将服务器的最大允许数据包值设置为16MB(默认为1M),然后重新启动服务。
如果服务器必须处理大查询,我们需要增加它。

[mysqld]
max-allowed-packet=16M

使用MariaDB

创建一个新的数据库和一个新的用户

以MariaDB根用户身份登录。
列出现有用户,创建一个新的数据库test1,向数据库用户dbuser1授予数据库test1的所有特权,刷新特权并显示对新创建的用户的授予。

# mysql -uroot -ppassword
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> SELECT user,host FROM mysql.user;
+------+-----------+
| user | host      |
+------+-----------+
| root | 127.0.0.1 |
| root | ::1       |
| root | localhost |
+------+-----------+
MariaDB [(none)]> CREATE DATABASE test1;
MariaDB [(none)]> SET old_passwords = 0;
MariaDB [(none)]> CREATE USER 'dbuser1'@'localhost' IDENTIFIED BY "password";
MariaDB [(none)]> GRANT ALL PRIVILEGES ON test1.* TO 'dbuser1'@'localhost' IDENTIFIED BY "password";
MariaDB [(none)]> FLUSH PRIVILEGES;
MariaDB [(none)]> SHOW GRANTS FOR 'dbuser1'@'localhost';
+-----------------------------------------------------------------------------+
| Grants for [email protected]                                                |
+-----------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'dbuser1'@'localhost' IDENTIFIED BY PASSWORD 'secret' |
| GRANT ALL PRIVILEGES ON `test1`.* TO 'dbuser1'@'localhost'                  |
+-----------------------------------------------------------------------------+
MariaDB [(none)]> SELECT user,host,Grant_priv,Super_priv FROM mysql.user;
+-----------+-----------+------------+------------+
| user      | host      | Grant_priv | Super_priv |
+-----------+-----------+------------+------------+
| root      | localhost | Y          | Y          |
| root      | 127.0.0.1 | Y          | Y          |
| root      | ::1       | Y          | Y          |
| dbuser1   | localhost | N          | N          |
+-----------+-----------+------------+------------+
MariaDB [(none)]> exit

如果我们需要更改数据库用户的dbuser1密码,可以通过以下方式进行更改:

MariaDB [(none)]> SET PASSWORD FOR 'dbuser1'@'localhost' = PASSWORD('new_password');

或者,如果我们想从MariaDB中删除用户dbuser1:

MariaDB [(none)]> DELETE FROM mysql.user WHERE user='dbuser1';

我们还可以从MariaDB中删除用户dbuser1:

MariaDB [(none)]> DROP USER [email protected];

如果我们要拥有一个WordPress数据库,下面将是一个为数据库用户dbuser1授予数据库test1特权的公平示例:

MariaDB [(none)]> GRANT SELECT,INSERT,UPDATE,DELETE,ALTER,CREATE,DROP,INDEX ON test1.* TO 'dbuser1'@'localhost' IDENTIFIED BY "password";

创建一个简单的数据库架构并针对数据库执行简单的SQL查询

# mysql -uroot -ppassword

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> use test1;
Database changed
MariaDB [test1]> create table services (id INT(10) unsigned, name VARCHAR(20), version INT(10));
MariaDB [test1]> show tables;
+-----------------+
| Tables_in_test1 |
+-----------------+
| services        |
+-----------------+
MariaDB [test1]> describe services;
+---------+------------------+------+-----+---------+-------+
| Field   | Type             | Null | Key | Default | Extra |
+---------+------------------+------+-----+---------+-------+
| id      | int(10) unsigned | YES  |     | NULL    |       |
| name    | varchar(20)      | YES  |     | NULL    |       |
| version | int(10)          | YES  |     | NULL    |       |
+---------+------------------+------+-----+---------+-------+
MariaDB [test1]> insert into services (id, name, version) values (1, "apache", "2");
MariaDB [test1]> insert into services (id, name, version) values (2, "samba", "4");
MariaDB [test1]> select * from services;
+------+--------+---------+
| id   | name   | version |
+------+--------+---------+
|    1 | apache |       2 |
|    2 | samba  |       4 |
+------+--------+---------+
MariaDB [test1]> delete from services where id=1;
MariaDB [test1]> select * from services;
+------+-------+---------+
| id   | name  | version |
+------+-------+---------+
|    2 | samba |       4 |
+------+-------+---------+
MariaDB [test1]> exit

可以使用drop table删除表。

现在,如果我们要在一个表中包含数十条记录,我们可能希望选择一小部分记录,例如5行:

MariaDB [test1]> select user,host from mysql.user limit 5;

查看在任何给定时间正在处理哪些查询:

MariaDB [test1]> SHOW FULL PROCESSLIST;

如果需要,您可以直接终止事务线程,其中12345是进程ID:

MariaDB [test1]> KILL 12345;

备份和还原MariaDB数据库

用Mysqldump备份

如果未使用–single-transaction选项,则Mysqldump至少需要对转储表具有SELECT特权,对转储视图必须具有SHOW VIEW,对转储触发器必须具有TRIGGER以及LOCK TABLES。

默认情况下,Mysqldump不会转储INFORMATION_SCHEMA数据库。
从MySQL 5.1.38开始,如果我们在命令行上明确命名,则mysqldump将转储INFORMATION_SCHEMA,尽管我们也必须使用–skip-lock-tables选项。

备份数据库test1:

# mysqldump -uroot -ppassword test1 > test1.sql

数据库备份也可以动态压缩:

# mysqldump -uroot -ppassword test1 | gzip > test1.sql.gz

还原资料库

# mysql -uroot -ppassword test1 < test1.sql

二进制日志备份

RHCE并未涵盖MariaDB二进制日志,但很高兴知道在需要时如何备份它们的方法:

# mysqlbinlog -v -uroot -ppassword --read-from-remote-server \
--host=localhost --to-last-log mysql-bin.000001 --result-file=binlog

常见的MariaDB错误

第1114行(HY000)错误:表" KEY_COLUMN_USAGE"已满

ERROR 1114 (HY000) at line : The table ‘KEY_COLUMN_USAGE’ is full

将max-heap-table-size增加到比现在更大的值,例如:

max-heap-table-size=256M

第1153错误(08S01):得到的数据包大于" max_allowed_packet"字节

ERROR 1153 (08S01) at line : Got a packet bigger than ‘max_allowed_packet’ bytes

将最大允许数据包增加到比现在更大的值,例如:

max-allowed-packet=16M

错误1102(42000):数据库名称" long_name_goes_here"不正确

ERROR 1102 (42000): Incorrect database name ‘long_name_goes_here’

MySQL 5数据库名称的最大长度为64,因此如果名称长于该名称,则会出现上述错误。
要解决此问题,请缩短数据库名称。

在Bash中测试:

#!/bin/bash
db=123456789-123456789-123456789-123456789-123456789-1234567890;
db_restore=""$db"_restore";
echo "start: ""$db_restore";
# check if a database name is not longer than 64 characters
db_length=$(echo -n "$db_restore"|wc -c);
if [[ "$db_length" -gt "64"  ]]; then
while [ "$db_length" -gt "64" ]
do
# delete the last character from the name until the length is 64
db_restore=${db_restore%?};
db_length=$(echo -n "$db_restore"|wc -c);
done
fi
echo "end: ""$db_restore";