学习笔记|MySQL
本文最后更新于:5 years ago
1.数据库基本概念
**数据库(DateBase):**用于储存和管理数据的仓库
1.1特点
- 持久化储存数据,数据库是一个文件系统
- 方便储存和管理数据
- 使用了统一的方式操作数据库——SQL
2.MySQL 数据库软件
2.1安装
CentOS 需要安装 mariadb。分别为 mariadb-server 和 mariadb-client。
1 |
|
2.2卸载
1 |
|
2.3启动
1 |
|
2.4开机自启
1 |
|
2.5配置
执行以下语句,开始进入配置步骤。
1 |
|
根据提示,完成以下步骤:
1 |
|
2.7配置字符集
1 |
|
在[mysqld]中添加 default-character-set=utf8
。
1 |
|
PS:Client 的字符集在 /etc/my.cnf.d/client.cnf
中的 [client] 和/etc/my.cnf.d/mysql-clients.cnf
中的 [mysql] 添加 default-character-set=utf8
。
2.8创建用户
1 |
|
参数 | 说明 |
---|---|
username | 将要创建的用户名 |
host | 指定该用户在哪个主机上可以登陆,如果是本地用户可用localhost,如果想让该用户可以从任意远程主机登陆,可以使用通配符% |
password | 该用户的登陆密码,密码可以为空,如果为空则该用户可以不需要密码登陆服务器 |
2.9其他命令
2.9.1登陆
1 |
|
2.9.2远程登陆
利用 -h
加 ip。
1 |
|
报错排查
- ERROR 2003 (HY000): Can’t connect to MySQL server on ‘192.168.47.128’ (111)
- 设置 bind-address 监听IP
1
vim /etc/mysql/mariadb.conf.d/50-server.cnf
- 设置 bind-address 监听IP
- ERROR 1698 (28000): Access denied for user ‘root’@‘192.168.47.1’
- 设置root 用户权限
1
2UPDATE mysql.user SET host='%' WHERE user='root' AND host='localhost';
FLUSH PRIVILEGES; - 查看服务器日志 /var/log/mysql/error.log
- 设置权限
1
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'your_password' WITH GRANT OPTION;
GRANT ALL PRIVILEGES
:授予用户所有权限(包括选择、插入、更新、删除、创建数据库、修改权限)。ALL PRIVILEGES
:允许该用户在 MySQL 中执行任何操作。ON *.*
:指定了权限的作用范围。(第一个*
表示所有数据库,第二个*
表示所有数据库中的所有表)。TO 'root'@'%'
:指定用户的用户名和允许连接的主机。'root'
是用户名,表示这是对root
用户授予权限。'%'
表示允许该用户从任何 IP 地址进行访问。如果想限制某个 IP,可以将'%
’ 改成具体的 IP 地址,如'192.168.1.100'
。IDENTIFIED BY 'your_password'
:用于设置用户root
的密码。'your_password'
是密码,可以替换成你希望为root
用户设置的实际密码。如果已经为root
用户设置了密码,则可以省略此部分。- WITH GRANT OPTION:表示授予
root
用户 转授权限 的能力。即,root
用户可以将自己拥有的权限授权给其他用户。
- 设置root 用户权限
2.9.3退出
1 |
|
3.目录结构
3.1路径
- usr/bin/mysql 是指:mysql的运行路径
- var/lib/mysql 是指:mysql数据库文件的存放路径
- usr/lib/mysql 是指:mysql的安装路径(有可能是 usr/lib64/mysql)
3.2基本概念
3.2.1数据库
目录
information_schema:视图(描述mysql 下的库和文件)
mysql:mysql的核心数据库,存放mysql服务的核心数据
proformance_schema:对性能提升的操作的表
3.2.2表
文件
表:文件(.frm)
3.2.3数据
数据:表中的记录
4.SQL
4.1基本概念
Structured Query Language(结构化查询语言)
SQL:定义了所有操作关系型数据库的规则。
4.2SQL 语法规则
SQL语句可以单行/多行书写,以分号结尾。
用空格和缩进增强语句可读性。
MySQL数据库的SQL语句不区分大小写,关键字建议使用大写。
注释
- 单行注释:
1
2
3-- 两个横杠一个空格后面加注释。
# 号后直接写注释(MySQL特有的)。- 多行注释
1
2
3
4/*
这是
注释
*/
4.3SQL分类
分类 | 备注 |
---|---|
DDL Data Definition Language,数据定义语言 | 操作数据库和表 |
DML Data Manipulation Language,数据操纵语言 | 增删改表中的数据 |
DQL Data Query Language,数据查询语言 | 查询表中的数据 |
DCL Data Controlling Language,数据控制语言 | 定义数据库访问权限和安全级别 |
5.DDL
5.1操作数据库:CRUD
5.1.1Create:创建
- 创建数据库 db1
1 |
|
- 若数据库 db1 不存在,则创建db1
1 |
|
- 创建数据库 db1 时,指定字符集为 utf-8
1 |
|
- 创建数据库 db1 时,检查是否存在,若不存在指定其字符集为 utf-8
1 |
|
5.1.2Retrieve:查询
- 查询所有数据库的名称
1 |
|
- 查询数据库 db1 的字符集
1 |
|
5.1.3Updata:修改
- 修改数据库的字符集
1 |
|
5.1.4Delete:删除
- 删除数据库
1 |
|
- 删除之前判断是否存在
1 |
|
5.1.5使用数据库
1.进入数据库(使用数据库)
1 |
|
- 查询正在使用的数据库
1 |
|
5.2操作表:CRUD
5.2.1Create:创建
- 创建表
5.2.2Retrieve:查询
查询数据库中所有表的名称
查询表结构
5.2.3Updata:修改
5.2.4Delete:删除
docker 运行 mysql
X.1 主要流程
pull image
最新版
1 |
|
- 设置配置文件
1 |
|
在my.cnf
中添加参数
1 |
|
- 启动 mysql
1 |
|
- 进入容器,使用 mysql
1 |
|
X.2 遇到的问题
/data/mysql/config/my.cnf
配置错了一个参数,导致 docker run 之后,容器退出。
导致无法进入容器,报 container is not running
1 |
|
- 现象
docker ps
看不到应用,docker ps -a
可以看到应用,但是显示 states 为 exited。
1 |
|
- 解决:查看 docker log
1 |
|
1 |
|
删除错误的配置,docker run
就可以。
X.3 数据库连接排查步骤
1.确认服务运行状态
确认容器是否正确启动并运行 MySQL,确保容器的端口正确映射到宿主机:
1
docker ps
你应该看到类似以下的输出:
1
2CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
578dd9b4f9a6 mysql:latest "docker-entrypoint.s…" 2 hours ago Up 2 hours 0.0.0.0:3306->3306/tcp mysql-container
2.检查网络联通性
在远程机器上尝试连接 MySQL。
1 |
|
3.检查端口监听
确保宿主机的 3306 端口正在监听。
1 |
|
正在监听。
1
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN
4.检查 MySQL 配置
检查 MySQL 配置文件(例如 /etc/mysql/my.cnf
或 /etc/my.cnf
):
1 |
|
如果
bind-address
设置为127.0.0.1
,说明 MySQL 仅允许本地连接,远程连接被禁止。修改配置允许远程访问: 将bind-address = 127.0.0.1
改为bind-address = 0.0.0.0
,然后重启 MySQL。如果在 MySQL 配置文件
/etc/my.cnf
中没有显式地配置bind-address
,默认情况下,MySQL 通常会绑定到0.0.0.0
(即允许来自任何 IP 的连接)在 MySQL 中运行以下 SQL 查询来查看 MySQL 实际上绑定的 IP 地址:
1
SHOW VARIABLES LIKE 'bind_address';
1
2
3
4
5
6+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| bind_address | * |
+---------------+-------+
1 row in set (0.01 sec)
5.检查端口映射
检查 Docker 在 bridge
模式下端口映射规则,以下命令检查 NAT 表规则:
1 |
|
DOCKER
链是否包含以下规则:1
2DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:3306 to:172.17.0.2:3306
MASQUERADE tcp -- 172.17.0.2 172.17.0.2 tcp dpt:3306
6.检查宿主机防火墙配置
确保宿主机的防火墙允许外部流量访问 3306 端口:
1
sudo iptables -L -n -v
如果
FORWARD
链的默认策略是DROP
,执行以下命令允许流量通过:1
sudo iptables -P FORWARD ACCEPT
7.检查 MySQL 配置
检查 MySQL 配置文件(例如 /etc/mysql/my.cnf
或 /etc/my.cnf
):
1 |
|
如果
bind-address
设置为127.0.0.1
,说明 MySQL 仅允许本地连接,远程连接被禁止。修改配置允许远程访问: 将bind-address = 127.0.0.1
改为bind-address = 0.0.0.0
,然后重启 MySQL。如果在 MySQL 配置文件
/etc/my.cnf
中没有显式地配置bind-address
,默认情况下,MySQL 通常会绑定到0.0.0.0
(即允许来自任何 IP 的连接)在 MySQL 中运行以下 SQL 查询来查看 MySQL 实际上绑定的 IP 地址:
1
SHOW VARIABLES LIKE 'bind_address';
1
2
3
4
5
6+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| bind_address | * |
+---------------+-------+
1 row in set (0.01 sec)
8.检查用户权限
查看用户的主机(host)字段
1 |
|
1 |
|
主机(host)字段的含义:
localhost
: 仅允许本地连接。%
: 允许从任意远程主机连接。- 具体 IP 或域名:仅允许从指定主机连接。
检查 root 的主机字段
- 确保存在
root@'%'
,如果没有,则添加:
1
2
3CREATE USER 'root'@'%' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;- 确保存在
允许远程的常见情况:
如果存在类似
root@'%'
的记录,说明允许远程使用root
登录。如果插件为
auth_socket
,表示使用了 Unix socket 认证,而非密码认证。- 修改为
mysql_native_password
或caching_sha2_password
:
1
2ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password';
FLUSH PRIVILEGES;- 修改为
如果
plugin
是mysql_native_password
或caching_sha2_password
,说明允许使用密码认证。
9.检查最大连接数
查询 MySQL 配置的最大连接数。
1 |
|
查询 MySQL 当前线程的相关状态信息。
1 |
|
Threads_connected
显示当前有 5 个连接。表示 MySQL 使用线程来处理客户端请求。过多的连接(Threads_connected
)或者过多的正在执行的线程(Threads_running
)可能导致系统资源耗尽,进而影响性能。Threads_running
显示当前有 2 个线程正在执行查询。如果Threads_running
很高,可能表明存在查询性能瓶颈,或者某些查询操作需要优化。Threads_created
显示自 MySQL 启动以来创建了 120 个线程。如果数量过多,可能意味着每次请求都需要创建新线程,增大了开销。你可以考虑调整thread_cache_size
来优化线程复用,避免频繁地创建和销毁线程。
10.检查抓包数据
检查流量是没有到主机,还是没有到 docker。
监听
ens33
网络接口上的3306
端口流量。1
sudo tcpdump -i ens33 port 3306
监听 Docker 网桥上的流量,确认是否有流量到达容器。
1
sudo tcpdump -i docker0 port 3306
11.终极手段
重启 Docker 服务
有时候,Docker 网络可能会遇到配置问题,重启 Docker 服务可以帮助重新加载网络配置:
1 |
|