运维必看:MariaDB 部署、配置与主从同步实战全解析

MariaDB 数据库

**摘要:**本文系统梳理了MariaDB数据库的完整知识体系,从基础概念、分类与关系型数据库的核心特性切入,对比了MariaDB作为MySQL分支的优势与特点。内容覆盖从部署安装、进程管理、安全加固,到SQL CRUD操作、ACID特性解析、用户权限管理,再到物理/逻辑备份恢复方案,最后深入讲解主从同步原理、延迟问题与集群架构实践,适合数据库管理员、开发与运维人员参考学习。

一、数据库介绍

数据库,是一个存放计算机数据的仓库。这个仓库是按照一定的数据结构来对数据进行组织和存储的,我们可以通过数据库提供的多种方法来管理其中的数据。

数据结构,是指数据的组织形式或数据之间的联系。

(一)数据库种类

按照早期的数据库理论,比较流行的数据库模型有三种,分别为:

  • 层次式数据库,以层次模型建立的数据库,例如文件系统、DNS。
  • 网状数据库,以网状模型建立的数据库,例如网络通信。
  • 关系型数据库,以二维表模型建议的数据库,例如图书馆管理系统。

在当今的互联网企业中,最常用的数据库模式主要有两种:

  • 关系型数据库,把复杂的数据结构归结为简单的二维表形式。在关系型数据库中,对数据的操作几乎全部建立在一个或多个关系表格上,通过对这些关联的表格分类、合并、连接或选取等运算来实现数据库的管理。例如:Oracle、MySql和PostgreSQL等。
  • 非关系型数据库,也被称为 NoSQL 数据库,本意是“Not Only SQL”,而非“NO SQL”的意思,因此,NoSQL的产生并不是要彻底否定关系型数据库,而是作为传统数据库的一个有效补充。典型产品有Redis(持久化缓存)、Mongodb、Memcached(纯内存)等。

(二)数据库排名

数据库排名 2026-01

在这里插入图片描述

(三)关系数据库

关系数据库将结构化数据存储在一组相互关联的表中。 这意味着一个表中的信息可以轻松地与另一表中的信息组合在一起,以处理和提供有关该数据的报告。

关系数据库管理系统(RDBMS-relational database management system)是用于管理关系数据库的软件。大多数关系数据库管理系统都允许您使用结构化查询语言(SQL)查找和管理数据库中的数据。

许多组织使用关系数据库存储业务信息,例如:库存,销售和财务。 关系数据库管理系统在许多应用中起着关键作用。 例如,许多需要支持动态生成内容的Web应用程序都是围绕LAMP(LNMP)解决方案构建:

  • Linux 操作系统提供了基本的环境。
  • Apache HTTPS ServerNginx,提供Web服务器。
  • MariaDBMySQL其他关系数据库,例如PostgreSQL,用于存储站点数据。
  • 由 Web 服务器运行的编程语言,例如 PHP,Python,Perl,Ruby,Java,服务器端JavaScript或其他,可以更新数据库中的数据并使用它为用户动态构建网页。

由于关系数据库通常与系统管理员管理的应用程序集成在一起,因此即使您不是数据库管理员,也有必要了解这些服务及其数据的安装和管理知识。

二、MariaDB 介绍

(一)MariaDB 介绍

MariaDB数据库管理系统是MySQL数据库的一个分支,主要由开源社区维护,采用GPL授权许可。开发这个MariaDB数据库分支的可能原因之一是:甲骨文公司收购了MySQL后,有将MySQL闭源的潜在风险,因此MySQL开源社区采用分支的方式来避开这个风险。

MariaDB数据库完全兼容MySQL数据库,包括API和命令行,使之能轻松的成为MySQL的代替品。

(二)MariaDB 存储结构

MariaDB数据库管理系统可以包含多个database,每个database包涵多张表。

在这里插入图片描述

关系数据库的表采用二维表格来存储数据,类似于Excle工作表。
• 表中的一行即为一个元组,或称为一条记录。
• 数据表中的每一列称为一个字段(属性),表是由其包含的各种字段定义,每个字段描述了它所含有的数据意义,为每个字段分配一个数据类型,定义它们的数据长度和其他属性。
• 行和列的交叉位置表示某个属性值。

在这里插入图片描述

三、MariaDB 部署

(一)安装数据库

# 安装服务端
[root@server ~]# yum install -y mariadb-server

# 安装客户端
[root@server ~]# yum install -y mariadb

# 启用并启动服务
[root@server ~]# systemctl enable --now mariadb

# 配置防火墙
[root@server ~]# firewall-cmd --permanent --add-service=mysql
[root@server ~]# firewall-cmd --reload

(二)数据库进程

MariaDB 启动后同时出现 mysqld_safe 和 mysqld 两个进程是完全正常的,这是 MariaDB(以及 MySQL)的标准运行机制。

1.核心进程

mariadb 服务有两个进程:

  1. mysqld 是 MariaDB 的核心进程,数据库的所有核心功能都由它实现: - 处理客户端的连接请求(比如 SQL 查询、数据写入);
    • 管理内存、磁盘数据(表、索引、事务等);
    • 执行 SQL 语句、维护数据一致性;
    • 负责锁机制、事务处理、复制等核心功能。 2. mysqld_safe 是一个监控和守护程序,主要负责:
    • 安全启动 mysqld 核心进程,处理启动前的环境检查(比如配置文件加载、权限验证);
    • 实时监控 mysqld 进程状态,如果 mysqld 意外崩溃 / 退出,mysqld_safe 会自动重启它,保证服务不中断;
    • 统一管理日志输出(把 mysqld 的日志重定向到指定日志文件,比如 error.log);
    • 处理一些启动参数的兼容转换,简化用户的启动配置。
2.进程关系

两者是父进程 - 子进程的关系:mysqld_safe 是父进程,mysqld 是它启动的子进程。通过以下命令验证:

# 查看进程的父子关系
ps -ef | grep -E 'mysqld_safe|mysqld'

# 或用 pstree 查看进程树(更直观)
pstree | grep mysqld

输出示例(核心部分):

root      1234     1  0 10:00 ?        00:00:00 /bin/sh /usr/bin/mysqld_safe --datadir=/var/lib/mysql --socket=/var/lib/mysql/mysql.sock
mysql     1456  1234  0 10:00 ?        00:00:05 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql ...

可以看到:

•mysqld_safe 由 root 用户运行(需要更高权限做环境准备);
• mysqld 由 mysql 普通用户运行(安全原则),且父进程 ID 是 mysqld_safe 的进程 ID(1234)。
3.特殊场景

如果你的 MariaDB 启动后只有 mysqld 进程,没有 mysqld_safe,通常是因为:

  1. 使用了 systemd 管理(现代 Linux 系统):systemctl start mariadb 会直接启动 mysqld,由 systemd 替代 mysqld_safe 做守护;
  2. 手动以后台方式启动 mysqld:比如 mysqld --daemonize,此时没有守护进程,崩溃后不会自动重启。

(三)加固数据库

MariaDB数据库默认具有test数据库和一些不太安全的配置。运行mysql_secure_installation修改这些配置。

[root@db1 ~ 15:51:43]# mysql_secure_installation

交互式提示您进行更改,包括:
• 为 root 帐户设置密码。
• 禁止 root 帐户从本地主机外部访问数据库。
• 删除 匿名 用户帐户。
• 删除用于演示的 test 数据库。

(四)配置数据库

默认情况下,MariaDB 侦听系统中所有网络地址上3306/TCP端口。
在 CentOS 7 中,MariaDB 的配置文件采用 “主配置文件 + 细分配置文件” 的分层结构,核心文件集中在 /etc/my.cnf 和 /etc/my.cnf.d/ 目录下。

1.主配置文件

/etc/my.cnf,MariaDB 的全局主配置文件,是服务启动时优先读取的配置入口。
• 本身可直接写入所有配置参数(覆盖客户端、服务器端配置);
• 默认会通过!includedir /etc/my.cnf.d/指令,加载 /etc/my.cnf.d/ 目录下的所有 .cnf 细分配置文件;
• 优先级最高:若细分配置文件与主文件参数冲突,以 my.cnf 中的配置为准。

2.细分配置文件

/etc/my.cnf.d/ 目录下文件是细分配置文件。
/etc/my.cnf.d/server.cnf,专门配置 MariaDB 服务器端(mysqld 进程)的参数,仅对数据库服务本身生效。
参数需放在 [mysqld][mysqld_safe] 等服务器端专属段落中。
常见配置项:
• 端口(port = 3306)、监听地址(bind-address = 0.0.0.0)
• 数据目录(datadir = /var/lib/mysql)、缓存大小(innodb_buffer_pool_size)
• 禁用网络连接(skip-networking = 1),禁用网络连接,客户端只能使用套接字文件与MariaDB通信。 如果您设置skip-networking = 0(默认值),MariaDB会侦听网络连接。
• 存储引擎(default-storage-engine = InnoDB)、日志配置(log_error、slow_query_log)
/etc/my.cnf.d/client.cnf,配置所有 MariaDB 客户端工具的通用参数(如 mysqlmysqldumpmysqladmin 等),简化客户端连接操作。
/etc/my.cnf.d/mysql-clients.cnf,与 client.cnf 功能类似,也是配置客户端工具,更偏向于 mysql 命令行客户端的专属优化(部分系统中与 client.cnf 功能重叠,可互补使用)。

(五)连接数据库

1.连接本地数据库

mysql命令可以通过本地特殊的套接字文件(socket)与数据库通信。 这种方式更安全,因为MariaDB不需要侦听来自网络客户端的连接。 但是使用该数据库的服务都需要在MariaDB服务器上运行,会影响性能。

[root@server ~ ]# mysql -u root
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 2
Server version: 5.5.68-MariaDB MariaDB Server

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)]> 
2.连接远端数据库

客户端可以使用TCP/IP网络连接到MariaDB服务,此时服务器需要配置侦听端口3306/TCP上的连接。

# 数据库服务器本机创建连接用户
[root@server ~ ]# mysql -u root -p
MariaDB [(none)]> create user lz identified by '123';
MariaDB [(none)]> grant all privileges on *.* to lz;
MariaDB [(none)]> flush privileges;

# 客户端测试
[root@client ~]# mysql -u lz -p123 -h server
3.非交互方式连接数据库

mysql命令可以通过-e选项,以非交互方式连接数据库。

[root@db1 ~ 16:56:31]# mysql -u root -p -e 'show databases;'
Enter password: 
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+

(六)配置客户端

1.配置文件

/etc/my.cnf.d/client.cnf,配置所有 MariaDB 客户端工具的通用参数(如 mysqlmysqldumpmysqladmin 等),简化客户端连接操作。
参数需放在 [client] 通用段落中(所有客户端工具都会读取)。
常见配置项:
• 默认用户名(user = root)、默认密码(password = 123456,不推荐明文存储)
• 默认主机(host = localhost)、默认端口(port = 3306)
• 字符集(default-character-set = utf8mb4)
/etc/my.cnf.d/mysql-clients.cnf,与 client.cnf 功能类似,也是配置客户端工具,更偏向于 mysql 命令行客户端的专属优化(部分系统中与 client.cnf 功能重叠,可互补使用)。
优先级低于 client.cnf,若两者配置冲突,以 client.cnf 为准。

2.配置登录信息
[root@client ~ ]# vim /etc/my.cnf.d/client.cnf
[client]
user=lz
password=123
host=server
port=3306
database=mysql

# 输入mysql命令可以直接登录数据库
[root@client ~ ]# mysql
MariaDB [(mysql)]> 
3.配置登录提示符
[root@client ~ ]# /etc/my.cnf.d/client.cnf
[client]
prompt="\\u@\\h [\\d]> "

# 登录效果如下
[root@client ~ ]# mysql -u lz -p -h 10.1.8.10 mysql
lz@10.1.8.10 [mysql]> 

四、结构化查询语言

(一)结构化查询语言

SQL(Structured Query Language),结构化查询语言,是1986年10 月由美国国家标准局颁布的数据库语言。国际标准化组织(ISO)也颁布了SQL国际标准。
结构化查询语言是关系数据库最重要的操作语言,它的影响已经超出数据库领域,得到其他领域的重视和采用,如人工智能领域的数据检索,第四代软件开发工具中嵌入SQL的语言等。
SQL语句可简单分为如下几类:
数据查询语言(DQL:Data Query Language):也称为“数据检索语句”,用以从表中获得数据,保留字SELECT WHERE,ORDER BY,GROUP BY和HAVING。
数据操作语言(DML:Data Manipulation Language):其语句包括动词INSERT,UPDATE和DELETE。
数据定义语言(DDL):其语句包括动词CREATE和DROP。例如,在数据库中创建新表(CREATE TABLE)、删除表(DROP TABLE),为表添加索引等。
事务处理语言(TPL):它的语句能确保被DML语句影响的表的所有行及时得以更新。TPL语句包括BEGIN TRANSACTION,COMMIT和ROLLBACK。
数据控制语言(DCL):它的语句通过GRANT或REVOKE获得许可,确定单个用户和用户组对数据库对象的访问。

在数据库管理中,ACID特性是确保数据库事务正确执行的四个基本要素。这些特性分别是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。这些特性共同保证了数据库事务的可靠性和稳定性,即使在系统故障或其他异常情况下也能保持数据的完整性和一致性。

• 原子性(Atomicity):原子性确保事务中的所有操作要么全部成功,要么全部失败。如果事务中的任何操作失败,整个事务都会回滚到开始状态,就像这个事务从未执行过一样。这意味着事务是一个不可分割的工作单位,它要么完全执行,要么完全不执行。
• 一致性(Consistency):一致性意味着数据库在事务执行前后都必须保持一致状态。事务不会破坏数据库的完整性约束,确保数据的准确性和合法性。例如,如果一个银行转账事务在转账前后保持总金额不变,那么这个事务就是一致的。
• 隔离性(Isolation):隔离性保证了当多个事务同时对数据库进行操作时,每个事务都是独立的。这意味着一个事务的操作不会被其他事务干扰。数据库系统提供了不同的隔离级别,以满足不同的并发控制需求。隔离级别越高,能够提供的数据一致性保证越强,但可能会降低系统的并发性能。
• 持久性(Durability):持久性确保一旦事务被提交,它对数据库的更改就是永久性的。即使发生系统故障,如断电或崩溃,事务的结果也不会丢失。这通常通过将事务操作记录到持久存储设备上来实现。

(二)数据库操作

1.查询数据库列表
MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.019 sec)

数据库说明:
• mysql 数据库,是一个系统数据库,保存数据库用户及其访问权限等信息。
• INFORMATION_SCHEMA 数据库,保存关于数据库或者数据表的元数据信息。
• PERFORMANCE_SCHEMA 数据库,保存数据库服务器性能信息。

2.使用数据库

您可以使用 USE 语句选择数据库之一,例如:USE mysql;,后续默认操作的表属于mysql数据库。

MariaDB [(none)]> USE mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [mysql]> 

SQL语句不区分大小写,但数据库名称区分大小写。 通常的做法是数据库名称全为小写字母,SQL语句全为大写字母,以区分SQL语句与语句的目标或参数。

3.创建数据库
MariaDB [mysql]> CREATE DATABASE webapp;
Query OK, 1 row affected (0.010 sec)

MariaDB [mysql]> USE webapp;
Database changed
4.删除数据库

DROP DATABASE语句删除数据库中的所有表并删除数据库。 这将破坏数据库中的所有数据。 只有对该数据库具有DROP特权的用户才能运行此语句。 这不会更改数据库的用户特权。 如果重新创建具有该名称的数据库,则为旧数据库设置的用户权限仍然有效。

MariaDB [inventory]> DROP DATABASE webapp;
Query OK, 0 rows affected (0.006 sec)

(三)表操作

SQL CRUD操作(create 添加数据 read读取数据 update 修改数据delete删除数据)。

1.环境准备
# 导入备份
[root@server ~]# mysql -uroot -p123 -e 'create database inventory;'
[root@server ~]# mysql -uroot -p123 inventory < inventory.dump
2.查询表
2.1查询表列表
# 查询表列表
MariaDB [(none)]> USE inventory;
MariaDB [inventory]> SHOW TABLES;
+---------------------+
| Tables_in_inventory |
+---------------------+
| category            |
| manufacturer        |
| product             |
+---------------------+
3 rows in set (0.001 sec)
2.2查询表结构
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)

MariaDB [inventory]> 

输出显示,表格中有六列(属性):

  • Field 列,显示该属性名称。
  • Type 列,显示该属性的数据必须采用的格式。例如,stock属性必须是最多11位数字的整数。
  • Null 列,指示此属性是否可以为null。
  • Default 列,指示如果未指定该属性,则是否设置了默认值。
  • Key 列,显示属性ID是primary key。 主键是表中一行的唯一标识符。 该属性的任何其他行都不能具有相同的值。
  • Extra列,提供该列额外信息,对于id字段标记为auto_increment。 这意味着每次将新项目插入表中时,该条目的属性值都会增加。 这样可以更轻松地使数字主键保持唯一。
2.3查询表中数据

查询表中所有记录所有字段

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 category;
+----+------------+
| id | name       |
+----+------------+
|  1 | Networking |
|  2 | Servers    |
|  3 | Ssd        |
+----+------------+
3 rows in set (0.001 sec)

MariaDB [inventory]> SELECT * FROM manufacturer;
+----+----------+----------------+-------------------+
| id | name     | seller         | phone_number      |
+----+----------+----------------+-------------------+
|  1 | SanDisk  | John Miller    | +1 (941) 329-8855 |
|  2 | Kingston | Mike Taylor    | +1 (341) 375-9999 |
|  3 | Asus     | Wilson Jackson | +1 (432) 367-8899 |
|  4 | Lenovo   | Allen Scott    | +1 (876) 213-4439 |
+----+----------+----------------+-------------------+
4 rows in set (0.001 sec)

MariaDB [inventory]>

查询表中所有记录特定字段

MariaDB [inventory]> SELECT name,price,stock FROM product;
+-------------------+---------+-------+
| name              | price   | stock |
+-------------------+---------+-------+
| ThinkServer TS140 |  539.88 |    20 |
| ThinkServer RD630 | 2379.14 |    20 |
| RT-AC68U          |  219.99 |    10 |
| X110 64GB         |   73.84 |   100 |
+-------------------+---------+-------+
4 rows in set (0.001 sec)
2.4WHERE 子句
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)

条件操作数

OperatorDescription
=Equal
<>Not equal. Note: In some versions of SQL, this operator may be written as !=
>Greater than
<Less than
>=Greater than or equal
<=Less than or equal
BETWEENBetween an inclusive range
LIKESearch for a pattern
INSpecify multiple possible values for a column
# 条件操作符包括:=、<>、>、<、>=、<=
MariaDB [inventory]> SELECT * FROM product WHERE price > 100;

# BETWEEN,匹配2个数字之间(包括数字本身)的记录。
MariaDB [inventory]> SELECT * FROM product WHERE id BETWEEN 1 AND 3;

# IN,匹配列表中记录。
MariaDB [inventory]> SELECT * FROM product WHERE id IN (1,3);
MariaDB [inventory]> SELECT * FROM category WHERE name IN ('Servers','Ssd');

# LIKE,用于匹配字符串。%表示一个或多个字符,_表示一个字符,[charlist]表示字符列中的任何单一字符,[^charlist]或者[!charlist]不在字符列中的任何单一字符。
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;
2.5多表查询
# 示例1:产品类型是Servers的产品名称和价格
MariaDB [inventory]> SELECT product.name,product.price
FROM product,category
WHERE product.id_category = category.id 
AND category.name='Servers';

# 示例2:查询厂商是Lenovo的产品名称和价格
MariaDB [inventory]> SELECT product.name,product.price
FROM product,manufacturer 
WHERE product.id_manufacturer = manufacturer.id
AND manufacturer.name='Lenovo';
2.6函数
# 示例1:查询产品价格平均值
MariaDB [inventory]> SELECT avg(price) FROM product;

# 示例2:查询产品价格最大值
MariaDB [inventory]> SELECT max(price) FROM product;

# 示例3:查询产品价格最小值
MariaDB [inventory]> SELECT min(price) FROM product;

# 示例4:查询产品存量
MariaDB [inventory]> SELECT sum(stock) FROM product;

# 示例5:查询产品价格最小值的那个产品信息
MariaDB [inventory]> SELECT min(price) FROM product;
MariaDB [inventory]> SELECT * FROM product WHERE price=73.84;
或者
MariaDB [inventory]> SELECT * FROM product WHERE price=(SELECT min(price) FROM product);

# 示例6:查询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;
3.创建表
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]> SHOW TABLES;
4.插入记录
MariaDB [inventory]> INSERT INTO staff (id,name,age,id_department)
VALUES (1,'lz1',28,10);
MariaDB [inventory]> INSERT INTO staff (id,name,age) VALUES (2,'lz2',20);
MariaDB [inventory]> INSERT INTO staff (id,name) VALUES (3,'lz3');
5.更新记录
MariaDB [inventory]> UPDATE staff SET age=30 WHERE id=3;
MariaDB [inventory]> UPDATE staff SET age=30

如果使用不带WHERE子句的UPDATE,则表中的所有记录都会更新。

6.删除记录
MariaDB [inventory]> DELETE FROM staff WHERE id=3 ;
MariaDB [inventory]> DELETE FROM staff ;

如果使用不带WHERE子句的DELETE子句,则表中的所有记录都会删除。

7.删除表
MariaDB [inventory]> DROP TABLE staff ;

五、管理数据库用户

(一)创建用户账户

默认情况下,MariaDB有自己的用户和密码,与本地系统的用户和密码分开。这意味着MariaDB数据库用户与服务器的Linux用户不同, 即使用户帐户具有相同的名称。
为了控制用户对数据库服务器的访问级别,必须在MariaDB中设置数据库用户并授予他们在服务器及其数据上执行操作的权限。
您可以配置MariaDB使用pam身份验证插件将系统用户帐户和密码集成为MariaDB数据库用户,本课程不介绍该配置。 在大多数情况下,最好分开管理数据库和系统用户账户。
要创建新用户,您需要以下权限级别之一:
• MariaDB的 root 用户。
• 被授予全局 CREATE USER 特权的用户。
• 被授予对mysql数据库的 INSERT 特权的用户。
用户帐户定义示例

AccountDescription
lz或者lz@‘%’User lz can connect from any host.
lz@‘localhost’User lz can only connect from localhost.
lz@‘192.168.1.5’User lz can only connect from the IP address192.168.1.5.
lz@‘192.168.1.%’User lz can connect from any address that belongs to the network 192.168.1.0/24.
lz@‘2001:db8:18:b51:c32:a21’User lz can connect from the IP address 2001:db8:18:b51:c32:a21.

我们可以使用CREATE USER语句,在mysql数据库的user表中创建一条新记。

用户名格式:user_name@host_name。 这样就可以根据主机源,创建具有相同名称但具有不同特权的多个用户帐户。

MariaDB [(none)]> CREATE USER lz@'%' IDENTIFIED BY '123';

当前,lz帐户可以使用密码123%**连接。

用户的密码,会被加密存在在mysql.user表:

MariaDB [mysql]> SELECT host,user,password FROM user WHERE user = 'lz';
+-----------+--------+-------------------------------------------+
| host      | user   | password                                  |
+-----------+--------+-------------------------------------------+
| %         | lz | *84BB5DF4823DA319BBF86C99624479A198E6EEE9 |
+-----------+--------+-------------------------------------------+
1 row in set (0.000 sec)

默认情况下,新帐户被授予最小特权。 在不授予其他特权的情况下,laoma用户只能访问最少的帐户信息,大多数其他操作均被拒绝。

(二)授予用户权限

GRANT语句可用于向帐户授予特权。 要授予GRANT特权,连接的用户必须具有GRANT OPTION必须具有他们所授予的特定特权

Mariadb 按“范围粒度”划分授权,从全局(整个数据库实例)到列级(单表某列)逐步缩小,不同范围对应不同的授权对象和业务场景。

GRANT [权限1, 权限2, ...]
ON [作用范围]
TO '用户名'@'主机地址'
[IDENTIFIED BY '密码'];

权限可以是单权限,也可以是逗号分隔的多权限组合。

作用范围授权对象格式适用场景核心特点
全局范围*.*管理员/超级用户权限覆盖整个 MySQL 实例所有资源
数据库范围数据库名.*业务库专属权限(如电商库)仅覆盖指定数据库的所有对象
表范围数据库名.表名单表专属权限(如订单表)仅覆盖指定库的指定表
列范围数据库名.表名(列1,列2)敏感列管控(如手机号/密码)仅覆盖表的指定列
1. 全局范围

管理员级全局权限是指作用于 *.*(所有数据库、所有表)的最高级别权限,通常只授予数据库管理员(DBA)。

常用权限

权限名称作用
CREATE USER创建、删除、重命名其他用户,以及为其他用户授权(这是用户管理的核心权限)
SUPER执行超级管理员操作,例如终止任意连接、修改全局系统变量、主从复制管理等
PROCESS查看所有用户的连接进程(SHOW PROCESSLIST),用于排查问题
RELOAD执行 FLUSH 系列命令(如 FLUSH PRIVILEGESFLUSH LOGS),使配置生效
SHUTDOWN关闭 MariaDB 服务
FILE读写服务器上的文件(如 LOAD DATA INFILE),需谨慎授予
CREATE创建数据库、表、视图等对象
ALTER修改数据库、表的结构
DROP删除数据库、表等对象
INSERT/UPDATE/DELETE/SELECT对所有表进行增删改查操作

示例

-- 示例1:超级管理员(完全控制)
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost';

-- 示例2:用户管理管理员
GRANT CREATE USER, RELOAD ON *.* TO 'user_admin'@'localhost';

-- 示例3:数据库管理员
GRANT CREATE, DROP  ON *.* TO 'db_admin'@'localhost';

-- 示例4:运维监控管理员
GRANT PROCESS, RELOAD, SUPER ON *.* TO 'ops_admin'@'localhost';

-- 示例5:授予只读管理员全局查询权限(监控/报表)
GRANT SELECT ON *.* TO 'monitor'@'%';
2. 数据库范围

数据库级权限作用于 数据库名.* 范围,仅对指定数据库生效,无法跨库操作;所有权限授权后都需执行 FLUSH PRIVILEGES; 生效。

数据操作类(增删改查),这类权限控制对数据库内表数据的读写操作,是最基础的业务权限:

权限名称作用授权示例
SELECT允许查询数据库内所有表的数据(读权限)GRANT SELECT ON app_db.* TO 'laoli'@'localhost';
INSERT允许向数据库内所有表插入数据(写权限)GRANT INSERT ON app_db.* TO 'laoli'@'localhost';
UPDATE允许修改数据库内所有表的数据GRANT UPDATE ON app_db.* TO 'laoli'@'localhost';
DELETE允许删除数据库内所有表的数据GRANT DELETE ON app_db.* TO 'laoli'@'localhost';

结构管理类(表 / 索引 / 视图管理),这类权限控制数据库内表、索引、视图等对象的创建 / 修改 / 删除,属于「结构层」权限:

权限名称作用授权示例
CREATE允许在数据库内创建表、视图、索引GRANT CREATE ON app_db.* TO 'laoli'@'localhost';
ALTER允许修改数据库内表的结构(如 ALTER TABLEGRANT ALTER ON app_db.* TO 'laoli'@'localhost';
DROP允许删除数据库内的表、视图GRANT DROP ON app_db.* TO 'laoli'@'localhost';
INDEX允许为数据库内的表创建 / 删除索引(注:CREATE 权限已包含此能力)GRANT INDEX ON app_db.* TO 'laoli'@'localhost';
CREATE VIEW允许在数据库内创建视图GRANT CREATE VIEW ON app_db.* TO 'laoli'@'localhost';
SHOW VIEW允许查看数据库内视图的定义(如 SHOW CREATE VIEWGRANT SHOW VIEW ON app_db.* TO 'laoli'@'localhost';

**特殊操作类,**这类权限针对数据库内的特殊操作,如存储过程、锁表等:

权限名称作用授权示例
CREATE ROUTINE允许在数据库内创建存储过程 / 函数GRANT CREATE ROUTINE ON app_db.* TO 'laoli'@'localhost';
ALTER ROUTINE允许修改 / 删除数据库内的存储过程 / 函数GRANT ALTER ROUTINE ON app_db.* TO 'laoli'@'localhost';
EXECUTE允许执行数据库内的存储过程 / 函数GRANT EXECUTE ON app_db.* TO 'laoli'@'localhost';
LOCK TABLES允许锁定数据库内的表(如 LOCK TABLESGRANT LOCK TABLES ON app_db.* TO 'laoli'@'localhost';

示例

-- 示例1:业务全权限(增删改查 + 结构管理)
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP 
ON app_db.* 
TO 'laoli'@'localhost';

-- 示例2:只读权限(仅查询)
GRANT SELECT, SHOW VIEW 
ON app_db.* 
TO 'report_user'@'localhost';

-- 示例3: 仅结构管理权限(无数据操作)
GRANT CREATE, ALTER, DROP, INDEX 
ON app_db.* 
TO 'dba_user'@'localhost';
3.表范围

表级权限作用于 数据库名.表名 范围,仅对指定数据库的指定表生效,不会影响同库其他表;所有授权后需执行 FLUSH PRIVILEGES; 使权限立即生效。

核心数据操作类(最常用),这类权限控制对单表数据的读写,是业务场景中最基础的表级权限:

权限名称作用授权示例(以 app_db.users 表为例)
SELECT允许查询该表的所有列数据(读权限)GRANT SELECT ON app_db.users TO 'laoli'@'localhost';
INSERT允许向该表插入新数据(写权限)GRANT INSERT ON app_db.users TO 'laoli'@'localhost';
UPDATE允许修改该表的现有数据GRANT UPDATE ON app_db.users TO 'laoli'@'localhost';
DELETE允许删除该表的现有数据GRANT DELETE ON app_db.users TO 'laoli'@'localhost';

表结构管理类,这类权限控制单表的结构修改、索引管理等,属于「结构层」权限:

权限名称作用授权示例
ALTER允许修改该表的结构(如添加 / 删除列、修改列类型)GRANT ALTER ON app_db.users TO 'laoli'@'localhost';
DROP允许删除该表(慎用)GRANT DROP ON app_db.users TO 'laoli'@'localhost';
INDEX允许为该表创建 / 删除索引(注:MariaDB 5.5 中 ALTER 权限已包含此能力)GRANT INDEX ON app_db.users TO 'laoli'@'localhost';
CREATE VIEW基于该表创建视图(需同时有该表的 SELECT 权限)GRANT CREATE VIEW ON app_db.users TO 'laoli'@'localhost';
SHOW VIEW查看基于该表创建的视图定义(如 SHOW CREATE VIEWGRANT SHOW VIEW ON app_db.users TO 'laoli'@'localhost';

特殊操作类,这类权限针对单表的特殊操作,如锁表、触发器管理等:

权限名称作用授权示例
LOCK TABLES允许锁定该表(用于并发控制)GRANT LOCK TABLES ON app_db.users TO 'laoli'@'localhost';
CREATE TRIGGER允许为该表创建触发器GRANT CREATE TRIGGER ON app_db.users TO 'laoli'@'localhost';
ALTER TRIGGER允许修改 / 删除该表的触发器GRANT ALTER TRIGGER ON app_db.users TO 'laoli'@'localhost';
EXECUTE允许执行该表关联的存储过程 / 函数(若有)GRANT EXECUTE ON app_db.users TO 'laoli'@'localhost';

示例

-- 示例1:业务读写权限(最常用)
GRANT SELECT, INSERT, UPDATE ON app_db.users TO 'laoli'@'localhost';
FLUSH PRIVILEGES;

-- 示例2:表结构管理权限
GRANT ALTER, INDEX ON app_db.users TO 'laoli'@'localhost';
FLUSH PRIVILEGES;

-- 示例3:只读权限(报表 / 分析用)
GRANT SELECT, SHOW VIEW ON app_db.users TO 'report_user'@'localhost';
FLUSH PRIVILEGES;
4.列范围

列级权限仅作用于「数据库名.表名.列名」,是表级权限的精细化补充;MariaDB 5.5 仅支持对 SELECT/INSERT/UPDATE 这 3 类操作做列级限制,其他操作(如 DELETE)无列级权限控制。所有授权后需执行 FLUSH PRIVILEGES; 生效。

列级权限(仅 3 类)

权限名称作用授权语法实操示例(以 app_db.users 表为例)
SELECT允许查询指定列的数据(控制「读哪些列」)GRANT SELECT(列1,列2) ON 库.表 TO 用户@主机;GRANT SELECT(name, phone) ON app_db.users TO 'laoli'@'localhost';
INSERT允许向指定列插入数据(控制「写哪些列」)GRANT INSERT(列1,列2) ON 库.表 TO 用户@主机;GRANT INSERT(name, email) ON app_db.users TO 'laoli'@'localhost';
UPDATE允许修改指定列的数据(控制「改哪些列」)GRANT UPDATE(列1,列2) ON 库.表 TO 用户@主机;GRANT UPDATE(phone) ON app_db.users TO 'laoli'@'localhost';

示例

注意:列级授权需显式指定列名,且仅支持 SELECT/INSERT/UPDATE/REFERENCES 权限。

-- 示例1:授予 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'@'%';

-- 示例2:授予 user_admin 仅能修改 `shop_db.user` 表的 `status` 列(账号状态)
GRANT UPDATE (status) ON shop_db.user TO 'user_admin'@'%';

-- 示例3:组合授权:查询基础列 + 修改手机号列
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)

(四)关键注意事项

  1. 最小权限原则:优先授予“刚好够用”的权限(如业务开发仅授予数据库级权限,而非全局),避免过度授权。

  2. 权限生效:所有授权后需执行 FLUSH PRIVILEGES;。

  3. 用户范围限制:生产环境避免 @‘%’(任意主机),替换为具体 IP(如 @‘192.168.1.100’)或网段(@‘192.168.1.%’)。

  4. 查看权限:验证授权结果,避免配置错误:

-- 查看指定用户的所有权限
SHOW GRANTS FOR 'lz'@'%';
-- 查看当前登录用户的权限
SHOW GRANTS;
  1. 权限回收:如需撤销权限,格式与授权对应(替换 GRANT 为 REVOKE):
-- 撤销 laoma 的全局创建用户权限
REVOKE CREATE USER ON *.* FROM 'lz'@'%';

(五)常见场景权限参考

角色权限范围推荐权限组合
超级管理员*.*ALL PRIVILEGES WITH GRANT OPTION
业务库开发业务库.*CREATE, ALTER, DROP, SELECT, INSERT, UPDATE, DELETE
运营只读业务库.*SELECT
订单表操作业务库.订单表SELECT, INSERT, UPDATE
敏感列管控业务库.用户表SELECT(id,name), UPDATE(status)

(六)回收用户权限

REVOKE语句从帐户中删除特权。 连接的用户必须具有GRANT OPTION特权,并且必须具有被撤消的特定特权。

MariaDB [(none)]> REVOKE SELECT, UPDATE, DELETE, INSERT
    -> ON inventory.category FROM lz@localhost;
Query OK, 0 rows affected (0.011 sec)

(七)删除用户

当不再需要特定的用户帐户时,可以使用DROP USER将其从数据库中删除。

用户名使用’user’@'host’格式。

MariaDB [(none)]> DROP USER lz@localhost;
Query OK, 0 rows affected (0.001 sec)

如果删除了当前连接的帐户,则在关闭连接之前不会删除该帐户,关闭连接之后才会删除该帐户。

(八)更改用户密码

# root用户修改普通用户账户密码
MariaDB [(none)]> USE mysql;
MariaDB [(mysql)]> UPDATE user SET password=PASSWORD('mypass') WHERE user='lz' and host=’localhost’;

# 或者
MariaDB [(none)]> SET PASSWORD FOR 'lz'@'localhost' = PASSWORD('mypass');

# 普通用户修改自己账户密码
MariaDB [(none)]> SET PASSWORD = PASSWORD('mypass');
MariaDB [(none)]> FLUSH PRIVILEGES;

(九)排故数据库访问

下表总结了用户在身份验证和访问方面可能遇到的一些问题,以及可能的原因。

问题解决方法
已授予用户从任何主机进行连接的访问权限,但只能使用数据库服务器本地mysql命令进行连接。如果在配置文件/etc/my.cnf.d/server.cnf中设置了skip-networking,请删除该指令并重新启动服务。
用户可以与localhost上的任何应用程序连接,但不能远程连接。确保/etc/my.cnf.d/server.cnf中的bind-address配置正确。 确保用户表中包含用户要尝试与其连接的主机的条目。
用户可以连接,但看不到除information_schema以外的任何数据库。确保已授予用户访问其数据库的权限。 刚创建的用户具有最小权限,会遇到这个问题。
用户可以连接,但不能创建任何数据库。考虑向用户授予全局CREATE特权(这也授予DROP特权)。
用户可以连接,但不能读取或写入任何数据。向用户授予他们打算使用的数据库的CRUD特权。

(十)思考

1. 忘记 root 用户密码

1.编辑**/etc/my.cnf.d/server.cnf**配置文件,在[mysqld]下添加skip-grant-tables=1

2.重启 mariadb 服务。

3.执行mysql -u root命令进入mysql命令行,修改root用户密码。

[root@server ~]# mysql -u root
MariaDB [(none)]> UPDATE mysql.user SET password=PASSWORD('新密码') where USER='root';
MariaDB [(none)]> exit

4.把/etc/my.cnf.d/server.cnf配置文件中的skip-grant-tables=1注释掉,然后重启mariadb服务。

2.无意回收了 root 账户权限

当 MySQL 的 root 账户所有权限被误回收时,核心解决思路是绕过权限验证启动 MySQL,直接修改权限表恢复 root 权限,以下是适配 MySQL 5.7/8.0 版本的完整恢复步骤(CentOS 7/8、Ubuntu 通用):

  • 步骤 1:停止 MySQL 服务

  • 步骤 2:跳过权限表启动 MySQL

  • 步骤 3:无密码登录 MySQL

  • 步骤 4:恢复 root 权限

场景 1:MySQL 5.7 版本

-- 1. 切换到 mysql 系统库
USE mysql;

-- 2. 重置 root 账户的所有权限(设置为 Y 表示开启)
UPDATE user SET 
  Select_priv='Y', Insert_priv='Y', Update_priv='Y', Delete_priv='Y',
  Create_priv='Y', Drop_priv='Y', Reload_priv='Y', Shutdown_priv='Y',
  Process_priv='Y', File_priv='Y', Grant_priv='Y', References_priv='Y',
  Index_priv='Y', Alter_priv='Y', Show_db_priv='Y', Super_priv='Y',
  Create_tmp_table_priv='Y', Lock_tables_priv='Y', Execute_priv='Y',
  Repl_slave_priv='Y', Repl_client_priv='Y', Create_view_priv='Y',
  Show_view_priv='Y', Create_routine_priv='Y', Alter_routine_priv='Y',
  Create_user_priv='Y', Event_priv='Y', Trigger_priv='Y',
  Create_tablespace_priv='Y'
WHERE User='root' AND Host='localhost';  -- 若需恢复远程 root(%),替换 Host='%'

-- 3. 刷新权限(使修改生效)
FLUSH PRIVILEGES;

-- 4. 验证权限(可选)
SELECT User, Host, Grant_priv FROM mysql.user WHERE User='root';

场景 2:MySQL 8.0 版本

-- 1. 先刷新权限(启用权限校验,否则 GRANT 命令失效)
FLUSH PRIVILEGES;

-- 2. 重新授予 root 全局所有权限(含授权权限)
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;

-- 若需恢复远程 root(%),补充执行:
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;

-- 3. 刷新权限
FLUSH PRIVILEGES;

-- 4. 验证权限(可选)
SHOW GRANTS FOR 'root'@'localhost';
  • 步骤 5:重启 MySQL 服务
3.无意删除了 root 账户

当 MySQL 中所有 root 账户(包括 root@localhost、root@% 等)被误删除时,核心思路是跳过权限验证启动 MySQL,直接重建 root 账户并赋予全权限,以下是适配 MySQL 5.7/8.0 版本的完整恢复步骤(CentOS/Ubuntu 通用):

  • 步骤 1:停止 MySQL 服务

  • 步骤 2:跳过权限表启动 MySQL

  • 步骤 3:无密码登录 MySQL

  • 步骤 4:重建 root 账户

场景 1:MySQL 5.7 版本

-- 1. 切换到 mysql 系统库
USE mysql;

-- 2. 插入 root 账户(本地登录)
INSERT INTO user (
  Host, User, Password, Select_priv, Insert_priv, Update_priv, Delete_priv,
  Create_priv, Drop_priv, Reload_priv, Shutdown_priv, Process_priv, File_priv,
  Grant_priv, References_priv, Index_priv, Alter_priv, Show_db_priv, Super_priv,
  Create_tmp_table_priv, Lock_tables_priv, Execute_priv, Repl_slave_priv,
  Repl_client_priv, Create_view_priv, Show_view_priv, Create_routine_priv,
  Alter_routine_priv, Create_user_priv, Event_priv, Trigger_priv,
  Create_tablespace_priv
) VALUES (
  'localhost', 'root', PASSWORD('你的新密码'), 'Y', 'Y', 'Y', 'Y',
  'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y',
  'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y'
);

-- (可选)若需要远程 root 账户(%),补充插入
INSERT INTO user (Host, User, Password, Grant_priv, Super_priv)
VALUES ('%', 'root', PASSWORD('你的新密码'), 'Y', 'Y');

-- 3. 刷新权限(使账户生效)
FLUSH PRIVILEGES;

-- 4. 验证 root 账户是否创建成功
SELECT User, Host FROM mysql.user WHERE User='root';

场景2:MySQL 8.0 版本

-- 1. 先刷新权限(启用权限校验,否则 CREATE USER 可能失效)
FLUSH PRIVILEGES;

-- 2. 创建本地 root 账户(设置密码,替换为你的密码)
CREATE USER IF NOT EXISTS 'root'@'localhost' IDENTIFIED BY '你的新密码';

-- (可选)创建远程 root 账户(生产环境不推荐)
CREATE USER IF NOT EXISTS 'root'@'%' IDENTIFIED BY '你的新密码';

-- 3. 授予 root 全局所有权限(含授权权限)
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;

-- 4. 刷新权限
FLUSH PRIVILEGES;

-- 5. 验证账户
SHOW GRANTS FOR 'root'@'localhost';
  • 步骤 5:重启 MySQL 服务(恢复正常)

六、备份和恢复

(一)备份方式

1.逻辑备份

逻辑备份,将数据库导出为包含重新创建数据库所需的SQL命令的文本文件。

通过查询数据库,检索数据库结构。

备份速度较慢,因为服务器必须访问数据库信息并将其转换为逻辑格式。

逻辑备份具有高度的可移植性,在某些情况下可以还原到其他数据库提供程序(例如PostgreSQL)。

在服务器联机时执行。

备份不包括日志或配置文件。

2.物理备份

物理备份,复制原始数据库目录和包含数据库内容的文件。

备份可以包括日志和配置文件。

兼容性差:仅可移植到具有类似硬件和软件的其他计算机上。

比逻辑备份更快。

在服务器脱机或数据库中的所有表均已锁定时执行,以防止在备份期间进行更改。

(二)物理备份和恢复

1.执行物理备份

提示:备份前需要停止服务。

# 停止
[root@server ~]# systemctl stop mariadb

# 执行备份
[root@server ~]# cp -a /var/lib/mysql /backup/mysql
2.恢复物理备份

提示:恢复前需要停止服务。

# 停止服务
[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 ~]# ls /var/lib/mysql

# 启动服务
[root@server ~]# systemctl start mariadb

(三)逻辑备份和恢复

1.执行逻辑备份

mysqldump命令可用于逻辑备份。使用mysqldump命令连的MariaDB,用户至少需要对转储表具有SELECT特权,对转储视图至少需要SHOW VIEW,对于转储触发器至少需要TRIGGER特权。
语法:

Usage: mysqldump [OPTIONS] database [tables]
OR     mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
OR     mysqldump [OPTIONS] --all-databases [OPTIONS]
For more options, use mysqldump --help

常用选项:

-A, --all-databases Dump all the databases. This will be same as --databases
                      with all databases selected.
  --ignore-database=name 
                      Do not dump the specified database. To specify more than
                      one database to ignore, use the directive multiple times,
                      once for each database. Only takes effect when used
                      together with --all-databases|-A
  -B, --databases     Dump several databases. Note the difference in usage; in
                      this case no tables are given. All name arguments are
                      regarded as database names. 'USE db_name;' will be
                      included in the output.

  -Y, --all-tablespaces 
                      Dump all the tablespaces.
  --ignore-table=name Do not dump the specified table. To specify more than one
                      table to ignore, use the directive multiple times, once
                      for each table.  Each table must be specified with both
                      database and table names, e.g.,
                      --ignore-table=database.table.
  -y, --no-tablespaces 
                      Do not dump any tablespace information.

  --add-drop-database Add a DROP DATABASE before each create.
  --add-drop-table    Add a DROP TABLE before each create.

-x, --lock-all-tables 
                      Locks all tables across all databases. This is achieved
                      by taking a global read lock for the duration of the
                      whole dump. Automatically turns --single-transaction and
                      --lock-tables off.

示例:

# 备份方式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

inventory.dump.sql-2 文本文件部分内容:

--
-- Current Database: `inventory`
--

CREATE DATABASE /*!32312 IF NOT EXISTS*/ `inventory` /*!40100 DEFAULT CHARACTER SET latin1 */;

USE `inventory`;

--
-- Table structure for table `category`
--

DROP TABLE IF EXISTS `category`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `category` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `category`
--

LOCK TABLES `category` WRITE;
/*!40000 ALTER TABLE `category` DISABLE KEYS */;
INSERT INTO `category` VALUES (1,'Networking'),(2,'Servers'),(3,'Ssd');
/*!40000 ALTER TABLE `category` ENABLE KEYS */;
UNLOCK TABLES;

还原备份时,它将用备份的内容覆盖数据库服务器的内容。 如果数据库中的数据比备份中的数据新,该部分数据将会丢失。

2.恢复逻辑备份

模拟故障:删除数据库

[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

提示:如果使用 /backup/inventory.dump.sql-1 恢复数据,则需要提前创建inventory数据库,并使用以下命令恢复:

[root@server ~]# mysql -u root -p inventory < /backup/inventory.dump.sql-1
# 或者
MariaDB [(none)]> use inventory;
MariaDB [(inventory)]> source /backup/inventory.dump.sql-1

七、MySQL 集群架构概述

(一)MySQL 集群架构类别

1️⃣ 普通主从架构

1主 + N 从

  • 主:写
  • 从:读、备份、报表
  • 异步复制 / 半同步复制

特点

  • 最简单、最稳定、成本最低
  • 故障需要手动切换
  • 无法自动故障转移

适用

  • 小型企业、测试环境、非核心业务

2️⃣ 主从 + Keepalived / VIP

1主 + 1从 + VIP

  • 主挂了,Keepalived 自动把 VIP 飘到从库
  • 简单实现自动切换

特点

  • 部署简单
  • 无复制状态判断,容易脑裂
  • 不判断复制延迟,直接切

适用

  • 中小企业、追求低成本高可用

3️⃣ 主从 + MHA

1主 + N从 + MHA管理

  • 业界最经典、最成熟的高可用方案
  • MHA 自动检测主库故障
  • 自动补齐数据、切换、提升新主

特点

  • 最稳定、最成熟
  • 切换速度快(秒级)
  • 不会丢数据(半同步+日志补偿)
  • 配置复杂一点

适用

  • 中大规模企业主流
  • 电商、金融、生产核心库 90% 在用

4️⃣ 主从 + Orchestrator

自动化主从拓扑管理 + 故障自愈

  • 开源、可视化、自动切换
  • 可以跨机房、自动修复复制

特点

  • 比 MHA 更现代化
  • 自动化程度更高
  • 适合大规模集群

适用

  • 中大型企业、云厂商、多实例集群

5️⃣ MySQL MGR

MySQL Group Replication 官方组团复制。

单主模式 / 多主模式

  • MySQL 官方原生高可用
  • 基于 Paxos 一致性协议
  • 多节点自动选主、强一致

特点

  • 强一致,不丢数据
  • 无需第三方工具
  • 单主模式非常稳定
  • 多主模式不推荐生产

适用

  • 新一代主流架构
  • 金融、政企、云平台、新系统首选

6️⃣ 主主架构(双主)

双主互相同步

  • 可以双写(危险)
  • 企业基本只做一主一备,不双写

特点

  • 切换快
  • 双写会冲突、死锁、数据不一致
  • 几乎不用在核心业务

总结
  1. 基础主从:简单但不自动切换
  2. Keepalived 主从:简单高可用,但脑裂风险
  3. MHA:经典稳定、企业主流
  4. Orchestrator:自动化集群管理
  5. MGR:官方强一致,新一代主流
  6. 主主:不用在生产双写

(二)MySQL 集群架构-企业主流

🔥 第一名:MGR 单主模式(新系统首选)

🔥 第二名:MHA(老系统、传统架构主流)

🔥 第三名:Orchestrator(大规模集群)

🔥 第四名:简单主从(小型业务)


为什么 MGR 单主 + MHA是企业主流架构?

  1. MGR(官方、强一致、不丢数据)
  • MySQL 官方亲生
  • 分布式一致性协议(Paxos)
  • 自动选主、自动故障转移
  • 金融级安全
  • 云原生、好维护

新系统 90% 直接上 MGR

  1. MHA(最成熟、最稳定、最靠谱)
  • 线上运行 10 年+
  • 百万级核心库验证
  • 几乎不出问题
  • 切换可靠、不丢数据

老系统、核心业务依然大量用


(三)电商平台数据库架构

1. MySQL 单机写入能力有天花板

京东、拼多多、淘宝这种顶级电商,根本不靠“单主MySQL”扛流量,单主绝对扛不住。

原因很简单:MySQL 单机写入能力有天花板。

  • 普通云服务器:2000 ~ 4000 TPS
  • 高性能物理机:5000 ~ 8000 TPS
  • 优化到极限:顶多 1 万 TPS

电商真实流量(秒杀/大促)

  • 拼多多:几十万 TPS
  • 京东:几十万 ~ 上百万 TPS
  • 淘宝:上百万 TPS

差 10~100 倍,单主根本接不住。


2. 那京东、拼多多、淘宝用什么扛?

不是 MySQL 单主,而是 一套分布式数据库体系

① 分库分表

把一个库 → 拆成 16、32、64、128 个库,每个库都是独立的 MySQL 集群。

例如:

  • 用户库 32 组
  • 订单库 64 组
  • 商品库 64 组
  • 库存库 32 组
  • 支付库 16 组

每组都是 高可用集群(主从/MGR),靠水平拆分撑住海量写入。

② MySQL 只做“存储引擎”,前面全是缓存
  • Redis 集群扛90% 读流量
  • 本地缓存 + 分布式锁
  • 消息队列削峰
    MySQL 只干最核心的落盘
③ 读写极端分离
  • 读请求 100% 走从库 / 只读实例
  • 主库只承担写入+实时读
  • 从库可以扩展到 N 个
④ 不用普通 MySQL,用“云数据库/分布式数据库”
  • 京东:TDSQL(腾讯)+ JDB + 自研分库分表
  • 拼多多:阿里云 PolarDB + 分库分表
  • 淘宝:OceanBase(完全自研)

这些本质都是:分布式数据库 = 无限水平扩展


3. 那他们还用不用“主从/MGR”?

用!但不是一个主,而是:几百套、几千套 主从/MGR 集群

每套负责一小块业务,互不干扰。


4. 总结

京东、拼多多这种电商:

  1. 单主 MySQL 绝对撑不住,写入有天花板。
  2. 真实架构是:分库分表 + 读写分离 + 缓存 + 分布式数据库
  3. MySQL 只是其中一环,而且是成百上千套集群一起扛。
  4. 高可用用 MGR 或 优化版主从(自己封装)

八、MySQL 主从同步解决方案

MySQL 主从同步本质是主库将数据变更以日志形式传输给从库,从库重放日志实现数据一致

(一)MySQL 主从同步架构

  1. 一主一从:一个主库对应一个从库,适合小型业务。

  2. 一主多从:一个主库对应多个从库,可实现读写分离(主库写,多个从库读),提升读性能。

  3. 级联复制(主 - 从 - 从):从库不再直接连接主库,而是连接另一个从库(中间层从库),减轻主库的复制压力。

    例如:Master → Slave1 → Slave2(Slave1 既是从库,也是 Slave2 的主库)。

  4. 双主复制(互为主从):两个库互为主从,A 是 B 的主库,B 也是 A 的主库,通常用于高可用切换(如主库宕机后,从库快速切换为主库)。

(二)MySQL 主从同步流程

1.发送写请求(INSERT/UPDATE/DELETE)

2.执行SQL语句,更新数据

3.数据更新完成

4.将SQL变更写入binlog

5.立即向客户端返回执行成功(不等待从库)

6.binlog日志就绪

7.主动拉取主库binlog

8.将binlog写入从库relay log(中继日志)

9.读取relay log中的变更指令

10.执行SQL指令,更新从库数据

11.从库数据更新完成

客户端

主库(Master)

主库存储引擎

主库binlog日志

从库I/O线程

从库relay log

从库SQL线程

从库存储引擎

从库数据与主库最终一致

1.客户端程序(如Java应用、Navicat等)向主库(Master)的MySQL服务进程发送数据写请求(如INSERT/UPDATE/DELETE等SQL指令)。

2.主库MySQL服务进程接收客户端请求后,解析并执行对应的SQL语句,调用自身存储引擎(如InnoDB)完成数据更新。

3.主库存储引擎(如InnoDB)完成数据页写入、事务提交等操作,向主库MySQL服务进程确认数据更新完成。

4.主库MySQL服务进程的binlog写入线程,将本次数据变更的完整信息写入主库本地的二进制日志(binlog)文件。

5.主库MySQL服务进程完成binlog写入后,立即向客户端程序返回“执行成功”的响应(不等待从库反馈,异步核心特征)。

6.主库MySQL服务进程的binlog守护线程,将binlog日志持久化到磁盘并标记为“可读取状态”,等待从库I/O线程连接拉取。

7.从库(Slave)MySQL服务进程的I/O线程(Slave_IO_Running)主动建立与主库的TCP连接,请求拉取主库最新的binlog日志片段。

8.从库MySQL服务进程的I/O线程,将从主库拉取到的binlog内容,按顺序写入从库本地的中继日志(relay log)文件。

9.从库MySQL服务进程的SQL线程(Slave_SQL_Running)持续读取中继日志中的数据变更指令,按顺序解析成可执行的SQL逻辑。

10.从库MySQL服务进程的SQL线程执行解析后的SQL指令,调用从库存储引擎(如InnoDB)完成本地数据的更新。

11.从库存储引擎(如InnoDB)确认数据更新完成,从库数据与主库的变更内容最终保持一致。

(三)MySQL 主从同步方式

  1. 异步复制(Asynchronous Replication)
    核心原理:主库执行完 SQL 并写入 binlog 后,立即向客户端返回执行成功,不等待从库接收或执行 binlog。

特点:

性能最好(主库无额外等待),是 MySQL 默认的复制方式。

数据一致性风险最高:如果主库宕机,可能存在部分 binlog 未传输到从库,导致主从数据不一致。

适用场景:对性能要求高、对数据一致性要求较低的场景(如普通业务的读写分离)。

  1. 半同步复制(Semi-synchronous Replication)
    核心原理:主库执行完 SQL 并写入 binlog 后,会等待至少一个从库接收并确认(将 binlog 写入中继日志 relay log),再向客户端返回成功;如果超时(默认 10 秒),则降级为异步复制。

特点:

性能略低于异步复制,但数据一致性大幅提升(至少保证 binlog 已传输到一个从库)。

需要手动开启(依赖 plugin/semisync_master.so 和 semisync_slave.so 插件)。

适用场景:对数据一致性有一定要求,且能接受少量性能损耗的场景(如核心业务的主从架构)。

  1. 全同步复制(Fully Synchronous Replication)
    核心原理:主库执行完 SQL 后,必须等待所有从库接收并执行完 binlog,才向客户端返回成功。

特点:

数据一致性最高(主从实时一致)。

性能极差(主库需等待所有从库执行完成),MySQL 原生不支持,需通过 MGR(MySQL Group Replication)或第三方插件实现。

适用场景:对数据一致性要求极高的核心金融场景(极少使用)。

(四)MySQL 主从异步复制延迟

MySQL 异步复制的时间差(通常称为 “主从延迟”)没有固定值,它不是由 MySQL 内置的参数决定的固定间隔,而是由多种因素共同影响的动态值 —— 理论上可以是毫秒级,也可能达到秒级、分钟级甚至更长。

1.异步复制的延迟本质

异步复制过程中,主库完全不等待从库,所以延迟的大小完全取决于从库 “拉取 + 执行” 的速度,以及主库产生 binlog 的速度。

2.影响延迟的核心因素
(1)网络延迟

主从库之间的网络带宽、时延直接影响 binlog 的传输速度:

同机房 / 同可用区:网络延迟通常毫秒级(1-10ms),几乎可以忽略。

跨机房 / 跨地域:网络延迟可能达到几十毫秒甚至上百毫秒,是延迟的基础值。

(2)主库写入压力

主库如果高频执行大批量写入(如批量 INSERT/UPDATE、大事务),会快速产生大量 binlog,从库可能 “追不上”:

小事务(单条 INSERT/UPDATE):从库能实时跟进,延迟通常 < 100ms。

大事务(如一次性更新 10 万行数据):主库一次性写入大量 binlog,从库 SQL 线程执行需要时间,延迟可能达到秒级 / 分钟级。

(3)从库性能瓶颈

从库硬件配置(CPU / 内存 / 磁盘)低于主库:比如从库用机械硬盘(HDD),主库用固态硬盘(SSD),从库执行 SQL 的速度会远慢于主库,导致延迟累积。

从库开启了大量慢查询、索引维护、报表统计等额外操作:占用从库资源,导致 SQL 线程执行 binlog 的速度下降。

从库 SQL 线程是单线程(MySQL 5.6 及以下默认):无法并行执行 binlog,主库并发写入时,从库会出现明显延迟;MySQL 5.7 + 支持并行复制,可大幅缓解。

(4)复制格式的影响

基于行的复制(RBR):binlog 体积更大,传输和解析耗时略高于基于语句的复制(SBR),但一致性更好,是权衡后的最优选择。

3.实际场景中的延迟范围
场景典型延迟核心原因
小事务 + 同机房 + 高性能从库0-100ms网络 / 执行耗时可忽略
中等事务 + 跨机房100ms-1s网络延迟 + 少量 binlog 堆积
大批量写入 / 大事务1s - 数分钟从库 SQL 线程执行速度跟不上
从库性能瓶颈 / 慢查询数分钟 - 甚至小时资源耗尽,延迟持续累积
4.如何监控和优化延迟
(1) 监控延迟

可以通过从库执行以下命令查看实时延迟:

-- 查看从库状态,Seconds_Behind_Master 即为延迟秒数(NULL表示复制异常)
SHOW SLAVE STATUS\G;

-- 关键字段说明:
-- Seconds_Behind_Master:从库落后主库的秒数
-- Slave_IO_Running:I/O线程是否正常(负责拉取binlog)
-- Slave_SQL_Running:SQL线程是否正常(负责执行relay log)
(2)常见优化手段

提升从库硬件配置(CPU / 内存 / SSD),至少不低于主库。

开启 MySQL 并行复制(MySQL 5.7+:slave_parallel_workers = 4,根据 CPU 核数调整)。

拆分大事务,避免主库一次性产生大量 binlog。

从库关闭不必要的操作(如慢查询日志、非必要的索引、报表任务)。

跨地域场景可使用级联复制,先在主库同机房部署一个从库,再同步到异地从库。

(五)MySQL 主从同步数据丢失问题

数据丢失的核心场景:主库写入 binlog 后立即返回业务,主库内存中的 binlog 未写入磁盘,从库还没来得及同步,主库宕机(磁盘损坏等),则未同步的 binlog 丢失;

应对策略:

开启半同步复制(主库需等待至少 1 个从库确认接收 binlog)

开启 sync_binlog=1(每次事务刷盘 binlog)

innodb_flush_log_at_trx_commit=1(事务提交立即刷 redo log)

1.安装半同步插件

主库安装半同步插件

mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';

从库安装半同步插件

mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
2.配置半同步

主库 my.cnf 中额外配置:

[mysqld]
# ========== 半同步复制核心参数 ==========
# 开启半同步主库插件(永久生效)
plugin-load-add = rpl_semi_sync_master.so

# 启用主库半同步复制(1=开启,0=关闭)
rpl_semi_sync_master_enabled = 1

# 半同步超时时间(毫秒),超时后降级为异步复制
rpl_semi_sync_master_timeout = 1000

# 至少等待1个从库确认
rpl_semi_sync_master_wait_for_slave_count = 1

# 无可用从库时,是否等待(1=等待,直到超时)
rpl_semi_sync_master_wait_no_slave = 1

# 等待时机:AFTER_SYNC(推荐,主库刷binlog到磁盘后等待)
rpl_semi_sync_master_wait_point = AFTER_SYNC
# ========== 半同步复制核心参数 ==========

# 每次事务刷盘binlog(降低数据丢失风险)
sync_binlog = 1

# 事务提交立即刷redo log(ACID强一致性)
innodb_flush_log_at_trx_commit = 1

从库 my.cnf 中额外配置:

[mysqld]
# ========== 半同步复制核心参数 ==========
# 开启半同步从库插件(永久生效)
plugin-load-add = rpl_semi_sync_slave.so
# 启用从库半同步复制
rpl_semi_sync_slave_enabled = 1
# ========== 半同步复制核心参数 ==========

九、Mariadb 主从同步实践

(一)实验环境

主机名IP 地址角色
db1.lz.cloud10.1.8.11主库
db2.lz.cloud10.1.8.12从库

(二)环境准备

所有数据库节点安装好 Mariadb 数据库,安全初始化。

(三)配置主库

编辑 /etc/my.cnf.d/master.cnf 并重启服务,确保主库满足同步要求:

[root@db1 ~ 15:57:26]# cat > /etc/my.cnf.d/master.cnf <<'EOF'
> [mysqld]
> # 主从唯一ID,主库建议设1,从库设2/3等(必填,不能重复)
> server_id = 1
> 
> # 开启二进制日志,指定日志前缀(必填)
> log_bin = mysql-bin
> # binlog格式:ROW(行级复制,最安全,5.7默认可能是STATEMENT,需手动改)
> 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 ~ 16:06:31]# systemctl restart mariadb.service 
# 预期输出:无报错即重启成功

(四)配置从库

编辑 /etc/my.cnf.d/master.cnf 并重启服务,确保主库满足同步要求:

[root@db2 ~ 16:01:35]# cat > /etc/my.cnf.d/master.cnf <<'EOF'
> [mysqld]
> # 主从唯一ID,主库建议设1,从库设2/3等(必填,不能重复)
> server_id = 2
> 
> # 开启二进制日志,指定日志前缀(必填)
> log_bin = mysql-bin
> # binlog格式:ROW(行级复制,最安全,5.7默认可能是STATEMENT,需手动改)
> 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 ~ 16:06:58]# systemctl restart mariadb.service 
# 预期输出:无报错即重启成功

(五)主从同步

# 配置主数据库
[root@db1 ~ 16:06:50]# mysql -uroot -p123

MariaDB [(none)]> grant replication slave, replication client on *.* to 'repl'@'10.1.8.12' identified by 'Lz@123';

MariaDB [(none)]> flush privileges;

MariaDB [(none)]> show master status\G;
*************************** 1. row ***************************
            File: mysql-bin.000001
        Position: 490
    Binlog_Do_DB: 
Binlog_Ignore_DB: information_schema,performance_schema,sys
1 row in set (0.00 sec)

ERROR: No query specified

# 配置从数据库
[root@db2 ~ 16:09:57]# mysql -uroot -p123
MariaDB [(none)]> change master to master_host='10.1.8.11',
    -> master_user='repl',
    -> master_password='Lz@123',
    -> master_port=3306,
    ->  master_log_file='mysql-bin.000001',
    -> master_log_pos=490,
    ->  master_connect_retry=30;
Query OK, 0 rows affected (0.01 sec)

MariaDB [(none)]> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: 10.1.8.11
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 30
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 490
               Relay_Log_File: mysql-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: No
            Slave_SQL_Running: No
......
1 row in set (0.00 sec)

ERROR: No query specified

# 启动同步,再次查看状态
MariaDB [(none)]> start slave;

MariaDB [(none)]> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.1.8.11
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 30
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 490
               Relay_Log_File: mysql-relay-bin.000002
                Relay_Log_Pos: 529
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
......
ERROR: No query specified
# 确保 Slave_IO_Running 和 Slave_SQL_Running 状态为Yes。

# 主库写入数据
MariaDB [(none)]> create database test;

MariaDB [(none)]> use test;

MariaDB [test]> create table linux(username varchar(15) not null,password varchar(15) not null);

MariaDB [test]> insert into linux values ('lz1', 'Lz@123');

MariaDB [test]> insert into linux values ('lz2', 'Lz@123');

MariaDB [test]> insert into linux values ('lz3', 'Lz@123');

MariaDB [test]> commit;

MariaDB [test]> select * from linux;
+----------+----------+
| username | password |
+----------+----------+
| lz1      | Lz@123   |
| lz2      | Lz@123   |
| lz3      | Lz@123   |
+----------+----------+
3 rows in set (0.00 sec)

MariaDB [test]> 

# 从库查询
MariaDB [(none)]> select * from test.linux;
+----------+----------+
| username | password |
+----------+----------+
| lz1      | Lz@123   |
| lz2      | Lz@123   |
| lz3      | Lz@123   |
+----------+----------+
3 rows in set (0.00 sec)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值