2024-06-03 14:51:39 +08:00

453 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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