在RHEL 7上使用SELinux设置MariaDB服务器
我们将安装和配置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";