diff --git a/02.企业服务/07.负载均衡.md b/02.企业服务/07.负载均衡.md index db25d92..8f30391 100644 --- a/02.企业服务/07.负载均衡.md +++ b/02.企业服务/07.负载均衡.md @@ -1575,7 +1575,7 @@ net.ipv4.ip_forward = 1 [root@lvs ~]# sysctl -p net.ipv4.ip_forward = 1 -[root@lvs ~]# iptables -t nat -A POSTROUTING -s 192.168.153.0/24 -j MASQUERADE +[root@lvs ~]# iptables -t nat -A POSTROUTING -s 192.168.65.0/24 -j MASQUERADE [root@lvs ~]# iptables -t nat -L -n ``` diff --git a/03.数据库/01.Mysql.md b/03.数据库/01.Mysql.md index 4986b89..a5efcd7 100644 --- a/03.数据库/01.Mysql.md +++ b/03.数据库/01.Mysql.md @@ -1,33 +1,6 @@ -# 1. MySQL介绍 +# 1. 数据库介绍 -## 1.1 DBA工作内容 - -![img](01.Mysql/R5j17V2j8h153YXZ.png!thumbnail) - -- 数据管理 - - 增删改查 -- 用户管理 - - grant all on *.* to all@'%' identified by '123'; - - 敲完这条命令就可以等着被开除了( • ̀ω•́ )✧ - - root,运维用户ops,程序连接用户(只读用户,读写用户) -- 集群管理 -- 数据备份、恢复 - - 逻辑备份 - - 物理备份 - - 冷备 - - 热备 - - 温备 - - 全备 - - 增量备份 - - 差异备份 -- 监控 - - 进程,端口 - - 集群状态 - - 主从复制 延时情况 - - SQL读写速率 - - slowlog - -## 1.2 什么是数据 +## 1.1 什么是数据 数据(data)是事实或观察的结果,是对客观事物的逻辑归纳,是用于表示客观事物的未经加工的的原始素材。 @@ -35,57 +8,57 @@ 在计算机系统中,数据以二进制信息单元0,1的形式表示。 -**数据的定义:**数据是指对客观事件进行记录并可以鉴别的符号,是对客观事物的性质、状态以及相互关系等进行记载的物理符号或这些物理符号的组合。它是可识别的、抽象的符号。* +**数据的定义:**数据是指对客观事件进行记录并可以鉴别的符号,是对客观事物的性质、状态以及相互关系等进行记载的物理符号或这些物理符号的组合。它是可识别的、抽象的符号。 -## 1.3 什么是数据库管理系统 +## 1.2 什么是数据库 -DBMS(database management system) +数据库就是存储和管理数据的仓库,数据按照一定的格式进行存储,用户可以对数据库中的数据进行增加修改、删除、查询等操作。数据库的分为关系型数据库和非关系型数据库。 -![img](01.Mysql/L8Ndjn2BuNL9IUl2.png!thumbnail) +关系型数据库是指采用了关系模型来组织数据的数据库,简单来说就是二维表格模型,好比Excel文件中的表格,强调使用表格的方式存储数据。关系型数据库核心元素:数据行、数据列、数据表、数据库(数据表的集合),非关系型数据库强调Key-Value的方式存储数据。 -## 1.4 数据库管理系统种类 +**常用关系数据库:**MySQL、SQLite、Oracle等 +**常见非关系数据库:**MongoDB、Redis -### 1.4.1 RDBMS +数据库特点:持久化存储、读写速度极高、保证数据的有效性 -以多张二维表的方式来存储,又给多张表建立了一定的关系(关系型数据库) +关系型数据库管理系统是为管理关系型数据库而设计的软件系统,如果要使用关系型数据库就需要安装数据库管理系统,其实就是一个应用软件。关系型数据库管理系统分为关系型数据库服务端软件和关系型数据库客户端软件。 +关系型数据库服务端软件主要负责管理不同的数据库,而每个数据库里面会有一系列数据文件,数据文件是用来存储数据的,其实数据库就是一系列数据文件的集合。 +关系型数据库客户端软件主要负责和关系型数据库服务端软件进行通信,向服务端传输数据或者从服务端获取数据。 -### 1.4.2 NoSQL +### 1.2.1 RDMS与NoSQL对比 -nosql 很多以json格式进行存储数据的(mogodb) +#### 1.2.1.1 功能对比 -### 1.4.3 RDMS与NoSQL对比 +| | 关系型数据库(sql/RDBMS) | 非关系型数据库 | +| :------------: | :---------------------: | :------------: | +| 强大的查询功能 | √ | × | +| 强一致性 | √ | × | +| 二级索引(目录) | √ | × | +| 灵活模式 | × | √ | +| 扩展性 | × | √ | +| 性能 | × | √ | -#### 1.4.3.1 功能对比 - -| | 关系型数据库 | 非关系型数据库 | -| :------------- | :----------- | :------------- | -| 强大的查询功能 | √ | × | -| 强一致性 | √ | × | -| 二级索引 | √ | × | -| 灵活模式 | × | √ | -| 扩展性 | × | √ | -| 性能 | × | √ | - -#### 1.4.3.2 特点对比 +#### 1.2.1.2 特点对比 - 关系型数据库(RDBMS)的特点: - 二维表 - 典型产品Oracle传统企业,MySQL互联网企业 - - 数据存取是通过SQL(Structured Query Language结构化查询语言) + - 数据存取是通过SQL语句(Structured Query Language结构化查询语言) - 最大特点数据安全性方面强(ACID) + - 非关系型数据库(NoSQL:Not only SQL)的特点: - 不是否定关系型数据库,而是做关系型数据库的补充 -### 1.4.4 数据库市场 +### 1.2.2 数据库市场 -#### 1.4.4.1 MySQL的市场应用 +#### 1.2.2.1 MySQL的市场应用 - 中、大型互联网公司 - 市场空间:互联网领域第一 - 趋势明显 - 同源产品:MariaDB、PerconaDB -#### 1.4.4.2 类似产品 +#### 1.2.2.2 其他产品 - 微软:SQLserver - 微软和sysbase合作开发的产品,后来自己开发,windows平台 @@ -97,7 +70,42 @@ nosql 很多以json格式进行存储数据的(mogodb) - MongoDB - Redis -## 1.5 MySQL发展史 +## 1.3 MySQL数据库 + +MySQL是一个关系型数据库管理系统由瑞典 MySQL AB公司开发,属于Oracle旗下产品。MySQL是最流行的关系型数据库管理系统之一,在WEB应用方面,MySQL是最好的RDBMS (Relational Database Management System,关系数据库管理系统)应用软件之一。 + +**数据库管理员(Database Administrator,简称*DBA*):**是从事管理和维护数据库管理系统(DBMS)的相关工作人员的统称,属于运维工程师的一个分支,主要负责业务数据库从设计、测试到部署交付的全生命周期管理。 + +### 1.3.1 DBA工作内容 + +如下图所示,分别是开发DBA和运维DBA: + +image-20240721145430464 + +包括但不限于以下工作内容: + +- 数据管理 + + - 对库和表的创建 + + - 基本的数据增删改查 + +- 用户管理 + + - root,运维用户ops,程序连接用户(只读用户,读写用户) + - 以及对于不同用户的权限管理 + +- 集群管理 + +- 数据备份、恢复 + + - 逻辑备份、物理备份、冷备、热备、温备、全备、增量备份、差异备份等 + +- 健康及状态监控 + + - 进程,端口、集群状态、主从复制 延时情况、SQL读写速率等 + +### 1.3.2 MySQL发展史 - 1979年,报表工具Unireg出现。 - 1985年,以瑞典David Axmark为首,成立了一家公司(AB前身),ISAM引擎出现。 @@ -105,11 +113,11 @@ nosql 很多以json格式进行存储数据的(mogodb) - 1999年-2000年,MySQL AB公司成立,并公布源码,开源化。 - 2000年4月BDB引擎出现,支持事务。 - 2008年1月16日 MySQL被Sun公司收购。 -- 2009年4月20日Oracle收购Sun公司,MySQL转入Oracle门下。 +- 2009年4月20日Oracle收购Sun公司,MySQL转入Oracle。 -# 2. MySQL安装 +# 2. MySQL的安装 -## 2.1 MySQL安装方式 +## 2.1 安装方式 - rpm、yum安装 - 安装方便、安装速度快、无法定制 @@ -148,9 +156,9 @@ useradd mysql -s /sbin/nologin -M ```shell [root@localhost mysql-5.6.40]# mkdir /application -[root@localhost mysql-5.6.40]# cmake . -DCMAKE_INSTALL_PREFIX=/application/mysql-5.6.38 \ --DMYSQL_DATADIR=/application/mysql-5.6.38/data \ --DMYSQL_UNIX_ADDR=/application/mysql-5.6.38/tmp/mysql.sock \ +[root@localhost mysql-5.6.40]# cmake . -DCMAKE_INSTALL_PREFIX=/application/mysql-5.6.40 \ +-DMYSQL_DATADIR=/application/mysql-5.6.40/data \ +-DMYSQL_UNIX_ADDR=/application/mysql-5.6.40/tmp/mysql.sock \ -DDEFAULT_CHARSET=utf8 \ -DDEFAULT_COLLATION=utf8_general_ci \ -DWITH_EXTRA_CHARSETS=all \ @@ -166,8 +174,8 @@ useradd mysql -s /sbin/nologin -M -DWITH_DEBUG=0 -[root@localhost mysql-5.6.40]# echo $? #查看上条命令是否运行正确,0表示正确 -[root@localhost mysql-5.6.40]# make +[root@localhost mysql-5.6.40]# c #查看上条命令是否运行正确,0表示正确 +[root@localhost mysql-5.6.40]# make -j 2 [root@localhost mysql-5.6.40]# make install ``` @@ -259,42 +267,50 @@ Bye - 下载二进制包并且解压 ```shell -wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.6.40-linux-glibc2.12-x86_64.tar.gz -tar xzvf mysql-5.6.40-linux-glibc2.12-x86_64.tar.gz +[root@localhost ~]# wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.6.40-linux-glibc2.12-x86_64.tar.gz +[root@localhost ~]# tar xzvf mysql-5.6.40-linux-glibc2.12-x86_64.tar.gz ``` - 然后的步骤就和编译安装一样 ```shell -mkdir /application -mv mysql-5.6.40-linux-glibc2.12-x86_64 /application/mysql-5.6.40 -ln -s /application/mysql-5.6.40 /application/mysql #为了后续写的脚本,方便监控mysql -cd /application/mysql/support-files #该文件夹有mysql初始化(预设)配置文件,覆盖文件是因为注释更全。 -cp my-default.cnf /etc/my.cnf -cp:是否覆盖"/etc/my.cnf"? y -cp mysql.server /etc/init.d/mysqld #mysql.server包含如何启动mysql的脚本命令,让系统知道通过该命令启动mysql时的动作,该目录存放系统中各种服务的启动/停止脚本 -cd /application/mysql/scripts -useradd mysql -s /sbin/nologin -M - yum -y install autoconf #不然会报错 -./mysql_install_db --user=mysql --basedir=/application/mysql --data=/application/mysql/data -vim /etc/profile.d/mysql.sh #写到环境变量的子配置文件内,未修改前只能使用/bin/mysql的命令才能启用,而不能全局使用 +[root@localhost ~]# mkdir /application +[root@localhost ~]# mv mysql-5.6.40-linux-glibc2.12-x86_64 /application/mysql-5.6.40 +[root@localhost ~]# ln -s /application/mysql-5.6.40 /application/mysql +#为了后续写的脚本,方便监控mysql + +[root@localhost ~]# cd /application/mysql/support-files +#该文件夹有mysql初始化(预设)配置文件,覆盖文件是因为注释更全。 + +[root@localhost ~]# cp my-default.cnf /etc/my.cnf +[root@localhost ~]# mkdir /etc/init.d +[root@localhost ~]# cp mysql.server /etc/init.d/mysqld +# mysql.server包含如何启动mysql的脚本命令,让系统知道通过该命令启动mysql时的动作,该目录存放系统中各种服务的启动/停止脚本 +[root@localhost ~]# cd /application/mysql/scripts +[root@localhost scripts]# useradd mysql -s /sbin/nologin -M + +[root@localhost scripts]# yum -y install autoconf +[root@localhost scripts]# yum install -y perl-Sys-Hostname +[root@localhost scripts]# ./mysql_install_db --user=mysql --basedir=/application/mysql --data=/application/mysql/data +[root@localhost ~]# vim /etc/profile.d/mysql.sh +#写到环境变量的子配置文件内,未修改前只能使用/bin/mysql的命令才能启用,而不能全局使用 export PATH="/application/mysql/bin:$PATH" -source /etc/profile #否则要重启系统才生效 +[root@localhost ~]# source /etc/profile #否则要重启系统才生效 ``` - 需要注意,官方编译的二进制包默认是在`/usr/local`目录下的,我们需要修改配置文件 ```shell -sed -i 's#/usr/local#/application#g' /etc/init.d/mysqld /application/mysql/bin/mysqld_safe +[root@localhost ~]# sed -i 's#/usr/local#/application#g' /etc/init.d/mysqld /application/mysql/bin/mysqld_safe ``` -此时不可以通过systemctl命令启动,只能通过/etc/init.d/mysql start启动(nginx也是,如果此时通过这样的命令启动Nginx,会导致systemctl start Nginx失败,因为冲突。) +此时不可以通过systemctl命令启动,只能通过/etc/init.d/mysqld start启动(nginx也是,如果此时通过这样的命令启动Nginx,会导致systemctl start Nginx失败,因为冲突。) - 创建systemd管理文件,并且测试是否正常使用 ```shell -vim /usr/lib/systemd/system/mysqld.service +[root@localhost ~]# vim /usr/lib/systemd/system/mysqld.service [Unit] Description=MySQL Server Documentation=man:mysqld(8) @@ -306,27 +322,128 @@ WantedBy=multi-user.target [Service] User=mysql Group=mysql -ExecStart=/application/mysql/bin/mysqld --defaults-file=/etc/my.cnf #强制从my.cnf读配置,不然会从多个路径读配置 +ExecStart=/application/mysql/bin/mysqld --defaults-file=/etc/my.cnf +#强制从my.cnf读配置,不然会从多个路径读配置 LimitNOFILE = 5000 -server_id = 1 #用作主从的时候生效 +server_id = 1 +#用作主从的时候生效 -vim /etc/my.cnf - basedir = /application/mysql/ - datadir = /application/mysql/data +[root@localhost ~]# vim /etc/my.cnf +basedir = /application/mysql/ +datadir = /application/mysql/data -systemctl daemon-reload -systemctl start mysqld -systemctl enable mysqld +# 关闭防火墙和selinux,负责会因为权限问题启动不了 +[root@localhost scripts]# setenforce 0 +[root@localhost scripts]# systemctl stop firewalld + +# 启动mysqld服务 +[root@localhost ~]# systemctl daemon-reload +[root@localhost ~]# systemctl start mysqld +[root@localhost ~]# systemctl enable mysqld #此时ss -ntl 可以看到3306端口 -mysqladmin -uroot password '123456' -mysql -uroot -p123456 + +[root@localhost ~]# mysqladmin -uroot password '123456' + +# 由于RockyLinux9版本的lib库较新,为了适配mysql5.6版本,我们通过软连接的方式降级 +[root@localhost ~]# ln -s /usr/lib64/libncurses.so.6 /usr/lib64/libncurses.so.5 +[root@localhost ~]# ln -s /usr/lib64/libtinfo.so.6 /usr/lib64/libtinfo.so.5 + +# 登录数据库测试 +[root@localhost ~]# mysql -uroot -p123456 ``` -# 3. MySQL体系结构管理 +## 2.4 客户端工具 + +### 2.4.1 mysql + +用来**连接**和**管理**数据库 + +### 2.4.2 mysqladmin + +- “强制回应 (Ping)”服务器 +- 关闭服务器 +- 创建和删除数据库 +- 显示服务器和版本信息 +- 显示或重置服务器状态变量 +- 设置口令 +- 重新刷新授权表 +- 刷新日志文件和高速缓存 +- 启动和停止复制 + +```shell +[root@localhost ~]# mysqladmin -uroot -p123456 create hellodb +[root@localhost ~]# mysqladmin -uroot -p123456 drop hellodb +[root@localhost ~]# mysqladmin -uroot -p123456 ping # 检查服务端状态的 +[root@localhost ~]# mysqladmin -uroot -p123456 status # 服务器运行状态 +[root@localhost ~]# mysqladmin -uroot -p123456 status # 服务器状态 --sleep 2 --count 10 每两秒钟显示⼀次。服务器实时状态⼀共显示10次 +Uptime:是mysql正常运行的时间。 +Threads:指开启的会话数。 +Questions: 服务器启动以来客户的问题(查询)数目 (应该是只要跟mysql作交互:不管你查询表,还是查询服务器状态都问记一次)。 +Slow queries:按字面意思是慢查询的意思,不知道mysql认为多久才足够算为长查询,这个先放着。 +Opens: 服务器已经打开的数据库表的数量 +Flush tables: 服务器已经执行的flush ...、refresh和reload命令的数量。 +open tables:通过命令是用的 数据库的表的数量,以服务器启动开始。 +Queries per second avg:select语句平均查询时间 +[root@localhost ~]# mysqladmin -uroot -p123456 extended-status 显示状态变量 +[root@localhost ~]# mysqladmin -uroot -p123456 variables 显示服务器变量 +[root@localhost ~]# mysqladmin -uroot -p123456 flush-privileges 数据库重读授权表,等同于reload +[root@localhost ~]# mysqladmin -uroot -p123456 flush-tables 关闭所有已经打开的表 +[root@localhost ~]# mysqladmin -uroot -p123456 flush-threds 重置线程池缓存 +[root@localhost ~]# mysqladmin -uroot -p123456 flush-status 重置⼤多数服务器状态变量 +[root@localhost ~]# mysqladmin -uroot -p123456 flush-logs ⽇志滚动。主要实现⼆进制和中继⽇志滚动 +[root@localhost ~]# mysqladmin -uroot -p123456 flush-hosts 清楚主机内部信息 +[root@localhost ~]# mysqladmin -uroot -p123456 kill 杀死线程 +[root@localhost ~]# mysqladmin -uroot -p123456 refresh 相当于同时执⾏flush-hosts flush-logs +[root@localhost ~]# mysqladmin -uroot -p123456 shutdown 关闭服务器进程 +[root@localhost ~]# mysqladmin -uroot -p123456 version 服务器版本以及当前状态信息 +[root@localhost ~]# mysqladmin -uroot -p123456 start-slave 启动复制,启动从服务器复制线程 +[root@localhost ~]# mysqladmin -uroot -p123456 stop-slave 关闭复制线程 +``` + +### 2.4.3 mysqldump + +- 备份数据库和表的内容 + +```shell +mysqldump -uroot -p --all-databases > /backup/mysqldump/all.db +# 备份所有数据库 +mysqldump -uroot -p test > /backup/mysqldump/test.db +# 备份指定数据库 +mysqldump -uroot -p mysql db event > /backup/mysqldump/2table.db +# 备份指定数据库指定表(多个表以空格间隔) +mysqldump -uroot -p test --ignore-table=test.t1 --ignore-table=test.t2 > /backup/mysqldump/test2.db +# 备份指定数据库排除某些表 +``` + +- 还原的方法 + +```shell +mysqladmin -uroot -p create db_name +mysql -uroot -p db_name < /backup/mysqldump/db_name.db +# 注:在导入备份数据库前,db_name如果没有,是需要创建的; 而且与db_name.db中数据库名是一样的才可以导入。 +mysql > use db_name +mysql > source /backup/mysqldump/db_name.db +# source也可以还原数据库 +``` + +## 2.5 图形化工具Navicate + +在windows上使用navicate工具的时候,需要先登录到MySQL中,授权来自windows的IP访问: + +```bash +mysql > grant all privileges on *.* to root@"192.168.88.%" identified by "123456"; +mysql > flush privileges; +``` + +然后打开navicate,输入数据库的连接信息,连接到数据库中 + +image-20240721151426381 + +# 3. MySQL架构 ## 3.1 客户端与服务器模型 -![img](01.Mysql/tL76EP1rBEQKcpeU.png!thumbnail) +![img](01.Mysql/tL76EP1rBEQKcpeU-173958397657497.png!thumbnail) - mysql是一个典型的C/S服务结构 @@ -369,7 +486,7 @@ 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> status; -------------- mysql Ver 14.14 Distrib 5.6.40, for linux-glibc2.12 (x86_64) using EditLine wrapper Connection id: 4 @@ -390,7 +507,7 @@ TCP port: 3306 Uptime: 1 hour 55 min 9 sec Threads: 2 Questions: 18 Slow queries: 0 Opens: 67 Flush tables: 1 Open tables: 60 Queries per second avg: 0.002 * 套接字连接方式 - * `mysql -uroot -p123456 -S/tmp/mysql.sock` + * `mysql -uroot -p123456 -S /application/mysql/tmp/mysql.sock` ``` ## 3.2 MySQL服务器构成 @@ -400,7 +517,7 @@ Threads: 2 Questions: 18 Slow queries: 0 Opens: 67 Flush tables: 1 Open tab - 实例=mysqld后台守护进程+Master Thread +干活的Thread+预分配的内存 - 公司=老板+经理+员工+办公室 -![img](01.Mysql/k1P7hTxOM3vKCIG2.png!thumbnail) +![img](01.Mysql/k1P7hTxOM3vKCIG2-173958397657498.png!thumbnail) - 连接层 - 验证用户的合法性(ip,端口,用户名) @@ -434,27 +551,23 @@ MySQL的逻辑对象:做为管理人员或者开发人员操作的对象 最直观的数据:二维表,必须用库来存放 -![img](01.Mysql/DsbxGtxBZzy6d1kN.png!thumbnail) +![img](01.Mysql/DsbxGtxBZzy6d1kN-173958397657599.png!thumbnail) mysql逻辑结构与Linux系统对比 -use test; - -create table db01(id int); - -| MySQL | Linux | -| :----------------------- | :------------------- | -| 库 | 目录 | -| show databases; | ls -l / | -| use mysql | cd /mysql | -| 表 | 文件 | -| show tables; | ls | -| 二维表=元数据+真实数据行 | 文件=文件名+文件属性 | +| MySQL | Linux | +| :----------------------- | :---------------------------- | +| 库 | 目录 | +| show databases; | ls -l / | +| use mysql | cd /mysql | +| 表 | 文件 | +| show tables; | ls | +| 二维表=元数据+真实数据行 | 文件=文件名+文件属性+文件内容 | ### 3.2.3 mysql的物理结构 - MySQL的最底层的物理结构是数据文件,也就是说,存储引擎层,打交道的文件,是数据文件。 -- 存储引擎分为很多种类(Linux中的FS) +- 存储引擎分为很多种类 - 不同存储引擎的区别:存储方式、安全性、性能 myisam: @@ -467,22 +580,15 @@ mysql> show create table mysql.user\G; ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges' ``` -![img](01.Mysql/JnL2YEThjuHERQPZ.png!thumbnail) +![img](01.Mysql/JnL2YEThjuHERQPZ-1739583976575100.png!thumbnail) innodb: - 自己创建一个表,在编译的时候已经默认指定使用innodb -![img](01.Mysql/lK3mQW6m9VMwIgVD.png!thumbnail) - -![img](01.Mysql/WCtzPCFRsaTUTp3A.png!thumbnail) - -### 3.2.4 段、区、页(块) - -- 段:理论上一个表就是一个段,由多个区构成,(分区表是一个分区一个段) -- 区:连续的多个页构成 - - 页:最小的数据存储单元,默认是16k #写数据就是替换这16k的数据,不然整个文件重写代价太大 +![img](01.Mysql/lK3mQW6m9VMwIgVD-1739583976575101.png!thumbnail) +![img](01.Mysql/WCtzPCFRsaTUTp3A-1739583976575102.png!thumbnail) # 4. Mysql用户权限管理 @@ -495,7 +601,7 @@ innodb: - Linux用户管理 - - 创建用户:useradd adduser + - 创建用户:useradd - 删除用户:userdel - 修改用户:usermod @@ -507,7 +613,7 @@ innodb: - Mysql用户管理 - 创建用户:create user - - 删除用户:delete user drop user + - 删除用户:delete user、drop user - 修改用户:update - 用户的定义 @@ -525,18 +631,24 @@ innodb: - 刚装完mysql数据库该做的事情 - 先truncate mysql.user;再重启mysql发现进不去了 - - 设定初始密码 ```shell -mysqladmin -uroot password '123456' -* 忘记root密码 -/etc/init.d/mysqld stop -mysqld_safe --skip-grant-tables --skip-networking #skip-networking禁止掉3306端口,不允许网络登录 +[root@localhost ~]# mysqladmin -uroot password '123456' + +# 忘记root密码 +[root@localhost ~]# systemctl stop mysqld +[root@localhost ~]# mysqld_safe --skip-grant-tables --skip-networking +# skip-networking 禁止掉3306端口,不允许网络登录 + # 修改root密码 -update user set password=PASSWORD('123456') where user='root' and host='localhost'; -flush privileges; +[root@localhost ~]# mysql -uroot +mysql> update mysql.user set password=PASSWORD('123') where user='root' and host='localhost'; +mysql> flush privileges; + +# 杀死mysqld服务,重启 +[root@localhost ~]# pkill mysqld +[root@localhost ~]# systemctl start mysqld ``` ## 4.2 用户管理 @@ -544,7 +656,7 @@ flush privileges; - 创建用户 ```sql -mysql> create user user01@'192.168.175.%' identified by '123456'; +mysql> create user user01@'192.168.88.%' identified by '123456'; ``` - 查看用户 @@ -555,28 +667,27 @@ mysql> select user,host from mysql.user; - 查看当前用户 - ```sql - mysql> select user(); - ``` +```sql +mysql> select user(); +``` - 查看当前数据库 - ```sql - mysql> select database(); - ``` +```sql +mysql> select database(); +``` - 删除用户 ```sql -mysql> drop user user01@'192.168.175.%'; +mysql> drop user user01@'192.168.88.%'; ``` - 修改密码 ```sql -mysql> set password=PASSOWRD('123456') -mysql> update user set password=PASSWORD('user01') where user='root' and host='localhost'; -mysql> grant all privileges on *.* to user01@'192.168.175.%' identified by '123456'; +mysql> update mysql.user set password=PASSWORD('user01') where user='root' and host='localhost'; +mysql> grant all privileges on *.* to user01@'192.168.88.%' identified by '123456'; ``` ## 4.3 用户权限介绍 @@ -587,10 +698,39 @@ mysql> grant all privileges on *.* to user01@'192.168.175.%' identified by '1234 INSERT,SELECT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ``` +1. **INSERT**: 用于向数据库表中插入新数据。 +2. **SELECT**: 用于从数据库表中查询和检索数据。 +3. **UPDATE**: 用于更新数据库表中的现有数据。 +4. **DELETE**: 用于从数据库表中删除数据。 +5. **CREATE**: 用于创建数据库对象,如表、视图、存储过程等。 +6. **DROP**: 用于删除数据库对象,如表、视图、存储过程等。 +7. **RELOAD**: 用于重新加载 MySQL 服务器的配置文件。 +8. **SHUTDOWN**: 用于关闭 MySQL 服务器。 +9. **PROCESS**: 用于查看和管理 MySQL 服务器的进程。 +10. **FILE**: 用于读写服务器上的文件。 +11. **REFERENCES**: 用于创建外键约束。 +12. **INDEX**: 用于创建和管理数据库索引。 +13. **ALTER**: 用于修改数据库对象的结构,如表、视图、存储过程等。 +14. **SHOW DATABASES**: 用于查看当前 MySQL 服务器上的所有数据库。 +15. **SUPER**: 是一种特殊的权限,允许用户执行一些高级操作,如查看和杀死其他用户的进程。 +16. **CREATE TEMPORARY TABLES**: 用于创建临时表。 +17. **LOCK TABLES**: 用于手动锁定数据库表。 +18. **EXECUTE**: 用于执行存储过程和函数。 +19. **REPLICATION SLAVE**: 用于配置数据库复制时的从库权限。 +20. **REPLICATION CLIENT**: 用于获取数据库复制状态信息。 +21. **CREATE VIEW**: 用于创建数据库视图。 +22. **SHOW VIEW**: 用于查看数据库视图的定义。 +23. **CREATE ROUTINE**: 用于创建存储过程和函数。 +24. **ALTER ROUTINE**: 用于修改存储过程和函数。 +25. **CREATE USER**: 用于创建新的数据库用户账号。 +26. **EVENT**: 用于创建和管理数据库事件。 +27. **TRIGGER**: 用于创建和管理数据库触发器。 +28. **CREATE TABLESPACE**: 用于创建数据库表空间。 + - 每次设定只能有一个属主,没有属组或其他用户的概念 ```sql -grant all privileges on *.* to user01@''192.168.175.%'' identified by ''123''; +grant all privileges on *.* to user01@''192.168.88.%'' identified by ''123''; 权限 作用对象 归属 密码 ``` @@ -654,41 +794,9 @@ create table tb1 (id int); - 但是我们不推荐在多级别定义重复权限。 - 最常用的权限设定方式是单库级别授权,即:wordpress.* -# 5. MySQL连接管理 +# 5. Mysql启动关闭流程 -- MySQL自带的连接工具 - - mysql -uroot -p123456 -h127.0.0.1 -P3306 -e "show databaese;" - - **不建议使用的方法:** - - ``` - vim /etc/my.cnf - [client] - user = root - password = 123456 - ``` - - - - - mysql - - -u:指定用户 - - -p:指定密码 - - -h:指定主机 - - -P:指定端口 - - -S:指定sock - - -e:指定SQL - -- 第三方连接工具 - - - sqlyog - - navicat - -![img](01.Mysql/agMqU13UrbmuyFz0.png!thumbnail) - -# 6. Mysql启动关闭流程 - -![img](01.Mysql/uCoOhC6Rn5HuTfxg.png!thumbnail) +![img](01.Mysql/uCoOhC6Rn5HuTfxg-1739583976575103.png!thumbnail) - 启动 @@ -698,12 +806,14 @@ create table tb1 (id int); ```shell /etc/init.d/mysqld start ------> mysqld_safe ------> mysqld +systemctl start mysqld ``` - 关闭 ```shell /etc/init.d/mysqld stop +systemctl stop mysqld mysqladmin -uroot -p123456 shutdown kill -9 pid ? killall mysqld ? @@ -717,7 +827,7 @@ pkill mysqld_safe 2. 号称可以达到和Oracle一样的安全性,但是并不能100%达到 3. 在业务繁忙的情况下,丢数据(补救措施,高可用) -# 7. Mysql实例初始化配置 +# 6. Mysql实例初始化配置 - 在启动一个实例的时候,必须要知道如下的问题 - 我不知道我的程序在哪? @@ -727,9 +837,9 @@ pkill mysqld_safe - 我启动,你们给了我多少内存? - ......若干问题 -![img](01.Mysql/Tw0AJl9FjrygD1S4.png!thumbnail) +![img](01.Mysql/Tw0AJl9FjrygD1S4-1739583976575104.png!thumbnail) -- 预编译:cmake去指定,硬编码到程序当中去 +- 预编译:cmake去指定,硬编译到程序当中去 - 在命令行设定启动初始化配置 ```shell @@ -746,12 +856,6 @@ pkill mysqld_safe ``` - 初始化配置文件(/etc/my.cnf) - - 配置文件读取顺序,通过mysql命令:show variables like 'server_id'; - - /etc/my.cnf - - /etc/mysql/my.cnf - - $MYSQL_HOME/my.cnf(前提是在环境变量中定义了MYSQL_HOME变量 /application/mysql/my.conf) - - defaults-extra-file (类似include) - - ~/my.cnf(隐藏文件) - --defaults-file:默认配置文件 - 如果使用./bin/mysqld_safe 守护进程启动mysql数据库时,使用了 --defaults-file=<配置文件的绝对路径>参数,这时只会使用这个参数指定的配置文件。 @@ -778,9 +882,9 @@ socket=/application/mysql/tmp/mysql.sock - [client]所有客户端程序 - [server]所有服务器程序 -# 8. MySQL多实例配置 +# 7. MySQL多实例配置 -## 8.1 多实例 +## 7.1 多实例 - 多套后台进程+线程+内存结构 - 多个配置文件 @@ -790,16 +894,16 @@ socket=/application/mysql/tmp/mysql.sock - 多个server_id - 多套数据 -## 8.2 实战配置 +## 7.2 实战配置 ```shell #创建数据目录 -mkdir -p /data/330{7..9} +[root@localhost ~]# mkdir -p /data/330{7..9} #创建配置文件 -touch /data/330{7..9}/my.cnf -touch /data/330{7..9}/mysql.log +[root@localhost ~]# touch /data/330{7..9}/my.cnf +[root@localhost ~]# touch /data/330{7..9}/mysql.log #编辑3307配置文件 -vim /data/3307/my.cnf +[root@localhost ~]# vim /data/3307/my.cnf [mysqld] basedir=/application/mysql datadir=/data/3307/data @@ -810,8 +914,9 @@ server_id=7 port=3307 [client] socket=/data/3307/mysql.sock + #编辑3308配置文件 -vim /data/3308/my.cnf +[root@localhost ~]# vim /data/3308/my.cnf [mysqld] basedir=/application/mysql datadir=/data/3308/data @@ -822,8 +927,9 @@ server_id=8 port=3308 [client] socket=/data/3308/mysql.sock + #编辑3309配置文件 -vim /data/3309/my.cnf +[root@localhost ~]# vim /data/3309/my.cnf [mysqld] basedir=/application/mysql datadir=/data/3309/data @@ -834,126 +940,49 @@ server_id=9 port=3309 [client] socket=/data/3309/mysql.sock -#初始化3307数据,每条命令需要间隔若干秒,否则失败 -/application/mysql/scripts/mysql_install_db \ + +# 修改目录权限 +[root@localhost ~]# chown -R mysql.mysql /data/330* + +# 初始化3307数据,每条命令需要间隔若干秒,否则失败 +[root@localhost ~]# /application/mysql/scripts/mysql_install_db \ --user=mysql \ --defaults-file=/data/3307/my.cnf \ --basedir=/application/mysql --datadir=/data/3307/data + #初始化3308数据,每条命令需要间隔若干秒,否则失败 -/application/mysql/scripts/mysql_install_db \ +[root@localhost ~]# /application/mysql/scripts/mysql_install_db \ --user=mysql \ --defaults-file=/data/3308/my.cnf \ --basedir=/application/mysql --datadir=/data/3308/data + #初始化3309数据,每条命令需要间隔若干秒,否则失败 -/application/mysql/scripts/mysql_install_db \ +[root@localhost ~]# /application/mysql/scripts/mysql_install_db \ --user=mysql \ --defaults-file=/data/3309/my.cnf \ --basedir=/application/mysql --datadir=/data/3309/data -#修改目录权限 -chown -R mysql.mysql /data/330* + #启动多实例 -mysqld_safe --defaults-file=/data/3307/my.cnf & -mysqld_safe --defaults-file=/data/3308/my.cnf & -mysqld_safe --defaults-file=/data/3309/my.cnf & +[root@localhost ~]# mysqld_safe --defaults-file=/data/3307/my.cnf & +[root@localhost ~]# mysqld_safe --defaults-file=/data/3308/my.cnf & +[root@localhost ~]# mysqld_safe --defaults-file=/data/3309/my.cnf & + #设置每个实例的密码 -#mysqladmin -S /data/3307/mysql.sock -uroot password '123456' +[root@localhost ~]# mysqladmin -S /data/3307/mysql.sock -uroot password '123456' + #查看server_id -mysql -S /data/3307/mysql.sock -e "show variables like 'server_id'" -mysql -S /data/3308/mysql.sock -e "show variables like 'server_id'" -mysql -S /data/3309/mysql.sock -e "show variables like 'server_id'" +[root@localhost ~]# mysql -S /data/3307/mysql.sock -uroot -p123456 -e "show variables like 'server_id'" +[root@localhost ~]# mysql -S /data/3308/mysql.sock -uroot -p123456 -e "show variables like 'server_id'" +[root@localhost ~]# mysql -S /data/3309/mysql.sock -uroot -p123456 -e "show variables like 'server_id'" # 进入单独的mysql实例 -mysql -S /data/3307/mysql.sock -uroot +[root@localhost ~]# mysql -S /data/3307/mysql.sock -uroot # 关闭实例,如果设置了密码登录就需要密码了 用参数-p -mysqladmin -S /data/3307/mysql.sock -uroot shutdown -mysqladmin -S /data/3308/mysql.sock -uroot shutdown -mysqladmin -S /data/3309/mysql.sock -uroot shutdown +[root@localhost ~]# mysqladmin -S /data/3307/mysql.sock -uroot -p123456 shutdown +[root@localhost ~]# mysqladmin -S /data/3308/mysql.sock -uroot -p123456 shutdown +[root@localhost ~]# mysqladmin -S /data/3309/mysql.sock -uroot -p123456 shutdown ``` -# 9. 客户端工具 - -## 9.1 mysql - -- 作用 - - 连接 - - 管理 -- 自带的命令 - -```shell -\h 或 help 或? 查看帮助 -\G 格式化查看数据(key:value) -\T 或 tee 记录日志 \T /tmp/temp.log,临时一次登录有效、永久vim /etc/my.cnf tee= -\c(5.7可以ctrl+c) 结束命令 -\s 或 status 查看状态信息 -\. 或 source 导入SQL数据 -\u或 use 使用数据库 -\q 或 exit 或 quit 退出 -! 或 system 执行shell命令 -``` - -- 接收用户的SQL语句 - -## 9.2 mysqladmin - -- “强制回应 (Ping)”服务器 -- 关闭服务器 -- 创建和删除数据库 -- 显示服务器和版本信息 -- 显示或重置服务器状态变量 -- 设置口令 -- 重新刷新授权表 -- 刷新日志文件和高速缓存 -- 启动和停止复制 - -```shell -[root@localhost ~]# mysqladmin -uroot -p1 create hellodb -[root@localhost ~]# mysqladmin -uroot -p1 drop hellodb -[root@localhost ~]# mysqladmin -uroot -p1 ping 检查服务端状态的 -[root@localhost ~]# mysqladmin -uroot -p1 status 服务器运行状态 -[root@localhost ~]# mysqladmin -uroot -p1 status 服务器状态 --sleep 2 --count 10 每两秒钟显示 -⼀次服务器实时状态⼀共显示10次 -[root@localhost ~]# mysqladmin -uroot -p1 extended-status 显示状态变量 -[root@localhost ~]# mysqladmin -uroot -p1 variables 显示服务器变量 -[root@localhost ~]# mysqladmin -uroot -p1 flush-privileges 数据库重读授权表,等同于reload -[root@localhost ~]# mysqladmin -uroot -p1 flush-tables 关闭所有已经打开的表 -[root@localhost ~]# mysqladmin -uroot -p1 flush-threds 重置线程池缓存 -[root@localhost ~]# mysqladmin -uroot -p1 flush-status 重置⼤多数服务器状态变量 -[root@localhost ~]# mysqladmin -uroot -p1 flush-logs ⽇志滚动。主要实现⼆进制和中继⽇志滚动 -[root@localhost ~]# mysqladmin -uroot -p1 flush-hosts 清楚主机内部信息 -[root@localhost ~]# mysqladmin -uroot -p1 kill 杀死线程 -[root@localhost ~]# mysqladmin -uroot -p1 refresh 相当于同时执⾏flush-hosts flush-logs -[root@localhost ~]# mysqladmin -uroot -p1 shutdown 关闭服务器进程 -[root@localhost ~]# mysqladmin -uroot -p1 version 服务器版本以及当前状态信息 -[root@localhost ~]# mysqladmin -uroot -p1 start-slave 启动复制,启动从服务器复制线程 -[root@localhost ~]# mysqladmin -uroot -p1 stop-slave 关闭复制线程 -``` - -## 9.3 mysqldump - -- 备份数据库和表的内容 - -```shell -mysqldump -uroot -p --all-databases > /backup/mysqldump/all.db -# 备份所有数据库 -mysqldump -uroot -p test > /backup/mysqldump/test.db -# 备份指定数据库 -mysqldump -uroot -p mysql db event > /backup/mysqldump/2table.db -# 备份指定数据库指定表(多个表以空格间隔) -mysqldump -uroot -p test --ignore-table=test.t1 --ignore-table=test.t2 > /backup/mysqldump/test2.db -# 备份指定数据库排除某些表 -``` - -- 还原的方法 - -```shell -mysqladmin -uroot -p create db_name -mysql -uroot -p db_name < /backup/mysqldump/db_name.db -# 注:在导入备份数据库前,db_name如果没有,是需要创建的; 而且与db_name.db中数据库名是一样的才可以导入。 -mysql > use db_name -mysql > source /backup/mysqldump/db_name.db -# source也可以还原数据库 -``` - -# 10. SQL语句 +# 8. SQL语句 - SQL是结构化的查询语句 - SQL的种类 @@ -962,7 +991,7 @@ mysql > source /backup/mysqldump/db_name.db - DML:数据操作语言 - DQL:数据查询语言 -## 10.1 DDL数据定义语句 +## 8.1 DDL数据定义语句 - 对库或者表进行操作的语句 - 创建数据库 @@ -972,7 +1001,18 @@ create database db01; # 创建数据库 create database DB01; # 数据库名区分大小写(注意windows里面不区分) -# show variables like 'lower%'; 可以看到lower_case_table_names默认0是区分大小写通过/etc/my.cnf [mysqld]下可以永久修改 +show variables like 'lower_case_table_names'; ++------------------------+-------+ +| Variable_name | Value | ++------------------------+-------+ +| lower_case_table_names | 0 | ++------------------------+-------+ + +具体lower_case_table_names 取值详解如下: +0:区分大小写 +1:不区分大小写,存储的时候,将表名都转换成小写 +2:不区分大小写,存储的时候,表名跟建表时大小写保持一致 + show databases; # 查看数据库(DQL) show create database db01; @@ -1002,13 +1042,16 @@ show create database db01; ```sql help create table; # 查看创表语句的帮助 + +use db01; +# 进入库中 create table student( sid int, sname varchar(20), sage tinyint, sgender enum('m','f'), -comtime datetime; -) +cometime datetime +); # 创建表,并且定义每一列 ``` @@ -1023,19 +1066,23 @@ comtime datetime; | datetime | 时间类型 年月日时分秒 | ```sql +# 删除表 +drop table student; + +# 带数据属性创建学生表 create table student( sid int not null primary key auto_increment comment '学号', sname varchar(20) not null comment '学生姓名', sgender enum('m','f') not null default 'm' comment '学生性别', cometime datetime not null comment '入学时间' )charset utf8 engine innodb; -# 带数据属性创建学生表 -show create table student; + # 查看建表语句 -show tables; +show create table student; # 查看表 -desc student; +show tables; # 查看表中列的定义信息 +desc student; ``` - 数据属性 @@ -1076,15 +1123,16 @@ alter table stu change phone telphone char(20); # 修改列及定义(列名及属性) ``` -## 10.2 DCL数据控制语言 +## 8.2 DCL数据控制语言 - DCL是针对权限进行控制 - 授权 ```sql -grant all on *.* to root@'192.168.175.%' identified by '123456' +grant all on *.* to root@'192.168.88.%' identified by '123456' # 授予root@'192.168.175.%'用户所有权限(非超级管理员) -grant all on *.* to root@'192.168.175.%' identified by '123456' with grant option; + +grant all on *.* to root@'192.168.88.%' identified by '123456' with grant option; # 授权一个超级管路员 max_queries_per_hour:一个用户每小时可发出的查询数量 max_updates_per_hour:一个用户每小时可发出的更新数量 @@ -1095,50 +1143,66 @@ max_user_connections:允许同时连接数量 - 收回权限 ```sql -revoke select on *.* from root@'192.168.175.%'; +revoke select on *.* from root@'192.168.88.%'; # 收回select权限 -show grants for root@'192.168.175.%'; +show grants for root@'192.168.88.%'; # 查看权限 ``` -## 10.3 DML数据操作语言 +## 8.3 DML数据操作语言 - 操作表中的数据 - 插入数据 ```sql -insert into stu valus('linux01',1,NOW(),'zhangsan',20,'m',NOW(),110,123456); +create table stu( +sid int not null primary key auto_increment comment '学号', +sname varchar(20) not null comment '学生姓名', +sgender enum('m','f') not null default 'm' comment '学生性别', +sage int comment '年龄', +qq varchar(20) comment 'QQ', +telphone varchar(20) comment '电话号', +cometime datetime not null comment '入学时间' +)charset utf8 engine innodb; + +insert into stu values(1,'zhangsan','m',19,'123123','18888888888',NOW()); # 基础用法,插入数据 -insert into stu(classid,birth.sname,sage,sgender,comtime,telnum,qq) values('linux01',1,NOW(),'zhangsan',20,'m',NOW(),110,123456); + +insert into stu(sname,sgender,sage,qq,telphone,cometime) values('lisi','f',20,'11111',1777777777,NOW()); # 规范用法,插入数据 -insert into stu(classid,birth.sname,sage,sgender,comtime,telnum,qq) values('linux01',1,NOW(),'zhangsan',20,'m',NOW(),110,123456), -('linux02',2,NOW(),'zhangsi',21,'f',NOW(),111,1234567); + +insert into stu(sname,sgender,sage,qq,telphone,cometime) values('linux01','f',20,'11111',1777777777,NOW()), +('linux02','f',20,'22222',1777777777,NOW()); # 插入多条数据 -insert into stu(classid,birth.sname,sage,sgender,comtime,qq) values('linux01',1,NOW(),'zhangsan',20,'m',NOW(),123456); -#少了电话 + +insert into stu(sname,cometime) values('linux03',NOW()); +# 不是非空字段可以为空 ``` - 更新数据 ```sql -update student set sgender='f'; +update stu set sgender='f'; # 不规范 -update student set sgender='f' where sid=1; + +update stu set sgender='f' where sid=1; # 规范update修改 -update student set sgender='f' where 1=1; + +update stu set sgender='f' where 1=1; # 如果非要全表修改 + update mysql.user set password=PASSWORD('123456') where user='root' and host='localhost'; # 修改密码,需要刷新权限flush privileges ``` -- 删除数据 +- 删除数据` ```sql -delete from student; +delete from stu; # 不规范 -delete from student where sid=3; +delete from stu where sid=6; # 规范删除(危险) -truncate table student; +truncate table stu; # DDL清空表中的内容,恢复表原来的状态,自增重新从1开始,否则delete依旧正常增长 ``` @@ -1147,23 +1211,24 @@ truncate table student; - 使用update代替delete,将状态改成删除状态,在查询的时候就可以不显示被标记删除的数据 ```sql -alter table student add status enum(1,0) default 1; +alter table stu add status enum('1','0') default '1'; # 额外添加一个状态列 -update student set status='0' where sid=1; +update stu set status='0' where sid=1; # 使用update -select * from student where status=1; +select * from stu where status=1; # 应用查询存在的数据 ``` -## 10.4 DQL数据查询语言 +## 8.4 DQL数据查询语言 - select:基础用法 - 演示用的SQL文件下载:https://download.s21i.faiusr.com/23126342/0/0/ABUIABAAGAAgzcXwhQYozuPv2AE?f=world.sql&v=1622942413 ```sql mysql -uroot -p123 < world.sql -或者mysql> \. /root/world.sql -# 常用用法 +或者mysql> source /root/world.sql + + select countrycode,district from city; # 常用用法 select countrycode from city; @@ -1177,7 +1242,7 @@ select name,population from city where countrycode='CHN' and district='heilongji # 多条件查询 select name,population,countrycode from city where countrycode like '%H%' limit 10; # 模糊查询 -select id,name,population,countrycode from city order by countrycode limit 10; + select id,name,population,countrycode from city order by countrycode limit 10; # 排序查询(顺序) select id,name,population,countrycode from city order by countrycode desc limit 10; # 排序查询(倒序) @@ -1191,12 +1256,12 @@ select country.name,city.name,city.population,country.code from city,country whe # 多表查询 ``` -# 11. 字符集定义 +# 9. 字符集定义 - 什么是字符集(Charset) - 字符集:是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。 -![img](01.Mysql/157ueBBseL6MvenH.png!thumbnail) +![img](01.Mysql/157ueBBseL6MvenH-1739583976575105.png!thumbnail) - MySQL数据库的字符集 - 字符集(CHARACTER) @@ -1248,83 +1313,9 @@ mysql> alter table t1 CHARACTER SET utf8; # 修改字符集 ``` -# 12. select的高级用法 +# 10. MySQL数据类型 -- 多表连接查询(连表查询) - -```sql -create table t1(id int primary key auto_increment,name varchar(20)) ENGINE=InnoDB CHARSET=utf8; -create table t2(id int primary key auto_increment,score int) ENGINE=InnoDB CHARSET=utf8; -insert into t1(name) values('cs'),('tj'),('lz'); -insert into t2(score) values(30),(80),(82); -select * from t1; -select * from t2; -``` - -- 传统连接(只能内连接,只能取交集) - -```sql -select t1.name,t2.score from t1,t2 where t1.id=t2.id and t2.score > 60; -# 查出及格 -#世界上小于100人的人口城市是哪个国家的? -select city.name,city.countrycode,country.name -from city,country -where city.countrycode=country.code -and city.population<100; -# 世界上小于100人的人口城市是哪个国家,说的什么语言? -国家人口数量 城市名 国家名 语言 -country.population, city.name, country.name, countrylanguage.Language -select country.population,city.name,country.name,countrylanguage.Language from city,country,countrylanguage where city.countrycode=country.code and countrylanguage.countrycode=country.code and country.population<100; -``` - -- NATURAL JOIN(自连接的表要有共同的列名字) - -```sql -SELECT city.name,city.countrycode ,countrylanguage.language ,city.population -FROM city NATURAL JOIN countrylanguage -WHERE population > 1000000 -ORDER BY population; -``` - -- 企业中多表连接查询(内连接) - -```sql -select city.name,city.countrycode,country.name -from city join country on city.countrycode=country.code -where city.population<100; -``` - -建议:使用join语句时,小表在前,大表在后。 - -- 外连接 - -```sql -select city.name,city.countrycode,country.name -from city left join country -on city.countrycode=country.code -and city.population<100; -``` - -- UNION(合并查询) - -```sql -mysql> select * from city where countrycode='CHN' or countrycode='USA'; -#范围查询OR语句 -mysql> select * from city where countrycode in ('CHN','USA'); -#范围查询IN语句 -替换为: -mysql> select * from city where countrycode='CHN' -union all -select * from city where countrycode='USA' limit 10 -``` - -- union:去重复合并 -- union all :不去重复 -- 使用情况:union + +**B+树的特点**: + +1. 多路平衡树,每个节点可以有多个子节点,树始终保持平衡,适合高效查找。 +2. 数据只在叶子节点,内部节点只存键值和指针(索引信息),叶子节点存键值和实际数据(或数据指针)。 +3. 叶子节点通过指针连接成链表,支持高效的范围查询和顺序访问。 +4. 适合磁盘存储,节点大小通常设计为磁盘块大小,减少磁盘 I/O 次数。 + +#### 11.2.1.2 B*树 + + + +#### 11.2.1.3 为什么 MySQL 使用 B+ 树? + +1. **数据存储在叶子节点** + B+ 树的所有数据都存储在叶子节点,内部节点只存储键值和指针。这种设计使得树的高度更低,查询效率更高。 +2. **叶子节点形成有序链表** + B+ 树的叶子节点通过指针连接成链表,非常适合范围查询(如 `BETWEEN`、`>`、`<` 等操作),只需遍历叶子节点即可。 +3. **更适合磁盘存储** + B+ 树的节点大小通常设计为磁盘块的大小,减少了磁盘 I/O 次数,适合处理大规模数据。 +4. **更高的查询效率** + 由于 B+ 树的内部节点只存储键值和指针,一个节点可以存储更多的键值,从而降低树的高度,减少查找时间。 + +#### 11.2.1.4 B+ 树 vs B 树 + +| 特性 | B 树 | B+ 树 | +| :--------------- | :--------------------- | :------------------------- | +| **数据存储位置** | 所有节点都可以存储数据 | 只有叶子节点存储数据 | +| **叶子节点连接** | 叶子节点没有连接 | 叶子节点通过指针连接成链表 | +| **范围查询效率** | 较低 | 较高 | +| **适合场景** | 内存数据库或小规模数据 | 磁盘数据库或大规模数据 | + +### 11.2.2 按功能分类 + +- **普通索引(INDEX)**:最基本的索引,没有任何限制。 + - 就像是在一本书的页边做了一些标记,方便以后快速找到感兴趣的内容。 + - 普通索引不要求值必须唯一,可以建立在单个列或多个列上。 + - 普通索引可以提高查询速度,但更新和插入数据时会稍微损耗一些性能。 +- **唯一索引(UNIQUE)**:索引列的值必须唯一,允许有空值。 + - 可以认为是一种特殊的主键,它要求索引列的值必须是唯一的。 + - 唯一索引既可以提高查询效率,又能确保数据的完整性,防止出现重复数据。 + - 不过,与主键不同的是,唯一索引允许出现空值。 +- **主键索引(PRIMARY KEY)**:特殊的唯一索引,不允许有空值。 + - 就像是一本书的目录页,可以快速定位到某一页的内容。 + - 每一行数据都有一个独一无二的标识(主键),建立主键索引可以迅速找到对应的行。 + - 主键索引是最重要的索引类型,能大大提高查询效率。 +- **全文索引(FULLTEXT)**:用于全文搜索。 +- ........ + +## 11.3 索引管理 + +### 11.3.1 添加索引 + +1. 添加普通索引 ```sql -alter table test add index index_name(name); -#创建索引 -create index index_name on test(name); -#创建索引 -desc table; -#查看索引 -show index from table; -#查看索引 -alter table test drop key index_name; -#删除索引 -alter table student add unique key uni_xxx(xxx); -#添加主键索引(略) -#添加唯一性索引 -select count(*) from city; -#查看表中数据行数 -select count(distinct(name)) from city; -#查看去重数据行数 +create index idx_name on table_name(column_name); + +# 查看索引 +show index from table_name; + +# 案例 +mysql> create index sname_idx on stu(sname); +Query OK, 0 rows affected (0.01 sec) +Records: 0 Duplicates: 0 Warnings: 0 +mysql> show index from stu; ++-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ +| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | ++-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ +| stu | 0 | PRIMARY | 1 | sid | A | 2 | NULL | NULL | | BTREE | | | +| stu | 1 | sname_idx | 1 | sname | A | 2 | NULL | NULL | | BTREE | | | ++-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ +2 rows in set (0.00 sec) ``` -## 14.3 前缀索引和联合索引 +2. 添加主键索引 -### 14.3.1 前缀索引 +如果我们将某个列设置为主键的话,那么会默认顺带设置主键索引。 + +手动添加主键索引 + +```sql +alter table table_name add primary key (column_name); +``` + +3. 添加唯一索引 + +```sql +create unique index idx_name on table_name(column_name); + +# 案例 +mysql> create unique index qq_idx on stu(qq); +Query OK, 0 rows affected (0.00 sec) +Records: 0 Duplicates: 0 Warnings: 0 + +mysql> show index from stu; ++-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ +| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | ++-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ +| stu | 0 | PRIMARY | 1 | sid | A | 2 | NULL | NULL | | BTREE | | | +| stu | 0 | qq_idx | 1 | qq | A | 2 | NULL | NULL | YES | BTREE | | | +| stu | 1 | sname_idx | 1 | sname | A | 2 | NULL | NULL | | BTREE | | | ++-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ +3 rows in set (0.00 sec) +``` + +#### 11.3.1.1 删除索引 + +删除普通索引或者唯一索引 + +```sql +DROP INDEX idx_name ON table_name; +``` + +删除主键索引 + +```sql +ALTER TABLE table_name DROP PRIMARY KEY; +``` + +## 11.4 前缀索引和联合索引 + +### 11.4.1 前缀索引 + +前缀索引是对列的前缀部分创建索引,适用于较长的字符串列。 - 根据字段的前N个字符建立索引 @@ -1503,10 +1591,9 @@ alter table test add index idx_name(name(10)); #比如表里很多城市以D开头,Dalas Des'Moine Denver Detroit,以字母D建立的索引会加快检索速度 ``` -- 避免对大列建索引 -- 如果有,就使用前缀索引 +### 11.4.2 联合索引 -### 14.3.2 联合索引 +联合索引是对多个列组合创建的索引。 - 多个字段建立一个索引 - 原则:把最常用来做为条件查询的列放在最前面 @@ -1514,42 +1601,88 @@ alter table test add index idx_name(name(10)); ```sql create table people (id int,name varchar(20),age tinyint,money int ,gender enum('m','f')); #创建people表 -alter table people add index idx_gam(gender,age,money); +alter table people add index idx_gam(gender,age,money); #创建联合索引 ``` -## 14.4 explain详解 +## 11.5 explain详解 -- explain命令使用方法 +`EXPLAIN` 是 SQL 中一个非常有用的关键字,它可以帮助我们分析和优化 SQL 查询的执行计划。使用 `EXPLAIN` 语句可以获取 SQL 查询的执行计划,了解查询是如何执行的,从而帮助我们识别并优化查询性能瓶颈。 + +下面我们来详细讲解 `EXPLAIN` 语句的用法和输出含义: ```sql -mysql> explain select name,countrycode from city where id=1; +mysql> explain select * from stu where sname='linux02'; ++----+-------------+-------+------+---------------+-----------+---------+-------+------+-----------------------+ +| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | ++----+-------------+-------+------+---------------+-----------+---------+-------+------+-----------------------+ +| 1 | SIMPLE | stu | ref | sname_idx | sname_idx | 62 | const | 1 | Using index condition | ++----+-------------+-------+------+---------------+-----------+---------+-------+------+-----------------------+ +1 row in set (0.01 sec) ``` -- MySQL查询数据的方式 - - 全表扫描(在explain语句结果中type为ALL,例如select * from XXX) - - 业务确实要获取所有数据 - - 不走索引导致的全表扫描 - - 没索引 - - 索引创建有问题 - - 语句有问题 - - 生产中,mysql在使用全表扫描时的性能是极其差的,所以MySQL尽量避免出现全表扫描 - - 索引扫描 - - 常见的索引扫描类型 - - index - - range - - ref - - eq_ref - - const - - system - - null - - 从上到下,性能从最差到最好,我们认为至少要达到range级别 +1. **使用方法**: -### 14.4.1 index + - 在 SQL 语句前加上 `EXPLAIN` 关键字即可,例如: `EXPLAIN SELECT * FROM users WHERE id = 1;` + + ```sql + mysql> explain select name,countrycode from city where id=1; + ``` + +2. **输出信息**: + + - `id`: 查询编号,表示查询执行的顺序。如果有子查询,每个子查询都会分配一个单独的 id。 + - `select_type`: 查询类型,包括 SIMPLE、PRIMARY、SUBQUERY 等。 + - `table`: 正在访问的数据表名称。 + - `type`: 访问类型,包括 system、const、eq_ref、ref、range、index、ALL 等,访问类型由快到慢依次排列。 + - `possible_keys`: 可能使用的索引。 + - `key`: 实际使用的索引名称。 + - `key_len`: 使用索引的长度。 + - `ref`: 列上的比较操作。 + - `rows`: 估计要读取的行数。 + - `filtered`: 条件过滤后剩余的行占原始行的比例。 + - `Extra`: 一些额外的信息,如 Using index、Using where 等。 + +3. **应用场景**: + + - 查看查询计划,了解 MySQL 是如何执行 SQL 查询的。 + - 分析查询瓶颈,如果 `type` 是 `ALL` 表示全表扫描,可能需要优化索引。 + - 检查是否使用了正确的索引,`possible_keys` 和 `key` 列可以告诉你 MySQL 选择了哪个索引。 + - 估算查询的行数,`rows` 列给出了 MySQL 估计的行数,可以帮助判断查询的效率。 + +### 11.5.1 MySQL查询数据的方式 + +**全表扫描**(在explain语句结果中type为ALL,例如select * from XXX) + +**出现场景:** + +- 业务确实要获取所有数据 +- 不走索引导致的全表扫描 + - 没索引 + - 索引创建有问题 + - 语句有问题 + +- 生产中,mysql在使用全表扫描时的性能是极其差的,所以MySQL尽量避免出现全表扫描 + +**索引扫描** + +#### 11.5.1.1 常见的索引扫描类型 + +- index(全索引扫描,扫描整个索引树) +- range(范围扫描,使用索引进行范围查询) +- ref(使用非唯一索引进行等值查询) +- eq_ref(使用唯一索引进行等值查询,通常出现在多表连接中) +- const(使用主键或唯一索引进行等值查询,最多返回一行) +- system(表中只有一行数据,是 const 的特例) +- null(MySQL 不用访问表或索引就能得到结果) + +- 从上到下,性能从最差到最好,我们认为至少要达到range级别 + +### 11.5.2 index - Full Index Scan,index与ALL区别为index类型只遍历索引树。 -### 14.4.2 range +### 11.5.3 range - 索引范围扫描,对索引的扫描开始于某一点,返回匹配值域的行。显而易见的索引范围扫描是带有between或者where子句里带有<,>查询。 @@ -1558,7 +1691,7 @@ mysql> alter table city add index idx_city(population); mysql> explain select * from city where population>30000000; ``` -### 14.4.3 ref +### 11.5.4 ref - 用非唯一索引扫描或者唯一索引的前缀扫描,返回匹配某个单独值的记录行。 @@ -1569,7 +1702,7 @@ mysql> explain select * from city where countrycode in ('CHN','USA'); mysql> explain select * from city where countrycode='CHN' union all select * from city where countrycode='USA'; ``` -### 14.4.4 eq_ref +### 11.5.5 eq_ref - 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件A @@ -1578,7 +1711,7 @@ join B on A.sid=B.sid ``` -### 14.4.5 const、system +### 11.5.6 const、system - 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。 - 如将主键置于where列表中,MySQL就能将该查询转换为一个常量 @@ -1587,7 +1720,7 @@ on A.sid=B.sid mysql> explain select * from city where id=1000; ``` -### 14.4.6 NULL +### 11.5.7 NULL - MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。 @@ -1595,11 +1728,33 @@ mysql> explain select * from city where id=1000; mysql> explain select * from city where id=1000000000000000000000000000; ``` -### 14.4.7 Extra(扩展) +### 11.5.8 Extra(扩展) + +在 MySQL 中,当你执行一条 SQL 语句时,结果集通常包含一个名为 "Extra" 的列,它提供了一些额外的信息,可以帮助我们更好地理解 SQL 语句的执行过程。下面是一些常见的 "Extra" 信息及其含义: + +1. **No index used** + - 表示在执行 SQL 语句时,数据库没有使用任何索引。这可能会降低查询性能。 +2. **Using index** + - 表示在执行 SQL 语句时,数据库使用了索引来优化查询。这通常意味着查询性能较好。 +3. **Using index condition** + - 表示在执行 SQL 语句时,数据库使用了索引条件下推(Index Condition Pushdown)技术来优化查询。这可以减少不必要的行访问。 +4. **Using index for group-by** + - 表示在执行 GROUP BY 语句时,数据库使用了索引来优化分组操作。 +5. **Using temporary** + - 表示在执行 SQL 语句时,数据库创建了一个临时表来存储中间结果。这可能会降低查询性能。 +6. **Using filesort** + - 表示在执行 SQL 语句时,数据库需要对结果集进行额外的排序操作。这可能会降低查询性能。 +7. **Using join buffer (Block Nested Loop)** + - 表示在执行 JOIN 查询时,数据库使用了连接缓冲区来优化连接操作。 +8. **Impossible WHERE noticed after reading const tables** + - 表示在执行 SQL 语句时,数据库发现 WHERE 条件永远为 false,因此直接返回空结果集。 +9. **No tables used** + - 表示在执行 SQL 语句时,数据库没有访问任何表,例如执行 `SELECT 1;`。 +10. **Select tables optimized away** + - 表示在执行 SQL 语句时,数据库优化掉了部分表的访问,例如在某些情况下,数据库可以直接从索引中获取所需的数据,而无需访问表本身。 + +这些 "Extra" 信息可以帮助我们了解 SQL 语句的执行过程,识别潜在的性能问题,并针对性地优化查询。在优化 SQL 语句时,我们应该关注那些可能降低性能的信息,例如 "Using temporary"、"Using filesort" 等 -- Using temporary -- Using filesort 使用了默认的文件排序(如果使用了索引,会避免这类排序) -- Using join buffer - 如果出现Using filesort请检查order by ,group by ,distinct,join 条件列上没有索引 ```sql @@ -1615,7 +1770,7 @@ mysql> select * from city where population=2870300 order by population; * 前缀索引去控制,rows: 越小越好 ``` -## 14.5 建立索引的原则(规范) +## 11.6 建立索引的原则(规范) - 为了使索引的使用效率更高,在创建索引时,必须考虑在哪些字段上创建索引和创建什么类型的索引。 - 选择唯一性索引 @@ -1708,16 +1863,6 @@ mysql> explain select * from test where telnum=120; mysql> explain select * from test where telnum='120'; ``` -- <> ,not in 不走索引 - -```sql -mysql> select * from tab where telnum <> '1555555'; -mysql> explain select * from tab where telnum <> '1555555'; -``` - -- 单独的>,<,in 有可能走,也有可能不走,和结果集有关,尽量结合业务添加limit -- or或in尽量改成union - ```sql EXPLAIN SELECT * FROM teltab WHERE telnum IN ('110','119'); #改写成 @@ -1726,40 +1871,15 @@ UNION ALL SELECT * FROM teltab WHERE telnum='119' ``` -- like "%_" 百分号在最前面不走索引 +# 12. MySQL的存储引擎 -```sql -#走range索引扫描 -EXPLAIN SELECT * FROM teltab WHERE telnum LIKE '31%'; -#不走索引 -EXPLAIN SELECT * FROM teltab WHERE telnum LIKE '%110'; -``` +## 12.1 存储引擎简介 -%linux%类的搜索需求,可以使用Elasticsearch -------> ELK +​ Mysql的数据用不同的技术存储在文件(或内存)中,不同的技术拥有不同的存储机制、索引技巧、锁定水平,通过选择不同的技术获得不同的功能,从而改善应用的整体功能,而这些不同的技术和功能就是存储引擎(也称作表引擎) -- 单独引用联合索引里非第一位置的索引列 +​ Mysql支持的存储引擎:InnoDB、MyISAM、MEMORY、CSV、BLACKHOLE、FEDERATED、MRG_MYISAM、 ARCHIVE、PERFORMANCE_SCHEMA。其中NDB和InnoDB提供事务安全表,其他存储引擎都是非事务安全表 -```sql -CREATE TABLE t1 (id INT,NAME VARCHAR(20),age INT ,sex ENUM('m','f'),money INT); -ALTER TABLE t1 ADD INDEX t1_idx(money,age,sex); -DESC t1 -SHOW INDEX FROM t1 -#走索引的情况测试 -EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE money=30 AND age=30 AND sex='m'; -#部分走索引 -EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE money=30 AND age=30; -EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE money=30 AND sex='m'; -#不走索引 -EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE age=20 -EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE age=30 AND sex='m'; -EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE sex='m'; -``` - -# 15. MySQL的存储引擎 - -## 15.1 存储引擎简介 - -![img](01.Mysql/KkaagjFIBB8C0CCF.png!thumbnail) +![img](01.Mysql/KkaagjFIBB8C0CCF-1739583976575108.png!thumbnail) - 文件系统: - 操作系统组织和存取数据的一种机制。 @@ -1773,7 +1893,7 @@ EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE sex='m'; - 除了可以提供基本的存取功能,还有更多功能事务功能、锁定、备份和恢复、优化以及特殊功能 - 总之,存储引擎的各项特性就是为了保障数据库的安全和性能设计结构。 -## 15.2 MySQL自带的存储引擎类型 +## 12.2 MySQL自带的存储引擎类型 - MySQL 提供以下存储引擎: - InnoDB @@ -1792,8 +1912,92 @@ EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE sex='m'; - perconaDB - mariaDB +## 12.3 不同存储引擎介绍 + +### 12.3.1 InnoDB + +MySql 5.6 版本默认的存储引擎。InnoDB 是一个事务安全的存储引擎,它具备提交、回滚以及崩溃恢复的功能以 保护用户数据。InnoDB 的行级别锁定以及 Oracle 风格的一致性无锁读提升了它的多用户并发数以及性能。 + +InnoDB 将用户数据存储在聚集索引中以减少基于主键的普通查询所带来的 I/O 开销。为了保证数据的完整性, + +InnoDB 还支持外键约束。 + +应用场景:并发高、数据一致、更新和删除操作较多、事务的完整提交和回滚 + +**innodb体系结构:** + +innodb主要包括 内存池、后台线程以及存储文件 + +内存池是由多个内存块组成的,主要包括缓存磁盘数据,redolog 缓冲等 + +后台线程则包括了: Master Thread、IO Thread、Purge Thread等 + +由 InnoDB 存储引擎实现的表的存储结构文件一般包括表结构文件(.frm)、共享表空间文件(ibdata1)、独占表空间文件(ibd)以及日志文件(redo 文件等)等。 + +### 12.3.2 MyISAM(读、插入操作) + +MyISAM既不支持事务、也不支持外键、其优势是访问速度快,但是表级别的锁定限制了它在读写负载方面的性能, 因此它经常应用于只读或者以读为主的数据场景。 + +应用场景:读操作和插入操作为主 + +### 12.3.3 Memory(内存存储数据,快速定位记录) + +在内存中存储所有数据,应用于对非关键数据由快速查找的场景。Memory类型的表访问数据非常快,因为它的数据 是存放在内存中的,并且默认使用HASH索引,但是一旦服务关闭,表中的数据就会丢失 + +应用场景:快速定位记录 + +- MEMORY是MySQL中一类特殊的存储引擎。它使用存储在内存中的内容来创建表,而且数据全部放在内存中。这些特性与前面的两个很不同。 +- 每个基于MEMORY存储引擎的表实际对应一个磁盘文件。该文件的文件名与表名相同,类型为frm类型。该文件中只存储表的结构。而其数据文件,都是存储在内存中,这样有利于数据的快速处理,提高整个表的效率。值得注意的是,服务器需要有足够的内存来维持MEMORY存储引擎的表的使用。如果不需要了,可以释放内存,甚至删除不需要的表。 +- MEMORY默认使用哈希索引。速度比使用B型树索引快。当然如果你想用B型树索引,可以在创建索引时指定。 +- 注意,MEMORY用到的很少,因为它是把数据存到内存中,如果内存出现异常就会影响数据。如果重启或者关机,所有数据都会消失。因此,基于MEMORY的表的生命周期很短,一般是一次性的。 + +### 12.3.4 BLACKHOLE(只接收不保存数据) + +黑洞存储引擎,类似于 Unix 的 /dev/null,Archive 只接收但却并不保存数据。对这种引擎的表的查询常常返 回一个空集。这种表可以应用于 DML 语句需要发送到从服务器,但主服务器并不会保留这种数据的备份的主从配置 中。 + +### 12.3.5 CSV + +它的表真的是以逗号分隔的文本文件。CSV 表允许你以 CSV 格式导入导出数据,以相同的读和写的格式和脚本和应用交互数据。由于 CSV 表没有索引,你最好是在普通操作中将数据放在 InnoDB 表里,只有在导入或导出阶段 使用一下 CSV 表。 + +### 12.3.6 NDB + +(又名 NDBCLUSTER)——这种集群数据引擎尤其适合于需要最高程度的正常运行时间和可用性的应用。注意:NDB 存 储引擎在标准 MySql 5.6 版本里并不被支持。 + +目前能够支持 MySql 集群的版本有:基于 MySql 5.1 的 MySQL Cluster NDB 7.1;基于 MySql 5.5 的 MySQL Cluster NDB 7.2;基于 MySql 5.6 的 MySQL Cluster NDB 7.3。同样基于 MySql 5.6 的 MySQL Cluster NDB 7.4 + +目前正处于研发阶段。 + +### 12.3.7 Merge(超大规模数据场景) + +允许 MySql DBA 或开发者将一系列相同的 MyISAM 表进行分组,并把它们作为一个对象进行引用。适用于超大规 模数据场景,如数据仓库。 + +### 12.3.8 Federated(分布式) + +提供了从多个物理机上联接不同的 MySql 服务器来创建一个逻辑数据库的能力。适用于分布式或者数据市场的场景。 + +### 12.3.9 Example(保存例子) + +这种存储引擎用以保存阐明如何开始写新的存储引擎的 MySql 源码的例子。它主要针对于有兴趣的开发人员。这 种存储引擎就是一个啥事也不做的 "存根"。你可以使用这种引擎创建表,但是你无法向其保存任何数据,也无法从 它们检索任何索引。 + +### 12.3.10 **经典面试题:InnoDB和MyISAM区别** + +两种存储引擎的大致区别表现在: + +- InnoDB支持事务,MyISAM不支持,这一点是非常之重要。事务是一种高级的处理方式,如在一些列增删改中只要哪个出错还可以回滚还原,而MyISAM就不可以了。 +- MyISAM适合查询以及插入为主的应用。 +- InnoDB适合频繁修改以及涉及到安全性较高的应用。 +- InnoDB支持外键,MyISAM不支持。 +- 从MySQL5.5.5以后,InnoDB是默认引擎。 +- InnoDB不支持FULLTEXT类型的索引。 +- InnoDB中不保存表的行数,如select count(*) from table时,InnoDB需要扫描一遍整个表来计算有多少行,但是 MyISAM只要简单的读出保存好的行数即可。注意的是,当count()语句包含where条件时MyISAM也需要扫描整个表。 +- 对于自增长的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中可以和其他字段一起建立联合索引。 +- DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的 删除,效率非常慢。MyISAM则会重建表。 +- InnoDB支持行锁(某些情况下还是锁整表,如 update table set a=1 where user like '%lee%'。 + +## 12.4 查看当前MySQL的存储引擎 + ```sql -mysql> show engines +mysql> show engines; #查看当前MySQL支持的存储引擎类型 mysql> select table_schema,table_name,engine from information_schema.tables where engine='innodb'; #查看innodb的表有哪些 @@ -1819,7 +2023,7 @@ mysql> select table_schema,table_name,engine from information_schema.tables wher -rw-rw---- 1 mysql mysql 688128 Aug 14 16:23 city.ibd ``` -## 15.3 innodb存储引擎的简介 +## 12.5 innodb存储引擎的简介 - 在MySQL5.5版本之后,默认的存储引擎,提供高可靠性和高性能。 @@ -1886,13 +2090,6 @@ SHOW TABLE STATUS LIKE 'CountryLanguage'\G # 查看表的存储引擎 ``` -- 使用 INFORMATION_SCHEMA 确认每个表的存储引擎 - -```sql -SELECT TABLE_NAME, ENGINE FROM INFORMATION_SCHEMA.TABLESWHERE TABLE_NAME = 'City'AND TABLE_SCHEMA = 'world'\G -# 查看表的存储引擎 -``` - - 存储引擎的设置 - 在启动配置文件中设置服务器存储引擎 @@ -1912,14 +2109,14 @@ SET @@storage_engine= - 在 CREATE TABLE 语句指定 ```sql -CREATE TABLE t (i INT) ENGINE = ; +CREATE TABLE talbe_name (id int) ENGINE = ; # 建表的时候指定存储引擎 ``` -## 15.4 【实战】存储引擎切换 +## 12.6 【实战】存储引擎切换 - 项目背景: - - 公司原有的架构:一个展示型的网站,LAMT,MySQL5.1.77版本(MYISAM),50M数据量。 + - 公司原有的架构:一个展示型的网站,LAMP,MySQL5.1.77版本(MYISAM),50M数据量。 - 小问题不断: - 表级锁:对表中任意一行数据修改类操作时,整个表都会锁定,对其他行的操作都不能同时进行。 - 不支持故障自动恢复(CSR):当断电时有可能会出现数据损坏或丢失的问题。 @@ -1948,50 +2145,7 @@ CREATE TABLE t (i INT) ENGINE = ; - 停应用,将备份之后的生产库发生的新变化,补偿到新库 - 应用割接到新数据库 -## 15.5 表空间介绍 - -![img](01.Mysql/5TsFS9HElaslP5ss.png!thumbnail) - -- 5.5版本以后出现共享表空间概念 -- 表空间的管理模式的出现是为了数据库的存储更容易扩展 -- 5.6版本中默认的是独立表空间 - - 共享表空间 - -```sql -[root@localhost ~]# ll /application/mysql/data/ --rw-rw----. 1 mysql mysql 12582912 6月 8 09:43 ibdata1 -# 物理查看 -mysql> show variables like '%path%'; -innodb_data_file_path = ibdata1:12M:autoextend -``` - -- 5.6版本中默认存储 - - 系统数据 - - undo - - 临时表 - - 5.7版本中默认会将undo和临时表独立出来,5.6版本也可以独立,只不过需要在初始化的时候进行配置 -- 共享表空间扩展配置方法 - -```shell -#编辑配置文件 -[root@db01 ~]# vim /etc/my.cnf -[mysqld] -#注意,idata1文件已存在,可能超过50M导致mysqld重启不成功,建议重命名了再重启。 -innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend -``` - -- 独立表空间 - - 对于用户自主创建的表,会采用此种模式,每个表由一个独立的表空间进行管理 - -```shell -[root@localhost ~]# ll /application/mysql/data/world/ --rw-rw----. 1 mysql mysql 589824 6月 6 10:23 city.ibd -# 物理查看 -mysql> show variables like '%per_table%'; -innodb_file_per_table = ON -``` - -## 15.6 【实战】数据库服务损坏 +## 12.7 【实战】数据库服务损坏 - 在没有备份数据的情况下,突然断电导致表损坏,打不开数据库。 @@ -2002,20 +2156,20 @@ innodb_file_per_table = ON [root@db01 ~]# chown -R mysql.mysql /application/mysql/data/world ``` -1. 启动新数据库 +2. 启动新数据库 ```shell #pkill mysqld 先干掉mysql [root@db01 ~]# mysqld_safe --defaults-file=/data/3307/my.cnf & ``` -1. 登陆数据库查看 +3. 登陆数据库查看 ```sql mysql> show databases; ``` -1. 查询表中数据 +4. 查询表中数据 ```sql mysql> select * from city; @@ -2024,7 +2178,7 @@ ERROR 1146 (42S02): Table 'world.city' doesn't exist ``` -1. 找到**以前的表**结构在新库中创建表,此处演示用的show命令实际需要从原来的开发文档查看 +5. 找到**以前的表**结构在新库中创建表,此处演示用的show命令实际需要从原来的开发文档查看 ```sql mysql> show create table world.city; @@ -2058,33 +2212,35 @@ mysql> CREATE TABLE `city_new` ( ``` -1. 删除表空间文件 +6. 删除表空间文件 ```sql mysql> alter table city_new discard tablespace; ``` -1. 拷贝旧表空间文件 +7. 拷贝旧表空间文件 ```sql [root@db01 world]# cp /data/3307/data/world/city.ibd /data/3307/data/world/city_new.ibd ``` -1. 授权 +8. 授权 ```sql [root@db01 world]# cd /data/3307/data/world [root@db01 world]# chown -R mysql.mysql * ``` -1. 导入表空间 +9. 导入表空间 ```sql mysql> alter table city_new import tablespace; mysql> alter table city_new rename city; ``` -## 15.7 事务 +# 13. MySQL事务 + +## 13.1 事务 - 事务的定义 - 主要针对DML语句(update,delete,insert)一组数据操作执行步骤,这些步骤被视为一个工作单元 @@ -2108,7 +2264,7 @@ mysql> alter table city_new rename city; - Durable(持久性) - 事务成功完成后,所做的所有更改都会准确地记录在数据库中。所做的更改不会丢失。 -![img](01.Mysql/uxH9iBpInyy8pwrk.png!thumbnail) +![img](01.Mysql/uxH9iBpInyy8pwrk-1739583976575109.png!thumbnail) - 事务的控制语句 @@ -2187,7 +2343,7 @@ mysql> rollback; - select for update - 在autocommit=1的时候 -### 15.7.1 事务日志redo +### 13.1.1 事务日志redo - redo,顾名思义“重做日志”,是事务日志的一种。 - 在事务ACID过程中,实现的是“D”持久化的作用。 @@ -2197,20 +2353,22 @@ mysql> rollback; ```sql update t1 set num=2 where num=1; -# 执行步骤 -* 首先将t1表中num=1的行所在数据页加载到内存中buffer page -* MySQL实例在内存中将num=1的数据页改成num=2 -* num=1变成num=2的变化过程会记录到,redo内存区域,也就是redo buffer page中 -commit; -# 提交事务执行步骤 -* 当敲下commit命令的瞬间,MySQL会将redo buffer page写入磁盘区域redo log -* 当写入成功之后,commit返回ok ``` -### 15.7.2 事务日志undo +- 执行步骤 + * 首先将t1表中num=1的行所在数据页加载到内存中buffer page + * MySQL实例在内存中将num=1的数据页改成num=2 + * num=1变成num=2的变化过程会记录到,redo内存区域,也就是redo buffer page中 + commit; +- 提交事务执行步骤 + * 当敲下commit命令的瞬间,MySQL会将redo buffer page写入磁盘区域redo log + * 当写入成功之后,commit返回ok + + +### 13.1.2 事务日志undo - undo,顾名思义“回滚日志”,是事务日志的一种。 -- 在事务ACID过程中,实现的是“A”原子性的作用。当然CI的特性也和undo有关 +- 在事务ACID过程中,实现的是“A”原子性的作用。当然C的特性也和undo有关 - redo和undo的存储位置 ```shell @@ -2226,7 +2384,7 @@ commit; - 在MySQL5.6版本中undo是在ibdata文件中,在MySQL5.7版本会独立出来。 -### 15.7.3 事务中的锁 +### 13.1.3 事务中的锁 - “锁”顾名思义就是锁定的意思 - 在事务ACID特性过程中,“锁”和“隔离级别”一起来实现“I”隔离性的作用。 @@ -2248,7 +2406,7 @@ commit; - 确保每个事务的 SELECT 输出一致,一个用户update命令即使commit。另一个用户看到的未修改的,除非重新登录或者commit+ - InnoDB 的默认级别 - SERIALIZABLE - - 将一个事务的结果与其他事务完全隔离,一个用户update命令后未commit,另一个用户即使select都看不到。 + - 将一个事务的结果与其他事务完全隔离,一个用户update命令后commit,另一个用户即使select都看不到。 ```sql mysql> show variables like '%iso%'; @@ -2264,9 +2422,9 @@ transaction_isolation=read-commit #修改隔离级别为RC ``` -# 16. MySQL日志管理 +# 14. MySQL日志管理 -## 16.1 日志简介 +## 14.1 日志简介 | 日志文件 | 选项 | 文件名,表名 | 程序 | | :------- | :--------------------------------- | :------------------------ | :------------ | @@ -2276,7 +2434,7 @@ transaction_isolation=read-commit | 二进制 | --log-bin --expire-logs-days | host_name-bin.000001 | mysqlbinlog | | 审计 | --audit_log --audit_log_file ... | audit.log | | -## 16.2 错误日志 +## 14.2 错误日志 - 记录mysql数据库的一般状态信息及报错信息,是我们对于数据库常规报错处理的常用日志。 - 默认位置 @@ -2293,12 +2451,12 @@ mysql> show variables like 'log_error'; # 查看方式 ``` -## 16.3 一般查询日志 +## 14.3 一般查询日志 - 记录mysql所有执行成功的SQL语句信息,可以做审计用,但是我们很少开启。 - 默认位置 - $MYSQL_HOME/data/ -- 开启方式 +- y开启方式 - MySQL安装完之后默认不开启 ```shell @@ -2311,7 +2469,7 @@ mysql> show variables like '%gen%'; # 查看方式 ``` -## 16.4 二进制日志 +## 14.4 二进制日志 - 记录已提交的DML事务语句,并拆分为多个事件(event)来进行记录 @@ -2346,38 +2504,53 @@ mysql> show variables like '%gen%'; - 数据的备份恢复 - 数据的复制 -### 16.4.1 二进制日志的管理操作实战 +### 14.4.1 二进制日志的管理操作实战 -- 开启方式 +#### 14.4.1.1 开启bin-log日志 + +注意:在mysql5.6及以后的版本中开启binlog必须要加上server-id。 ```shell -[root@db01 data]# vim /etc/my.cnf -[mysqld] -log-bin=mysql-bin -binlog_format=row -``` - -注意:在mysql5.7中开启binlog必须要加上server-id。 - -```shell -[root@db01 data]# vim /etc/my.cnf +[root@localhost ~]# vim /etc/my.cnf [mysqld] log-bin=mysql-bin binlog_format=row server_id=1 ``` -- 二进制日志的操作 +检查主目录下的binlog日志文件 ```shell -[root@db01 data]# ll /application/mysql/data/ --rw-rw---- 1 mysql mysql 285 Mar 6 2021 mysql-bin.000001 -#物理查看 +# 物理查看 +[root@localhost ~]# ll /application/mysql/data/mysql-bin* +-rw-rw---- 1 mysql mysql 120 Feb 15 11:23 /application/mysql/data/mysql-bin.000001 +-rw-rw---- 1 mysql mysql 19 Feb 15 11:23 /application/mysql/data/mysql-bin.index + +# MySQL命令行查看 mysql> show binary logs; ++------------------+-----------+ +| Log_name | File_size | ++------------------+-----------+ +| mysql-bin.000001 | 120 | ++------------------+-----------+ +1 row in set (0.00 sec) + mysql> show master status; -#命令行查看 -mysql> show binlog events in 'mysql-bin.000007'; -#查看binlog事件 ++------------------+----------+--------------+------------------+-------------------+ +| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | ++------------------+----------+--------------+------------------+-------------------+ +| mysql-bin.000001 | 120 | | | | ++------------------+----------+--------------+------------------+-------------------+ +1 row in set (0.00 sec) + +# 查看binlog事件 +mysql> show binlog events in 'mysql-bin.000001'; ++------------------+-----+-------------+-----------+-------------+---------------------------------------+ +| Log_name | Pos | Event_type | Server_id | End_log_pos | Info | ++------------------+-----+-------------+-----------+-------------+---------------------------------------+ +| mysql-bin.000001 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.40-log, Binlog ver: 4 | ++------------------+-----+-------------+-----------+-------------+---------------------------------------+ +1 row in set (0.00 sec) ``` - 事件介绍 @@ -2388,114 +2561,194 @@ mysql> show binlog events in 'mysql-bin.000007'; - 所谓的位置就是event对整个二进制的文件的相对位置。 - 对于一个二进制日志中,前120个position是文件格式信息预留空间。 - MySQL第一个记录的事件,都是从120开始的。 -- row模式下二进制日志分析及数据恢复 + +#### 14.4.1.2 row模式下binlog分析及数据恢复 + +一、查看初始binlog信息 ```sql mysql> show master status; -# 查看binlog信息 ++------------------+----------+--------------+------------------+-------------------+ +| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | ++------------------+----------+--------------+------------------+-------------------+ +| mysql-bin.000001 | 120 | | | | ++------------------+----------+--------------+------------------+-------------------+ +1 row in set (0.00 sec) +``` + +二、模拟数据变化 + +```sql +# 创建数据库和表 mysql> create database binlog; -# 创建一个binlog库 -mysql> use binlog -# 使用binlog库 +mysql> use binlog; mysql> create table binlog_table(id int); -# 创建binglog_table表 + +# 查看现在的binlog信息 mysql> show master status; -# 查看binlog信息 ++------------------+----------+--------------+------------------+-------------------+ +| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | ++------------------+----------+--------------+------------------+-------------------+ +| mysql-bin.000001 | 331 | | | | ++------------------+----------+--------------+------------------+-------------------+ +1 row in set (0.00 sec) + +# 插入数据(如果是非自动提交,记得手动commit) mysql> insert into binlog_table values(1); -# 插入数据1 mysql> show master status; -# 查看binlog信息 -mysql> commit; -# 提交 -mysql> show master status; -# 查看binlog信息 ++------------------+----------+--------------+------------------+-------------------+ +| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | ++------------------+----------+--------------+------------------+-------------------+ +| mysql-bin.000001 | 533 | | | | ++------------------+----------+--------------+------------------+-------------------+ +1 row in set (0.00 sec) + +# 再次插入数据 mysql> insert into binlog_table values(2); -# 插入数据2 mysql> insert into binlog_table values(3); -#插入数据3 mysql> show master status; -# 查看binlog信息 -mysql> commit; -# 提交 ++------------------+----------+--------------+------------------+-------------------+ +| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | ++------------------+----------+--------------+------------------+-------------------+ +| mysql-bin.000001 | 937 | | | | ++------------------+----------+--------------+------------------+-------------------+ +1 row in set (0.00 sec) + +# 删除数据操作 mysql> delete from binlog_table where id=1; -# 删除数据1 mysql> show master status; -# 查看binlog信息 -mysql> commit; -# 提交 ++------------------+----------+--------------+------------------+-------------------+ +| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | ++------------------+----------+--------------+------------------+-------------------+ +| mysql-bin.000001 | 1139 | | | | ++------------------+----------+--------------+------------------+-------------------+ +1 row in set (0.00 sec) + +# 更改数据操作 mysql> update binlog_table set id=22 where id=2; -# 更改数据2为22 mysql> show master status; -# 查看binlog -mysql> commit; -# 提交 -mysql> show master status; -# 查看binlog信息 ++------------------+----------+--------------+------------------+-------------------+ +| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | ++------------------+----------+--------------+------------------+-------------------+ +| mysql-bin.000001 | 1347 | | | | ++------------------+----------+--------------+------------------+-------------------+ +1 row in set (0.00 sec) + +# 查看数据操作 mysql> select * from binlog_table; -# 查看数据 +mysql> show master status; ++------------------+----------+--------------+------------------+-------------------+ +| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | ++------------------+----------+--------------+------------------+-------------------+ +| mysql-bin.000001 | 1347 | | | | ++------------------+----------+--------------+------------------+-------------------+ +1 row in set (0.00 sec) + +# 删表删库跑路 mysql> drop table binlog_table; -# 删表 mysql> drop database binlog; -# 删库 +mysql> show master status; ++------------------+----------+--------------+------------------+-------------------+ +| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | ++------------------+----------+--------------+------------------+-------------------+ +| mysql-bin.000001 | 1565 | | | | ++------------------+----------+--------------+------------------+-------------------+ +1 row in set (0.00 sec) ``` -- 恢复数据之前 - -```shell -mysql> show binlog events in 'mysql-bin.000013'; -# 查看binlog事件 -# 使用mysqlbinlog来查看 -[root@db01 data]# mysqlbinlog /application/mysql/data/mysql-bin.000013 -[root@db01 data]# mysqlbinlog /application/mysql/data/mysql-bin.000013|grep -v SET -[root@db01 data]# mysqlbinlog --base64-output=decode-rows -vvv mysql-bin.000013 -# 查看二进制日志后,发现删除开始位置是858 -# binlog某些内容是以二进制放进去的,加入base64-output用于解码 -[root@db01 data]# mysqlbinlog --start-position=120 --stop-position=858 /application/mysql/data/mysql-bin.000013 > /tmp/binlog.sql -mysql> set sql_log_bin=0; -#临时关闭binlog,必须关闭,否则source倒入的内容也会被记录进binlog,binlog就脏了。 -mysql> source /tmp/binlog.sql -#执行sql文件 -mysql> show databases; -#查看删除的库 -mysql> use binlog -#进binlog库 -mysql> show tables; -#查看删除的表 -mysql> select * from binlog_table; -#查看表中内容 -``` - -- 只查看某个数据库的binlog文件 +三、数据恢复 ```sql +# 查看当前binlog事件 +mysql> show binlog events in 'mysql-bin.000001'; + +# 还可以使用mysqlbinlog工具进行查看 +[root@localhost ~]# mysqlbinlog --base64-output=decode-rows /application/mysql/data/mysql-bin.000001 +[root@localhost ~]# mysqlbinlog --base64-output=decode-rows /application/mysql/data/mysql-bin.000001|grep -v SET + +# 发现开始删库删表的开始位置是1347,开始截取删库之前的binlog日志 +[root@localhost ~]# mysqlbinlog --start-position=120 --stop-position=1347 /application/mysql/data/mysql-bin.000001 > /tmp/binlog.sql + +# 恢复数据,恢复之前,临时关闭binlog,否则会继续记录恢复的过程,导致binlog变成脏日志 +mysql> set sql_log_bin=0; +mysql> source /tmp/binlog.sql + +# 检查数据恢复情况 +mysql> show databases; ++--------------------+ +| Database | ++--------------------+ +| information_schema | +| binlog | +| mysql | +| performance_schema | +| test | ++--------------------+ +5 rows in set (0.00 sec) + +mysql> use binlog; +mysql> show tables; ++------------------+ +| Tables_in_binlog | ++------------------+ +| binlog_table | ++------------------+ +1 row in set (0.00 sec) +mysql> select * from binlog_table; ++------+ +| id | ++------+ +| 22 | +| 3 | ++------+ +2 rows in set (0.00 sec) +``` + +#### 14.4.1.3 查看某个数据库的binlog + +一、刷新binlog日志 + +```sql +# 刷新一个新的binlog,从新日志开始记录,但是原来的日志也不会删除 mysql> flush logs; -#刷新一个新的binlog,原来的bin000X.log作废 +mysql> show master status; ++------------------+----------+--------------+------------------+-------------------+ +| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | ++------------------+----------+--------------+------------------+-------------------+ +| mysql-bin.000002 | 120 | | | | ++------------------+----------+--------------+------------------+-------------------+ +1 row in set (0.00 sec) +``` + +二、创建不同的库测试 + +```sql +# 创建db1、db2两个库 mysql> create database db1; mysql> create database db2; -#创建db1、db2两个库 +# 库db1操作 mysql> use db1 -#库db1操作 mysql> create table t1(id int); -#创建t1表 mysql> insert into t1 values(1),(2),(3),(4),(5); -#插入5条数据 -mysql> commit; -#提交 + +# 库db2操作 mysql> use db2 -#库db2操作 mysql> create table t2(id int); -#创建t2表 mysql> insert into t2 values(1),(2),(3); -#插入3条数据 -mysql> commit; -#提交 -mysql> show binlog events in 'mysql-bin.000014'; -#查看binlog事件 -[root@db01 data]# mysqlbinlog -d db1 --base64-output=decode-rows -vvv /application/mysql/data/mysql-bin.000014 -#查看db1的操作 ``` +三、检查binlog日志 + +```sql +mysql> show binlog events in 'mysql-bin.000002'; + +# 只查看db1数据库的binlog +[root@localhost ~]# mysqlbinlog -d db1 --base64-output=decode-rows -vvv /application/mysql/data/mysql-bin.000002 +``` + +### 14.4.2 其他操作 + - 刷新binlog日志 - flush logs; - 重启数据库时会刷新 @@ -2507,116 +2760,204 @@ mysql> show binlog events in 'mysql-bin.000014'; - 删除方式 - 根据存在时间删除日志 -```shell -#临时生效 +```sql +# 临时生效 SET GLOBAL expire_logs_days = 7; -#永久生效 -[root@db01 data]# vim /etc/my.cnf +# 永久生效 +[root@localhost data]# vim /etc/my.cnf [mysqld] expire_logs_days = 7 -* 使用purge命令删除 -PURGE BINARY LOGS BEFORE now() - INTERVAL 3 day; -* 根据文件名删除 -PURGE BINARY LOGS TO 'mysql-bin.000010'; -* 用reset master + +# 使用purge命令删除 +mysql> PURGE BINARY LOGS BEFORE now() - INTERVAL 3 day; +# 根据文件名删除 +mysql> PURGE BINARY LOGS TO 'mysql-bin.000002'; + +# 用reset master 重置binlog mysql> reset master; ``` -## 16.5 慢查询日志 +## 14.5 慢查询日志 - 是将mysql服务器中影响数据库性能的相关SQL语句记录到日志文件 - 通过对这些特殊的SQL语句分析,改进以达到提高数据库性能的目的 -- 默认位置: - - MYSQL_HOME/data/*M**Y**S**Q**L**H**O**M**E*/*d**a**t**a*/hostname-slow.log -- 开启方式(默认没有开启) + +### 14.5.1 开启方式(默认没有开启) ```shell -[root@db01 ~]# vim /etc/my.cnf +[root@localhost ~]# vim /etc/my.cnf [mysqld] -#指定是否开启慢查询日志 +# 指定是否开启慢查询日志 slow_query_log = 1 -#指定慢日志文件存放位置(默认在data) +# 指定慢日志文件存放位置(默认在data) slow_query_log_file=/application/mysql/data/slow.log -#设定慢查询的阀值(默认10s) +# 设定慢查询的阀值(默认10s) long_query_time=0.05 -#不使用索引的慢查询日志是否记录到索引 +# 不使用索引的慢查询日志是否记录到索引 log_queries_not_using_indexes -#查询检查返回少于该参数指定行的SQL不被记录到慢查询日志 -min_examined_row_limit=100(鸡肋) +# 查询检查返回少于该参数指定行的SQL不被记录到慢查询日志 +min_examined_row_limit=100 ``` -- 模拟慢查询语句 +### 14.5.2 慢查询实验 + +一、模拟慢查询语句 ```sql +# 导入SELECT练习中的world库 +[root@localhost ~]# wget -O world.sql 'https://download.s21i.faiusr.com/23126342/0/0/ABUIABAAGAAgzcXwhQYozuPv2AE?f=world.sql&v=1622942413' +[root@localhost ~]# mysql -uroot -p123456 < world.sql + +# 登录到数据库中 mysql> use world -#进入world库 -mysql> show tables; -#查看表 + +# 创建一个新的表 mysql> create table t1 select * from city; -#将city表中所有内容加到t1表中 -mysql> desc t1; -#查看t1的表结构 + +# 将t1表所有内容插入到t1表中(多插入几次) mysql> insert into t1 select * from t1; mysql> insert into t1 select * from t1; mysql> insert into t1 select * from t1; mysql> insert into t1 select * from t1; -#将t1表所有内容插入到t1表中(多插入几次) -mysql> commit; -#提交 -mysql> delete from t1 where id>2000; -#删除t1表中id>2000的数据 -[root@db01 ~]# cat /application/mysql/data/mysql-db01 -#查看慢日志 + +# 搜索t1表中id>2000的数据 +mysql> select * from t1 where id>2000; ``` -- 使用mysqldumpslow命令来分析慢查询日志 +二、查看慢日志 -```shell -$PATH/mysqldumpslow -s c -t 10 /database/mysql/slow-log -#输出记录次数最多的10条SQL语句 +```bash +[root@localhost ~]# cat /application/mysql/data/slow.log +/application/mysql/bin/mysqld, Version: 5.6.40-log (MySQL Community Server (GPL)). started with: +Tcp port: 0 Unix socket: (null) +Time Id Command Argument +# Time: 250215 14:17:49 +# User@Host: root[root] @ localhost [] Id: 2 +# Query_time: 0.043734 Lock_time: 0.009772 Rows_sent: 0 Rows_examined: 4079 +use world; +SET timestamp=1739600269; +create table t1 select * from city; +# Time: 250215 14:18:02 +# User@Host: root[root] @ localhost [] Id: 2 +# Query_time: 0.038587 Lock_time: 0.000171 Rows_sent: 0 Rows_examined: 8158 +SET timestamp=1739600282; +insert into t1 select * from t1; +# Time: 250215 14:18:03 +# User@Host: root[root] @ localhost [] Id: 2 +# Query_time: 0.028329 Lock_time: 0.000063 Rows_sent: 0 Rows_examined: 16316 +SET timestamp=1739600283; +insert into t1 select * from t1; +# Time: 250215 14:18:04 +# User@Host: root[root] @ localhost [] Id: 2 +# Query_time: 0.077498 Lock_time: 0.000064 Rows_sent: 0 Rows_examined: 32632 +SET timestamp=1739600284; +insert into t1 select * from t1; +# Time: 250215 14:18:05 +# User@Host: root[root] @ localhost [] Id: 2 +# Query_time: 0.147896 Lock_time: 0.000062 Rows_sent: 0 Rows_examined: 65264 +SET timestamp=1739600285; +insert into t1 select * from t1; +# Time: 250215 14:18:06 +# User@Host: root[root] @ localhost [] Id: 2 +# Query_time: 0.342130 Lock_time: 0.000066 Rows_sent: 0 Rows_examined: 130528 +SET timestamp=1739600286; +insert into t1 select * from t1; +# Time: 250215 14:19:19 +# User@Host: root[root] @ localhost [] Id: 2 +# Query_time: 0.059468 Lock_time: 0.000121 Rows_sent: 66528 Rows_examined: 130528 +SET timestamp=1739600359; +select * from t1 where id>2000; ``` -- 参数说明: - - -s: - - 是表示按照何种方式排序,c、t、l、r分别是按照记录次数、时间、查询时间、返回的记录数来排序,ac、at、al、ar,表示相应的倒叙; - - -t: - - 是top n的意思,即为返回前面多少条的数据; - - -g: - - 后边可以写一个正则匹配模式,大小写不敏感的; +三、使用mysqldumpslow进行慢日志分析 + +```bash +[root@localhost ~]# mysqldumpslow -s c -t 10 /application/mysql/data/slow.log +``` + +参数说明: + +- -s:是表示按照何种方式排序,c、t、l、r分别是按照记录次数、时间、查询时间、返回的记录数来排序,ac、at、al、ar,表示相应的倒叙; +- -t:是top n的意思,即为返回前面多少条的数据; +- -g:后边可以写一个正则匹配模式,大小写不敏感的; + +例如: ```shell -$PATH/mysqldumpslow -s r -t 10 /database/mysql/slow-log -#得到返回记录集最多的10个查询 -$PATH/mysqldumpslow -s t -t 10 -g "left join" /database/mysql/slow-log #得到按照时间排序的前10条里面含有左连接的查询语句 +$PATH/mysqldumpslow -s t -t 10 -g "left join" /database/mysql/slow-log ``` -- 第三方推荐(扩展): +### 14.5.3 第三方慢日志分析工具-Percona + +Percona Toolkit 是由 Percona 公司开发的一套高级命令行工具,用于执行各种 MySQL、MongoDB 和系统任务。这些工具专为复杂任务设计,能够帮助数据库管理员和运维人员解决手动操作难以完成的任务。Percona Toolkit 是 Percona 支持团队日常使用的工具,具有专业开发、正式测试和全面文档化的特点。 + +`pt-query-digest` 是 Percona Toolkit 中的一个重要工具,专门用于分析 MySQL 的慢查询日志。它的核心功能包括: + +- **分析和汇总慢查询日志**:通过解析日志文件,找出执行时间长、负载高的查询。 +- **生成详细的性能报告**:提供查询执行时间、锁定时间、查询效率排名等信息,帮助快速定位性能瓶颈。 +- **支持多种输入类型**:可以分析 MySQL 慢查询日志、通用日志、二进制日志,甚至通过 tcpdump 捕获的网络数据。 +- **灵活的过滤和排序**:支持通过正则表达式过滤特定查询,按执行时间、调用次数等排序。 + +#### 14.5.3.1 工具安装 ```shell -yum install -y percona-toolkit-3.0.11-1.el6.x86_64.rpm -* 使用percona公司提供的pt-query-digest工具分析慢查询日志 -[root@mysql-db01 ~]# pt-query-digest /application/mysql/data/mysql-db01-slow.log +[root@localhost ~]# wget https://downloads.percona.com/downloads/percona-toolkit/3.5.0/binary/redhat/9/x86_64/percona-toolkit-3.5.0-5.el9.x86_64.rpm +[root@localhost ~]# yum install -y percona-toolkit-3.5.0-5.el9.x86_64.rpm + + +[root@localhost ~]# pt-query-digest /application/mysql/data/slow.log ``` -有能力的可以做成可视化界面: -Anemometer基于pt-query-digest将MySQL慢查询可视化 +#### 14.5.3.2 慢日志分析示例 -慢日志分析工具下载 https://[www.percona.com/downloads/percona-toolkit/LATEST/](http://www.percona.com/downloads/percona-toolkit/LATEST/) +```bash +[root@localhost ~]# pt-query-digest /application/mysql/data/slow.log -可视化代码下载 https://github.com/box/Anemometer +pt-query-digest 的分析结果: -![img](01.Mysql/yhWTJJz8GZkilbZN.png!thumbnail) +总体统计数据: +Queries examined: 总共分析的查询语句数量 +Query time: 总查询时间 +Min/Max/Avg query time: 最短、最长和平均查询时间 +Variance: 查询时间的方差 +Aggregated profile: 按查询类型统计的信息,如 SELECT、INSERT、UPDATE 等 +Top Queries: +这部分列出了执行时间最长的前 10 个查询语句。 +Rank: 查询在整体中的排名 +Query ID: 查询的唯一标识 +Response Time: 查询的总响应时间 +Calls: 查询被执行的次数 +R/Call: 每次调用的平均响应时间 +V/M: 查询时间的方差与平均值的比率,反映了查询时间的离散程度 +Item: 查询语句的文本 +查询语句的详细信息: +Query ID: 查询的唯一标识 +Database: 查询所针对的数据库 +Users: 执行查询的用户 +Hosts: 执行查询的主机 +Query: 查询语句的文本 +Exec time: 查询的总执行时间 +Lock time: 查询获取的锁定时间 +Rows sent: 查询返回的行数 +Rows examined: 查询扫描的行数 +Rows affected: 查询影响的行数 +Bytes sent: 查询返回的字节数 +Tmp tables: 查询使用的临时表数量 +Tmp disk tables: 查询使用的临时磁盘表数量 +Scan/Join tables: 查询扫描的表数量 +``` -# 17. 备份与恢复 +# 15. 备份与恢复 -- 备份的原因 - - 第一个是保护公司的数据. - - 第二个是让网站能7*24小时提供服务(用户体验)。 - - 备份就是为了恢复。 - - 尽量减少数据的丢失(公司的损失) +**备份的原因:** -## 17.1 备份的类型 +- 第一个是保护公司的数据. +- 第二个是让网站能7*24小时提供服务(用户体验)。 +- 备份就是为了恢复。 +- 尽量减少数据的丢失(公司的损失) + +## 15.1 备份的类型 - 冷备份: - 这些备份在用户不能访问数据时进行,因此无法读取或修改数据。这些脱机备份会阻止执行任何使用数据的活动。这些类型的备份不会干扰正常运行的系统的性能。但是,对于某些应用程序,会无法接受必须在一段较长的时间里锁定或完全阻止用户访问数据。 @@ -2625,15 +2966,14 @@ Anemometer基于pt-query-digest将MySQL慢查询可视化 - 热备份: - 这些动态备份在读取或修改数据的过程中进行,很少中断或者不中断传输或处理数据的功能。使用热备份时,系统仍可供读取和修改数据的操作访问。 -## 17.2 备份的方式 +## 15.2 备份的方式 -- 逻辑备份 +**逻辑备份:**MySQL软件自带的功能 - SQL软件自带的功能 - - - 基于SQL语句的备份 - - binlog - - into outfile +- 基于SQL语句的备份 + - binlog + - into outfile + - mysqldump ```sql [root@localhost ~]# vim /etc/my.cnf @@ -2644,59 +2984,122 @@ mysql> select * from world.city into outfile '/tmp/world_city.data'; * replication ``` -- 物理备份 +**物理备份:**通过二进制方式直接拖走所有数据、配置文件 - 通过二进制方式直接拖走所有数据、配置文件 +- 基于数据文件的备份 + - Xtrabackup(percona公司) - - 基于数据文件的备份 - - Xtrabackup(percona公司) +**备份策略:** -## 17.3 备份工具 +- 全量备份 full +- 增量备份 increamental -- 备份策略 - - 全量备份 full - - 增量备份 increamental -- 备份工具 - - mysqldump(逻辑) - - mysql原生自带很好用的逻辑备份工具 - - mysqlbinlog(逻辑) - - 实现binlog备份的原生态命令 - - xtrabackup(物理) - - precona公司开发的性能很高的物理备份工具 -- 备份工具使用 - - mysqldump - - 连接服务端参数(基本参数):-u -p -h -P -S - - -A, --all-databases:全库备份 +**备份工具:** -```shell -[root@db01 ~]# mysqldump -uroot -p123456 -A > /backup/full.sql - * 不加参数:单库、单表多表备份 -[root@db01 ~]# mysqldump -uroot -p123456 db1 > /backup/db1.sql -[root@mysql-db01 backup]# mysqldump -uroot -p123456 world city > /backup/city.sql - * -B:指定库备份 -[root@db01 ~]# mysqldump -uroot -p123 -B db1 > /backup/db1.sql -[root@db01 ~]# mysqldump -uroot -p123 -B db1 db2 > /backup/db1_db2.sql - * -F:flush logs在备份时自动刷新binlog(不怎么常用) -[root@db01 backup]# mysqldump -uroot -p123 -A -R –triggers -F > /backup/full_2.sql - * -d:仅表结构 - * -t:仅数据 +- mysqldump(逻辑) + - mysql原生自带很好用的逻辑备份工具 +- mysqlbinlog(逻辑) + - 实现binlog备份的原生态命令 +- xtrabackup(物理) + - precona公司开发的性能很高的物理备份工具 + +## 15.3 mysqldump + +`mysqldump` 是 MySQL 数据库备份工具,用于导出数据库结构和数据到 SQL 文件。 + +### 15.3.1 参数说明 + +**数据库连接参数** + +- `-u` 或 `--user`:指定连接数据库的用户名。 +- `-p` 或 `--password`:指定连接数据库的密码。如果省略密码,系统会提示输入。 +- `-h` 或 `--host`:指定数据库服务器的主机名或 IP 地址。默认为本地主机(`localhost`)。 +- `-P` 或 `--port`:指定数据库服务器的端口号。默认为 `3306`。 +- `-S` 或 `--socket`:指定连接到本地 MySQL 服务器的 Unix 套接字文件路径。 + +------ + +**数据库和表选择参数** + +- 数据库名:指定要备份的数据库名称。 +- `-B` 或 `--databases`:备份多个数据库时使用。例如:`mysqldump -B db1 db2`。 +- `--all-databases` 或 `-A`:备份所有数据库。 +- `--tables`:指定要备份的表名。例如:`mysqldump db_name table1 table2`。 + +------ + +**备份内容和格式参数** + +- `--no-data` 或 `-d`:只备份数据库结构,不备份数据。 +- `--no-create-info` 或 `-t`:只备份数据,不备份表结构。 +- `--complete-insert`:使用完整的 `INSERT` 语句(包含列名)。 +- `--extended-insert`:使用多行 `INSERT` 语句,提高导入效率。 +- `--skip-extended-insert`:禁用多行 `INSERT`,每行数据生成单独的 `INSERT` 语句。 +- `--hex-blob`:将二进制数据以十六进制形式导出。 +- `--set-gtid-purged`:控制是否记录 GTID 信息。选项为 `ON`、`OFF` 或 `AUTO`。 + +------ + +**性能和优化参数** + +- `--quick`:对大表进行快速导出,直接将数据写入输出文件,减少内存占用。 +- `--single-transaction`:在导出时启动一个事务,确保数据一致性,适用于 InnoDB 存储引擎。 +- `--flush-logs`:在导出开始时刷新 MySQL 日志。 +- `--master-data`:包含二进制日志信息,用于主从复制的备份。选项为 `1` 或 `2`,`2` 会将日志信息写入注释中。 +- `--lock-tables`:在导出时锁定所有表,确保数据一致性。 +- `--skip-lock-tables`:跳过锁定表的操作,适用于大表或高并发环境。 + +------ + +**其他参数** + +- `--routines` 或 `-R`:导出存储过程和函数。 +- `--triggers`:导出触发器。 +- `--events`:导出事件调度器中的事件。 +- `--ignore-table`:忽略指定的表。例如:`--ignore-table=db_name.table_name`。 +- `--result-file` 或 `-r`:将输出结果写入指定文件,而不是标准输出。 +- `--help`:显示帮助信息。 + +### 15.3.2 示例命令 + +1. **备份单个数据库**: + +```bash +[root@localhost ~]# mysqldump -uroot -p123456 db_name > backup.sql ``` -- 备份额外扩展项 - - -R, --routines:备份存储过程和函数数据 - - --triggers:备份触发器数据 +2. **备份多个数据库**: -```shell -[root@db01 backup]# mysqldump -uroot -p123 -A -R --triggers > /backup/full_2.sql +```bash +[root@localhost ~]# mysqldump -uroot -p123456 --databases db1 db2 > backup.sql ``` -- mysqldump特殊参数 - - -x:锁表备份(myisam温备份) - - --single-transaction:快照备份 +3. **备份所有数据库**: + +```bash +[root@localhost ~]# mysqldump -uroot -p123456 --all-databases > all_backup.sql +``` + +4. **只备份表结构**: + +```bash +[root@localhost ~]# mysqldump -uroot -p123456 --no-data db_name > structure.sql +``` + +5. **备份数据但不锁定表**: + +```bash +[root@localhost ~]# mysqldump -uroot -p123456 --single-transaction db_name > backup.sql +``` + +### 15.3.3 **mysqldump特殊使用** + +- -x:锁表备份(myisam温备份) +- --single-transaction:快照备份 ```shell -[root@db01 backup]# mysqldump -uroot -p123 -A -R --triggers --master-data=2 –-single-transaction>/backup/full.sql -# 加了文件末尾会多一行:CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=120; +[root@localhost ~]# mysqldump -uroot -p123 -A -R --triggers --master-data=2 –-single-transaction > /backup/full.sql +# 加了文件末尾会多一行:CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=120; # 不加master-data就不会记录binlog的位置,导致后续不利于增量备份 ``` @@ -2704,9 +3107,9 @@ mysql> select * from world.city into outfile '/tmp/world_city.data'; - gzip:压缩备份 ```shell -[root@db01 ~]# mysqldump -uroot -p123 -A -R --triggers --master-data=2 –single-transaction|gzip>/backup/full.sql.gz -[root@db01 ~]# gzip -d /backup/full.sql.gz -[root@db01 ~]# zcat /backup/full.sql.gz > linshi.sql +[root@localhost ~]# mysqldump -uroot -p123456 -A -R --triggers --master-data=2 –single-transaction|gzip > /backup/full.sql.gz +[root@localhost ~]# gzip -d /backup/full.sql.gz +[root@localhost ~]# zcat /backup/full.sql.gz > linshi.sql ``` - 常用的热备份备份语句 @@ -2722,16 +3125,17 @@ mysql> set sql_log_bin=0; #先不记录二进制日志 mysql> source /backup/full.sql #库内恢复操作 -[root@db01 ~]# mysql -uroot -p123 < /backup/full.sql +[root@localhost ~]# mysql -uroot -p123456 < /backup/full.sql #库外恢复操作 ``` -- 注意 - - mysqldump在备份和恢复时都需要MySQL实例启动为前提 - - 一般数据量级100G以内,大约15-30分钟可以恢复(PB、EB就需要考虑别的方式) - - mysqldump是以覆盖的形式恢复数据的 +**注意事项:** -## 17.4 【实战】企业故障恢复 +- mysqldump在备份和恢复时都需要MySQL实例启动为前提 +- 一般数据量级100G以内,大约15-30分钟可以恢复(PB、EB就需要考虑别的方式) +- mysqldump是以覆盖的形式恢复数据的 + +### 15.3.4 实战案例-企业故障恢复 - 背景: - 正在运行的网站系统,MySQL数据库,数据量25G,日业务增量10-15M。 @@ -2748,120 +3152,171 @@ mysql> source /backup/full.sql - 直接使用临时库顶替原生产库,前端应用割接到新库 - 将误删除的表单独导出,然后导入到原生产环境 - 开启业务 - - 故障模拟 + +#### 15.3.4.1 故障模拟 + +一、故障模拟 ```sql -mysql> flush logs; -#刷新binlog使内容更清晰 +# 刷新binlog使内容更清晰 +mysql> reset master; mysql> show master status; -#查看当前使用的binlog ++------------------+----------+--------------+------------------+-------------------+ +| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | ++------------------+----------+--------------+------------------+-------------------+ +| mysql-bin.000001 | 120 | | | | ++------------------+----------+--------------+------------------+-------------------+ + +# 创建backup库 mysql> create database backup; -#创建backup库 mysql> use backup -#进入backup库 + +# 创建full表 mysql> create table full select * from world.city; -#创建full表 -mysql> create table full_1 select * from world.city; -#创建full_1表 +Query OK, 4079 rows affected (0.04 sec) +Records: 4079 Duplicates: 0 Warnings: 0 + mysql> show tables; -#查看表 ++------------------+ +| Tables_in_backup | ++------------------+ +| full | ++------------------+ +1 row in set (0.00 sec) ``` -- 全备 +二、对数据库进行一次全备 -```sql -[root@db01 ~]# mysqldump -uroot -p123 -A -R --triggers --master-data=2 --single-transaction|gzip > /backup/full_$(date +%F).sql.gz +```bash +[root@localhost ~]# mkdir /backup +[root@localhost ~]# mysqldump -uroot -p123456 -A -R --triggers --master-data=1 --single-transaction|gzip > /backup/full_$(date +%F).sql.gz +[root@localhost ~]# ll /backup/ +total 2332 +-rw-r--r-- 1 root root 2385815 Feb 15 15:31 full_2025-02-15.sql.gz ``` -- 模拟数据变化 +三、模拟从前一天晚上23点到10点前的数据变化 ```sql -mysql> use backup -#进入backup库 -mysql> create table new select * from mysql.user; -#创建new表 -mysql> create table new_1 select * from world.country; -#创建new_1表 -mysql> show tables; -#查看表 -mysql> select * from full; -#查看full表中所有数据 +# 把full表中所有的countrycode都改成CHN mysql> update full set countrycode='CHN' where 1=1; -#把full表中所有的countrycode都改成CHN -mysql> commit; -#提交 +# 删除id大于200的数据 mysql> delete from full where id>200; -#删除id大于200的数据 -mysql> commit; -#提交 + +# 产生一个新的表 +mysql> create table new select * from mysql.user; ``` -- 模拟故障 +四、模拟第二天上午10点误删new表 ```sql mysql> drop table new; -#删除new表 mysql> show tables; -#查看表 ++------------------+ +| Tables_in_backup | ++------------------+ +| full | ++------------------+ +1 row in set (0.00 sec) ``` -- 恢复过程 - - 准备临时数据库 +#### 15.3.4.2 **数据恢复** + +一、启动一个新的数据库实例 + +```bash +[root@localhost ~]# mysqld_safe --defaults-file=/data/3307/my.cnf & -```shell -#开启一个新的实例 -[root@db02 ~]# mysqld_safe --defaults-file=/data/3307/my.cnf & -#拷贝数据到新库上 -[root@db02 ~]# scp /backup/full_2018-08-16.sql.gz root@10.0.0.52:/tmp #解压全备数据文件,如果用同一个机器的不同实例则不需要这步 -[root@db02 ~]# cd /tmp/ -#进入tmp目录 -[root@db02 tmp]# gzip -d full_2018-08-16.sql.gz -#解压全备数据文件 -截取二进制 -[root@db02 tmp]# head -50 full_2018-08-16.sql |grep -i 'change master to' -#查看全备的位置点(起始位置点),忽略大小写,假设找到起始的位置为268002 -mysql> show binlog events in 'mysql-bin.000017'\G -#生产环境db01找到drop语句执行的位置点(结束位置点) -[root@db01 tmp]#mysqlbinlog -uroot -p123 --start-position=268002 --stop-position=671148 /application/mysql/data/mysql-bin.000017 > /tmp/inc.sql -#截取二进制日志,把备份点和drop直接的信息倒入到inc.sql -[root@db01 tmp]# scp /tmp/inc.sql root@10.0.0.52:/tmp -#发送增量数据到新库 +[root@localhost ~]# scp /backup/full_2024-08-16.sql.gz root@192.168.88.20:/tmp +``` + +二、准备恢复 + +```bash +mysql> show binlog events in 'mysql-bin.000001'\G +# 解压全备数据文件 +[root@localhost ~]# gzip -d /backup/full_2025-02-15.sql.gz +[root@localhost ~]# ll /backup/ +total 6600 +-rw-r--r-- 1 root root 6754549 Feb 15 15:31 full_2025-02-15.sql + +# 找到全备数据的binlog位置点 +[root@localhost ~]# head -50 /backup/full_2025-02-15.sql | grep -i 'change master to' +CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=134046; + +# 在生产环境中找到drop删除前的位置点 +mysql> show binlog events in 'mysql-bin.000001'\G +*************************** 81. row *************************** + Log_name: mysql-bin.000001 + Pos: 510614 + Event_type: Query + Server_id: 1 +End_log_pos: 510734 + Info: use `backup`; DROP TABLE `new` /* generated by server */ + +# 截取二进制日志,把备份点和drop之间的信息倒入到inc.sql +[root@localhost ~]# mysqlbinlog -uroot -p123456 --start-position=134046 --stop-position=510614 /application/mysql/data/mysql-bin.000001 > /tmp/inc.sql +# 如果是新库是远程主机,就将截取好的binlog日志发送到远程主机上,本机不需要发送 +``` + +三、在新库内恢复数据 + +```bash +[root@localhost ~]# mysql -uroot -p123456 -S /data/3307/mysql.sock -#在新库内恢复数据 -mysql> set sql_log_bin=0; #不记录二进制日志 -mysql> source /tmp/full_2018-08-16.sql +mysql> set sql_log_bin=0; #恢复全备数据 +mysql> source /backup/full_2025-02-15.sql mysql> use backup -#进入backup库 mysql> show tables; -# 查看表,此时没有new表 ++------------------+ +| Tables_in_backup | ++------------------+ +| full | ++------------------+ +1 row in set (0.00 sec) +# 此时只恢复了前一天23点的全被数据,所以并没有new表 + +# 再次恢复我们截取好的binlog日志(增量日志) + mysql> source /tmp/inc.sql -#恢复增量数据 mysql> show tables; -#查看表,此时有new表 ++------------------+ +| Tables_in_backup | ++------------------+ +| full | +| new | ++------------------+ +mysql> select user,host from new; ++------+-----------------------+ +| user | host | ++------+-----------------------+ +| root | localhost | +| root | localhost.localdomain | +| root | 127.0.0.1 | +| root | ::1 | +| | localhost | +| | localhost.localdomain | ++------+-----------------------+ +6 rows in set (0.00 sec) + ``` -- 将故障表导出并恢复到生产 +这个时候,我们就在新库中完全恢复好了我们数据库所有的信息,如果想要恢复生产数据库,我们直接让生产数据库恢复增量备份的数据即可。或者是从新库中导出new表的数据,直接恢复到生产服务器上即可 -```sql -#将现在已经恢复好的数据库backup里的new表备份到/tmp/new.sql文件中 -#此时/tmp/目录下有昨天23:00前完整备份文件full_2018-08-16.sql、昨天23:00到drop的增量文件inc.sql。 -#通过这两个文件恢复了数据库出事前的所有内容 -[root@db02 ~]# mysqldump -uroot -p123 -S /data/3307/mysql.sock backup new > /tmp/new.sql -#导出new表 -[root@db02 ~]# scp /tmp/new.sql root@10.0.0.51:/tmp/ -#发送到db01的库,此时db01的生产环境backup库里没有new表(被无良开发drop掉了);可直接从new.sql倒入 +```bash +[root@localhost ~]# mysqldump -uroot -p123456 -S /data/3307/mysql.sock backup new > /tmp/new.sql +# 导出new表,发送到生产数据库,此时生产数据库backup库里没有new表(被无良开发drop掉了);可直接从new.sql倒入 mysql> use backup -#进入backup库,此时生产环境的backup +# 进入backup库,此时生产环境的backup mysql> source /tmp/new.sql -#在生产库恢复数据 -mysql> show tables; -#查看表 ``` -## 17.5 物理备份(Xtrabackup) +## 15.4 物理备份(Xtrabackup) + +Xtrabackup 是由 Percona 公司开源的一款 MySQL 物理热备份工具,广泛应用于 MySQL 和 MariaDB 数据库的备份。它支持非阻塞备份,能够在备份过程中不中断事务处理,同时不会显著增加数据库服务器的负载 - Xtrabackup安装 @@ -3008,11 +3463,11 @@ copy-back [root@db01 ~]# /etc/init.d/mysqld start ``` -# 18. MySQL的主从复制 +# 16. MySQL的主从复制 -## 18.1 主从复制原理 +## 16.1 主从复制原理 -![img](01.Mysql/sql_MS.jpg) +img - 复制是 MySQL 的一项功能,允许服务器将更改从一个实例复制到另一个实例。 - 主服务器将所有数据和结构更改记录到二进制日志中。 @@ -3036,7 +3491,7 @@ copy-back - 从库: - relay-log(中继日志):存储所有主库TP过来的binlog事件,在SQL thread执行完毕,数据持久化后清空,但写入relaylog.info文件 - relaylog.info:类似于master的binlog文件 - - [master.info](http://master.info/):存储复制用户信息,**上次请求到的主库binlog位置点** + - master.info:存储复制用户信息,**上次请求到的主库binlog位置点** - IO thread:接收主库发来的binlog日志,也是从库请求主库的线程 - SQL thread:执行主库TP过来的日志 - 原理 @@ -3045,49 +3500,51 @@ copy-back - 从库通过IO线程拿着change master to用户密码相关信息,连接主库,验证合法性 - 从库连接成功后,会根据binlog的pos问主库,有没有比这个更新的 - 主库接收到从库请求后,比较一下binlog信息,如果有就将最新数据通过dump线程给从库IO线程 - - 从库通过IO线程接收到主库发来的binlog事件,存储到TCP/IP缓存中,[并返回ACK更新master.info](http://xn--ackmaster-fr4ph28do0tlydq13q.info/) + - 从库通过IO线程接收到主库发来的binlog事件,存储到TCP/IP缓存中,并返回ACK更新master.info - 将TCP/IP缓存中的内容存到relay-log中 - - [SQL线程读取relay-log.info](http://xn--sqlrelay-log-fo0uq362b8zo333c.info/),读取到上次已经执行过的relay-log位置点,继续执行后续的relay-log日志,执行完成后,[更新relay-log.info](http://xn--relay-log-fq5sl5i.info/) + - SQL线程读取relay-log.info,读取到上次已经执行过的relay-log位置点,继续执行后续的relay-log日志,执行完成后,更新relay-log.info -## 18.2 【实战】MySQL主从复制 +## 16.2 【实战】MySQL主从复制 -本实例中db01是master,db02,03是slave,MHA-manager是db03 +本实例中需要两台MySQL数据库,最好是在两个不同的机器上面。其中db01是master,db02是slave。 -- 保证两台数据库数据一致性 +并且两台机器上面具有不同的server_id - ```shell - [root@db01 ~]#mysqldump -uroot -p123 -A -R --triggers --master-data=2 --single-transaction > /tmp/full.sql - [root@db01 ~]#scp /tmp/full.sql root@10.0.0.52:/tmp - [root@db02 ~]#mysql -uroot -p123456 - sql> source /tmp/full.sql - ``` - - - -- 主库操作 +#### 16.2.1 主库操作(db01) - 修改配置文件 ```shell [root@db01 ~]# vim /etc/my.cnf -#编辑mysql配置文件 -[mysqld] -#在mysqld标签下配置 +[mysqld] #在mysqld标签下配置 server_id =1 -#主库server-id为1,从库不等于1 +#主库server-id为1,从库的server_id必须与主库不同 log_bin=mysql-bin #开启binlog日志 -* 创建主从复制用户 -[root@db01 ~]# mysql -uroot -p123456 -#登录数据库 -mysql> grant replication slave on *.* to rep@'10.0.0.%' identified by '123456'; -#创建rep用户 +[root@db01 ~]# systemctl restart mysqld ``` -- 从库操作 - - 修改配置文件 + - 导出一份全备数据给从库(在已经使用的数据库中,如果是后续搭建主从,则需要做如下操作。确保已有的数据一致) ```shell +[root@db01 ~]# mysqldump -uroot -p123456 -A -R --triggers --master-data=2 --single-transaction > /tmp/full.sql +[root@db01 ~]# scp /tmp/full.sql root@192.168.88.140:/tmp/ +``` + + - 创建主从复制用户 + +```shell +[root@db01 ~]# mysql -uroot -p123456 +#登录数据库 +mysql> grant replication slave on *.* to slave@'192.168.88.%' identified by '123456'; +#创建slave用户 +``` + +#### 16.2.2 从库操作(db02) + +1. 修改配置文件 + +```bash [root@db02 ~]# vim /etc/my.cnf #修改db02配置文件 [mysqld] @@ -3096,29 +3553,46 @@ server_id =5 #主库server-id为1,从库不等于1 log_bin=mysql-bin #开启binlog日志 -[root@db02 ~]# /etc/init.d/mysqld restart -#重启mysql +[root@db02 ~]# systemctl restart mysqld +``` + +2. 记录主库当前的binlog位置 + +```bash +[root@db01 ~]# mysql -uroot -p123456 mysql> show master status; -#记录主库binlog及位置点 +``` + +3. 再从库上配置主库等信息 + +```bash [root@db02 ~]# mysql -uroot -p123456 #登陆数据库 mysql> change master to --> master_host='10.0.0.51', --> master_user='rep', --> master_password='123456', --> master_log_file='mysql-bin.000004', --> master_log_pos=120; -#head -50 /tmp/full.sql内的master_log_file与master_log_pos --># master_auto_position=1; # 与前两句冲突,表示自动适配master的file和position,MariaDB5.5不支持GTID特性。此时未开启GTID -#执行change master to 语句 -mysql> start slave; -mysql> show slave status\G -#看到Slave_IO_Running: Yes Slave_SQL_Running: Yes表示运行成功 -#从数据库:/application/mysql/data目录下出现master.info文件,记录了同步的索引号 -#测试方法:在主里面库建表插入内容,从里面可以看到主新增的内容表示同步成功。 +master_host='192.168.88.10', +master_user='slave', +master_password='123456', +master_log_file='mysql-bin.000001', +master_log_pos=120; + +# master_auto_position=1; # 与前两句冲突,表示自动适配master的file和position,MariaDB5.5不支持GTID特性。此时未开启GTID +# master_auto_position=1 表示开启 MySQL 的基于 GTID 的主从复制功能。 +# GTID(Global Transaction Identifier)是一种基于事务的复制方式,相比传统的基于文件和位置的复制方式,GTID 复制更加灵活和可靠。 +# 当 master_auto_position=1 时,slave 会自动找到主库上最新的 GTID 位置,而不需要手动指定日志文件和位置。这样可以避免主从同步时由于位置不匹配而导致的问题。 ``` -## 18.3 主从复制基本故障处理 +#### 16.2.3 开启主从复制 + +```sql +# 执行change master to 语句后 +mysql> start slave; +mysql> show slave status\G +# 看到Slave_IO_Running: Yes Slave_SQL_Running: Yes表示运行成功 +# 从数据库:/application/mysql/data目录下出现master.info文件,记录了同步的索引号 +# 测试方法:在主里面库建表插入内容,从里面可以看到主新增的内容表示同步成功。 +``` + +## 16.3 主从复制基本故障处理 - IO线程报错 - user password ip port @@ -3134,7 +3608,7 @@ mysql> show slave status\G - 操作对象不存在(insert update delete drop truncate alter) - 约束问题、数据类型、列属性 -### 18.3.1 处理方法一 +### 16.3.1 处理方法一 ```sql mysql> stop slave; @@ -3145,7 +3619,7 @@ mysql> start slave; #开启同步 ``` -### 18.3.2 处理方法二 +### 16.3.2 处理方法二 ```shell [root@db01 ~]# vim /etc/my.cnf @@ -3156,7 +3630,7 @@ slave-skip-errors=1032,1062,1007 但是以上操作都是有风险存在的 -### 18.3.3 处理方法三 +### 16.3.3 处理方法三 ```sql set global read_only=1; @@ -3165,7 +3639,7 @@ read_only=1 #在配置文件中永久生效[mysqld] ``` -## 18.4 延时从库 +## 16.4 延时从库 - 普通的主从复制可能存在不足 - 逻辑损坏怎么办? @@ -3199,17 +3673,17 @@ mysql> start slave; - 导出从库数据 - 主库导入数据 -## 18.5 半同步复制 +## 16.5 半同步复制 从MYSQL5.5开始,支持半自动复制。之前版本的MySQL Replication都是异步(asynchronous)的,主库在执行完一些事务后,是不会管备库的进度的。如果备库不幸落后,而更不幸的是主库此时又出现Crash(例如宕机),这时备库中的数据就是不完整的。简而言之,在主库发生故障的时候,我们无法使用备库来继续提供数据一致的服务了。 -![img](01.Mysql/remote_mem_larger_local_disk.jpg) +![img](01.Mysql/remote_mem_larger_local_disk-1739583976576112.jpg) 半同步复制(Semi synchronous Replication)则一定程度上保证提交的事务已经传给了至少一个备库。 IO在收到了读写后会发送ACK报告已经收到了。 -![img](01.Mysql/semi_synchronized_dual_master.jpg) +![img](01.Mysql/semi_synchronized_dual_master-1739583976576113.jpg) 出发点是保证主从数据一致性问题,安全的考虑。 @@ -3236,7 +3710,12 @@ rpl_semi_sync_master_timeout=1000 #多长时间认为超时,单位ms mysql> show variables like'rpl%'; mysql> show global status like 'rpl_semi%'; #检查安装 -* 安装(从库) + +``` + +**从库安装:** + +```bash [root@mysql-db02 ~]# mysql -uroot -p123456 #登录数据库 mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME'semisync_slave.so'; @@ -3253,13 +3732,15 @@ rpl_semi_sync_slave_enabled =1 #在[mysqld]标签下添加如下内容 ``` -- 注:相关参数说明 - - rpl_semi_sync_master_timeout=milliseconds - - 设置此参数值(ms),为了防止半同步复制在没有收到确认的情况下发生堵塞,如果Master在超时之前没有收到任何确认,将恢复到正常的异步复制,并继续执行没有半同步的复制操作。 - - rpl_semi_sync_master_wait_no_slave={ON|OFF} - - 如果一个事务被提交,但Master没有任何Slave的连接,这时不可能将事务发送到其它地方保护起来。默认情况下,Master会在时间限制范围内继续等待Slave的连接,并确认该事务已经被正确的写到磁盘上。 - - 可以使用此参数选项关闭这种行为,在这种情况下,如果没有Slave连接,Master就会恢复到异步复制。 -- 测试半同步 +**注:相关参数说明:** + +- rpl_semi_sync_master_timeout=milliseconds + - 设置此参数值(ms),为了防止半同步复制在没有收到确认的情况下发生堵塞,如果Master在超时之前没有收到任何确认,将恢复到正常的异步复制,并继续执行没有半同步的复制操作。 +- rpl_semi_sync_master_wait_no_slave={ON|OFF} + - 如果一个事务被提交,但Master没有任何Slave的连接,这时不可能将事务发送到其它地方保护起来。默认情况下,Master会在时间限制范围内继续等待Slave的连接,并确认该事务已经被正确的写到磁盘上。 + - 可以使用此参数选项关闭这种行为,在这种情况下,如果没有Slave连接,Master就会恢复到异步复制。 + +**测试半同步:** ```sql mysql> create database test1; @@ -3301,6 +3782,8 @@ mysql> show databases; | test1 | | test2 | +--------------------+ + +# 主库 mysql> SET GLOBAL rpl_semi_sync_master_enabled = 0; #关闭半同步(1:开启 0:关闭) mysql> show global status like 'rpl_semi%'; @@ -3355,9 +3838,9 @@ mysql> show global status like 'rpl_semi%'; 注:不难发现,在查询半同步状态是,开启半同步,查询会有延迟时间,关闭之后则没有 ``` -![img](01.Mysql/mysql_goal.jpg) +![img](01.Mysql/mysql_goal-1739583976576114.jpg) -## 18.6 过滤复制 +## 16.6 过滤复制 - 主库: - 白名单:只记录白名单中列出的库的二进制日志 @@ -3413,19 +3896,19 @@ mysql> use test mysql> show tables; ``` -# 19. MHA高可用架构 +# 17. MHA高可用架构 MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton(现就职于Facebook公司)开发,是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件。在MySQL故障切换过程中,MHA能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。 -![img](01.Mysql/MHA_topo.jpg) +![img](01.Mysql/MHA_topo-1739583976576115.jpg) -MHA能够在较短的时间内实现自动故障检测和故障转移,通常在10-30秒以内;在复制框架中,MHA能够很好地解决复制过程中的数据一致性问题,由于不需要在现有的replication中添加额外的服务器,仅需要一个manager节点,而一个Manager能管理多套复制,所以能大大地节约服务器的数量;另外,安装简单,无性能损耗,以及不需要修改现有的复制部署也是它的优势之处。 +MHA能够在较短的时间内实现自动故障检测和故障转移,通常在0.5-2秒以内;在复制框架中,MHA能够很好地解决复制过程中的数据一致性问题,由于不需要在现有的replication中添加额外的服务器,仅需要一个manager节点,而一个Manager能管理多套复制,所以能大大地节约服务器的数量;另外,安装简单,无性能损耗,以及不需要修改现有的复制部署也是它的优势之处。 MHA还提供在线主库切换的功能,能够安全地切换当前运行的主库到一个新的主库中(通过将从库提升为主库),大概0.5-2秒内即可完成。 MHA由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。MHA Manager可以独立部署在一台独立的机器上管理多个Master-Slave集群,也可以部署在一台Slave上。当Master出现故障时,它可以自动将最新数据的Slave提升为新的Master,然后将所有其他的Slave重新指向新的Master。整个故障转移过程对应用程序是完全透明的。 -## 19.1 工作流程 +## 17.1 工作流程 1. 把宕机的master二进制日志保存下来。 2. 找到binlog位置点最新的slave。 @@ -3434,9 +3917,9 @@ MHA由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点 5. 将含有最新位置点binlog所在的slave提升为master。 6. 将其它slave重新指向新提升的master,并开启主从复制。 -![img](01.Mysql/MHA_process.jpg) +img -## 19.2 MHA工具介绍 +## 17.2 MHA工具介绍 - MHA软件由两部分组成,Manager工具包和Node工具包 @@ -3476,7 +3959,7 @@ MHA由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点 - Works with any storage engine - 只要replication支持的存储引擎,MHA都支持,不会局限于innodb -## 19.3 MHA实验环境 +## 17.3 MHA实验环境 - 搭建三台mysql数据库 @@ -3518,7 +4001,7 @@ mysqladmin -uroot password '123456' mysql -uroot -p123456 ``` -## 19.4 基于GTID的主从复制 +## 17.4 基于GTID的主从复制 - 先决条件 - 主库和从库都要开启binlog @@ -3548,8 +4031,8 @@ server-uuid=8108d02e-be0a-11ec-8a15-000c2956d2e2 ```shell [root@mysql-db01 ~]# mysql -uroot -p123456 #登录数据库 -mysql> grant replication slave on *.* to rep@'10.0.0.%' identified by '123456'; -#创建rep用户 +mysql> grant replication slave on *.* to slave@'192.168.88.%' identified by '123456'; +#创建slave用户 ``` 从库操作 @@ -3565,7 +4048,7 @@ server_id =5 #主库server-id为1,从库必须大于1 log_bin=mysql-bin #开启binlog日志 -[root@mysql-db02 ~]# /etc/init.d/mysqld restart +[root@mysql-db02 ~]# systemctl restart mysqld #重启mysql [root@mysql-db03 ~]# vim /etc/my.cnf #修改mysql-db03配置文件 @@ -3575,7 +4058,7 @@ server_id =10 #主库server-id为1,从库必须大于1 log_bin=mysql-bin #开启binlog日志 -[root@mysql-db03 ~]# /etc/init.d/mysqld restart +[root@mysql-db03 ~]# systemctl restart mysqld #重启mysql ``` @@ -3613,7 +4096,7 @@ log_slave_updates #重要:开启slave的binlog同步 enforce_gtid_consistency #开启GTID特性 -[root@mysql-db01 ~]# /etc/init.d/mysqld restart +[root@mysql-db01 ~]# systemctl restart mysqld #重启数据库 mysql> show global variables like '%gtid%'; #检查GTID状态 @@ -3631,12 +4114,12 @@ mysql> show global variables like '%gtid%'; **注:主库从库都需要开启GTID否则在做主从复制的时候就会报错,因为slave可能变成master** ```sql -[root@mysql-db02 ~]# mysql -uroot -123456 +[root@mysql-db02 ~]# mysql -uroot -p123456 mysql> change master to --> master_host='10.0.0.51', --> master_user='rep', --> master_password='123456', --> master_auto_position=1; +master_host='192.168.88.10', +master_user='slave', +master_password='123456', +master_auto_position=1; #如果GTID没有开的话 ERROR 1777 (HY000): CHANGE MASTER TO MASTER_AUTO_POSITION = 1 can only be executed when @@GLOBAL.GTID_MODE = ON. ``` @@ -3704,32 +4187,36 @@ relay_log_purge = 0 #禁用自动删除relay log 永久生效 ``` -## 19.5 部署MHA +## 17.5 部署MHA 环境准备(所有节点) -记得要这个MHA安装包 +下载MHA工具包: -https://download.s21i.faiusr.com/23126342/0/0/ABUIABBPGAAg30HUiAYolpPt7AQ.zip?f=mysql-master-ha.zip&v=1628778716 +```bash +[root@localhost ~]# wget "https://download.s21i.faiusr.com/23126342/0/0/ABUIABBPGAAg3OHUiAYolpPt7AQ.zip?f=mysql-master-ha.zip&v=1628778716" -O mysql-master-ha.zip +``` ```shell -[root@mysql-db01 ~]# yum install perl-DBD-MySQL -y -#安装依赖包 -[root@mysql-db01 ~]# unzip mysql-master-ha.zip /home/user1/tools/ -[root@mysql-db01 ~]# cd /home/user1/tools/ +[root@localhost ~]# mkdir /application/tools +[root@mysql-db01 ~]# unzip mysql-master-ha.zip -d /application/tools/ +[root@mysql-db01 ~]# cd /application/tools/mysql-master-ha/ #进入安装包存放目录 [root@mysql-db01 tools]# ll mha4mysql-manager-0.56-0.el6.noarch.rpm mha4mysql-manager-0.56.tar.gz mha4mysql-node-0.56-0.el6.noarch.rpm mha4mysql-node-0.56.tar.gz -[root@mysql-db01 tools]# rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm + +[root@mysql-db01 ~]# yum install perl-DBD-MySQL -y +#安装依赖包 +[root@mysql-db01 tools]# yum install -y mha4mysql-node-0.56-0.el6.noarch.rpm Preparing... ########################################### [100%] 1:mha4mysql-node ########################################### [100%] #安装node包,所有节点都要安装node包 [root@mysql-db01 tools]# mysql -uroot -p123456 #登录数据库,主库,从库会自动同步 -mysql> grant all privileges on *.* to mha@'10.0.0.%' identified by 'mha'; +mysql> grant all privileges on *.* to mha@'192.168.88.%' identified by 'mha'; #添加mha管理账号 mysql> select user,host from mysql.user; #查看是否添加成功 @@ -3752,7 +4239,7 @@ mysql> select user,host from mysql.user; #使用epel源 [root@mysql-db03 ~]# yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes #安装manager依赖包 -[root@mysql-db03 tools]# rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm +[root@mysql-db03 tools]# yum install -y mha4mysql-manager-0.56-0.el6.noarch.rpm Preparing... ########################################### [100%] 1:mha4mysql-manager ########################################### [100%] #安装manager包 @@ -3831,9 +4318,9 @@ port=3306 hostname=10.0.0.52 port=3306 candidate_master=1 -#设置为候选master,如果设置该参数以后,发生主从切换以后将会将此从库提升为主库,即使这个主库不是集群中事件最新的slave。 +# 设置为候选master,如果设置该参数以后,发生主从切换以后将会将此从库提升为主库,即使这个主库不是集群中事件最新的slave。 check_repl_delay=0 -#默认情况下如果一个slave落后master 100M的relay logs的话,MHA将不会选择该slave作为一个新的master,因为对于这个slave的恢复需要花费很长时间,通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master +# 默认情况下如果一个slave落后master 100M的relay logs的话,MHA将不会选择该slave作为一个新的master,因为对于这个slave的恢复需要花费很长时间,通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master ``` - 配置ssh信任(所有节点) @@ -3841,9 +4328,9 @@ check_repl_delay=0 ```shell [root@mysql-db01 ~]# ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa >/dev/null 2>&1 #创建秘钥对 -[root@mysql-db01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.0.0.51 -[root@mysql-db01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.0.0.52 -[root@mysql-db01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.0.0.53 +[root@mysql-db01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.88.10 +[root@mysql-db01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.88.20 +[root@mysql-db01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub root@192.168.88.30 #发送公钥,包括自己 ``` @@ -3857,7 +4344,7 @@ Tue Mar 7 01:03:33 2017 - [info] All SSH connection tests passed successfully. [root@mysql-db03 ~]# masterha_check_repl --conf=/etc/mha/app1.cnf #测试复制 #看到如下字样,则测试成功 -#若不在slave库上创建用户会失败,按理说应该slave会同步master的库但创建rep用户是创建主从关系前 +#若不在slave库上创建用户会失败,按理说应该slave会同步master的库但创建slave用户是创建主从关系前 #mysql> grant replication slave on *.* to rep@'10.0.0.%' identified by '123456'; MySQL Replication Health is OK. ``` @@ -3943,17 +4430,15 @@ mysql> show slave status\G ```sql [root@mysql-db01 ~]# mysql -uroot -123456 -mysql> change master to --> master_host='10.0.0.52', --> master_user='rep', --> master_password='123456', --> master_auto_position=1; +change master to +master_host='192.168.88.136', +master_user='slave', +master_password='123456', +master_auto_position=1; -> start slave; ``` - - -## 19.6 配置vIP漂移 +## 17.6 配置vIP漂移 - VIP漂移的两种方式 - 通过keepalived的方式,管理虚拟IP的漂移,与后面Nginx负载均衡有关 @@ -3983,8 +4468,8 @@ master_ip_failover_script=/etc/mha/master_ip_failover my $vip = '10.0.0.55/24'; my $key = '0'; #网卡名要改对,可能是ens33 -my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip"; -my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down"; +my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip"; +my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down"; #修改以下几行内容 [root@mysql-db03 ~]# chmod +x /etc/mha/master_ip_failover #添加执行权限,否则mha无法启动 @@ -3992,7 +4477,7 @@ my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down"; #安装IFconfig,每台设备都要安装否则脚本执行失败 * 手动绑定vIP,假设db01是master -[root@mysql-db01 ~]# ifconfig eth0:0 10.0.0.55/24 +[root@mysql-db01 ~]# ifconfig ens33:0 192.168.88.88/24 #绑定vip,第一次要在master上手工配置,后面不需要了 [root@mysql-db01 ~]# ip a |grep eth0 #查看vip diff --git a/03.数据库/01.Mysql/157ueBBseL6MvenH.png!thumbnail b/03.数据库/01.Mysql/157ueBBseL6MvenH-173958382539012.png!thumbnail similarity index 100% rename from 03.数据库/01.Mysql/157ueBBseL6MvenH.png!thumbnail rename to 03.数据库/01.Mysql/157ueBBseL6MvenH-173958382539012.png!thumbnail diff --git a/03.数据库/01.Mysql/157ueBBseL6MvenH-173958392751660.png!thumbnail b/03.数据库/01.Mysql/157ueBBseL6MvenH-173958392751660.png!thumbnail new file mode 100644 index 0000000..0f39627 Binary files /dev/null and b/03.数据库/01.Mysql/157ueBBseL6MvenH-173958392751660.png!thumbnail differ diff --git a/03.数据库/01.Mysql/157ueBBseL6MvenH-1739583976575105.png!thumbnail b/03.数据库/01.Mysql/157ueBBseL6MvenH-1739583976575105.png!thumbnail new file mode 100644 index 0000000..0f39627 Binary files /dev/null and b/03.数据库/01.Mysql/157ueBBseL6MvenH-1739583976575105.png!thumbnail differ diff --git a/03.数据库/01.Mysql/5TsFS9HElaslP5ss.png!thumbnail b/03.数据库/01.Mysql/5TsFS9HElaslP5ss-173958382539016.png!thumbnail similarity index 100% rename from 03.数据库/01.Mysql/5TsFS9HElaslP5ss.png!thumbnail rename to 03.数据库/01.Mysql/5TsFS9HElaslP5ss-173958382539016.png!thumbnail diff --git a/03.数据库/01.Mysql/5TsFS9HElaslP5ss-173958392751664.png!thumbnail b/03.数据库/01.Mysql/5TsFS9HElaslP5ss-173958392751664.png!thumbnail new file mode 100644 index 0000000..50ab4d5 Binary files /dev/null and b/03.数据库/01.Mysql/5TsFS9HElaslP5ss-173958392751664.png!thumbnail differ diff --git a/03.数据库/01.Mysql/DsbxGtxBZzy6d1kN.png!thumbnail b/03.数据库/01.Mysql/DsbxGtxBZzy6d1kN-17395838253895.png!thumbnail similarity index 100% rename from 03.数据库/01.Mysql/DsbxGtxBZzy6d1kN.png!thumbnail rename to 03.数据库/01.Mysql/DsbxGtxBZzy6d1kN-17395838253895.png!thumbnail diff --git a/03.数据库/01.Mysql/DsbxGtxBZzy6d1kN-173958392751553.png!thumbnail b/03.数据库/01.Mysql/DsbxGtxBZzy6d1kN-173958392751553.png!thumbnail new file mode 100644 index 0000000..9d1b43e Binary files /dev/null and b/03.数据库/01.Mysql/DsbxGtxBZzy6d1kN-173958392751553.png!thumbnail differ diff --git a/03.数据库/01.Mysql/DsbxGtxBZzy6d1kN-173958397657599.png!thumbnail b/03.数据库/01.Mysql/DsbxGtxBZzy6d1kN-173958397657599.png!thumbnail new file mode 100644 index 0000000..9d1b43e Binary files /dev/null and b/03.数据库/01.Mysql/DsbxGtxBZzy6d1kN-173958397657599.png!thumbnail differ diff --git a/03.数据库/01.Mysql/G1WukGpm4kWFCtKy.png!thumbnail b/03.数据库/01.Mysql/G1WukGpm4kWFCtKy-173958382539013.png!thumbnail similarity index 100% rename from 03.数据库/01.Mysql/G1WukGpm4kWFCtKy.png!thumbnail rename to 03.数据库/01.Mysql/G1WukGpm4kWFCtKy-173958382539013.png!thumbnail diff --git a/03.数据库/01.Mysql/G1WukGpm4kWFCtKy-173958392751661.png!thumbnail b/03.数据库/01.Mysql/G1WukGpm4kWFCtKy-173958392751661.png!thumbnail new file mode 100644 index 0000000..d7a8e70 Binary files /dev/null and b/03.数据库/01.Mysql/G1WukGpm4kWFCtKy-173958392751661.png!thumbnail differ diff --git a/03.数据库/01.Mysql/G1WukGpm4kWFCtKy-1739583976575106.png!thumbnail b/03.数据库/01.Mysql/G1WukGpm4kWFCtKy-1739583976575106.png!thumbnail new file mode 100644 index 0000000..d7a8e70 Binary files /dev/null and b/03.数据库/01.Mysql/G1WukGpm4kWFCtKy-1739583976575106.png!thumbnail differ diff --git a/03.数据库/01.Mysql/HET6YsqLtNayuI6Q.png!thumbnail b/03.数据库/01.Mysql/HET6YsqLtNayuI6Q-173958382539014.png!thumbnail similarity index 100% rename from 03.数据库/01.Mysql/HET6YsqLtNayuI6Q.png!thumbnail rename to 03.数据库/01.Mysql/HET6YsqLtNayuI6Q-173958382539014.png!thumbnail diff --git a/03.数据库/01.Mysql/HET6YsqLtNayuI6Q-173958392751662.png!thumbnail b/03.数据库/01.Mysql/HET6YsqLtNayuI6Q-173958392751662.png!thumbnail new file mode 100644 index 0000000..274b2f1 Binary files /dev/null and b/03.数据库/01.Mysql/HET6YsqLtNayuI6Q-173958392751662.png!thumbnail differ diff --git a/03.数据库/01.Mysql/HET6YsqLtNayuI6Q-1739583976575107.png!thumbnail b/03.数据库/01.Mysql/HET6YsqLtNayuI6Q-1739583976575107.png!thumbnail new file mode 100644 index 0000000..274b2f1 Binary files /dev/null and b/03.数据库/01.Mysql/HET6YsqLtNayuI6Q-1739583976575107.png!thumbnail differ diff --git a/03.数据库/01.Mysql/JnL2YEThjuHERQPZ.png!thumbnail b/03.数据库/01.Mysql/JnL2YEThjuHERQPZ-17395838253896.png!thumbnail similarity index 100% rename from 03.数据库/01.Mysql/JnL2YEThjuHERQPZ.png!thumbnail rename to 03.数据库/01.Mysql/JnL2YEThjuHERQPZ-17395838253896.png!thumbnail diff --git a/03.数据库/01.Mysql/JnL2YEThjuHERQPZ-173958392751554.png!thumbnail b/03.数据库/01.Mysql/JnL2YEThjuHERQPZ-173958392751554.png!thumbnail new file mode 100644 index 0000000..f3971c9 Binary files /dev/null and b/03.数据库/01.Mysql/JnL2YEThjuHERQPZ-173958392751554.png!thumbnail differ diff --git a/03.数据库/01.Mysql/JnL2YEThjuHERQPZ-1739583976575100.png!thumbnail b/03.数据库/01.Mysql/JnL2YEThjuHERQPZ-1739583976575100.png!thumbnail new file mode 100644 index 0000000..f3971c9 Binary files /dev/null and b/03.数据库/01.Mysql/JnL2YEThjuHERQPZ-1739583976575100.png!thumbnail differ diff --git a/03.数据库/01.Mysql/KkaagjFIBB8C0CCF.png!thumbnail b/03.数据库/01.Mysql/KkaagjFIBB8C0CCF-173958382539015.png!thumbnail similarity index 100% rename from 03.数据库/01.Mysql/KkaagjFIBB8C0CCF.png!thumbnail rename to 03.数据库/01.Mysql/KkaagjFIBB8C0CCF-173958382539015.png!thumbnail diff --git a/03.数据库/01.Mysql/KkaagjFIBB8C0CCF-173958392751663.png!thumbnail b/03.数据库/01.Mysql/KkaagjFIBB8C0CCF-173958392751663.png!thumbnail new file mode 100644 index 0000000..0a3d697 Binary files /dev/null and b/03.数据库/01.Mysql/KkaagjFIBB8C0CCF-173958392751663.png!thumbnail differ diff --git a/03.数据库/01.Mysql/KkaagjFIBB8C0CCF-1739583976575108.png!thumbnail b/03.数据库/01.Mysql/KkaagjFIBB8C0CCF-1739583976575108.png!thumbnail new file mode 100644 index 0000000..0a3d697 Binary files /dev/null and b/03.数据库/01.Mysql/KkaagjFIBB8C0CCF-1739583976575108.png!thumbnail differ diff --git a/03.数据库/01.Mysql/L8Ndjn2BuNL9IUl2.png!thumbnail b/03.数据库/01.Mysql/L8Ndjn2BuNL9IUl2-17395838253882.png!thumbnail similarity index 100% rename from 03.数据库/01.Mysql/L8Ndjn2BuNL9IUl2.png!thumbnail rename to 03.数据库/01.Mysql/L8Ndjn2BuNL9IUl2-17395838253882.png!thumbnail diff --git a/03.数据库/01.Mysql/L8Ndjn2BuNL9IUl2-173958392751550.png!thumbnail b/03.数据库/01.Mysql/L8Ndjn2BuNL9IUl2-173958392751550.png!thumbnail new file mode 100644 index 0000000..05fdf37 Binary files /dev/null and b/03.数据库/01.Mysql/L8Ndjn2BuNL9IUl2-173958392751550.png!thumbnail differ diff --git a/03.数据库/01.Mysql/MHA_process.jpg b/03.数据库/01.Mysql/MHA_process-173958382539124.jpg similarity index 100% rename from 03.数据库/01.Mysql/MHA_process.jpg rename to 03.数据库/01.Mysql/MHA_process-173958382539124.jpg diff --git a/03.数据库/01.Mysql/MHA_process-173958392751772.jpg b/03.数据库/01.Mysql/MHA_process-173958392751772.jpg new file mode 100644 index 0000000..b1bc3b3 Binary files /dev/null and b/03.数据库/01.Mysql/MHA_process-173958392751772.jpg differ diff --git a/03.数据库/01.Mysql/MHA_process-1739583976576116.jpg b/03.数据库/01.Mysql/MHA_process-1739583976576116.jpg new file mode 100644 index 0000000..b1bc3b3 Binary files /dev/null and b/03.数据库/01.Mysql/MHA_process-1739583976576116.jpg differ diff --git a/03.数据库/01.Mysql/MHA_topo.jpg b/03.数据库/01.Mysql/MHA_topo-173958382539123.jpg similarity index 100% rename from 03.数据库/01.Mysql/MHA_topo.jpg rename to 03.数据库/01.Mysql/MHA_topo-173958382539123.jpg diff --git a/03.数据库/01.Mysql/MHA_topo-173958392751771.jpg b/03.数据库/01.Mysql/MHA_topo-173958392751771.jpg new file mode 100644 index 0000000..1d2bd66 Binary files /dev/null and b/03.数据库/01.Mysql/MHA_topo-173958392751771.jpg differ diff --git a/03.数据库/01.Mysql/MHA_topo-1739583976576115.jpg b/03.数据库/01.Mysql/MHA_topo-1739583976576115.jpg new file mode 100644 index 0000000..1d2bd66 Binary files /dev/null and b/03.数据库/01.Mysql/MHA_topo-1739583976576115.jpg differ diff --git a/03.数据库/01.Mysql/R5j17V2j8h153YXZ.png!thumbnail b/03.数据库/01.Mysql/R5j17V2j8h153YXZ-17395838253881.png!thumbnail similarity index 100% rename from 03.数据库/01.Mysql/R5j17V2j8h153YXZ.png!thumbnail rename to 03.数据库/01.Mysql/R5j17V2j8h153YXZ-17395838253881.png!thumbnail diff --git a/03.数据库/01.Mysql/R5j17V2j8h153YXZ-173958392751549.png!thumbnail b/03.数据库/01.Mysql/R5j17V2j8h153YXZ-173958392751549.png!thumbnail new file mode 100644 index 0000000..d9b0785 Binary files /dev/null and b/03.数据库/01.Mysql/R5j17V2j8h153YXZ-173958392751549.png!thumbnail differ diff --git a/03.数据库/01.Mysql/Tw0AJl9FjrygD1S4.png!thumbnail b/03.数据库/01.Mysql/Tw0AJl9FjrygD1S4-173958382538911.png!thumbnail similarity index 100% rename from 03.数据库/01.Mysql/Tw0AJl9FjrygD1S4.png!thumbnail rename to 03.数据库/01.Mysql/Tw0AJl9FjrygD1S4-173958382538911.png!thumbnail diff --git a/03.数据库/01.Mysql/Tw0AJl9FjrygD1S4-173958392751659.png!thumbnail b/03.数据库/01.Mysql/Tw0AJl9FjrygD1S4-173958392751659.png!thumbnail new file mode 100644 index 0000000..280b2b6 Binary files /dev/null and b/03.数据库/01.Mysql/Tw0AJl9FjrygD1S4-173958392751659.png!thumbnail differ diff --git a/03.数据库/01.Mysql/Tw0AJl9FjrygD1S4-1739583976575104.png!thumbnail b/03.数据库/01.Mysql/Tw0AJl9FjrygD1S4-1739583976575104.png!thumbnail new file mode 100644 index 0000000..280b2b6 Binary files /dev/null and b/03.数据库/01.Mysql/Tw0AJl9FjrygD1S4-1739583976575104.png!thumbnail differ diff --git a/03.数据库/01.Mysql/WCtzPCFRsaTUTp3A.png!thumbnail b/03.数据库/01.Mysql/WCtzPCFRsaTUTp3A-17395838253898.png!thumbnail similarity index 100% rename from 03.数据库/01.Mysql/WCtzPCFRsaTUTp3A.png!thumbnail rename to 03.数据库/01.Mysql/WCtzPCFRsaTUTp3A-17395838253898.png!thumbnail diff --git a/03.数据库/01.Mysql/WCtzPCFRsaTUTp3A-173958392751656.png!thumbnail b/03.数据库/01.Mysql/WCtzPCFRsaTUTp3A-173958392751656.png!thumbnail new file mode 100644 index 0000000..ac1b24f Binary files /dev/null and b/03.数据库/01.Mysql/WCtzPCFRsaTUTp3A-173958392751656.png!thumbnail differ diff --git a/03.数据库/01.Mysql/WCtzPCFRsaTUTp3A-1739583976575102.png!thumbnail b/03.数据库/01.Mysql/WCtzPCFRsaTUTp3A-1739583976575102.png!thumbnail new file mode 100644 index 0000000..ac1b24f Binary files /dev/null and b/03.数据库/01.Mysql/WCtzPCFRsaTUTp3A-1739583976575102.png!thumbnail differ diff --git a/03.数据库/01.Mysql/agMqU13UrbmuyFz0.png!thumbnail b/03.数据库/01.Mysql/agMqU13UrbmuyFz0-17395838253899.png!thumbnail similarity index 100% rename from 03.数据库/01.Mysql/agMqU13UrbmuyFz0.png!thumbnail rename to 03.数据库/01.Mysql/agMqU13UrbmuyFz0-17395838253899.png!thumbnail diff --git a/03.数据库/01.Mysql/agMqU13UrbmuyFz0-173958392751657.png!thumbnail b/03.数据库/01.Mysql/agMqU13UrbmuyFz0-173958392751657.png!thumbnail new file mode 100644 index 0000000..d868e34 Binary files /dev/null and b/03.数据库/01.Mysql/agMqU13UrbmuyFz0-173958392751657.png!thumbnail differ diff --git a/03.数据库/01.Mysql/image-20240721145430464.png b/03.数据库/01.Mysql/image-20240721145430464.png new file mode 100644 index 0000000..3fec45b Binary files /dev/null and b/03.数据库/01.Mysql/image-20240721145430464.png differ diff --git a/03.数据库/01.Mysql/image-20240721151426381.png b/03.数据库/01.Mysql/image-20240721151426381.png new file mode 100644 index 0000000..7b0b8bd Binary files /dev/null and b/03.数据库/01.Mysql/image-20240721151426381.png differ diff --git a/03.数据库/01.Mysql/k1P7hTxOM3vKCIG2.png!thumbnail b/03.数据库/01.Mysql/k1P7hTxOM3vKCIG2-17395838253894.png!thumbnail similarity index 100% rename from 03.数据库/01.Mysql/k1P7hTxOM3vKCIG2.png!thumbnail rename to 03.数据库/01.Mysql/k1P7hTxOM3vKCIG2-17395838253894.png!thumbnail diff --git a/03.数据库/01.Mysql/k1P7hTxOM3vKCIG2-173958392751552.png!thumbnail b/03.数据库/01.Mysql/k1P7hTxOM3vKCIG2-173958392751552.png!thumbnail new file mode 100644 index 0000000..6b741b1 Binary files /dev/null and b/03.数据库/01.Mysql/k1P7hTxOM3vKCIG2-173958392751552.png!thumbnail differ diff --git a/03.数据库/01.Mysql/k1P7hTxOM3vKCIG2-173958397657498.png!thumbnail b/03.数据库/01.Mysql/k1P7hTxOM3vKCIG2-173958397657498.png!thumbnail new file mode 100644 index 0000000..6b741b1 Binary files /dev/null and b/03.数据库/01.Mysql/k1P7hTxOM3vKCIG2-173958397657498.png!thumbnail differ diff --git a/03.数据库/01.Mysql/lK3mQW6m9VMwIgVD.png!thumbnail b/03.数据库/01.Mysql/lK3mQW6m9VMwIgVD-17395838253897.png!thumbnail similarity index 100% rename from 03.数据库/01.Mysql/lK3mQW6m9VMwIgVD.png!thumbnail rename to 03.数据库/01.Mysql/lK3mQW6m9VMwIgVD-17395838253897.png!thumbnail diff --git a/03.数据库/01.Mysql/lK3mQW6m9VMwIgVD-173958392751555.png!thumbnail b/03.数据库/01.Mysql/lK3mQW6m9VMwIgVD-173958392751555.png!thumbnail new file mode 100644 index 0000000..f9080b8 Binary files /dev/null and b/03.数据库/01.Mysql/lK3mQW6m9VMwIgVD-173958392751555.png!thumbnail differ diff --git a/03.数据库/01.Mysql/lK3mQW6m9VMwIgVD-1739583976575101.png!thumbnail b/03.数据库/01.Mysql/lK3mQW6m9VMwIgVD-1739583976575101.png!thumbnail new file mode 100644 index 0000000..f9080b8 Binary files /dev/null and b/03.数据库/01.Mysql/lK3mQW6m9VMwIgVD-1739583976575101.png!thumbnail differ diff --git a/03.数据库/01.Mysql/mysql_goal.jpg b/03.数据库/01.Mysql/mysql_goal-173958382539022.jpg similarity index 100% rename from 03.数据库/01.Mysql/mysql_goal.jpg rename to 03.数据库/01.Mysql/mysql_goal-173958382539022.jpg diff --git a/03.数据库/01.Mysql/mysql_goal-173958392751770.jpg b/03.数据库/01.Mysql/mysql_goal-173958392751770.jpg new file mode 100644 index 0000000..5ab52d6 Binary files /dev/null and b/03.数据库/01.Mysql/mysql_goal-173958392751770.jpg differ diff --git a/03.数据库/01.Mysql/mysql_goal-1739583976576114.jpg b/03.数据库/01.Mysql/mysql_goal-1739583976576114.jpg new file mode 100644 index 0000000..5ab52d6 Binary files /dev/null and b/03.数据库/01.Mysql/mysql_goal-1739583976576114.jpg differ diff --git a/03.数据库/01.Mysql/remote_mem_larger_local_disk.jpg b/03.数据库/01.Mysql/remote_mem_larger_local_disk-173958382539020.jpg similarity index 100% rename from 03.数据库/01.Mysql/remote_mem_larger_local_disk.jpg rename to 03.数据库/01.Mysql/remote_mem_larger_local_disk-173958382539020.jpg diff --git a/03.数据库/01.Mysql/remote_mem_larger_local_disk-173958392751768.jpg b/03.数据库/01.Mysql/remote_mem_larger_local_disk-173958392751768.jpg new file mode 100644 index 0000000..ccf1377 Binary files /dev/null and b/03.数据库/01.Mysql/remote_mem_larger_local_disk-173958392751768.jpg differ diff --git a/03.数据库/01.Mysql/remote_mem_larger_local_disk-1739583976576112.jpg b/03.数据库/01.Mysql/remote_mem_larger_local_disk-1739583976576112.jpg new file mode 100644 index 0000000..ccf1377 Binary files /dev/null and b/03.数据库/01.Mysql/remote_mem_larger_local_disk-1739583976576112.jpg differ diff --git a/03.数据库/01.Mysql/semi_synchronized_dual_master.jpg b/03.数据库/01.Mysql/semi_synchronized_dual_master-173958382539021.jpg similarity index 100% rename from 03.数据库/01.Mysql/semi_synchronized_dual_master.jpg rename to 03.数据库/01.Mysql/semi_synchronized_dual_master-173958382539021.jpg diff --git a/03.数据库/01.Mysql/semi_synchronized_dual_master-173958392751769.jpg b/03.数据库/01.Mysql/semi_synchronized_dual_master-173958392751769.jpg new file mode 100644 index 0000000..663e3b1 Binary files /dev/null and b/03.数据库/01.Mysql/semi_synchronized_dual_master-173958392751769.jpg differ diff --git a/03.数据库/01.Mysql/semi_synchronized_dual_master-1739583976576113.jpg b/03.数据库/01.Mysql/semi_synchronized_dual_master-1739583976576113.jpg new file mode 100644 index 0000000..663e3b1 Binary files /dev/null and b/03.数据库/01.Mysql/semi_synchronized_dual_master-1739583976576113.jpg differ diff --git a/03.数据库/01.Mysql/sql_MS.jpg b/03.数据库/01.Mysql/sql_MS-173958382539019.jpg similarity index 100% rename from 03.数据库/01.Mysql/sql_MS.jpg rename to 03.数据库/01.Mysql/sql_MS-173958382539019.jpg diff --git a/03.数据库/01.Mysql/sql_MS-173958392751667.jpg b/03.数据库/01.Mysql/sql_MS-173958392751667.jpg new file mode 100644 index 0000000..6561945 Binary files /dev/null and b/03.数据库/01.Mysql/sql_MS-173958392751667.jpg differ diff --git a/03.数据库/01.Mysql/sql_MS-1739583976576111.jpg b/03.数据库/01.Mysql/sql_MS-1739583976576111.jpg new file mode 100644 index 0000000..6561945 Binary files /dev/null and b/03.数据库/01.Mysql/sql_MS-1739583976576111.jpg differ diff --git a/03.数据库/01.Mysql/tL76EP1rBEQKcpeU.png!thumbnail b/03.数据库/01.Mysql/tL76EP1rBEQKcpeU-17395838253893.png!thumbnail similarity index 100% rename from 03.数据库/01.Mysql/tL76EP1rBEQKcpeU.png!thumbnail rename to 03.数据库/01.Mysql/tL76EP1rBEQKcpeU-17395838253893.png!thumbnail diff --git a/03.数据库/01.Mysql/tL76EP1rBEQKcpeU-173958392751551.png!thumbnail b/03.数据库/01.Mysql/tL76EP1rBEQKcpeU-173958392751551.png!thumbnail new file mode 100644 index 0000000..da23166 Binary files /dev/null and b/03.数据库/01.Mysql/tL76EP1rBEQKcpeU-173958392751551.png!thumbnail differ diff --git a/03.数据库/01.Mysql/tL76EP1rBEQKcpeU-173958397657497.png!thumbnail b/03.数据库/01.Mysql/tL76EP1rBEQKcpeU-173958397657497.png!thumbnail new file mode 100644 index 0000000..da23166 Binary files /dev/null and b/03.数据库/01.Mysql/tL76EP1rBEQKcpeU-173958397657497.png!thumbnail differ diff --git a/03.数据库/01.Mysql/uCoOhC6Rn5HuTfxg.png!thumbnail b/03.数据库/01.Mysql/uCoOhC6Rn5HuTfxg-173958382538910.png!thumbnail similarity index 100% rename from 03.数据库/01.Mysql/uCoOhC6Rn5HuTfxg.png!thumbnail rename to 03.数据库/01.Mysql/uCoOhC6Rn5HuTfxg-173958382538910.png!thumbnail diff --git a/03.数据库/01.Mysql/uCoOhC6Rn5HuTfxg-173958392751658.png!thumbnail b/03.数据库/01.Mysql/uCoOhC6Rn5HuTfxg-173958392751658.png!thumbnail new file mode 100644 index 0000000..af5f847 Binary files /dev/null and b/03.数据库/01.Mysql/uCoOhC6Rn5HuTfxg-173958392751658.png!thumbnail differ diff --git a/03.数据库/01.Mysql/uCoOhC6Rn5HuTfxg-1739583976575103.png!thumbnail b/03.数据库/01.Mysql/uCoOhC6Rn5HuTfxg-1739583976575103.png!thumbnail new file mode 100644 index 0000000..af5f847 Binary files /dev/null and b/03.数据库/01.Mysql/uCoOhC6Rn5HuTfxg-1739583976575103.png!thumbnail differ diff --git a/03.数据库/01.Mysql/uxH9iBpInyy8pwrk.png!thumbnail b/03.数据库/01.Mysql/uxH9iBpInyy8pwrk-173958382539017.png!thumbnail similarity index 100% rename from 03.数据库/01.Mysql/uxH9iBpInyy8pwrk.png!thumbnail rename to 03.数据库/01.Mysql/uxH9iBpInyy8pwrk-173958382539017.png!thumbnail diff --git a/03.数据库/01.Mysql/uxH9iBpInyy8pwrk-173958392751665.png!thumbnail b/03.数据库/01.Mysql/uxH9iBpInyy8pwrk-173958392751665.png!thumbnail new file mode 100644 index 0000000..c044005 Binary files /dev/null and b/03.数据库/01.Mysql/uxH9iBpInyy8pwrk-173958392751665.png!thumbnail differ diff --git a/03.数据库/01.Mysql/uxH9iBpInyy8pwrk-1739583976575109.png!thumbnail b/03.数据库/01.Mysql/uxH9iBpInyy8pwrk-1739583976575109.png!thumbnail new file mode 100644 index 0000000..c044005 Binary files /dev/null and b/03.数据库/01.Mysql/uxH9iBpInyy8pwrk-1739583976575109.png!thumbnail differ diff --git a/03.数据库/01.Mysql/yhWTJJz8GZkilbZN.png!thumbnail b/03.数据库/01.Mysql/yhWTJJz8GZkilbZN-173958382539018.png!thumbnail similarity index 100% rename from 03.数据库/01.Mysql/yhWTJJz8GZkilbZN.png!thumbnail rename to 03.数据库/01.Mysql/yhWTJJz8GZkilbZN-173958382539018.png!thumbnail diff --git a/03.数据库/01.Mysql/yhWTJJz8GZkilbZN-173958392751666.png!thumbnail b/03.数据库/01.Mysql/yhWTJJz8GZkilbZN-173958392751666.png!thumbnail new file mode 100644 index 0000000..1b37974 Binary files /dev/null and b/03.数据库/01.Mysql/yhWTJJz8GZkilbZN-173958392751666.png!thumbnail differ diff --git a/03.数据库/01.Mysql/yhWTJJz8GZkilbZN-1739583976575110.png!thumbnail b/03.数据库/01.Mysql/yhWTJJz8GZkilbZN-1739583976575110.png!thumbnail new file mode 100644 index 0000000..1b37974 Binary files /dev/null and b/03.数据库/01.Mysql/yhWTJJz8GZkilbZN-1739583976575110.png!thumbnail differ