453 lines
11 KiB
Markdown
453 lines
11 KiB
Markdown
---
|
||
title: "Mysql 笔记"
|
||
date: 2019-10-30T11:51:23+08:00
|
||
lastmod: 2019-10-30T11:51:23+08:00
|
||
tags: ["mysql"]
|
||
categories: ["database"]
|
||
---
|
||
|
||
## MySQL 5.7 配置文件 my.cnf
|
||
```
|
||
[mysqld]
|
||
datadir = /db/mysql
|
||
socket = /var/lib/mysql/mysql.sock
|
||
symbolic-links = 0
|
||
log-timestamps = SYSTEM
|
||
slow-query-log = 1
|
||
slow-query-log-file = /var/log/mysqld/slow.log
|
||
long-query-time = 8
|
||
#log-queries-not-using-indexes = 1
|
||
log-error = /var/log/mysqld/error.log
|
||
pid-file = /var/run/mysqld/mysqld.pid
|
||
max-connections = 1000
|
||
max-connect-errors = 1000
|
||
max-user-connections = 600
|
||
interactive-timeout = 3600
|
||
wait-timeout = 3600
|
||
skip-name-resolve = 1
|
||
lower-case-table-names = 1
|
||
default-time-zone = '+08:00'
|
||
character-set-server = utf8mb4
|
||
sql-mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
|
||
bind-address = 0.0.0.0
|
||
table-open-cache = 2048
|
||
default-storage-engine = innodb
|
||
innodb-autoinc-lock-mode = 2
|
||
innodb-flush-log-at-trx-commit = 0
|
||
# 建议物理内存一半
|
||
innodb-buffer-pool-size = 8G
|
||
innodb-buffer-pool-instances = 8
|
||
max-allowed-packet = 512M
|
||
query-cache-size = 0
|
||
query-cache-type = 0
|
||
# 建议点分 ip 的最后一个数字
|
||
server-id = 123
|
||
# bin log
|
||
#binlog-format = ROW
|
||
#log-bin = /var/lib/mysql/mysql-bin
|
||
#expire-logs-days = 3
|
||
# relay log
|
||
#read-only = 1
|
||
#replicate-wild-do-table = db1.%
|
||
#relay-log = /var/lib/mysql/mysql-relay-bin
|
||
#slave-parallel-type = logical-clock
|
||
```
|
||
|
||
## 复制表结构
|
||
```sql
|
||
create table db1.t1 like db2.t2;
|
||
create table db1.t1 select db2.t2 where 1=2;
|
||
```
|
||
|
||
## 复制表结构及其数据
|
||
```sql
|
||
create table db1.t1 select db2.t2 [where ...]
|
||
```
|
||
|
||
## 复制表数据
|
||
```
|
||
insert into db2.t2(column1, column2 ...)
|
||
select column1, column2 ... from db1.t1 [where ...]
|
||
```
|
||
|
||
## 通过复制表文件来复制表数据
|
||
- 在db2中创建同结构表
|
||
```sql
|
||
create table db2.t1 like db1.t1;
|
||
```
|
||
|
||
- 丢弃表空间
|
||
```sql
|
||
alter table db2.t1 discard tablespace;
|
||
```
|
||
|
||
- 复制 t1 的表数据文件
|
||
```bash
|
||
#关闭数据库
|
||
systemctl stop mysqld
|
||
cd /var/lib/mysql
|
||
scp db1/t1.idb db2/t1.idb
|
||
chown mysql.mysql db2/t1.idb
|
||
#启动数据库
|
||
systemctl start mysqld
|
||
```
|
||
|
||
- 导入表空间
|
||
```sql
|
||
alter table db2.t1 import tablespace;
|
||
```
|
||
|
||
## 设置一个表的空列自增
|
||
```sql
|
||
-- 删除可能存在的主键
|
||
alter table 表名 drop primary key;
|
||
alter table 表名 modify 列名 auto_increment primary key;
|
||
```
|
||
|
||
## 查看数据库中每个表的全部列名
|
||
```sql
|
||
select table_name, column_name from
|
||
information_schema.columns
|
||
where table_schema = '数据库名';
|
||
```
|
||
|
||
## 查看数据库中每个表的行数
|
||
```sql
|
||
select table_name, table_rows
|
||
from information_schema.tables
|
||
where table_schema = '数据库名';
|
||
```
|
||
|
||
## 查看数据库中每个表的索引
|
||
```sql
|
||
select table_name, column_name, index_name
|
||
from INFORMATION_SCHEMA.STATISTICS
|
||
where table_schema = '数据库名';
|
||
```
|
||
|
||
## 表的部分列数据到另一个表
|
||
```sql
|
||
update db2.t2(column1, column2 ...) = (
|
||
select column1, column2 from db1.t1
|
||
where db1.t1.id = db2.t2.id);
|
||
```
|
||
|
||
## 把语句执行结果写到文件
|
||
```bash
|
||
mysql -uroot -p -hsever_ip -Ddb_name
|
||
-Ne "select ... from table_name;" > file_name
|
||
```
|
||
|
||
## 表分区
|
||
- 查看表的分区情况
|
||
```sql
|
||
select table_schema, table_name, partition_name, table_rows
|
||
from information_schema.partitions
|
||
where table_name = 'table_name';
|
||
```
|
||
|
||
- 建表时指定
|
||
```sql
|
||
create table table_name(...)
|
||
partition by range columns(column_name)
|
||
(partition part_name values less than(some_value));
|
||
```
|
||
|
||
- 修改成分区表
|
||
```sql
|
||
alter table table_name
|
||
partition by range(column_name)
|
||
(partition part_name values less than(som_value));
|
||
```
|
||
|
||
- 增加分区
|
||
```sql
|
||
alter table table_name add partition
|
||
(partition part_name values less than(som_value));
|
||
```
|
||
|
||
- 删除分区
|
||
```sql
|
||
alter table table_name drop partition part_name;
|
||
```
|
||
|
||
- 合并/拆分分区
|
||
```sql
|
||
alter table table_name
|
||
reorganize part_old_1, part_old_2, part_old_3 into
|
||
(partition part_new_1 values less than(value_1),
|
||
partition part_new_2 values less than(value_2));
|
||
```
|
||
|
||
- 重建分区,整理分区碎片
|
||
```sql
|
||
alter table table_name
|
||
rebuild partition part_name_1, part_name_2;
|
||
```
|
||
|
||
- 优化分区,回收空间,整理碎片
|
||
```sql
|
||
alter table table_name
|
||
optimize partition part_name_1, part_name_2;
|
||
```
|
||
|
||
- 分析分区,读取并保存分区的健分布
|
||
```sql
|
||
alter table table_name
|
||
analyze partition part_name_1, part_name_2;
|
||
```
|
||
|
||
- 修复分区
|
||
```sql
|
||
alter table table_name
|
||
repair partition part_name_1, part_name_2;
|
||
```
|
||
|
||
- 检查分区
|
||
```sql
|
||
alter table table_name
|
||
check partition part_name_1, part_name_2;
|
||
```
|
||
|
||
## MySQL 5.7 从库多线程同步
|
||
```sql
|
||
stop slave;
|
||
set global slave_parallel_type='logical_clock';
|
||
set global slave_parallel_workers=4;
|
||
start slave;
|
||
show processlist;
|
||
```
|
||
|
||
## MySQL 5.7 提示密码复杂度不够
|
||
```sql
|
||
set global validate_password_policy=0;
|
||
```
|
||
|
||
## MySQL 5.7 从库复制失败跳过指定数量的事务
|
||
```sql
|
||
stop slave;
|
||
-- 跳过一个事务
|
||
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
|
||
start slave;
|
||
-- 修改 my.cnf
|
||
slave-skip-errors=1062,1053,1146,1032 #跳过指定error no类型的错误
|
||
slave-skip-errors=all #跳过所有错误
|
||
```
|
||
|
||
## MySQL 5.7 查看全部任务
|
||
```sql
|
||
-- 分号换成 \G 显示完整 sql
|
||
show processlist;
|
||
show full processlist;
|
||
SELECT command FROM information_schema.processlist;
|
||
```
|
||
|
||
## MySQL 5.7 ssl 连接
|
||
```
|
||
--ssl-mode=REQUIRED
|
||
```
|
||
|
||
## MariaDB 10.1 修改密码
|
||
```sql
|
||
UPDATE user SET password=password('newpassword') WHERE user='root';
|
||
```
|
||
|
||
## MySQL 5.7 编码
|
||
- 查看
|
||
```sql
|
||
SHOW VARIABLES LIKE 'character_set%';
|
||
```
|
||
|
||
- 数据库连接参数中,characterEncoding=utf8 会被自动识别为 utf8mb4,但是 autoReconnect=true 必须指定
|
||
- 更改数据库编码
|
||
```sql
|
||
ALTER DATABASE db_name
|
||
CHARSET UTF8MB4 COLLATE UTF8MB4_GENERAL_CI;
|
||
```
|
||
|
||
- 更改表编码
|
||
```sql
|
||
ALTER TABLE table_name
|
||
CONVERT TO CHARSET UTF8MB4 COLLATE UTF8MB4_GENERAL_CI;
|
||
```
|
||
|
||
## MySQL 5.7 升级数据库管理表结构
|
||
```bash
|
||
mysql_upgrade -u root -p
|
||
```
|
||
|
||
## MySQL 5.7 误删 root 后恢复 root 账户
|
||
- 停止 mysql 服务
|
||
```bash
|
||
systemctl stop mysqld
|
||
```
|
||
|
||
- 修改 my.cnf
|
||
```
|
||
# 添加如下一行
|
||
skip-grant-tables
|
||
```
|
||
|
||
- 启动 mysql 服务
|
||
```bash
|
||
systemctl start mysqld
|
||
```
|
||
|
||
- 重建 root 账户,并授权
|
||
```sql
|
||
insert into user
|
||
set user='root',
|
||
ssl_cipher='',
|
||
x509_issuer='',
|
||
x509_subject='';
|
||
update user
|
||
set Host='localhost',
|
||
select_priv='y',
|
||
insert_priv='y',
|
||
update_priv='y',
|
||
Alter_priv='y',
|
||
delete_priv='y',
|
||
create_priv='y',
|
||
drop_priv='y',
|
||
reload_priv='y',
|
||
shutdown_priv='y',
|
||
Process_priv='y',
|
||
file_priv='y',
|
||
grant_priv='y',
|
||
References_priv='y',
|
||
index_priv='y',
|
||
create_user_priv='y',
|
||
show_db_priv='y',
|
||
super_priv='y',
|
||
create_tmp_table_priv='y',
|
||
Lock_tables_priv='y',
|
||
execute_priv='y',
|
||
repl_slave_priv='y',
|
||
repl_client_priv='y',
|
||
create_view_priv='y',
|
||
show_view_priv='y',
|
||
create_routine_priv='y',
|
||
alter_routine_priv='y',
|
||
create_user_priv='y',
|
||
event_priv='y',
|
||
trigger_priv='y',
|
||
create_tablespace_priv='y'
|
||
where user='root';
|
||
flush privileges;
|
||
```
|
||
|
||
- 停止 mysql 服务
|
||
```bash
|
||
systemctl stop mysqld
|
||
```
|
||
|
||
- 修改 my.cnf
|
||
```
|
||
# 删除或注释刚添加的如下一行
|
||
skip-grant-tables
|
||
```
|
||
|
||
- 启动 mysql 服务,root 账户正常可用
|
||
```bash
|
||
systemctl start mysqld
|
||
```
|
||
|
||
## 通过EXPLAIN分析SQL的执行计划
|
||
- 使用
|
||
```sql
|
||
explain sql
|
||
```
|
||
|
||
- select_type 查询类型
|
||
- SIMPLE 简单表,没有表连接或子查询
|
||
- PRIMARY 最外层的查询
|
||
- UNION union语句的后置查询
|
||
- SUBQUERY 第一个子查询
|
||
- table 表/别名
|
||
- type 访问类型
|
||
- ALL 全表扫描
|
||
- index 全索引扫描
|
||
- range 索引范围扫描
|
||
- ref 非唯一索引扫描
|
||
- eq_ref 唯一索引扫描
|
||
- const,system 单表最多一个匹配行
|
||
- NULL 不需要扫描表或索引
|
||
- possible_keys 查询可能使用的索引
|
||
- key 实际使用的索引
|
||
- key_len 使用的索引字段的长度
|
||
- ref 其他匹配字段
|
||
- rows 扫描行的数量
|
||
- filtered 满足查询条件的记录占存储引擎返回记录的比例
|
||
- Extra 执行情况说明
|
||
- Using Index 全部使用索引,没有回表查询
|
||
- Using Where 有回表查询
|
||
- Using Index Condition ICP优化,直接在存储引擎完成条件过滤
|
||
- Using Flesort 依靠索引顺序达不到排序效果,需额外排序
|
||
|
||
## 统计 insert、delete、update 和 select 次数
|
||
```sql
|
||
show global status where Variable_name in
|
||
('com_insert', 'com_delete', 'com_update', 'com_select');
|
||
```
|
||
|
||
## csv 文件
|
||
- 导出
|
||
```
|
||
# Shell 终端
|
||
# mysql -e "select * from t1
|
||
into outfile '/var/lib/mysql-files/t1.csv'
|
||
fields terminated by ','
|
||
enclosed by '\"'
|
||
escaped by '\\\'
|
||
lines terminated by '\n'"
|
||
# MySQL 终端
|
||
# MySQL> select * from t1
|
||
into outfile '/var/lib/mysql-files/t1.csv'
|
||
fields terminated by ','
|
||
enclosed by '\"'
|
||
escaped by '\\'
|
||
lines terminated by '\n';
|
||
```
|
||
|
||
- 导入
|
||
```
|
||
# Shell 终端
|
||
# mysql -e "load data infile '/var/lib/mysql-files/t1.csv'
|
||
into table t1
|
||
fields terminated by ','
|
||
enclosed by '\"'
|
||
escaped by '\\\'
|
||
lines terminated by '\n'"
|
||
# MySQL 终端
|
||
# MySQL> load data infile '/var/lib/mysql-files/t1.csv'
|
||
into table t1
|
||
fields terminated by ','
|
||
enclosed by '\"'
|
||
escaped by '\\'
|
||
lines terminated by '\n';
|
||
```
|
||
|
||
## mysql8 配置登录失败 5 次锁定 5 分钟
|
||
- 安装插件
|
||
```
|
||
docker exec -ti mysql mysql -e "
|
||
install plugin CONNECTION_CONTROL soname 'connection_control.so';
|
||
install plugin CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS soname 'connection_control.so';
|
||
"
|
||
```
|
||
|
||
- 查看插件列表
|
||
```
|
||
docker exec -ti mysql mysql -e "show plugins"
|
||
# 此时会看到最后两行时新激活的插件
|
||
```
|
||
|
||
- 修改 my.cnf,增加两行
|
||
```
|
||
connection-control-failed-connections-threshold=5
|
||
connection-control-min-connection-delay=300000
|
||
```
|
||
|
||
- 重启 mysql
|
||
|