Mysql实战技能全解

一、数据库原理

1 数据的分类

  • 结构化的数据:即有固定格式和有限长度的数据。例如填的表格就是结构化的数据,国籍:中华人民共和国,民族:汉,性别:男,这都叫结构化数据
  • 非结构化的数据:非结构化的数据越来越多,就是不定长、无固定格式的数据,例如: 网页,图片文件,有时候非常大,有时候很小;例如语音,视频都是非结构化的数据
  • 半结构化数据:比如:XML或者HTML的格式的数据

2 数据库的发展史

  • 萌芽阶段:文件系统

使用磁盘文件来存储数据

  • 初级阶段:第一代数据库

出现了网状模型、层次模型的数据库

  • 中级阶段:第二代数据库

关系型数据库和结构化查询语言

  • 高级阶段:新一代数据库

“关系-对象”型数据库

3 数据库管理系统

3.1 相关概念

Database:数据库是数据的汇集,它以一定的组织形式存于存储介质上
DBMS:Database Management System, 是管理数据库的系统软件,它实现数据库系统的各种功能。是数据库系统的核心
DBA:Database Administrator, 负责数据库的规划、设计、协调、维护和管理等工作
Application:应用程序,指以数据库为基础的应用程序

3.2 数据库管理系统的优点

  • 程序与数据相互独立
  • 保证数据的安全、可靠
  • 最大限度地保证数据的正确性
  • 数据可以并发使用并能同时保证一致性
  • 相互关联的数据的集合
  • 较少的数据冗余

3.2.1 RDBMS 关系型数据库

Relational Database Management System,关系模型最初由IBM公司的英国计算机科学家埃德加·科德(Edgar F. Codd)于1969年描述1974年,IBM开始开发系统R,这是一个开发RDBMS原型的研究项目。然而,第一个商业上可用的RDBMS是甲骨文,于1979年由关系软件(现为甲骨文oracle公司)发布

3.2.1.1 关系统型数据库相关概念
  • 关系Relational :关系就是二维表,其中:表中的行、列次序并不重要
  • 行row:表中的每一行,又称为一条记录record
  • 列column:表中的每一列,称为属性,字段,域field
  • 主键Primary key:PK ,一个或多个字段的组合, 用于惟一确定一个记录的字段,一张表只有一个主键, 主键字段不能为空NULL
  • 唯一键Unique key: 一个或多个字段的组合,用于惟一确定一个记录的字段,一张表可以有多个UK,而且UK字段可以为NULL
  • *域domain:属性的取值范围,如,性别只能是’男’和’女’两个值,人类的年龄只能0-150
3.2.1.2常用关系数据库
  • MySQL: MySQL, MariaDB, Percona Server
  • PostgreSQL: 简称为pgsql,EnterpriseDB
  • Oracle
  • MSSQL Server
  • DB2

数据库排行

4 关系型数据库理论

4.1 实体-联系模型E-R

4.2 联系类型

  • 一对一联系(1:1): 在表A或表B中创建一个字段﹐存储另一个表的主键值 如: 一个人只有一个身份证
  • 一对多联系(1:n):外键, 如: 部门和员工
  • 多对多联系(m:n):增加第三张表, 如: 学生和课程

4.3 数据的操作

开发工程师 CRUD (增加Create、查询Read或 Retrieve、更新Update、 删除Delete)

  • 数据提取:在数据集合中提取感兴趣的内容。SELECT
  • 数据更新:变更数据库中的数据。INSERT、DELETE、UPDATE

4.4 数据库的正规化分析

  • 数据库规范化,又称数据库或资料库的正规化、标准化,是数据库设计中的一系列原理和技术,以减少数据库中数据冗余,增进数据的一致性。关系模型的发明者埃德加·科德最早提出这一概念,并于1970年代初定义了第一范式、第二范式和第三范式的概念
  • 设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,不同的规范要求被称为不同范式,各种范式呈递次规范, 越高的范式数据库冗余越小
  • 目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴德斯科范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。满足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步满足更多规范要求的称为第二范式(2NF),其余范式以次类推。一般数据库只需满足第三范式(3NF)即可
  • 规则是死的,人是活的,所以 范式是否必须遵守,要看业务需要而定
  • 掌握范式的目的是为了在合适的场景下违反范式

4.4.1 第一范式:1NF

无重复的列,每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性,确保每一列的原子性。除去同类型的字段,就是无重复的列
说明:第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库

4.4.2 第二范式:2NF

第二范式必须先满足第一范式,属性完全依赖于主键,要求表中的每个行必须可以被唯一地区分,通常为表加上每行的唯一标识主键PK,非PK的字段需要与整个PK有直接相关性,即非PK的字段不能依赖于部分主键

4.4.3 第三范式:3NF

满足第三范式必须先满足第二范式属性,非主键属性不依赖于其它非主键属性。第三范式要求一个数据表中不包含已在其它表中已包含的非主关键字信息,非PK的字段间不能有从属关系

4.5 SQL 结构化查询语言简介

SQL:Structure Query Language,结构化查询语言是1974年由Boyce和Chamberlin提出的一个通用的、功能极强的关系性数据库语言
SQL解释器:将SQL语句解释成机器语言
数据存储协议:应用层协议,C/S

  • S:server, 监听于套接字,接收并处理客户端的应用请求
  • C:Client

客户端程序接口

  • CLI
  • GUI

应用编程接口

  • ODBC:Open Database Connectivity
  • JDBC:Java Data Base Connectivity

二、MySQL安装和基本使用

1 MySQL 介绍

1.1 MySQL系列

MySQL 的三大主要分支

  • MySQL
  • Mariadb
  • Percona Server

官方网址

  • https://www.mysql.com/
  • http://mariadb.org/
  • https://www.percona.com

官方文档

  • https://dev.mysql.com/doc/
  • https://mariadb.com/kb/en/
  • https://www.percona.com/software/mysql-database/percona-server

版本演变

  • MySQL:5.1 –> 5.5 –> 5.6 –> 5.7 –>8.0
  • MariaDB:5.1 –>5.5 –>10.0–> 10.1 –> 10.2 –> 10.3 –> 10.4 –> 10.5
  • MySQL被Sun收购后,搞了个过渡的6.0版本,没多久就下线了,后来被Oracle收购后,终于迎来了像样的5.6版本,之后就是5.7、8.0版本。由于6.0版本号已被用过,7.x系列版本专用于NDB Cluster,因而新版本号从8.0开始。

1.2 MySQL的特性

  • 开源免费
  • 插件式存储引擎:也称为”表类型”,存储管理器有多种实现版本,功能和特性可能均略有差别;用户可根据需要灵活选择,Mysql5.5.5开始 *innoDB引擎是MYSQL默认引擎
MyISAM ==> Aria
InnoDB ==> XtraDB
  • 单进程,多线程
  • 诸多扩展和新特性
  • 提供了较多测试组件

2 MySQL 安装方式介绍和快速安装

2.1 yum 安装

mysql最新源

[root@rocky01 ~]# yum install -y mysql-server
[root@rocky01 ~]# systemctl enable --now mysqld
Created symlink /etc/systemd/system/multi-user.target.wants/mysqld.service → /usr/lib/systemd/system/mysqld.service.

[root@rocky01 ~]# ss -ntl
State      Recv-Q      Send-Q           Local Address:Port            Peer Address:Port     Process
LISTEN     0           70                           *:33060                      *:*
LISTEN     0           128                          *:3306                       *:*

[root@rocky01 ~]# mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 13
Server version: 8.0.26 Source distribution

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> status

mysql>

2.2 初始化脚本提高安全性

运行脚本:[root@centos7 ~]# mysql_secure_installation

  • 设置数据库管理员root口令
  • 禁止root远程登录
  • 删除anonymous(匿名)用户帐号
  • *删除test数据库

3 MySQL 组成和常用工具

3.1 客户端程序

  • mysql: 基于mysql协议交互式或非交互式的CLI工具
  • mysqldump:备份工具,基于mysql协议向mysqld发起查询请求,并将查得的所有数据转换成insert等写操作语句保存文本文件中
  • mysqladmin:基于mysql协议管理mysqld
  • mysqlimport:数据导入工具

MyISAM存储引擎的管理工具:

  • myisamchk:检查MyISAM库
  • myisampack:打包MyISAM表,只读

3.2 服务器端程序

  • mysqld_safe
  • mysqld
  • mysqld_multi 多实例 ,示例:mysqld_multi –example

3.3 用户账号

说明:

  • HOST限制此用户可通过哪些远程主机连接mysql服务器
  • 支持使用通配符

*
% 匹配任意长度的任意字符,相当于shell中, 示例: 172.16.0.0/255.255.0.0 或 172.16.%.%
_ 匹配任意单个字符,相当于shell中?

mysql用户账号由两部分组成:

'USERNAME'@'HOST'
root@'10.0.0.100'
root@'10.0.0.%'
root@'%'

3.4 mysql 客户端命令

3.4.1 mysql 运行命令类型

  • 客户端命令:本地执行,每个命令都完整形式和简写格式
  • 服务端命令:通过mysql协议发往服务器执行并取回结果, 命令末尾都必须使用命令结束符号,默认为分号
范例:查看版本
#客户端
[root@rocky01 ~]# mysql -V
mysql  Ver 8.0.26 for Linux on x86_64 (Source distribution)

#服务端
mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 8.0.26    |
+-----------+
1 row in set (0.00 sec)

3.4.2 mysql 使用模式

  • 交互模式
  • 脚本模式:
mysql -uUSERNAME -pPASSWORD < /path/somefile.sql
cat /path/somefile.sql |mysql -uUSERNAME -pPASSWORD
mysql>source /path/from/somefile.sql

3.4.3 mysql命令使用格式

mysql [OPTIONS] [database]

mysql客户端常用选项:

  • -A, –no-auto-rehash 禁止补全
  • -u, –user= 用户名,默认为root
  • -h, –host= 服务器主机,默认为localhost
  • -p, –passowrd= 用户密码,建议使用-p,默认为空密码
  • -P, –port= 服务器端口
  • -S, –socket= 指定连接socket文件路径
  • -D, –database= 指定默认数据库
  • -C, –compress 启用压缩
  • -e “SQL” 执行SQL命令
  • -V, –version 显示版本
  • -v –verbose 显示详细信息
  • –print-defaults 获取程序默认使用的配置
范例:修改提示符
#&#x4E34;&#x65F6;&#x4FEE;&#x6539;mysql&#x63D0;&#x793A;&#x7B26;
[root@rocky01 ~]# mysql -uroot -p123456 --prompt="(\\u@\\h) [\\d]>\\_"

#&#x4E34;&#x65F6;&#x4FEE;&#x6539;mysql&#x63D0;&#x793A;&#x7B26;
[root@rocky01 ~]# export MYSQL_PS1="(\\u@\\h) [\\d]>\\_" &#xA0;

#&#x6301;&#x4E45;&#x4FEE;&#x6539;mysql&#x63D0;&#x793A;&#x7B26;
[root@rocky01 ~]# vim /etc/my.cnf
[mysql]
prompt="[\\u@\\h \\d]>\\_"
范例:配置所有MySQL 客户端的自动登录
[root@rocky01 ~]# vim /etc/my.cnf
[mysql]
user=root
password=123456

3.4.4 mysqladmin命令

mysqladmin 命令格式

mysqladmin [OPTIONS] command command....

使用范例
#&#x67E5;&#x770B;mysql&#x670D;&#x52A1;&#x662F;&#x5426;&#x6B63;&#x5E38;&#xFF0C;&#x5982;&#x679C;&#x6B63;&#x5E38;&#x63D0;&#x793A;mysqld is alive
mysqladmin -uroot -p123456 ping

#&#x5173;&#x95ED;mysql&#x670D;&#x52A1;&#xFF0C;&#x4F46;mysqladmin&#x547D;&#x4EE4;&#x65E0;&#x6CD5;&#x5F00;&#x542F;mysql
mysqladmin -uroot -p123456 shutdown

#&#x521B;&#x5EFA;&#x6570;&#x636E;&#x5E93;testdb
mysqladmin -uroot -p123456 create testdb

#&#x5220;&#x9664;&#x6570;&#x636E;&#x5E93;testdb
mysqladmin -uroot -p123456 drop testdb

#&#x4FEE;&#x6539;root&#x5BC6;&#x7801;
mysqladmin -uroot -p123456 password "654321"

#&#x65E5;&#x5FD7;&#x6EDA;&#x52A8;,&#x751F;&#x6210;&#x65B0;&#x6587;&#x4EF6;/var/lib/mysql/mariadb-bin.00000N
mysqladmin -uroot -p123456 flush-logs

3.4.5 mycli

MyCLI 是基于Python开发的MySQL的命令行工具,具有自动完成和语法突出显示功能

#CentOS8&#x5B89;&#x88C5;
[root@centos8 ~]#yum install python3-pip -y
[root@centos8 ~]#pip3 install mycli

#ubuntu&#x5B89;&#x88C5;
[root@ubuntu1804 ~]#apt -y install mycli
[root@ubuntu1804 ~]#mycli -u root -S /var/run/mysqld/mysqld.sock

Mysql实战技能全解

3.5 服务器端配置

3.5.1 服务器端配置文件

服务器端(mysqld):工作特性有多种配置方式
1、命令行选项:
2、配置文件:类ini格式,集中式的配置,能够为mysql的各应用程序提供配置信息
服务器端配置文件:

/etc/my.cnf &#xA0; #Global&#x9009;&#x9879;
/etc/mysql/my.cnf #Global&#x9009;&#x9879;
~/.my.cnf #User-specific &#x9009;&#x9879;

配置文件格式:

[mysqld]
[mysqld_safe]
[mysqld_multi]
[mysql]
[mysqladmin]
[mysqldump]
[server]
[client]
  • [client] 里面的内容可以被 mysql,mysqladmin,mysqldump 等客户端读取的,而 [mysql]里的内容只能给mysql客户端读取
  • 两者都配置了一样的参数时,遵循覆盖原则,选取最下面的
  • MySQL的客户端都是可以在命令行指定连接参数的, *如配置文件的参数错误,可直接在命令行输入该参数覆盖参数文件参数
    说明:

  • _和- 相同

  • 1,ON,TRUE意义相同
  • *0,OFF,FALSE意义相同,无区分大小写

3.5.2 socket 连接说明

服务器监听的两种 socket 地址:

  • ip socket: 监听在tcp的3306端口,支持远程通信 ,侦听3306/tcp端口可以在绑定有一个或全部接口IP上
  • unix sock: 监听在sock文件上,仅支持本机通信, 如:/var/lib/mysql/mysql.sock)

说明:host为localhost 时自动使用unix sock

范例:MySQL的端口
[root@localhost (none)]> SHOW VARIABLES LIKE 'port';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| port          | 3306  |
+---------------+-------+
1 row in set (0.01 sec)

#MySQL8.0&#x589E;&#x52A0;&#x4E86;&#x4E00;&#x4E2A;33060/tcp&#x7AEF;&#x53E3;
#Port 33060 is the default port for the MySQL Database Extended Interface (the MySQL X Protocol).&#x6269;&#x5C55;&#x63A5;&#x53E3;&#x7684;&#x7AEF;&#x53E3;
[root@localhost (none)]> SHOW VARIABLES LIKE 'mysqlx_port';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| mysqlx_port   | 33060 |
+---------------+-------+
1 row in set (0.00 sec)

3.5.3 关闭mysqld网络连接

只侦听本地客户端, 所有客户端和服务器的交互都通过一个socket文件实现,socket的配置存放在/var/lib/mysql/mysql.sock) 可在/etc/my.cnf修改

范例:

vim /etc/my.cnf
[mysqld]
skip-networking=1

4 通用二进制格式安装 MySQL

实战案例:手动安装MySQL 5.7、MySQL8.0

(1)安装相关包

[root@rocky01 ~]# yum -y install libaio numactl-libs

(2)创建用户和组

groupadd mysql
useradd -r -g mysql -s /bin/false mysql

(3)准备程序文件

#&#x5B98;&#x7F51;&#x4E0B;&#x8F7D;&#x4E8C;&#x8FDB;&#x5236;&#x5305;
https://dev.mysql.com/downloads/mysql/

[root@rocky01 ~]# tar xf mysql-8.0.31-linux-glibc2.12-x86_64.tar.xz -C /usr/local
[root@rocky01 ~]# ln -s /usr/local/mysql-8.0.31-linux-glibc2.12-x86_64/ mysql
[root@rocky01 ~]# chown -R root:root /usr/local/mysql/

(5)准备环境变量

[root@rocky01 ~]# echo 'PATH=/usr/local/mysql/bin:$PATH' > /etc/profile.d/mysql.sh
[root@rocky01 ~]# . /etc/profile.d/mysql.sh

(6)准备配置文件

[root@rocky01 ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
skip_name_resolve=1
socket=/data/mysql/mysql.sock &#xA0; &#xA0; &#xA0; &#xA0;
log-error=/data/mysql/mysql.log
pid-file=/data/mysql/mysql.pid
[client]
socket=/data/mysql/mysql.sock

(7) 初始化数据库文件并提取 root 密码

#/data/mysql &#x4F1A;&#x81EA;&#x52A8;&#x751F;&#x6210;,&#x4F46;&#x662F;/data/&#x5FC5;&#x987B;&#x4E8B;&#x5148;&#x5B58;&#x5728;
[root@rocky01 ~]# mkdir -pv /data/mysql

方式 1: 生成随机密码

[root@rocky01 ~]# mysqld --initialize --user=mysql --datadir=/data/mysql
[root@rocky01 ~]# grep password /data/mysql/mysql.log
2022-10-23T13:54:58.508775Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: L!fdbgQpH2AQ

#&#x8FD9;&#x540E;&#x9762;&#x4E3A;&#x751F;&#x6210;&#x7684;&#x968F;&#x673A;&#x5BC6;&#x7801;
#&#x5BC6;&#x7801;L!fdbgQpH2AQ

方式 2: 生成 root 空密码

mysqld --initialize-insecure --user=mysql --datadir=/data/mysql

(8)准备服务脚本和启动

[root@rocky01 ~]# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
[root@rocky01 ~]# chkconfig --add mysqld
[root@rocky01 ~]# service mysqld start
Starting MySQL.. SUCCESS!

(9)修改口令

#&#x4FEE;&#x6539;&#x524D;&#x9762;&#x751F;&#x6210;&#x7684;&#x968F;&#x673A;&#x5BC6;&#x7801;&#x4E3A;&#x6307;&#x5B9A;&#x5BC6;&#x7801;
[root@rocky01 ~]# mysqladmin -uroot -p'L!fdbgQpH2AQ' password 123456
mysqladmin: [Warning] Using a password on the command line interface can be insecure.

Warning: Since password will be sent to server in plain text, use ssl connection to ensure password safety.

#&#x4FEE;&#x6539;&#x524D;&#x9762;&#x751F;&#x6210;&#x7684;&#x7A7A;&#x5BC6;&#x7801;&#x4E3A;&#x6307;&#x5B9A;&#x5BC6;&#x7801;
mysqladmin -uroot password 123456

(10)测试登录

[root@rocky01 ~]# mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 8
Server version: 8.0.31 MySQL Community Server - GPL
...&#x7701;&#x7565;..

#&#x6CE8;&#xFF1A;&#x82E5;&#x62A5;&#x5982;&#x4E0B;&#x9519;&#x8BEF;&#xFF0C;&#x8BF7;&#x6267;&#x884C;&#x4E0B;&#x9762;&#x547D;&#x4EE4;
[root@rocky01 ~]# mysql -uroot -p123456
mysql: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory
[root@rocky01 ~]# ln -s /usr/lib64/libtinfo.so.6.1 /usr/lib64/libtinfo.so.5

实战案例:一键安装MySQL5.7、MySQL8.0脚本

#bin/bash
#https://dev.mysql.com/downloads/mysql/

. /etc/init.d/functions
SRC_DIR=pwd

MYSQL='mysql-8.0.31-linux-glibc2.12-x86_64.tar.xz'
#MYSQL='mysql-8.0.23-linux-glibc2.12-x86_64.tar.xz'
MYSQL_ROOT_PASSWORD=123456

COLOR='echo -e \E[01;31m'
END='\E[0m'

check (){

if [ $UID -ne 0 ]; then
  action "&#x5F53;&#x524D;&#x7528;&#x6237;&#x4E0D;&#x662F;root,&#x5B89;&#x88C5;&#x5931;&#x8D25;" false
  exit 1
fi

cd  $SRC_DIR

if [ !  -e $MYSQL ];then
        $COLOR"&#x7F3A;&#x5C11;${MYSQL}&#x6587;&#x4EF6;"$END
        $COLOR"&#x8BF7;&#x5C06;&#x76F8;&#x5173;&#x8F6F;&#x4EF6;&#x653E;&#x5728;${SRC_DIR}&#x76EE;&#x5F55;&#x4E0B;"$END
        exit
elif [ -e /usr/local/mysql ];then
        action "&#x6570;&#x636E;&#x5E93;&#x5DF2;&#x5B58;&#x5728;&#xFF0C;&#x5B89;&#x88C5;&#x5931;&#x8D25;" false
        exit
else
    return
fi
}

install_mysql(){
    $COLOR"&#x5F00;&#x59CB;&#x5B89;&#x88C5;MySQL&#x6570;&#x636E;&#x5E93;..."$END
    yum  -y -q install libaio numactl-libs
    tar xf $MYSQL -C /usr/local/
    MYSQL_DIR=echo $MYSQL| sed -nr 's/^(.*[0-9]).*/\1/p'
    ln -s  /usr/local/$MYSQL_DIR /usr/local/mysql
    chown -R  root.root /usr/local/mysql/
    id mysql &> /dev/null || { useradd -s /sbin/nologin -r  mysql ; action "&#x521B;&#x5EFA;mysql&#x7528;&#x6237;"; }

    echo 'PATH=/usr/local/mysql/bin/:$PATH' > /etc/profile.d/mysql.sh
    .  /etc/profile.d/mysql.sh
    ln -s /usr/local/mysql/bin/* /usr/bin/
    cat > /etc/my.cnf <<-eof 0 [mysqld] server-id="hostname" -i|cut -d. -f4 log-bin datadir="/data/mysql" socket="/data/mysql/mysql.sock" log-error="/data/mysql/mysql.log" pid-file="/data/mysql/mysql.pid" [client] eof [ -d data ] || mkdir mysqld --initialize-insecure --user="mysql" --datadir="/data/mysql" cp usr local mysql support-files mysql.server etc init.d chkconfig --add on service start $? -ne && { $color"数据库启动失败,退出!"$end;exit; } #mysql_oldpassword="awk" ' a temporary password {print $nf}' mysql.log #mysqladmin -uroot -p$mysql_oldpassword $mysql_root_password &>/dev/null
    sleep 3
    mysqladmin  -uroot  password $MYSQL_ROOT_PASSWORD &>/dev/null
    action "&#x6570;&#x636E;&#x5E93;&#x5B89;&#x88C5;&#x5B8C;&#x6210;"
}

check

install_mysql</-eof>

三、SQL 语言

1 关系型数据库的常见组件

  • 数据库:database 表的集合,物理上表现为一个目录
  • 表:table,行:row 列:column
  • 索引:index
  • 视图:view,虚拟的表
  • 存储过程:procedure
  • 存储函数:function
  • 触发器:trigger
  • 事件调度器:event scheduler,任务计划
  • 用户:user
  • 权限:privilege

2 SQL 语法标准

2.1 SQL 语言规范

  • 在数据库系统中,SQL 语句不区分大小写,建议用大写
  • SQL语句可单行或多行书写,默认以 ” ; ” 结尾
  • 关键词不能跨多行或简写
  • 用空格和TAB 缩进来提高语句的可读性
  • 子句通常位于独立行,便于编辑,提高可读性

注释:

  • SQL标准:
#&#x5355;&#x884C;&#x6CE8;&#x91CA;&#xFF0C;&#x6CE8;&#x610F;&#x6709;&#x7A7A;&#x683C;
-- &#x6CE8;&#x91CA;&#x5185;&#x5BB9; &#xA0;

#&#x591A;&#x884C;&#x6CE8;&#x91CA;
/*&#x6CE8;&#x91CA;&#x5185;&#x5BB9;
&#x6CE8;&#x91CA;&#x5185;&#x5BB9;
&#x6CE8;&#x91CA;&#x5185;&#x5BB9;*/ &#xA0;
  • MySQL注释:
&#x6CE8;&#x91CA;&#x5185;&#x5BB9;

2.2 数据库对象和命名

数据库的组件 ( 对象 )

  • 数据库、表、索引、视图、用户、存储过程、函数、触发器、事件调度器等

命名规则:

  • 必须以字母开头,后续可以包括字母,数字和三个特殊字符(# _ $)
  • 不要使用MySQ

2.3 SQL语句分类

  • DDL: Data Defination Language 数据定义语言*
    CREATE,DROP,ALTER**

  • DML: Data Manipulation Language 数据操纵语言*
    INSERT,DELETE,UPDATE**
    软件开发:CRUD

  • DQL:Data Query Language 数据查询语言*
    SELECT**

  • DCL:Data Control Language 数据控制语言

GRANT,REVOKE

  • TCL:Transaction Control Language 事务控制语言

COMMIT,ROLLBACK,SAVEPOINT

2.4 SQL语句构成

关健字Keyword组成子句clause,多条clause组成语句

示例:一组SQL语句由三个子句构成,SELECT,FROM和WHERE是关键字

SELECT * &#xA0; &#xA0; &#xA0; &#xA0; #SELECT&#x5B50;&#x53E5;
FROM products &#xA0;  #FROM&#x5B50;&#x53E5;
WHERE price>666  #WHERE&#x5B50;&#x53E5;

范例:查看SQL帮助

[root@localhost (none)]> help contents
You asked for help about help category: "Contents"
For more information, type 'help <item>', where <item> is one of the following
categories:
   Account Management
   Administration
   Components
   Compound Statements
   Contents
   Data Definition
   Data Manipulation
   Data Types
...&#x7701;&#x7565;...</item></item>

2.5 字符集和排序

早期MySQL版本默认为 latin1,从MySQL8.0开始默认字符集已经为 utf8mb4

查看支持所有字符集

SHOW CHARACTER SET;
SHOW CHARSET;

查看当前使用的字符集

SHOW VARIABLES LIKE '%char%';

查看支持所有排序规则

SHOW COLLATION;
#&#x6CE8;&#x610F;
utf8_general_ci&#x4E0D;&#x533A;&#x5206;&#x5927;&#x5C0F;&#x5199;
utf8_bin &#x533A;&#x5206;&#x5927;&#x5C0F;&#x5199;

查看当前使用的排序规则

SHOW VARIABLES LIKE 'collation%';

设置服务器默认的字符集

vim /etc/my.cnf
[mysqld]
character-set-server=utf8mb4

设置客户端默认的字符集

vim /etc/my.cnf
#&#x9488;&#x5BF9;mysql&#x5BA2;&#x6237;&#x7AEF;
[mysql]
default-character-set=utf8mb4
#&#x9488;&#x5BF9;&#x6240;&#x6709;MySQL&#x5BA2;&#x6237;&#x7AEF;
[client]
default-character-set=utf8mb4

3 管理数据库

3.1 创建数据库

CREATE DATABASE|SCHEMA [IF NOT EXISTS] 'DB_NAME'
CHARACTER SET 'character set name'
COLLATE 'collate name';

#Mysql&#x4E2D;DATABASE&#x548C;SCHEMA&#x662F;&#x7B49;&#x4EF7;&#x7684;

范例:常见用法

#&#x521B;&#x5EFA;&#x6570;&#x636E;&#x5E93;
[root@localhost (none)]> create database IF NOT EXISTS db1;
Query OK, 1 row affected (0.00 sec)

#&#x663E;&#x793A;&#x521B;&#x5EFA;&#x6570;&#x636E;&#x5E93;&#x7684;&#x8BED;&#x53E5;
[root@localhost (none)]> show create database db1;
+----------+-------------------------------------------------------------------------------------------------------------------------------+
| Database | Create Database                       |
+----------+-------------------------------------------------------------------------------------------------------------------------------+
| db1      | CREATE DATABASE db1 /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */ |
+----------+-------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

#&#x663E;&#x793A;warnings
[root@localhost (none)]> show warnings;
Empty set (0.00 sec)

#&#x521B;&#x5EFA;&#x6570;&#x636E;&#x5E93;
[root@localhost (none)]> create database IF NOT EXISTS db1;
Query OK, 1 row affected, 1 warning (0.00 sec)

#&#x663E;&#x793A;warnings
[root@localhost (none)]> show warnings;
+-------+------+----------------------------------------------+
| Level | Code | Message                                      |
+-------+------+----------------------------------------------+
| Note  | 1007 | Can't create database 'db1'; database exists |
+-------+------+----------------------------------------------+
1 row in set (0.00 sec)

范例:指定字符集创建数据库

#&#x6307;&#x5B9A;&#x5B57;&#x7B26;&#x96C6;
[root@localhost (none)]> create database IF NOT EXISTS db2 CHARACTER SET 'utf8';
Query OK, 1 row affected, 1 warning (0.00 sec)

#&#x7B80;&#x5199;
create database db2 charset=utf8;

#&#x6307;&#x5B9A;&#x5B57;&#x7B26;&#x96C6;&#x548C;&#x6392;&#x5E8F;&#x89C4;&#x5219;&#xFF08;utf8_bin&#x4E3A;&#x533A;&#x5206;&#x5927;&#x5C0F;&#x5199;&#xFF09;
[root@localhost (none)]> create database zabbix character set utf8 collate utf8_bin;

3.2 修改数据库

ALTER DATABASE DB_NAME character set utf8;

范例:使用方法

#&#x6539;&#x53D8;&#x6570;&#x636E;&#x5E93;&#x7684;&#x5B57;&#x7B26;&#x96C6;&#x548C;&#x6392;&#x5E8F;&#x89C4;&#x5219;
[root@localhost (none)]>  ALTER DATABASE db1 character set utf8 COLLATE utf8_bin;
Query OK, 1 row affected, 2 warnings (0.00 sec)

3.3 删除数据库

DROP DATABASE|SCHEMA [IF EXISTS] 'DB_NAME';

范例:使用方法

[root@localhost (none)]> drop database db1;
Query OK, 0 rows affected (0.00 sec)

[root@rocky01 ~]# ls -l /var/lib/mysql |grep ^d
drwxr-x--- 2 mysql mysql      187 Oct 24 00:29 #innodb_temp
drwxr-x--- 2 mysql mysql      143 Oct 23 15:38 mysql
drwxr-x--- 2 mysql mysql     8192 Oct 23 15:38 performance_schema
drwxr-x--- 2 mysql mysql       28 Oct 23 15:38 sys

3.4 查看数据库列表

SHOW DATABASES;

范例:

[root@localhost (none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

4 数据类型

数据类型

  • 数据长什么样
  • 数据需要多少空间来存放

数据类型

  • 系统内置数据类型
  • 用户定义数据类型

MySQL 支持多种内置数据类型

  • 数值类型
  • 日期/时间类型
  • 字符串(字符)类型

Mysql实战技能全解

选择正确的数据类型对于获得高性能至关重要,三大原则:

  1. 更小的通常更好,尽量使用可正确存储数据的最小数据类型
  2. 简单就好,简单数据类型的操作通常需要更少的CPU周期
  3. 尽量避免NULL,包含为NULL的列,对MySQL更难优化

4.1 整数型

  • tinyint(m) 1个字节 范围(-128~127)
  • smallint(m) 2个字节 范围(-32768~32767)
  • mediumint(m) 3个字节 范围(-8388608~8388607)
  • int(m) 4个字节 范围(-2147483648~2147483647)
  • bigint(m) 8个字节 范围(+-9.22*10的18次方)

上述数据类型,如果加修饰符unsigned(取消负数,全是正数)后,则最大值翻倍
如:tinyint unsigned的取值范围为(0~255)
int(m)里的m是表示SELECT查询结果集中的显示宽度,并不影响实际的取值范围,规定了MySQL的一些交互工具(例如MySQL命令行客户端)用来显示字符的个数。对于存储和计算来说,Int(1)和Int(20)是相同的
BOOL,BOOLEAN:布尔型,是TINYINT(1)的同义词。zero值被视为假,非zero值视为真

4.2 浮点型(float和double),近似值

float(m,d) 单精度浮点型 8位精度(4字节) m总个数,d小数位, 注意: 小数点不占用总个数
double(m,d) 双精度浮点型16位精度(8字节) m总个数,d小数位, 注意: 小数点不占用总个数
设一个字段定义为float(6,3),如果插入一个数123.45678,实际数据库里存的是123.457,但总个数还以实际为准,即6位

4.3 定点数

4.4 字符串(char,varchar,text)

  • char(n) 固定长度,最多255个字符,注意不是字节
  • varchar(n) 可变长度,最多65535个字符
  • tinytext 可变长度,最多255个字符
  • text 可变长度,最多65535个字符
  • mediumtext 可变长度,最多2的24次方-1个字符
  • longtext 可变长度,最多2的32次方-1个字符
  • BINARY(M) 固定长度,可存二进制或字符,长度为0-M字节
  • VARBINARY(M) 可变长度,可存二进制或字符,允许长度为0-M字节
  • 内建类型:ENUM枚举, SET集合

char类型的字符串检索速度要比varchar类型的快
varchar查询速度快于text

char varchar 的比较:

面试题: VARCHAR(50) 能存放几个 UTF8 编码的汉字?

存放的汉字个数与版本相关。

  • mysql 4.0以下版本,varchar(50) 指的是 50 字节,如果存放 UTF8 格式编码的汉字时(每个汉字3字节),只能存放16 个。
  • mysql 5.0以上版本,varchar(50) 指的是 50 字符,无论存放的是数字、字母还是 UTF8 编码的汉字,都可以存放 50 个。

4.5 二进制数据BLOB

BLOB和text存储方式不同,TEXT以文本方式存储,英文存储区分大小写,而Blob以二进制方式存储,不分大小写
BLOB存储的数据只能整体读出
TEXT可以指定字符集,BLOB不用指定字符集

4.6 日期时间类型

date 日期 ‘2008-12-2′
time 时间 ’12:25:36’
datetime 日期时间 ‘2008-12-2 22:06:44’
timestamp 自动存储记录修改时间
YEAR(2), YEAR(4):年份
timestamp 此字段里的时间数据会随其他字段修改的时候自动刷新,这个数据类型的字段可以存放这条记录最后被修改的时间

4.7 修饰符

适用所有类型的修饰符:

  • NULL 数据列可包含NULL值,默认值
  • NOT NULL 数据列不允许包含NULL值,相当于网站注册表中的 * 为必填选项
  • DEFAULT 默认值
  • PRIMARY KEY 主键,所有记录中此字段的值不能重复,且不能为NULL
  • UNIQUE KEY 唯一键,所有记录中此字段的值不能重复,但可以为NULL
  • CHARACTER SET name 指定一个字符集

适用数值型的修饰符:

  • AUTO_INCREMENT 自动递增,适用于整数类型, 必须作用于某个 key 的字段,比如primary key
  • UNSIGNED 无符号

5 DDL 语句

5.1 create 创建表

(1) 直接创建

CREATE TABLE [IF NOT EXISTS] 'tbl_name' (col1 type1 &#x4FEE;&#x9970;&#x7B26;, col2 type2 &#x4FEE;&#x9970;&#x7B26;, ...)
#&#x5B57;&#x6BB5;&#x4FE1;&#x606F;
col type1
PRIMARY KEY(col1,...)
INDEX(col1, ...)
UNIQUE KEY(col1, ...)
#&#x8868;&#x9009;&#x9879;&#xFF1A;
ENGINE [=] engine_name
ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}

注意:

  • Storage Engine是指表类型,也即在表创建时指明其使用的存储引擎
  • 同一库中不同表可以使用不同的存储引擎
  • 同一个库中表建议要使用同一种存储引擎类型
范例:用法
#&#x76F4;&#x63A5;&#x521B;&#x5EFA;&#x8868;
[root@localhost zabbix]> create table student (
    -> id tinyint unsigned primary key auto_increment ,
    -> name char(4) not null,
    -> gender char(1),
    -> age tinyint unsigned  );
Query OK, 0 rows affected (0.01 sec)

(2) 通过查询现存表创建

新表会被直接插入查询而来的数据

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)] [table_options] [partition_options] select_statement
范例:用法
[root@localhost zabbix]> create table userhost select user,host from mysql.user;
Query OK, 4 rows affected (0.01 sec)
Records: 4  Duplicates: 0  Warnings: 0

(3) 通过复制现存的表的表结构创建

不复制数据

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name { LIKE old_tbl_name | (LIKE old_tbl_name) }
范例:用法
[root@localhost zabbix]> create table user like student;
Query OK, 0 rows affected (0.01 sec)

5.2 show 表查看

查看表

SHOW TABLES [FROM db_name]

查看表创建命令

SHOW CREATE TABLE tbl_name

查看表结构

#&#x5E38;&#x7528;
DESC [db_name.]tb_name

#&#x6BD4;&#x8F83;&#x5C11;&#x7528;
SHOW COLUMNS FROM [db_name.]tb_name

查看表状态

#&#x663E;&#x793A;&#x6307;&#x5B9A;&#x8868;&#x7684;&#x72B6;&#x6001;
SHOW TABLE STATUS LIKE 'tbl_name'\G

#&#x67E5;&#x770B;&#x5E93;&#x4E2D;&#x6240;&#x6709;&#x8868;&#x72B6;&#x6001;
SHOW TABLE STATUS FROM db_name

查看支持的engine类型

SHOW ENGINES;
范例:用法
#&#x67E5;&#x770B;&#x8868;&#x521B;&#x5EFA;&#x547D;&#x4EE4;
[root@localhost zabbix]> show create table student;
+---------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table   | Create Table                                         |
+---------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| student | CREATE TABLE student (
  id tinyint unsigned NOT NULL AUTO_INCREMENT,
  name char(4) NOT NULL,
  gender char(1) DEFAULT NULL,
  age tinyint unsigned DEFAULT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+---------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

#&#x67E5;&#x770B;&#x8868;&#x7ED3;&#x6784;
[root@localhost zabbix]> desc student;
+--------+------------------+------+-----+---------+----------------+
| Field  | Type             | Null | Key | Default | Extra          |
+--------+------------------+------+-----+---------+----------------+
| id     | tinyint unsigned | NO   | PRI | NULL    | auto_increment |
| name   | char(4)          | NO   |     | NULL    |                |
| gender | char(1)          | YES  |     | NULL    |                |
| age    | tinyint unsigned | YES  |     | NULL    |                |
+--------+------------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

#&#x663E;&#x793A;&#x8868;&#x7684;&#x4FE1;&#x606F;
[root@localhost zabbix]> select * from student;
Empty set (0.00 sec)

#&#x67E5;&#x770B;&#x8868;&#x72B6;&#x6001;
[root@localhost zabbix]> SHOW TABLE STATUS LIKE 'student'\G
*************************** 1. row ***************************
           Name: student
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 0
 Avg_row_length: 0
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: 1
    Create_time: 2022-10-24 19:30:14
    Update_time: NULL
     Check_time: NULL
      Collation: utf8mb4_0900_ai_ci
       Checksum: NULL
 Create_options:
        Comment:
1 row in set (0.00 sec)

5.3 修改和删除表

alter 修改表

ALTER TABLE 'tbl_name'
#&#x5B57;&#x6BB5;&#xFF1A;
#&#x6DFB;&#x52A0;&#x5B57;&#x6BB5;&#xFF1A;add
ADD col1 data_type [FIRST|AFTER col_name]
#&#x5220;&#x9664;&#x5B57;&#x6BB5;&#xFF1A;drop
#&#x4FEE;&#x6539;&#x5B57;&#x6BB5;&#xFF1A;
alter&#xFF08;&#x9ED8;&#x8BA4;&#x503C;&#xFF09;, change&#xFF08;&#x5B57;&#x6BB5;&#x540D;&#xFF09;, modify&#xFF08;&#x5B57;&#x6BB5;&#x5C5E;&#x6027;&#xFF09;

drop 删除表

DROP TABLE [IF EXISTS] 'tbl_name';

6 DML 语句

DML: INSERT, DELETE, UPDATE

6.1 INSERT 语句

功能:一次插入一行或多行数据

#&#x65B9;&#x6CD5;&#x4E00;
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
 &#xA0; &#xA0;[INTO] tbl_name [(col_name,...)]
 &#xA0; &#xA0;{VALUES | VALUE} ({expr | DEFAULT},...),(...),...

 &#xA0; &#xA0;[ ON DUPLICATE KEY UPDATE #&#x5982;&#x679C;&#x91CD;&#x590D;&#x66F4;&#x65B0;&#x4E4B;
 &#xA0; &#xA0; col_name=expr
 &#xA0; &#xA0; &#xA0; &#xA0;[, col_name=expr] ... ]

#&#x65B9;&#x6CD5;&#x4E8C;
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
 &#xA0; &#xA0;[INTO] tbl_name
 &#xA0; &#xA0;SET col_name={expr | DEFAULT}, ...

 &#xA0; &#xA0;[ ON DUPLICATE KEY UPDATE
 &#xA0; &#xA0; col_name=expr
 &#xA0; &#xA0; &#xA0; &#xA0;[, col_name=expr] ... ]

#&#x65B9;&#x6CD5;&#x4E09;
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
 &#xA0; &#xA0;[INTO] tbl_name [(col_name,...)]
 &#xA0; &#xA0;SELECT ...

 &#xA0; &#xA0;[ ON DUPLICATE KEY UPDATE
 &#xA0; &#xA0; col_name=expr
 &#xA0; &#xA0; &#xA0; &#xA0;[, col_name=expr] ... ]

简化写法:

INSERT tbl_name [(col1,...)] VALUES (val1,...), (val21,...)

范例:用法

#&#x6CE8;&#xFF1A;&#x4EE5;&#x4E0B;&#x547D;&#x4EE4;&#x7684;into&#x90FD;&#x53EF;&#x7701;&#x7565;
#&#x65B9;&#x6CD5;&#x4E00;&#xFF1A;&#x63D2;&#x5165;&#x4E00;&#x6761;
[root@localhost zabbix]> insert into student (id,name,gender,age) values(1,'Rye','M',20);
Query OK, 1 row affected (0.00 sec)

#&#x65B9;&#x6CD5;&#x4E00;&#xFF1A;&#x5168;&#x90E8;&#x5B57;&#x6BB5;&#x90FD;&#x9700;&#x8981;&#x8D4B;&#x503C;&#x65F6;&#x53EF;&#x7701;&#x7565;&#x4E0D;&#x5199;
[root@localhost zabbix]> insert student values(1,'Rye','M',20);
Query OK, 1 row affected (0.00 sec)

#&#x65B9;&#x6CD5;&#x4E00;&#xFF1A;&#x63D2;&#x5165;&#x591A;&#x6761;
[root@localhost zabbix]> insert into student (name,gender,age) values('Rye2','M',21),('Rye3','M',22);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

#&#x65B9;&#x6CD5;&#x4E8C;&#xFF1A;&#x63D2;&#x5165;&#x4E00;&#x6761;
[root@localhost zabbix]> insert into student set name='Rye4',gender='F';
Query OK, 1 row affected (0.00 sec)

#&#x65B9;&#x6CD5;&#x4E09;&#xFF1A;&#x590D;&#x5236;&#x8868;&#x6570;&#x636E;&#xFF0C;&#x524D;&#x63D0;&#x8868;&#x7ED3;&#x6784;&#x4E00;&#x81F4;
[root@localhost zabbix]> insert user select * from student;
Query OK, 4 rows affected (0.01 sec)
Records: 4  Duplicates: 0  Warnings: 0

#&#x7EFC;&#x4E0A;&#xFF0C;&#x67E5;&#x770B;
[root@localhost zabbix]> select * from student;
+----+------+--------+------+
| id | name | gender | age  |
+----+------+--------+------+
|  1 | Rye  | M      |   20 |
|  2 | Rye2 | M      |   21 |
|  3 | Rye3 | M      |   22 |
|  4 | Rye4 | F      | NULL |
+----+------+--------+------+
4 rows in set (0.00 sec)

6.2 UPDATE 语句

语法:

UPDATE [LOW_PRIORITY] [IGNORE] table_reference
 &#xA0; &#xA0;SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...

 &#xA0; &#xA0;[WHERE where_condition]
 &#xA0; &#xA0;[ORDER BY ...]
 &#xA0; &#xA0;[LIMIT row_count]

注意:一定要有限制条件,否则将修改所有行的指定字段

范例:用法

#&#x7528;&#x6CD5;
[root@localhost zabbix]> update student set age=23 where id=4;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

#&#x67E5;&#x770B;
[root@localhost zabbix]> select * from student;
+----+------+--------+------+
| id | name | gender | age  |
+----+------+--------+------+
|  1 | Rye  | M      |   20 |
|  2 | Rye2 | M      |   21 |
|  3 | Rye3 | M      |   22 |
|  4 | Rye4 | M      |   23 |
+----+------+--------+------+
4 rows in set (0.00 sec)

6.3 DELETE 语句

删除表中数据,但不会自动缩减数据文件的大小。
语法:

DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name
 &#xA0; &#xA0;[WHERE where_condition]
 &#xA0; &#xA0;[ORDER BY ...]
 &#xA0; &#xA0;[LIMIT row_count]
#&#x53EF;&#x5148;&#x6392;&#x5E8F;&#x518D;&#x6307;&#x5B9A;&#x5220;&#x9664;&#x7684;&#x884C;&#x6570;

注意:一定要有限制条件,否则将清空表中的所有数据
可利用mysql 选项避免此错误:

#&#x65B9;&#x6CD5;&#x4E00;
#&#x767B;&#x9646;&#x65F6;&#x52A0;&#x5982;&#x4E0B;&#x53C2;&#x6570;&#xFF08;&#x9009;&#x4E00;&#x4E2A;&#x5373;&#x53EF;&#xFF09;
mysql -U
mysql --safe-updates
mysql --i-am-a-dummy

#&#x65B9;&#x6CD5;&#x4E8C;
[root@rocky01 ~]# vim /etc/my.cnf
[mysql]
safe-updates

如果想清空表,保留表结构,也可以使用下面语句,此语句会自动缩减数据文件的大小。

TRUNCATE TABLE tbl_name;

缩减表大小

OPTIMIZE TABLE tb_name

范例:用法

#&#x7528;&#x6CD5;
[root@localhost zabbix]> delete from student where age>=21;
Query OK, 0 rows affected (0.00 sec)

#&#x67E5;&#x770B;
[root@localhost zabbix]> select * from student;
+----+------+--------+------+
| id | name | gender | age  |
+----+------+--------+------+
|  1 | Rye  | M      |   20 |
+----+------+--------+------+
1 row in set (0.00 sec)

7 DQL 语句(select)

Mysql实战技能全解

7.1 单表操作

语法:

SELECT
 [ALL | DISTINCT | DISTINCTROW ]
 [SQL_CACHE | SQL_NO_CACHE]
 select_expr [, select_expr ...]
 &#xA0; &#xA0;[FROM table_references
 &#xA0; &#xA0;[WHERE where_condition]
 &#xA0; &#xA0;[GROUP BY {col_name | expr | position}
 &#xA0; &#xA0; &#xA0;[ASC | DESC], ... [WITH ROLLUP]]
 &#xA0; &#xA0;[HAVING where_condition]
 &#xA0; &#xA0;[ORDER BY {col_name | expr | position}
 &#xA0; &#xA0; &#xA0;[ASC | DESC], ...]
 &#xA0; &#xA0;[LIMIT {[offset,] row_count | row_count OFFSET offset}]
 &#xA0; &#xA0;[FOR UPDATE | LOCK IN SHARE MODE]

说明:

  • 字段显示可以使用别名:

*
– col1 AS alias1, col2 AS alias2, …

  • WHERE子句:指明过滤条件以实现”选择”的功能:

*
– 过滤条件:布尔型表达式
– 算术操作符:+, -, *, /, %
– 比较操作符:=,

  • *GROUP BY:根据指定的条件把查询结果进行”分组”以用于做”聚合”运算

*
常见聚合函数: count(), sum(), max(), min(), avg(),注意:聚合函数不对null统计
HAVING: 对分组聚合运算后的结果指定过滤条件
– *一旦分组 group by ,select语句后只跟分组的字段,聚合函数

  • *ORDER BY: 根据指定的字段对查询结果进行排序

*
升序:ASC
– *降序:DESC

  • LIMIT [[offset,]row_count]:对查询的结果进行输出行数数量限制,跳过offset,显示row_count行,offset默为值为0
  • 对查询结果中的数据请求施加”锁”

*
– FOR UPDATE: 写锁,独占或排它锁,只有一个读和写操作
– LOCK IN SHARE MODE: 读锁,共享锁,同时多个读操作

范例:字段别名

MariaDB [hellodb]> select stuid &#x5B66;&#x5458;ID,name as &#x59D3;&#x540D;,gender &#x6027;&#x522B; from students;
+----------+---------------+--------+
| &#x5B66;&#x5458;ID &#xA0; | &#x59D3;&#x540D; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;| &#x6027;&#x522B; &#xA0; |
+----------+---------------+--------+
| &#xA0; &#xA0; &#xA0; &#xA0;1 | Shi Zhongyu &#xA0; | M &#xA0; &#xA0; &#xA0;|
| &#xA0; &#xA0; &#xA0; &#xA0;2 | Shi Potian &#xA0; &#xA0;| M &#xA0; &#xA0; &#xA0;|
| &#xA0; &#xA0; &#xA0; &#xA0;3 | Xie Yanke &#xA0; &#xA0; | M &#xA0; &#xA0; &#xA0;|
| &#xA0; &#xA0; &#xA0; &#xA0;4 | Ding Dian &#xA0; &#xA0; | M &#xA0; &#xA0; &#xA0;|
| &#xA0; &#xA0; &#xA0; &#xA0;5 | Yu Yutong &#xA0; &#xA0; | M &#xA0; &#xA0; &#xA0;|

范例:判断是否为NULL

MariaDB [hellodb]> select * from students where classid is null;
+-------+-------------+-----+--------+---------+-----------+
| StuID | Name &#xA0; &#xA0; &#xA0; &#xA0;| Age | Gender | ClassID | TeacherID |
+-------+-------------+-----+--------+---------+-----------+
| &#xA0; &#xA0;24 | Xu Xian &#xA0; &#xA0; | &#xA0;27 | M &#xA0; &#xA0; &#xA0;| &#xA0; &#xA0;NULL | &#xA0; &#xA0; &#xA0;NULL |
| &#xA0; &#xA0;25 | Sun Dasheng | 100 | M &#xA0; &#xA0; &#xA0;| &#xA0; &#xA0;NULL | &#xA0; &#xA0; &#xA0;NULL |
+-------+-------------+-----+--------+---------+-----------+
2 rows in set (0.002 sec)

MariaDB [hellodb]> select * from students where classid is not null;

范例:去重

MariaDB [hellodb]> select distinct gender from students ;
+--------+
| gender |
+--------+
| M &#xA0; &#xA0; &#xA0;|
| F &#xA0; &#xA0; &#xA0;|
+--------+
2 rows in set (0.001 sec)

#&#x5C06;age&#x548C;gender&#x591A;&#x4E2A;&#x5B57;&#x6BB5;&#x91CD;&#x590D;&#x7684;&#x8BB0;&#x5F55;&#x53BB;&#x91CD;
MariaDB [hellodb]> select distinct age,gender from students;

范例:SQL 注入攻击

select * from user where name='admin' and password='' or '1'='1';
select * from user where name='admin' and password='' or '1=1';
select * from user where name='admin'; -- ' and password='123';
select * from user where name='admin'; # ' and password='123';

范例:分页查询

#&#x53EA;&#x53D6;&#x524D;3&#x4E2A;
mysql> select * from students limit 0,3;
mysql> select * from students limit 3;
+-------+-------------+-----+--------+---------+-----------+
| StuID | Name &#xA0; &#xA0; &#xA0; | Age | Gender | ClassID | TeacherID |
+-------+-------------+-----+--------+---------+-----------+
| &#xA0; &#xA0; 1 | Shi Zhongyu | &#xA0;22 | M &#xA0; &#xA0; | &#xA0; &#xA0; &#xA0; 2 | &#xA0; &#xA0; &#xA0; &#xA0; 3 |
| &#xA0; &#xA0; 2 | Shi Potian | &#xA0;22 | M &#xA0; &#xA0; | &#xA0; &#xA0; &#xA0; 1 | &#xA0; &#xA0; &#xA0; &#xA0; 7 |
| &#xA0; &#xA0; 3 | Xie Yanke &#xA0; | &#xA0;53 | M &#xA0; &#xA0; | &#xA0; &#xA0; &#xA0; 2 | &#xA0; &#xA0; &#xA0; &#xA0;16 |
+-------+-------------+-----+--------+---------+-----------+
3 rows in set (0.00 sec)

#&#x8DF3;&#x8FC7;&#x7B2C;&#x4E00;&#x4E2A;&#x4E4B;&#x540E;&#xFF0C;&#x53D6;&#x524D;&#x4E09;&#x4E2A;
mysql> select * from students limit 1,3;
+-------+------------+-----+--------+---------+-----------+
| StuID | Name &#xA0; &#xA0; &#xA0; | Age | Gender | ClassID | TeacherID |
+-------+------------+-----+--------+---------+-----------+
| &#xA0; &#xA0; 2 | Shi Potian | &#xA0;22 | M &#xA0; &#xA0; | &#xA0; &#xA0; &#xA0; 1 | &#xA0; &#xA0; &#xA0; &#xA0; 7 |
| &#xA0; &#xA0; 3 | Xie Yanke | &#xA0;53 | M &#xA0; &#xA0; | &#xA0; &#xA0; &#xA0; 2 | &#xA0; &#xA0; &#xA0; &#xA0;16 |
| &#xA0; &#xA0; 4 | Ding Dian | &#xA0;32 | M &#xA0; &#xA0; | &#xA0; &#xA0; &#xA0; 4 | &#xA0; &#xA0; &#xA0; &#xA0; 4 |
+-------+------------+-----+--------+---------+-----------+
3 rows in set (0.00 sec)

范例:聚合函数

mysql> select sum(age)/count(*) from students where gender ='M';
+-------------------+
| sum(age)/count(*) |
+-------------------+
| &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; 33.0000 |
+-------------------+
1 row in set (0.00 sec)

范例:分组统计

mysql> select classid, count(*) &#x6570;&#x91CF; from students group by classid;
+---------+--------+
| classid | &#x6570;&#x91CF; &#xA0; |
+---------+--------+
| &#xA0; &#xA0; &#xA0; 2 | &#xA0; &#xA0; &#xA0;3 |
| &#xA0; &#xA0; &#xA0; 1 | &#xA0; &#xA0; &#xA0;4 |
| &#xA0; &#xA0; &#xA0; 4 | &#xA0; &#xA0; &#xA0;4 |
| &#xA0; &#xA0; &#xA0; 3 | &#xA0; &#xA0; &#xA0;4 |
| &#xA0; &#xA0; &#xA0; 5 | &#xA0; &#xA0; &#xA0;1 |
| &#xA0; &#xA0; &#xA0; 7 | &#xA0; &#xA0; &#xA0;3 |
| &#xA0; &#xA0; &#xA0; 6 | &#xA0; &#xA0; &#xA0;4 |
| &#xA0; &#xA0;NULL | &#xA0; &#xA0; &#xA0;2 |
+---------+--------+
8 rows in set (0.00 sec)

#&#x5206;&#x7EC4;&#x7EDF;&#x8BA1;
select classid,avg(age) as &#x5E73;&#x5747;&#x5E74;&#x9F84; from students where classid > 3 group by classid having &#x5E73;&#x5747;&#x5E74;&#x9F84; >30 ;
select gender,avg(age) &#x5E73;&#x5747;&#x5E74;&#x9F84; from students group by gender having gender='M';

#&#x591A;&#x4E2A;&#x5B57;&#x6BB5;&#x5206;&#x7EC4;&#x7EDF;&#x8BA1;
select classid,gender,count(*) &#x6570;&#x91CF; from students group by classid,gender;
select classid,gender,count(*) &#x6570;&#x91CF; from students group by gender,classid;

范例:排序

#&#x53EA;&#x53D6;&#x524D;3&#x4E2A;
mysql> select * from students order by age desc limit 3;
+-------+-------------+-----+--------+---------+-----------+
| StuID | Name &#xA0; &#xA0; &#xA0; | Age | Gender | ClassID | TeacherID |
+-------+-------------+-----+--------+---------+-----------+
| &#xA0; &#xA0;25 | Sun Dasheng | 100 | M &#xA0; &#xA0; | &#xA0; NULL | &#xA0; &#xA0; NULL |
| &#xA0; &#xA0; 3 | Xie Yanke &#xA0; | &#xA0;53 | M &#xA0; &#xA0; | &#xA0; &#xA0; &#xA0;2 | &#xA0; &#xA0; &#xA0;&#xA0;16 |
| &#xA0; &#xA0; 6 | Shi Qing &#xA0;  | &#xA0;46 | M &#xA0; &#xA0; | &#xA0; &#xA0;&#xA0; 5 | &#xA0; &#xA0; NULL |
+-------+-------------+-----+--------+---------+-----------+
3 rows in set (0.00 sec)

#&#x8DF3;&#x8FC7;&#x524D;3&#x4E2A;&#x53EA;&#x663E;&#x793A;&#x540E;&#x7EED;&#x7684;2&#x4E2A;
mysql> select * from students order by age desc limit 3,2;
+-------+--------------+-----+--------+---------+-----------+
| StuID | Name &#xA0; &#xA0; &#xA0; &#xA0; | Age | Gender | ClassID | TeacherID |
+-------+--------------+-----+--------+---------+-----------+
| &#xA0; &#xA0;13 | Tian Boguang | &#xA0;33 | M &#xA0; &#xA0; | &#xA0; &#xA0; &#xA0; 2 | &#xA0; &#xA0; NULL |
| &#xA0; &#xA0; 4 | Ding Dian &#xA0;  | &#xA0;32 | M &#xA0; &#xA0; | &#xA0; &#xA0; &#xA0; 4 | &#xA0; &#xA0;&#xA0; &#xA0; 4 |
+-------+--------------+-----+--------+---------+-----------+
2 rows in set (0.00 sec)

范例:分组和排序

mysql> select classid,count(*) &#x6570;&#x91CF; &#xA0;from students group by classid order by &#x6570;&#x91CF;
;
+---------+--------+
| classid | &#x6570;&#x91CF; &#xA0; |
+---------+--------+
| &#xA0; &#xA0; &#xA0; 5 | &#xA0; &#xA0; &#xA0;1 |
| &#xA0; &#xA0;NULL | &#xA0; &#xA0; &#xA0;2 |
| &#xA0; &#xA0; &#xA0; 2 | &#xA0; &#xA0; &#xA0;3 |
| &#xA0; &#xA0; &#xA0; 7 | &#xA0; &#xA0; &#xA0;3 |
| &#xA0; &#xA0; &#xA0; 1 | &#xA0; &#xA0; &#xA0;4 |
| &#xA0; &#xA0; &#xA0; 4 | &#xA0; &#xA0; &#xA0;4 |
| &#xA0; &#xA0; &#xA0; 3 | &#xA0; &#xA0; &#xA0;4 |
| &#xA0; &#xA0; &#xA0; 6 | &#xA0; &#xA0; &#xA0;4 |
+---------+--------+
8 rows in set (0.00 sec)

7.2 多表查询

多表查询,即查询结果来自于多张表

  • 子查询:在SQL语句嵌套着查询语句,性能较差,基于某语句的查询结果再次进行的查询
  • 联合查询:UNION
  • 交叉连接:笛卡尔乘积 CROSS JOIN
  • 内连接:

等值连接:让表之间的字段以”等值”建立连接关系
不等值连接
自然连接:去掉重复列的等值连接 , 语法: FROM table1 NATURAL JOIN table2;

  • 外连接:

左外连接:FROM tb1 LEFT JOIN tb2 ON tb1.col=tb2.col
右外连接:FROM tb1 RIGHT JOIN tb2 ON tb1.col=tb2.col
完全外连接: FROM tb1 FULL OUTER JOIN tb2 ON tb1.col=tb2.col 注意:MySQL 不支持此SQL语法

  • 自连接:本表和本表进行连接查询

7.2.1 子查询

select 的执行结果,被其它SQL调用

常用范例

#&#x5B50;&#x67E5;&#x8BE2;&#xFF1A;select &#x7684;&#x6267;&#x884C;&#x7ED3;&#x679C;&#xFF0C;&#x88AB;&#x5176;&#x5B83;SQL&#x8C03;&#x7528;
SELECT Name,Age FROM students WHERE Age>(SELECT avg(Age) FROM teachers);
update students set Age=(SELECT avg(Age) FROM teachers) where stuid=25;

7.2.2 联合查询

联合查询 Union 实现的条件,多个表的字段数量相同,字段名和数据类型可以不同,但一般数据类型是相同的

常用范例

#&#x591A;&#x8868;&#x7EB5;&#x5411;&#x5408;&#x5E76;union
SELECT Name,Age FROM students UNION SELECT Name,Age FROM teachers;

#UNION ALL&#x4E0D;&#x4F1A;&#x53BB;&#x91CD;&#xFF0C;UNION&#x4F1A;&#x53BB;&#x91CD;
SELECT Name,Age FROM students UNION ALL SELECT Name,Age FROM teachers;

7.2.3 交叉连接

cross join 即多表的记录之间做笛卡尔乘积组合,并且多个表的列横向合并相加, “雨露均沾”
比如: 第一个表3行4列,第二个表5行6列,cross join后的结果为3*5=15行,4+6=10列
交叉连接生成的记录可能会非常多,建议慎用

常用范例

#&#x6A2A;&#x5411;&#x5408;&#x5E76;&#xFF0C;&#x4EA4;&#x53C9;&#x8FDE;&#x63A5;&#xFF08;&#x6A2A;&#x5411;&#x7B1B;&#x5361;&#x5C14;&#xFF09;
#&#x65B9;&#x6CD5;&#x4E00;
MariaDB [hellodb]> select * from students cross join teachers;

#&#x65B9;&#x6CD5;&#x4E8C;
MariaDB [hellodb]> select * from teachers , students;

7.2.4 内连接

inner join 内连接取多个表的交集

常用范例

#&#x5185;&#x8FDE;&#x63A5;inner join
MariaDB [hellodb]> select * from students inner join teachers on students.teacherid=teachers.tid;

7.2.5 左和右外连接

  • 左连接: 以左表为主根据条件查询右表数据﹐如果根据条件查询右表数据不存在使用null值填充
  • 右连接: 以右表为主根据条件查询左表数据﹐如果根据条件查询左表数据不存在使用null值填充

常用范例

#&#x5DE6;&#x5916;&#x8FDE;&#x63A5;&#xFF0C;s&#x548C;t&#x662F;&#x522B;&#x540D;
MariaDB [hellodb]> select s.stuid,s.name,s.age,s.teacherid,t.tid,t.name,t.age from students as s left outer join teachers as t on s.teacherid=t.tid;

#&#x5DE6;&#x5916;&#x8FDE;&#x63A5;&#x6269;&#x5C55;
MariaDB [hellodb]> select * from students s left outer join teachers t on s.teacherid=t.tid where t.tid is null;

7.2.6 完全外连接

MySQL 不支持完全外连接full outer join语法

常用范例

#MySQL&#x4E0D;&#x652F;&#x6301;&#x5B8C;&#x5168;&#x5916;&#x8FDE;&#x63A5; full outer join,&#x5229;&#x7528;&#x4EE5;&#x4E0B;&#x65B9;&#x5F0F;&#x6CD5;&#x4EE3;&#x66FF;
MariaDB [hellodb]> select * from students left join teachers on students.teacherid=teachers.tid
 &#xA0; &#xA0;-> union
 &#xA0; &#xA0;-> select * from students right join teachers on students.teacherid=teachers.tid;

7.2.7 自连接

自连接, 即表自身连接自身

常用范例

#&#x8868;
MariaDB [hellodb]> select * from emp;
+------+----------+----------+
| id &#xA0; | name &#xA0; &#xA0; | leaderid |
+------+----------+----------+
| &#xA0; &#xA0;1 | mage &#xA0; &#xA0; | &#xA0; &#xA0; NULL |
| &#xA0; &#xA0;2 | zhangsir | &#xA0; &#xA0; &#xA0; &#xA0;1 |
| &#xA0; &#xA0;3 | wang &#xA0; &#xA0; | &#xA0; &#xA0; &#xA0; &#xA0;2 |
| &#xA0; &#xA0;4 | zhang &#xA0; &#xA0;| &#xA0; &#xA0; &#xA0; &#xA0;3 |
+------+----------+----------+
4 rows in set (0.00 sec)

#&#x64CD;&#x4F5C;
MariaDB [hellodb]> select e.name,l.name from emp as e inner join emp as l on e.leaderid=l.id;
+----------+----------+
| name &#xA0; &#xA0; | name &#xA0; &#xA0; |
+----------+----------+
| zhangsir | mage &#xA0; &#xA0; |
| wang &#xA0; &#xA0; | zhangsir |
| zhang &#xA0; &#xA0;| wang &#xA0; &#xA0; |
+----------+----------+
3 rows in set (0.00 sec)

7.3 SELECT 语句处理的顺序

Mysql实战技能全解

SELECT语句的执行流程:

FROM Clause --> WHERE Clause --> GROUP BY --> HAVING Clause -->SELECT --> ORDER BY --> LIMIT

8 VIEW 视图

视图:虚拟表,保存有实表的查询结果,相当于别名
利用视图,可以隐藏表的真实结构,在程序中利用视图进行查询,可以避免表结构的变化,而修改程序,降低程序和数据库之间的耦合度

创建方法

CREATE &#xA0; VIEW view_name [(column_list)]
 &#xA0; &#xA0; AS select_statement
 &#xA0; &#xA0; [WITH [CASCADED | LOCAL] CHECK OPTION]

查看视图定义

SHOW CREATE VIEW view_name #&#x53EA;&#x80FD;&#x770B;&#x89C6;&#x56FE;&#x5B9A;&#x4E49;
SHOW CREATE TABLE view_name # &#x53EF;&#x4EE5;&#x67E5;&#x770B;&#x8868;&#x548C;&#x89C6;&#x56FE;

删除视图

DROP VIEW [IF EXISTS]
 &#xA0; view_name [, view_name] ...

 &#xA0; &#xA0;[RESTRICT | CASCADE]

9 FUNCTION 函数

函数:分为系统内置函数和自定义函数

创建 UDF 语法

CREATE [AGGREGATE] FUNCTION function_name(parameter_name type,[parameter_name
type,...])
 &#xA0; RETURNS {STRING|INTEGER|REAL}
 runtime_body

说明:

  • 参数可以有多个,也可以没有参数
  • 无论有无参数,小括号()是必须的
  • 必须有且只有一个返回值

查看函数列表

SHOW FUNCTION STATUS;

查看函数定义

SHOW CREATE FUNCTION function_name

删除UDF

DROP FUNCTION function_name

调用自定义函数语法

SELECT function_name(parameter_value,...)

注意:

#&#x9ED8;&#x8BA4;MySQL8.0&#x5F00;&#x542F;&#x4E8C;&#x8FDB;&#x5236;&#x65E5;&#x5FD7;,&#x800C;&#x4E0D;&#x5141;&#x8BB8;&#x521B;&#x5EFA;&#x51FD;&#x6570;
mysql> show variables like 'log_bin_trust_function_creators';
+---------------------------------+-------+
| Variable_name &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; | Value |
+---------------------------------+-------+
| log_bin_trust_function_creators | OFF &#xA0; |
+---------------------------------+-------+
1 row in set (0.00 sec)

#&#x6253;&#x5F00;&#x6B64;&#x53D8;&#x91CF;&#x5141;&#x8BB8;&#x4E8C;&#x8FDB;&#x5236;&#x65E5;&#x5FD7;&#x4FE1;&#x606F;&#x51FD;&#x6570;&#x521B;&#x5EFA;
mysql> set global log_bin_trust_function_creators=ON;
Query OK, 0 rows affected (0.00 sec)

使用范例

#&#x65E0;&#x53C2;UDF
CREATE FUNCTION simpleFun() RETURNS VARCHAR(20) RETURN "Hello World";

#&#x6709;&#x53C2;&#x6570;UDF
DELIMITER //
CREATE FUNCTION deleteById(id SMALLINT UNSIGNED) RETURNS VARCHAR(20)
BEGIN
     DELETE FROM students WHERE stuid = id;
     RETURN (SELECT COUNT(*) FROM students);
END//
DELIMITER ;

10 PROCEDURE 存储过程

存储过程:多表SQL的语句的集合,可以独立执行,存储过程保存在mysql.proc表中
存储过程优势

  • 存储过程把经常使用的SQL语句或业务逻辑封装起来,预编译保存在数据库中,当需要时从数据库中直接调
  • 用,省去了编译的过程,提高了运行速度,同时降低网络数据传输量

存储过程与自定义函数的区别

  • 存储过程实现的过程要复杂一些,而函数的针对性较强
  • 存储过程可以有多个返回值,而自定义函数只有一个返回值
  • 存储过程一般可独立执行,而函数往往是作为其他SQL语句的一部分来使用
  • 无参数的存储过程执行过程中可以不加(),函数必须加 ( )

创建存储过程

CREATE PROCEDURE sp_name ([ proc_parameter [,proc_parameter ...]])
routime_body
proc_parameter : [IN|OUT|INOUT] parameter_name type

&#x8BF4;&#x660E;&#xFF1A;&#x5176;&#x4E2D;IN&#x8868;&#x793A;&#x8F93;&#x5165;&#x53C2;&#x6570;&#xFF0C;OUT&#x8868;&#x793A;&#x8F93;&#x51FA;&#x53C2;&#x6570;&#xFF0C;INOUT&#x8868;&#x793A;&#x65E2;&#x53EF;&#x4EE5;&#x8F93;&#x5165;&#x4E5F;&#x53EF;&#x4EE5;&#x8F93;&#x51FA;&#xFF1B;
param_name&#x8868;&#x793A;&#x53C2;&#x6570;&#x540D;&#x79F0;&#xFF1B;type&#x8868;&#x793A;&#x53C2;&#x6570;&#x7684;&#x7C7B;&#x578B;

查看存储过程列表

SHOW PROCEDURE &#xA0;STATUS;

调用存储过程

CALL sp_name ([ proc_parameter [,proc_parameter ...]])

删除存储过程

DROP PROCEDURE [IF EXISTS] sp_name

使用范例

delimiter //
CREATE PROCEDURE dorepeat(n INT)
BEGIN
    SET @i = 0;
    SET @sum = 0;
    REPEAT SET @sum = @sum+@i;
    SET @i = @i + 1;
    UNTIL @i > n END REPEAT;
END//
delimiter ;
CALL dorepeat(100);
SELECT @sum;

11 TRIGGER 触发器

触发器的执行不是由程序调用,也不是由手工启动,而是由事件来触发、激活从而实现执行

使用范例

#&#x521B;&#x5EFA;&#x89E6;&#x53D1;&#x5668;&#xFF0C;&#x5728;&#x5411;&#x5B66;&#x751F;&#x8868;INSERT&#x6570;&#x636E;&#x65F6;&#xFF0C;&#x5B66;&#x751F;&#x6570;&#x589E;&#x52A0;&#xFF0C;DELETE&#x5B66;&#x751F;&#x65F6;&#xFF0C;&#x5B66;&#x751F;&#x6570;&#x51CF;&#x5C11;
CREATE TABLE student_info (
    stu_id INT(11) NOT NULL AUTO_INCREMENT ,
    stu_name VARCHAR(255) DEFAULT NULL,
    PRIMARY KEY (stu_id)
);
CREATE TABLE student_count (
     student_count &#xA0;INT(11) DEFAULT 0
);
INSERT INTO student_count VALUES(0);

CREATE TRIGGER trigger_student_count_insert
AFTER INSERT
ON student_info FOR EACH ROW
UPDATE student_count SET student_count=student_count+1;

CREATE TRIGGER trigger_student_count_delete
AFTER DELETE
ON student_info FOR EACH ROW
UPDATE student_count SET student_count=student_count-1;

12 Event 事件

事件(event)是MySQL在相应的时刻调用的过程式数据库对象。一个事件可调用一次,也可周期性的启动,它由一个特定的线程来管理的,也就是所谓的”事件调度器”。
事件和触发器类似,都是在某些事情发生的时候启动。当数据库上启动一条语句的时候,触发器就启动了,而事件是根据调度事件来启动的。由于它们彼此相似,所以事件也称为临时性触发器。
事件取代了原先只能由操作系统的计划任务来执行的工作,而且MySQL的事件调度器可以精确到每秒钟执行一个任务,而操作系统的计划任务(如:Linux下的CRON或Windows下的任务计划)只能精确到每分钟执行一次。
事件的优缺点
优点:一些对数据定时性操作不再依赖外部程序,而直接使用数据库本身提供的功能,可以实现每秒钟执行一个任务,这在一些对实时性要求较高的环境下就非常实用
缺点:定时触发,不可以直接调用

#&#x9ED8;&#x8BA4;&#x4E8B;&#x4EF6;&#x8C03;&#x5EA6;&#x529F;&#x80FD;&#x662F;&#x5173;&#x95ED;&#x7684;,MySQL8.0&#x9ED8;&#x8BA4;&#x662F;&#x5F00;&#x542F;&#x7684;
[root@localhost (none)]> select @@event_scheduler;
+-------------------+
| @@event_scheduler |
+-------------------+
| ON                |
+-------------------+
1 row in set (0.00 sec)

13 MySQL 用户管理

相关数据库和表

&#x5143;&#x6570;&#x636E;&#x6570;&#x636E;&#x5E93;&#xFF1A;mysql
&#x7CFB;&#x7EDF;&#x6388;&#x6743;&#x8868;&#xFF1A;db, host, user,columns_priv, tables_priv, procs_priv, proxies_priv

用户帐号

'USERNAME'@'HOST'
@'HOST': &#x4E3B;&#x673A;&#x540D;&#xFF1A; user1@'web1.magedu.org'
IP&#x5730;&#x5740;&#x6216;Network
 &#x901A;&#x914D;&#x7B26;&#xFF1A; % &#xA0; _
 &#x793A;&#x4F8B;&#xFF1A;wang@'172.16.%.%' &#xA0;
 &#xA0; &#xA0; user2@'192.168.1.%'
 &#xA0; &#xA0; mage@'10.0.0.0/255.255.0.0'

创建用户

CREATE USER 'USERNAME'@'HOST' [IDENTIFIED BY 'password']&#xFF1B;
#&#x793A;&#x4F8B;:
create user test2@'10.0.0.%' identified by 123456;
create user test@'10.0.0.0/255.255.255.0' identified by '123456';

用户重命名

RENAME USER old_user_name TO new_user_name;

删除用户

DROP USER 'USERNAME'@'HOST'

范例:删除默认的空用户

DROP USER ''@'localhost';

范例:MySQL5.7和8.0 破解root密码

#&#x65B9;&#x6CD5;1&#x3001;2&#x5B9E;&#x73B0;&#x524D;&#x63D0;&#x6B65;&#x9AA4;
[root@centos8 ~]# vim /etc/my.cnf
[mysqld]
skip-grant-tables &#xA0;
skip-networking &#xA0;#MySQL8.0&#x4E0D;&#x9700;&#x8981;
[root@centos8 ~]# systemctl restart mysqld

#&#x65B9;&#x6CD5;1
mysql> update mysql.user set authentication_string='' where user='root' and host='localhost';

#&#x65B9;&#x6CD5;2
mysql> flush privileges;
#&#x518D;&#x6267;&#x884C;&#x4E0B;&#x9762;&#x4EFB;&#x610F;&#x4E00;&#x4E2A;&#x547D;&#x4EE4;
mysql> alter user root@'localhost' identified by 'ubuntu';
mysql> set password for root@'localhost'='ubuntu';
[root@centos8 ~]#vim /etc/my.cnf
[mysqld]
#skip-grant-tables &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;
#skip-networking
[root@centos8 ~]# systemctl restart mysqld
[root@centos8 ~]# mysql -uroot -pubuntu

范例:删库跑路之清空root密码方法

#&#x6B64;&#x65B9;&#x6CD5;&#x9002;&#x7528;&#x4E8E;&#x5305;&#x5B89;&#x88C5;&#x65B9;&#x5F0F;&#x7684;MySQL&#x6216;Mariadb
[root@centos8 ~]#systemctl stop mysqld
[root@centos8 ~]#rm -rf /var/lib/mysql/*
[root@centos8 ~]#systemctl start mysqld

14 权限管理和DCL语句

GRANT 授权

GRANT priv_type [(column_list)],... ON [object_type] priv_level TO 'user'@'host'
[IDENTIFIED BY 'password'] [WITH GRANT OPTION];
priv_type: ALL [PRIVILEGES]
object_type:TABLE | FUNCTION | PROCEDURE
priv_level: &#xA0;*(&#x6240;&#x6709;&#x5E93;) &#xA0;|*.* &#xA0; | db_name.* &#xA0;| db_name.tbl_name &#xA0;| tbl_name(&#x5F53;&#x524D;&#x5E93;&#x7684;
&#x8868;) &#xA0;| db_name.routine_name(&#x6307;&#x5B9A;&#x5E93;&#x7684;&#x51FD;&#x6570;,&#x5B58;&#x50A8;&#x8FC7;&#x7A0B;,&#x89E6;&#x53D1;&#x5668;)
with_option: GRANT OPTION
 &#xA0;| MAX_QUERIES_PER_HOUR count
 &#xA0;| MAX_UPDATES_PER_HOUR count
 &#xA0;| MAX_CONNECTIONS_PER_HOUR count
 &#xA0;| MAX_USER_CONNECTIONS count

使用范例

GRANT ALL ON wordpress.* TO wordpress@'10.0.0.%' ;

GRANT SELECT (col1), INSERT (col1,col2) ON mydb.mytbl TO 'someuser'@'somehost';

GRANT ALL PRIVILEGES ON *.* TO 'root'@'10.0.0.%' &#xA0;WITH GRANT OPTION;

#&#x521B;&#x5EFA;&#x7528;&#x6237;&#x548C;&#x6388;&#x6743;&#x540C;&#x65F6;&#x6267;&#x884C;&#x7684;&#x65B9;&#x5F0F;&#x5728;MySQL8.0&#x53D6;&#x6D88;&#x4E86;
GRANT ALL ON wordpress.* TO wordpress@'192.168.8.%' IDENTIFIED BY '123456';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.8.%' IDENTIFIED BY '123456' WITH GRANT OPTION;

REVOKE 取消权限

REVOKE priv_type [(column_list)] [, priv_type [(column_list)]] ... ON [object_type] priv_level FROM user [, user] ...

使用范例

REVOKE DELETE ON *.* FROM 'testuser'@'172.16.0.%';

查看指定用户获得的授权

Help SHOW GRANTS
SHOW GRANTS FOR 'user'@'host';
SHOW GRANTS FOR CURRENT_USER[()];

注意
MariaDB服务进程启动时会读取mysql库中所有授权表至内存
(1) GRANT或REVOKE等执行权限操作会保存于系统表中,MariaDB的服务进程通常会自动重读授权表,使之生效
(2) 对于不能够或不能及时重读授权表的命令,可手动让MariaDB的服务进程重读授权表:
mysql> FLUSH PRIVILEGES;

四、MySQL 架构和性能优化

1 存储引擎

MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力,此种技术称为存储擎,MySQL 支持多种存储引擎其中目前应用最广泛的是 InnoDB和MyISAM两种

Mysql实战技能全解

1.1 MyISAM 存储引擎

MyISAM 引擎特点

  • 不支持事务
  • 表级锁定
  • 读写相互阻塞,写入不能读,读时不能写
  • 只缓存索引
  • 不支持外键约束
  • 不支持聚簇索引
  • 读取数据较快,占用资源较少
  • 不支持MVCC(多版本并发控制机制)高并发
  • 崩溃恢复性较差
  • MySQL5.5.5 前默认的数据库引擎*
    MyISAM 存储引擎适用场景**

  • 只读(或者写较少)

  • 表较小(可以接受长时间进行修复操作)

MyISAM 引擎文件

  • tbl_name.frm 表格式定义
  • tbl_name.MYD 数据文件
  • *tbl_name.MYI 索引文件

1.2 InnoDB 引擎

InnoDB引擎特点

  • 行级锁
  • 支持事务,适合处理大量短期事务
  • 读写阻塞与事务隔离级别相关
  • 可缓存数据和索引
  • 支持聚簇索引
  • 崩溃恢复性更好
  • 支持MVCC高并发
  • 从MySQL5.5后支持全文索引
  • 从MySQL5.5.5开始为默认的数据库引擎*
    InnoDB 数据库文件**

  • 所有InnoDB表的数据和索引放置于同一个表空间中

&#x6570;&#x636E;&#x6587;&#x4EF6;&#xFF1A;ibdata1, ibdata2,&#x5B58;&#x653E;&#x5728;datadir&#x5B9A;&#x4E49;&#x7684;&#x76EE;&#x5F55;&#x4E0B;
&#x8868;&#x683C;&#x5F0F;&#x5B9A;&#x4E49;&#xFF1A;tb_name.frm,&#x5B58;&#x653E;&#x5728;datadir&#x5B9A;&#x4E49;&#x7684;&#x6BCF;&#x4E2A;&#x6570;&#x636E;&#x5E93;&#x5BF9;&#x5E94;&#x7684;&#x76EE;&#x5F55;&#x4E0B;
  • *每个表单独使用一个表空间存储表的数据和索引
&#x4E24;&#x7C7B;&#x6587;&#x4EF6;&#x653E;&#x5728;&#x5BF9;&#x5E94;&#x6BCF;&#x4E2A;&#x6570;&#x636E;&#x5E93;&#x72EC;&#x7ACB;&#x76EE;&#x5F55;&#x4E2D;
&#x6570;&#x636E;&#x6587;&#x4EF6;(&#x5B58;&#x50A8;&#x6570;&#x636E;&#x548C;&#x7D22;&#x5F15;)&#xFF1A;tb_name.ibd
&#x8868;&#x683C;&#x5F0F;&#x5B9A;&#x4E49;&#xFF1A;tb_name.frm

1.3 管理存储引擎

查看mysql支持的存储引擎

show engines;

查看当前默认的存储引擎

show variables like '%storage_engine%';

设置默认的存储引擎

vim /etc/my.cnf
[mysqld]
default_storage_engine= InnoDB

查看库中所有表使用的存储引擎

show table status from db_name;

查看库中指定表的存储引擎

show table status like &#xA0;'tb_name';
show create table tb_name;

设置表的存储引擎

CREATE TABLE tb_name(... ) ENGINE=InnoDB;
ALTER TABLE tb_name ENGINE=InnoDB;

2 MySQL 中的系统数据库

  • mysql *数据库
    是mysql的核心数据库,类似于Sql Server中的master库,主要负责存储数据库的用户、权限设置、关键字等mysql自己需要使用的控制和管理信息

  • information_schema *数据库
    MySQL 5.0之后产生的,一个虚拟数据库,物理上并不存在information_schema数据库类似与”数据字典”,提供了访问数据库元数据的方式,即数据的数据。比如数据库名或表名,列类型,访问权限(更加细化的访问方式)

  • performance_schema *数据库
    MySQL 5.5开始新增的数据库,主要用于收集数据库服务器性能参数,库里表的存储引擎均为PERFORMANCE_SCHEMA,用户不能创建存储引擎为PERFORMANCE_SCHEMA的表

  • sys *数据库
    MySQL5.7之后新增加的数据库,库中所有数据源来自performance_schema。目标是把performance_schema的把复杂度降低,让DBA能更好的阅读这个库里的内容。让DBA更快的了解DataBase的运行情况

3 服务器配置和状态

可以通过mysqld选项,服务器系统变量和服务器状态变量进行MySQL的配置和查看状态
注意

  • 其中有些参数支持运行时修改,会立即生效
  • 有些参数不支持动态修改,且只能通过修改配置文件,并重启服务器程序生效
  • 有些参数作用域是全局的,为所有会话设置
  • 有些可以为每个用户提供单独(会话)的设置

3.1 服务器选项

注意 : 服务器选项用横线 , 不用下划线

获取mysqld的可用选项列表

#&#x67E5;&#x770B;mysqld&#x53EF;&#x7528;&#x9009;&#x9879;&#x5217;&#x8868;&#x548C;&#x53CA;&#x5F53;&#x524D;&#x503C;
mysqld --verbose --help

#&#x83B7;&#x53D6;mysqld&#x5F53;&#x524D;&#x542F;&#x52A8;&#x9009;&#x9879;
mysqld --print-defaults

#&#x67E5;&#x770B;&#x53EF;&#x7528;&#x9009;&#x9879;&#x5217;&#x8868;&#x548C;&#x5F53;&#x524D;&#x503C;
[root@centos8 ~]#/usr/libexec/mysqld --verbose --help

#&#x67E5;&#x770B;mysqld&#x7684;&#x5F53;&#x524D;&#x542F;&#x52A8;&#x9009;&#x9879;
[root@centos8 ~]#/usr/libexec/mysqld --print-defaults
/usr/libexec/mysqld would have been started with the following arguments:
--plugin-load-add=auth_gssapi.so --datadir=/var/lib/mysql --
socket=/var/lib/mysql/mysql.sock --log-error=/var/log/mariadb/mariadb.log --pidfile=/run/mariadb/mariadb.pid

设置服务器选项方法

#1.&#x5728;&#x547D;&#x4EE4;&#x884C;&#x4E2D;&#x8BBE;&#x7F6E;
shell> /usr/bin/mysqld_safe --skip-name-resolve=1
shell> /usr/libexec/mysqld --basedir=/usr

#2.&#x5728;&#x914D;&#x7F6E;&#x6587;&#x4EF6;my.cnf&#x4E2D;&#x8BBE;&#x7F6E;
vim /etc/my.cnf
[mysqld]
skip_name_resolve=1
skip-grant-tables

3.2 服务器系统变量

服务器系统变量:可以分全局和会话两种
注意 : 系统变量用下划线 , 不用横线

获取系统变量

#&#x53EA;&#x67E5;&#x770B;global&#x53D8;&#x91CF;
SHOW GLOBAL VARIABLES;
#&#x67E5;&#x770B;&#x6240;&#x6709;&#x53D8;&#x91CF;(&#x5305;&#x62EC;global&#x548C;session)
SHOW [SESSION] VARIABLES;

#&#x67E5;&#x770B;&#x6307;&#x5B9A;&#x7684;&#x7CFB;&#x7EDF;&#x53D8;&#x91CF;
SHOW VARIABLES LIKE 'VAR_NAME';
SELECT @@VAR_NAME;

#&#x67E5;&#x770B;&#x9009;&#x9879;&#x548C;&#x90E8;&#x5206;&#x53D8;&#x91CF;
[root@centos8 ~]#mysqladmin variables

修改变量的值

#&#x4FEE;&#x6539;&#x670D;&#x52A1;&#x5668;&#x53D8;&#x91CF;&#x7684;&#x503C;
help SET

#&#x4FEE;&#x6539;&#x5168;&#x5C40;&#x53D8;&#x91CF;&#xFF1A;&#x4EC5;&#x5BF9;&#x4FEE;&#x6539;&#x540E;&#x65B0;&#x521B;&#x5EFA;&#x7684;&#x4F1A;&#x8BDD;&#x6709;&#x6548;&#xFF1B;&#x5BF9;&#x5DF2;&#x7ECF;&#x5EFA;&#x7ACB;&#x7684;&#x4F1A;&#x8BDD;&#x65E0;&#x6548;
SET GLOBAL system_var_name=value;
SET @@global.system_var_name=value;

#&#x4FEE;&#x6539;&#x4F1A;&#x8BDD;&#x53D8;&#x91CF;
SET [SESSION] system_var_name=value;
SET @@[session.]system_var_name=value;

3.3 服务器状态变量

服务器状态变量:分全局和会话两种
状态变量(只读):用于保存mysqld运行中的统计数据的变量,不可更改

SHOW GLOBAL STATUS;
SHOW [SESSION] STATUS;

#&#x8303;&#x4F8B;
MariaDB [hellodb]> SHOW GLOBAL STATUS like 'com_select';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_select &#xA0; &#xA0;| 5 &#xA0; &#xA0; |
+---------------+-------+
1 row in set (0.001 sec)

3.4 服务器变量 SQL_MODE

SQL_MODE:对其设置可以完成一些约束检查的工作,可分别进行全局的设置或当前会话的设置
常见 MODE:

  • NO_AUTO_CREATE_USER: 禁止GRANT创建密码为空的用户
  • NO_ZERO_DATE:在严格模式,不允许使用’0000-00-00’的时间
  • ONLY_FULL_GROUP_BY: 对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,那么将认为这个SQL是不合法的
  • NO_BACKSLASH_ESCAPES: 反斜杠”\”作为普通字符而非转义字符
  • PIPES_AS_CONCAT: 将”||”视为连接操作符而非”或”运算符
[root@localhost (none)]> show variables like 'sql_mode';
+---------------+-----------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value  |
+---------------+-----------------------------------------------------------------------------------------------------------------------+
| sql_mode      | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION |
+---------------+-----------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

4 INDEX 索引

4.1 索引介绍

索引:是排序的快速查找的特殊数据结构,定义作为查找条件的字段上,又称为键key,索引通过存储引擎实现
优点:

  • 索引可以降低服务需要扫描的数据量,减少了IO次数
  • 索引可以帮助服务器避免排序和使用临时表
  • 索引可以帮助将随机I/O转为顺序 I/O

缺点:

  • 占用额外空间,影响插入速度

索引类型:

  • B+ TREE、HASH、R TREE、FULL TEXT
  • 聚簇(集)索引、非聚簇索引:数据和索引是否存储在一起
  • 主键索引、二级(辅助)索引
  • 稠密索引、稀疏索引:是否索引了每一个数据项
  • 简单索引、组合索引: 是否是多个字段的索引
  • 左前缀索引:取前面的字符做索引
  • 覆盖索引:从索引中即可取出要查询的数据,性能高

4.2 索引结构

二叉树

Mysql实战技能全解

红黑树

  • 根节点是黑色的, 叶节点是不存储数据的黑色空节点,图中叶节点为正方形的黑色节点
  • 任何相邻的两个节点不能同时为红色,红色节点被黑色节点隔开,红色节点的子节点是黑色的
  • 任意节点到其可到达的叶节点间包含相同数量的黑色节点,保证任何路径相差不会超出2倍,从而实现基本平衡

B-Tree索引

Mysql实战技能全解

B+Tree索引

B+Tree索引:按顺序存储,每一个叶子节点到根结点的距离是相同的;左前缀索引,适合查询范围类的数据
可以使用 B+Tree 索引的查询类型:(假设前提: 姓,名,年龄三个字段建立了一个复合索引)

  • 全值匹配:精确所有索引列,如:姓wang,名xiaochun,年龄30
  • 匹配最左前缀:即只使用索引的第一列,如:姓wang
  • 匹配列前缀:只匹配一列值开头部分,如:姓以w开头的记录
  • 匹配范围值:如:姓ma和姓wang之间
  • 精确匹配某一列并范围匹配另一列:如:姓wang,名以x开头的记录
  • 只访问索引的查询

B+Tree 索引的限制:

  • 如不从最左列开始,则无法使用索引,如:查找名为xiaochun,或姓为g结尾
  • 不能跳过索引中的列:如:查找姓wang,年龄30的,只能使用索引第一列

特别提示:

  • 索引列的顺序和查询语句的写法应相匹配,才能更好的利用索引
  • 为优化性能,可能需要针对相同的列但顺序不同创建不同的索引来满足不同类型的查询需求

Mysql实战技能全解
面试题: InnoDB中一颗的B+树可以存放多少行数据

假设定义一颗B+树高度为2,即一个根节点和若干叶子节点。那么这棵B+树的存放总行记录数=根节点指针数单个叶子记录的行数。这里先计算叶子节点,B+树中的单个叶子节点的大小为16K,假设每一条目为1K,那么记录数即为16(16k/1K=16),然后计算非叶子节点能够存放多少个指针,假设主键ID为bigint类型,那么长度为8字节,而指针大小在InnoDB中是设置为6个字节,这样加起来一共是14个字节。那么通过页大小/(主键ID大小+指针大小),即16384/14=1170个指针,所以一颗高度为2的B+树能存放161170=18720条这样的记录。根据这个原理就可以算出一颗高度为3的B+树可以存放1611701170=21902400条记录。所以在InnoDB中B+树高度一般为2-3层,它就能满足千万级的数据存储

4.3 索引优化

  • 独立地使用列:尽量避免其参与运算,独立的列指索引列不能是表达式的一部分,也不能是函数的参数,在where条件中,始终将索引列单独放在比较符号的一侧,尽量不要在列上进行运算(函数操作和表达式操作)
  • 左前缀索引:构建指定索引字段的左侧的字符数,要通过索引选择性(不重复的索引值和数据表的记录总数的比值)来评估,尽量使用短索引,如果可以,应该制定一个前缀长度
  • 多列索引:AND操作时更适合使用多列索引,而非为每个列创建单独的索引
  • 选择合适的索引列顺序:无排序和分组时,将选择性最高放左侧
  • 只要列中含有NULL值,就最好不要在此列设置索引,复合索引如果有NULL值,此列在使用时也不会使用索引
  • 对于经常在where子句使用的列,最好设置索引
  • 对于有多个列where或者order by子句,应该建立复合索引
  • 对于like语句,以 % 或者 _ 开头的不会使用索引,以 % 结尾会使用索引
  • 尽量不要使用not in和<>操作,虽然可能使用索引,但性能不高
  • 不要使用RLIKE正则表达式会导致索引失效
  • 查询时,能不要就不用,尽量写全字段名,比如:select id,name,age from students;
  • 大部分情况连接效率远大于子查询
  • 在有大量记录的表分页时使用limit
  • 对于经常使用的查询,可以开启查询缓存
  • 多使用explain和profile分析查询语句
  • 查看慢查询日志,找出执行时间长的sql语句优化

4.4 管理索引

创建索引

CREATE [UNIQUE] INDEX index_name ON tbl_name (index_col_name[(length)],...);
ALTER TABLE tbl_name ADD INDEX index_name(index_col_name[(length)]);
help CREATE INDEX;

删除索引

DROP INDEX index_name ON tbl_name;
ALTER TABLE tbl_name DROP INDEX index_name(index_col_name);

查看索引

SHOW INDEX FROM [db_name.]tbl_name;

优化表空间

OPTIMIZE TABLE tb_name;

查看索引的使用

SET GLOBAL userstat=1; &#xA0;#MySQL&#x65E0;&#x6B64;&#x53D8;&#x91CF;
SHOW INDEX_STATISTICS;
范例:创建索引和使用索引
MariaDB [hellodb]> create index idx_name on students(name(10));
Query OK, 0 rows affected (0.009 sec)
Records: 0 Duplicates: 0 &#xA0;Warnings: 0
MariaDB [hellodb]> show indexes from students\G
*************************** 1. row ***************************
 &#xA0; &#xA0; &#xA0; &#xA0;Table: students
 &#xA0; Non_unique: 0
 &#xA0; &#xA0; Key_name: PRIMARY
 Seq_in_index: 1
 Column_name: StuID
 &#xA0; &#xA0;Collation: A
 Cardinality: 25
 &#xA0; &#xA0; Sub_part: NULL
 &#xA0; &#xA0; &#xA0; Packed: NULL
 &#xA0; &#xA0; &#xA0; &#xA0; Null:
 &#xA0; Index_type: BTREE
 &#xA0; &#xA0; &#xA0;Comment:
Index_comment:
*************************** 2. row ***************************
 &#xA0; &#xA0; &#xA0; &#xA0;Table: students
 &#xA0; Non_unique: 1
 &#xA0; &#xA0; Key_name: idx_name
 Seq_in_index: 1
 Column_name: Name
 &#xA0; &#xA0;Collation: A
 Cardinality: 25
 &#xA0; &#xA0; Sub_part: 10
 &#xA0; &#xA0; &#xA0; Packed: NULL
 &#xA0; &#xA0; &#xA0; &#xA0; Null:
 &#xA0; Index_type: BTREE
 &#xA0; &#xA0; &#xA0;Comment:
Index_comment:
2 rows in set (0.000 sec)

4.5 EXPLAIN 工具

可以通过EXPLAIN来分析索引的有效性,获取查询执行计划信息,用来查看查询优化器如何执行查询
语法:

EXPLAIN SELECT clause

说明: type显示的是访问类型,是较为重要的一个指标,结果值从好到坏依次是:NULL> system >const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery >range > index > ALL , 一般来说,得保证查询至少达到range级别(未达到建议优化,比如加索引),最好能达到ref

使用范例

MariaDB [hellodb]> explain select * from students where stuid not in (5,10,20);
+------+-------------+----------+------+---------------+------+---------+------+-
| &#xA0; &#xA0;1 | SIMPLE &#xA0; &#xA0; &#xA0;| students | ALL &#xA0;| PRIMARY &#xA0; &#xA0; &#xA0; | NULL | NULL &#xA0; &#xA0;| NULL |
&#xA0; 25 | Using where |
+------+-------------+----------+------+---------------+------+---------+------+-
2 lock struct(s), heap size 1136, 28 row lock(s), undo log entries 27
MySQL thread id 13, OS thread handle 139719808595712, query id 206 localhost
root
...&#x7701;&#x7565;...

#&#x6B64;&#x6307;&#x4EE4;&#x4E0D;&#x652F;&#x6301;MySQL8.0
MariaDB [hellodb]> SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
+-----------+-------------+-----------+-----------+----------------------+-------
| 123:9:3:2 | 123 &#xA0; &#xA0; &#xA0; &#xA0; | X &#xA0; &#xA0; &#xA0; &#xA0; | RECORD &#xA0; &#xA0;| hellodb.students |
PRIMARY &#xA0; &#xA0;| &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;9 | &#xA0; &#xA0; &#xA0; &#xA0; 3 | &#xA0; &#xA0; &#xA0; &#xA0;2 | 1 &#xA0; &#xA0; &#xA0; &#xA0; |
| 120:9:3:2 | 120 &#xA0; &#xA0; &#xA0; &#xA0; | X &#xA0; &#xA0; &#xA0; &#xA0; | RECORD &#xA0; &#xA0;| hellodb.students |
PRIMARY &#xA0; &#xA0;| &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;9 | &#xA0; &#xA0; &#xA0; &#xA0; 3 | &#xA0; &#xA0; &#xA0; &#xA0;2 | 1 &#xA0; &#xA0; &#xA0; &#xA0; |
+-----------+-------------+-----------+-----------+----------------------+-------
| Id | User &#xA0; &#xA0; &#xA0; &#xA0;| Host &#xA0; &#xA0; &#xA0;| db &#xA0; &#xA0; &#xA0;| Command | Time | State &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;
&#xA0; &#xA0; &#xA0;| Info &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; | Progress |
+----+-------------+-----------+---------+---------+------+----------------------
7 rows in set (0.000 sec)
#&#x6740;&#x6389;&#x672A;&#x5B8C;&#x6210;&#x7684;&#x4E8B;&#x52A1;
MariaDB [hellodb]> kill 13;
Query OK, 0 rows affected (0.000 sec)
#&#x67E5;&#x770B;&#x4E8B;&#x52A1;&#x9501;&#x7684;&#x8D85;&#x65F6;&#x65F6;&#x957F;&#xFF0C;&#x9ED8;&#x8BA4;50s
MariaDB [hellodb]> show global variables like 'innodb_lock_wait_timeout';
+--------------------------+-------+
| Variable_name &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;| Value |
+--------------------------+-------+
| innodb_lock_wait_timeout | 50 &#xA0; &#xA0;|
+--------------------------+-------+
1 row in set (0.001 sec)

5.3.3 事务隔离级别

MySQL 支持四种隔离级别,事务隔离级别从上至下更加严格

Mysql实战技能全解
  • READ UNCOMMITTED 读未提交*
    可读取到未提交数据,产生
    脏读**

  • READ COMMITTED 读提交*
    可读取到提交数据,但未提交数据不可读,产生
    不可重复读**,即可读取到多个提交数据,导致每次读取数据不一致

  • REPEATABLE READ 可重复读*
    可重复读,多次读取数据都一致,产生
    幻读,即读取过程中,即使有其它提交的事务修改数据,仍只能读取到未修改前的旧数据。 此为MySQL默认设置**

  • SERIALIZABLE 序列化*
    可串行化,未提交的读事务阻塞写事务(加读锁,但不阻塞读事务),或者未提交的写事务阻塞读和写事务(加写锁,其它事务的读,写都不可以执行)。会导致
    并发性能差**

#&#x670D;&#x52A1;&#x5668;&#x9009;&#x9879;&#x4E2D;&#x6307;&#x5B9A;
vim /etc/my.cnf
[mysqld]
transaction-isolation=SERIALIZABLE

#MySQL8.0 &#x4E8B;&#x52A1;&#x9694;&#x79BB;&#x7EA7;&#x522B;&#x7CFB;&#x7EDF;&#x53D8;&#x91CF;tx_isolation&#x5DF2;&#x53D6;&#x6D88;
mysql> select @@tx_isolation;
ERROR 1193 (HY000): Unknown system variable 'tx_isolation'

mysql> select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ &#xA0; &#xA0; &#xA0; &#xA0; |
+-------------------------+
1 row in set (0.00 sec)

6 日志管理

MySQL 支持丰富的日志类型,如下:

  • 事务日志:transaction log

事务日志的写入类型为”追加”,因此其操作为”顺序IO”;通常也被称为:预写式日志 write ahead logging
事务日志文件: ib_logfile0, ib_logfile1

  • 错误日志error log
  • 通用日志general log
  • 慢查询日志 slow query log
  • 二进制日志 binary log
  • 中继日志reley log,在主从复制架构中,从服务器用于保存从主服务器的二进制日志中读取的事件

6.1 事务日志

Innodb事务日志相关配置

show variables like '%innodb_log%';

innodb_log_file_size &#xA0; 50331648 #&#x6BCF;&#x4E2A;&#x65E5;&#x5FD7;&#x6587;&#x4EF6;&#x5927;&#x5C0F;
innodb_log_files_in_group 2 &#xA0; &#xA0; #&#x65E5;&#x5FD7;&#x7EC4;&#x6210;&#x5458;&#x4E2A;&#x6570;
innodb_log_group_home_dir ./ #&#x4E8B;&#x52A1;&#x6587;&#x4EF6;&#x8DEF;&#x5F84;

vim /etc/my.cnf
[mysqld]
innodb_log_group_home_dir=/data/

chown -R mysql./data

事务日志性能优化

  • 1 此为默认值,日志缓冲区将写入日志文件,并在每次事务后执行刷新到磁盘。 这是完全遵守ACID特性
  • 0 提交时没有写磁盘的操作; 而是每秒执行一次将日志缓冲区的提交的事务写入刷新到磁盘。 这样可提供更好的性能,但服务器崩溃可能丢失最后一秒的事务
  • 2 每次提交后都会写入OS的缓冲区,但每秒才会进行一次刷新到磁盘文件中。 性能比0略差一些,但操作系统或停电可能导致最后一秒的交易丢失
innodb_flush_log_at_trx_commit=0|1|2

6.2 错误日志

  • mysqld启动和关闭过程中输出的事件信息
  • mysqld运行中产生的错误信息
  • event scheduler运行一个event时产生的日志信息
  • 在主从复制架构中的从服务器上启动从服务器线程时产生的信息

错误文件路径

[root@localhost (none)]> SHOW GLOBAL VARIABLES LIKE 'log_error';
+---------------+---------------------------+
| Variable_name | Value                     |
+---------------+---------------------------+
| log_error     | /var/log/mysql/mysqld.log |
+---------------+---------------------------+
1 row in set (0.00 sec)

6.3 通用日志

通用日志:记录对数据库的通用操作,包括:错误的SQL语句
通用日志可以保存在:file(默认值)或 table(mysql.general_log表)
通用日志相关设置

general_log=ON|OFF
general_log_file=HOSTNAME.log
log_output=TABLE|FILE|NONE

范例: 启用通用日志并记录至文件中

#&#x9ED8;&#x8BA4;&#x6CA1;&#x6709;&#x542F;&#x7528;&#x901A;&#x7528;&#x65E5;&#x5FD7;
mysql> select @@general_log;
+---------------+
| @@general_log |
+---------------+
| &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; 0 |
+---------------+
1 row in set (0.00 sec)

#&#x542F;&#x7528;
mysql> set global general_log=1;
Query OK, 0 rows affected (0.01 sec)
mysql> select @@general_log;
+---------------+
| @@general_log |
+---------------+
| &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; 1 |
+---------------+
1 row in set (0.00 sec)

#&#x9ED8;&#x8BA4;&#x901A;&#x7528;&#x65E5;&#x5FD7;&#x5B58;&#x653E;&#x5728;&#x6587;&#x4EF6;&#x4E2D;
mysql> SHOW GLOBAL VARIABLES LIKE 'log_output';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_output &#xA0; &#xA0;| FILE &#xA0;|
+---------------+-------+
1 row in set (0.00 sec)

#&#x901A;&#x7528;&#x65E5;&#x5FD7;&#x5B58;&#x653E;&#x7684;&#x6587;&#x4EF6;&#x8DEF;&#x5F84;
mysql> select @@general_log_file;
+----------------------------+
| @@general_log_file &#xA0; &#xA0; &#xA0; &#xA0; |
+----------------------------+
| /var/lib/mysql/centos8.log |
+----------------------------+
1 row in set (0.00 sec)

范例:通用日志记录到表中

#&#x4FEE;&#x6539;&#x901A;&#x7528;&#x65E5;&#x5FD7;&#xFF0C;&#x8BB0;&#x5F55;&#x901A;&#x7528;&#x65E5;&#x5FD7;&#x81F3;mysql.general_log&#x8868;&#x4E2D;
MariaDB [mysql]> set global log_output="table";
MariaDB [mysql]> SHOW GLOBAL VARIABLES LIKE 'log_output';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_output &#xA0; &#xA0;| TABLE |
+---------------+-------+
1 row in set (0.002 sec)

#general_log&#x8868;&#x662F;CSV&#x7684;&#x6587;&#x672C;&#x6587;&#x4EF6;
[root@centos8 ~]#file /var/lib/mysql/mysql/general_log.CSV
/var/lib/mysql/mysql/general_log.CSV: ASCII text
[root@centos8 ~]#head /var/lib/mysql/mysql/general_log.CSV
"2021-02-05 10:02:03.629031","root[root] @ localhost []",8,1,"Query","show databases"
"2021-02-05 10:02:03.629901","root[root] @ localhost []",8,1,"Query","show tables"
MariaDB [mysql]> select * from mysql.general_log\G
...&#x7701;&#x7565;...

*************************** 7. row ***************************
 event_time: 2019-11-25 11:03:44.549211
 &#xA0; user_host: root[root] @ localhost []
 &#xA0; thread_id: 8
 &#xA0; server_id: 1
command_type: Query
 &#xA0; argument: select * from general_log
7 rows in set (0.000 sec)

6.4 慢查询日志

记录执行查询时长超出指定时长的操作

慢查询相关变量

slow_query_log=ON|OFF #&#x5F00;&#x542F;&#x6216;&#x5173;&#x95ED;&#x6162;&#x67E5;&#x8BE2;&#xFF0C;&#x652F;&#x6301;&#x5168;&#x5C40;&#x548C;&#x4F1A;&#x8BDD;&#xFF0C;&#x53EA;&#x6709;&#x5168;&#x5C40;&#x8BBE;&#x7F6E;&#x624D;&#x4F1A;&#x751F;&#x6210;&#x6162;&#x67E5;&#x8BE2;&#x6587;&#x4EF6;
long_query_time=N #&#x6162;&#x67E5;&#x8BE2;&#x7684;&#x9600;&#x503C;&#xFF0C;&#x5355;&#x4F4D;&#x79D2;,&#x9ED8;&#x8BA4;&#x4E3A;10s
slow_query_log_file=HOSTNAME-slow.log &#xA0;#&#x6162;&#x67E5;&#x8BE2;&#x65E5;&#x5FD7;&#x6587;&#x4EF6;
log_slow_filter = admin,filesort,filesort_on_disk,full_join,full_scan,
query_cache,query_cache_miss,tmp_table,tmp_table_on_disk
#&#x4E0A;&#x8FF0;&#x67E5;&#x8BE2;&#x7C7B;&#x578B;&#x4E14;&#x67E5;&#x8BE2;&#x65F6;&#x957F;&#x8D85;&#x8FC7;long_query_time&#xFF0C;&#x5219;&#x8BB0;&#x5F55;&#x65E5;&#x5FD7;
log_queries_not_using_indexes=ON &#xA0;#&#x4E0D;&#x4F7F;&#x7528;&#x7D22;&#x5F15;&#x6216;&#x4F7F;&#x7528;&#x5168;&#x7D22;&#x5F15;&#x626B;&#x63CF;&#xFF0C;&#x4E0D;&#x8BBA;&#x662F;&#x5426;&#x8FBE;&#x5230;&#x6162;&#x67E5;&#x8BE2;&#x9600;&#x503C;&#x7684;&#x8BED;&#x53E5;&#x662F;&#x5426;&#x8BB0;&#x5F55;&#x65E5;&#x5FD7;&#xFF0C;&#x9ED8;&#x8BA4;OFF&#xFF0C;&#x5373;&#x4E0D;&#x8BB0;&#x5F55;
log_slow_rate_limit = 1 #&#x591A;&#x5C11;&#x6B21;&#x67E5;&#x8BE2;&#x624D;&#x8BB0;&#x5F55;&#xFF0C;mariadb&#x7279;&#x6709;
log_slow_verbosity= Query_plan,explain #&#x8BB0;&#x5F55;&#x5185;&#x5BB9;
log_slow_queries = OFF &#xA0; &#xA0;#&#x540C;slow_query_log&#xFF0C;MariaDB 10.0/MySQL 5.6.1 &#x7248;&#x540E;&#x5DF2;&#x5220;&#x9664;

select @@slow_query_log;

6.5 二进制日志(备份)

  • 记录导致数据改变或潜在导致数据改变的SQL语句
  • 记录已提交的日志
  • 不依赖于存储引擎类型

功能:通过”重放”日志文件中的事件来生成数据副本
注意:建议二进制日志和数据文件分开存放
二进制日志记录三种格式

  • 基于” 语句“记录:statement,记录语句,默认模式( MariaDB 10.2.3 版本以下 ),日志量较少
  • 基于” “记录:row,记录数据,日志量较大,更加安全,建议使用的格式,MySQL8.0默认格式
  • 混合模式:mixed, 让系统自行判定该基于哪种方式进行,默认模式( MariaDB 10.2.4及版本以上)

格式配置:

MariaDB [hellodb]> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | MIXED |
+---------------+-------+
1 row in set (0.001 sec)
#MySQL 8.0 &#x9ED8;&#x8BA4;&#x4F7F;&#x7528;ROW&#x65B9;&#x5F0F;
mysql> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW &#xA0; |
+---------------+-------+
1 row in set (0.07 sec)

二进制日志文件的构成

有两类文件
1.日志文件:mysql|mariadb-bin.文件名后缀,二进制格式,如: on.000001,mariadb-bin.000002
2.索引文件:mysql|mariadb-bin.index,文本格式,记录当前已有的二进制日志文件列表

二进制日志相关的服务器变量

  • sql_log_bin=ON|OFF:#是否记录二进制日志,默认ON,支持动态修改,系统变量,而非服务器选项
  • log_bin=/PATH/BIN_LOG_FILE:#指定文件位置;默认OFF,表示不启用二进制日志功能,上述两项都开启才可以
  • binlog_format=STATEMENT|ROW|MIXED:#二进制日志记录的格式,mariadb5.5默认STATEMENT
  • max_binlog_size=1073741824:#单个二进制日志文件的最大体积,到达最大值会自动滚动,默认为1G
  • 说明:文件达到上限时的大小未必为指定的精确值

  • binlog_cache_size=4m #此变量确定在每次事务中保存二进制日志更改记录的缓存的大小(每次连接)
  • max_binlog_cache_size=512m #限制用于缓存多事务查询的字节大小。
  • sync_binlog=1|0:#设定是否启动二进制日志即时同步磁盘功能,默认0,由操作系统负责同步日志到磁盘
  • expire_logs_days=N:#二进制日志可以自动删除的天数。 默认为0,即不自动删除

查看mariadb自行管理使用中的二进制日志文件列表,及大小

SHOW {BINARY | MASTER} LOGS &#xA0; &#xA0;

查看使用中的二进制日志文件

SHOW MASTER STATUS

在线查看二进制文件中的指定内容

SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]

#&#x8303;&#x4F8B;&#xFF1A;
show binlog events in 'mysql-bin.000001' from 6516 limit 2,3

mysqlbinlog

二进制日志的客户端命令工具,支持离线查看二进制日志
命令格式:

mysqlbinlog [OPTIONS] log_file&#x2026;
 --start-position=# &#x6307;&#x5B9A;&#x5F00;&#x59CB;&#x4F4D;&#x7F6E;
 --stop-position=#
 --start-datetime= &#xA0;#&#x65F6;&#x95F4;&#x683C;&#x5F0F;&#xFF1A;YYYY-MM-DD hh:mm:ss
 --stop-datetime=
 --base64-output[=name]
 &#xA0; &#xA0; &#xA0; &#xA0;-v -vvv
使用范例
mysqlbinlog --start-position=678 --stop-position=752 /var/lib/mysql/mariadbbin.000003 -v
mysqlbinlog &#xA0;--start-datetime="2018-01-30 20:30:10" &#xA0; --stop-datetime="2018-01-30 20:35:22" mariadb-bin.000003 -vvv
范例: 同步远程主机的二进制日志
#&#x4ECE;10.0.0.8&#x8FDC;&#x7A0B;&#x4E3B;&#x673A;&#x5B9E;&#x65F6;&#x540C;&#x6B65;&#x4E8C;&#x8FDB;&#x5236;&#x65E5;&#x5FD7;binlog.000002&#x5F00;&#x59CB;&#x5411;&#x540E;&#x8FDB;&#x884C;&#x540C;&#x6B65;&#x5230;&#x5F53;&#x524D;&#x76EE;&#x5F55;
[root@centos8 data]#mysqlbinlog -R --host=10.0.0.8 --user=test --password=123456 --raw --stop-never binlog.000002

清除指定二进制日志

PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr }

#&#x8303;&#x4F8B;
PURGE BINARY LOGS TO 'mariadb-bin.000003'; #&#x5220;&#x9664;mariadb-bin.000003&#x4E4B;&#x524D;&#x7684;&#x65E5;&#x5FD7;
PURGE BINARY LOGS BEFORE '2017-01-23';
PURGE BINARY LOGS BEFORE '2017-03-22 09:25:30';

删除所有二进制日志,index文件重新记数

RESET MASTER [TO #];
#&#x5220;&#x9664;&#x6240;&#x6709;&#x4E8C;&#x8FDB;&#x5236;&#x65E5;&#x5FD7;&#x6587;&#x4EF6;&#xFF0C;&#x5E76;&#x91CD;&#x65B0;&#x751F;&#x6210;&#x65E5;&#x5FD7;&#x6587;&#x4EF6;&#xFF0C;&#x6587;&#x4EF6;&#x540D;&#x4ECE;#&#x5F00;&#x59CB;&#x8BB0;&#x6570;&#xFF0C;
#&#x9ED8;&#x8BA4;&#x4ECE;1&#x5F00;&#x59CB;&#xFF0C;&#x4E00;&#x822C;&#x662F;master&#x4E3B;&#x673A;&#x7B2C;&#x4E00;&#x6B21;&#x542F;&#x52A8;&#x65F6;&#x6267;&#x884C;&#xFF0C;MariaDB 10.1.6&#x5F00;&#x59CB;&#x652F;&#x6301;TO #

切换日志文件

FLUSH LOGS;

五、MySQL 备份和恢复

1 备份恢复概述

Mysql实战技能全解

1.1 备份类型

  • 完全备份,部分备份

完全备份:整个数据集
部分备份:只备份数据子集,如部分库或表

  • 完全备份、增量备份、差异备份

增量备份:仅备份最近一次完全备份或增量备份(如果存在增量)以来变化的数据,备份较快,还原复杂
差异备份:仅备份最近一次完全备份以来变化的数据,备份较慢,还原简单
注意:二进制日志文件不应该与数据文件放在同一磁盘

  • 冷、温、热备份

冷备:读、写操作均不可进行,数据库停止服务
温备:读操作可执行;但写操作不可执行
热备:读、写操作均可执行
MyISAM:温备,不支持热备
InnoDB:都支持

  • 物理和逻辑备份

物理备份:直接复制数据文件进行备份,与存储引擎有关,占用较多的空间,速度快
逻辑备份:从数据库中”导出”数据另存而进行的备份,与存储引擎无关,占用空间少,速度慢,可能丢失精度

1.2 实战案例:数据库冷备份和还原

#MySQL8.0
#&#x5907;&#x4EFD;&#x8FC7;&#x7A0B;
[root@centos8 ~]#systemctl stop mysqld
#&#x5907;&#x4EFD;&#x6570;&#x636E;
[root@centos8 ~]#rsync -a /var/lib/mysql 10.0.0.28:/data/
#&#x5982;&#x679C;&#x914D;&#x7F6E;&#x53CA;&#x4E8C;&#x8FDB;&#x5236;&#x6587;&#x4EF6;&#x76F8;&#x5173;&#x6709;&#x7279;&#x6B8A;&#x8BBE;&#x7F6E;&#x4E5F;&#x9700;&#x8981;&#x5907;&#x4EFD;
#&#x8FD8;&#x539F;
[root@centos8 ~]#yum -y install mysql-server
[root@centos8 ~]#cp -a /data/mysql/* /var/lib/mysql/
[root@centos8 ~]#systemctl start mysqld

#Mariadb10.3
#&#x5728;&#x76EE;&#x6807;&#x670D;&#x52A1;&#x5668;&#xFF08;10.0.0.18&#xFF09;&#x5B89;&#x88C5;mariadb-server&#xFF0C;&#x4E0D;&#x542F;&#x52A8;&#x670D;&#x52A1;
[root@centos8 ~]#dnf install mariadb-server
#&#x5728;&#x6E90;&#x4E3B;&#x673A;&#xFF08;10.0.0.8&#xFF09;&#x6267;&#x884C;
[root@centos8 ~]# systemctl stop mariadb
#&#x590D;&#x5236;&#x76F8;&#x5173;&#x6587;&#x4EF6;
[root@centos8 ~]# scp -r /var/lib/mysql/* 10.0.0.18:/var/lib/mysql/
[root@centos8 ~]# scp /etc/my.cnf.d/mariadb-server.cnf 10.0.0.18:/etc/my.cnf.d/
[root@centos8 ~]# scp -r /data/logbin/ 10.0.0.18:/data/ &#xA0; #10.0.0.18&#x987B;&#x4E8B;&#x5148;&#x5B58;&#x5728;/data/&#x76EE;&#x5F55;
#&#x590D;&#x5236;&#x76F8;&#x5173;&#x6587;&#x4EF6;&#x5E76;&#x4FDD;&#x7559;&#x5C5E;&#x6027;&#xFF1A;&#x53EF;&#x4EE5;&#x7528;rsync
[root@centos8 ~]#rsync /etc/my.cnf.d/mariadb-server.cnf 10.0.0.18:/etc/my.cnf.d/
[root@centos8 ~]#rsync -av /var/lib/mysql/ 10.0.0.18:/var/lib/mysql/
[root@centos8 ~]#rsync -av/data/logbin/ 10.0.0.18:/data/ &#xA0; #10.0.0.18 &#x987B;&#x4E8B;&#x5148;&#x5B58;&#x5728;/data/&#x76EE;&#x5F55;
#&#x5728;&#x76EE;&#x6807;&#x4E3B;&#x673A;&#xFF08;10.0.0.18&#xFF09;&#x6267;&#x884C;
[root@centos8 ~]#chown -R mysql.mysql /var/lib/mysql/
[root@centos8 ~]#chown -R mysql.mysql /data/logbin/
[root@centos8 ~]#systemctl start mariadb

2 mysqldump 备份工具

2.1 mysqldump 说明

命令格式 :

mysqldump [OPTIONS] database [tables] &#xA0; #&#x652F;&#x6301;&#x6307;&#x5B9A;&#x6570;&#x636E;&#x5E93;&#x548C;&#x6307;&#x5B9A;&#x591A;&#x8868;&#x7684;&#x5907;&#x4EFD;&#xFF0C;&#x4F46;&#x6570;&#x636E;&#x5E93;&#x672C;&#x8EAB;&#x5B9A;&#x4E49;&#x4E0D;&#x5907;&#x4EFD;
mysqldump [OPTIONS] -B DB1 [DB2 DB3...] #&#x652F;&#x6301;&#x6307;&#x5B9A;&#x6570;&#x636E;&#x5E93;&#x5907;&#x4EFD;&#xFF0C;&#x5305;&#x542B;&#x6570;&#x636E;&#x5E93;&#x672C;&#x8EAB;&#x5B9A;&#x4E49;&#x4E5F;&#x4F1A;&#x5907;&#x4EFD;
mysqldump [OPTIONS] -A [OPTIONS] &#xA0; &#xA0; &#xA0; &#xA0;#&#x5907;&#x4EFD;&#x6240;&#x6709;&#x6570;&#x636E;&#x5E93;&#xFF0C;&#x5305;&#x542B;&#x6570;&#x636E;&#x5E93;&#x672C;&#x8EAB;&#x5B9A;&#x4E49;&#x4E5F;&#x4F1A;&#x5907;&#x4EFD;

mysqldump 常见通用选项:

  • -u, –user=name User for login if not current user
  • -p, –password[=name] Password to use when connecting to server
  • -A, –all-databases #备份所有数据库,含create database
  • -B, –databases db_name… #指定备份的数据库,包括create database语句
  • -E, –events:#备份相关的所有event scheduler
  • -R, –routines:#备份所有存储过程和自定义函数
  • –triggers:#备份表相关触发器,默认启用,用–skip-triggers,不备份触发器
  • –default-character-set=utf8 #指定字符集

  • –master-data[=#]:#注意:MySQL8.0.26版以后,此选项变为–source-data

  • 此选项须启用二进制日志

  • #1:所备份的数据之前 加一条记录为CHANGE MASTER TO语句,非注释,不指定#, 默认为1适合于主从复制多机使用
  • #2:记录为被注释的#CHANGE MASTER TO语句,适合于单机使用,适用于备份还原
  • 此选项会自动关闭–lock-tables功能,自动打开-x | –lock-all-tables功能(除非开启–single-transaction)

  • -F, –flush-logs #备份前滚动日志,锁定表完成后,执行flush logs命令,生成新的二进制日志文件,配合-A 或 -B 选项时,会导致刷新多次数据库。建议在同一时刻执行转储和日志刷新 ,可通过和–single-transaction或-x ,–master-data 一起使用实现,此时只刷新一次二进制日志

  • –compact #去掉注释,适合调试,节约备份占用的空间,生产不使用
  • -d, –no-data #只备份表结构,不备份数据,即只备份create table
  • -t, –no-create-info #只备份数据,不备份表结构,即不备份create table
  • -n,–no-create-db #不备份create database,可被-A或-B覆盖
  • –flush-privileges #备份mysql或相关时需要使用
  • -f, –force #忽略SQL错误,继续执行
  • –hex-blob #使用十六进制符号转储二进制列,当有包括BINARY,VARBINARY,BLOB,BIT的数据类型的列时使用,避免乱码
  • -q, –quick #不缓存查询,直接输出,加快备份速度

mysqldump MyISAM 存储引擎相关的备份选项:
MyISAM不支持事务,只能支持温备;不支持热备,所以必须先锁定要备份的库,而后启动备份操作

  • -x,–lock-all-tables #加全局读锁,锁定所有库的所有表,同时加–single-transaction或–lock-tables选项会关闭此选项功能,注意:数据量大时,可能会导致长时间无法并发访问数据库
  • -l,–lock-tables #对于需要备份的每个数据库,在启动备份之前分别锁定其所有表,默认为on,–skip-lock-tables选项可禁用,对备份MyISAM的多个库,可能会造成数据不一致

注:以上选项对InnoDB表一样生效,实现温备,但不推荐使用

mysqldump InnoDB 存储引擎相关的备份选项:
InnoDB 存储引擎支持事务,可以利用事务的相应的隔离级别,实现热备,也可以实现温备但不建议用

  • *–single-transaction

此选项Innodb中推荐使用,且 不会锁表!不适用MyISAM,此选项会开始备份前,先执行START TRANSACTION指令开启事务

此选项通过在单个事务中转储所有表来创建一致的快照。 仅适用于存储在支持多版本控制的存储引擎中的表(目前只有InnoDB可以); 转储不保证与其他存储引擎保持一致。 在进行单事务转储时,要确保有效的转储文件(正确的表内容和二进制日志位置),没有其他连接应该使用以下语句:ALTER TABLE,DROP TABLE,RENAME TABLE,TRUNCATE TABLE,此选项和–lock-tables(此选项隐含提交挂起的事务)选项是相互排斥,备份大型表时,建议将–single-transaction选项和–quick结合一起使用

2.2 生产环境实战备份策略

InnoDB建议备份策略

mysqldump -uroot -p -A -F -E -R --triggers --single-transaction --master-data=1 \
--flush-privileges --default-character-set=utf8 --hex-blob >${BACKUP}/fullbak_${BACKUP_TIME}.sql

MyISAM建议备份策略

mysqldump -uroot -p -A -F -E -R -x --master-data=1 --flush-privileges &#xA0;\
--triggers &#xA0;--default-character-set=utf8 &#xA0;--hex-blob>${BACKUP}/fullbak_${BACKUP_TIME}.sql

2.3 mysqldump 备份还原实战案例

实战案例:特定数据库的备份脚本

[root@centos8 ~]#cat mysql_backup.sh
#!/bin/bash
TIME=date +%F_%H-%M-%S
DIR=/backup
DB=hellodb
PASS=123456
[ -d $DIR ] || mkdir $DIR
mysqldump -uroot -p "$PASS" -F --triggers --single-transaction --master-data=2 -B $DB | gzip > ${DIR}/${DB}_${TIME}.sql.gz

#&#x53EA;&#x7528;&#x4E0A;&#x9762;&#x7684;&#x53C2;&#x6570;&#x8DB3;&#x591F;&#x4E86;
mysqldump -uroot -p "$PASS" -F -E -R --triggers --single-transaction --master-data=2 --default-character-set=utf8 -q -B $DB | gzip > ${DIR}/${DB}_${TIME}.sql.gz

实战案例:分库备份的实战脚本

[root@centos8 ~]#cat backup_db.sh
#!/bin/bash
TIME=date +%F_%H-%M-%S
DIR=/backup
PASS=123456
[ -d "$DIR" ] || mkdir $DIR
for DB in mysql -uroot -p "$PASS" -e 'show databases' | grep -Ev "^Database|.*schema$";do
    mysqldump -F --single-transaction --master-data=2 -B $DB | gzip > ${DIR}/${DB}_${TIME}.sql.gz
done

#&#x53EA;&#x7528;&#x4E0A;&#x9762;&#x7684;&#x53C2;&#x6570;&#x8DB3;&#x591F;&#x4E86;
mysqldump -F --single-transaction --master-data=2 --default-character-set=utf8 -q -B $DB | gzip > &#xA0;${DIR}/${DB}_${TIME}.sql.gz

实战案例:恢复误删除的表

案例说明:每天2:30做完全备份,早上10:00误删除了表students,10:10才发现故障,现需要将数据库还原到10:10的状态,且恢复被删除的students表

#&#x5B8C;&#x5168;&#x5907;&#x4EFD;,&#x8981;&#x6C42;&#x5FC5;&#x987B;&#x5F00;&#x542F;&#x4E8C;&#x8FDB;&#x5236;&#x65E5;&#x5FD7;(@@sql_log_bin&#x548C;@@log_bin)
[root@rocky01 ~]# mkdir /backup
[root@rocky01 ~]# mysqldump -uroot -p123456 -A -F --single-transaction --master-data=2 > /backup/allbackup_date +%F_%T.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.

#&#x6A21;&#x62DF;&#x5B8C;&#x5168;&#x5907;&#x4EFD;&#x540E;&#x6570;&#x636E;&#x66F4;&#x65B0;
MariaDB [testdb]> insert students (name,age,gender) values('rose',20,'f');
Query OK, 1 row affected (0.001 sec)
MariaDB [testdb]> insert students (name,age,gender) values('jack',22,'M');
Query OK, 1 row affected (0.001 sec)

#10&#xFF1A;00&#x8BEF;&#x5220;&#x9664;&#x4E86;&#x4E00;&#x4E2A;&#x91CD;&#x8981;&#x7684;&#x8868;
MariaDB [testdb]> drop table students;
Query OK, 0 rows affected (0.021 sec)

#&#x6A21;&#x62DF;&#x540E;&#x7EED;&#x5176;&#x5B83;&#x8868;&#x7EE7;&#x7EED;&#x66F4;&#x65B0;
MariaDB [testdb]> use hellodb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MariaDB [hellodb]> insert teachers (name,age,gender)values('wang',30,'M');
Query OK, 1 row affected (0.002 sec)
MariaDB [hellodb]> insert teachers (name,age,gender)values('mage',28,'M');
Query OK, 1 row affected (0.002 sec)
MariaDB [hellodb]> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;| Age | Gender |
+-----+---------------+-----+--------+
| &#xA0; 1 | Song Jiang &#xA0; &#xA0;| &#xA0;45 | M &#xA0; &#xA0; &#xA0;|
| &#xA0; 2 | Zhang Sanfeng | &#xA0;94 | M &#xA0; &#xA0; &#xA0;|
| &#xA0; 3 | Miejue Shitai | &#xA0;77 | F &#xA0; &#xA0; &#xA0;|
| &#xA0; 4 | Lin Chaoying &#xA0;| &#xA0;93 | F &#xA0; &#xA0; &#xA0;|
| &#xA0; 5 | wang &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;| &#xA0;30 | M &#xA0; &#xA0; &#xA0;|
| &#xA0; 6 | mage &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;| &#xA0;28 | M &#xA0; &#xA0; &#xA0;|
+-----+---------------+-----+--------+
6 rows in set (0.001 sec)

#10&#xFF1A;10&#x53D1;&#x73B0;&#x8868;&#x5220;&#x9664;&#xFF0C;&#x8FDB;&#x884C;&#x8FD8;&#x539F;
#&#x505C;&#x6B62;&#x6570;&#x636E;&#x5E93;&#x8BBF;&#x95EE;
#&#x4ECE;&#x5B8C;&#x5168;&#x5907;&#x4EFD;&#x4E2D;&#xFF0C;&#x627E;&#x5230;&#x4E8C;&#x8FDB;&#x5236;&#x4F4D;&#x7F6E;
[root@rocky01 ~]# grep '\-\- CHANGE MASTER TO' allbackup_2022-10-31_14\:52\:32.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='binlog.000008', MASTER_LOG_POS=156;

#&#x5907;&#x4EFD;&#x4ECE;&#x5B8C;&#x5168;&#x5907;&#x4EFD;&#x540E;&#x7684;&#x4E8C;&#x8FDB;&#x5236;&#x65E5;&#x5FD7;&#xFF0C;&#x82E5;&#x751F;&#x6210;&#x4E86;&#x65B0;&#x6587;&#x4EF6;bin.000009&#x7B49;&#xFF09;&#xFF0C;&#x5219;&#x8FFD;&#x52A0;
[root@rocky01 ~]# mysqlbinlog --start-position=156 /var/lib/mysql/binlog.000008 > /backup/inc.sql
[root@rocky01 ~]# mysqlbinlog /var/lib/mysql/mariadb-bin.000009 >> /backup/inc.sql
[root@rocky01 ~]# mysqlbinlog /var/lib/mysql/mariadb-bin.000010 >> /backup/inc.sql

#&#x627E;&#x5230;&#x8BEF;&#x5220;&#x9664;&#x7684;&#x8BED;&#x53E5;&#xFF0C;&#x4ECE;&#x5907;&#x4EFD;&#x4E2D;&#x5220;&#x9664;&#x6B64;&#x8BED;&#x53E5;
[root@rocky01 ~]# vim /backup/inc.sql
#DROP TABLE students /* generated by server */
#&#x5982;&#x679C;&#x6587;&#x4EF6;&#x8FC7;&#x5927;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;sed&#x5B9E;&#x73B0;
[root@rocky01 ~]# sed -i '/^DROP TABLE students/d' /backup/inc.sql

#&#x5229;&#x7528;&#x5B8C;&#x5168;&#x5907;&#x4EFD;&#x548C;&#x4FEE;&#x6539;&#x8FC7;&#x7684;&#x4E8C;&#x8FDB;&#x5236;&#x65E5;&#x5FD7;&#x8FDB;&#x884C;&#x8FD8;&#x539F;
[root@rocky02 ~]# mysql -uroot -p
MariaDB [hellodb]> set sql_log_bin=0;
MariaDB [hellodb]> source /backup/allbackup_2019-11-27_10:20:08.sql;
MariaDB [hellodb]> source /backup/inc.sql
MariaDB [hellodb]> set sql_log_bin=1;

3 xtrabackup 备份工具

percona提供的mysql数据库备份工具,惟一开源的能够对innodb和xtradb数据库进行热备的工具
xtrabackup 特点:

  • 备份还原过程快速、可靠
  • 备份过程不会打断正在执行的事务
  • 能够基于压缩等功能节约磁盘空间和流量
  • 自动实现备份检验
  • 开源,免费

下载地址

3.1 xtrabackup 用法

xtrabackup工具备份和还原,需要三步实现

  1. 备份:对数据库做完全或增量备份
  2. 预准备: 还原前,先对备份的数据,整理至一个临时目录
  3. 还原:将整理好的数据,复制回数据库目录中

  4. –user:#该选项表示备份账号

  5. –password:#该选项表示备份的密码
  6. –host:#该选项表示备份数据库的地址
  7. –databases:#该选项接受的参数为数据库名,如果要指定多个数据库,彼此间需要以空格隔开;

如:”xtra_test dba_test”,同时,在指定某数据库时,也可以只指定其中的某张表。
如:”mydatabase.mytable”。该选项对innodb引擎表无效,还是会备份所有innodb表

  • –defaults-file:#该选项指定从哪个文件读取MySQL配置,必须放在命令行第一个选项位置
  • –incremental:#该选项表示创建一个增量备份,需要指定–incremental-basedir
  • –incremental-basedir:#该选项指定为前一次全备份或增量备份的目录,与–incremental同时使用
  • –incremental-dir:#该选项表示还原时增量备份的目录
  • –include=name:#指定表名,格式:databasename.tablename

实战案例:利用 xtrabackup 实现完全备份及还原

#&#x5229;&#x7528;xtrabackup8.0 &#x5B8C;&#x5168;&#x5907;&#x4EFD;&#x548C;&#x8FD8;&#x539F;MySQL8.0
#1 &#x5B89;&#x88C5;xtrabackup&#x5305;
[root@centos8 ~]#yum -y install percona-xtrabackup-80-8.0.23-16.1.el8.x86_64.rpm

#2 &#x5728;&#x539F;&#x4E3B;&#x673A;&#x505A;&#x5B8C;&#x5168;&#x5907;&#x4EFD;&#x5230;/backup/base
[root@centos8 ~]#mkdir /backup
[root@centos8 ~]#xtrabackup -uroot -p123456 --backup --target-dir=/backup/base
#&#x76EE;&#x6807;&#x4E3B;&#x673A;&#x65E0;&#x9700;&#x521B;&#x5EFA;/backup&#x76EE;&#x5F55;,&#x76F4;&#x63A5;&#x590D;&#x5236;&#x76EE;&#x5F55;&#x672C;&#x8EAB;
[root@centos8 ~]#scp -r /backup/ &#xA0; &#x76EE;&#x6807;&#x4E3B;&#x673A;:/

#3 &#x5728;&#x76EE;&#x6807;&#x4E3B;&#x673A;&#x4E0A;&#x8FD8;&#x539F;
#&#x6CE8;&#x610F;&#xFF1A;&#x6062;&#x590D;&#x4E3B;&#x673A;MySQL&#x670D;&#x52A1;&#x505C;&#x6B62;&#xFF0C;&#x5E76;&#x4E14;&#x6570;&#x636E;&#x76EE;&#x5F55;&#x4E3A;&#x7A7A;
#1&#xFF09;&#x9884;&#x51C6;&#x5907;&#xFF1A;&#x786E;&#x4FDD;&#x6570;&#x636E;&#x4E00;&#x81F4;&#xFF0C;&#x63D0;&#x4EA4;&#x5B8C;&#x6210;&#x7684;&#x4E8B;&#x52A1;&#xFF0C;&#x56DE;&#x6EDA;&#x672A;&#x5B8C;&#x6210;&#x7684;&#x4E8B;&#x52A1;
[root@centos8 ~]#yum -y install percona-xtrabackup-80-8.0.23-16.1.el8.x86_64.rpm
[root@centos8 ~]#xtrabackup --prepare --target-dir=/backup/base
#2&#xFF09;&#x590D;&#x5236;&#x5230;&#x6570;&#x636E;&#x5E93;&#x76EE;&#x5F55;
#&#x6CE8;&#x610F;&#xFF1A;&#x6570;&#x636E;&#x5E93;&#x76EE;&#x5F55;&#x5FC5;&#x987B;&#x4E3A;&#x7A7A;&#xFF0C;MySQL&#x670D;&#x52A1;&#x4E0D;&#x80FD;&#x542F;&#x52A8;
[root@centos8 ~]#xtrabackup --copy-back --target-dir=/backup/base
#3&#xFF09;&#x8FD8;&#x539F;&#x5C5E;&#x6027;
[root@centos8 ~]#chown -R mysql:mysql /var/lib/mysql
#4&#xFF09;&#x542F;&#x52A8;&#x670D;&#x52A1;
[root@centos8 ~]#service mysqld start

实战案例:利用xtrabackup完全,增量备份及还原

#&#x5229;&#x7528;xtrabackup8.0 &#x5B8C;&#x5168;&#x3001;&#x589E;&#x91CF;&#x5907;&#x4EFD;&#x53CA;&#x8FD8;&#x539F;MySQL8.0
#1 &#x5907;&#x4EFD;&#x8FC7;&#x7A0B;
#1&#xFF09;&#x5B8C;&#x5168;&#x5907;&#x4EFD;&#xFF1A;
[root@centos8 ~]#yum -y install percona-xtrabackup-24-2.4.20-1.el8.x86_64.rpm
[root@centos8 ~]#mkdir /backup/
[root@centos8 ~]#xtrabackup -uroot -p123456 --backup --target-dir=/backup/base

#2&#xFF09;&#x6A21;&#x62DF;&#x7B2C;&#x4E00;&#x6B21;&#x4FEE;&#x6539;&#x6570;&#x636E;
mysql>insert students (name,age,gender) values('rose',20,'f');
#3&#xFF09;&#x7B2C;&#x4E00;&#x6B21;&#x589E;&#x91CF;&#x5907;&#x4EFD;
[root@centos8 ~]#xtrabackup -uroot -p123456 --backup --target-dir=/backup/inc1 --incremental-basedir=/backup/base

#4&#xFF09;&#x6A21;&#x62DF;&#x7B2C;&#x4E8C;&#x6B21;&#x4FEE;&#x6539;&#x6570;&#x636E;
mysql>insert students (name,age,gender) values('jack',22,'M');
#5&#xFF09;&#x7B2C;&#x4E8C;&#x6B21;&#x589E;&#x91CF;
[root@centos8 ~]#xtrabackup -uroot -p123456 --backup --target-dir=/backup/inc2 --incremental-basedir=/backup/inc1

#6&#xFF09;[root@centos8 ~]#scp -r /backup/* &#x76EE;&#x6807;&#x4E3B;&#x673A;:/backup/
#&#x5907;&#x4EFD;&#x8FC7;&#x7A0B;&#x751F;&#x6210;&#x4E09;&#x4E2A;&#x5907;&#x4EFD;&#x76EE;&#x5F55;/backup/{base&#xFF0C;inc1&#xFF0C;inc2}

#2&#x8FD8;&#x539F;&#x8FC7;&#x7A0B;
#1&#xFF09;&#x9884;&#x51C6;&#x5907;&#x5B8C;&#x6210;&#x5907;&#x4EFD;&#xFF0C;&#x6B64;&#x9009;&#x9879;--apply-log-only &#x963B;&#x6B62;&#x56DE;&#x6EDA;&#x672A;&#x5B8C;&#x6210;&#x7684;&#x4E8B;&#x52A1;
[root@centos8 ~]#yum -y install percona-xtrabackup-24-2.4.20-1.el8.x86_64.rpm
[root@centos8 ~]#xtrabackup --prepare --apply-log-only --target-dir=/backup/base

#2&#xFF09;&#x5408;&#x5E76;&#x7B2C;1&#x6B21;&#x589E;&#x91CF;&#x5907;&#x4EFD;&#x5230;&#x5B8C;&#x5168;&#x5907;&#x4EFD;
[root@centos8 ~]#xtrabackup --prepare --apply-log-only --target-dir=/backup/base --incremental-dir=/backup/inc1

#3&#xFF09;&#x5408;&#x5E76;&#x7B2C;2&#x6B21;&#x589E;&#x91CF;&#x5907;&#x4EFD;&#x5230;&#x5B8C;&#x5168;&#x5907;&#x4EFD;&#xFF1A;&#x6700;&#x540E;&#x4E00;&#x6B21;&#x8FD8;&#x539F;&#x4E0D;&#x9700;&#x8981;&#x52A0;&#x9009;&#x9879;--apply-log-only
[root@centos8 ~]#xtrabackup --prepare --target-dir=/backup/base --incremental-dir=/backup/inc2

#4&#xFF09;&#x590D;&#x5236;&#x5230;&#x6570;&#x636E;&#x5E93;&#x76EE;&#x5F55;&#xFF0C;&#x6CE8;&#x610F;&#x6570;&#x636E;&#x5E93;&#x76EE;&#x5F55;&#x5FC5;&#x987B;&#x4E3A;&#x7A7A;&#xFF0C;MySQL&#x670D;&#x52A1;&#x4E0D;&#x80FD;&#x542F;&#x52A8;
[root@centos8 ~]#xtrabackup --copy-back --target-dir=/backup/base

#5&#xFF09;&#x8FD8;&#x539F;&#x5C5E;&#x6027;&#xFF1A;
[root@centos8 ~]#chown -R mysql:mysql /var/lib/mysql
#6&#xFF09;&#x542F;&#x52A8;&#x670D;&#x52A1;&#xFF1A;
[root@centos8 ~]#service mysqld start

六、MySQL 集群 Cluster

1 MySQL 主从复制

1.1 主从复制架构和原理

(1)MySQL的主从复制

  • 读写分离
  • 复制:每个节点都有相同的数据集,向外扩展,基于二进制日志的单向复制

(2)主从复制原理

主从复制相关线程

  • 主节点:

dump Thread 为每个Slave的I/O Thread启动一个dump线程,用于向其发送binary log events

  • 从节点:

I/O Thread 向Master请求二进制日志事件,并保存于中继日志中
SQL Thread 从中继日志中读取日志事件,在本地完成重放
跟复制功能相关的文件:

  • master.info:用于保存slave连接至master时的相关信息,例如账号、密码、服务器地址等
  • relay-log.info:保存在当前slave节点上已经复制的当前二进制日志和本地relay log日志的对应关系
  • mysql-relay-bin.00000#: 中继日志,保存从主节点复制过来的二进制日志,本质就是二进制日志

复制需要考虑二进制日志事件记录格式

  • STATEMENT(5.0之前), Mariadb5.5 默认使用此格式
  • ROW(5.1之后,推荐),MySQL 8.0 默认使用此格式
  • MIXED: Mariadb10.3 默认使用此格式

Mysql实战技能全解

1.2 实现主从复制配置

主节点配置

(1) 启用二进制日志

[mysqld]
log_bin

(2) 为当前节点设置一个全局惟一的ID号

[mysqld]
server-id=#

#&#x8BF4;&#x660E;&#xFF1A;
#server-id&#x7684;&#x53D6;&#x503C;&#x8303;&#x56F4;
#1 to 4294967295 (>= MariaDB 10.2.2)&#xFF0C;&#x9ED8;&#x8BA4;&#x503C;&#x4E3A;1&#xFF0C;MySQL8.0&#x9ED8;&#x8BA4;&#x503C;&#x4E3A;1
#0 to 4294967295 (<= mariadb 10.2.1),默认值为0,如果从节点为0,所有master都将拒绝此slave的连接< code></=>

(3) 查看从二进制日志的文件和位置开始进行复制

SHOW MASTER STATUS;

(4) 创建有复制权限的用户账号

GRANT REPLICATION SLAVE ON *.* TO 'repluser'@'HOST' IDENTIFIED BY '123456';

#MySQL8.0 &#x5206;&#x6210;&#x4E24;&#x6B65;&#x5B9E;&#x73B0;
mysql> create user repluser@'10.0.0.%' identified by '123456';
mysql> grant replication slave on *.* to repluser@'10.0.0.%';

从节点配置

(1) 启动中继日志(二进制日志)

[mysqld]
server_id=# #&#x4E3A;&#x5F53;&#x524D;&#x8282;&#x70B9;&#x8BBE;&#x7F6E;&#x4E00;&#x4E2A;&#x5168;&#x5C40;&#x60DF;&#x7684;ID&#x53F7;
log-bin
read_only=ON #&#x8BBE;&#x7F6E;&#x6570;&#x636E;&#x5E93;&#x53EA;&#x8BFB;&#xFF0C;&#x9488;&#x5BF9;supper user&#x8D85;&#x7EA7;&#x7528;&#x6237;&#x65E0;&#x6548;

(2) 使用有复制权限的用户账号连接至主服务器,并启动复制线程

CHANGE MASTER TO
  MASTER_HOST='masterhost',
  MASTER_USER='repluser',
  MASTER_PASSWORD='123456',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='mariadb-bin.xxxxxx',
  MASTER_LOG_POS=
  MASTER_DELAY=3; #&#x53EF;&#x6307;&#x5B9A;&#x5EF6;&#x8FDF;&#x590D;&#x5236;&#x5B9E;&#x73B0;&#x8BBF;&#x95EE;&#x8BEF;&#x64CD;&#x4F5C;&#xFF08;&#x9ED8;&#x8BA4;10s&#xFF09;,&#x5355;&#x4F4D;&#x79D2;

start slave [IO_THREAD|SQL_THREAD];
SHOW SLAVE STATUS;
#&#x67E5;&#x770B; relaylog &#x4E8B;&#x4EF6;
SHOW RELAYLOG EVENTS in 'relay-bin.00000x';

1.3 主从复制相关命令

从节点清除信息

#&#x6CE8;&#x610F;&#xFF1A;&#x4EE5;&#x4E0B;&#x90FD;&#x9700;&#x8981;&#x5148; STOP SLAVE
RESET SLAVE #&#x4ECE;&#x670D;&#x52A1;&#x5668;&#x6E05;&#x9664;master.info &#xFF0C;relay-log.info, relay log &#xFF0C;&#x5F00;&#x59CB;&#x65B0;&#x7684;relay log
RESET SLAVE ALL #&#x6E05;&#x9664;&#x6240;&#x6709;&#x4ECE;&#x670D;&#x52A1;&#x5668;&#x4E0A;&#x8BBE;&#x7F6E;&#x7684;&#x4E3B;&#x670D;&#x52A1;&#x5668;&#x540C;&#x6B65;&#x4FE1;&#x606F;&#xFF0C;&#x5982;HOST&#xFF0C;PORT, USER&#x548C; PASSWORD &#x7B49;

跳过复制错误

可以在从服务器忽略几个主服务器的复制事件,此为global变量,或指定跳过事件的ID
注意: Centos 8.1以上版本上的MariaDB10.3主从节点同时建同名的库和表不会冲突,建主键记录会产生冲突

#&#x7CFB;&#x7EDF;&#x53D8;&#x91CF;&#xFF0C;&#x6307;&#x5B9A;&#x8DF3;&#x8FC7;&#x590D;&#x5236;&#x4E8B;&#x4EF6;&#x7684;&#x4E2A;&#x6570;
SET GLOBAL sql_slave_skip_counter = N

#&#x670D;&#x52A1;&#x5668;&#x9009;&#x9879;&#xFF0C;&#x53EA;&#x8BFB;&#x7CFB;&#x7EDF;&#x53D8;&#x91CF;&#xFF0C;&#x6307;&#x5B9A;&#x8DF3;&#x8FC7;&#x4E8B;&#x4EF6;&#x7684;ID&#xFF1B;show slave status\G &#x53EF;&#x67E5;&#x770B;&#x5230;&#x9519;&#x8BEF;id
[mysqld]
slave_skip_errors=1007|ALL

START SLAVE 语句

START SLAVE [thread_types]
START SLAVE [SQL_THREAD] UNTIL MASTER_LOG_FILE = 'log_name', MASTER_LOG_POS = log_pos
START SLAVE [SQL_THREAD] UNTIL RELAY_LOG_FILE = 'log_name', RELAY_LOG_POS = log_pos

thread_types:
 &#xA0; &#xA0;[thread_type [, thread_type] ... ]
thread_type: IO_THREAD | SQL_THREAD

范例:主从复制(非新建)

模拟主服务器非新建时 , 主服务器运行一段时间后,新增从节点服务器

#&#x4E3B;&#x8282;&#x70B9;10.0.0.8
[root@master ~]#dnf -y install mysql-server
[root@master ~]#vim /etc/my.cnf
[mysqld]
server-id=8
log_bin=/data/logbin/mysql-bin
[root@master ~]#mkdir /data/logbin
[root@master ~]#chown mysql:mysql /data/logbin
[root@master ~]#systemctl restart mysqld

#&#x521B;&#x5EFA;&#x590D;&#x5236;&#x7528;&#x6237;
mysql>create user 'repluser'@'10.0.0.%' identified by '123456';
mysql>grant replication slave on *.* to 'repluser'@'10.0.0.%';
#&#x5982;&#x679C;&#x662F;MySQL8.0&#x4EE5;&#x4E0B;&#x7248;&#x672C;&#x53EF;&#x4E00;&#x6B65;&#x5B9E;&#x73B0;&#xFF08;&#x6388;&#x6743;&#x65F6;&#x82E5;&#x7528;&#x6237;&#x4E0D;&#x5B58;&#x5728;&#x4F1A;&#x81EA;&#x52A8;&#x521B;&#x5EFA;&#xFF09;
MariaDB [(none)]> grant replication slave on *.* to repluser@'10.0.0.%' identified by '123456';
#&#x5B8C;&#x5168;&#x5907;&#x4EFD;(&#x5148;&#x521B;&#x5EFA;&#x6388;&#x6743;&#x7528;&#x6237;&#x5728;&#x5907;&#x4EFD;&#x7684;&#x597D;&#x5904;&#xFF1A;&#x4E07;&#x4E00;&#x4ECE;&#x8282;&#x70B9;&#x6210;&#x4E86;&#x4E3B;&#x8282;&#x70B9;&#x4EE5;&#x540E;&#x5C31;&#x4E0D;&#x7528;&#x5728;&#x521B;&#x5EFA;&#x6388;&#x6743;&#x8D26;&#x53F7;&#x4E86;)
[root@master ~]#mysqldump -uroot -p123456 -A -F --single-transaction --master-data=1 > /backup/fullbackup_date +%F_%T.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.

[root@master ~]#scp -r /backup/ 10.0.0.18:/

#&#x4ECE;&#x8282;&#x70B9;10.0.0.18
[root@slave1 ~]#dnf -y install mysql-server
[root@slave1 ~]#vim /etc/my.cnf
[mysqld]
server-id=18
read-only #&#x53EA;&#x8BFB;&#xFF0C;&#x5EFA;&#x8BAE;&#x52A0;&#x4E0A;

[root@slave1 ~]#systemctl restart mysqld
[root@slave1 ~]#mysql
mysql> help change master to
[root@slave1 ~]#vim /backup/fullbackup_2022-10-31_21\:48\:48.sql
CHANGE MASTER TO
  MASTER_HOST='10.0.0.8',
  MASTER_USER='repluser',
  MASTER_PASSWORD='123456',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=156;

mysql> set sql_log_bin=0;
Query OK, 0 rows affected (0.00 sec)
mysql> source fullbackup_2022-10-31_21:48:48.sql;
mysql> set sql_log_bin=1;
Query OK, 0 rows affected (0.00 sec)

mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.000 sec)
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: 10.0.0.8
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 156
               Relay_Log_File: rocky02-relay-bin.000002
                Relay_Log_Pos: 324
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
...&#x7701;&#x7565;...

1 row in set, 1 warning (0.01 sec)

1.4 实现级联复制

需要在中间的从服务器启用以下配置 , 实现中间slave节点能将master的二进制日志在本机进行数据库更新,并且也同时更新本机的二进制,从而实现级联复制

[mysqld]
server-id=18
log_bin
log_slave_updates &#xA0; &#xA0; &#xA0;#&#x7EA7;&#x8054;&#x590D;&#x5236;&#x4E2D;&#x95F4;&#x8282;&#x70B9;&#x7684;&#x5FC5;&#x9009;&#x9879;,MySQL8.0&#x6B64;&#x4E3A;&#x9ED8;&#x8BA4;&#x503C;,&#x53EF;&#x4EE5;&#x4E0D;&#x8981;&#x4EBA;&#x4E3A;&#x6DFB;&#x52A0;,&#x5176;&#x5B83;&#x7248;&#x672C;&#x9ED8;&#x8BA4;&#x4E0D;&#x5F00;&#x542F;
read-only
#&#x5728;10.0.0.8&#x5145;&#x5F53;master
#&#x5728;10.0.0.18&#x5145;&#x5F53;&#x7EA7;&#x8054;slave
#&#x5728;10.0.0.28&#x5145;&#x5F53;slave
#&#x5728;master&#x5B9E;&#x73B0;
[root@centos8 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=8
log-bin &#xA0;
[root@centos8 ~]#systemctl restart mariadb
[root@centos8 ~]#mysql
MariaDB [(none)]> grant replication slave on *.* to repluser@'10.0.0.%' identified by '123456';
[root@centos8 ~]#mysqldump -A -F --single-transaction --master-data=1 > /data/all.sql
[root@centos8 ~]#scp /data/all.sql 10.0.0.18:/data
[root@centos8 ~]#scp /data/all.sql 10.0.0.28:/data

#&#x5728;&#x4E2D;&#x95F4;&#x7EA7;&#x8054;slave&#x5B9E;&#x73B0;
[root@centos8 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=18
log-bin
read-only
log_slave_updates &#xA0;#&#x7EA7;&#x8054;&#x590D;&#x5236;&#x4E2D;&#x95F4;&#x8282;&#x70B9;&#x7684;&#x5FC5;&#x9009;&#x9879;,MySQL8.0&#x6B64;&#x4E3A;&#x9ED8;&#x8BA4;&#x503C;,&#x53EF;&#x4EE5;&#x4E0D;&#x8981;&#x4EBA;&#x4E3A;&#x6DFB;&#x52A0;
[root@centos8 ~]#systemctl restart mariadb
#&#x8FD8;&#x539F;&#x6570;&#x636E;&#x5E93;
[root@centos8 ~]#vim /data/all.sql
CHANGE MASTER TO
 &#xA0;MASTER_HOST='master&#x8282;&#x70B9;&#x7684;iP',
 &#xA0;MASTER_USER='repluser',
 &#xA0;MASTER_PASSWORD='centos',
 &#xA0;MASTER_PORT=3306,
 &#xA0;MASTER_LOG_FILE='mysql-bin.000004',
 &#xA0;MASTER_LOG_POS=523;
 &#xA0;
[root@centos8 ~]#mysql
MariaDB [(none)]> set sql_log_bin=0;
MariaDB [(none)]> source /data/all.sql
MariaDB [(none)]> show master logs; &#xA0;#&#x8BB0;&#x5F55;&#x4E8C;&#x8FDB;&#x5236;&#x4F4D;&#x7F6E;&#xFF0C;&#x7ED9;&#x7B2C;&#x4E09;&#x4E2A;&#x8282;&#x70B9;&#x4F7F;&#x7528; &#xA0;
MariaDB [(none)]> set sql_log_bin=0;
MariaDB [(none)]> start slave;

#&#x5728;&#x7B2C;&#x4E09;&#x4E2A;&#x8282;&#x70B9;slave&#x4E0A;&#x5B9E;&#x73B0;
[root@centos8 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
server-id=28
read-only
[root@centos8 ~]#systemctl restart mariadb
[root@centos8 ~]#vim /data/all.sql
CHANGE MASTER TO
MASTER_HOST='&#x4E2D;&#x95F4;&#x8282;&#x70B9;&#x7684;IP',
MASTER_USER='repluser',
MASTER_PASSWORD='123456',
MASTER_PORT=3306,
MASTER_LOG_FILE='mariadb-bin.000002', MASTER_LOG_POS=344;
[root@centos8 ~]#mysql < /data/all.sql
[root@centos8 ~]#mysql -e 'start slave;'

1.5 主主复制

主主复制:两个节点,都可以更新数据,并且互为主从
容易产生的问题:数据不一致;因此慎用
考虑要点:自动增长id
配置一个节点使用奇数id

auto_increment_offset=1 &#xA0; #&#x5F00;&#x59CB;&#x70B9;
auto_increment_increment=2 #&#x589E;&#x957F;&#x5E45;&#x5EA6;

另一个节点使用偶数id

auto_increment_offset=2
auto_increment_increment=2

主主复制的配置步骤:

  • (1) 各节点使用一个惟一server_id
  • (2) 都启动binary log和relay log
  • (3) 创建拥有复制权限的用户账号
  • (4) 定义自动增长id字段的数值范围各为奇偶
  • (5) 均把对方指定为主节点,并启动复制线程

1.6 半同步复制

  • 默认情况下,MySQL的复制功能是异步的 ,异步复制可以提供最佳的性能,主库把binlog日志发送给从库即结束,并不验证从库是否接收完毕。这意味着当主服务器或从服务器端发生故障时,有可能从服务器没有接收到主服务器发送过来的binlog日志,这就会造成主服务器和从服务器的数据不一致,甚至在恢复时造成数据的丢失
  • MySQL5.5版本为了保证主从数据的一致性问题。加入了 半同步复制的组件(插件),可以控制从库IO线程是否将relaylog落盘,一旦落盘通过插件返回ACK给主库ACK_REC。接受到ACK之后,主库的事务才能提交成功。在默认情况下,如果 超过10秒没有返回ACK,此次复制行为会切换为异步复制
  • 在MySQL5.6,5.7 当中也加入了一些比较好的特性,也不能完全保证的数据一致。如果生产业务比较关注主从最终一致(比如:金融等)。推荐可以使用MGR的架构,或者PXC等一致性架构

半同步复制默认设置

  • 缺点1: 幻读

当用户提交一个事务,该事务已经写入redo日志和binlog日志,但该事务还没写入从库,
此时处在waiting slave dump处,此时另一个用户可以读取到这条数据,而他自己却不能;

  • 缺点2:数据丢失

一个提交的事务在waiting slave dump处crash后,主库将比从库多一条数据

rpl_semi_sync_master_wait_point=after_commit

增强半同步复制(MySQL5.7新增功能)

  • 改善1:解决幻读

当用户发起一个事务,该事务先写入二进制后,再向从库进行同步,由于还没有完成提交,
此时其他用户无法读取到该数据,解决了幻读

  • 改善2:解决数据丢失

一个事务在waiting slave dump处crash掉后,可以通过观察从库上是否存在主库的last gtid值,
如果存在,这条数据正常恢复,如果不存在则删除主库的那条多余的GTID值,然后恢复,保证了数据的完整性

rpl_semi_rsync_master_wait_point=after_sync

范例:MySQL8.0 实现半同步复制

#&#x524D;&#x63D0;&#xFF1A;&#x5DF2;&#x5B8C;&#x6210;&#x4E3B;&#x4ECE;&#xFF08;&#x9ED8;&#x8BA4;&#x7684;&#x5F02;&#x6B65;&#x590D;&#x5236;&#xFF09;
#&#x67E5;&#x770B;&#x63D2;&#x4EF6;&#x6587;&#x4EF6;
[root@rocky01 ~]# rpm -ql mysql-server |grep semisync
/usr/lib64/mysql/plugin/semisync_master.so
/usr/lib64/mysql/plugin/semisync_slave.so

#master&#x670D;&#x52A1;&#x5668;10.0.0.8&#x914D;&#x7F6E;
[root@master ~]# mysql
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; #&#x6C38;&#x4E45;&#x5B89;&#x88C5;&#x63D2;&#x4EF6;
mysql> SHOW PLUGINS; #&#x67E5;&#x770B;&#x63D2;&#x4EF6;
[root@master ~]# vim /etc/my.cnf
[mysqld]
server-id=8
log_bin=/data/logbin/mysql-bin
rpl_semi_sync_master_enabled=ON    #&#x4FEE;&#x6539;&#x6B64;&#x884C;,&#x9700;&#x8981;&#x5148;&#x5B89;&#x88C5;semisync_master.so&#x63D2;&#x4EF6;&#x540E;,&#x518D;&#x91CD;&#x542F;,&#x5426;&#x5219;&#x65E0;&#x6CD5;&#x542F;&#x52A8;
rpl_semi_sync_master_timeout=3000  #&#x8BBE;&#x7F6E;3s&#x5185;&#x65E0;&#x6CD5;&#x540C;&#x6B65;&#xFF08;&#x9ED8;&#x8BA4;10s&#xFF09;&#xFF0C;&#x4E5F;&#x5C06;&#x8FD4;&#x56DE;&#x6210;&#x529F;&#x4FE1;&#x606F;&#x7ED9;&#x5BA2;&#x6237;&#x7AEF;
[root@master ~]# systemctl restart mysqld

#slave1&#x670D;&#x52A1;&#x5668;10.0.0.18&#x914D;&#x7F6E;
[root@slave1 ~]# mysql
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';#&#x6C38;&#x4E45;&#x5B89;&#x88C5;&#x63D2;&#x4EF6;
[root@slave1 ~]#vim /etc/my.cnf
[mysqld]
server-id=18
read-only
rpl_semi_sync_slave_enabled=ON    #&#x4FEE;&#x6539;&#x6B64;&#x884C;,&#x9700;&#x8981;&#x5148;&#x5B89;&#x88C5;semisync_slave.so&#x63D2;&#x4EF6;&#x540E;,&#x518D;&#x91CD;&#x542F;,&#x5426;&#x5219;&#x65E0;&#x6CD5;&#x542F;&#x52A8;
[root@slave1 ~]# systemctl restart mysqld

#slave2&#x670D;&#x52A1;&#x5668;10.0.0.28&#x914D;&#x7F6E;
[root@slave2 ~]# mysql
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';#&#x6C38;&#x4E45;&#x5B89;&#x88C5;&#x63D2;&#x4EF6;
[root@slave2 ~]#vim /etc/my.cnf
[mysqld]
server-id=28
read-only
rpl_semi_sync_slave_enabled=ON    #&#x4FEE;&#x6539;&#x6B64;&#x884C;,&#x9700;&#x8981;&#x5148;&#x5B89;&#x88C5;semisync_slave.so&#x63D2;&#x4EF6;&#x540E;,&#x518D;&#x91CD;&#x542F;,&#x5426;&#x5219;&#x65E0;&#x6CD5;&#x542F;&#x52A8;
[root@slave2 ~]# systemctl restart mysqld

#&#x4EE5;&#x4E0A;&#x6B65;&#x9AA4;&#x5DF2;&#x5B8C;&#x6210;&#x534A;&#x540C;&#x6B65;&#x590D;&#x5236;&#xFF01;
#&#x4E3B;&#x670D;&#x52A1;&#x5668;&#x76F8;&#x5173;&#x547D;&#x4EE4;:
mysql>UNINSTALL PLUGIN rpl_semi_sync_master ; #&#x5378;&#x8F7D;&#x63D2;&#x4EF6;
mysql>SHOW PLUGINS; #&#x67E5;&#x770B;&#x63D2;&#x4EF6;
mysql>SET GLOBAL rpl_semi_sync_master_enabled=1; #&#x4E34;&#x65F6;&#x4FEE;&#x6539;&#x53D8;&#x91CF;
mysql>SET GLOBAL rpl_semi_sync_master_timeout = 3000; &#xA0;#&#x4E34;&#x65F6;&#x8D85;&#x65F6;&#x957F;1s,&#x9ED8;&#x8BA4;&#x503C;&#x4E3A;10s

mysql>SHOW GLOBAL VARIABLES LIKE '%semi%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | ON         |
| rpl_semi_sync_master_timeout              | 3000       |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set (0.00 sec)

mysql> SHOW GLOBAL STATUS LIKE '%semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 2     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 4     |
| Rpl_semi_sync_master_no_times              | 1     |
| Rpl_semi_sync_master_no_tx                 | 1     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 669   |
| Rpl_semi_sync_master_tx_wait_time          | 1339  |
| Rpl_semi_sync_master_tx_waits              | 2     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 2     |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)

#&#x4ECE;&#x670D;&#x52A1;&#x5668;&#x76F8;&#x5173;&#x547D;&#x4EE4;:
mysql>SET GLOBAL rpl_semi_sync_slave_enabled=1; #&#x4E34;&#x65F6;&#x4FEE;&#x6539;&#x53D8;&#x91CF;

mysql> SHOW GLOBAL VARIABLES LIKE '%semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.00 sec)

#&#x6CE8;&#x610F;:&#x5982;&#x679C;&#x5DF2;&#x7ECF;&#x5B9E;&#x73B0;&#x4E3B;&#x4ECE;&#x590D;&#x5236;,&#x9700;&#x8981;stop slave;start slave;
mysql> stop slave;
mysql> start slave;
mysql> SHOW GLOBAL STATUS LIKE '%semi%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.00 sec)

1.7 复制过滤器

让从节点仅复制指定的数据库,或指定数据库的指定表
复制过滤器两种实现方式:
(1) 服务器选项:主服务器仅向二进制日志中记录与特定数据库相关的事件

  • 缺点:基于二进制还原将无法实现;不建议使用
  • 优点: 只需要在主节点配置一次即可
vim /etc/my.cnf
binlog-do-db=db1 #&#x6570;&#x636E;&#x5E93;&#x767D;&#x540D;&#x5355;&#x5217;&#x8868;&#xFF0C;&#x4E0D;&#x652F;&#x6301;&#x540C;&#x65F6;&#x6307;&#x5B9A;&#x591A;&#x4E2A;&#x503C;&#xFF0C;&#x5982;&#x679C;&#x60F3;&#x5B9E;&#x73B0;&#x591A;&#x4E2A;&#x6570;&#x636E;&#x5E93;&#x9700;&#x591A;&#x884C;&#x5B9E;&#x73B0;
binlog-do-db=db2
binlog-ignore-db= #&#x6570;&#x636E;&#x5E93;&#x9ED1;&#x540D;&#x5355;&#x5217;&#x8868;

(2) 从服务器SQL_THREAD在relay log中的事件时,仅读取与特定数据库(特定表)相关的事件并应用于本地

  • 缺点:会造成网络及磁盘IO浪费,在所有从节点都要配置
  • 优点: 不影响二进制备份还原
#&#x4ECE;&#x670D;&#x52A1;&#x5668; &#x4E0A;&#x7684;&#x590D;&#x5236;&#x8FC7;&#x6EE4;&#x5668;&#x76F8;&#x5173;&#x53D8;&#x91CF;
replicate_do_db="db1,db2,db3" #&#x6307;&#x5B9A;&#x590D;&#x5236;&#x5E93;&#x7684;&#x767D;&#x540D;&#x5355;&#xFF0C;&#x53D8;&#x91CF;&#x53EF;&#x4EE5;&#x6307;&#x5B9A;&#x9017;&#x53F7;&#x5206;&#x9694;&#x7684;&#x591A;&#x4E2A;&#x503C;&#xFF0C;&#x9009;&#x9879;&#x4E0D;&#x652F;&#x6301;&#x591A;&#x503C;,&#x53EA;&#x80FD;&#x5206;&#x522B;&#x5199;&#x591A;&#x884C;&#x5B9E;&#x73B0;
replicate_ignore_db= #&#x6307;&#x5B9A;&#x590D;&#x5236;&#x5E93;&#x9ED1;&#x540D;&#x5355;
replicate_do_table= #&#x6307;&#x5B9A;&#x590D;&#x5236;&#x8868;&#x7684;&#x767D;&#x540D;&#x5355;
replicate_ignore_table= #&#x6307;&#x5B9A;&#x590D;&#x5236;&#x8868;&#x7684;&#x9ED1;&#x540D;&#x5355;
replicate_wild_do_table= foo%.bar% &#xA0;#&#x652F;&#x6301;&#x901A;&#x914D;&#x7B26;
replicate_wild_ignore_table=

1.8 GTID复制

GTID 优点 :

  • 保证事务全局统一
  • 截取日志更加方便。跨多文件,判断起点终点更加方便
  • 判断主从工作状态更加方便
  • 传输日志, 可以并发传输。SQL回放可以更高并发
  • 主从复制构建更加方便

  • GTID = server_uuid:transaction_id,在一组复制中,全局唯一

  • server_uuid 来源于 /var/lib/mysql/auto.cnf

1.8.1 GTID服务器相关选项

gtid_mode #gtid&#x6A21;&#x5F0F;
enforce_gtid_consistency #&#x4FDD;&#x8BC1;GTID&#x5B89;&#x5168;&#x7684;&#x53C2;&#x6570;

1.8.2 GTID配置范例

(1)主服务器
vim /etc/my.cnf
server-id=8
gtid_mode=ON
enforce_gtid_consistency
log-bin=mysql-bin

systemctl restart mysqld
mysql> grant replication slave on *.* to 'repluser'@'10.0.0.%' identified by '123456';
(2)从服务器
vim /etc/my.cnf
server-id=18
gtid_mode=ON
enforce_gtid_consistency

systemctl restart mysqld

#&#x5982;&#x679C;&#x4E3B;&#x670D;&#x52A1;&#x5668;&#x548C;&#x4ECE;&#x670D;&#x52A1;&#x5668;&#x6570;&#x636E;&#x4E0D;&#x4E00;&#x81F4;,&#x9700;&#x8981;&#x5148;&#x5C06;&#x4E3B;&#x5E93;&#x6570;&#x636E;&#x5907;&#x4EFD;&#x8FD8;&#x539F;&#x81F3;&#x4ECE;&#x5E93;,&#x518D;&#x6267;&#x884C;&#x4E0B;&#x9762;&#x64CD;&#x4F5C;
mysqldump -A --master-data=2 > /backup/full.sql
mysql>CHANGE MASTER TO MASTER_HOST='10.0.0.8',
 MASTER_USER='repluser',
 MASTER_PASSWORD='123456',
 MASTER_PORT=3306,
 MASTER_AUTO_POSITION=1; &#xA0;#&#x4F7F;&#x7528;GTID

 mysql>start slave;
#&#x6CE8;&#x610F;&#x89C2;&#x5BDF;:Retrieved_Gtid_set&#x548C;Executed_Gtid_Set&#x8FD9;&#x4E24;&#x4E2A;&#x503C;,
#&#x5BF9;&#x6BD4;&#x4E3B;&#x8282;&#x70B9;&#x6267;&#x884C;show master status&#x7684;&#x503C;,&#x5982;&#x679C;&#x76F8;&#x540C;&#x8868;&#x793A;&#x540C;&#x6B65;&#x5B8C;&#x6210;

1.9 MySQL 主从数据不一致(面试重点)

原因

  • 主库binlog格式为Statement,同步到从库执行后可能造成主从不一致。
  • 主库执行更改前有执行set sql_log_bin=0,会使主库不记录binlog,从库也无法变更这部分数据。
  • 从节点未设置只读,误操作写入数据
  • 主库或从库意外宕机,宕机可能会造成binlog或者relaylog文件出现损坏,导致主从不一致
  • 主从实例版本不一致,特别是高版本是主,低版本为从的情况下,主数据库上面支持的功能,从数据库上面可能不支持该功能
  • 主从sql_mode 不一致
  • *MySQL自身bug导致

修复方法

  • 将从库重新实现

虽然这也是一种解决方法,但是这个方案恢复时间比较慢,而且有时候从库也是承担一部分的查询操作的,不能贸然重建。

  • 使用percona-toolkit工具辅助

PT工具包中包含pt-table-checksum和pt-table-sync两个工具,主要用于检测主从是否一致以及修复数据不一致情况。这种方案优点是修复速度快,不需要停止主从辅助,缺点是需要知识积累,需要时间去学习,去测试,特别是在生产环境,还是要小心使用

  • 手动重建不一致的表

在从库发现某几张表与主库数据不一致,而这几张表数据量也比较大,手工比对数据不现实,并且重做整个库也比较慢,这个时候可以只重做这几张表来修复主从不一致这种方案缺点是在执行导入期间需要暂时停止从库复制,不过也是可以接受的
范例:A,B,C这三张表主从数据不一致

#1&#x3001;&#x4ECE;&#x5E93;&#x505C;&#x6B62;Slave&#x590D;&#x5236;
mysql>stop slave;

#2&#x3001;&#x5728;&#x4E3B;&#x5E93;&#x4E0A;dump&#x8FD9;&#x4E09;&#x5F20;&#x8868;&#xFF0C;&#x5E76;&#x8BB0;&#x5F55;&#x4E0B;&#x540C;&#x6B65;&#x7684;binlog&#x548C;POS&#x70B9;
mysqldump -uroot -p123456 -q --single-transaction --master-data=2 testdb A B C >/backup/A_B_C.sql

#3&#x3001;&#x67E5;&#x770B;A_B_C.sql&#x6587;&#x4EF6;&#xFF0C;&#x627E;&#x51FA;&#x8BB0;&#x5F55;&#x7684;binlog&#x548C;POS&#x70B9;
head A_B_C.sql
#&#x4F8B;&#x5982;:MASTERLOGFILE='mysql-bin.000002', MASTERLOGPOS=123;

#&#x4EE5;&#x4E0B;&#x6307;&#x4EE4;&#x662F;&#x4E3A;&#x4E86;&#x4FDD;&#x969C;&#x5176;&#x4ED6;&#x8868;&#x7684;&#x6570;&#x636E;&#x4E0D;&#x4E22;&#x5931;&#xFF0C;&#x4E00;&#x76F4;&#x540C;&#x6B65;&#x76F4;&#x5230;&#x90A3;&#x4E2A;&#x70B9;&#x7ED3;&#x675F;&#xFF0C;
#A,B,C&#x8868;&#x7684;&#x6570;&#x636E;&#x5728;&#x4E4B;&#x524D;&#x7684;&#x5907;&#x4EFD;&#x5DF2;&#x7ECF;&#x751F;&#x6210;&#x4E86;&#x4E00;&#x4EFD;&#x5FEB;&#x7167;&#xFF0C;&#x53EA;&#x9700;&#x8981;&#x5BFC;&#x5165;&#x8FDB;&#x5165;&#xFF0C;&#x7136;&#x540E;&#x5F00;&#x542F;&#x540C;&#x6B65;&#x5373;&#x53EF;
#4&#x3001;&#x628A;A_B_C.sql&#x62F7;&#x8D1D;&#x5230;Slave&#x673A;&#x5668;&#x4E0A;&#xFF0C;&#x5E76;&#x505A;&#x6307;&#x5411;&#x65B0;&#x4F4D;&#x7F6E;
mysql>start slave until MASTERLOGFILE='mysql-bin.000002', MASTERLOGPOS=123;

#5&#x3001;&#x5728;Slave&#x673A;&#x5668;&#x4E0A;&#x5BFC;&#x5165;A_B_C.sql
mysql -uroot -p123456 testdb
mysql>set sql_log_bin=0;
mysql>source /backup/A_B_C.sql
mysql>set sql_log_bin=1;

#6&#x3001;&#x5BFC;&#x5165;&#x5B8C;&#x6BD5;&#x540E;&#xFF0C;&#x4ECE;&#x5E93;&#x5F00;&#x542F;&#x540C;&#x6B65;&#x5373;&#x53EF;&#x3002;
mysql>start slave;

如何避免

  • 主库binlog采用ROW格式
  • 主从实例数据库版本保持一致
  • 主库做好账号权限把控,不可以执行set sql_log_bin=0
  • 从库开启只读,不允许人为写入
  • *定期进行主从一致性检验

2 MySQL 中间件代理服务器

Mysql实战技能全解

2.1 Mycat

基于心跳的自动故障切换,支持读写分离,支持MySQL主从,以及galera cluster集群
配置文件:

  • server.xml Mycat软件本身相关的配置文件,设置账号、参数等
  • schema.xml Mycat对应的物理数据库和数据库表的配置,读写分离、高可用、分布式策略定制、节点控制

2.1.1 Mycat 安装

#&#x6CE8;&#xFF1A;&#x4EE5;&#x4E0B;&#x64CD;&#x4F5C;&#x672A;&#x5B9E;&#x73B0;&#x8BFB;&#x5199;&#x5206;&#x79BB;
#1.&#x4E0B;&#x8F7D;&#x5B89;&#x88C5;JDK
yum -y install java
#&#x786E;&#x8BA4;&#x5B89;&#x88C5;&#x6210;&#x529F;
java -version

#2.&#x4E0B;&#x8F7D;&#x5B89;&#x88C5;mycat
wget http://dl.mycat.org.cn/1.6.7.4/Mycat-server-1.6.7.4-release/Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz
mkdir /apps
tar xvf Mycat-server-1.6.7.4-release-20200105164103-linux.tar.gz -C /apps

#3.&#x914D;&#x7F6E;&#x73AF;&#x5883;&#x53D8;&#x91CF;
vim /etc/profile.d/mycat.sh
PATH=/apps/mycat/bin:$PATH
source /etc/profile.d/mycat.sh

#4.&#x542F;&#x52A8;&#x5E76;&#x67E5;&#x770B;&#x65E5;&#x5FD7;&#xFF0C;&#x786E;&#x5B9A;&#x6210;&#x529F;
mycat start
cat /app/mycat/logs/wrapper.log
...&#x7701;&#x7565;...

INFO &#xA0; | jvm 1 &#xA0; | 2019/11/01 21:41:02 | MyCAT Server startup successfully. see logs in logs/mycat.log

#5.&#x8FDE;&#x63A5;mycat&#xFF1A;
mysql -uroot -p123456 -h 127.0.0.1 -P8066

实战案例:Mycat 实现读写分离

服务器共三台

mycat 10.0.0.88 #&#x5185;&#x5B58;&#x5EFA;&#x8BAE;2G&#x4EE5;&#x4E0A;
master 10.0.0.8 MySQL 8.0 &#x6216;&#x8005;Mariadb 10.3.17
slave &#xA0;10.0.0.18 MySQL 8.0 &#x6216;&#x8005;Mariadb 10.3.17

关闭 SELinux 和防火墙

systemctl stop firewalld
setenforce 0
&#x65F6;&#x95F4;&#x540C;&#x6B65;

(1)创建 MySQL 主从数据库

(2) 安装 mycat 并启动

(3) mycat 服务器上修改 server.xml 文件配置 Mycat 的连接信息

[root@mycat ~]# vim /apps/mycat/conf/server.xml
...&#x7701;&#x7565;...

#&#x4FEE;&#x6539;&#x4E0B;&#x9762;&#x884C;&#x7684;8066&#x6539;&#x4E3A;3306&#x590D;&#x5236;&#x5230;&#x5230;&#x72EC;&#x7ACB;&#x975E;&#x6CE8;&#x91CA;&#x884C;
<property name="serverPort">3306</property>
<property name="handlelDistributedTransactions">0</property> #&#x5C06;&#x4E0A;&#x9762;&#x884C;&#x653E;&#x5728;&#x6B64;&#x884C;&#x524D;&#x9762;

#&#x6216;&#x8005;&#x5220;&#x9664;&#x6CE8;&#x91CA;,&#x5E76;&#x4FEE;&#x6539;&#x4E0B;&#x9762;&#x884C;&#x7684;8066&#x6539;&#x4E3A;3306
<property name="serverPort">3306</property>
<property name="managerPort">9066</property>
<property name="idleTimeout">300000</property>
<property name="authTimeout">15000</property>
<property name="bindIp">0.0.0.0</property>
<property name="dataNodeIdleCheckPeriod">300000</property> #5 * 60 * 1000L; //&#x8FDE;&#x63A5;&#x7A7A;&#x95F2;&#x68C0;&#x67E5; &#x5220;&#x9664;#&#x540E;&#x9762;&#x6B64;&#x90E8;&#x5206;
<property name="frontWriteQueueSize">4096</property> <property name="processors">32</property> #--> &#x5220;&#x9664;#&#x540E;&#x9762;&#x6B64;&#x90E8;&#x5206;
 .....

<user name="root"> &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;  #&#x8FDE;&#x63A5;Mycat&#x7684;&#x7528;&#x6237;&#x540D;
 &#xA0; <property name="password">123456</property> &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;#&#x8FDE;&#x63A5;Mycat&#x7684;&#x5BC6;&#x7801;
 &#xA0; <property name="schemas">TESTDB</property> &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; #&#x6570;&#x636E;&#x5E93;&#x540D;&#x8981;&#x548C;schema.xml&#x76F8;&#x5BF9;&#x5E94;
</user>

#&#x8FD9;&#x91CC;&#x4F7F;&#x7528;&#x7684;&#x662F;root&#xFF0C;&#x5BC6;&#x7801;&#x4E3A;123456,&#x903B;&#x8F91;&#x6570;&#x636E;&#x5E93;&#x4E3A;TESTDB&#xFF0C;&#x8FD9;&#x4E9B;&#x4FE1;&#x606F;&#x90FD;&#x53EF;&#x4EE5;&#x81EA;&#x5DF1;&#x968F;&#x610F;&#x5B9A;&#x4E49;,
#&#x8BFB;&#x5199;&#x6743;&#x9650;&#x90FD;&#x6709;&#xFF0C;&#x6CA1;&#x6709;&#x9488;&#x5BF9;&#x8868;&#x505A;&#x4EFB;&#x4F55;&#x7279;&#x6B8A;&#x7684;&#x6743;&#x9650;&#x3002;&#x91CD;&#x70B9;&#x5173;&#x6CE8;&#x4E0A;&#x9762;&#x8FD9;&#x6BB5;&#x914D;&#x7F6E;&#xFF0C;&#x5176;&#x4ED6;&#x9ED8;&#x8BA4;&#x5373;&#x53EF;&#x3002;

Mysql实战技能全解

(4)修改schema.xml实现读写分离策略

###  &#x5148;&#x5220;&#x9664;&#x6240;&#x6709;<!--  --> &#x548C;<table></table> &#x7684;&#x5185;&#x5BB9;&#x5728;&#x5BF9;&#x7167;&#x4E0B;&#x9762;&#x7684;&#x589E;&#x5220;&#x6539;  ###
[root@mycat ~]# cat /apps/mycat/conf/schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
    <schema name="TESTDB" checksqlschema="false" sqlmaxlimit="100" datanode="dn1">
    </schema>
    <datanode name="dn1" datahost="localhost1" database="hellodb">
    <datahost name="localhost1" maxcon="1000" mincon="10" balance="1" writetype="0" dbtype="mysql" dbdriver="native" switchtype="1" slavethreshold="100">
        <heartbeat>select user()</heartbeat>
        <writehost host="host1" url="10.0.0.8:3306" user="admin" password="123456">
         <readhost host="host2" url="10.0.0.18:3306" user="admin" password="123456">
        </readhost></writehost>
    </datahost>
</datanode></mycat:schema>

###&#x4E0A;&#x9762;&#x914D;&#x7F6E;&#x4E2D;&#xFF0C;balance&#x6539;&#x4E3A;1&#xFF0C;&#x8868;&#x793A;&#x8BFB;&#x5199;&#x5206;&#x79BB;&#x3002;
###&#x9700;&#x8981;&#x8D4B;&#x4E88;&#x4E0A;&#x9762;admin&#x8D26;&#x53F7;&#x6240;&#x6709;&#x6743;&#x9650;*.*
###&#x4EE5;&#x4E0A;&#x914D;&#x7F6E;&#x8FBE;&#x5230;&#x7684;&#x6548;&#x679C;&#x5C31;&#x662F;10.0.0.18&#x4E3A;&#x4E3B;&#x5E93;&#xFF0C;10.0.0.28&#x4E3A;&#x4ECE;&#x5E93;&#x3002;&#x5B9E;&#x73B0;&#x7684;&#x662F;hellodb&#x6570;&#x636E;&#x5E93;&#x7684;&#x8BFB;&#x5199;&#x5206;&#x79BB;
###checkSQLschema &#x6570;&#x636E;&#x5E93;&#x524D;&#x7F00;&#x76F8;&#x5173;&#x8BBE;&#x7F6E;&#xFF0C;&#x8FD9;&#x91CC;&#x4E3A;false
###balance="0": &#x4E0D;&#x5F00;&#x542F;&#x8BFB;&#x5199;&#x5206;&#x79BB;&#xFF0C;&#x8BFB;&#x64CD;&#x4F5C;&#x548C;&#x5199;&#x64CD;&#x4F5C;&#x90FD;&#x662F;&#x7528;&#x7684;writeHost&#xFF1B;
###balance="1": &#x5F00;&#x542F;&#x8BFB;&#x5199;&#x5206;&#x79BB;&#xFF0C;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#x662F;&#x5B58;&#x5728;&#x591A;&#x4E3B;&#x591A;&#x4ECE;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x4E00;&#x4E2A;&#x4E3B;&#x8282;&#x70B9;&#x63D0;&#x4F9B;&#x5199;&#x64CD;&#x4F5C;&#xFF0C;&#x5176;&#x4ED6;&#x7684;&#x4E3B;&#x8282;&#x70B9;&#x548C;&#x6240;&#x6709;&#x4ECE;&#x8282;&#x70B9;&#x63D0;&#x4F9B;&#x8D1F;&#x8F7D;&#x5747;&#x8861;&#x7684;&#x8BFB;&#x64CD;&#x4F5C;
###balance="2": &#x8BFB;&#x64CD;&#x4F5C;&#x968F;&#x673A;&#x8BFB;&#x9009;&#x62E9;&#x4E3B;&#x8282;&#x70B9;&#x548C;&#x4ECE;&#x8282;&#x70B9;
###balance="3": &#x5F00;&#x542F;&#x8BFB;&#x5199;&#x5206;&#x79BB;&#xFF0C;&#x5199;&#x64CD;&#x4F5C;&#x4F7F;&#x7528;&#x5199;&#x4E3B;&#x673A;&#xFF08;&#x4E3B;&#x8282;&#x70B9;&#x4E5F;&#x5C31;&#x662F;&#x5199;&#x4E3B;&#x673A;&#xFF0C;&#x4ECE;&#x8282;&#x70B9;&#x662F;&#x8BFB;&#x4E3B;&#x673A;&#xFF09;&#xFF0C;&#x8BFB;&#x64CD;&#x4F5C;&#x4F7F;&#x7528;&#x8BFB;&#x4E3B;

(5)重新启动mycat

[root@mycat ~]# mycat restart

(6)在主服务器创建用户并对mycat授权

#mysql -uroot -p
mysql>GRANT ALL ON *.* TO 'admin'@'10.0.0.%' IDENTIFIED BY '123456' ;
mysql> flush privileges;

(7)在 Mycat 服务器上连接并测试

[root@mycat ~]# mysql -uroot -p123456 -h127.0.0.1 TESTDB
mysql> show databases;
+----------+
| DATABASE |
+----------+
| TESTDB &#xA0; | &#xA0; //&#x53EA;&#x80FD;&#x770B;&#x4E00;&#x4E2A;&#x865A;&#x62DF;&#x6570;&#x636E;&#x5E93;

(8)通过通用日志确认实现读写分离

#&#x5728;mysql&#x4E2D;&#x67E5;&#x770B;&#x901A;&#x7528;&#x65E5;&#x5FD7;&#x65B9;&#x6CD5;&#x5982;&#x4E0B;
show variables like 'general_log'; &#xA0;#&#x67E5;&#x770B;&#x65E5;&#x5FD7;&#x662F;&#x5426;&#x5F00;&#x542F;
set global general_log=on; &#xA0; &#xA0;#&#x5F00;&#x542F;&#x65E5;&#x5FD7;&#x529F;&#x80FD;
show variables like 'general_log_file'; #&#x67E5;&#x770B;&#x65E5;&#x5FD7;&#x6587;&#x4EF6;&#x4FDD;&#x5B58;&#x4F4D;&#x7F6E;
set global general_log_file='tmp/general.log'; #&#x8BBE;&#x7F6E;&#x65E5;&#x5FD7;&#x6587;&#x4EF6;&#x4FDD;&#x5B58;&#x4F4D;&#x7F6E;

#&#x5728;&#x4E3B;&#x548C;&#x4ECE;&#x670D;&#x52A1;&#x5668;&#x5206;&#x522B;&#x542F;&#x7528;&#x901A;&#x7528;&#x65E5;&#x5FD7;&#xFF0C;&#x67E5;&#x770B;&#x8BFB;&#x5199;&#x5206;&#x79BB;&#xFF08;&#x4E0B;&#x9762;&#x7684;&#x662F;&#x4E3B;&#x8282;&#x70B9;&#xFF0C;&#x4ECE;&#x8282;&#x70B9;&#x64CD;&#x4F5C;&#x4E00;&#x6837;&#xFF09;
[root@master ~]# vim /etc/my.cnf.d/mariadb-server.cnf
[mysqld]
general_log=ON
[root@master ~]# systemctl restart mariadb
[root@master ~]# tail -f /var/lib/mysql/master.log

(9)MyCAT对后端服务器的健康性检查方法select user()

#mycat&#x5224;&#x65AD;&#x6570;&#x636E;&#x5E93;&#x5F97;&#x5B58;&#x6D3B;&#x6027;&#xFF0C;&#x5B9A;&#x671F;&#x53D1;&#x9001;(&#x9ED8;&#x8BA4;5&#x79D2;/&#x6B21;) select user()
#&#x67E5;&#x770B;&#x901A;&#x7528;&#x65E5;&#x5FD7;
[root@master ~]# tail -f /var/lib/mysql/master.log
/usr/libexec/mysqld, Version: 8.0.17 (Source distribution). started with:
Tcp port: 3306 Unix socket: /var/lib/mysql/mysql.sock
Time &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; Id Command &#xA0; Argument
2021-02-22T08:52:57.086198Z &#xA0; 17 Query select user()
2021-02-22T08:53:07.086340Z &#xA0; 24 Query select user()
2021-02-22T08:53:17.086095Z &#xA0; 16 Query select user()
2021-02-22T08:53:27.086629Z &#xA0; 18 Query select user()

#&#x505C;&#x6B62;&#x4ECE;&#x8282;&#x70B9;&#xFF0C;MyCAT&#x81EA;&#x52A8;&#x8C03;&#x5EA6;&#x201C;&#x8BFB;&#x201D;&#x8BF7;&#x6C42;&#x81F3;&#x4E3B;&#x8282;&#x70B9;
#&#x505C;&#x6B62;&#x4E3B;&#x8282;&#x70B9;&#xFF0C;MyCAT&#x4E0D;&#x4F1A;&#x81EA;&#x52A8;&#x8C03;&#x5EA6;&#x201C;&#x5199;&#x201D;&#x8BF7;&#x6C42;&#x81F3;&#x4ECE;&#x8282;&#x70B9;

2.2 ProxySQL

暂略

3 MySQL 高可用

3.1 MHA Master High Availability

MHA 工作原理

  • MHA利用 SELECT 1 As Value 指令判断master服务器的健康性, 一旦master 宕机,MHA 从宕机崩溃的master保存二进制日志事件(binlog events) 识别含有最新更新的slave
  • 应用差异的中继日志(relay log)到其他的slave
  • 应用从master保存的二进制日志事件(binlog events)到所有slave节点
  • 提升一个slave为新的master
  • 使其他的slave连接新的master进行复制
  • 故障服务器自动被剔除集群(masterha_conf_host),将配置信息去掉
  • MHA是一次性的高可用性解决方案,Manager会自动退出*
    注意:
    为了尽可能的减少主库硬件损坏宕机造成的数据丢失,因此在配置MHA的同时
    建议配置成MySQL的半同步复制**

实战案例:实现 MHA

Mysql实战技能全解

环境:四台主机

  • 10.0.0.7 CentOS7 MHA管理端
  • 10.0.0.8 CentOS8 MySQL8.0 Master
  • 10.0.0.18 CentOS8 MySQL8.0 Slave1
  • 10.0.0.28 CentOS8 MySQL8.0 Slave2

说明

  • mha4mysql-manager-0.56-0.el6.noarch.rpm 不支持CentOS 8,只支持CentOS7 以下版本
  • mha4mysql-manager-0.58-0.el7.centos.noarch.rpm 支持MySQL5.7和MySQL8.0 ,但和CentOS8版本上的Mariadb -10.3.17不兼容

两个安装包

  • mha4mysql-manager
  • mha4mysql-node

下载地址

(1)在管理节点上安装两个包mha4mysql-manager和mha4mysql-node
#&#x6CE8;&#xFF1A;&#x9700;&#x8981;&#x914D;&#x7F6E;epel&#x6E90;&#xFF0C;&#x4E14;&#x5148;&#x5B89;&#x88C5;mha4mysql-node&#xFF0C;&#x5728;&#x5B89;&#x88C5;mha4mysql-manager
[root@MHA ~]# yum install -y mha4mysql-node-0.58-0.el7.centos.noarch.rpm
[root@MHA ~]# yum install -y mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

#&#x82E5;&#x51FA;&#x73B0;&#x4EE5;&#x4E0B;&#x9519;&#x8BEF;:Requires: perl(:MODULE_COMPAT_5.10.1),&#x66F4;&#x65B0;epel&#x5373;&#x53EF;
[root@MHA ~]#  yum install epel-release -y
(2)在所有MySQL服务器上安装mha4mysql-node包
[root@master ~]# yum install -y mha4mysql-node-0.58-0.el7.centos.noarch.rpm
[root@slave1 ~]# yum install -y mha4mysql-node-0.58-0.el7.centos.noarch.rpm
[root@slave2 ~]# yum install -y mha4mysql-node-0.58-0.el7.centos.noarch.rpm
(3)在所有节点实现相互之间ssh key验证
[root@MHA ~]# ssh-keygen
[root@MHA ~]# ssh-copy-id 127.0.0.1
[root@MHA ~]# cat .ssh/known_hosts
127.0.0.1 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIZoaMippL2cffS52fGVZF8UfywNMhFaVjFQ3LXHf6palT79jiSSBYODQgEM9O5caj9K/lu50LnkfTVq/OtEvw0=
10.0.0.7 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIZoaMippL2cffS52fGVZF8UfywNMhFaVjFQ3LXHf6palT79jiSSBYODQgEM9O5caj9K/lu50LnkfTVq/OtEvw0=
10.0.0.8 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLTQXGNANczi5/GMOn9K20r3rh8MWxloJI1xh1AURK0I2G+d7LznBH3LY6IUzT23xD1i5NXFjkGFkuHynSNTToA=
10.0.0.18 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLTQXGNANczi5/GMOn9K20r3rh8MWxloJI1xh1AURK0I2G+d7LznBH3LY6IUzT23xD1i5NXFjkGFkuHynSNTToA=
10.0.0.28 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLTQXGNANczi5/GMOn9K20r3rh8MWxloJI1xh1AURK0I2G+d7LznBH3LY6IUzT23xD1i5NXFjkGFkuHynSNTToA=

[root@MHA ~]# scp -rp .ssh/ 10.0.0.8:
[root@MHA ~]# scp -rp .ssh/ 10.0.0.18:
[root@MHA ~]# scp -rp .ssh/ 10.0.0.28:
(4)在管理节点建立配置文件

格式说明

  • user=mhauser #用于远程连接MySQL所有节点的用户,需要有管理员的权限
  • manager_workdir=/data/mastermha/app1/ #目录会自动生成,无需手动创建(MHA节点)
  • remote_workdir=/data/mastermha/app1/ #mysql节点上生成的目录
  • ssh_user=root #用于实现远程ssh基于KEY的连接,访问二进制日志
  • repl_user=repluser #主从复制的用户信息
  • ping_interval=1 #健康性检查的时间间隔(单位秒)
  • master_ip_failover_script=/usr/local/bin/master_ip_failover #切换VIP的perl脚本(官网已提供),不支持跨网络,也可用Keepalived实现
  • report_script=/usr/local/bin/sendmail.sh #当执行报警脚本
  • check_repl_delay=0 #默认值为1,表示如果slave中从库落后主库relay log超过100M,主库不会选择这个从库为新的master,因为这个从库进行恢复需要很长的时间.通过设置参数check_repl_delay=0,mha触发主从切换时会忽略复制的延时,对于设置candidate_master=1的从库非常有用,这样确保这个从库一定能成为最新的master
  • master_binlog_dir=/data/mysql/ #指定二进制日志存放的目录,mha4mysql-manager-0.58必须指定,之前版本不需要指定
  • candidate_master=1 #设置为优先候选master,即使不是集群中事件最新的slave,也会优先当master

说明 : 主库宕机谁来接管新的 master

  1. 所有从节点日志都是一致的,默认会以配置文件的顺序去选择一个新主
  2. 从节点日志不一致,自动选择最接近于主库的从库充当新主
  3. 如果对于某节点设定了权重(candidate_master=1),权重节点会优先选择。但是此节点日志量落后主库超过100M日志的话,也不会被选择。可以配合check_repl_delay=0,关闭日志量的检查,强制选择候选节点
#&#x6CE8;&#x610F;: &#x6B64;&#x6587;&#x4EF6;&#x7684;&#x884C;&#x5C3E;&#x4E0D;&#x8981;&#x52A0;&#x7A7A;&#x683C;&#x7B49;&#x7B26;&#x53F7;
[root@MHA ~]# mkdir /etc/mastermha/
[root@MHA ~]# vim /etc/mastermha/app1.cnf
[server default]
user=mhauser
password=123456
manager_workdir=/data/mastermha/app1/
manager_log=/data/mastermha/app1/manager.log
remote_workdir=/data/mastermha/app1/
ssh_user=root
repl_user=repluser
repl_password=123456
ping_interval=1
master_ip_failover_script=/usr/local/bin/master_ip_failover
report_script=/usr/local/bin/sendmail.sh
check_repl_delay=0
master_binlog_dir=/data/mysql/

[server1]
hostname=10.0.0.8
candidate_master=1
[server2]
hostname=10.0.0.18
candidate_master=1
[server3]
hostname=10.0.0.28
(5)相关脚本
sendmail.sh
[root@MHA ~]# chmod +x /usr/local/bin/sendmail.sh
[root@MHA ~]# cat /usr/local/bin/sendmail.sh
#!/bin/bash

#******************************************************
Author:          &#x4F1A;&#x4E0D;&#x4F1A;&#x6709;&#x90A3;&#x4E48;&#x4E00;&#x5929;
E-mail:          willoneday@qq.com
Date:            2022-11-03
FileName:        sendmail.sh
Version:         1.0.0
Description:     The test script
BLOG:            https://www.cnblogs.com/Willoneday
#******************************************************

echo "MHA is failover!" | mail -s "MHA Warning" willoneday@qq.com

#&#x82E5;&#x672A;&#x5B89;&#x88C5;&#x90AE;&#x4EF6;&#x670D;&#x52A1;&#x64CD;&#x4F5C;&#x5982;&#x4E0B;
[root@MHA ~]# yum install -y mailx
[root@MHA ~]# cat /etc/mail.rc
set from=willoneday@qq.com
set smtp=smtp.qq.com
set smtp-auth-user=willoneday@qq.com
set smtp-auth-password=xxxxxxxxxx
set smtp-auth=login
master_ip_failover
#&#x6B64;&#x811A;&#x672C;&#x4E3A;&#x5B98;&#x65B9;&#x63D0;&#x4F9B;
[root@MHA ~]# chmod +x /usr/local/bin/master_ip_failover
[root@MHA ~]# cat /usr/local/bin/master_ip_failover
#!/usr/bin/env perl

 Copyright (C) 2011 DeNA Co.,Ltd.

#
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

#
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

#
 You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
 Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

## Note: This is a sample script and is not complete. Modify the script based on your environment.

use strict;
use warnings FATAL => 'all';

use Getopt::Long;
use MHA::DBHelper;

my (
  $command,        $ssh_user,         $orig_master_host,
  $orig_master_ip, $orig_master_port, $new_master_host,
  $new_master_ip,  $new_master_port,  $new_master_user,
  $new_master_password
);
my $vip = '10.0.0.100/24';
my $key = "1";
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";

GetOptions(
  'command=s'             => \$command,
  'ssh_user=s'            => \$ssh_user,
  'orig_master_host=s'    => \$orig_master_host,
  'orig_master_ip=s'      => \$orig_master_ip,
  'orig_master_port=i'    => \$orig_master_port,
  'new_master_host=s'     => \$new_master_host,
  'new_master_ip=s'       => \$new_master_ip,
  'new_master_port=i'     => \$new_master_port,
  'new_master_user=s'     => \$new_master_user,
  'new_master_password=s' => \$new_master_password,
);

exit &main();

sub main {
  if ( $command eq "stop" || $command eq "stopssh" ) {

    # $orig_master_host, $orig_master_ip, $orig_master_port are passed.

    # If you manage master ip address at global catalog database,
    # invalidate orig_master_ip here.

    my $exit_code = 1;
    eval {

      # updating global catalog, etc
      $exit_code = 0;
    };
    if ($@) {
      warn "Got Error: $@\n";
      exit $exit_code;
    }
    exit $exit_code;
  }
    elsif ( $command eq "start" ) {

        # all arguments are passed.

        # If you manage master ip address at global catalog database,
        # activate new_master_ip here.

        # You can also grant write access (create user, set read_only=0, etc) here.

        my $exit_code = 10;
        eval {
            print "Enabling the VIP - $vip on the new master - $new_master_host \n";
            &start_vip();
            &stop_vip();
            $exit_code = 0;
        };
        if ($@) {
            warn $@;
            exit $exit_code;
        }
        exit $exit_code;
    }
    elsif ( $command eq "status" ) {
        print "Checking the Status of the script.. OK \n";
        ssh $ssh_user\@$orig_master_host \" $ssh_start_vip \";
        exit 0;
    }
    else {
        &usage();
        exit 1;
    }
}

sub start_vip() {
    ssh $ssh_user\@$new_master_host \" $ssh_start_vip \";
}
A simple system call that disable the VIP on the old_master
sub stop_vip() {
   ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \";
}

sub usage {
  print
"Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
}
(6)实现master
[root@master ~]# yum install -y mysql-server
[root@master ~]# mkdir -p /data/mysql
[root@master ~]# chown mysql.mysql /data/mysql/

[root@master ~]# vim /etc/my.cnf
[mysqld]
server-id=8
log-bin=/data/mysql/mysql-bin  #&#x6307;&#x5B9A;&#x4E8C;&#x8FDB;&#x5236;&#x65E5;&#x5FD7;&#x5B58;&#x653E;&#x7684;&#x76EE;&#x5F55;,mha4mysql-manager-0.58&#x5FC5;&#x987B;&#x6307;&#x5B9A;&#xFF08;&#x9700;&#x8981;&#x548C;/etc/mastermha/app1.cnf&#x5185;&#x7684;&#x4E00;&#x81F4;&#xFF09;
skip_name_resolve=1 #&#x7981;&#x6B62;&#x53CD;&#x5411;&#x89E3;&#x6790;
general_log #&#x89C2;&#x5BDF;&#x7ED3;&#x679C;,&#x975E;&#x5FC5;&#x987B;&#x9879;,&#x751F;&#x4EA7;&#x65E0;&#x9700;&#x542F;&#x7528;

[root@master ~]# systemctl enable --now mysqld

#&#x56E0;&#x4E3A;&#x662F;&#x65B0;&#x5B89;&#x88C5;&#x7684;&#x673A;&#x5668;&#xFF0C;&#x6240;&#x4EE5;&#x4E0D;&#x9700;&#x8981;&#x5B8C;&#x5168;&#x5907;&#x4EFD;&#x3002;
#&#x5728;&#x672A;&#x8FDB;&#x884C;&#x4EFB;&#x4F55;&#x64CD;&#x4F5C;&#x524D;&#x8BB0;&#x5F55;&#x4E0B;&#x503C;&#xFF08;&#x8FD9;&#x6837;slvae&#x4F1A;master&#x540C;&#x6B65;&#x4E0B;&#x9762;&#x4E24;&#x4E2A;&#x6388;&#x6743;&#x8D26;&#x53F7;&#xFF09;
[root@master ~]# mysql
mysql> show master logs;
+------------------+-----------+-----------+
| Log_name         | File_size | Encrypted |
+------------------+-----------+-----------+
| mysql-bin.000001 |       179 | No        |
| mysql-bin.000002 |       156 | No        |
+------------------+-----------+-----------+
2 rows in set (0.00 sec)

#&#x5982;&#x679C;&#x662F;MySQL8.0&#x6267;&#x884C;&#x4E0B;&#x9762;&#x64CD;&#x64CD;&#x4F5C;
mysql> create user repluser@'10.0.0.%' identified by '123456';
mysql> grant replication slave on *.* to repluser@'10.0.0.%';
mysql> create user mhauser@'10.0.0.%' identified by '123456';
mysql> grant all on *.* to mhauser@'10.0.0.%';

#&#x5982;&#x679C;&#x662F;MySQL8.0&#x4EE5;&#x524D;&#x7248;&#x672C;&#x6267;&#x884C;&#x4E0B;&#x9762;&#x64CD;&#x64CD;&#x4F5C;
mysql>grant replication slave on *.* to repluser@'10.0.0.%' identified by '123456';
mysql>grant all on *.* to mhauser@'10.0.0.%' identified by '123456';

#&#x914D;&#x7F6E;VIP
#&#x6B64;IP&#x4E3A;master_ip_failover&#x811A;&#x672C;&#x91CC;&#x9762;&#x7684;&#x53D8;&#x91CF;
#&#x7B2C;&#x4E00;&#x6B21;&#x9700;&#x8981;&#x624B;&#x52A8;&#x6DFB;&#x52A0;&#xFF08;&#x4E14;&#x522B;&#x540D;&#x4E3A;eth0:1&#xFF09;
#&#x5982;&#x679C;&#x4E3B;&#x8282;&#x70B9;down&#x6389;&#xFF0C;&#x90A3;&#x4E48;&#x6B64;IP&#x4F1A;&#x81EA;&#x52A8;&#x8F6C;&#x79FB;&#x5230;&#x4ECE;&#x8282;&#x70B9;&#x4E0A;
[root@MHA ~]# cat /usr/local/bin/master_ip_failover |grep "^my"
my $vip = '10.0.0.100/24';
my $key = "1";
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";
[root@master ~]# ifconfig eth0:1 10.0.0.100/24
(7) 实现 slave
#&#x4E0B;&#x9762;&#x53EA;&#x6F14;&#x793A;slvae1&#x64CD;&#x4F5C;&#x8FC7;&#x7A0B;&#xFF0C;slave2&#x4E5F;&#x9700;&#x64CD;&#x4F5C;
#slave1&#x548C;slave2&#x9664;server-id&#x9700;&#x4E0D;&#x4E00;&#x81F4;&#x5916;&#x5176;&#x4ED6;&#x64CD;&#x4F5C;&#x76F8;&#x540C;
[root@slave1 ~]# yum install -y mysql-server
[root@slave1 ~]# mkdir -p /data/mysql
[root@slave1 ~]# chown mysql.mysql /data/mysql/

[root@slave1 ~]# vim /etc/my.cnf
[mysqld]
server-id=18 #&#x4E0D;&#x540C;&#x8282;&#x70B9;&#x6B64;&#x503C;&#x5404;&#x4E0D;&#x76F8;&#x540C;
log-bin=/data/mysql/mysql-bin  #&#x6307;&#x5B9A;&#x4E8C;&#x8FDB;&#x5236;&#x65E5;&#x5FD7;&#x5B58;&#x653E;&#x7684;&#x76EE;&#x5F55;,mha4mysql-manager-0.58&#x5FC5;&#x987B;&#x6307;&#x5B9A;&#xFF08;&#x9700;&#x8981;&#x548C;/etc/mastermha/app1.cnf&#x5185;&#x7684;&#x4E00;&#x81F4;&#xFF09;
read-only
relay-log-purge=0
skip-name-resolve=1 #&#x7981;&#x6B62;&#x53CD;&#x5411;&#x89E3;&#x6790;
general_log #&#x89C2;&#x5BDF;&#x7ED3;&#x679C;,&#x975E;&#x5FC5;&#x987B;&#x9879;,&#x751F;&#x4EA7;&#x65E0;&#x9700;&#x542F;&#x7528;

[root@slave1 ~]# systemctl enable --now mysqld

[root@slave1 ~]# mysql
mysql> CHANGE MASTER TO
         MASTER_HOST='10.0.0.8',
         MASTER_USER='repluser',
         MASTER_PASSWORD='123456',
         MASTER_PORT=3306,
         MASTER_LOG_FILE='mysql-bin.000002',
         MASTER_LOG_POS=156,
         MASTER_CONNECT_RETRY=3;
mysql> start slave;
(8)检查MHA的环境
#&#x68C0;&#x67E5;&#x73AF;&#x5883;
[root@MHA ~]# masterha_check_ssh --conf=/etc/mastermha/app1.cnf
[root@MHA ~]# masterha_check_repl --conf=/etc/mastermha/app1.cnf

#&#x67E5;&#x770B;&#x72B6;&#x6001;
[root@MHA ~]# masterha_check_status --conf=/etc/mastermha/app1.cnf
(9)启动MHA
#&#x5F00;&#x542F;MHA,&#x9ED8;&#x8BA4;&#x662F;&#x524D;&#x53F0;&#x8FD0;&#x884C;,&#x751F;&#x4EA7;&#x73AF;&#x5883;&#x4E00;&#x822C;&#x4E3A;&#x540E;&#x53F0;&#x6267;&#x884C;
[root@MHA ~]# nohup masterha_manager --conf=/etc/mastermha/app1.cnf --remove_dead_master_conf --ignore_last_failover &> /dev/null
#&#x6D4B;&#x8BD5;&#x73AF;&#x5883;
[root@MHA ~]# masterha_manager --conf=/etc/mastermha/app1.cnf --remove_dead_master_conf --ignore_last_failover

#&#x5982;&#x679C;&#x60F3;&#x505C;&#x6B62;&#x540E;&#x53F0;&#x6267;&#x884C;&#x7684;MHA,&#x53EF;&#x4EE5;&#x6267;&#x884C;&#x4E0B;&#x9762;&#x547D;&#x4EE4;
[root@MHA ~]# masterha_stop --conf=/etc/mastermha/app1.cnf
Stopped app1 successfully.

#&#x67E5;&#x770B;&#x72B6;&#x6001;
[root@MHA ~]# masterha_check_status --conf=/etc/mastermha/app1.cnf
(10)排错日志
[root@MHA ~]# tail /data/mastermha/app1/manager.log

#&#x5065;&#x5EB7;&#x6027;&#x68C0;&#x67E5;
[root@master ~]# tail -f /var/lib/mysql/master.log
2022-11-03T17:41:32.075497Z    22 Query SELECT 1 As Value
2022-11-03T17:41:33.074744Z    22 Query SELECT 1 As Value
2022-11-03T17:41:34.076151Z    22 Query SELECT 1 As Value
(11)模拟故障
#&#x6A21;&#x62DF;&#x6545;&#x969C;
[root@master ~]# systemctl stop mysqld
#&#x5F53; master down&#x673A;&#x540E;,mha&#x7BA1;&#x7406;&#x7A0B;&#x5E8F;&#x81EA;&#x52A8;&#x9000;&#x51FA;
[root@MHA ~]# masterha_manager --conf=/etc/mastermha/app1.cnf --remove_dead_master_conf --ignore_last_
Fri Nov  4 09:39:37 2022 - [warning] Global configuration file /etc/masterha_default.cnf not found. Sk
Fri Nov  4 09:39:37 2022 - [info] Reading application default configuration from /etc/mastermha/app1.c
Fri Nov  4 09:39:37 2022 - [info] Reading server configuration from /etc/mastermha/app1.cnf..

  Creating /data/mastermha/app1 if not exists..    ok.

  Checking output directory is accessible or not..

   ok.

  Binlog found at /data/mysql/, up to mysql-bin.000003
Fri Nov  4 09:45:55 2022 - [warning] Global configuration file /etc/masterha_default.cnf not found. Sk
Fri Nov  4 09:45:55 2022 - [info] Reading application default configuration from /etc/mastermha/app1.c
Fri Nov  4 09:45:55 2022 - [info] Reading server configuration from /etc/mastermha/app1.cnf..

#&#x9A8C;&#x8BC1;VIP&#x6F02;&#x79FB;&#x81F3;&#x65B0;&#x7684;Master&#x4E0A;
[root@slave1 ~]# ifconfig eth0:1
eth0:1: flags=4163<up,broadcast,running,multicast>  mtu 1500
        inet 10.0.0.100  netmask 255.255.255.0  broadcast 10.0.0.255
        ether 00:0c:29:34:3d:e8  txqueuelen 1000  (Ethernet)

#&#x81EA;&#x52A8;&#x4FEE;&#x6539;manager&#x8282;&#x70B9;&#x4E0A;&#x7684;&#x914D;&#x7F6E;&#x6587;&#x4EF6;,&#x5C06;master&#x5254;&#x9664;
[root@slave1 ~]# cat /etc/mastermha/app1.cnf
[server2]
hostname=10.0.0.18
port=3306
candidate_master=1
[server3]
hostname=10.0.0.28
port=3306</up,broadcast,running,multicast>

收到报警邮件

Mysql实战技能全解
(12)修复主从
  • 修复故障的主库,保证数据同步
  • 修复主从,手工新故障库加入新的主,设为为从库
  • 修复manager的配置文件
  • 清理相关目录
  • 检查ssh互信和replication的复制是否成功
  • 检查VIP,如果有问题,重新配置VIP
  • 重新运行MHA,查询MHA状态,确保运行正常
(13)如果再次运行MHA,需要先删除下面文件

MHA只能漂移一次,如果多次使用必须删除以下文件,要不MHA不可重用

[root@MHA ~]# rm -rf /data/mastermha/app1/ &#xA0; &#xA0; &#xA0;        #mha_master&#x81EA;&#x5DF1;&#x7684;&#x5DE5;&#x4F5C;&#x8DEF;&#x5F84;
[root@MHA ~]# rm -rf /data/mastermha/app1/manager.log &#xA0; #mha_master&#x81EA;&#x5DF1;&#x7684;&#x65E5;&#x5FD7;&#x6587;&#x4EF6;
[root@master ~]#rm -rf /data/mastermha/app1/ &#xA0;          #&#x6BCF;&#x4E2A;&#x8FDC;&#x7A0B;&#x4E3B;&#x673A;&#x5373;&#x4E09;&#x4E2A;&#x8282;&#x70B9;&#x7684;&#x7684;&#x5DE5;&#x4F5C;&#x76EE;&#x5F55;

3.2 Galera Cluster

Galera Cluster:集成了Galera插件的MySQL集群,是一种新型的,数据不共享的,高度冗余的高可用方案,目前Galera Cluster有两个版本,分别是 Percona Xtradb ClusterMariaDB Cluster,Galera本身是具有多主特性的,即采用multi-master的集群架构,是一个既稳健,又在数据一致性、完整性及高性能方面有出色表现的高可用解决方案
特点

  • 多主架构:真正的多点读写的集群,在任何时候读写数据,都是最新的
  • 同步复制:改善了主从复制延迟问题,基本上达到了实时同步
  • 并发复制:从节点APPLY数据时,支持并行执行,更好的性能
  • 故障切换:在出现数据库故障时,因支持多点写入,切换容易

实战案例:Percona XtraDB Cluster(PXC 5.7)

环境准备
四台主机:

  • pxc1:10.0.0.7
  • pxc2:10.0.0.17
  • pxc3:10.0.0.27
  • pxc4:10.0.0.37
  • 第4台模拟生产中后续增加的节点

OS 版本目前不支持 CentOS 8

  • 关闭防火墙和SELinux
  • 保证时间同步

注意:如果已经安装MySQL,必须卸载

(1)安装 Percona XtraDB Cluster 5.7
#&#x6B64;&#x5904;&#x4F7F;&#x7528;&#x6E05;&#x534E;&#x5927;&#x5B66;yum&#x6E90;&#xFF0C;&#x5B98;&#x65B9;&#x6E90;&#x592A;&#x6162;&#x4E86;
[root@pxc1 ~]#vim /etc/yum.repos.d/pxc.repo
[percona]
name=percona_repo
baseurl=https://mirrors.tuna.tsinghua.edu.cn/percona/release/$releasever/RPMS/$basearch
enabled=1
gpgcheck=0

[root@pxc1 ~]#scp /etc/yum.repos.d/pxc.repo 10.0.0.17:/etc/yum.repos.d
[root@pxc1 ~]#scp /etc/yum.repos.d/pxc.repo 10.0.0.27:/etc/yum.repos.d
#&#x5728;&#x4E09;&#x4E2A;&#x8282;&#x70B9;&#x90FD;&#x5B89;&#x88C5;&#x597D;PXC 5.7
[root@pxc1 ~]#yum install Percona-XtraDB-Cluster-57 -y
[root@pxc2 ~]#yum install Percona-XtraDB-Cluster-57 -y
[root@pxc3 ~]#yum install Percona-XtraDB-Cluster-57 -y
(2)在各个节点上分别配置mysql及集群配置文件

/etc/my.cnf为主配置文件,当前版本中,其余的配置文件都放在/etc/percona-xtradb-cluster.conf.d目录里,包括下面三个文件

  • mysqld.cnf
  • mysqld_safe.cnf
  • wsrep.cnf

注意:尽管Galera Cluster不再需要通过binlog的形式进行同步,但还是建议在配置文件中开启二进制日志功能,原因是后期如果有新节点需要加入,老节点通过SST全量传输的方式向新节点传输数据,很可能会拖垮集群性能,所以让新节点先通过binlog方式完成同步后再加入集群会是一种更好的选择

[root@pxc1 ~]#ls /etc/percona-xtradb-cluster.conf.d/
mysqld.cnf mysqld_safe.cnf wsrep.cnf
#&#x4E0B;&#x9762;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x4E0D;&#x9700;&#x8981;&#x4FEE;&#x6539;
[root@pxc1 ~]#cat /etc/percona-xtradb-cluster.conf.d/mysqld.cnf
...&#x7701;&#x7565;...

[client]
socket=/var/lib/mysql/mysql.sock
[mysqld]
server-id=1 &#xA0; &#xA0; #&#x5EFA;&#x8BAE;&#x5404;&#x4E2A;&#x8282;&#x70B9;&#x4E0D;&#x540C;
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
log-bin &#xA0; &#xA0; #&#x5EFA;&#x8BAE;&#x542F;&#x7528;&#xFF0C;&#x975E;&#x5FC5;&#x987B;&#x9879;
log_slave_updates
expire_logs_days=7

#PXC&#x7684;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x5FC5;&#x987B;&#x4FEE;&#x6539;
[root@pxc1 ~]#vim /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
[root@pxc1 ~]#grep -Ev "^#|^$" /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
[mysqld]
wsrep_provider=/usr/lib64/galera3/libgalera_smm.so
wsrep_cluster_address=gcomm://10.0.0.7,10.0.0.17,10.0.0.27 #&#x4E09;&#x4E2A;&#x8282;&#x70B9;&#x7684;IP
binlog_format=ROW
default_storage_engine=InnoDB
wsrep_slave_threads= 8
wsrep_log_conflicts
innodb_autoinc_lock_mode=2
wsrep_node_address=10.0.0.7 #&#x5404;&#x4E2A;&#x8282;&#x70B9;&#xFF0C;&#x6307;&#x5B9A;&#x81EA;&#x5DF2;&#x7684;IP
wsrep_cluster_name=pxc-cluster
wsrep_node_name=pxc-cluster-node-1 #&#x5404;&#x4E2A;&#x8282;&#x70B9;&#xFF0C;&#x6307;&#x5B9A;&#x81EA;&#x5DF2;&#x8282;&#x70B9;&#x540D;&#x79F0;
pxc_strict_mode=ENFORCING
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth="sstuser:s3cretPass" #&#x53D6;&#x6D88;&#x672C;&#x884C;&#x6CE8;&#x91CA;,&#x540C;&#x4E00;&#x96C6;&#x7FA4;&#x5185;&#x591A;&#x4E2A;&#x8282;&#x70B9;&#x7684;&#x9A8C;&#x8BC1;&#x7528;&#x6237;&#x548C;&#x5BC6;&#x7801;&#x4FE1;&#x606F;&#x5FC5;&#x987B;&#x4E00;&#x81F4;

[root@pxc2 ~]#grep -Ev "^#|^$" /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
[mysqld]
wsrep_provider=/usr/lib64/galera3/libgalera_smm.so
wsrep_cluster_address=gcomm://10.0.0.7,10.0.0.17,10.0.0.27
binlog_format=ROW
default_storage_engine=InnoDB
wsrep_slave_threads= 8
wsrep_log_conflicts
innodb_autoinc_lock_mode=2 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;
wsrep_node_address=10.0.0.17 #&#x5404;&#x4E2A;&#x8282;&#x70B9;&#xFF0C;&#x6307;&#x5B9A;&#x81EA;&#x5DF2;&#x7684;IP
wsrep_cluster_name=pxc-cluster
wsrep_node_name=pxc-cluster-node-2 #&#x5404;&#x4E2A;&#x8282;&#x70B9;&#xFF0C;&#x6307;&#x5B9A;&#x81EA;&#x5DF2;&#x8282;&#x70B9;&#x540D;&#x79F0;
pxc_strict_mode=ENFORCING
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth="sstuser:s3cretPass" #&#x53D6;&#x6D88;&#x672C;&#x884C;&#x6CE8;&#x91CA;

[root@pxc3 ~]#grep -Ev "^#|^$" /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
[mysqld]
wsrep_provider=/usr/lib64/galera3/libgalera_smm.so
wsrep_cluster_address=gcomm://10.0.0.7,10.0.0.17,10.0.0.27
binlog_format=ROW
default_storage_engine=InnoDB
wsrep_slave_threads= 8
wsrep_log_conflicts
innodb_autoinc_lock_mode=2 &#xA0;
wsrep_node_address=10.0.0.27 #&#x5404;&#x4E2A;&#x8282;&#x70B9;&#xFF0C;&#x6307;&#x5B9A;&#x81EA;&#x5DF2;&#x7684;IP
wsrep_cluster_name=pxc-cluster
wsrep_node_name=pxc-cluster-node-3 #&#x5404;&#x4E2A;&#x8282;&#x70B9;&#xFF0C;&#x6307;&#x5B9A;&#x81EA;&#x5DF2;&#x7684;IP
pxc_strict_mode=ENFORCING
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth="sstuser:s3cretPass"  #&#x53D6;&#x6D88;&#x672C;&#x884C;&#x6CE8;&#x91CA;
(3)启动PXC集群中第一个节点
[root@pxc1 ~]#systemctl start mysql@bootstrap.service
[root@pxc1 ~]#ss -ntul
State       Recv-Q Send-Q             Local Address:Port                            Peer Address:Port
LISTEN      0      128                            *:4567                                       *:*
LISTEN      0      80                            :::3306                                      :::*

#&#x67E5;&#x770B;root&#x5BC6;&#x7801;
[root@pxc1 ~]#grep "password" /var/log/mysqld.log
2022-11-04T19:30:20.592377Z 1 [Note] A temporary password is generated for root@localhost: mNZTH2o*4Use
[root@pxc1 ~]#mysql -uroot -p'=mNZTH2o*4Use'
#&#x4FEE;&#x6539;root&#x5BC6;&#x7801;
mysql> alter user 'root'@'localhost' identified by '123456';
#&#x521B;&#x5EFA;&#x76F8;&#x5173;&#x7528;&#x6237;&#x5E76;&#x6388;&#x6743;&#xFF08;&#x4E0B;&#x9762;&#x6240;&#x8D4B;&#x4E88;&#x7684;&#x6743;&#x9650;&#x662F;&#x5B98;&#x65B9;&#x6587;&#x6863;&#x91CC;&#x9762;&#x63D0;&#x4F9B;&#x7684;&#xFF09;
mysql> CREATE USER 'sstuser'@'localhost' IDENTIFIED BY 's3cretPass';
mysql> GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO 'sstuser'@'localhost';

#&#x67E5;&#x770B;&#x76F8;&#x5173;&#x53D8;&#x91CF;
mysql> SHOW VARIABLES LIKE 'wsrep%'\G
#&#x67E5;&#x770B;&#x76F8;&#x5173;&#x72B6;&#x6001;&#x53D8;&#x91CF;
mysql> SHOW STATUS LIKE 'wsrep%'\G
(5)启动PXC集群中其它所有节点
[root@pxc2 ~]#systemctl start mysql
(6)查看集群状态,验证集群是否成功
mysql> SHOW VARIABLES LIKE 'wsrep_on';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wsrep_on &#xA0; &#xA0; &#xA0;| ON &#xA0; &#xA0;|
+---------------+-------+
1 row in set (0.00 sec)
mysql> SHOW STATUS LIKE 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name &#xA0; &#xA0; &#xA0;| Value |
+--------------------+-------+
| wsrep_cluster_size | 3 &#xA0; &#xA0; |
+--------------------+-------+
1 row in set (0.01 sec)
(7)在PXC集群中加入节点
#&#x5728;PXC&#x96C6;&#x7FA4;&#x4E2D;&#x518D;&#x52A0;&#x4E00;&#x53F0;&#x65B0;&#x7684;&#x4E3B;&#x673A;PXC4&#xFF1A;10.0.0.37
[root@pxc4 ~]#yum install Percona-XtraDB-Cluster-57 -y
[root@pxc4 ~]#vim /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
[root@pxc4 ~]#grep -Ev "^#|^$" /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
[mysqld]
wsrep_provider=/usr/lib64/galera3/libgalera_smm.so
wsrep_cluster_address=gcomm://10.0.0.7,10.0.0.17,10.0.0.27,10.0.0.37 #&#x6539;
binlog_format=ROW
default_storage_engine=InnoDB
wsrep_slave_threads= 8
wsrep_log_conflicts
innodb_autoinc_lock_mode=2
wsrep_node_address=10.0.0.37 #&#x6539;
wsrep_cluster_name=pxc-cluster
wsrep_node_name=pxc-cluster-node-4 #&#x6539;
pxc_strict_mode=ENFORCING
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth="sstuser:s3cretPass"  #&#x6539;

[root@pxc4 ~]#systemctl start mysql
[root@pxc4 ~]#mysql -uroot -p123456
Server version: 5.7.27-30-57-log Percona XtraDB Cluster (GPL), Release rel30,
Revision
mysql> SHOW STATUS LIKE 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name &#xA0;  &#xA0; | Value |
+--------------------+-------+
| wsrep_cluster_size | 4 &#xA0; &#xA0; |
+--------------------+-------+

#&#x5C06;&#x5176;&#x5B83;&#x8282;&#x70B9;&#x7684;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x52A0;&#x4EE5;&#x4FEE;&#x6539;
[root@pxc1 ~]#vim /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
wsrep_cluster_address=gcomm://10.0.0.7,10.0.0.17,10.0.0.27,10.0.0.37
[root@pxc2 ~]#vim /etc/percona-xtradb-cluster.conf.d/wsrep.cnf
[root@pxc3 ~]#vim /etc/percona-xtradb-cluster.conf.d/wsrep.cnf

实战案例:MariaDB Galera Cluster

(1)centos8 实现MariaDB Galera Cluster
#&#x5728;&#x4E09;&#x4E2A;&#x8282;&#x70B9;&#x4E0A;&#x90FD;&#x5B9E;&#x73B0;
[root@centos8 ~]#dnf install mariadb-server-galera -y
[root@centos8 ~]#vim /etc/my.cnf.d/galera.cnf
#wsrep_cluster_address="dummy://" &#x5728;&#x6B64;&#x884C;&#x4E0B;&#x9762;&#x52A0;&#x4E00;&#x884C;
wsrep_cluster_address="gcomm://10.0.0.8,10.0.0.18,10.0.0.28" &#xA0;

#&#x542F;&#x52A8;&#x7B2C;&#x4E00;&#x8282;&#x70B9;
[root@centos8 ~]#galera_new_cluster
[root@centos8 ~]#systemctl enable mariadb

#&#x518D;&#x542F;&#x52A8;&#x5176;&#x5B83;&#x8282;&#x70B9;
[root@centos8 ~]#systemctl enable --now mariadb
[root@centos8 ~]#ss -ntl
State       Recv-Q Send-Q             Local Address:Port                            Peer Address:Port
LISTEN      0      128                            *:4567                                       *:*
LISTEN      0      80                            :::3306                                      :::*

#&#x9A8C;&#x8BC1;
[root@centos8 ~]#mysql
MariaDB [(none)]> &#xA0;show status like "wsrep_ready";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wsrep_ready &#xA0; | ON &#xA0; &#xA0;|
+---------------+-------+
1 row in set (0.001 sec)
MariaDB [(none)]> SHOW STATUS LIKE 'wsrep_cluster_size';
+--------------------+-------+
| Variable_name &#xA0; &#xA0; &#xA0;| Value |
+--------------------+-------+
| wsrep_cluster_size | 3 &#xA0; &#xA0; |
+--------------------+-------+
(2)CentOS 7 实现 MariaDB Galera Cluster 5.5
#&#x53C2;&#x8003;&#x4ED3;&#x5E93;&#xFF1A;https://mirrors.tuna.tsinghua.edu.cn/mariadb/mariadb-5.5.X/yum/centos7-amd64/
yum install MariaDB-Galera-server
vim /etc/my.cnf.d/server.cnf
[galera]
wsrep_provider = /usr/lib64/galera/libgalera_smm.so
wsrep_cluster_address="gcomm://10.0.0.7,10.0.0.17,10.0.0.27"
binlog_format=row
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0

#&#x4E0B;&#x9762;&#x914D;&#x7F6E;&#x53EF;&#x9009;&#x9879;
wsrep_cluster_name = 'mycluster' &#x9ED8;&#x8BA4;my_wsrep_cluster
wsrep_node_name = 'node1'
wsrep_node_address = '10.0.0.7'

#&#x9996;&#x6B21;&#x542F;&#x52A8;&#x65F6;&#xFF0C;&#x9700;&#x8981;&#x521D;&#x59CB;&#x5316;&#x96C6;&#x7FA4;&#xFF0C;&#x5728;&#x5176;&#x4E2D;&#x4E00;&#x4E2A;&#x8282;&#x70B9;&#x4E0A;&#x6267;&#x884C;&#x547D;&#x4EE4;
/etc/init.d/mysql start --wsrep-new-cluster

#&#x800C;&#x540E;&#x6B63;&#x5E38;&#x542F;&#x52A8;&#x5176;&#x5B83;&#x8282;&#x70B9;
service mysql start

#&#x67E5;&#x770B;&#x96C6;&#x7FA4;&#x4E2D;&#x76F8;&#x5173;&#x7CFB;&#x7EDF;&#x53D8;&#x91CF;&#x548C;&#x72B6;&#x6001;&#x53D8;&#x91CF;
SHOW VARIABLES LIKE 'wsrep_%';
SHOW STATUS LIKE 'wsrep_%';
SHOW STATUS LIKE 'wsrep_cluster_size';

3.3 TiDB

七、MySQL压力测试

1 mysqlslap 压力测试工具

格式

  • mysqlslap [options]

常用参数 [options] 说明

--auto-generate-sql, -a #&#x81EA;&#x52A8;&#x751F;&#x6210;&#x6D4B;&#x8BD5;&#x8868;&#x548C;&#x6570;&#x636E;&#xFF0C;&#x8868;&#x793A;&#x7528;mysqlslap&#x5DE5;&#x5177;&#x81EA;&#x5DF1;&#x751F;&#x6210;&#x7684;SQL&#x811A;&#x672C;&#x6765;&#x6D4B;&#x8BD5;&#x5E76;&#x53D1;&#x538B;&#x529B;
--auto-generate-sql-load-type=type #&#x6D4B;&#x8BD5;&#x8BED;&#x53E5;&#x7684;&#x7C7B;&#x578B;&#x3002;&#x4EE3;&#x8868;&#x8981;&#x6D4B;&#x8BD5;&#x7684;&#x73AF;&#x5883;&#x662F;&#x8BFB;&#x64CD;&#x4F5C;&#x8FD8;&#x662F;&#x5199;&#x64CD;&#x4F5C;&#x8FD8;&#x662F;&#x4E24;&#x8005;&#x6DF7;&#x5408;&#x7684;&#x3002;&#x53D6;&#x503C;&#x5305;&#x62EC;&#xFF1A;read&#xFF0C;key&#xFF0C;write&#xFF0C;update&#x548C;mixed(&#x9ED8;&#x8BA4;)
--auto-generate-sql-add-auto-increment #&#x4EE3;&#x8868;&#x5BF9;&#x751F;&#x6210;&#x7684;&#x8868;&#x81EA;&#x52A8;&#x6DFB;&#x52A0;auto_increment&#x5217;&#xFF0C;&#x4ECE;5.1.18&#x7248;&#x672C;&#x5F00;&#x59CB;&#x652F;&#x6301;
--number-char-cols=N, -x N #&#x81EA;&#x52A8;&#x751F;&#x6210;&#x7684;&#x6D4B;&#x8BD5;&#x8868;&#x4E2D;&#x5305;&#x542B;&#x591A;&#x5C11;&#x4E2A;&#x5B57;&#x7B26;&#x7C7B;&#x578B;&#x7684;&#x5217;&#xFF0C;&#x9ED8;&#x8BA4;1
--number-int-cols=N, -y N #&#x81EA;&#x52A8;&#x751F;&#x6210;&#x7684;&#x6D4B;&#x8BD5;&#x8868;&#x4E2D;&#x5305;&#x542B;&#x591A;&#x5C11;&#x4E2A;&#x6570;&#x5B57;&#x7C7B;&#x578B;&#x7684;&#x5217;&#xFF0C;&#x9ED8;&#x8BA4;1
--number-of-queries=N #&#x603B;&#x7684;&#x6D4B;&#x8BD5;&#x67E5;&#x8BE2;&#x6B21;&#x6570;(&#x5E76;&#x53D1;&#x5BA2;&#x6237;&#x6570;&#xD7;&#x6BCF;&#x5BA2;&#x6237;&#x67E5;&#x8BE2;&#x6B21;&#x6570;)
--query=name,-q #&#x4F7F;&#x7528;&#x81EA;&#x5B9A;&#x4E49;&#x811A;&#x672C;&#x6267;&#x884C;&#x6D4B;&#x8BD5;&#xFF0C;&#x4F8B;&#x5982;&#x53EF;&#x4EE5;&#x8C03;&#x7528;&#x81EA;&#x5B9A;&#x4E49;&#x7684;&#x5B58;&#x50A8;&#x8FC7;&#x7A0B;&#x6216;&#x8005;sql&#x8BED;&#x53E5;&#x6765;&#x6267;&#x884C;&#x6D4B;&#x8BD5;
--create-schema #&#x4EE3;&#x8868;&#x81EA;&#x5B9A;&#x4E49;&#x7684;&#x6D4B;&#x8BD5;&#x5E93;&#x540D;&#x79F0;&#xFF0C;&#x6D4B;&#x8BD5;&#x7684;schema
--commint=N #&#x591A;&#x5C11;&#x6761;DML&#x540E;&#x63D0;&#x4EA4;&#x4E00;&#x6B21;
--compress, -C #&#x5982;&#x670D;&#x52A1;&#x5668;&#x548C;&#x5BA2;&#x6237;&#x7AEF;&#x90FD;&#x652F;&#x6301;&#x538B;&#x7F29;&#xFF0C;&#x5219;&#x538B;&#x7F29;&#x4FE1;&#x606F;
--concurrency=N, -c N #&#x8868;&#x793A;&#x5E76;&#x53D1;&#x91CF;&#xFF0C;&#x5373;&#x6A21;&#x62DF;&#x591A;&#x5C11;&#x4E2A;&#x5BA2;&#x6237;&#x7AEF;&#x540C;&#x65F6;&#x6267;&#x884C;select&#x3002;&#x53EF;&#x6307;&#x5B9A;&#x591A;&#x4E2A;&#x503C;&#xFF0C;&#x4EE5;&#x9017;&#x53F7;&#x6216;&#x8005;--delimiter&#x53C2;&#x6570;&#x6307;&#x5B9A;&#x503C;&#x505A;&#x4E3A;&#x5206;&#x9694;&#x7B26;,&#x5982;&#xFF1A;--concurrency=100,200,500
--engine=engine_name, -e engine_name #&#x4EE3;&#x8868;&#x8981;&#x6D4B;&#x8BD5;&#x7684;&#x5F15;&#x64CE;&#xFF0C;&#x53EF;&#x4EE5;&#x6709;&#x591A;&#x4E2A;&#xFF0C;&#x7528;&#x5206;&#x9694;&#x7B26;&#x9694;&#x5F00;&#x3002;&#x4F8B;&#x5982;&#xFF1A;--engines=myisam,innodb
--iterations=N, -i N #&#x6D4B;&#x8BD5;&#x6267;&#x884C;&#x7684;&#x8FED;&#x4EE3;&#x6B21;&#x6570;&#xFF0C;&#x4EE3;&#x8868;&#x8981;&#x5728;&#x4E0D;&#x540C;&#x5E76;&#x53D1;&#x73AF;&#x5883;&#x4E0B;&#xFF0C;&#x5404;&#x81EA;&#x8FD0;&#x884C;&#x6D4B;&#x8BD5;&#x591A;&#x5C11;&#x6B21;
--only-print #&#x53EA;&#x6253;&#x5370;&#x6D4B;&#x8BD5;&#x8BED;&#x53E5;&#x800C;&#x4E0D;&#x5B9E;&#x9645;&#x6267;&#x884C;&#x3002;
--detach=N #&#x6267;&#x884C;N&#x6761;&#x8BED;&#x53E5;&#x540E;&#x65AD;&#x5F00;&#x91CD;&#x8FDE;
--debug-info, -T #&#x6253;&#x5370;&#x5185;&#x5B58;&#x548C;CPU&#x7684;&#x76F8;&#x5173;&#x4FE1;&#x606F;

使用示例

#&#x5355;&#x7EBF;&#x7A0B;&#x6D4B;&#x8BD5;
mysqlslap -a -uroot -p123456

#&#x591A;&#x7EBF;&#x7A0B;&#x6D4B;&#x8BD5;&#x3002;&#x4F7F;&#x7528;--concurrency&#x6765;&#x6A21;&#x62DF;&#x5E76;&#x53D1;&#x8FDE;&#x63A5;
mysqlslap -a -c 100 -uroot -p123456
#&#x8FED;&#x4EE3;&#x6D4B;&#x8BD5;&#x3002;&#x7528;&#x4E8E;&#x9700;&#x8981;&#x591A;&#x6B21;&#x6267;&#x884C;&#x6D4B;&#x8BD5;&#x5F97;&#x5230;&#x5E73;&#x5747;&#x503C;
mysqlslap -a -i 10 -uroot -p123456
mysqlslap ---auto-generate-sql-add-autoincrement -a
mysqlslap -a --auto-generate-sql-load-type=read
mysqlslap -a --auto-generate-secondary-indexes=3
mysqlslap -a --auto-generate-sql-write-number=1000
mysqlslap --create-schema world -q "select count(*) from City"
mysqlslap -a -e innodb -uroot -p123456
mysqlslap -a --number-of-queries=10 -uroot -p123456

#&#x6D4B;&#x8BD5;&#x540C;&#x65F6;&#x4E0D;&#x540C;&#x7684;&#x5B58;&#x50A8;&#x5F15;&#x64CE;&#x7684;&#x6027;&#x80FD;&#x8FDB;&#x884C;&#x5BF9;&#x6BD4;
mysqlslap -a --concurrency=50,100 --number-of-queries 1000 --iterations=5 --engine=myisam,innodb --debug-info -uroot -p123456

#&#x6267;&#x884C;&#x4E00;&#x6B21;&#x6D4B;&#x8BD5;&#xFF0C;&#x5206;&#x522B;50&#x548C;100&#x4E2A;&#x5E76;&#x53D1;&#xFF0C;&#x6267;&#x884C;1000&#x6B21;&#x603B;&#x67E5;&#x8BE2;
mysqlslap -a --concurrency=50,100 --number-of-queries 1000 --debug-info -uroot -p123456
#50&#x548C;100&#x4E2A;&#x5E76;&#x53D1;&#x5206;&#x522B;&#x5F97;&#x5230;&#x4E00;&#x6B21;&#x6D4B;&#x8BD5;&#x7ED3;&#x679C;(Benchmark)&#xFF0C;&#x5E76;&#x53D1;&#x6570;&#x8D8A;&#x591A;&#xFF0C;&#x6267;&#x884C;&#x5B8C;&#x6240;&#x6709;&#x67E5;&#x8BE2;&#x7684;&#x65F6;&#x95F4;&#x8D8A;&#x957F;&#x3002;&#x4E3A;&#x4E86;&#x51C6;&#x786E;&#x8D77;&#x89C1;&#xFF0C;&#x53EF;&#x4EE5;&#x591A;&#x8FED;&#x4EE3;&#x6D4B;&#x8BD5;&#x51E0;&#x6B21;
mysqlslap -a --concurrency=50,100 --number-of-queries 1000 --iterations=5 --debug-info -uroot -p123456

2 MySQL配置最佳实践

参考资料:
阿里巴巴Java开发手册
58到家数据库30条军规解读

Original: https://www.cnblogs.com/Willoneday/p/16572867.html
Author: 会不会有那么一天
Title: Mysql实战技能全解

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/581484/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球