3915 字
20 分钟
MySQL数据库指南(基础篇):小白必须掌握的五大核心技能

作为系统运维工程师,MySQL是绕不开的核心技能。本文将带你掌握MySQL运维的五大基础技能,从配置优化到日志分析,助你快速入门。

学习路线

本文内容适合有Linux基础的运维新手,学习时长约3-5天。建议在测试环境中动手实践每个操作。

一、熟练配置my.cnf核心参数#

MySQL的主配置文件my.cnf是性能调优的关键,掌握核心参数配置是运维的第一步。

1.1 配置文件位置#

不同系统下my.cnf的默认位置:

查找my.cnf位置
# 查看MySQL读取配置文件的顺序
mysql --help | grep my.cnf
# 常见位置
ls -l /etc/my.cnf # CentOS/RHEL
ls -l /etc/mysql/my.cnf # Ubuntu/Debian
ls -l ~/.my.cnf # 用户级配置
配置优先级

MySQL按顺序读取配置文件:/etc/my.cnf → /etc/mysql/my.cnf → ~/.my.cnf,后面的配置会覆盖前面的。

1.2 配置文件结构说明#

my.cnf采用INI格式,由多个配置段组成:

配置文件基本结构
[client] # 客户端程序(mysql命令)的配置
参数名 = 参数值
[mysqld] # MySQL服务端的配置(最重要)
参数名 = 参数值
[mysqldump] # mysqldump备份工具的配置
参数名 = 参数值

配置语法规则:

  • 每行一个参数,格式为参数名 = 参数值
  • #开头的行是注释
  • 参数名不区分大小写,但建议使用小写加下划线
  • 数字单位(千字节)、M(兆字节)、G(吉字节)

1.3 核心参数详解#

下面是一份生产环境常用的my.cnf配置模板:

/etc/my.cnf
2 collapsed lines
[client]
port = 3306
socket = /var/lib/mysql/mysql.sock
[mysqld]
# === 基本设置 ===
port = 3306
datadir = /var/lib/mysql
socket = /var/lib/mysql/mysql.sock
pid-file = /var/run/mysqld/mysqld.pid
user = mysql
# === 字符集设置 ===
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect = 'SET NAMES utf8mb4'
# === 连接设置 ===
max_connections = 500 # 最大连接数
max_connect_errors = 100 # 最大连接错误数
wait_timeout = 28800 # 空闲连接超时时间(秒)
interactive_timeout = 28800
back_log = 500 # 积压连接队列大小
# === 缓存设置 ===
# InnoDB缓冲池大小,建议设置为物理内存的60-80%
innodb_buffer_pool_size = 4G
innodb_buffer_pool_instances = 4 # 多实例提高并发
# 查询缓存(MySQL 8.0已移除)
query_cache_size = 0
# === 日志设置 ===
# 慢查询日志
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2# 超过2秒的查询记录
log_queries_not_using_indexes = 1 # 记录未使用索引的查询
# 错误日志
log_error = /var/log/mysql/error.log
# 二进制日志(用于主从复制和数据恢复)
log_bin = /var/log/mysql/mysql-bin
binlog_format = ROW
expire_logs_days = 7 # 日志保留天数
max_binlog_size = 100M # 单个日志文件大小
# === InnoDB设置 ===
innodb_file_per_table = 1 # 每表独立表空间
innodb_flush_log_at_trx_commit = 2 # 性能与安全平衡
innodb_log_file_size = 256M # 事务日志大小
innodb_log_buffer_size = 16M
# === 其他优化 ===
tmp_table_size = 64M
max_heap_table_size = 64M
table_open_cache = 4000
open_files_limit = 65535

重点参数说明:

参数名作用推荐值
datadir数据文件存储目录/var/lib/mysql
portMySQL监听端口3306(默认)
max_connections允许的最大并发连接数根据业务量调整,一般500-1000
innodb_buffer_pool_sizeInnoDB缓存池大小物理内存的60-80%
character-set-server默认字符集utf8mb4(支持emoji)
slow_query_log是否开启慢查询日志1(开启)
long_query_time慢查询阈值(秒)2(超过2秒记录)
内存参数调优关键

innodb_buffer_pool_size是最重要的参数,建议设置为物理内存的60-80%。例如8GB内存的服务器可设置为5-6GB。

1.4 修改配置后重启服务#

重启MySQL服务
# 备份原配置
cp /etc/my.cnf /etc/my.cnf.bak
# 编辑配置文件
vim /etc/my.cnf
# 检查配置语法
mysqld --validate-config
# 重启服务
systemctl restart mysqld
# 检查服务状态
systemctl status mysqld
# 验证参数是否生效
mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
配置修改风险

修改配置前务必备份原文件,错误的配置可能导致MySQL无法启动。建议在测试环境先验证。

二、掌握用户权限管理#

MySQL的权限系统遵循最小权限原则,合理的权限管理是数据安全的基础。

2.1 用户创建语法详解#

CREATE USER语法格式:

CREATE USER '用户名'@'允许登录的主机' IDENTIFIED BY '密码';

语法组成部分:

  • 用户名: 登录MySQL使用的账号名称
  • @: 分隔符,固定写法
  • 允许登录的主机: 指定哪些机器可以用这个账号登录
    • localhost: 只能本机登录
    • 192.168.1.100: 只能从这个IP登录
    • 192.168.1.%: 可以从192.168.1网段任意IP登录
    • %: 可以从任意IP登录(不安全,生产环境慎用)
  • IDENTIFIED BY: 固定关键字,表示”密码是”
  • 密码: 登录时使用的密码,需要用单引号包裹

实际示例:

-- 创建只能本机登录的用户
CREATE USER 'admin'@'localhost' IDENTIFIED BY 'Admin@2024';
-- 创建可以从192.168.1网段登录的用户
CREATE USER 'webapp'@'192.168.1.%' IDENTIFIED BY 'StrongPass@2024';
-- 创建可以从任意IP登录的用户(测试环境)
CREATE USER 'testuser'@'%' IDENTIFIED BY 'Test@2024';
主机地址通配符
  • %: 匹配任意字符
  • 192.168.1.%: 匹配192.168.1.0到192.168.1.255
  • %.example.com: 匹配example.com域下所有主机

2.2 权限授予语法详解#

GRANT语法格式:

GRANT 权限类型 ON 数据库名.表名 TO '用户名'@'主机';

语法组成部分:

  • 权限类型: 要授予的权限,如SELECT、INSERT、UPDATE等
  • ON: 固定关键字,表示”在…上”
  • 数据库名.表名: 指定权限作用范围
    • *.*: 所有数据库的所有表
    • webapp_db.*: webapp_db数据库的所有表
    • webapp_db.users: webapp_db数据库的users表
  • TO: 固定关键字,表示”给”
  • 用户名@主机: 接收权限的用户

实际示例:

-- 授予webapp_db数据库的所有权限
GRANT ALL PRIVILEGES ON webapp_db.* TO 'webapp'@'192.168.1.%';
-- 授予只读权限(只能查询)
GRANT SELECT ON webapp_db.* TO 'readonly'@'%';
-- 授予特定表的增删改查权限
GRANT SELECT, INSERT, UPDATE, DELETE ON webapp_db.users TO 'app'@'%';
-- 授予所有数据库的查询权限
GRANT SELECT ON *.* TO 'monitor'@'localhost';
-- 刷新权限(使授权立即生效)
FLUSH PRIVILEGES;

常用权限类型说明:

权限名称说明对应操作
SELECT查询数据SELECT * FROM table
INSERT插入数据INSERT INTO table VALUES(...)
UPDATE更新数据UPDATE table SET ...
DELETE删除数据DELETE FROM table
CREATE创建数据库/表CREATE DATABASE/TABLE
DROP删除数据库/表DROP DATABASE/TABLE
ALTER修改表结构ALTER TABLE
INDEX创建/删除索引CREATE INDEX
ALL PRIVILEGES所有权限(除GRANT)上述所有操作
GRANT OPTION授权给其他用户GRANT ... TO ...

2.3 完整的用户创建与授权流程#

创建应用数据库账号完整流程
-- 第1步:创建用户
CREATE USER 'webapp'@'192.168.1.%' IDENTIFIED BY 'StrongPass@2024';
-- 第2步:授予权限
GRANT SELECT, INSERT, UPDATE, DELETE ON webapp_db.* TO 'webapp'@'192.168.1.%';
-- 第3步:刷新权限
FLUSH PRIVILEGES;
-- 第4步:查看用户权限
SHOW GRANTS FOR 'webapp'@'192.168.1.%';
-- 第5步:测试登录
-- 在应用服务器上执行:
-- mysql -h 数据库服务器IP -u webapp -p
为什么要分开创建用户和授权?

MySQL将用户管理和权限管理分离:

  • CREATE USER: 创建登录凭证(用户名+密码+允许登录的主机)
  • GRANT: 授予这个用户可以做什么操作 这样设计更灵活,可以随时调整用户权限而不影响登录凭证。

2.4 不同场景的权限配置#

不同场景的权限授予
-- 场景1:应用程序账号(读写权限,不能改表结构)
CREATE USER 'app_user'@'10.0.0.%' IDENTIFIED BY 'AppPass@2024';
GRANT SELECT, INSERT, UPDATE, DELETE
ON webapp_db.*
TO 'app_user'@'10.0.0.%';
-- 场景2:备份账号(需要锁表权限)
CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'BackupPass@2024';
GRANT SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER
ON *.*
TO 'backup_user'@'localhost';
-- 场景3:监控账号(仅需查看权限)
CREATE USER 'monitor'@'%' IDENTIFIED BY 'MonitorPass@2024';
GRANT SELECT, PROCESS, REPLICATION CLIENT
ON *.*
TO 'monitor'@'%';
-- 场景4:开发测试账号(开发库全部权限)
CREATE USER 'developer'@'%' IDENTIFIED BY 'DevPass@2024';
GRANT ALL PRIVILEGES
ON dev_db.*
TO 'developer'@'%';
-- 统一刷新权限
FLUSH PRIVILEGES;

2.5 用户管理进阶操作#

查看用户语法:

-- 查看所有用户
SELECT user, host, account_locked FROM mysql.user;
-- 查看当前登录用户
SELECT USER(), CURRENT_USER();
-- 查看指定用户的权限
SHOW GRANTS FOR 'webapp'@'192.168.1.%';

修改密码语法:

ALTER USER '用户名'@'主机' IDENTIFIED BY '新密码';
-- 修改webapp用户的密码
ALTER USER 'webapp'@'192.168.1.%' IDENTIFIED BY 'NewPass@2024';
-- 修改当前登录用户自己的密码
ALTER USER USER() IDENTIFIED BY 'MyNewPass@2024';

撤销权限语法:

REVOKE 权限类型 ON 数据库名.表名 FROM '用户名'@'主机';
-- 撤销DELETE权限
REVOKE DELETE ON webapp_db.* FROM 'webapp'@'192.168.1.%';
-- 撤销所有权限
REVOKE ALL PRIVILEGES ON webapp_db.* FROM 'webapp'@'192.168.1.%';
-- 刷新权限
FLUSH PRIVILEGES;

删除用户语法:

DROP USER '用户名'@'主机';
-- 删除指定用户
DROP USER 'olduser'@'%';
-- 删除多个用户
DROP USER 'user1'@'%', 'user2'@'localhost';

锁定/解锁用户:

-- 锁定用户(禁止登录)
ALTER USER 'webapp'@'192.168.1.%' ACCOUNT LOCK;
-- 解锁用户
ALTER USER 'webapp'@'192.168.1.%' ACCOUNT UNLOCK;
删除用户注意事项

删除用户会同时删除该用户的所有权限,但不会删除该用户创建的数据库和表。删除前请确认:

  1. 该用户不再被应用程序使用
  2. 已备份相关数据
  3. 已通知相关人员

三、掌握数据库、表、数据的基本操作#

这是运维日常工作中最频繁的操作,必须熟练掌握。

3.1 数据库操作#

查看数据库语法:

SHOW DATABASES;
-- 查看所有数据库
SHOW DATABASES;
-- 查看数据库名包含"app"的数据库
SHOW DATABASES LIKE '%app%';

创建数据库语法:

CREATE DATABASE 数据库名 CHARACTER SET 字符集 COLLATE 排序规则;

语法说明:

  • 数据库名: 要创建的数据库名称,建议使用小写字母和下划线
  • CHARACTER SET: 指定字符集,推荐utf8mb4(支持emoji和特殊字符)
  • COLLATE: 指定排序规则,推荐utf8mb4_unicode_ci(不区分大小写)
-- 创建数据库(指定字符集)
CREATE DATABASE webapp_db
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
-- 创建数据库(简化写法,使用默认字符集)
CREATE DATABASE test_db;
-- 如果数据库不存在才创建
CREATE DATABASE IF NOT EXISTS webapp_db;

查看数据库详情:

-- 查看数据库创建语句
SHOW CREATE DATABASE webapp_db;
-- 查看数据库字符集
SELECT
SCHEMA_NAME AS '数据库名',
DEFAULT_CHARACTER_SET_NAME AS '字符集',
DEFAULT_COLLATION_NAME AS '排序规则'
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME = 'webapp_db';

切换数据库语法:

USE 数据库名;
-- 切换到webapp_db数据库
USE webapp_db;
-- 查看当前使用的数据库
SELECT DATABASE();

删除数据库语法:

DROP DATABASE 数据库名;
-- 删除数据库(危险操作!)
DROP DATABASE test_db;
-- 如果数据库存在才删除
DROP DATABASE IF EXISTS test_db;
删除数据库风险

DROP DATABASE会永久删除数据库及其所有表和数据,无法恢复!生产环境操作前必须:

  1. 确认数据库不再使用
  2. 完成数据备份
  3. 获得上级审批

3.2 数据表操作#

创建表语法:

CREATE TABLE 表名 (
字段名1 数据类型 [约束],
字段名2 数据类型 [约束],
...
[索引定义]
) ENGINE=存储引擎 DEFAULT CHARSET=字符集 COMMENT='表注释';

常用数据类型:

数据类型说明示例
INT整数用户ID、年龄
BIGINT大整数订单号、手机号
VARCHAR(长度)可变长度字符串用户名、邮箱
TEXT长文本文章内容、备注
DECIMAL(总位数,小数位)精确小数金额、价格
DATE日期生日(2024-01-01)
DATETIME日期时间创建时间(2024-01-01 10:30:00)
TIMESTAMP时间戳更新时间(自动记录)
TINYINT小整数状态(0/1)、性别

常用约束:

约束说明示例
PRIMARY KEY主键(唯一且非空)id INT PRIMARY KEY
AUTO_INCREMENT自动递增id INT AUTO_INCREMENT
NOT NULL不允许为空username VARCHAR(50) NOT NULL
UNIQUE唯一(不能重复)email VARCHAR(100) UNIQUE
DEFAULT默认值status TINYINT DEFAULT 1
COMMENT字段注释username VARCHAR(50) COMMENT '用户名'
创建表示例
-- 创建用户表
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT COMMENT '用户ID',
username VARCHAR(50) NOT NULL UNIQUE COMMENT '用户名',
email VARCHAR(100) COMMENT '邮箱',
password VARCHAR(255) NOT NULL COMMENT '密码',
status TINYINT DEFAULT 1 COMMENT '状态:1启用 0禁用',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
INDEX idx_username (username),
INDEX idx_email (email)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
-- 创建订单表
CREATE TABLE orders (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
order_no VARCHAR(32) NOT NULL UNIQUE COMMENT '订单号',
user_id INT NOT NULL COMMENT '用户ID',
total DECIMAL(10,2) NOT NULL COMMENT '订单金额',
status TINYINT DEFAULT 0 COMMENT '状态:0待付款 1已付款 2已发货 3已完成',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_user_id (user_id),
INDEX idx_order_no (order_no),
INDEX idx_status (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
为什么要加索引?

索引就像书的目录,可以快速找到数据:

  • 在经常用于查询条件的字段上建索引(如WHERE username = 'xxx')
  • 在经常用于排序的字段上建索引(如ORDER BY created_at)
  • 在经常用于关联的字段上建索引(如JOIN ON user_id)

查看表结构语法:

-- 查看表结构(简洁)
DESC users;
-- 查看表结构(详细)
SHOW COLUMNS FROM users;
-- 查看建表语句
SHOW CREATE TABLE users;
-- 查看表索引
SHOW INDEX FROM users;
-- 查看表状态(大小、行数等)
SHOW TABLE STATUS LIKE 'users';

修改表结构语法:

-- 添加字段
ALTER TABLE 表名 ADD COLUMN 字段名 数据类型 [约束];
-- 修改字段
ALTER TABLE 表名 MODIFY COLUMN 字段名 新数据类型;
-- 删除字段
ALTER TABLE 表名 DROP COLUMN 字段名;
-- 添加索引
ALTER TABLE 表名 ADD INDEX 索引名 (字段名);
-- 删除索引
ALTER TABLE 表名 DROP INDEX 索引名;
-- 添加手机号字段
ALTER TABLE users ADD COLUMN phone VARCHAR(20) COMMENT '手机号';
-- 修改邮箱字段长度
ALTER TABLE users MODIFY COLUMN email VARCHAR(150);
-- 删除手机号字段
ALTER TABLE users DROP COLUMN phone;
-- 在status字段上添加索引
ALTER TABLE users ADD INDEX idx_status (status);
-- 删除索引
ALTER TABLE users DROP INDEX idx_status;
-- 修改表名
ALTER TABLE users RENAME TO sys_users;

查看表占用空间:

-- 查看指定数据库所有表的大小
SELECT
table_name AS '表名',ROUND((data_length + index_length) / 1024 / 1024, 2) AS '大小(MB)',
table_rows AS '行数'
FROM information_schema.tables
WHERE table_schema = 'webapp_db'
ORDER BY (data_length + index_length) DESC;

删除表语法:

-- 删除表(删除表结构和数据)
DROP TABLE users;
-- 如果表存在才删除
DROP TABLE IF EXISTS users;
-- 清空表数据(保留表结构,重置自增ID)
TRUNCATE TABLE users;
-- 删除表数据(保留表结构,不重置自增ID)
DELETE FROM users;
TRUNCATE vs DELETE
  • TRUNCATE TABLE: 快速清空表,重置自增ID,不能回滚
  • DELETE FROM: 逐行删除,不重置自增ID,可以回滚 生产环境清空大表推荐用TRUNCATE,速度更快。

3.3 数据操作(CRUD)#

INSERT - 插入数据语法:

INSERT INTO 表名 (字段1, 字段2, ...) VALUES (值1, 值2, ...);
-- 插入单条数据
INSERT INTO users (username, email, password)
VALUES ('admin', 'admin@example.com', 'hashed_password');
-- 插入数据(省略字段名,按表结构顺序)
INSERT INTO users
VALUES (NULL, 'user1', 'user1@example.com', 'pass1', 1, NOW(), NOW());
-- 批量插入(推荐,效率高)
INSERT INTO users (username, email, password) VALUES
('user1', 'user1@example.com', 'pass1'),
('user2', 'user2@example.com', 'pass2'),
('user3', 'user3@example.com', 'pass3');
-- 插入时忽略重复数据(不报错)
INSERT IGNORE INTO users (username, email, password)
VALUES ('admin', 'admin@example.com', 'pass');
-- 插入或更新(如果主键/唯一键冲突则更新)
INSERT INTO users (id, username, email, password)
VALUES (1, 'admin', 'admin@example.com', 'newpass')
ON DUPLICATE KEY UPDATE
email = 'admin@example.com',
password = 'newpass';

SELECT - 查询数据语法:

SELECT 字段列表 FROM 表名 [WHERE 条件] [ORDER BY 排序] [LIMIT 数量];
-- 查询所有数据
SELECT * FROM users;
-- 查询指定字段
SELECT id, username, email FROM users;
-- 条件查询
SELECT * FROM users WHERE status = 1;
-- 多条件查询(AND表示"并且")
SELECT * FROM users WHERE status = 1 AND created_at >= '2024-01-01';
-- 多条件查询(OR表示"或者")
SELECT * FROM users WHERE username = 'admin' OR email = 'admin@example.com';
-- 模糊查询(LIKE)
SELECT * FROM users WHERE email LIKE '%@gmail.com';
-- 范围查询(BETWEEN)
SELECT * FROM users WHERE id BETWEEN 10 AND 100;
-- 列表查询(IN)
SELECT * FROM users WHERE id IN (1, 5, 10, 20);
-- 空值查询
SELECT * FROM users WHERE email IS NULL;
-- 非空查询
SELECT * FROM users WHERE email IS NOT NULL;
-- 排序查询(ASC升序,DESC降序)
SELECT * FROM users ORDER BY created_at DESC;
-- 限制返回数量
SELECT * FROM users LIMIT 10;
-- 分页查询(跳过前10条,取10条)
SELECT * FROM users LIMIT 10, 10;
-- 去重查询
SELECT DISTINCT username FROM users;
-- 统计查询
SELECT COUNT(*) AS total FROM users;
SELECT COUNT(*) AS total FROM users
MySQL数据库指南(基础篇):小白必须掌握的五大核心技能
https://www.6ixblog.site/posts/linux-basic-13-1/
作者
Licwic
发布于
2025-04-14
许可协议
CC BY-NC-SA 4.0