ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

MySQL保姆级安装与核心操作速查手册

MySQL保姆级安装与核心操作速查手册 1. 环境准备与安装方式盘点既然标题是Mysql--01我就把它当作一个系列的开篇来写。这个系列会覆盖MySQL从环境搭建、基础语法、进阶功能到运维实践的全链路内容。开篇这一章先把环境这块最头疼的问题讲透因为很多新手朋友不是死在SQL上而是死在装不上、连不上、莫名其妙报错这几关上。这一篇里面我把你关心的安装、连接、配置、默认值、字符串转日期这些高频需求全部拆开揉碎讲一遍最后再补充一批面试题和优化思路。你可以把它当作一份随时翻查的操作手册也可以当成系统学习的起点。1.1 Windows环境下的安装与配置Windows装MySQL属于最省心的场景但也有一堆细节容易踩坑。官方下载地址是MySQL官网的下载页面进去之后选MySQL Community Server版本目前主流是8.0系列和5.7系列。我给新手的建议是直接装8.0不要犹豫。5.7虽然经典但已经进入EOL阶段新项目没必要再抱着老版本不放。下载的时候有ZIP Archive和MSI Installer两种格式。MSI是图形化安装一路Next就行适合完全没经验的朋友。ZIP包需要手动配置但更灵活。我通常推荐ZIP包因为后续想换版本、做多实例部署的时候ZIP包管理起来更直观。ZIP包的安装流程其实就三步第一步解压到目标目录比如D盘下的mysql-8.0目录注意路径里不要有中文和空格。第二步在解压目录下新建my.ini配置文件最小化配置如下[mysqld] basedirD:/mysql-8.0 datadirD:/mysql-8.0/data port3306 character-set-serverutf8mb4 default-storage-engineINNODB [client] default-character-setutf8mb4这里有个关键点character-set-server一定要设成utf8mb4不要再用utf8。MySQL的utf8实际是utf8mb3只能存3字节的字符像emoji表情、生僻字这类4字节字符会直接报错。utf8mb4才是真正的完整UTF-8支持这是8.0版本之后的强制趋势也是很多人在插入特殊字符时遇到Incorrect string value报错的根源。第三步以管理员身份打开CMD进入bin目录执行mysqld --initialize-insecure mysqld --install mysql8 net start mysql8--initialize-insecure的意思是初始化数据目录并且root账号默认空密码。如果想生成临时随机密码把参数换成--initialize就行但随机密码会写在数据目录的err日志文件里。第一次启动成功后马上做两件事修改root密码创建自己的业务账号。mysql -u root -p ALTER USER rootlocalhost IDENTIFIED BY 你的新密码; CREATE USER app% IDENTIFIED BY 业务密码; GRANT ALL PRIVILEGES ON *.* TO app% WITH GRANT OPTION; FLUSH PRIVILEGES;注意8.0版本的认证插件默认是caching_sha2_password有些老客户端比如某些版本的Navicat、老版本JDBC驱动不支持这个插件连接时会报认证失败。这时候需要把账号的认证插件改回mysql_native_password或者升级客户端驱动。这个坑我见得太多了很多人排查半天以为是网络问题结果就是认证插件不兼容。1.2 Linux环境下的安装与配置Linux装MySQL分两条路线在线安装和离线安装。在线安装走的是系统包管理器。CentOS/RHEL系列用yum或dnf先装官方仓库再装MySQLDebian/Ubuntu系列用apt。以CentOS为例wget https://repo.mysql.com/mysql80-community-release-el7-3.noarch.rpm rpm -ivh mysql80-community-release-el7-3.noarch.rpm yum install mysql-community-server -y systemctl start mysqld安装完成后查看初始密码是个经典问题。MySQL 5.7及之后版本会在首次启动时生成临时密码存放在日志文件里grep temporary password /var/log/mysqld.log拿到临时密码登录后第一件事就是改密码。如果嫌这个流程啰嗦可以在my.cnf里加一行skip-grant-tables跳过授权表直接免密登录改完密码后再把这行注释掉重启。不过这个操作有安全隐患只建议在纯本地实验环境用。离线安装是另一种常见场景尤其是内网服务器或没有外网权限的机器。思路是在一台能联网的同版本系统上下载好所有rpm包拷到目标机器上然后用rpm -ivh批量安装。需要注意包之间的依赖关系MySQL的rpm包依赖顺序一般是common、libs、client、server。如果嫌麻烦可以用yum localinstall一次性解决依赖校验。Linux环境还有一个高频问题启动时报error 2002 (HY000): Cant connect to local MySQL server through socket /tmp/mysql.sock。这个报错的本质是客户端通过socket文件连接本地MySQL但socket文件不存在或者路径不对。排查思路就三步第一步确认mysqld进程有没有启动ps -ef | grep mysqld看看。第二步看socket文件实际在哪MySQL默认可能写在/var/lib/mysql/mysql.sock而客户端默认去/tmp找。解决办法是在my.cnf的[mysqld]和[client]段同时指定一致的socket路径[mysqld] socket/var/lib/mysql/mysql.sock [client] socket/var/lib/mysql/mysql.sock第三步确认目录权限socket文件所在目录必须对mysql用户可写。很多装了系统之后自己建数据目录的朋友就是死在权限这一步。1.3 Docker方式部署MySQLDocker部署MySQL是现在开发和测试环境的主流选择好处是环境隔离、清理方便、版本切换零成本。一条命令就能拉起一个实例docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDroot123 \ -v /myown/mysql/data:/var/lib/mysql \ mysql:8.0这里有几个细节值得展开说。MYSQL_ROOT_PASSWORD环境变量只对初始化数据目录时生效如果你挂载了已有的数据目录这个变量不会改变root密码遇到这种情况直接用docker exec进去改密码即可。数据目录挂载一定要做否则容器删除后数据全部丢失这是新手最容易忽视的致命操作。有个常见的坑是执行docker run之后容器启动失败docker logs一看报的是权限问题或者配置文件找不到。多数情况下是宿主机挂载目录的内核权限SELinux拦截或者mysql官方镜像里自带的配置和你的挂载文件冲突。我的建议是不要挂载自己写的my.cnf先让容器默认配置跑起来需要调参的时候再用docker cp把配置拷进容器或者写一个自定义Dockerfile一步到位。还有一个问题是连接池的连接数和容器资源的匹配关系。默认配置下MySQL最大连接数是151如果你是Spring Boot默认的HikariCP连接池默认maximum-pool-size是10正常情况下够用。但如果你的服务是多实例部署每个实例都开10个连接十几个实例就把连接数打满了。启动容器的时候加个参数docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDroot123 \ --max-connections500 \ -v /myown/mysql/data:/var/lib/mysql \ mysql:8.0或者进容器里改SET GLOBAL max_connections 500; 注意这个设置重启后失效要持久化还得写配置。2. 基础操作的几个高频场景这一节把你在热搜词里看到的几个基础操作集中处理掉设置默认值为0、字符串转日期、int类型相关操作、排序、去重。这些看起来都是小问题但在实际开发里出现频率非常高而且很多细节不留意就会返工。2.1 字段默认值设置为0的两个位置mysql设置默认值为0是搜索频率极高的问题常见场景是新建表的时候给某个数字字段设初值比如订单状态、库存数量、计数统计。DDL建表时直接指定CREATE TABLE t_order ( id INT PRIMARY KEY AUTO_INCREMENT, status INT NOT NULL DEFAULT 0, stock INT NOT NULL DEFAULT 0 );如果表已经存在需要用ALTER TABLE修改ALTER TABLE t_order ALTER COLUMN status SET DEFAULT 0;这里有个容易混淆的点DEFAULT 0只是在INSERT语句没给这个字段赋值时生效。如果你显式INSERT了NULL字段照样是NULL除非列定义为NOT NULL。所以生产表里我建议数字类型字段一律加NOT NULL DEFAULT 0从根源上杜绝NULL值的各种意外。NULL值在WHERE条件判断、索引统计、聚合计算里都会引发一系列隐蔽问题能避免就尽量避免。另一个经常踩的坑是ALTER TABLE修改默认值时如果表里已经有很多数据这个操作本身不加锁实际上MySQL 8.0对ALTER TABLE的默认值修改用的是INSTANT算法可以秒级完成不会锁表。但如果你同时修改列属性比如把INT改成BIGINT那就要看具体情况了大数据量表可能需要COPY算法会锁表导致业务中断。所以我的建议是默认值的修改单独执行不要和列类型修改混在一条ALTER语句里。2.2 字符串转日期的正确姿势字符串转日期是数据清洗和报表开发里的高频需求。MySQL里核心函数是STR_TO_DATE()格式符和DATE_FORMAT()是互逆的。SELECT STR_TO_DATE(2024-06-15, %Y-%m-%d); SELECT STR_TO_DATE(2024/06/15 14:30:00, %Y/%m/%d %H:%i:%s); SELECT STR_TO_DATE(15-06-2024, %d-%m-%Y);这里需要注意格式符的严格匹配%Y代表四位年份%y代表两位年份%m代表月份%c代表不带前导零的月份%H代表24小时制小时%h代表12小时制小时。格式符不匹配时STR_TO_DATE返回NULL而不是报错这是很多人排查半天数据怎么老是NULL的原因。还有个更好用的替代方案MySQL的CAST语法直接支持字符串转日期的隐式转换SELECT CAST(2024-06-15 AS DATE);但CAST对输入格式要求比较严格必须是ISO格式YYYY-MM-DD或者带时间部分的标准格式。遇到不规范的输入还是得先清洗再用STR_TO_DATE解析。实际业务里日志表、导入表的日期字段往往千奇百怪我的建议是导入阶段统一用STR_TO_DATE加格式判断清洗成标准DATE/DATETIME类型再落库不要在查询阶段反复转换既浪费性能又容易出错。2.3 字段计算与排序去重mysql中int5这类热搜反映的是新手对MySQL表达式计算的困惑。比如有个字段余额是DECIMAL类型想给每行加5元SELECT balance, balance 5 AS new_balance FROM t_account;这个直接做就行MySQL对数值类型隐式转换很智能。但要注意如果balance是VARCHAR类型存着数字加上5之后MySQL会自动把字符串转成数字运算但一旦字符串里混入非数字字符比如12.5元结果就是0或者报错。所以生产环境一定不要让业务字段出现这种混合格式。排序方面ORDER BY的坑主要在字符集和排序规则。用utf8mb4_general_ci和utf8mb4_unicode_ci对中文、英文字母的大小写、重音字符的排序结果不一样。如果需要中文按拼音排序可以用SELECT name FROM t_user ORDER BY CONVERT(name USING gbk);这个技巧在处理中文排序时很有用但要注意性能对索引列做CONVERT转换会让索引失效数据量大的时候建议在应用层排序或者加一个拼音字段做冗余。去重方面mysql的or能去重吗这个热搜问题问得挺可爱。OR是条件逻辑运算符本身和去重没有任何关系。去通用器是DISTINCT或者GROUP BYSELECT DISTINCT category FROM t_product; SELECT category FROM t_product GROUP BY category;两者的细微差别是DISTINCT在语义上更直观GROUP BY在搭配COUNT、SUM等聚合函数时更灵活。另外注意DISTINCT只能去重查询结果中完全相同的行如果查询里同时选择多个字段那多字段组合完全相同才会去重。很多新人在只查一列时用了DISTINCT加了JOIN之后发现数据还是重复的其实就是因为组合字段不完全相等。3. 进阶功能存储过程、触发器与主从复制这一节讲的是从会写SQL到能设计数据库逻辑的进阶内容。热搜词里出现了存储过程、触发器中的分隔符、主从复制、远程表同步等关键词这些在传统项目里可能用得不多但在复杂业务和运维场景中非常能解决问题。3.1 存储过程的创建与错误处理存储过程是MySQL里一组预编译的SQL语句集合优势是减少网络交互、封装复杂逻辑、权限控制更精细。一个带异常处理的存储过程长这样DELIMITER // CREATE PROCEDURE sp_transfer( IN from_account INT, IN to_account INT, IN amount DECIMAL(10,2) ) BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; SELECT 转账失败事务回滚 AS error_msg; END; START TRANSACTION; UPDATE t_account SET balance balance - amount WHERE id from_account; UPDATE t_account SET balance balance amount WHERE id to_account; COMMIT; END // DELIMITER ;这里我特意加了DELIMITER //这是存储过程和触发器中最容易让新手困惑的点。原因很简单MySQL默认把分号当作语句结束符而存储过程内部也有分号如果不用DELIMITER改掉默认结束符MySQL会把存储过程的定义截断在第一行分号处导致语法错误。CREATE PROCEDURE本身是一个完整的语句必须用临时结束符包裹等创建完成后再用DELIMITER ;恢复默认。存储过程里的错误处理DECLARE EXIT HANDLER是核心。除了SQLEXCEPTION还有SQLWARNING和NOT FOUND两类条件。NOT FOUND在处理游标遍历时用得最多DECLARE CONTINUE HANDLER FOR NOT FOUND SET done TRUE;这里EXIT和CONTINUE的区别要记牢EXIT表示出错后直接退出BEGIN事务块CONTINUE表示出错后继续往下执行。金融类业务中必须用EXIT加ROLLBACK否则一旦中途出错事务不会自动回滚数据就脏了。关于存储过程的另一个实操心得是现在很多互联网公司不太推荐用存储过程主要原因是存储过程的版本管理困难、测试不方便、对数据库负载集中。但如果你做的是传统企业项目、报表系统、或者是处理逻辑固定且安全性要求极高的操作存储过程依然是合理的选择。技术没有绝对的好与坏只有适合与不适合。3.2 触发器与分隔符的配合触发器是在INSERT、UPDATE、DELETE事件发生时自动执行的SQL逻辑常用于审计日志、自动填充时间戳、级联更新等场景。一个标准触发器示例DELIMITER // CREATE TRIGGER trg_order_audit AFTER INSERT ON t_order FOR EACH ROW BEGIN INSERT INTO t_order_log(order_id, action, operate_time) VALUES (NEW.id, INSERT, NOW()); END // DELIMITER ;同前面存储过程的原理一致触发器也必须配合DELIMITER使用。触发器里NEW代表新插入的行或UPDATE后的行OLD代表UPDATE前的行或DELETE删除的行。触发器的性能隐患我之前踩过不少坑。比如在循环INSERT的场景下每插入一行就会触发一次AFTER INSERT逻辑如果触发逻辑里有大量查询或更新整批插入的性能会急剧下降。我曾经调过一个跑批任务每秒只能插入几百行排查后果然是个触发器里嵌了复杂的SELECT操作。最后方案是把审计逻辑改成应用层批量写入性能提升了一个数量级。所以触发器的使用准则我给三条不要在其中做复杂查询、不要嵌套调用其他触发器或存储过程、触发器内不要做耗时操作比如调用外部接口。触发器适合轻量级的约束和审计重量级逻辑还是老老实实放到业务层和应用层。3.3 主从复制与远程表同步实操主从复制是MySQL高可用体系里的基石方案。核心原理是主库把所有变更记录到二进制日志binlog从库通过IO线程拉取binlog写到自己的中继日志relay log再由SQL线程重放中继日志完成数据同步。搭建主从复制的关键步骤分四大块第一块主库开启binlog。在my.cnf里配置[mysqld] server-id1 log-binmysql-bin binlog_formatROWbinlog_format建议用ROW模式相比STATEMENT模式ROW模式对数据一致性更安全虽然日志量会大一些但避免了存储过程、函数、触发器在主从两端执行结果不一致的风险。第二块主库创建复制专用账号CREATE USER repl% IDENTIFIED BY Repl123456; GRANT REPLICATION SLAVE ON *.* TO repl%; FLUSH PRIVILEGES;第三块从库配置并启动复制[mysqld] server-id2 read_only1CHANGE MASTER TO MASTER_HOST主库IP, MASTER_USERrepl, MASTER_PASSWORDRepl123456, MASTER_LOG_FILEmysql-bin.000001, MASTER_LOG_POS154; START SLAVE; SHOW SLAVE STATUS\G;这个执行过程一定要记录清楚MASTER_LOG_FILE和MASTER_LOG_POS怎么获取在主库执行SHOW MASTER STATUS;拿到当前的binlog文件名和位置然后从库从这个位置开始同步。如果主库已有大量数据需要先做主库全量备份恢复到从库再从备份时点的binlog位点开始拉取这个操作顺序我强烈建议先在测试环境完整走一遍。第四块验证同步状态。SHOW SLAVE STATUS里重点看两项Slave_IO_Running和Slave_SQL_Running两个都必须是YES。其中IO线程负责拉日志SQL线程负责重放任何一个是NO都说明同步中断了需要看Last_IO_Error或者Last_SQL_Error定位原因。把远程库的这张表同步到本地这个需求很多人第一反应是做全库同步其实单表单同步在MySQL里是个麻烦事因为原生复制是基于binlog的库级和表级过滤但binlog内的复制不支持按表同步到不同结构的库。实际可行方案有几个方案一主从复制加过滤规则。从库启动时指定只复制某库的某表replicate-do-tabledbname.tablename但注意这种方案要求远程库和本地库的表结构一致而且是持续性的整个表的复制不能灵活指定只同步某几个字段或者加WHERE条件。方案二程序定时同步。写一个脚本或者Job用binlog订阅工具比如Canal、Maxwell解析远程库的binlog把变更事件转发到本地。这个方案灵活度高可以做字段映射、带过滤条件、多表合并是现在数据同步平台的主流做法。方案三如果是离线同步直接用mysqldump导单表mysqldump -h 远程库IP -u user -p dbname tablename table.sql mysql -h 本地IP -u user -p dbname table.sql这种方案适合一次性或定时全量同步不适合实时增量。选择哪个方案取决于你的业务对实时性的要求——实时性要求高就上Canal能接受分钟级延迟就写脚本定时任务一次性数据迁移就mysqldump最简单。4. 连接与性能问题的排查思路这一节解决的是环境没问题、SQL也写了但连接不稳定、性能跑不动这一类让人抓狂的问题。很多问题看起来玄学实际都是配置或机制理解不到位导致的。4.1 数据库连接池的配置逻辑mysql的数据库连接池是JavaWeb项目里的高频配置项。连接池存在的意义是复用数据库连接避免每次请求都新建连接。新建连接的开销比执行SQL本身大得多所以连接池参数的配置直接决定了应用在高并发下的表现。以HikariCP为例核心参数就三个maximumPoolSize最大连接数不是越大越好。MySQL默认max_connections是151你的应用连接池如果设置150再叠加运维工具、监控工具、其他服务的连接分分钟打爆数据库。我常用的评估公式是单实例连接数×应用实例数数据库连接总数留20%到30%的余量。minimumIdle最小空闲连接数建议和maximumPoolSize一致避免突发流量时频繁创建新连接。connectionTimeout获取连接的超时时间默认30秒太长生产环境建议3000到5000毫秒避免应用线程无限等待。还有一个容易被忽略的配置连接的最大生命周期maxLifetime。MySQL服务端有个wait_timeout参数默认8小时超过时间的空闲连接会被服务端关闭。如果连接池不知道这个情况继续使用已失效的连接应用层就会报Communications link failure。解决办法是把连接池的maxLifetime设成比数据库wait_timeout短比如240000毫秒4分钟让连接池在数据库断开之前主动回收连接。对于数据库端我建议把wait_timeout调短比如300秒把interactive_timeout也调短这样可以在数据库侧主动清理僵尸连接避免连接数被占满。两个参数配合好连接池会稳定很多。4.2 MySQL SSL连接错误排查mysql ssl连接错误这个热搜词说明很多人遇到了SSL/TLS相关的连接问题。MySQL 8.0默认开启SSL但证书路径配置不对或者客户端兼容性差就会报各种奇怪的错误。常见错误场景一客户端连接时报SSL connection error: unknown error number。这个多半是客户端无法验证服务器证书。解决思路有三个一是把连接字符串里的SSL模式调整为不校验证书。JDBC里设置useSSLfalse但8.0版本建议改成verifyServerCertificatefalse配合useSSLtrue而不是彻底关闭SSL。二是如果数据库没配置证书可以在服务端生成自签名证书。MySQL自带mysql_ssl_rsa_setup工具执行一下就会生成ca.pem、server-cert.pem、server-key.pem等文件然后在my.cnf里配置ssl-ca、ssl-cert、ssl-key路径重启生效。三是如果只想临时验证客户端可以加参数跳过SSL校验但生产环境不推荐长期这样做。常见错误场景二SSL证书过期导致连接失败。证书是有有效期的默认生成的自签名证书有效期可能较长但也要提前规划轮换。检查SSL状态SHOW VARIABLES LIKE %ssl%; SHOW STATUS LIKE Ssl_cipher;如果是连接池里的连接SSL握手失败时连接池会连续重试导致应用启动特别慢。这种情况建议先确认证书有效性再检查连接池配置最后看防火墙端口是否放行。4.3 锁原理与性能调优要点MySQL锁的问题既是运维排查高频场景也是面试必考题。热词里mysql锁原理及面试题和mysql锁表两个词放在一起正好构成了完整的学习闭环。先厘清锁的分类。按粒度分全局锁FLUSH TABLES WITH READ LOCK、表级锁表锁、元数据锁MDL、行级锁InnoDB的Record Lock、Gap Lock、Next-Key Lock。按模式分共享锁S Lock和排他锁X Lock。InnoDB的行锁是建立在索引上的如果查询没有走索引行锁会升级成表锁这是导致锁表和高并发下死锁的核心原因之一。mysql锁表最常见的原因是长事务。一个事务开启后迟迟不提交它持有的行锁不释放后续对该行的所有操作都会阻塞。排查长事务的标准SQLSELECT * FROM information_schema.INNODB_TRX\G; SELECT * FROM sys.innodb_lock_waits\G;定位到阻塞的事务ID后可以查看它正在执行的SQL判断是逻辑问题还是纯粹忘了提交事务必要时用KILL杀掉这个连接。死锁是另一个经典问题。两个事务各自持有对方需要的锁互相等待InnoDB会自动检测并回滚其中一方。处理死锁的思路不是等死锁发生再去解决而是从设计上规避一是所有事务里的SQL操作按固定顺序执行避免交叉获取锁。二是事务尽量短小精悍减少持有锁的时间窗口。三是设置合理的隔离级别默认REPEATABLE READ在大多数场景下没必要可以降到READ COMMITTED减少Gap Lock的概率这在MySQL中是官方推荐的互联网业务实践。关于性能调优新手容易犯的错误是一上来就改一堆参数结果越改越糟。我的建议是先定位瓶颈再调参。用慢查询日志定位慢SQL用EXPLAIN分析执行计划看是否走了索引看扫描行数是否异常看临时表和排序是否有额外开销。参数优化排在这些后面常用的几个innodb_buffer_pool_size物理内存的60%-70% innodb_log_file_size512M max_connections根据实际压测结果定innodb_buffer_pool_size是最关键的参数它决定了InnoDB缓存数据和索引的内存池大小命中率高则磁盘IO显著降低。8.0版本里这个参数可以动态调整SET GLOBAL innodb_buffer_pool_size 4G但生产环境仍然建议写在配置文件里持久化。5. 常见问题速查与实用建议这一节把你搜到的那些零散问题集中整理成速查表方便下次遇到直接查。另外补充一些运维实战中的细节以及面试题的高频考点。5.1 零散问题速查表问题原因与解决error 2002 (HY000): Cant connect through socketsocket路径不一致或mysqld未启动统一socket路径并确认进程在跑mysql e0434352通常是cnf配置编码问题检查character-set-server是否配置正确银河麒麟启动mysql失败多半是依赖库缺失或SELinux阻止检查libaio依赖、关闭SELinux或放行端口Navicat连接失败八成是caching_sha2_password认证插件不兼容改mysql_native_passworddocker安装mysql失败看docker logs检查端口冲突、挂载目录权限伪设置或SELinux拦截dbeaver离线驱动下载失败手动下载mysql-connector-java jar包放入dbeaver的驱动目录存储过程中的错误信息用DECLARE EXIT HANDLER捕获SELECT抛出可读错误信息存储过程与函数能否和ASP搭配可以ASP通过ADO调用MySQL存储过程执行时参数传参即可Navicat for MySQL版本兼容新Navicat对MySQL 8.0支持良好老版本建议升级驱动5.2 面试题核心考点整理MySQL面试题我在这个系列里打算单独开一篇深入展开这里先列个框架性的脉络方便面试前快速过一遍事务ACID和隔离级别这部分重点要理解MVCC机制InnoDB通过隐藏字段、undo log和read view实现多版本并发控制不同隔离级别下read view的生成时机不同。RC隔离级别下每条普通SELECT都会生成新read viewRR隔离级别下事务内第一个SELECT才生成。索引原理这块重点搞懂B树为什么能支撑高效范围查询。聚簇索引的叶子节点存整行数据二级索引的叶子节点存主键值回表是怎么发生的。联合索引的最左前缀原则要配合实际查询讲而不是背概念。锁和死锁这块面试官喜欢让你现场分析死锁场景。把握几个要点行锁加在索引上、Gap Lock防止幻读、Next-Key Lock是记录锁和间隙锁的组合、事务中SQL执行顺序不一致是死锁的常见导火索。主从复制和高可用重点讲清楚binlog的三种格式各有什么优劣势半同步复制和异步复制的区别以及MHA或组复制等方案的基本原理。5.3 环境变量与常用命令补充最后补充一批我实际工作中反复在用的命令特别是那些搜索频率极高的场景。查看MySQL初始密码、端口、状态这类基础操作mysqladmin -u root -p status mysqladmin -u root -p variables | grep port mysql -u root -p -e SHOW VARIABLES LIKE port;Linux下离线安装MySQL的完整思路前面讲过这里再补充一个关键点。离线包管理系统用rpm方式安装时遇到依赖报错很普遍。最高效的办法是配置一个本地yum源把依赖的rpm包全部放在一个目录里然后createrepo生成metadata再用yum localinstall安装。这样yum会自动解决包依赖顺序免得自己挨个手动试错。JavaWeb项目完整案例里MySQL的配置核心就三处JDBC驱动坐标、数据源配置、连接池参数。JDBC连接串里常用参数我列一下jdbc:mysql://localhost:3306/appdb?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/ShanghaiallowMultiQueriestrueuseUnicode和characterEncoding保证中文不乱码useSSL避免本地开发环境SSL握手问题serverTimezone解决时区报错allowMultiQueries开启多语句执行注意这个在生产环境要谨慎会增大SQL注入风险。tdengine和MySQL表结构转换的场景最近咨询的朋友也变多了。这个需求一般出现在物联网项目里MySQL做业务库TDengine做时序库。核心思路是MySQL的表结构映射为TDengine的超级表STABLE每条设备的数据作为子表时间戳字段用TIMESTAMP类型标签字段比如设备ID、站点ID用TAG类型。转换时要注意TDengine的字段类型没有VARCHAR的长字符串用BINARY或NCHAR替代。6. 我对这个系列后续的规划Mysql--01既然开了头这个系列后面我计划按这样一条线走下去索引与SQL优化单独讲透不管是慢查询优化还是EXPLAIN的执行计划分析都是实际项目里最能体现存在感的技术点事务、锁与MVCC机制需要配着线上死锁日志一起分析才有意思主从复制从原理讲到实战再到故障切换备份与恢复方面mysqldump和binlog的配合策略是每个DBA都必须掌握的保命技能。最后再分享一个实操心得。我见过太多项目的MySQL问题是能用就行的心态种下的。建表不加主键、字符集不统一、索引乱建、事务随手开、连接池参数全默认。这些问题单个看都不算致命但累积到一定规模以后你就会陷入今天这条SQL超时、明天那张表锁死的泥潭。与其等出事故再救火不如在最开始就建立一套规范所有表必须有主键、字符集统一utf8mb4、数字列尽量NOT NULL DEFAULT 0、连接池参数按压测结果配置、慢查询日志长期开着、定期检查长事务和锁等待。这些习惯花不了多少时间但在关键时刻能救你一命。MySQL这个东西入门只需要一天但要真正理解它的脾气需要几年时间跟它斗智斗勇。这个系列我会持续更新把我在这条路上踩过的坑、总结出来的最优解都放在里面。下一篇见。
返回列表