玩Linux的老哥都知道,Ubuntu 22.04 LTS上安装MySQL,说难不难,但每次都能看到有人被同一个坑卡住。上个月我帮同事在一台全新的Ubuntu 22.04服务器上装MySQL 8.0,他照着网上老教程一步步走,结果卡在ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock'这个问题上,折腾了一下午。其实从22.04开始,apt自带的mysql-server已经是8.0.x版本,无论是认证插件、socket路径还是配置目录结构,都和CentOS或者Ubuntu 16.04时期有很大区别。这篇文章就围绕Ubuntu 22.04上完整的MySQL安装与配置过程来写,从最基础的软件源检查,到远程访问、SSL错误排查、常见调优项以及备份恢复,全部基于我实际操作的流程,适合刚接触Ubuntu或者正打算部署MySQL 8.0的同学直接参考。
1. 安装前的环境准备:理解Ubuntu 22.04的包管理差异与系统状态检查
1.1 为什么我推荐直接用apt而不是官网二进制包
先说结论:在Ubuntu 22.04 LTS上,直接使用官方apt源安装mysql-server是最省事的方案。你不需要去官网下载二进制包,也不需要自己写systemd服务文件,apt会自动处理依赖、初始化数据目录、注册开机自启。很多教程现在还习惯让人去下载MySQL官网的包,其实那是给特殊场景准备的,比如需要特定版本、自定义安装路径或者离线安装。如果你只是正常部署一个业务数据库,apt版本和系统本身的库文件匹配度更高,后面升级维护也简单。
MySQL 8.0的官网二进制包通用性很强,但依赖库版本、glibc版本稍有差异就可能和Ubuntu 22.04打架。我记得有朋友图省事直接从官网下载了Linux Generic的压缩包,解压后折腾了半天还是起不来,日志里报缺少libaio或libtinfo的库文件。虽然可以用apt install libaio1t64之类的方式补上,但这不是常规操作,也没有必要。apt源里的mysql-server在22.04上默认是8.0.3x版本,业务开发完全够用,官方也确实把它作为主要维护分支。
1.2 系统状态检查与软件源更新
在动手安装之前,先把系统基础情况摸一遍。不要上来就apt install,不然你可能被一些历史残留问题绕进去。用这几条命令确认环境:
lsb_release -a uname -m sudo apt updatelsb_release -a确认当前确实是Ubuntu 22.04 LTS,uname -m确认架构是x86_64还是其他。sudo apt update会把软件源索引刷新一遍,第一次执行可能会比较慢,尤其在国内服务器上,如果apt源没调优,可以顺手把源换成阿里云镜像,但注意换源和安装MySQL不是强关联,只要update能正常完成就行。
接着检查3306端口是否被占用,以及系统是否装了别的数据库相关包:
ss -lntp | grep 3306 dpkg -l | grep -E "mysql|mariadb"如果你的机器上之前装过MariaDB,或者系统镜像自带了一个占3306端口的实例,apt安装MySQL时可能会因为端口冲突或者包冲突失败。遇到这种情况,先确认旧数据是否还需要,需要就备份迁移,不需要就停掉服务并卸载相关包,保持一个干净的数据库环境。
1.3 看清Ubuntu 22.04上MySQL 8.0的几个默认行为
Ubuntu 22.04仓库里的MySQL 8.0有几个默认行为和CentOS/RHEL体系不一样,很多老手也是在这里栽跟头。
第一个是root账号的认证方式。Ubuntu的mysql-server安装完成后,root默认使用auth_socket插件认证,而不是通常理解的密码认证。什么叫auth_socket?它做的是系统级校验:只要你是操作系统的root用户,或者通过sudo以root身份执行的命令,就可以直接登录MySQL,不需要输入MySQL密码。反过来,你用密码登录反而会失败。这是Ubuntu的默认安全设计,很多人刚装完发现mysql -u root -p死活连不上,却不知道应该先sudo mysql -u root进去。
第二个是socket路径。Ubuntu打包的MySQL,服务端默认socket是/var/run/mysqld/mysqld.sock,但客户端默认可能去找/tmp/mysql.sock。这个差异会在后续复现最经典的报错:Can't connect to local MySQL server through socket '/tmp/mysql.sock'。
第三个是默认监听地址。MySQL 8.0装完后默认bind-address = 127.0.0.1,也就是只允许本机访问,不接受任何远程连接。所以远程工具连不上不一定是你密码错了,可能是监听本身就不在外部网卡上。
这些默认行为不是毛病,而是系统的安全取舍。理解它们之后,后续的配置调整就有方向了。
2. apt安装MySQL 8.0:从更新索引到服务自启动
2.1 安装命令与安装过程说明
在系统环境确认没问题之后,直接执行:
sudo apt install mysql-server -y-y参数跳过交互确认,这个包会带上mysql-client、mysql-server以及一些依赖组件,安装体积不算小,根据网速等一两分钟很正常。装完之后,安装脚本会自动完成数据目录初始化,并把服务启动起来,这也是我用apt方案的一个重要原因,它把mysqld --initialize这些步骤都封装好了。
装完后看下版本:
mysql --version正常情况下你会看到类似mysql Ver 8.0.39-0ubuntu0.22.04.1 for Linux on x86_64的输出。注意官方在8.0中继续维护版本号8.0.x,不会有5.x的新版本,不要再惦记老版本了。
2.2 首次登录:理解auth_socket
安装完成后,用这条命令进入MySQL:
sudo mysql -u root因为root默认用的是auth_socket,所以直接用系统root身份连接,不需要密码。进去后再验证一下基本信息:
SELECT VERSION(); SELECT user, host, plugin FROM mysql.user;从mysql.user表能看到root对应的plugin是auth_socket,host是localhost。这也就解释了为什么此时你无法通过密码远程登录,因为根本没有密码认证。这个阶段不需要急着改root为密码认证,先让服务跑起来,接着做安全初始化。
2.3 服务状态管理
apt安装后服务一般已经启动了,但还是建议手动确认一下:
systemctl status mysql --no-pager sudo systemctl enable mysqlsystemctl enable mysql的作用是确保开机自启。在Ubuntu 22.04上,默认服务名是mysql而不是mysqld,这也是和RHEL系一个区别。注意不要习惯性地敲systemctl status mysqld,那在Ubuntu上会提示服务不存在。
如果想确认监听端口,可以执行:
ss -lntp | grep 3306你会看到mysqld进程绑定在127.0.0.1:3306上,这说明服务已经在运行,但只能本机访问。下一步的安全初始化和远程访问配置,就是围绕这个基础展开的。
3. 安全初始化与root认证方式调整
3.1 执行mysql_secure_installation交互详解
很多教程会建议装完MySQL后直接改配置、建远程用户,但我习惯先跑一遍安全初始化脚本,把默认的匿名用户、测试库清理掉:
sudo mysql_secure_installation这个脚本会有一系列交互提问,逐条说:
第一问一般涉及密码强度校验插件,也就是validate_password。如果你打算用强密码,直接选Y,它会要求密码长度至少8位,并且包含大小写字母、数字和特殊字符。如果你只是本机开发不想受约束,可以选择N跳过密码策略。但要注意,选择N之后脚本可能还会让你确认是否继续设置root密码,这时你自己要有起码的密码强度意识,别用纯数字“123456”这种。
第二问是设置root密码。因为当前root还是auth_socket认证,所以这里的逻辑是先切换到密码认证,然后让你设置新密码。如果选Yes,root会切换成密码认证,之后远程可以尝试连接;如果选No,root继续保持auth_socket,只能用sudo连接。我的建议是:如果这台机器需要远程管理数据库,这里选Yes并设一个复杂密码;如果只是本机跑服务,那保持auth_socket反而更安全,也不需要担心SSH爆破MySQL账号。
后续几个问题分别是:
Remove anonymous users?选Yes,删除匿名用户,否则本地任何人都能直接连接。Disallow root login remotely?建议选Yes,root只允许本机登录,远程访问用专门创建的业务账号。Remove test database and access to it?选Yes,删掉默认的测试库。Reload privilege tables now?选Yes,刷新权限表。
这套做完,实例的基础安全水平已经比默认状态高很多了。注意,如果你在第一步拒绝设置root密码并保留auth_socket,脚本后面的几个清理问题依然会问,不影响。
3.2 root切换为密码认证与认证插件选择
如果你选择保留auth_socket,后面又想用Navicat或DataGrip远程管理,就必须给root设置一个密码认证。操作很简单,在sudo mysql -u root状态下执行:
ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'YourStrongPass!2024'; FLUSH PRIVILEGES;这里有一个关键选择:caching_sha2_password还是mysql_native_password。MySQL 8.0的默认认证插件是caching_sha2_password,这是官方推荐的安全选项。但它有一个常见兼容问题,很多老版本的客户端、图形化工具如果太旧,会直接报Authentication plugin 'caching_sha2_password' cannot be loaded,或者连接时卡在公钥获取上。
如果你的客户端工具比较旧,或者你的开发框架内置的MySQL驱动版本太低,暂时改回mysql_native_password是最快的解决办法:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'YourStrongPass!2024'; FLUSH PRIVILEGES;但要明白,mysql_native_password在MySQL文档里已经被标记为废弃,未来版本可能移除。这只是兼容旧客户端的过渡方案,有条件还是尽量用caching_sha2_password并升级客户端驱动。
3.3 排查ERROR 2002 socket错误的完整链路
这条报错在Ubuntu 22.04上极其常见,而且搜索量一直很大。复现一下:执行mysql -u root -p并输入密码后,得到:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)很多人第一反应是MySQL服务没装好或者没启动,于是反复重装。实际上这很可能只是一个socket路径不一致的问题。
排查链路是这样走的:
第一步,确认服务是否在运行:
systemctl status mysql --no-pager如果服务是active (running),说明数据库进程没问题。此时错误大概率是客户端读取的socket路径和服务端不一致。Ubuntu默认服务端socket在/var/run/mysqld/mysqld.sock,而客户端默认可能找/tmp/mysql.sock。
第二步,用一个显式socket参数连接:
mysql --socket=/var/run/mysqld/mysqld.sock -u root -p如果这样能连上,那基本就是路径问题。解决方式有两种:一是建立一个符号链接,让客户端找得到:
sudo ln -s /var/run/mysqld/mysqld.sock /tmp/mysql.sock二是直接修改服务端配置中的socket路径,让它创建在客户端默认路径:
# /etc/mysql/mysql.conf.d/mysqld.cnf [mysqld] socket = /tmp/mysql.sock改完记得重启:sudo systemctl restart mysql。
如果服务确实没运行,那要去看日志:
sudo tail -50 /var/log/mysql/error.log最常看到的是数据目录权限问题,比如/var/lib/mysql的属主不是mysql:mysql,这通常是因为手动强行复制过数据或者变更过目录。修复方式:
sudo chown -R mysql:mysql /var/lib/mysql sudo systemctl restart mysql这条排查链路走一遍,大部分socket报错都能解决。不要一上来就重装,重装并不会修复socket路径不一致的问题。
4. 远程访问配置与SSL连接问题实测
4.1 修改监听地址与防火墙放行
当你需要从本地电脑或者另一台服务器连接数据库时,第一步是让MySQL监听所有网卡。修改/etc/mysql/mysql.conf.d/mysqld.cnf:
[mysqld] bind-address = 0.0.0.0或者直接注释掉bind-address这一行,默认效果同样是监听所有地址。然后重启:
sudo systemctl restart mysql重启后验证监听情况:
ss -lntp | grep 3306如果你看到*:3306,说明已经在所有接口上监听了。接下来,如果开了ufw防火墙,要放行3306端口:
sudo ufw allow 3306/tcp这一步很容易被忽略。很多人在云服务器上明明记得开放了安全组规则,本地还是连不上,因为Ubuntu自身的ufw还在拦截。另外,如果你用的是云厂商的VPS,安全组控制台里也要放行对应端口,双重确认。
4.2 创建远程用户并授予最小权限
我不建议远程直接用root连接,更规范的做法是创建独立业务账号,并按需授权。比如我有一个库叫appdb,想给网段192.168.1.0/24的机器开放读写权限:
CREATE USER 'app'@'192.168.1.%' IDENTIFIED WITH caching_sha2_password BY 'AppPassw0rd!'; GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.* TO 'app'@'192.168.1.%'; FLUSH PRIVILEGES;这里有几个关键点:
192.168.1.%表示只允许这个网段连接,比'app'@'%'安全得多。哪怕密码泄漏,攻击者也只能从这个网段进来。- 授权不要直接
GRANT ALL ON *.*,按需给SELECT, INSERT, UPDATE, DELETE就好。如果业务需要DDL权限,可以再单独加。 FLUSH PRIVILEGES是强制刷新权限表,避免出现权限已授权但连接时还没生效的情况。
如果你确实要允许所有IP连接,可以改为'app'@'%',但要综合考虑安全性。生产环境不建议这样。
4.3 MySQL 8.0 SSL连接错误的根因与处理
很多人在远程连接时遇到SSL相关报错,比如:
- 命令行客户端报
ERROR 2026 (HY000): SSL connection error: SSL_CTX_set_tmp_dh failed - Navicat连接时报
RSA Encryption not supported或者直接提示SSL错误
这个问题的核心原因是:MySQL 8.0默认启用了TLS加密连接,同时默认认证插件caching_sha2_password在远程连接时会向客户端索取公钥或进行SSL握手。如果你的客户端旧,或者服务器的SSL证书配置不完整,握手就会失败。
解决思路分两条路。如果你只在内网使用,对传输加密要求不高,最简单的方法是在客户端侧禁用SSL。命令行加--ssl-mode=DISABLED:
mysql -h 192.168.1.10 -P 3306 -u app -p --ssl-mode=DISABLEDNavicat的话,在连接属性里找到SSL标签,把“使用SSL”设置为不使用即可。这能绕过大部分SSL握手问题。
如果还是报错Authentication plugin 'caching_sha2_password' cannot be loaded,那除了关SSL,还要考虑认证插件兼容性,给这个远程用户换成mysql_native_password:
ALTER USER 'app'@'192.168.1.%' IDENTIFIED WITH mysql_native_password BY 'AppPassw0rd!'; FLUSH PRIVILEGES;但这里要提醒一句:生产环境建议保留SSL,不要图省事全关。如果你能配置正式的CA证书,并且把客户端驱动升级到支持8.0的版本,SSL连接是稳妥的。测试环境图省事可以关,生产环境还是把钱花在证书和驱动升级上。
验证MySQL当前SSL是否开启,可以执行:
SHOW VARIABLES LIKE '%ssl%';have_ssl显示YES表示支持,显示DISABLED表示被禁用了。如果确认要全局关闭SSL,可以在mysqld.cnf里加入skip_ssl,然后重启。不过这种做法在8.0中有点激进,除非实在被旧客户端折腾得不行,否则我不建议一上来就动全局配置。
5. 常用配置调优与目录权限细节
5.1 理解Ubuntu的MySQL配置include体系
Ubuntu上MySQL的配置文件和CentOS不太一样,/etc/mysql/my.cnf并不是全部配置所在,它只是一个入口,会通过!includedir指令加载/etc/mysql/conf.d/和/etc/mysql/mysql.conf.d/两个目录下的配置文件。真正的服务端配置在/etc/mysql/mysql.conf.d/mysqld.cnf里。
这个结构意味着,不要随意在my.cnf里塞一堆配置,更规范的姿势是在mysql.conf.d/下新建一个zz-custom.cnf文件,或者直接改mysqld.cnf。我自己更倾向于新建一个独立配置文件,比如/etc/mysql/mysql.conf.d/custom.cnf,好处是将来升级MySQL时不会和默认配置冲突,排错时一眼就能看到自定义项。
下面是一份我常用的基础调优配置:
[mysqld] max_connections = 300 innodb_buffer_pool_size = 1G character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci default-storage-engine = InnoDB slow_query_log = ON long_query_time = 2这里innodb_buffer_pool_size是最关键的参数,它决定了InnoDB引擎在内存中缓存数据页的大小。经验值是物理内存的50%到70%,不要盲目填1G。如果机器内存只有2G,你给1G反而会触发swap,性能更差。同时也要考虑这套MySQL上还跑不跑其他应用,比如Java服务或者Nginx,别把内存全给数据库。
max_connections和数据库连接池的配合也经常被问到。连接池最大连接数加上其他跳板连接,总和不要超过这个值,否则会报Too many connections。如果你有应用端连接池,设置成100或200就差不多了,MySQL开300通常不会成为瓶颈。但如果你直接设成2000,MySQL会为每个连接分配线程栈资源,内存和CPU都受不了。更合理的方式是:控制好连接池数量,MySQL侧设置略高于你的预估峰值即可。
排序规则我这里选了utf8mb4_unicode_ci,是因为它和MySQL 5.7时代的兼容性更好。8.0默认的utf8mb4_0900_ai_ci性能更好,但老项目迁移过来时,一些查询的排序结果可能和原来不一样,导致“数据看起来没变但排序变了”的诡异问题。新项目直接用默认也行,老项目建议沿用utf8mb4_unicode_ci。
5.2 表名大小写、sql_mode与“默认值为0”的隐性坑
Linux上MySQL的lower_case_table_names默认值是0,也就是表名和库名严格区分大小写。这意味着你在本地开发时如果用驼峰表名,比如UserInfo,上传到Linux服务器上执行select * from userinfo就会报Table doesn't exist。很多从Windows或Mac切到Linux的开发者都会在这里踩坑。
8.0版本安装完成后,lower_case_table_names不能随便改,因为它和数据字典的元数据一致性强绑定。强行改会在服务启动时报错或者数据字典不一致。所以最靠谱的做法是:从一开始就统一表名命名规范,全程使用小写字母加下划线,避免大小写依赖。
另一个坑是sql_mode。MySQL 8.0默认包含ONLY_FULL_GROUP_BY,很多老项目的分页查询或统计SQL依赖隐式分组,会报Expression #1 of SELECT list is not in GROUP BY clause。有人图省事,直接SET GLOBAL sql_mode='STRICT_TRANS_TABLES',把ONLY_FULL_GROUP_BY临时移除,但这是治标不治本。真正确切的做法是重写SQL,把非聚合字段都放进GROUP BY,或者用ANY_VALUE()解决特定字段的取值问题。
再就是“设置默认值为0”这个话题,这两个月搜索量很高。其实MySQL里给字段默认值0很简单:
ALTER TABLE `user` ALTER COLUMN `status` SET DEFAULT 0;新加字段也一样:
ALTER TABLE `user` ADD COLUMN `status` TINYINT NOT NULL DEFAULT 0;但有一个坑:在NO_ZERO_DATE模式下,你不能把日期字段默认值设为'0000-00-00',因为MySQL 8.0默认不允许零日期。如果你想表达“未设置”的时间,可以允许NULL,或者用'1970-01-01 00:00:00'作为可取默认值。另外,如果你要给日期字段设默认值,8.0里TIMESTAMP字段的默认值可以是CURRENT_TIMESTAMP,DATETIME字段同样支持,但要注意一张表只能有一个TIMESTAMP字段使用CURRENT_TIMESTAMP的默认值,这是老版本遗留的限制,8.0依然存在,策划表结构时要提前考虑。
5.3 AppArmor限制下的数据目录迁移
很多人在磁盘空间不足时想把MySQL数据目录挪到新挂载的数据盘上,然后直接改datadir,重启后却发现服务起不来。日志里往往有类似apparmor="DENIED"的字样。
Ubuntu 22.04默认启用了AppArmor对mysqld进程的限制,配置在/etc/apparmor.d/usr.sbin.mysqld里,默认只允许mysqld访问/var/lib/mysql/等特定路径。你把数据目录迁移到/mnt/data/mysql之后,即使权限都改对了,AppArmor仍然会拒绝访问。
有两种处理方式。
第一种是改AppArmor配置,在/etc/apparmor.d/usr.sbin.mysqld中把新目录加入白名单:
/mnt/data/mysql/ r, /mnt/data/mysql/** rwk,然后重新加载AppArmor规则:
sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld sudo systemctl restart mysql第二种更省事,在挂载数据盘时直接把新磁盘挂载到/var/lib/mysql上,比如在/etc/fstab中把数据盘挂载到这个目录,一次性避开AppArmor的路径限制。如果数据目录已经初始化好了,需要先停MySQL,把原数据复制到新盘,然后改挂载点或做软链接,软链接也要注意AppArmor同样限制符号链接的实际路径,所以不一定每次都能绕过。最干净的方法还是提前规划好数据盘挂载点,并在初始化MySQL之前完成。
6. 备份、恢复与单表同步的实用套路
6.1 生产级mysqldump备份命令
备份这件事,等数据库出问题再想起来就晚了。Ubuntu 22.04上天然会装好mysqldump,直接用即可。我常用的单库备份命令是这样:
sudo mysqldump -u root -p --single-transaction --routines --triggers --events appdb | gzip > appdb-$(date +%F).sql.gz几个参数的含义值得多说一句:
--single-transaction:对InnoDB表开启一个一致性快照,备份过程中不加锁,业务可以继续读写。如果某些表是MyISAM,这个参数无法保证一致性,备份期间可能会锁表。--routines:导出存储过程和函数。很多老系统迁移后存储过程全丢,就是因为备份时漏了这个参数。如果你不用存储过程,加不加都行,但只要库里可能存在,建议无条件加上。--triggers:导出触发器,同理。--events:导出事件调度器,定时任务也是容易被遗漏的一部分。
如果你要备份整个实例的所有库,可以改用--all-databases,但一般生产环境按库备份更灵活,恢复单个库时也不用从全量备份里挑库。
6.2 恢复数据时最容易忽略的排序规则问题
恢复数据库前,先确认目标库存在。如果不存在,先创建:
mysql -u root -p -e "CREATE DATABASE appdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"然后解压并导入:
gunzip -c appdb-2025-01-01.sql.gz | mysql -u root -p appdb恢复过程最常见的坑是从MySQL 8.0导出的dump导入到MySQL 5.7或MariaDB时,报错Unknown collation: utf8mb4_0900_ai_ci。原因是8.0默认排序规则是utf8mb4_0900_ai_ci,老版本根本不认识这个排序规则。解决办法有两种,一种是在dump文件里全局替换排序规则:
sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_unicode_ci/g' backup.sql另一种是导出时就直接指定兼容排序规则:
mysqldump -u root -p --single-transaction --routines --triggers --events \ --default-character-set=utf8mb4 --no-create-db appdb > backup.sql--no-create-db只会导出表结构和数据,不会附带老的排序规则声明,有时候能避开一部分兼容问题。但最稳妥的还是替换文本,因为表字段级别的排序规则也是写在DDL里的。
6.3 从一份远程库单表同步到本地:主从复制的落地步骤
经常有人问:“怎么把远程库的某一张表同步到本地?”最正统的答案是搭MySQL主从复制,然后在从库上通过复制过滤只接收指定表。我用一个实际场景说明:远程主库192.168.1.10上有一个orders表,需要实时同步到本地分析库。
先配置主库,修改/etc/mysql/mysql.conf.d/mysqld.cnf:
[mysqld] server-id = 1 log_bin = /var/log/mysql/mysql-bin.log binlog_format = ROW gtid_mode = ON enforce_gtid_consistency = ON重启MySQL后,创建复制用户:
CREATE USER 'repl'@'192.168.1.%' IDENTIFIED WITH mysql_native_password BY 'ReplPassw0rd!'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.%'; FLUSH PRIVILEGES;主库这里之所以用mysql_native_password,是因为复制协议在旧驱动下的兼容性更稳,如果你确认所有环节都支持caching_sha2_password,也可以保留默认认证,但很多复制工具或脚本还是更认mysql_native_password一些。
接着备份主库的orders表并恢复到从库:
mysqldump -u root -p --single-transaction --no-create-db appdb orders > orders.sql mysql -u root -p localdb < orders.sql从库的配置是在mysqld.cnf中设置一个不同于主库的server-id,并指定只复制特定表:
[mysqld] server-id = 2 replicate-do-table = appdb.orders然后启动复制。这里按8.0.23后的推荐语法来:
CHANGE REPLICATION SOURCE TO SOURCE_HOST='192.168.1.10', SOURCE_USER='repl', SOURCE_PASSWORD='ReplPassw0rd!', SOURCE_PORT=3306, SOURCE_AUTO_POSITION=1; START REPLICA; SHOW REPLICA STATUS\G如果你的MySQL版本低于8.0.23,对应的语法是:
CHANGE MASTER TO MASTER_HOST='192.168.1.10', MASTER_USER='repl', MASTER_PASSWORD='ReplPassw0rd!', MASTER_PORT=3306, MASTER_AUTO_POSITION=1; START SLAVE; SHOW SLAVE STATUS\G;看到Replica_IO_Running: Yes和Replica_SQL_Running: Yes,说明同步已经跑起来了。注意replicate-do-table的过滤逻辑,它是在从库执行SQL前做表名匹配过滤,如果你的源库在更新这张表的同时还会更新同事务里的另一张表,基于行的复制可能会把其他表也带到从库执行一部分事务逻辑。所以如果你只是要纯粹单表同步,建议源表的事务里尽量少夹带其他表的写操作,或者考虑用更专职的数据同步工具。但九成场景下,这个配置已经够用了。
我在实际操作中的体会是:Ubuntu 22.04上的MySQL大多数问题不是SQL问题,而是系统层面的差异在捣乱。apt装完后别急着改配置,先搞清楚auth_socket、socket路径、AppArmor这几个隐藏关卡。你在CentOS上的经验可以照搬到SQL语法上,但配置文件路径和服务管理方式一定要重新适应。这篇文章里的每一步都是我在新装系统上验证过的,按这个顺序走,基本能绕开九成以上的常见坑。