0x05-MySQL
0x05-MySQL
【mysql部署】在ubuntu22.04上安装和配置mysql教程_ubuntu22.04安装mysql-CSDN博客
Ubuntu 上安装 MySQL
- 记得
sudo apt update sudo apt install mysql-serversudo mysql_secure_installation, 进入配置页
# 1.询问是否安装密码插件,我选择 No ==> 不选 No 的话密码最少要8位, 不好记
VALIDATE PASSWORD COMPONENT can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD component?
Press y|Y for Yes, any other key for No: n
# 2.为root用户设置密码,不一定提示这个,特别强调不一定提示这个,如果不提示等会再通过mysql无密码进入配置
Please set the password for root here.
New password:
Re-enter new password:
#2.1 解决方法详见下一小节,解决bug
... Failed! Error: SET PASSWORD has no significance for user 'root'@'localhost' as the authentication method used doesn't store authentication data in the MySQL server. Please consider using ALTER USER instead if you want to change authentication parameters.
# 2.2 解决bug后,重新设置密码
New password:
Re-enter new password:
#3.删除匿名用户,我选No
By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.
Remove anonymous users? (Press y|Y for Yes, any other key for No) : n
... skipping.
#4.禁止root管理员从远程登录,这里我选 No
Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.
Disallow root login remotely? (Press y|Y for Yes, any other key for No) : n
... skipping.
#5.删除test数据库并取消对它的访问权限, 我选 No
By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.
Remove test database and access to it? (Press y|Y for Yes, any other key for No) : n
... skipping.
#6.刷新授权表,让初始化后的设定立即生效, 选 Yes
Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.
Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y
Success.
All done!
解决配置MySQL中的bug(在上述操作中如果有问题,比如报错Failed! Error: SET PASSWORD has no significance for user ‘root’@‘localhost’ as the authentication me)
或者不提示输入root密码,则无密码登录msyql,使用命令:
sudo mysql
进入控制台后,修改密码 ,注意改成自己的密码
# 修改 root密码:ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password';
#比如把密码设置为123456
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';
然后输入 exit 退出

退出后再使用
mysql -uroot -p
根据提示输入刚才配置的密码。
远程连接
修改 mysqld.cnf
sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
找到:
bind-address = 127.0.0.1
把它注释掉 → 改为:
# bind-address = 127.0.0.1
保存并退出(:wq)。
重启 MySQL 使配置生效
sudo systemctl restart mysql
检查 MySQL 是否监听所有 IP
运行:sudo netstat -tulnp | grep mysql
如果看到 0.0.0.0:3306 或 :::3306,说明 MySQL 已经允许远程连接:
tcp6 0 0 :::3306 :::* LISTEN 12345/mysqld
如果 ubuntu 没有装netstat, 可以用ss`, 更高级
ss(Socket Statistics)是 `netstat 的现代替代工具,性能更好,默认安装在 Ubuntu 22.04 上:
sudo ss -tulnp | grep mysql
输出示例:
tcp LISTEN 0 151 0.0.0.0:3306 0.0.0.0:* users:(("mysqld",pid=1234,fd=21))
配置 MySQL 用户权限(关键!)
默认情况下,MySQL 的 root 用户可能只允许本地登录。你需要 授权远程访问:
方法 1:允许 root 远程登录(不推荐,安全性较低)
-- 登录 MySQL
sudo mysql -u root -p
-- 授权 root 用户从任意 IP 访问(替换 '你的密码')
CREATE USER 'root'@'%' IDENTIFIED BY '你的密码';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
方法 2:创建专用用户(推荐)
'%': 允许从任意 IP 访问
'localhost': 只能从本地访问
'xxx.xxx.xxx.xxx': 只允许从特定 IP 访问
-- 创建新用户(例如 'remote_user')并允许从任意 IP 访问
CREATE USER 'remote_user'@'%' IDENTIFIED BY '强密码'; // 创建专属用户
GRANT ALL PRIVILEGES ON *.* TO 'remote_user'@'%'; // 授予新用户高权限
FLUSH PRIVILEGES; // 刷新一下
开放防火墙(如果使用 ufw)
sudo ufw allow 3306/tcp
sudo ufw reload
测试远程连接
从另一台机器尝试连接:
mysql -h <你的服务器IP> -u remote_user -p
如果成功,说明配置正确。
或者直接使用你的数据库客户端工具

开发 --- 知识点记录
文本数据
先装这个包: 得以使用 mysql.h头文件
**<font style="color:#DF2A3F;">apt install libmysqlclient-dev</font>**

编译:
gcc conn.c -o conn -I /usr/include/mysql/ -lmysqlclient
存储过程
一次性执行多条语句, 相当于定义了一个函数, 并且create后会被存储到该数据库内


图片数据INSERT
write_image --> mysql_write
fopen中mode参数 + 作用
遇到图片数据读/写, 可使用二进制模式:
- eg:
rb,wb,wb+…
| 模式 | 原始能力 | **增加 ****+**后的能力 | 文件存在时的处理 | 文件位置 | 典型用途 |
|---|---|---|---|---|---|
r | 只读 | 读写 r+ | 必须存在,不修改内容 | 文件开头 | 修改现有文件 |
w | 只写 | 读写 w+ | 截断为0字节 | 文件开头 | 创建/覆盖文件 |
a | 只追加 | 读写 a+ | 保留内容 | 文件末尾(写) 任意位置(读) | 日志文件 |
正常情形下: 文件数据流向图
Node Server1和Node Server2也可能是同一个服务器

什么是预处理语句(Prepared Statement)
预处理语句是 MySQL 提供的一种高效、安全的 SQL 执行方式,具有以下特点:
- **SQL与数据分离:**SQL模板与参数值分开处理
- **预编译:**SQL语句先被数据库解析和编译
- **参数绑定:**通过占位符(
?)动态绑定参数 - **高效复用:**同一语句可多次执行,只需改变参数值
stmt 的具体作用
在您的代码中,stmt 作为预处理语句句柄,承担了以下职责:
- “先把SQL模板发给服务器检查”
mysql_stmt_prepare(stmt, "INSERT INTO images_t VALUES(?)", ...);
这里的 ? 是参数占位符
- 把这条 SQL 发给 MySQL 服务器做语法/语义检查,生成内部执行计划
- 创建参数, 绑定占位符
?:
MYSQL_BIND param = {0};
param.buffer_type = MYSQL_TYPE_LONG_BLOB;
param.buffer = NULL; // 下面用 send_long_data 逐块送
param.is_null = 0; // 不是 NULL
param.length = NULL; // 也交给 send_long_data 动态决定
mysql_stmt_bind_param(stmt, ¶m);
- 把上面的
param和 SQL 里的第 1 个?绑定在一起。
- 现在服务器知道了:
“一会儿客户端会送一个 LONG_BLOB 过来,但具体字节流请他自己用 send_long_data 发”
- 真正地把二进制数据流进服务器
mysql_stmt_send_long_data(stmt, 0, buffer, length);
“分块上传”接口。
- 第 2 个参数
0:表示给第 0 号参数(也就是 SQL 里的第 1 个?) buffer / length:这次要发的内存块- 可以多次调用,把大文件切成小包慢慢传;这里一次就发完
- 执行SQL操作:
mysql_stmt_execute(stmt);
服务器收到 send_long_data 传完的所有数据后,执行 INSERT,把行写进表
为什么使用 stmt 而不是直接执行SQL
| 直接执行SQL | 使用预处理语句stmt |
|---|---|
mysql_query(handle, "INSERT...") | mysql_stmt_prepare()准备语句+ mysql_stmt_execute()执行语句 |
| 每次都要解析SQL | SQL只需解析一次 |
| 容易SQL注入 | 天然防注入 |
| 处理二进制数据麻烦 | 完美支持BLOB |
| 性能较低 | 高性能,特别适合重复操作 |
图片数据SELECT
mysql_read --> read_image