MariaDB 数据库笔记


📋 数据库介绍

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


📋 MariaDB 介绍

MariaDB 是 MySQL 的一个分支,主要由开源社区维护,采用 GPL 授权许可。MariaDB 完全兼容 MySQL,包括 API 和命令行,能轻松成为 MySQL 的代替品。


1️⃣ MariaDB 部署

1.1 安装数据库

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

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

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

# 防火墙
[root@server ~ 09:50:51]# firewall-cmd --permanent --add-service=mysql
[root@server ~ 09:50:51]# firewall-cmd --reload

1.2 数据库进程

进程 角色 说明
mysqld_safe 🛡️ 监控守护 安全启动、监控 mysqld、崩溃自动重启、管理日志
mysqld ⚙️ 核心引擎 处理连接、管理数据、执行 SQL、事务和锁机制

两者是父进程-子进程关系:

[root@server ~]# ps -ef | grep -E 'mysqld_safe|mysqld'
root      1234     1  /bin/sh /usr/bin/mysqld_safe ...
mysql     1456  1234  /usr/libexec/mysqld ...

📌 mysqld_saferoot 运行,mysqldmysql 用户运行(父进程 PID=1234)

1.3 加固数据库

[root@server ~ 10:03:53]# mysql_secure_installation

交互式操作,包括:

  • 为 root 设置密码
  • 禁止 root 远程登录
  • 删除匿名用户
  • 删除 test 数据库

1.4 配置数据库

MariaDB 采用 主配置文件 + 细分配置文件 的分层结构:

文件 说明 常见配置项
/etc/my.cnf 📄 全局主配置,优先级最高 所有参数,通过 !includedir 加载子目录
server.cnf 🖥️ 服务器端配置 [mysqld] 端口、监听地址、数据目录、缓存大小
client.cnf 🔗 客户端通用配置 [client] 默认用户名、密码、主机、端口
mysql-clients.cnf 🔗 客户端补充配置 优先级低于 client.cnf

2️⃣ 连接数据库

2.1 连接本地(Socket)

[root@server ~ 10:22:41]# mysql -u root
MariaDB [(none)]>

2.2 连接远端(TCP/IP)

# 创建远程用户
MariaDB [(none)]> create user laoma identified by '123';
MariaDB [(none)]> grant all privileges on *.* to ggg;
MariaDB [(none)]> flush privileges;
# 客户端连接测试
[root@client ~ 10:22:35]# mysql -u ggg -p123 -h server

2.3 非交互方式

[root@server ~ 10:21:55]# mysql -u root -p -e 'show databases;'
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+

2.4 配置客户端

🔧 /etc/my.cnf.d/client.cnf:

[client]
user=ggg
password=123
host=server
port=3306
database=mysql
prompt="\\u@\\h [\\d]> "

# 直接登录
[root@client ~ 10:26:57]# mysql
ggg@10.1.8.10 [mysql]>

3️⃣ 结构化查询语言(SQL)

3.1 数据库操作

-- 📋 查询数据库列表
SHOW DATABASES;

-- 🔄 使用数据库
USE database_name;

-- ➕ 创建数据库
CREATE DATABASE database_name;

-- ❌ 删除数据库
DROP DATABASE database_name;

3.2 表操作

-- 📋 查询表列表
SHOW TABLES;

-- ➕ 创建表
CREATE TABLE table_name (
    column1 datatype constraints,
    column2 datatype constraints
);

-- ➕ 插入记录
INSERT INTO table_name (col1, col2) VALUES (val1, val2);

-- ✏️ 更新记录
UPDATE table_name SET col1 = val1 WHERE condition;

-- ❌ 删除记录
DELETE FROM table_name WHERE condition;

-- ❌ 删除表
DROP TABLE table_name;

3.3 查询语法

-- 🔍 条件查询
SELECT * FROM table_name WHERE condition;

-- 条件操作符:=、<>、>、<、>=、<=
-- BETWEEN:匹配范围
-- IN:匹配列表
-- LIKE:字符串匹配(% 多个字符,_ 单个字符)
-- AND / OR:逻辑与 / 或

-- 📊 排序
SELECT * FROM table_name ORDER BY column;

-- 📊 聚合函数
SELECT AVG(col) FROM table_name;  -- 平均值
SELECT MAX(col) FROM table_name;  -- 最大值
SELECT MIN(col) FROM table_name;  -- 最小值
SELECT COUNT(col) FROM table_name; -- 计数

-- 📊 分组
SELECT col, COUNT(*) FROM table_name GROUP BY col;

4️⃣ 管理数据库用户

4.1 创建用户

CREATE USER 'username'@'host' IDENTIFIED BY 'password';

4.2 查询用户

SELECT User, Host FROM mysql.user;

4.3 授予权限

-- 1️⃣ 全局范围(所有数据库)
GRANT ALL PRIVILEGES ON *.* TO 'user'@'host';

-- 2️⃣ 数据库范围
GRANT ALL PRIVILEGES ON db_name.* TO 'user'@'host';

-- 3️⃣ 表范围
GRANT SELECT, INSERT ON db_name.table_name TO 'user'@'host';

-- 4️⃣ 列范围
GRANT SELECT (col1, col2) ON db_name.table_name TO 'user'@'host';

FLUSH PRIVILEGES;

4.4 查询权限

SHOW GRANTS FOR 'user'@'host';

4.5 回收权限

REVOKE privilege ON database.* FROM 'user'@'host';
FLUSH PRIVILEGES;

4.6 删除用户

DROP USER 'user'@'host';

4.7 更改密码

-- root 修改普通用户密码
SET PASSWORD FOR 'user'@'host' = PASSWORD('new_password');
-- 或
ALTER USER 'user'@'host' IDENTIFIED BY 'new_password';

-- 普通用户改自己密码
SET PASSWORD = PASSWORD('new_password');

4.8 🚨 常见故障排除

问题 解决方案
忘记 root 密码 --skip-grant-tables 启动 → 直接更新 mysql.user 表 → 重启
回收了 root 权限 --skip-grant-tables 启动 → 重新授予权限 → 重启
删除了 root 用户 --skip-grant-tables 启动 → INSERT 重建 root 用户 → 重启

5️⃣ 备份和恢复

5.1 备份方式

方式 说明 适用场景
逻辑备份 📝 导出 SQL 语句,可跨版本/平台 小数据量、迁移
物理备份 💾 直接复制数据文件,速度快 大数据量、快速恢复

5.2 物理备份

# 停止 → 复制 → 启动
[root@server ~]# systemctl stop mariadb
[root@server ~]# cp -a /var/lib/mysql /backup/
[root@server ~]# systemctl start mariadb

# 恢复
[root@server ~]# systemctl stop mariadb
[root@server ~]# rm -rf /var/lib/mysql/*
[root@server ~]# cp -a /backup/mysql_backup/* /var/lib/mysql/
[root@server ~]# systemctl start mariadb

5.3 逻辑备份

# 备份单个数据库(不含 CREATE DATABASE)
[root@server ~]# mysqldump -u root -p db_name > backup.sql

# 备份单个数据库(含 CREATE DATABASE)
[root@server ~]# mysqldump -u root -p --databases db_name > backup.sql

# 备份所有数据库
[root@server ~]# mysqldump -u root -p --all-databases > all_backup.sql

# 恢复
[root@server ~]# mysql -u root -p db_name < backup.sql
[root@server ~]# mysql -u root -p < backup.sql

6️⃣ MySQL 集群架构

6.1 架构类别

架构 说明 特点
普通主从 一主多从 读写分离、手动故障转移
主从 + Keepalived 虚拟 IP 自动切换 自动故障转移
主从 + MHA Master High Availability 自动检测并提升新主
主从 + Orchestrator 高级复制拓扑管理 GitHub 开源,在线切换
MySQL MGR Group Replication 强一致性、自动选主
主主架构(双主) 互为主从 可双向写入,需处理冲突

6.2 企业主流方案

企业主流采用 MGR(MySQL Group Replication)

  • ✅ 强一致性
  • ✅ 自动选主
  • ✅ 多节点写入
  • ✅ 在线扩缩容

6.3 电商平台架构

层级 方案 说明
📈 单机瓶颈 MySQL 单机写入有上限 需要分布式方案
🏗️ 大规模方案 MySQL + 分库分表(MyCat/ShardingSphere) 京东、拼多多等采用
🛡️ 主从/MGR 用途 高可用、异地容灾 保障数据安全

7️⃣ MySQL 主从同步

7.1 同步架构

binlog

binlog

binlog

主库 Master

从库 Slave 1

从库 Slave 2

从库 Slave 3

7.2 同步流程

网络传输

主库写入

binlog

Dump 线程

I/O 线程

relay log

SQL 线程

从库数据

  1. 📝 主库写入 → 记录 binlog
  2. 📤 Dump 线程发送 binlog
  3. 📥 从库 I/O 线程接收 → 写入 relay log
  4. ▶️ SQL 线程读取 relay log → 重放

7.3 同步方式

方式 说明 特点
异步复制 主库不等待从库确认 性能最好,可能丢数据
⚖️ 半同步复制 等待至少一个从库确认 性能与可靠性平衡 ⭐ 推荐
🐢 全同步复制 等待所有从库确认 强一致性,性能最差

7.4 延迟问题

📌 本质: 从库 SQL 线程重放速度跟不上主库写入

影响因素:

  • 主库大事务(大批量更新)
  • 从库硬件性能低
  • 从库同时提供读取服务
  • 网络延迟

优化方案:

  • SHOW SLAVE STATUS 查看 Seconds_Behind_Master
  • 避免大事务,分批处理
  • 多线程复制 slave_parallel_workers
  • 从库使用更高性能硬件

7.5 数据丢失与半同步

异步复制下主库宕机会丢数据 → 解决方案:

[mysqld]
# 半同步主库配置
plugin-load-add = rpl_semi_sync_master.so
rpl_semi_sync_master_enabled = 1
rpl_semi_sync_master_timeout = 10000
rpl_semi_sync_master_wait_for_slave_count = 1
rpl_semi_sync_master_wait_point = AFTER_SYNC
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1

# 半同步从库额外配置
plugin-load-add = rpl_semi_sync_slave.so
rpl_semi_sync_slave_enabled = 1

8️⃣ MariaDB 主从同步实践

📋 实验环境

主机名 IP 地址 角色
db1.laoma.cloud 10.1.8.11 👑 主库
db2.laoma.cloud 10.1.8.12 📋 从库

🔧 配置主库

[root@db1 ~ 15:52:11]# 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 ~ 16:05:42]# systemctl restart mariadb

🔧 配置从库

[root@db2 ~ 15:52:17]# 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 ~ 16:06:13]# systemctl restart mariadb

🔗 建立主从同步

# 1️⃣ 主库:创建复制用户
[root@db1 ~ 16:06:46]# mysql -uroot -p123
MariaDB [(none)]> grant replication slave, replication client on *.*
    -> to 'repl'@'10.1.8.12' identified by '123';
MariaDB [(none)]> flush privileges;

# 2️⃣ 主库:查看 binlog 位置
MariaDB [(none)]> show master status\G
*************************** 1. row ***************************
            File: mysql-bin.000001
        Position: 3089

# 3️⃣ 从库:指定主库信息
[root@db2 ~ 16:09:34]# mysql -uroot -p123
MariaDB [(none)]> change master to
    -> master_host='10.1.8.11',
    -> master_user='repl',
    -> master_password='123',
    -> master_port=3306,
    -> master_log_file='mysql-bin.000001',
    -> master_log_pos=3089,
    -> master_connect_retry=30;

# 4️⃣ 从库:重启并检查状态
[root@db2 ~ 16:14:06]# systemctl restart mariadb.service
[root@db2 ~ 16:14:53]# mysql -uroot -p123 -e 'show slave status\G' | grep 'Slave.*Running'
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

✅ 验证同步

# 主库写入数据
[root@db1 ~]# mysql -uroot -p123
MariaDB [(none)]> create database test;
MariaDB [(none)]> use test;
MariaDB [(none)]> create table linux(username varchar(15) not null, password varchar(15) not null);
MariaDB [(none)]> insert into linux values ('g1', 'g1@123'), ('g2', 'g2@123'), ('g3', 'g3@123');
MariaDB [(none)]> commit;

# 从库查询 → 数据已同步
[root@db2 ~]# mysql -uroot -p123 -e 'select * from test.linux;'
+----------+----------+
| username | password |
+----------+----------+
| g1       | g1@123   |
| g2       | g2@123   |
| g3       | g3@123   |
+----------+----------+
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐