简介
- mycat:不仅仅可以用作读写分离、以及分表分库、容灾备份,而且可以用于多租户应用开发、云平台基础设施
- pt-osc(Online Schema Change) 对于大表进行DDL操作工具
- MySQL 中间件汇总比较:https://zhuanlan.zhihu.com/p/490261031
Mysql安装与配置
Mysql安装
- 软件下载:服务器安装包 mysql-installer-community-5.7.32.0.msi (或云盘)、Community Server压缩包 mysql-5.7.32-winx64.zip。installer安装备注如下
- installer默认安装在
C:\Program Files (x86)\MySQL\MySQL Installer for Windows
目录,打开上述msi则会自动安装在此目录,之后可进行配置Server的安装,安装完server之后,仍然可打开此Installer重新安装、增加安装或卸载,尽管下载的是5.7的Installer,但是包含了5.7、8个版本的安装配置 - 启动安装,选择Setup Type:Developer Default默认安装了Server和一些连接器和文档,且安装在C盘,如需定义安装目录,需选择Custom
- 自定义安装时,选择Mysql Servers - Mysql Server 5.7 x64 - 添加到安装列表,其他的连接器和文档(包括示例数据库)可在安装完Server之后进行增加安装
- Windows 10安装Server 5.7可能提示无Visual C++ 2013,此时可去MS官网下载安装后再安装Mysql Server
- installer默认安装在
- CentOS-mysql安装:http://blog.aezo.cn/2017/01/10/linux/CentOS%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E/
- windows 安装 mysql,千万不要用通过记事本编辑
my.ini
,容易让文件变成 BOM 格式导致服务无法启动 - 查看系统版本:命令行登录后欢迎信息中有版本信息,或者登录仅命令行执行
status
查看
Mysql其他分支
- MariaDB
- MariaDB 5.5 对应 Mysql 5.5,5.5以下的版本都是上述对应关系
- MariaDB 10.0 对应 Mysql 5.6
- MariaDB 10.1 对应 Mysql 5.7
相关配置
- 大小写敏感问题
- mysql 在 windows 系统下安装好后,默认是对表名大小写不敏感的。但是在 linux 下,一些系统需要手动设置
- linux设置:打开并修改
/etc/my.cnf
在[mysqld]
节点下,加入一行:lower_case_table_names=1
(表名大小写:0 是大小写敏感,1 是大小写不敏感)。重启 mysql 服务systemctl restart mysqld
- mysql 服务器编码问题
- 保存到数据库编码错误:1.编辑器编码(复制的代码要注意原始代码格式) 2.数据库/表/字段编码 3.服务器编码
- 查看服务器编码
show variables like '%char%';
,如果character_set_server=latin1
就说明有问题(曾经因为这个问题遇到这么个场景:此数据库下大部分表可以正常插入中文,但是有一张表的一个字段死活插入乱码,当尝试修改 java 代码中此 sql 语句的另外几个传入参数并连续插入两次可以正常插入,不产生乱码。此情景简直可以怀疑人生,最终修改 character_set_server 后一切正常) - 修改 character_set_server 编码:linux 修改
/etc/my.cnf
,在[mysqld]
节点下加入一行character-set-server=utf8
,重启 mysqld 服务
基本
登录
- Mysql 进入系统
mysql -uroot -p
用户名登陆,输入回车后再输入 root 密码即可登陆(在 cmd 中定位到 mysql.exe 所在目录)mysql -h 192.168.1.1 -P 3307 -uroot -p my_db_name
登录并选择数据库exit
、quit
退出
- 忘记 root 密码
my.ini
配置文件的[mysqld]
下增加skip-grant-tables
参数,重启数据库- 修改
mysql.user
中该用户的密码 - 去掉启动参数重新启动
创建/删除用户
1 | -- 创建超级用户(对于项目级别用户可对每个数据库进行控制,并去掉Grant权限,即去掉查看当前数据库用户列表权限) |
权限
1 | -- 创建用户并授权 |
管理员
查询相关
show variables like '%dir%';
或使用select @@basedir, @@datadir
- 查看 mysql 相关文件(数据/日志)存放位置,一般也可用于查看my.cfg位置(一般在@@datadir上级目录)
- 数据文件(datadir)默认位置:
/var/lib/mysql
show variables like 'autocommit';
- MySQL 默认操作模式就是 autocommit 自动提交模式(ON/1)
- 这就表示除非显式地开始一个事务(mysql>
set autocommit=0;
),否则每个查询都被当做一个单独的事务自动执行。当 mysql>commit;
之后则又回到自动提交模式
- 查看数据库大小
- InnoDB 存储引擎将表保存在一个表空间内,该表空间可由数个文件创建。表空间的最大容量为 64TB
- MySQL 单表大约在 2 千万条记录(4G)下能够良好运行,经过数据库的优化后 5 千万条记录(10G)下运行良好
1 | use information_schema; |
索引维护
- Mysql索引
- 在没有外键约束的情况下,MySql的不同表的索引可以重名,索引文件一表一个,不会出现冲突
1 | -- ALTER TABLE用来创建普通索引、UNIQUE索引或PRIMARY KEY索引 |
慢SQL/数据库CPU飙高问题
锁相关
- Mysql造成锁的情况有很多,下面我们就列举一些情况
- 执行DML操作没有commit,再执行删除操作就会锁表
- 在同一事务内先后对同一条数据进行插入和更新操作
- 长事物(如期间进行了HTTP请求且等待时间太长),阻塞DDL,继而阻塞所有同表的后续操作
- 表索引设计不当,导致数据库出现死锁
- 更新数据时报错
Lock wait timeout exceeded; try restarting transaction
数据结构ddl操作的锁的等待时间 ^3 - 参考:https://www.cnblogs.com/better-farther-world2099/articles/14721482.html
1 | # 事物等待锁超时,如:一个事物还没有提交(对某些表加锁了还没释放),另外一个线程需要获取锁,从而等待超时 |
- 情景:information_schema.innodb_trx 中有一条事物线程一直存在,且锁定了两行记录(innodb_locks 和 innodb_lock_waits 中并未锁/锁等待记录);最后发现为卡死的事物中进行了HTTP请求,正好HTTP请求一直卡死不返回,导致其他地方修改这个表记录时报错
- 执行DDL时报错
Waiting for table metadata lock
- 参考上文,查询
innodb_trx
表中是否有DDL操作或长事物没有提交
- 参考上文,查询
- 死锁
- mysql5.6的jdbc连接参数useServerPrepStmts=true是个官方bug,所以建议不要用这个,可能会导致select死锁
- 更新/删除死锁,可能两个session操作到了同一行数据
- mysql默认是行级锁,如果操作到不同行数据则不会产生
- 降低死锁
- 选择合理的事务大小,小事务发生锁冲突的概率一般也更小
- 在不同线程中去访问一组DB的数据表时,尽量约定以相同的顺序进行访问;对于同一个单表而言,尽可能以固定的顺序存取表中的行
其他
- 命令行执行sql
- Mysql 通过上下左右按键修改语句
- 或者新建一个文本文件 h:/demo/test.sql,将 sql 语句放在文件中,再在命令行输入
\. h:/demo/test.sql
其中\.
相当于source
,末尾不要分号
- 或者新建一个文本文件 h:/demo/test.sql,将 sql 语句放在文件中,再在命令行输入
- Oracle 输入 ed 则打开记事本可进行修改修改 DOS 中的数据
- Mysql 通过上下左右按键修改语句
- (增删改数据时)可考虑关闭外键校验
SET foreign_key_checks = 0;
0关闭外键校验,1开启校验
业务场景
CPU过高或慢SQL问题
数据恢复
https://zhuanlan.zhihu.com/p/189443387
https://www.cnblogs.com/geoffreyone/p/14247914.html
数据备份/恢复
导出表结构
- MySQL-Front:可导出 html 格式(样式和字段比较人性化),直接复制到 word 中
- SQLyong(数据库-在创建数据库架构 HTML):可导出很完整的字段结构(太过完整,无法自定义)
- DBExportDoc V1.0 For MySQL:基于提供的 word 模板(包含宏命令)和 ODBC 导出结构到模板 word 中(表格无线框)
ibtmp1临时表空间文件过大
- 参考:https://cloud.tencent.com/developer/article/1491411
- ibtmp1文件位于数据目录下,为临时表空间文件,用于存储临时数据,如排序、临时表等
- 默认是12M且会无限增长,当关闭数据库或重启时此临时表空间会清空
- 用到临时表空间的一般为慢SQL,可进行优化。从而也可以设置临时表空间的上限,当超过此上限后,执行SQL用到临时表空间就会报错
- 什么情况会用到临时表空间?可通过explain查看,如果Extra列出现Using temporary则表示使用了临时表空间
- 可GROUP BY 无索引字段或GROUP BY + ORDER BY 的子句字段不一样时
- ORDER BY 与distinct 共用,其中distinct与ORDER BY里的字段不一致(主键字段除外)
- UNION查询(MySQL5.7后union all已不使用临时表)
- insert into select …from …
Oracle表结构与Mysql表结构转换
- 使用 navicat 转换
- 点击
工具 -> 数据传输 - 左边选择源数据库 - 右边选择文件 - 去勾选与原服务器相同
- 其他选项
- 去勾选创建记录
- 去勾选创建前删除表(如果目标库中无次表则会报错)
- 勾选转换对象名为大写/小写(创建oracle表时不会自动将小写转大写,mysql也不会自动转小写)
- 存在问题:小数点精度丢失(如手动替换
Number
为Number(10,2)
)、默认值丢失
- 点击
- Oracle迁移MySQL注意事项
内存参数优化(适用小内存VPS)
- 适用mysql 5.6/5.7/8.0内存参数,优化内存占用为40MB左右。参考: http://www.manongjc.com/detail/56-vqenqmbjvqxtfmr.html
- 修改
/etc/my.cnf
并重启
1 | [mysqld] |
测试
执行耗时案例
1 | -- 复制1000w条数据用时205秒,大概3分钟25秒,粗略估算,5000万数据如果通过此种方式将全表数据备份,也只需要18分钟左右 |
- 使用
mysqldump/source
方法进行导出导入- 15 分钟导出 1.6 亿条记录,导出的文件中平均 7070 条记录拼成一个 insert 语句
- 通过 source 进行批量插入,导入 1.6 亿条数据耗时将近 5 小时,平均速度 3200W 条/h(网测)
快速创建数据
1 | -- 1.创建一个临时内存表 |
参考文章