🗄️ 第01章 · 安装与基础

apt 安装/服务/客户端

安装与基础

在 Ubuntu 上把 MySQL 8 装起来、让服务随系统启动、再用客户端连进去——这是所有数据库运维的第一块基石。本章以当前这台 Ubuntu 24.04 服务器为背景,讲清楚安装、服务管理与客户端连接这一整套入门动作。

MySQL 是什么

MySQL 是一个开源的关系型数据库管理系统(RDBMS),底层默认使用 InnoDB 存储引擎,支持事务、行级锁和外键约束。它和 MariaDB 同源(MariaDB 是 MySQL 的一个分支),两者命令大体兼容,但 MySQL 8 引入了不少 MariaDB 没有的特性,比如 caching_sha2_password 认证插件、JSON 类型、公共表表达式(CTE)、窗口函数等。

MySQL 8 有一个明显的变化:默认认证插件从 MySQL 5.7 的 mysql_native_password 改成了 caching_sha2_password,这一点直接决定了你从命令行或应用里连接它时要用哪个密码加密方式。

安装 MySQL

Ubuntu 24.04 官方仓库里自带 MySQL 8.0,直接 apt 安装即可。注意安装过程本身会顺手创建 MySQL 系统用户和默认的 root 账户。

# 更新软件包索引,安装 mysql-server(服务端)和 mysql-client(客户端)
sudo apt update
sudo apt install -y mysql-server mysql-client

# 查看安装到的版本
mysql --version
# 输出示例: mysql  Ver 8.0.46-0ubuntu0.24.04.4 for Linux on x86_64 ((Ubuntu))

安装完成后,MySQL 会被 systemd 管理。它默认监听本机回环地址 127.0.0.1:3306,以及 MySQL X Protocol 端口 33060(这是给 mysqlx 这类 X DevAPI 用的,普通 SQL 访问用不到)。

# 确认 MySQL 已经随系统启动
systemctl status mysql --no-pager

# 如果需要手动控制(一般装好后自动运行,无需手动)
sudo systemctl start mysql      # 启动
sudo systemctl stop mysql       # 停止
sudo systemctl restart mysql    # 重启
sudo systemctl enable mysql     # 设为开机自启(默认已启用)

客户端连接方式

连接 MySQL 有两种方式:通过本地 socket 文件(只在同一台机器上生效,不走 TCP)或 TCP 端口(跨机器或经过网络)。在本机用 mysql 不带 -h 时,默认走 socket 文件(通常是 /var/run/mysqld/mysqld.sock)。

# 1) 以 root 身份在本机连接(Ubuntu 上 root@localhost 默认走 auth_socket 认证,
#    即“只要你是系统 root 就放行”,无需密码)
sudo mysql

# 2) 指定用户名和密码连接(也走 socket)
mysql -u bangdream -p

# 3) 通过 TCP 连接(显式指定主机和端口,务必用 127.0.0.1,不要用 localhost 走 socket)
mysql -h 127.0.0.1 -P 3306 -u lovelive -p

安全提示:localhost 在 MySQL 客户端里特指 socket 文件连接;127.0.0.1 才走 TCP。如果想确认到底连的是哪个端口,执行 SELECT @@port;。root@localhost 走 auth_socket,这对本地管理是安全的——只有系统 root 用户才能免密登录,其它任何用户都无法冒用。

密码不用每次手敲,可以写进一个只有 root 可读的配置文件,用 --defaults-extra-file 在连接时注入,这样密码不会出现在命令行历史里。

# 把密码写进只有 root 能读的文件
cat > /root/.deploy/db_passwords <<'EOF'
bangdream_password=GrxzyyrRQjOv0P2P0nXG
lovelive_password=dPhnCijr3DvtCjopDsRz
EOF
chmod 600 /root/.deploy/db_passwords

# 连接时用 --defaults-extra-file 注入客户端配置,避免密码写进 shell 历史
mysql --defaults-extra-file=<(printf '[client]\npassword=%s\n' \
  "$(grep bangdream_password /root/.deploy/db_passwords | cut -d= -f2)") \
  -u bangdream bangdream

连接成功后,先看版本和工作参数,确认环境正常:

-- 查看服务器版本、是否使用严格模式、字符集、数据目录、InnoDB 缓冲池大小
SELECT version()                 AS 版本,
       @@sql_mode                AS SQL严格模式,
       @@character_set_server    AS 服务器字符集,
       @@datadir                 AS 数据目录,
       @@port                    AS 端口;
-- 结果示例: 8.0.46 | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,... | utf8mb4 | /var/lib/mysql/ | 3306

配置文件在哪

MySQL 8 的配置是“分片段加载”的,主文件 /etc/mysql/mysql.conf.d/mysqld.cnf,它通过 !includedir 引入目录下的所有片段。改配置最稳妥的做法是新建一个片段文件,而不是直接改主文件,避免升级时被覆盖。

# 查看当前生效的配置项
sudo mysqld --print-defaults

# 新建自定义配置片段(以 # 开头注释的配置会被识别为扩展名,只需放在目录内)
sudo tee /etc/mysql/mysql.conf.d/zz-local.cnf <<'EOF'
[mysqld]
bind-address = 127.0.0.1
max_connections = 200
EOF
# 改完必须重启服务才会生效
sudo systemctl restart mysql

易错点:改了 [mysqld] 段的配置后忘记重启,或把写错变量的配置放进去导致服务起不来。每次大改建议先用 sudo mysqld --validate-config 校验一遍,再重启,最后用 SELECT @@max_connections; 确认生效。

案例场景:在本机连接真实业务库

这台服务器上跑着两个业务库 bangdream 和 lovelive,应用通过各自的账号连接。运维日常就是确认它们能连、状态正常:

# 列出所有数据库
mysql -e "SHOW DATABASES;"
# 结果会包含: bangdream information_schema lovelive mysql performance_schema sys

# 查看业务库的表
mysql -e "USE bangdream; SHOW TABLES;"
# 结果示例: bands characters stories story_name_map

常用命令速查

命令 作用 示例
systemctl status mysql 查看 MySQL 服务运行状态 systemctl status mysql
systemctl restart mysql 重启 MySQL 服务 systemctl restart mysql
mysql --version 查看客户端版本 mysql --version
sudo mysql 以 root 免密登录 sudo mysql
mysql -h 127.0.0.1 -P 3306 -u 用户 -p 通过 TCP 连接 mysql -h 127.0.0.1 -u lovelive -p
SHOW DATABASES; 列出所有数据库 SHOW DATABASES;

连接报错的快速排查

连不上 MySQL 时,按这个顺序把它救回来:

# 1) 服务到底活着没有?(没起来先看 systemctl status 的报错日志)
sudo systemctl status mysql --no-pager

# 2) 端口在听吗?(没有 3306 说明 mysqld 没起来或被禁了)
sudo ss -ltnp | grep 3306

# 3) 是不是权限问题(Access denied)——账号存在吗?主机对吗?
sudo mysql -e "SELECT user,host,plugin FROM mysql.user;"

# 4) socket 文件在吗?(本机连接失败多因 socket 路径不对)
ls -l /var/run/mysqld/mysqld.sock

# 5) 看错误日志兜底
sudo tail -n 50 /var/log/mysql/error.log

易错点:bind-address = 127.0.0.1 时,MySQL 只在本机监听,任何远程连接都会直接被拒绝,这常常被误认为是“密码不对”。先确认 SHOW VARIABLES LIKE 'bind_address'; 是不是回环地址,以及防火墙有没有放行。

服务端口一览

MySQL 运行时开放两类端口,别把它们弄混:

端口 协议 用途
3306 TCP 常规 SQL 连接(mysql 客户端、JDBC、PDO 等都走它)
33060 TCP MySQL X Protocol(mysqlx、支持 X DevAPI 的驱动)

用 ss 确认监听状态是运维基本功:

sudo ss -ltnp | grep -E '3306|33060'
# 示例: LISTEN 127.0.0.1:3306  ... (mysqld)
#       LISTEN 127.0.0.1:33060 ... (mysqld)

延伸阅读

  • 数据文件默认在 /var/lib/mysql/,日志在 /var/log/mysql/,日常排查从这里入手。
  • 需要远程访问时改 bind-address,但务必配合防火墙和强密码,裸奔在公网是重大安全隐患。
  • 生产环境建议用专门的运维账号而非 root,最小权限原则贯穿本书后续章节。