云原生运维学习笔记:MariaDB进阶管理与Nginx服务实战
今天的内容接续昨天的数据库和存储,重点是MariaDB的进阶操作和Nginx服务器的部署配置。昨天我们学了NFS、iSCSI和MariaDB的基础,今天继续深入MariaDB的用户权限管理、备份恢复和主从同步,然后转向Nginx——这个在云原生时代几乎无处不在的Web服务器。说实话,MariaDB的用户权限部分内容真的很多,各种授权范围、权限类型,刚开始看有点晕。但跟着老师一步步操作下来,发现其实只要理解了"最小权限原则"和"范围粒度"这两个概念,剩下的就是查文档的事了。Nginx部分则相对轻松,配置结构清晰,虚拟主机的概念也很直观。
这篇博客就当作我的课堂笔记,把重点、踩过的坑和自己的理解都记下来,希望能帮到同样在学的朋友。环境还是老样子:CentOS 7,server和client两台虚拟机,所有命令都实际跑过。
昨日回顾:NFS、iSCSI与MariaDB基础
昨天我们学了三块内容:NFS存储、iSCSI存储和MariaDB基础。
NFS部分,理解了RPC机制和导出配置。/etc/exports的语法要记清楚,特别是客户端定义的末尾和左括号之间不能有空格这个细节。root_squash是默认的安全机制,生产环境要理解它的作用。
iSCSI部分,理解了Initiator、Target、IQN、LUN、ACL这些概念。targetcli的配置比NFS复杂一些,但掌握了交互式和命令行两种方式后,配置起来也不算难。iSCSI的优势在于客户端看到的是一块裸磁盘,可以自由地做分区、LVM、文件系统。
MariaDB部分,从数据库的基本概念到SQL语言,再到具体的增删改查操作,内容非常多。mysql_secure_installation加固数据库是第一步,然后才是创建数据库、表、记录。
有了这些基础,今天的进阶内容和Nginx就顺理成章了。
MariaDB进阶管理
环境准备
首先导入备份数据,这是后续操作的基础:
# 导入备份
[root@server ~]# curl -o inventory.sql -s http://192.168.49.200/class/course-materials/softwares/stage01/inventory.middle.sql
[root@server ~]# mysql -uroot -p123 -e 'create database inventory;'
[root@server ~]# mysql -uroot -p123 inventory < inventory.sql
数据表操作回顾
查询表列表:
MariaDB [(none)]> USE inventory;
MariaDB [inventory]> SHOW TABLES;
+———————+
| Tables_in_inventory |
+———————+
| category |
| manufacturer |
| product |
+———————+
3 rows in set (0.001 sec)
查询表结构:
MariaDB [inventory]> DESCRIBE product;
+—————–+————–+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+—————–+————–+——+—–+———+—————-+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(100) | NO | | NULL | |
| price | double | NO | | NULL | |
| stock | int(11) | NO | | NULL | |
| id_category | int(11) | NO | | NULL | |
| id_manufacturer | int(11) | NO | | NULL | |
+—————–+————–+——+—–+———+—————-+
6 rows in set (0.008 sec)
输出中几个关键列的含义:
- Field:属性名称
- Type:数据类型,例如stock属性必须是最多11位数字的整数
- Null:是否可以为null
- Key:属性ID是primary key,主键是表中一行的唯一标识符
- Extra:对于id字段标记为auto_increment,每次插入新记录时自动增加
查询表中数据:
MariaDB [inventory]> SELECT * FROM product;
+—-+——————-+———+——-+————-+—————–+
| id | name | price | stock | id_category | id_manufacturer |
+—-+——————-+———+——-+————-+—————–+
| 1 | ThinkServer TS140 | 539.88 | 20 | 2 | 4 |
| 2 | ThinkServer RD630 | 2379.14 | 20 | 2 | 4 |
| 3 | RT-AC68U | 219.99 | 10 | 1 | 3 |
| 4 | X110 64GB | 73.84 | 100 | 3 | 1 |
+—-+——————-+———+——-+————-+—————–+
4 rows in set (0.004 sec)
条件查询:
MariaDB [inventory]> SELECT * FROM product WHERE price > 100;
+—-+——————-+———+——-+————-+—————–+
| id | name | price | stock | id_category | id_manufacturer |
+—-+——————-+———+——-+————-+—————–+
| 1 | ThinkServer TS140 | 539.88 | 20 | 2 | 4 |
| 2 | ThinkServer RD630 | 2379.14 | 20 | 2 | 4 |
| 3 | RT-AC68U | 219.99 | 10 | 1 | 3 |
+—-+——————-+———+——-+————-+—————–+
3 rows in set (0.020 sec)
常用的条件操作符:
- =:等于
- <>:不等于
- >:大于
- <:小于
- >=:大于等于
- <=:小于等于
- BETWEEN:在某个范围内
- LIKE:搜索模式
- IN:指定多个可能值
# BETWEEN
MariaDB [inventory]> SELECT * FROM product WHERE id BETWEEN 1 AND 3;
# IN
MariaDB [inventory]> SELECT * FROM product WHERE id IN (1,3);
# LIKE
MariaDB [inventory]> SELECT * FROM product WHERE name like '%Server%';
# AND
MariaDB [inventory]> SELECT * FROM product WHERE name like '%RD%' AND price>1000;
# OR
MariaDB [inventory]> SELECT * FROM product WHERE name like '%RD%' OR price>500;
# ORDER BY
MariaDB [inventory]> SELECT * FROM product ORDER BY price;
MariaDB [inventory]> SELECT * FROM product ORDER BY price desc;
函数:
# 查询产品价格平均值
MariaDB [inventory]> SELECT avg(price) FROM product;
# 查询产品价格最大值
MariaDB [inventory]> SELECT max(price) FROM product;
# 查询产品价格最小值
MariaDB [inventory]> SELECT min(price) FROM product;
# 查询产品存量
MariaDB [inventory]> SELECT sum(stock) FROM product;
# 查询产品价格最小值的那个产品信息
MariaDB [inventory]> SELECT * FROM product WHERE price=(SELECT min(price) FROM product);
# 查询Lenovo厂商提供了几种产品
MariaDB [inventory]> SELECT count(product.name)
FROM product,manufacturer
WHERE product.id_manufacturer = manufacturer.id
AND manufacturer.name='Lenovo';
# GROUP BY
MariaDB [inventory]> SELECT id_category,sum(stock) FROM product GROUP BY id_category;
创建表:
MariaDB [inventory]> CREATE TABLE staff(
id INT(11) NOT NULL,
name VARCHAR(100) NOT NULL,
age INT(11) DEFAULT 10,
id_department INT(11)
);
Query OK, 0 rows affected (0.017 sec)
插入记录:
MariaDB [inventory]> INSERT INTO staff (id,name,age,id_department)
VALUES (1,'laoma1',28,10);
MariaDB [inventory]> INSERT INTO staff (id,name,age) VALUES (2,'laoma2',20);
MariaDB [inventory]> INSERT INTO staff (id,name) VALUES (3,'laoma3');
更新记录:
MariaDB [inventory]> UPDATE staff SET age=30 WHERE id=3;
如果使用不带WHERE子句的UPDATE,则表中的所有记录都会更新。
删除记录:
MariaDB [inventory]> DELETE FROM staff WHERE id=3;
如果使用不带WHERE子句的DELETE子句,则表中的所有记录都会删除。
删除表:
MariaDB [inventory]> DROP TABLE staff;
管理数据库用户
创建用户账户:
默认情况下,MariaDB有自己的用户和密码,与本地系统的用户和密码分开。这意味着MariaDB数据库用户与服务器的Linux用户不同,即使用户帐户具有相同的名称。
要创建新用户,需要以下权限级别之一:
- MariaDB的root用户
- 被授予全局CREATE USER特权的用户
- 被授予对mysql数据库的INSERT特权的用户
用户帐户定义示例:
| laoma或laoma@‘%’ | 用户laoma可以从任何主机连接 |
| laoma@‘localhost’ | 用户laoma只能从本地连接 |
| laoma@‘192.168.1.5’ | 用户laoma只能从IP地址192.168.1.5连接 |
| laoma@‘192.168.1.%’ | 用户laoma可以从192.168.1.0/24网络连接 |
MariaDB [(none)]> CREATE USER laoma@'%' IDENTIFIED BY '123';
用户的密码会被加密存在mysql.user表:
MariaDB [mysql]> SELECT host,user,password FROM user WHERE user = 'laoma';
+———–+——–+——————————————-+
| host | user | password |
+———–+——–+——————————————-+
| % | laoma | *84BB5DF4823DA319BBF86C99624479A198E6EEE9 |
+———–+——–+——————————————-+
1 row in set (0.000 sec)
默认情况下,新帐户被授予最小特权。在不授予其他特权的情况下,laoma用户只能访问最少的帐户信息。
授予用户权限:
GRANT语句可用于向帐户授予特权。要授予GRANT特权,连接的用户必须具有GRANT OPTION且必须具有他们所授予的特定特权。
MariaDB按"范围粒度"划分授权,从全局到列级逐步缩小:
| 全局范围 | *.* | 管理员/超级用户权限 | 覆盖整个MySQL实例所有资源 |
| 数据库范围 | 数据库名.* | 业务库专属权限 | 仅覆盖指定数据库的所有对象 |
| 表范围 | 数据库名.表名 | 单表专属权限 | 仅覆盖指定库的指定表 |
| 列范围 | 数据库名.表名(列1,列2) | 敏感列管控 | 仅覆盖表的指定列 |
全局范围示例:
— 超级管理员(完全控制)
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost';
— 用户管理管理员
GRANT CREATE USER, RELOAD ON *.* TO 'user_admin'@'localhost';
— 运维监控管理员
GRANT PROCESS, RELOAD, SUPER ON *.* TO 'ops_admin'@'localhost';
— 授予只读管理员全局查询权限
GRANT SELECT ON *.* TO 'monitor'@'%';
数据库范围示例:
— 业务全权限
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP
ON app_db.*
TO 'laowang'@'localhost';
— 只读权限
GRANT SELECT, SHOW VIEW
ON app_db.*
TO 'report_user'@'localhost';
— 仅结构管理权限
GRANT CREATE, ALTER, DROP, INDEX
ON app_db.*
TO 'dba_user'@'localhost';
表范围示例:
— 业务读写权限
GRANT SELECT, INSERT, UPDATE ON app_db.users TO 'laowang'@'localhost';
FLUSH PRIVILEGES;
— 表结构管理权限
GRANT ALTER, INDEX ON app_db.users TO 'laowang'@'localhost';
FLUSH PRIVILEGES;
— 只读权限
GRANT SELECT, SHOW VIEW ON app_db.users TO 'report_user'@'localhost';
FLUSH PRIVILEGES;
列范围示例:
— 授予user_op仅能查询shop_db.user表的id、name列
CREATE USER IF NOT EXISTS 'user_op'@'%' IDENTIFIED BY 'UserOp@123';
GRANT SELECT (id, name) ON shop_db.user TO 'user_op'@'%';
— 授予user_admin仅能修改shop_db.user表的status列
GRANT UPDATE (status) ON shop_db.user TO 'user_admin'@'%';
— 组合授权
GRANT SELECT (id, name), UPDATE (phone) ON shop_db.user TO 'user_mgr'@'%';
查询用户权限:
MariaDB [(none)]> SHOW GRANTS FOR root@localhost;
+—————————————————————————————————————————————-+
| Grants for root@localhost |
+—————————————————————————————————————————————-+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY PASSWORD '*84BB5DF4823DA319BBF86C99624479A198E6EEE9' WITH GRANT OPTION |
| GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION |
+—————————————————————————————————————————————-+
2 rows in set (0.006 sec)
关键注意事项:
— 撤销laoma的全局创建用户权限
REVOKE CREATE USER ON *.* FROM 'laoma'@'%';
— 撤销具体权限
MariaDB [(none)]> REVOKE SELECT, UPDATE, DELETE, INSERT
–> ON inventory.category FROM laoma@localhost;
Query OK, 0 rows affected (0.011 sec)
删除用户:
MariaDB [(none)]> DROP USER laoma@localhost;
Query OK, 0 rows affected (0.001 sec)
更改用户密码:
# root用户修改普通用户账户密码
MariaDB [(none)]> SET PASSWORD FOR 'laoma'@'localhost' = PASSWORD('mypass');
# 普通用户修改自己账户密码
MariaDB [(none)]> SET PASSWORD = PASSWORD('mypass');
MariaDB [(none)]> FLUSH PRIVILEGES;
备份和恢复
备份方式对比:
| 备份内容 | 导出为SQL文本文件 | 复制原始数据库目录和文件 |
| 备份速度 | 较慢 | 更快 |
| 可移植性 | 高,可还原到其他数据库 | 兼容性差,仅限类似环境 |
| 执行时机 | 服务器联机时 | 服务器脱机或锁表时 |
| 包含日志/配置 | 不包括 | 可以包括 |
物理备份和恢复:
# 执行物理备份
[root@server ~]# systemctl stop mariadb
[root@server ~]# cp -a /var/lib/mysql /backup/mysql
# 恢复物理备份
[root@server ~]# systemctl stop mariadb
[root@server ~]# rm -fr /var/lib/mysql
[root@server ~]# cp -a /backup/mysql /var/lib/mysql
[root@server ~]# chown -R mysql:mysql /var/lib/mysql/
[root@server ~]# systemctl start mariadb
逻辑备份和恢复:
mysqldump命令可用于逻辑备份。使用mysqldump连接MariaDB的用户至少需要对转储表具有SELECT特权。
# 备份方式1:不包含创建数据库语句
[root@server ~]# mysqldump -u root -p inventory > /backup/inventory.dump.sql-1
# 备份方式2:包含创建数据库语句
[root@server ~]# mysqldump -u root -p –databases inventory > /backup/inventory.dump.sql-2
# 备份方式3:备份所有数据库
[root@server ~]# mysqldump -u root -p –all-databases > /backup/all-databases.dump.sql
恢复逻辑备份:
# 模拟故障:删除数据库
[root@server ~]# mysql -u root -p -e 'drop database inventory;'
# 恢复
[root@server ~]# mysql -u root -p < /backup/inventory.dump.sql-2
# 或者
MariaDB [(none)]> source /backup/inventory.dump.sql
主从同步
主从同步本质是主库将数据变更以日志形式传输给从库,从库重放日志实现数据一致。
主从同步架构:
- 一主一从:一个主库对应一个从库,适合小型业务
- 一主多从:一个主库对应多个从库,可实现读写分离
- 级联复制:从库不再直接连接主库,而是连接另一个从库
- 双主复制:两个库互为主从,通常用于高可用切换
主从同步流程:
主从同步实践:
# 配置主库
[root@db1 ~]# cat > /etc/my.cnf.d/master.cnf <<'EOF'
[mysqld]
server_id = 1
log_bin = mysql-bin
binlog_format = ROW
relay_log = mysql-relay-bin
binlog-ignore-db = information_schema
binlog-ignore-db = performance_schema
binlog-ignore-db = sys
EOF
[root@db1 ~]# systemctl restart mariadb
# 配置从库
[root@db2 ~]# cat > /etc/my.cnf.d/master.cnf <<'EOF'
[mysqld]
server_id = 2
log_bin = mysql-bin
binlog_format = ROW
relay_log = mysql-relay-bin
binlog-ignore-db = information_schema
binlog-ignore-db = performance_schema
binlog-ignore-db = sys
EOF
[root@db2 ~]# systemctl restart mariadb
# 主库授权
[root@db1 ~]# mysql -uroot -pLaoma@123
MariaDB [(none)]> grant replication slave, replication client on *.* to 'repl'@'10.1.8.12' identified by 'Laoma@123';
MariaDB [(none)]> flush privileges;
MariaDB [(none)]> show master status\\G;
# 从库配置
[root@db2 ~]# mysql -uroot -pLaoma@123
MariaDB [(none)]> change master to master_host='10.1.8.11',
master_user='repl',
master_password='Laoma@123',
master_port=3306,
master_log_file='mysql-bin.000003',
master_log_pos=327,
master_connect_retry=30;
MariaDB [(none)]> start slave;
MariaDB [(none)]> show slave status\\G;
# 确保 Slave_IO_Running 和 Slave_SQL_Running 状态为Yes
验证主从同步:
# 主库写入数据
[root@db1 ~]# mysql -uroot -pLaoma@123
create database test;
use test;
create table linux(username varchar(15) not null,password varchar(15) not null);
insert into linux values ('laoma1', 'Laoma@123');
insert into linux values ('laoma2', 'Laoma@123');
insert into linux values ('laoma3', 'Laoma@123');
commit;
select * from linux;
# 从库查询
[root@db2 ~]# mysql -uroot -pLaoma@123
MariaDB [(none)]> select * from test.linux;
+———-+———-+
| username | password |
+———-+———-+
| laoma1 | Laoma@123 |
| laoma2 | Laoma@123 |
| laoma3 | Laoma@123 |
+———-+———-+
3 rows in set (0.00 sec)
主从同步是数据库高可用的基础,理解了binlog、relay log、I/O线程、SQL线程这些概念,以后做读写分离、故障切换就心里有数了。
Nginx服务器
Nginx介绍
Nginx是一款高性能的HTTP和反向代理服务器。在高连接并发的情况下,能够支持高达5万个并发连接数的响应,而内存、CPU等系统资源消耗却非常低,运行非常稳定。
Nginx部署
# 安装nginx
[root@www ~]# yum -y install nginx
# 启动nginx
[root@www ~]# systemctl enable nginx –now
# 准备主页
[root@www ~]# mv /usr/share/nginx/html/index.html{,.ori}
[root@www ~]# echo Hello World From Nginx > /usr/share/nginx/html/index.html
# 防火墙
[root@www ~]# firewall-cmd –add-service=http –permanent
[root@www ~]# firewall-cmd –reload
# 客户端测试
[root@client ~]# curl http://www.laoma.cloud
Hello World From Nginx
Nginx配置结构
Nginx配置采用层级化、模块化的组织方式,整体是"全局块 → 核心模块块 → 业务模块块"的嵌套结构。
1. 全局配置块:
作用于Nginx整个进程的基础配置,不嵌套在任何块内。
user nginx; # 运行Nginx的用户/用户组
worker_processes auto; # 工作进程数(建议设为CPU核心数)
error_log /var/log/nginx/error.log; # 错误日志路径
pid /run/nginx.pid; # 主进程PID文件路径
include /usr/share/nginx/modules/*.conf; # 加载外部模块配置
2. 核心模块块:
events块用于处理网络连接相关配置。
events {
worker_connections 1024; # 每个工作进程的最大并发连接数
use epoll; # 事件驱动模型
multi_accept on; # 允许一个进程一次性接受多个新连接
}
3. 业务模块块:
http块是最核心的配置块,可以包含多个server块。
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr – $remote_user [$time_local] "$request"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
location / {
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
}
}
4. HTTPS专属块:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/cert/server.crt;
ssl_certificate_key /etc/nginx/cert/server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
}
配置加载机制:
Nginx支持通过include引入外部配置文件,实现模块化管理。配置优先级:同层级后定义的覆盖先定义的;不同层级子级覆盖父级;location匹配精准匹配>正则匹配>普通前缀匹配。
虚拟主机
同一个web服务器提供多个站点。虚拟主机支持多种方式:
根据名称配置:
[root@www ~]# cp /etc/nginx/nginx.conf /etc/nginx/conf.d/vhost-name.conf
[root@www ~]# vim /etc/nginx/conf.d/vhost-name.conf
server {
server_name web1.laoma.cloud;
root /usr/share/nginx/web1;
}
server {
server_name web2.laoma.cloud;
root /usr/share/nginx/web2;
}
[root@www ~]# mkdir /usr/share/nginx/web{1,2}
[root@www ~]# echo web1.laoma.cloud > /usr/share/nginx/web1/index.html
[root@www ~]# echo web2.laoma.cloud > /usr/share/nginx/web2/index.html
[root@www ~]# systemctl restart nginx
客户端测试:
# 配置名称解析
10.1.8.10 web1.laoma.cloud
10.1.8.10 web2.laoma.cloud
[root@client ~]# curl http://web1.laoma.cloud/
web1.laoma.cloud
[root@client ~]# curl http://web2.laoma.cloud/
web2.laoma.cloud
课后总结
今天的内容量很大,从数据库的进阶管理到Nginx的部署配置,每一块都是运维的核心技能。
MariaDB部分,用户权限管理是重点。理解了"范围粒度"的概念后,授权就清晰了:全局、数据库、表、列四个级别,从大到小逐步精细化。最小权限原则要牢记,生产环境避免@'%',尽量用具体IP或网段。备份恢复部分,物理备份快但可移植性差,逻辑备份慢但灵活。mysqldump的三种备份方式要记清楚,恢复时注意是否包含创建数据库语句。主从同步是数据库高可用的基础,理解了binlog、relay log、I/O线程、SQL线程这些概念,以后做读写分离、故障切换就心里有数了。
Nginx部分,配置结构是重点。全局块、events块、http块、server块、location块,层层嵌套。include指令让配置可以模块化管理。虚拟主机基于名称或端口,生产环境用名称的更多。
踩过的坑:MariaDB授权后要FLUSH PRIVILEGES、mysqldump备份时不加–databases恢复时要先建库、Nginx的server_name匹配规则、location匹配优先级……这些都是实际操作才会遇到的问题。
希望这篇笔记能帮到同样在学云原生运维的朋友。MariaDB和Nginx是运维的两大核心工具,理解了它们的工作原理,以后遇到数据库管理和Web服务配置问题就能从容应对了。大家一起加油!



