2180 lines
66 KiB
Plaintext
2180 lines
66 KiB
Plaintext
# 数据库
|
||
|
||
## 第一章:数据库基础
|
||
|
||
### 数据库
|
||
|
||
Mysql 数据库软件 Oracle Sql-server Mariadb 自研数据库 云产品 云数据库
|
||
|
||
------
|
||
|
||
###### 数据库技术:
|
||
|
||
DBS DBMS
|
||
|
||
------
|
||
|
||
###### 数据库分类:
|
||
|
||
关系型数据库(SQL):Mysql Oracle 数据采用库表的形式存储
|
||
|
||
非关系型数据库(NoSQL)Not only SQL:Redis Memcache Mongodb K-V 键值对
|
||
|
||
------
|
||
|
||
###### 数据库访问技术:
|
||
|
||
Java:
|
||
|
||
JDBC
|
||
实现在项目后端源码中添加数据库的相关信息: 数据库IP地址 数据库端口 数据库用户名 数据库密码 数据库库名
|
||
|
||
------
|
||
|
||
php:
|
||
|
||
ODBC
|
||
实现在项目后端源码中添加数据库的相关信息: 数据库IP地址 数据库端口 数据库用户名 数据库密码 数据库库名
|
||
|
||
------
|
||
|
||
python:
|
||
|
||
settings.py
|
||
实现在项目后端源码中添加数据库的相关信息: 数据库IP地址 数据库端口 数据库用户名 数据库密码 数据库库名
|
||
|
||
------
|
||
|
||
###### 数据库部署:
|
||
|
||
版本:
|
||
|
||
mysql:8.0
|
||
|
||
mysql:5.7
|
||
|
||
网址:www.mysql.com
|
||
|
||
------
|
||
|
||
#### YUM安装
|
||
|
||
安装:在BASE和EPEL仓库中没有Mysql的RPM包,但是有Mariadb的RPM包
|
||
|
||
```
|
||
1.准备Mysql的yum仓库:
|
||
yum -y install https://dev.mysql.com/get/mysql80-community-release-el7-11.noarch.rpm
|
||
2.修改安装版本,启用5.7版本
|
||
yum -y install yum-utils
|
||
yum-config-manager --disable mysql80-community
|
||
yum-config-manager --enable mysql57-community
|
||
3.安装
|
||
yum -y install mysql mysql-server
|
||
客户端:mysql-community-client
|
||
服务器端:mysql-community-server
|
||
|
||
初始化:
|
||
[root@mysql-rpm ~]# systemctl start mysqld
|
||
[root@mysql-rpm ~]# systemctl enable mysqld
|
||
修改密码:
|
||
cat /var/log/mysqld.log | grep password
|
||
[root@mysql-rpm ~]# mysqladmin -uroot -p'uEe0vMb#kRHY' password 'QianFeng@123'
|
||
[root@mysql-rpm ~]# mysql -uroot -pQianFeng@123
|
||
```
|
||
|
||
------
|
||
|
||
#### 编译安装
|
||
|
||
```
|
||
1.准备编译安装的环境
|
||
yum -y install ncurses ncurses-devel openssl-devel bison gcc gcc-c++ make cmake
|
||
2.获取编译安装包(wget)
|
||
[root@xingdian ~]# wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-boost-5.7.39.tar.gz
|
||
[root@xingdian ~]# tar xf mysql-boost-5.7.39.tar.gz
|
||
3.采用cmake的方式配置(指定安装目录 存放数据的目录 指定了端口号 指定了字符集等)
|
||
cd mysql-5.7.43/
|
||
vi 1.sh写入:
|
||
cmake . \
|
||
-DWITH_BOOST=boost/boost_1_59_0/ \
|
||
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
|
||
-DSYSCONFDIR=/etc \
|
||
-DMYSQL_DATADIR=/usr/local/mysql/data \
|
||
-DINSTALL_MANDIR=/usr/share/man \
|
||
-DMYSQL_TCP_PORT=3306 \
|
||
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock \
|
||
-DDEFAULT_CHARSET=utf8 \
|
||
-DEXTRA_CHARSETS=all \
|
||
-DDEFAULT_COLLATION=utf8_general_ci \
|
||
-DWITH_READLINE=1 \
|
||
-DWITH_SSL=system \
|
||
-DWITH_EMBEDDED_SERVER=1 \
|
||
-DENABLED_LOCAL_INFILE=1 \
|
||
-DWITH_INNOBASE_STORAGE_ENGINE=1
|
||
4.make进行编译
|
||
5.make install 进行安装
|
||
初始话:
|
||
1.准备用户和组
|
||
[root@xingdian ~]# groupadd mysql
|
||
[root@xingdian ~]# useradd -r -g mysql -s /bin/nolgin mysql
|
||
2.创建了所需要的目录 (在指定的目录下创建)
|
||
mkdir /usr/local/mysql/mysql-files
|
||
3.修改安装目录所有者和所属组
|
||
chown mysql.mysql /usr/local/mysql/ -R
|
||
4.进行指定用户指定安装目录指定数据存放目录的初始化操作,这一步可以获取到对应的初始密码
|
||
/usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
|
||
5.利用mysqld_safe的命令指定用户后台运行了mysql
|
||
/usr/local/mysql/bin/mysqld_safe --user=mysql &
|
||
排错:yum -y remove mariadb-libs
|
||
6.利用mysqladmin的命令修改了数据库的初始密码
|
||
./bin/mysqladmin -u root -p'#l5.i0suoijM' password 'Zhuwenbao@123'
|
||
7.登录测试 mysql的命令指定用户和密码
|
||
./bin/mysql -uroot -p 'Zhuwenbao@123'
|
||
```
|
||
|
||
------
|
||
|
||
###### 目录和文件
|
||
|
||
YUM 安装:
|
||
|
||
/etc/my.cnf:默认的数据库mysql的主配置文件
|
||
|
||
/var/lib/mysql/:用来存放数据的目录
|
||
|
||
/var/log/mysqld.log: mysql的错误日志文件
|
||
|
||
如果在数据库mysql没有运行的情况下,删除/var/lib/mysql这个目录下的内容,相当于是重置(恢复出厂设置)当在次启动的时候,数据全部被删除了,得到了新的初始密码
|
||
|
||
------
|
||
|
||
编译安装:
|
||
|
||
指定了安装目录和数据存放目录 /usr/local/mysql /usr/local/mysql/data
|
||
|
||
如果在数据库mysql没有运行的情况下,删除了/usr/local/mysql 安装目录,相当于卸载了mysql
|
||
|
||
如果在数据库mysql没有运行的情况下,删除了/usr/local/mysql/data 数据存放目录,相当于是重置了数据库
|
||
|
||
------
|
||
|
||
###### 编译安装扩展:
|
||
|
||
```
|
||
设置环境变量;可以直接使用mysql相关命令:
|
||
[root@xingdian ~]# echo "export PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
|
||
[root@xingdian ~]# source /etc/profile
|
||
|
||
设置开机启动,并用systemctl管理mysql服务:
|
||
[root@xingdian ~]# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
|
||
[root@xingdian ~]# chkconfig mysqld on //做开机启动
|
||
[root@xingdian ~]# systemctl start mysqld
|
||
[root@xingdian ~]# systemctl stop mysqld
|
||
```
|
||
|
||
------
|
||
|
||
#### 数据库引擎
|
||
|
||
数据库存储引擎是数据库底层软件组织,数据库管理系统(DBMS)使用数据引擎进行创建、查询、更新和删除数据。不同的存储引擎提供不同的存储机制、索引技巧、锁定水平等功能,使用不同的存储引擎,还可以 获得特定的功能。现在许多不同的数据库管理系统都支持多种不同的数据引擎。MySQL的核心就是存储引擎
|
||
|
||
------
|
||
|
||
##### InnoDB存储引擎
|
||
|
||
InnoDB是事务型数据库的首选引擎,支持事务安全表(ACID),支持行锁定和外键;InnoDB是默认的MySQL引擎
|
||
|
||
特点:
|
||
|
||
支持事务处理,支持外键,支持崩溃修复能力和并发控制。如果需要对事务的完整性要求比较高(比如银行),要求实现并发控制(比如售票),那选择InnoDB有很大的优势。如果需要频繁的更新、删除操作的数据库,也可以选择InnoDB,因为支持事务的提交和回滚
|
||
|
||
------
|
||
|
||
##### MyISAM存储引擎
|
||
|
||
MyISAM基于ISAM存储引擎,并对其进行扩展。它是在Web、数据仓储和其他应用环境下最常使用的存储引擎之一。MyISAM拥有较高的插入、查询速度,但不支持事务
|
||
|
||
特点:
|
||
|
||
插入数据快,空间和内存使用比较低。如果表主要是用于插入新记录和读出记录,那么选择MyISAM能实现处理高效率。如果应用的完整性、并发性要求比较低,也可以使用
|
||
|
||
------
|
||
|
||
##### MEMORY存储引擎
|
||
|
||
MEMORY存储引擎将表中的数据存储到内存中,为查询和引用其他表数据提供快速访问
|
||
|
||
特点:
|
||
|
||
所有的数据都在内存中,数据的处理速度快,但是安全性不高。如果需要很快的读写速度,对数据的安全性要求较低,可以选择MEMOEY。它对表的大小有要求,不能建立太大的表。所以,这类数据库只使用在相对较小的数据库表
|
||
|
||
------
|
||
|
||
##### 如何选择引擎
|
||
|
||
show engines;(查看)
|
||
|
||
如果要提供提交、回滚、崩溃恢复能力的事物安全(ACID兼容)能力,并要求实现并发控制,InnoDB是一个好的选择;
|
||
|
||
如果数据表主要用来插入和查询记录,则MyISAM引擎能提供较高的处理效率;如果只是临时存放数据,数据量不大,并且不需要较高的数据安全性,可以选择将数据保存在内存中的Memory引擎;MySQL中使用该引擎作为临时表,存放查询的中间结果;
|
||
|
||
如果只有INSERT和SELECT操作,可以选择Archive,Archive支持高并发的插入操作,但是本身不是事务安全的。Archive非常适合存储归档数据,如记录日志信息可以使用Archive。
|
||
使用哪一种引擎需要灵活选择,一个数据库中多个表可以使用不同引擎以满足各种性能和实际需求,使用合适的存储引擎,将会提高整个数据库的性能
|
||
|
||
------
|
||
|
||
#### mysql事务
|
||
|
||
**MySQL 事务主要用于处理操作量大,复杂度高的数据。**比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!
|
||
|
||
在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务
|
||
|
||
事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行
|
||
|
||
事务用来管理 insert,update,delete 语句
|
||
|
||
------
|
||
|
||
##### 满足事务条件
|
||
|
||
**原子性**:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样
|
||
|
||
**一致性**:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作
|
||
|
||
**隔离性**:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)
|
||
|
||
**持久性**:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失
|
||
|
||
------
|
||
|
||
## 第二章:数据库管理及数据类型
|
||
|
||
##### 一.数据类型
|
||
|
||
###### 1.数值类型
|
||
|
||
###### 2.整数类型
|
||
|
||
整数类型:TINYINT SMALLINT MEDIUMINT INT BIGINT
|
||
|
||
作用:用于存储用户的年龄、游戏的Level、经验值等
|
||
|
||
------
|
||
|
||
###### 3.浮点数类型
|
||
|
||
浮点数类型:FLOAT DOUBLE
|
||
|
||
作用:用于存储用户的身高、体重、薪水等
|
||
|
||
float(5,3) 5宽度 3精度
|
||
|
||
------
|
||
|
||
###### 4.定点数类型
|
||
|
||
定点数类型:DEC
|
||
|
||
定点数在MySQL内部以字符串形式存储,比浮点数更精确,适合用来表示货币等精度高的数据
|
||
|
||
###### 5.位类型
|
||
|
||
位类型:BIT
|
||
|
||
BIT(M)可以用来存放多位二进制数,M范围从1~64,如果不写默认为1位
|
||
|
||
------
|
||
|
||
##### 二.字符串类型
|
||
|
||
CHAR系列 CHAR VARCHAR
|
||
|
||
TEXT系列 TINYTEXT TEXT MEDIUMTEXT LONGTEXT
|
||
|
||
BLOB 系列 TINYBLOB BLOB MEDIUMBLOB LONGBLOB
|
||
|
||
BINARY系列 BINARY VARBINARY
|
||
|
||
------
|
||
|
||
###### 1.枚举类型
|
||
|
||
性别 男女
|
||
|
||
枚举类型:枚举列可以把一些不重复的字符串存储成一个预定义的集合
|
||
|
||
------
|
||
|
||
###### 2.时间和日期类型
|
||
|
||
时间和日期类型:DATE TIME DATETIME TIMESTAMP YEAR
|
||
|
||
作用:用于存储用户的注册时间,文章的发布时间,文章的更新时间,员工的入职时间等
|
||
|
||
扩展:select now();查看当前时间
|
||
|
||
------
|
||
|
||
#### 库操作
|
||
|
||
##### 相关命令
|
||
|
||
```
|
||
创建库:create database 库名
|
||
mysql> create database qianfeng;
|
||
mysql> create database diandian default character set utf8; 指定默认字符集
|
||
删除库:drop database 库名;
|
||
切换: 切换:use 库名;
|
||
查看:show databases;
|
||
```
|
||
|
||
------
|
||
|
||
#### 表操作
|
||
|
||
##### 相关命令
|
||
|
||
```
|
||
创建:
|
||
表名 字段(数据类型 [约束条件])[存储引擎 字符集]
|
||
create table t1(name varchar(20),id int(4),sex enum('m','f'),class varchar(50));
|
||
插入:
|
||
insert into 表名 values(字段和值);
|
||
可以同时插入多条数据
|
||
指定字段插入数据(字段的约束条件)
|
||
按照字段的顺序依次插入
|
||
删除:drop database 数据库名;
|
||
更新:update Update 表名 set 列名=值where 条件
|
||
mysql> update student set name='123' where id=1;
|
||
删除某一行:
|
||
delete from 表名 where id=1
|
||
mysql> delete from type where id=1;
|
||
查看:desc student1;
|
||
查询:select * from 表名
|
||
修改:alter
|
||
mysql> alter table t1 rename table1; //修改表名
|
||
mysql> alter table school.t2 rename school.table2;
|
||
```
|
||
|
||
------
|
||
|
||
##### 表修改
|
||
|
||
------
|
||
|
||
###### 1.修改数据库引擎
|
||
|
||
```shell
|
||
mysql> alter table service engine=innodb; //engine=myisam|memory|....
|
||
```
|
||
|
||
------
|
||
|
||
###### 2.添加字段
|
||
|
||
```shell
|
||
mysql> create table student10 (id int);
|
||
mysql> alter table student10 add name varchar(20) not null, add age int not null default 22;
|
||
|
||
mysql> alter table student10 add stu_num int not null after name; //添加name字段之后
|
||
|
||
mysql> alter table student10 add sex enum('male','female') default 'male' first; //添加到最前面
|
||
```
|
||
|
||
------
|
||
|
||
###### 3.删除字段
|
||
|
||
```shell
|
||
mysql> alter table student10 drop sex;
|
||
```
|
||
|
||
------
|
||
|
||
###### 4.修改字段类型
|
||
|
||
```shell
|
||
MySQL [school]> desc student10;
|
||
MySQL [school]> alter table student10 modify age tinyint not null ;
|
||
MySQL [school]> desc student10;
|
||
+-------+------------+------+-----+---------+-------+
|
||
| Field | Type | Null | Key | Default | Extra |
|
||
+-------+------------+------+-----+---------+-------+
|
||
| id | int(11) | YES | | NULL | |
|
||
| age | tinyint(4) | NO | | NULL | |
|
||
+-------+------------+------+-----+---------+-------+
|
||
MySQL [school]> alter table student10 modify id int not null primary key ; //修改字段类型、约束、主键
|
||
MySQL [school]> desc student10;
|
||
+-------+------------+------+-----+---------+-------+
|
||
| Field | Type | Null | Key | Default | Extra |
|
||
+-------+------------+------+-----+---------+-------+
|
||
| id | int(11) | NO | PRI | NULL | |
|
||
| age | tinyint(4) | NO | | NULL | |
|
||
+-------+------------+------+-----+---------+-------+
|
||
```
|
||
|
||
------
|
||
|
||
###### 5.增加约束
|
||
|
||
```shell
|
||
MySQL [school]> alter table student10 modify id int not null primary key ;
|
||
Query OK, 0 rows affected (0.02 sec)
|
||
Records: 0 Duplicates: 0 Warnings: 0
|
||
MySQL [school]> desc student10;
|
||
+-------+------------+------+-----+---------+-------+
|
||
| Field | Type | Null | Key | Default | Extra |
|
||
+-------+------------+------+-----+---------+-------+
|
||
| id | int(11) | NO | PRI | NULL | |
|
||
| age | tinyint(4) | NO | | NULL | |
|
||
+-------+------------+------+-----+---------+-------+
|
||
MySQL [school]> alter table student10 modify id int not null primary key auto_increment;
|
||
ERROR 1068 (42000): Multiple primary key defined //错误,该字段已经是primary key
|
||
MySQL [school]> alter table student10 modify id int not null auto_increment;
|
||
Query OK, 0 rows affected (0.04 sec)
|
||
Records: 0 Duplicates: 0 Warnings: 0
|
||
```
|
||
|
||
------
|
||
|
||
###### 6.增加主键
|
||
|
||
```shell
|
||
MySQL [school]> alter table student1 add primary key(id);
|
||
MySQL [school]> desc student1;
|
||
+-------+---------+------+-----+---------+-------+
|
||
| Field | Type | Null | Key | Default | Extra |
|
||
+-------+---------+------+-----+---------+-------+
|
||
| id | int(11) | NO | PRI | NULL | |
|
||
| age | int(11) | YES | | NULL | |
|
||
| name | char(1) | YES | | NULL | |
|
||
+-------+---------+------+-----+---------+-------+
|
||
```
|
||
|
||
------
|
||
|
||
###### 7.修改主键和自增
|
||
|
||
```shell
|
||
MySQL [school]> alter table student1 modify id int auto_increment;
|
||
Query OK, 0 rows affected (0.03 sec)
|
||
Records: 0 Duplicates: 0 Warnings: 0
|
||
|
||
MySQL [school]> desc student1;
|
||
+-------+---------+------+-----+---------+----------------+
|
||
| Field | Type | Null | Key | Default | Extra |
|
||
+-------+---------+------+-----+---------+----------------+
|
||
| id | int(11) | NO | PRI | NULL | auto_increment |
|
||
| age | int(11) | YES | | NULL | |
|
||
| name | char(1) | YES | | NULL | |
|
||
+-------+---------+------+-----+---------+----------------+
|
||
```
|
||
|
||
------
|
||
|
||
###### 8.删除主键
|
||
|
||
```shell
|
||
MySQL [school]> desc student10;
|
||
MySQL [school]> alter table student10 drop primary key;
|
||
ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key
|
||
删除自增
|
||
ySQL [school]> alter table student10 modify id int not null;
|
||
MySQL [school]> alter table student10 drop primary key;
|
||
```
|
||
|
||
------
|
||
|
||
###### 9.复制表
|
||
|
||
复制表结构+记录 (key不会复制: 主键、外键和索引)复制表结构/记录+表结构,不会将Key复制
|
||
|
||
```shell
|
||
mysql> create table new_service select * from service;
|
||
```
|
||
|
||
只复制表结构:
|
||
|
||
```shell
|
||
mysql> create table new1_service select * from service where 1=2; //条件为假,查不到任何记录
|
||
```
|
||
|
||
可以复制主键,只复制表结构:
|
||
|
||
```shell
|
||
mysql> create table t4 like employees;
|
||
```
|
||
|
||
------
|
||
|
||
###### 10.删除表
|
||
|
||
```shell
|
||
mysql> DROP TABLE 表名;
|
||
```
|
||
|
||
------
|
||
|
||
###### 11.修改数据表中字段的值
|
||
|
||
语法:Update 表名 set 列名=值where 条件
|
||
|
||
```shell
|
||
mysql> update student set name='123' where id=1;
|
||
```
|
||
|
||
删除某一行:delete from 表名 where id=1
|
||
|
||
```shell
|
||
mysql> delete from type where id=1;
|
||
```
|
||
|
||
------
|
||
|
||
## 第三章:数据库查询
|
||
|
||
### 一:基本查询
|
||
|
||
1.单表查询
|
||
|
||
2.简单查询
|
||
|
||
3.通过条件查询
|
||
|
||
4.查询排序
|
||
|
||
5.限制查询记录数
|
||
|
||
6.使用集合函数查询
|
||
|
||
7.分组查询
|
||
|
||
8.使用正则表达式查询
|
||
|
||
#### 2.查询案例
|
||
|
||
创建案例所需表:company.employee5
|
||
|
||
插入模拟数据:select 字段名称,字段名称2...... from 表名 [条件]
|
||
|
||
------
|
||
|
||
##### a.简单查询
|
||
|
||
```shell
|
||
MySQL [company]> select * from employee5;
|
||
|
||
MySQL [company]> select name, salary, dep_id from employee5 where id <=5;
|
||
+-------+---------+--------+
|
||
| name | salary | dep_id |
|
||
+-------+---------+--------+
|
||
| jack | 5000.00 | 100 |
|
||
| tom | 5500.00 | 100 |
|
||
| robin | 8000.00 | 100 |
|
||
| alice | 7200.00 | 100 |
|
||
| | 600.00 | 101 |
|
||
+-------+---------+--------+
|
||
5 rows in set (0.00 sec)
|
||
```
|
||
|
||
------
|
||
|
||
##### b.避免重复
|
||
|
||
不能部分使用DISTINCT,通常仅用于某一字段
|
||
|
||
```shell
|
||
MySQL [company]> SELECT post FROM employee5;
|
||
|
||
MySQL [company]> SELECT distinct post FROM employee5;
|
||
+------------+
|
||
| post |
|
||
+------------+
|
||
| instructor |
|
||
| hr |
|
||
| sale |
|
||
+------------+
|
||
```
|
||
|
||
------
|
||
|
||
##### c.四则运算查询
|
||
|
||
```shell
|
||
MySQL [company]> SELECT name, salary, salary*14 FROM employee5;
|
||
+-----------+----------+-----------+
|
||
| name | salary | salary*14 |
|
||
+-----------+----------+-----------+
|
||
| jack | 5000.00 | 70000.00 |
|
||
|
||
MySQL [company]> SELECT name, salary, salary*14 AS Annual_salary FROM employee5;(名字)
|
||
+-----------+----------+---------------+
|
||
| name | salary | Annual_salary |
|
||
+-----------+----------+---------------+
|
||
```
|
||
|
||
##### d.定义显示格式
|
||
|
||
CONCAT() 函数用于连接字符串
|
||
|
||
```shell
|
||
MySQL [company]> SELECT concat(name, 's annual salary: ', salary*14) AS Annual_salary FROM employee5;
|
||
+------------------------------------+
|
||
| Annual_salary |
|
||
+------------------------------------+
|
||
| jacks annual salary: 70000.00 |
|
||
```
|
||
|
||
------
|
||
|
||
##### e.单条件查询
|
||
|
||
```shell
|
||
MySQL [company]> SELECT name,post FROM employee5 WHERE post='hr';
|
||
+-------+------+
|
||
| name | post |
|
||
+-------+------+
|
||
| | hr |
|
||
| harry | hr |
|
||
+-------+------+
|
||
```
|
||
|
||
------
|
||
|
||
##### f.多条件查询
|
||
|
||
```shell
|
||
MySQL [company]> SELECT name,salary FROM employee5 WHERE post='hr' AND salary>10000;
|
||
Empty set (0.00 sec)
|
||
|
||
MySQL [company]> select * from employee5 where salary>5000 and salary<10000 or dep_id=102;
|
||
```
|
||
|
||
------
|
||
|
||
##### g.关键字
|
||
|
||
BETWEEN AND
|
||
|
||
```shell
|
||
MySQL [company]> SELECT name,salary FROM employee5 where salary BETWEEN 5000 AND 15000;
|
||
|
||
between .....and (之间)
|
||
MySQL [company]> SELECT name,salary FROM employee5 WHERE salary NOT BETWEEN 5000 AND 15000;
|
||
```
|
||
|
||
IS NULL
|
||
|
||
```shell
|
||
MySQL [company]> SELECT name,job_description FROM employee5 WHERE job_description IS NULL;
|
||
+--------+-----------------+
|
||
| name | job_description |
|
||
+--------+-----------------+
|
||
| harry | NULL |
|
||
| zhuzhu | NULL |
|
||
+--------+-----------------+
|
||
|
||
MySQL [company]> SELECT name,job_description FROM employee5 WHERE job_description IS NOT NULL;
|
||
|
||
MySQL [company]> SELECT name,job_description FROM employee5 WHERE job_description='';
|
||
+--------+-----------------+
|
||
| name | job_description |
|
||
+--------+-----------------+
|
||
| gougou | |
|
||
+--------+-----------------+
|
||
1 row in set (0.00 sec)
|
||
```
|
||
|
||
注意:(NULL说明)
|
||
|
||
等价于没有任何值、是未知数
|
||
|
||
NULL与0、空字符串、空格都不同,NULL没有分配存储空间
|
||
|
||
对空值做加、减、乘、除等运算操作,结果仍为空
|
||
|
||
比较时使用关键字用“is null”和“is not null”
|
||
|
||
排序时比其他数据都小(索引默认是降序排列,小→大),所以NULL值总是排在最前
|
||
|
||
IN集合查询
|
||
|
||
```shell
|
||
MySQL [company]> SELECT name, salary FROM employee5 WHERE salary=4000 OR salary=5000 OR salary=6000 OR salary=9000 ;
|
||
+-------+---------+
|
||
| name | salary |
|
||
+-------+---------+
|
||
| jack | 5000.00 |
|
||
| harry | 6000.00 |
|
||
+-------+---------+
|
||
|
||
MySQL [company]> SELECT name, salary FROM employee5 WHERE salary IN (4000,5000,6000,9000) ;
|
||
|
||
MySQL [company]> SELECT name, salary FROM employee5 WHERE salary NOT IN (4000,5000,6000,9000) ;
|
||
```
|
||
|
||
------
|
||
|
||
##### h.模糊查询
|
||
|
||
关键字LIKE
|
||
|
||
通配符%:所有字符
|
||
|
||
通配符_: 一个字符
|
||
|
||
```shell
|
||
MySQL [company]> SELECT * FROM employee5 WHERE name LIKE 'al%';
|
||
|
||
MySQL [company]> SELECT * FROM employee5 WHERE name LIKE 'al___';
|
||
```
|
||
|
||
------
|
||
|
||
##### i.排序查询
|
||
|
||
```shell
|
||
MySQL [company]> select name,salary from employee5 order by salary;(升序)
|
||
|
||
MySQL [company]> select name,salary from employee5 order by salary desc; (降序)
|
||
|
||
MySQL [company]> select name,salary from employee5 order by salary desc limit 3; //控制显示前3行
|
||
|
||
MySQL [company]> select name,salary from employee5 order by salary desc limit 1,3; //从序号1开始显示三行的内容
|
||
```
|
||
|
||
------
|
||
|
||
##### j.集合函数查询
|
||
|
||
count:可以查看共有多少条记录
|
||
|
||
```shell
|
||
MySQL [company]> select count(*) from employee5;
|
||
|
||
MySQL [company]> select count(name) from employee5;
|
||
|
||
```
|
||
|
||
max:查看最大值
|
||
|
||
```shell
|
||
MySQL [company]> select max(salary) from employee5;
|
||
```
|
||
|
||
min:查看最小值
|
||
|
||
```shell
|
||
MySQL [company]> select min(salary) from employee5;
|
||
```
|
||
|
||
avg:查看平均值
|
||
|
||
```shell
|
||
MySQL [company]> select avg(salary) from employee5;
|
||
```
|
||
|
||
sum:求和
|
||
|
||
sale这个部门的总工资
|
||
|
||
```shell
|
||
MySQL [company]> select concat("Total Department Wages:",sum(salary)) from employee5 where post='sale';
|
||
+-------------------------------------------------+
|
||
| concat("Total Department Wages:",sum(salary)) |
|
||
+-------------------------------------------------+
|
||
| Total Department Wages:26600.00 |
|
||
+-------------------------------------------------+
|
||
1 row in set (0.00 sec)
|
||
```
|
||
|
||
获取薪水最高的这个人的详细信息
|
||
|
||
```shell
|
||
MySQL [company]> select * from employee5 where salary = (select max(salary) from employee5);
|
||
```
|
||
|
||
------
|
||
|
||
##### k.分组查询
|
||
|
||
GROUP BY和GROUP_CONCAT()函数一起使用
|
||
|
||
获取部门ID相同的员工并把名字拼接到一起
|
||
|
||
```shell
|
||
MySQL [company]> SELECT dep_id,GROUP_CONCAT(name) FROM employee5 GROUP BY dep_id;
|
||
+--------+------------------------------+
|
||
| dep_id | GROUP_CONCAT(name) |
|
||
+--------+------------------------------+
|
||
| 100 | jack,tom,robin,alice |
|
||
| 101 | ,harry |
|
||
| 102 | emma,christine,zhuzhu,gougou |
|
||
+--------+------------------------------+
|
||
3 rows in set (0.01 sec)
|
||
```
|
||
|
||
GROUP BY和集合函数一起使用
|
||
|
||
获取部门最高薪资
|
||
|
||
```shell
|
||
MySQL [company]> SELECT post,max(salary) FROM employee5 GROUP BY post;
|
||
+------------+-------------+
|
||
| post | max(salary) |
|
||
+------------+-------------+
|
||
| hr | 6000.00 |
|
||
| instructor | 8000.00 |
|
||
| sale | 20000.00 |
|
||
+------------+-------------+
|
||
3 rows in set (0.00 sec)
|
||
```
|
||
|
||
------
|
||
|
||
##### l.正则查询
|
||
|
||
```shell
|
||
以什么开头
|
||
MySQL [company]> SELECT * FROM employee5 WHERE name REGEXP '^ali';
|
||
|
||
以什么结尾
|
||
MySQL [company]> SELECT * FROM employee5 WHERE name REGEXP 'ce$';
|
||
|
||
连续出现n次
|
||
MySQL [company]> SELECT * FROM employee5 WHERE name REGEXP 'm{2}';
|
||
```
|
||
|
||
------
|
||
|
||
### 二:多表联合查询【扩展了解】
|
||
|
||
#### 1.数据准备
|
||
|
||
###### 两张表
|
||
|
||
#### 2.多表连接查询
|
||
|
||
交叉连接:生成笛卡尔积,它不使用任何匹配条件;交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行组合
|
||
|
||
内连接:只连接匹配的行
|
||
|
||
外连接:
|
||
|
||
1.左连接:会显示左边表内所有的值,不论在右边表内匹不匹配
|
||
|
||
2.右连接:会显示右边表内所有的值,不论在左边表内匹不匹配
|
||
|
||
全外连接:包含左、右两个表的全部行
|
||
|
||
------
|
||
|
||
##### 交叉连接
|
||
|
||
```shell
|
||
MySQL [company]> select employee6.emp_name,employee6.age,employee6.dept_id,department6.dept_name from employee6,department6;
|
||
```
|
||
|
||
------
|
||
|
||
##### 内连接
|
||
|
||
获取有部门的员工 (部门表中没有natasha所在的部门)
|
||
|
||
```shell
|
||
MySQL [company]> select employee6.emp_name,employee6.age,employee6.dept_id,department6.dept_name from employee6,department6 where employee6.dept_id=department6.dept_id;
|
||
|
||
MySQL [company]> select employee6.emp_name,department6.dept_name from employee6 inner join department6 on
|
||
employee6.dept_id=department6.dept_id;
|
||
```
|
||
|
||
------
|
||
|
||
##### 外连接
|
||
|
||
语法:
|
||
|
||
SELECT 字段列表 FROM 表1 LEFT|RIGHT JOIN 表2 ON 表1.字段 = 表2.字段;
|
||
|
||
注意:
|
||
|
||
先用谁谁就是左
|
||
|
||
------
|
||
|
||
###### 左连接 left join
|
||
|
||
```shell
|
||
找出所有员工及所属的部门,包括没有部门的员工
|
||
MySQL [company]> select emp_id,emp_name,dept_name from employee6 left join department6 on employee6.dept_id = department6.dept_id;
|
||
```
|
||
|
||
------
|
||
|
||
###### 右连接right join
|
||
|
||
```
|
||
找出所有部门包含的员工,包括空部门
|
||
MySQL [company]> select emp_id,emp_name,dept_name from employee6 right join department6 on employee6.dept_id = department6.dept_id;
|
||
```
|
||
|
||
------
|
||
|
||
##### 全外连接
|
||
|
||
```shell
|
||
MySQL [company]> select * from employee6 full join department6;
|
||
```
|
||
|
||
------
|
||
|
||
#### 3.复合条件连接查询
|
||
|
||
------
|
||
|
||
##### 案例一
|
||
|
||
找出公司所有部门中年龄大于25岁的员工
|
||
|
||
以内连接的方式查询employee6和department6表,并且employee6表中的age字段值必须大于25
|
||
|
||
```shell
|
||
MySQL [company]> select emp_id,emp_name,dept_name FROM employee6,department6 WHERE employee6.dept_id = department6.dept_id AND age > 25;
|
||
```
|
||
|
||
------
|
||
|
||
##### 案例二
|
||
|
||
以内连接的方式查询employee6和department6表,并且以age字段的升序方式显示
|
||
|
||
```shell
|
||
MySQL [company]> select emp_id,emp_name,dept_name FROM employee6,department6 WHERE employee6.dept_id = department6.dept_id ORDER BY age asc;
|
||
```
|
||
|
||
------
|
||
|
||
#### 4.子查询
|
||
|
||
子查询是将一个查询语句嵌套在另一个查询语句中
|
||
|
||
内层查询语句的查询结果,可以为外层查询语句提供查询条件
|
||
|
||
子查询中可以包含:IN、NOT IN等关键字;还可以包含比较运算符:= 、 !=、> 、<等
|
||
|
||
------
|
||
|
||
##### 案例一
|
||
|
||
带IN关键字的子查询;查询employee表,但dept_id必须在department表中出现过
|
||
|
||
```shell
|
||
MySQL [company]> select * from employee6 WHERE dept_id IN (select dept_id FROM department6);
|
||
```
|
||
|
||
------
|
||
|
||
##### 案例二
|
||
|
||
带比较运算符的子查询;查询年龄大于等于25岁员工所在部门(查询老龄化的部门)
|
||
|
||
```
|
||
MySQL [company]> select dept_id,dept_name FROM department6 WHERE dept_id IN (SELECT DISTINCT dept_id FROM employee6 WHERE age >=25);
|
||
```
|
||
|
||
------
|
||
|
||
## 第四章:数据库日志管理
|
||
|
||
### 一:日志管理
|
||
|
||
<img src="https://xingdian-image.oss-cn-beijing.aliyuncs.com/xingdian-image/image-20220925214046253.png" alt="image-20220925214046253" style="zoom:50%;" />
|
||
|
||
------
|
||
|
||
#### 1.日志分类
|
||
|
||
错误日志 :启动,停止,关闭失败报错。rpm安装日志位置 /var/log/mysqld.log
|
||
|
||
通用查询日志:所有的查询都记下来
|
||
|
||
二进制日志:实现备份,增量备份。只记录改变数据,除了select都记
|
||
|
||
中继日志:读取主服务器的binlog,在本地回放。保持一致
|
||
|
||
slow log:慢查询日志,指导调优,定义某一个查询语句,定义超时时间,通过日志提供调优建议给开发人员
|
||
|
||
DDL log: 定义语句的日志
|
||
|
||
------
|
||
|
||
#### 2.Error Log
|
||
|
||
```shell
|
||
log-error=/var/log/mysqld.log
|
||
```
|
||
|
||
#### 3.Binary Log
|
||
|
||
```
|
||
vi /etc/my.cnf
|
||
log-bin=/var/log/mysql-bin/slave2
|
||
server-id=2
|
||
|
||
[root@slave2 ~]# mkdir /var/log/mysql-bin
|
||
[root@slave2 ~]# chown mysql.mysql /var/log/mysql-bin/
|
||
[root@slave2 ~]# systemctl restart mysqld
|
||
```
|
||
|
||
注意:需要提前开启
|
||
|
||
查看binlog日志:
|
||
|
||
```shel
|
||
[root@slave2 ~]# mysqlbinlog slave2-bin.000001 -v -base64-output=decode-rows
|
||
注:
|
||
1. 重启mysqld 会截断
|
||
2. flush logs 会截断
|
||
3. reset master 删除所有binlog
|
||
4. 删除部分
|
||
PURGE BINARY LOGS TO 'mysql-bin.010';
|
||
PURGE BINARY LOGS BEFORE '2019-04-02 22:46:26';
|
||
|
||
截取binlog
|
||
all:
|
||
# mysqlbinlog mysql.000002
|
||
```
|
||
|
||
------
|
||
|
||
#### 4.Slow Query Log
|
||
|
||
开启慢查询日志:
|
||
|
||
```shell
|
||
[root@xingdian ~]# vi /etc/my.cnf
|
||
slow_query_log=1
|
||
slow_query_log_file=/var/lib/mysql/slow.log
|
||
long_query_time=3 设置慢查询超时时间 单位是:秒
|
||
```
|
||
|
||
创建对应目录:
|
||
|
||
```shell
|
||
[root@xingdian ~]# mkdir /var/log/mysql-slow
|
||
[root@xingdian ~]# chown mysql.mysql mysql-slow
|
||
```
|
||
|
||
重启服务:
|
||
|
||
```shell
|
||
[root@xingdian ~]# systemctl restart mysqld
|
||
```
|
||
|
||
验证:mysql -uroot -pQianFeng@123
|
||
|
||
cat slow.log
|
||
|
||
------
|
||
|
||
## 第五章:权限管理及数据备份与恢复
|
||
|
||
------
|
||
|
||
### 一:权限管理
|
||
|
||
------
|
||
|
||
#### 1.权限级别
|
||
|
||
```
|
||
Global level:系统级,所有库,所有表的权限
|
||
Database level:某个数据库中的所有表的权限
|
||
Table level:库中的某个表的权限
|
||
Column level:表中的某个字段的权限
|
||
procs level:某个存储过程的权限
|
||
proxies level:代理服务器的权限
|
||
```
|
||
|
||
------
|
||
|
||
#### 2.查看权限记录表
|
||
|
||
因为超级管理员默认已经设置;所以直接查询权限即可
|
||
|
||
##### Global level(*)
|
||
|
||
```
|
||
mysql> select * from mysql.user\G
|
||
```
|
||
|
||
------
|
||
|
||
字段介绍:
|
||
|
||
```shell
|
||
用户字段:root
|
||
权限字段:Select_priv
|
||
安全字段:*B1DD4ADE47888D9AEC4D705C85230F1B52D2A817
|
||
Select_priv:查询权限
|
||
Insert_priv:插入权限
|
||
Update_priv:更新权限
|
||
Delete_priv:删除权限
|
||
```
|
||
|
||
------
|
||
|
||
##### Database level(*)
|
||
|
||
```shell
|
||
mysql> select * from mysql.db\G;
|
||
```
|
||
|
||
测试库权限:
|
||
|
||
```shell
|
||
mysql> create database t1;
|
||
Query OK, 1 row affected (0.00 sec)
|
||
|
||
mysql> grant all on t1.* to 't1'@'localhost' identified by 'QianFeng@123';
|
||
Query OK, 0 rows affected, 1 warning (0.00 sec)
|
||
|
||
|
||
查看:mysql> select * from mysql.db\G
|
||
验证:[root@xingdian ~]# mysql -u t1 -pQianFeng@123
|
||
```
|
||
|
||
------
|
||
|
||
##### Table level(*)
|
||
|
||
```shell
|
||
mysql> select * from mysql.tables_priv\G;
|
||
|
||
创建库表验证:
|
||
mysql> create database t2;
|
||
mysql> use t2;
|
||
mysql> insert into u1 values (1);
|
||
mysql> grant all on t2.u1 to 't2'@'localhost' identified by 'QianFeng@123';
|
||
mysql> create table u2(id int);
|
||
mysql> show tables;
|
||
|
||
|
||
权限查看:mysql> select * from mysql.tables_priv\G;
|
||
|
||
验证:(登录t2账户,看到u1表,看不到u2代表权限成功)
|
||
mysql -u t2 -pQianFeng@123
|
||
show databases;
|
||
use t2
|
||
show tables;
|
||
```
|
||
|
||
------
|
||
|
||
##### Column level
|
||
|
||
```shell
|
||
[root@xingdian ~]# mysql -uroot -pQianFeng@123
|
||
mysql> select * from mysql.columns_priv\G;
|
||
|
||
mysql> insert into mysql.columns_priv(host,db,user,table_name,column_name,column_priv) values('%','t2','t2','u1','id','select');
|
||
|
||
mysql> select * from mysql.columns_priv\G;
|
||
注意:前提是有库,有表,有权限
|
||
```
|
||
|
||
------
|
||
|
||
### 二:用户管理
|
||
|
||
#### 1.登录和退出
|
||
|
||
```shell
|
||
[root@xingdian ~]# mysql -h 192.168.18.160 -P 30042 -u root -pmysql -e "show databases;"
|
||
[root@xingdian ~]# mysql -h 192.168.18.160 -P 30042 -u root -pmysql mysql -e "show tables;"
|
||
|
||
-h 指定主机名 【默认为localhost】
|
||
-P MySQL服务器端口 【默认3306】
|
||
-u 指定用户名 【默认root】
|
||
-p 指定登录密码 【默认为空密码】
|
||
此处mysql为指定登录的数据库
|
||
-e 接SQL语句 (在脚本中使用)
|
||
|
||
```
|
||
|
||
------
|
||
|
||
#### 2.创建用户
|
||
|
||
方式一:
|
||
|
||
```shell
|
||
mysql> create user xingdian;
|
||
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
|
||
注意:该报错是因为密码强度问题,取消密码强度即可创建用户
|
||
|
||
mysql> create user xingdian@'%' identified by 'QianFeng@123';
|
||
Query OK, 0 rows affected (0.00 sec)
|
||
```
|
||
|
||
------
|
||
|
||
方式二:
|
||
|
||
```shell
|
||
mysql> grant all on *.* to 'diange'@'localhost' identified by 'QianFeng@123';
|
||
|
||
注意:该方式采用授权的方式 ALL所有权限 select单独某一个权限(多个权限用逗号隔开)
|
||
|
||
mysql> grant select on *.* to 'dianye'@'localhost' identified by 'QianFeng@123';
|
||
*.* :所有的库所有的表 也可以单独某一个库某一个表
|
||
```
|
||
|
||
```shell
|
||
xingdian@localhost 用户有则授权无则创建 localhost % 10.19.40.% 10.19.40.11
|
||
```
|
||
|
||
------
|
||
|
||
#### 3.删除用户
|
||
|
||
方式一:
|
||
|
||
```shell
|
||
MySQL [(none)]> Drop user xingdian@'%';
|
||
```
|
||
|
||
------
|
||
|
||
方法二:
|
||
|
||
```shell
|
||
MySQL [(none)]> delete from mysql.user where user='diandian' AND Host='%';
|
||
```
|
||
|
||
------
|
||
|
||
#### 4.修改密码
|
||
|
||
方式一:
|
||
|
||
```shell
|
||
[root@xingdian ~]# mysqladmin -uroot -p'123' password 'new_password' //123为旧密码
|
||
```
|
||
|
||
------
|
||
|
||
方式二:
|
||
|
||
```shell
|
||
MySQL [(none)]> update mysql.user set authentication_string=password(123456) where user='diange' And Host='%';
|
||
刷新授权表后生效:flush privileges
|
||
```
|
||
|
||
自己设置自己密码:
|
||
|
||
```shell
|
||
自己设置自己密码:
|
||
MySQL [(none)]> set password='123';
|
||
root用户修改其他用户密码:
|
||
方法一:
|
||
mysql> SET PASSWORD FOR user3@'localhost'='new_password';
|
||
方法二:
|
||
UPDATE mysql.user SET authentication_string=password('new_password') WHERE user='user3' AND host='localhost';
|
||
```
|
||
|
||
------
|
||
|
||
#### 5.查看密码策略
|
||
|
||
```shell
|
||
mysql> show variables like 'validate_password%'
|
||
参数解释:
|
||
validate_password_dictionary_file 指定密码验证的文件路径
|
||
validate_password_length 密码最小长度
|
||
validate_password_mixed_case_count 密码至少要包含的小写字母个数和大写字母个数
|
||
validate_password_number_count 密码至少要包含的数字个数
|
||
validate_password_policy 密码强度检查等级,对应等级为:0/LOW、1/MEDIUM、2/STRONG,默认为1
|
||
0/LOW:只检查长度
|
||
1/MEDIUM:检查长度、数字、大小写、特殊字符
|
||
2/STRONG:检查长度、数字、大小写、特殊字符字典文件
|
||
validate_password_special_char_count密码至少要包含的特殊字符数
|
||
|
||
修改密码策略:
|
||
set global validate_password_length=4;
|
||
|
||
关闭密码策略:(简单密码设置)
|
||
修改配置文件,添加以下参数:
|
||
vi /etc/my.cnf
|
||
添加:validate_password=off
|
||
```
|
||
|
||
------
|
||
|
||
### 三:数据备份及恢复
|
||
|
||
#### 1.概述
|
||
|
||
```
|
||
所有备份数据都应放在非数据库本地,而且建议有多份副本
|
||
|
||
备份: 能够防止由于机械故障以及人为误操作带来的数据丢失,例如将数据库文件保存在了其它地方
|
||
|
||
冗余: 数据有多份冗余,但不等备份,只能防止机械故障还来的数据丢失,例如主备模式、数据库集群
|
||
|
||
备份考虑的因素:数据的一致性,服务的可用性
|
||
|
||
分类:
|
||
逻辑备份:备份的是建表、建库、插入等操作所执行SQL语句;适用于中小型数据库,效率相对较低(mysqldump)
|
||
物理备份:直接复制数据库文件,适用于大型数据库环境,不受存储引擎的限制,但不能恢复到不同的MySQL版本(tar、xtrabackup)
|
||
|
||
|
||
```
|
||
|
||
------
|
||
|
||
#### 2.tar备份
|
||
|
||
注意:备份期间,服务不可用
|
||
|
||
备份过程:完全物理备份
|
||
|
||
```shell
|
||
停止数据库:
|
||
[root@xingdian ~]# systemctl stop mysqld
|
||
tar备份数据:
|
||
[root@xingdian ~]# mkdir /opt
|
||
[root@xingdian ~]# cd /var/lib/mysql
|
||
[root@xingdian ~]# tar -cf /opt/`date +%F`-mysql-all.tar.gz ./*
|
||
恢复过程:模拟数据丢失,恢复数据:
|
||
清理环境:rm -rf /var/lib/mysql/*
|
||
导入备份数据:
|
||
[root@xingdian ~]# tar -xf /opt/2019-08-20-mysql-all.tar.gz -C /var/lib/mysql
|
||
修改所属组所属主:
|
||
[root@xingdian ~]# chown mysql.mysql /var/lib/mysql/* -R
|
||
启动数据库(恢复后验证数据是否恢复成功):
|
||
[root@xingdian ~]# systemctl start mysqld
|
||
```
|
||
|
||
------
|
||
|
||
#### 3.xtrabackup备份
|
||
|
||
安装软件:
|
||
|
||
```shell
|
||
[root@xingdian ~]# yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm -y
|
||
[root@xingdian ~]# yum install percona-xtrabackup-24 -y
|
||
```
|
||
|
||
##### 完整备份
|
||
|
||
```shell
|
||
创建备份目录:
|
||
[root@xingdian ~]# mkdir -p /opt/full/
|
||
备份:
|
||
[root@xingdian ~]# innobackupex --user=root --password='Zhuwenbao@123' /opt/full/
|
||
查看备份数据:
|
||
[root@xingdian ~]# ls /opt/full/
|
||
2022-09-25_19-40-47
|
||
模拟增加数据
|
||
模拟数据丢失:
|
||
[root@xingdian ~]# systemctl stop mysqld
|
||
[root@xingdian ~]# rm -rf /var/lib/mysql/*
|
||
[root@xingdian ~]# rm -rf /var/log/mysqld.log
|
||
[root@xingdian ~]# rm -rf /var/log/mysql-slow/slow.log (有则删除,无则不需要操作)
|
||
恢复前的验证:
|
||
[root@xingdian ~]# innobackupex --apply-log /xtrabackup/full/2022-09-25_19-40-47/
|
||
恢复数据:
|
||
[root@xingdian ~]# innobackupex --copy-back /xtrabackup/full/2022-09-25_19-40-47/
|
||
修改权限:
|
||
[root@xingdian ~]# chown mysql.mysql /var/lib/mysql -R
|
||
启动服务:
|
||
[root@xingdian ~]# systemctl start mysqld
|
||
验证: mysql -u root -pZhuwenbao@123
|
||
```
|
||
|
||
------
|
||
|
||
##### 增量备份
|
||
|
||
原理:每次备份上一次备份到现在产生的新数据
|
||
|
||
注意:在进行增量备份前先进行完整备份
|
||
|
||
案例:周一进行全备,周二到周天进行增量备份
|
||
|
||
```shell
|
||
完整备份:(周一)
|
||
[root@xingdian ~]# innobackupex --user=root --password='Zhuwenbao@123' /opt/full
|
||
创建增量备份存放数据目录:
|
||
[root@xingdian ~]# mkdir /opt/zeng -p
|
||
模拟增加数据
|
||
第一次增量备份:(周二)
|
||
[root@xingdian ~]# innobackupex --user=root --password='Zhuwenbao@123' --incremental /opt/zeng/ --incremental-basedir=/opt/full/2022-09-25_19-40-47/
|
||
[root@xingdian ~]# ls /opt/zeng/
|
||
模拟增加数据
|
||
第二次增量备份:(周三)
|
||
[root@xingdian ~]# innobackupex --user=root --password='Zhuwenbao@123' --incremental /opt/zeng/ --incremental-basedir=/opt/zeng/2022-09-25_19-56-00/
|
||
[root@xingdian ~]# ls /opt/zeng/
|
||
模拟数据丢失
|
||
[root@xingdian ~]# systemctl stop mysqld
|
||
删除数据
|
||
[root@xingdian ~]# rm -rf /var/lib/mysql/*
|
||
[root@xingdian ~]# rm -rf /var/log/mysqld.log
|
||
|
||
|
||
依次重演回滚:(从前往后回滚)
|
||
全备回滚
|
||
[root@xingdian ~]# innobackupex --apply-log --redo-only /opt/full/2022-09-25_19-40-47/
|
||
|
||
第一次增量回滚:
|
||
[root@xingdian ~]# innobackupex --apply-log --redo-only /opt/full/2022-09-25_19-40-47/ --incremental-dir=/opt/zeng/2022-09-25_19-56-00/
|
||
|
||
第二次增量回滚:
|
||
[root@xingdian ~]# innobackupex --apply-log --redo-only /opt/full/2022-09-25_19-40-47/ --incremental-dir=/opt/zeng/2022-09-25_19-58-12/
|
||
恢复数据:
|
||
[root@xingdian ~]# innobackupex --copy-back /opt/full/2022-09-25_19-40-47/
|
||
修改权限:
|
||
chown mysql.mysql /var/lib/mysql -R
|
||
启动数据库
|
||
验证
|
||
```
|
||
|
||
------
|
||
|
||
##### 差异备份
|
||
|
||
原理:只备份跟完整备份不一样的
|
||
|
||
注意:在进行增量备份前先进行完整备份
|
||
|
||
案例:周一进行全备,周二到周天进行差异备份
|
||
|
||
```shell
|
||
完整备份:(周一)
|
||
[root@xingdian ~]# mkdir -p /opt/full
|
||
[root@xingdian ~]# mkdir -p /opt/jian
|
||
[root@xingdian ~]# innobackupex --user=root --password=QianFeng@123 /xtrabackup/full
|
||
模拟数据增加
|
||
第一次差异备份:(周二)
|
||
[root@xingdian ~]# innobackupex --user=root --password=Zhuwenbao@123 --incremental /opt/jian --incremental-basedir=/opt/full/2022-09-25_20-10-52/
|
||
模拟数据增加
|
||
第二次差异备份:(周三)
|
||
[root@xingdian ~]# innobackupex --user=root --password=Zhuwenbao@123 --incremental /opt/jian --incremental-basedir=/opt/full/2022-09-25_20-10-52/
|
||
模拟数据丢失
|
||
停止数据库
|
||
删除数据:
|
||
[root@xingdian ~]# rm -rf /var/lib/mysql/*
|
||
[root@xingdian ~]# rm -rf /var/log/mysqld.log
|
||
|
||
|
||
|
||
数据回滚:
|
||
完整备份回滚:
|
||
[root@xingdian ~]# innobackupex --apply-log --redo-only /opt/full/2022-09-25_20-10-52/
|
||
|
||
差异备份回滚(根据差异备份的原理,如果恢复所有数据只需要将最后依次差异回滚)
|
||
[root@xingdian ~]# innobackupex --apply-log --redo-only /opt/full/2022-09-25_20-10-52/ --incremental-dir=/opt/jian/2022-09-25_20-14-32/(最后一次差异备份数据)
|
||
恢复数据:
|
||
[root@xingdian ~]# innobackupex --copy-back /opt/full/2022-09-25_20-10-52/
|
||
修改权限
|
||
启动数据库
|
||
验证
|
||
```
|
||
|
||
------
|
||
|
||
#### 4.mysqldump备份
|
||
|
||
```shell
|
||
备份表:(前提有库有表)
|
||
[root@xingdian ~]# mysqldump -u root -pQianFeng@123 k1 t1 > /t1.sql
|
||
恢复表:(恢复之前模拟数据丢失)
|
||
[root@xingdian ~]# mysql -u root -pQianFeng@123 k1 < /t1.sql
|
||
验证
|
||
```
|
||
|
||
------
|
||
|
||
备份一个库:
|
||
|
||
```shell
|
||
[root@xingdian ~]# mysqldump -u root -pQianFeng@123 k1 > /k1.sql
|
||
```
|
||
|
||
------
|
||
|
||
备份多个库:
|
||
|
||
```shell
|
||
[root@xingdian ~]# mysqldump -u root -pQianFeng@123 -B k1 k2 > /kall.sql
|
||
```
|
||
|
||
------
|
||
|
||
备份所有库:
|
||
|
||
```shell
|
||
[root@xingdian ~]# mysqldump -u root -pQianFeng@123 -A > /all.sql
|
||
```
|
||
|
||
------
|
||
|
||
数据恢复:
|
||
|
||
为保证数据一致性,应在恢复数据之前停止数据库对外的服务,停止binlog日志
|
||
|
||
binlog使用binlog日志恢复数据时也会产生binlog日志(如果开启的话,需要关闭)
|
||
|
||
```shell
|
||
mysql> set sql_log_bin=0;
|
||
```
|
||
|
||
模拟数据丢失(略)
|
||
|
||
```shell
|
||
[root@xingdian ~]# mysql -u root -pQianFeng@123 -D k1 < /k1.sql
|
||
mysql: [Warning] Using a password on the command line interface can be insecure.
|
||
ERROR 1049 (42000): Unknown database 'k1'
|
||
出现该错误是因为在恢复的时候需要有库的存在
|
||
|
||
[root@xingdian ~]# mysql -u root -pQianFeng@123 -e "create database k1"
|
||
[root@xingdian ~]# mysql -u root -pQianFeng@123 -D k1 < /k1.sql
|
||
|
||
[root@xingdian ~]# mysql -u root -pQianFeng@123 -e "create database k1"
|
||
[root@xingdian ~]# mysql -u root -pQianFeng@123 -e "create database k2"
|
||
[root@xingdian ~]# mysql -u root -pQianFeng@123 -D k1 k2 < /kall.sql
|
||
|
||
或者
|
||
mysql> source /k1.sql
|
||
```
|
||
|
||
------
|
||
|
||
#### 5.binlog日志备份
|
||
|
||
原理:日志方法备份恢复数据
|
||
|
||
日志默认存储位置: /var/lib/mysql
|
||
|
||
rpm安装(永久)
|
||
|
||
```shell
|
||
[root@xingdian ~]# vim /etc/my.cnf
|
||
log-bin=mylog
|
||
server-id=1 //做主从复制使用
|
||
|
||
[root@xingdian ~]# systemctl restart mysqld
|
||
|
||
查看:[root@xingdian ~]# ls /var/lib/mysql
|
||
方法一:
|
||
[root@xingdian ~]# mysqlbinlog /var/lib/mysql/mylog.000001 -v --base64-output=decode-rows
|
||
方法二:
|
||
mysql> show binlog events in "mylog.000001";
|
||
默认查看第一个
|
||
mysql> show binlog events;
|
||
```
|
||
|
||
------
|
||
|
||
数据恢复:
|
||
|
||
根据时间点恢复数据:
|
||
|
||
```shell
|
||
[root@xingdian ~]# mysqlbinlog --start-datetime='2022-9-25 21:12:47' --stop-datetime='2022-9-25 21:16:55' /var/lib/mysql/mylog.000001 | mysql -u root -pQianFeng@123
|
||
```
|
||
|
||
根据位置点恢复数据:
|
||
|
||
```
|
||
mysql> show binlog events;(查看位置点)
|
||
[root@xingdian ~]# mysqlbinlog --start-position 219 --stop-position 307 /var/lib/mysql/mylog.000001 | mysql -u root -pQianFeng@123shell
|
||
```
|
||
|
||
------
|
||
|
||
## 第六章:主从复制
|
||
|
||
### 一:主从复制
|
||
|
||
#### 1.主从复制概念
|
||
|
||
```
|
||
什么是主从复制:
|
||
主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库;主数据库一般是准实时的业务数据库
|
||
主从复制的作用:
|
||
做数据的热备,作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失
|
||
架构的扩展,业务量越来越大,I/O访问频率过高,单机无法满足,多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能,读写分离,使数据库能支撑更大的并发
|
||
|
||
主从复制的原理:
|
||
数据库有个bin-log二进制文件,记录了所有sql语句,我们的目标就是把主数据库的bin-log文件的sql语句复制到从库,让其在从数据的relay-log(中继日志)重做日志文件中再执行一次这些sql语句即可
|
||
总结:
|
||
从库slave生成两个线程,i/o线程和sql线程,i/o将变更记录写到二进制日志文件中,再写到中继日志中,sql线程读取中继日志,解析操作,最终数据统一
|
||
注意:
|
||
I/O进程:负责通信
|
||
SQL进程:负责写数据,根据log日志写数据
|
||
```
|
||
|
||
------
|
||
|
||
#### 2.主从复制部署
|
||
|
||
##### 环境准备
|
||
|
||
```
|
||
注意:
|
||
所有节点关闭防火墙和selinux
|
||
保证yum仓库可用
|
||
保证网络畅通
|
||
如果是克隆的服务器需要修改每台数据库的server-uuid修改主机名:
|
||
修改主机名:
|
||
添加本地解析:vi /etc/hosts
|
||
```
|
||
|
||
------
|
||
|
||
##### Master部署
|
||
|
||
```
|
||
安装数据库: 重置MySQL:
|
||
启动数据库: systemctl stop mysql
|
||
修改数据库初始密码 rm -rf /var/lib/mysql/*
|
||
主服务器部署: systemctl start mysql
|
||
[root@master ~]# vi /etc/my.cnf
|
||
log-bin = my1log
|
||
server-id = 1
|
||
创建授权账户:
|
||
mysql -u root -pQianFeng@123
|
||
grant all on *.* to 'slave'@'%' identified by 'QianFeng@123';
|
||
flush privileges;
|
||
重启服务:
|
||
[root@master ~]# systemctl restart mysqld
|
||
|
||
```
|
||
|
||
##### Slave部署
|
||
|
||
```
|
||
安装数据库
|
||
启动数据库
|
||
修改数据库初始密码
|
||
[root@slave ~]# vi /etc/my.cnf
|
||
log-bin = my2log
|
||
server-id = 2
|
||
重启服务:
|
||
[root@slave ~]# systemctl restart mysqld
|
||
获取主服务器信息:(主服务器操作)
|
||
[root@master ~]# mysql -u root -pQianFeng@123
|
||
show binlog events;
|
||
指定主服务器信息:(从服务器操作)
|
||
[root@slave ~]# mysql -u root -pQianFeng@123
|
||
edit添加
|
||
CHANGE MASTER TO
|
||
MASTER_HOST='master',
|
||
MASTER_USER='slave',
|
||
MASTER_PASSWORD='QianFeng@123',
|
||
MASTER_PORT=3306,
|
||
MASTER_LOG_FILE='my1log.000001',
|
||
MASTER_LOG_POS=4,
|
||
MASTER_CONNECT_RETRY=10;
|
||
获取参数:
|
||
mysql> help change master to
|
||
start slave;
|
||
show slave status\G
|
||
验证:主服务器创建数据,从服务器可以看到代表成功
|
||
```
|
||
|
||
```
|
||
注意:
|
||
stop slave;停止slave
|
||
reset master;删除所有的binglog日志文件,并将日志索引文件清空,重新开始所有新的日志文件;用于第一次进行搭建主从库时,进行主库binlog初始化工作
|
||
reset slave;用于删除SLAVE数据库的relaylog日志文件,并重新启用新的relaylog文件
|
||
```
|
||
|
||
------
|
||
|
||
### 二:GTID主从复制
|
||
|
||
#### 1.GTID概念
|
||
|
||
|
||
|
||
```
|
||
GTID基于事务ID复制
|
||
GTID全局事务标识(global transaction identifiers)
|
||
是用来代替传统复制的方法,GTID复制与普通复制模式的最大不同就是不需要指定二进制文件名和位置
|
||
不再使用MASTER_LOG_FILE+MASTER_LOG_POS开启复制。而是使用MASTER_AUTO_POSTION=1的方式开始复制
|
||
```
|
||
|
||
------
|
||
|
||
#### 2.GTID组成
|
||
|
||
|
||
|
||
```
|
||
GTID = source_id:transaction_id
|
||
source_id源id,用于鉴别原服务器,即mysql服务器唯一的server_uuid,由于GTID会传递到slave,所以也可以理解为源ID
|
||
transaction_id事务id,为当前服务器上已提交事务的一个序列号,通常从1开始自增长的序列,一个数值对应一个事务
|
||
示例:
|
||
3E11FA47-71CA-11E1-9E33-C80AA9429562:23
|
||
前面的一串为服务器的server_uuid
|
||
后面的23为transaction_id
|
||
```
|
||
|
||
------
|
||
|
||
#### 3.GTID工作原理
|
||
|
||
```
|
||
master更新数据时,会在事务前产生GTID,一同记录到binlog日志中
|
||
slave端的i/o 线程将变更的binlog,写入到本地的relay log中
|
||
sql线程从relay log中获取GTID,然后对比slave端的binlog是否有记录
|
||
如果有记录,说明该GTID的事务已经执行,slave会忽略
|
||
如果没有记录,slave就会从relay log中执行该GTID的事务,并记录到binlog
|
||
```
|
||
|
||
------
|
||
|
||
#### 4.主从部署
|
||
|
||
##### Master部署
|
||
|
||
|
||
|
||
```shell
|
||
主服务器部署:
|
||
[root@master ~]# vim /etc/my.cnf
|
||
log-bin
|
||
server-id=1
|
||
gtid_mode = ON
|
||
enforce_gtid_consistency=1
|
||
创建授权用户:
|
||
mysql -u root -pQianFeng@123
|
||
grant all on *.* to slave@'%' identified by 'QianFeng@123';
|
||
flush privileges;
|
||
重启服务:
|
||
[root@master ~]# systemctl restart mysqld
|
||
```
|
||
|
||
##### Slave部署
|
||
|
||
```shell
|
||
[root@slave ~]# vim /etc/my.cnf
|
||
log-bin
|
||
server-id=2
|
||
gtid_mode = ON
|
||
enforce_gtid_consistency=1
|
||
relay_log_recovery = on
|
||
master-info-repository=TABLE
|
||
relay-log-info-repository=TABLE
|
||
//这两个参数会将master.info和relay.info保存在表中,默认是Myisam引擎,官方建议用
|
||
重启服务:
|
||
[root@slave ~]# systemctl restart mysqld
|
||
配置连接主服务器:
|
||
mysql -u root -pQianFeng@123
|
||
mysql> change master to
|
||
-> master_host='master',
|
||
-> master_user='slave',
|
||
-> master_password='QianFeng@123',
|
||
-> master_auto_position=1;
|
||
启动Slave:
|
||
mysql> start slave;
|
||
mysql> show slave status\G
|
||
验证:主服务器创建数据,从服务器可以看到代表成功
|
||
```
|
||
|
||
------
|
||
|
||
### 三:GTID双主双从
|
||
|
||
#### Master-1部署
|
||
|
||
```shell
|
||
主服务器一部署:
|
||
[root@master-1 ~]# vim /etc/my.cnf
|
||
log-bin = my1log
|
||
server-id = 1
|
||
gtid_mode=ON
|
||
enforce_gtid_consistency=1
|
||
创建授权账户:
|
||
[root@master-1 ~]# mysql -u root -pQianFeng@123
|
||
grant all on *.* to 'slave'@'%' identified by 'QianFeng@123';
|
||
flush privileges;
|
||
重启服务:
|
||
[root@master-1 ~]# systemctl restart mysqld
|
||
```
|
||
|
||
------
|
||
|
||
#### Master-2部署
|
||
|
||
```shell
|
||
主服务器二部署:
|
||
[root@master-2 ~]# vim /etc/my.cnf
|
||
log-bin = my2log
|
||
server-id = 2
|
||
gtid_mode=ON
|
||
enforce_gtid_consistency=1
|
||
创建授权账户:
|
||
[root@master-1 ~]# mysql -u root -pQianFeng@123
|
||
grant all on *.* to 'slave'@'%' identified by 'QianFeng@123';
|
||
flush privileges;
|
||
重启服务:
|
||
[root@master-1 ~]# systemctl restart mysqld
|
||
```
|
||
|
||
------
|
||
|
||
#### 双主互为主从
|
||
|
||
```shell
|
||
Master-1:
|
||
[root@master-1 ~]# mysql -u root -pQianFeng@123
|
||
mysql> change master to
|
||
-> master_host='master-2',
|
||
-> master_user='slave',
|
||
-> master_password='QianFeng@123',
|
||
-> master_auto_position=1;
|
||
mysql> start slave;
|
||
mysql> show slave status\G
|
||
```
|
||
|
||
```shell
|
||
Master-2:
|
||
[root@master-2 ~]# mysql -u root -pQianFeng@123
|
||
mysql> change master to
|
||
-> master_host='master-1',
|
||
-> master_user='slave',
|
||
-> master_password='QianFeng@123',
|
||
-> master_auto_position=1;
|
||
mysql> start slave;
|
||
mysql> show slave status\G
|
||
```
|
||
|
||
------
|
||
|
||
#### Slave-1部署
|
||
|
||
从服务器一部署:
|
||
|
||
```shell
|
||
从服务器一部署:
|
||
[root@slave-1 ~]# vim /etc/my.cnf
|
||
log-bin = my3log
|
||
server-id = 3
|
||
gtid_mode=ON
|
||
enforce_gtid_consistency=1
|
||
relay_log_info_repository = TABLE
|
||
master_info_repository = TABLE
|
||
relay_log_recovery = on
|
||
重启服务:
|
||
[root@slave-1 ~]# systemctl restart mysqld
|
||
从连接主服务器:
|
||
mysql -u root -pQianFeng@123
|
||
mysql> CHANGE MASTER TO
|
||
-> MASTER_HOST='master-1',
|
||
-> MASTER_USER='slave',
|
||
-> MASTER_PASSWORD='QianFeng@123',
|
||
-> MASTER_AUTO_POSITION=1 FOR CHANNEL 'master-1';
|
||
mysql> start slave;
|
||
show slave status\G
|
||
mysql> CHANGE MASTER TO
|
||
-> MASTER_HOST='master-2',
|
||
-> MASTER_USER='slave',
|
||
-> MASTER_PASSWORD='QianFeng@123',
|
||
-> MASTER_AUTO_POSITION=1 FOR CHANNEL 'master-2';
|
||
mysql> start slave;
|
||
show slave status\G
|
||
```
|
||
|
||
------
|
||
|
||
#### Slave-2部署
|
||
|
||
```shell
|
||
从服务器二部署:
|
||
[root@slave-2 ~]# vim /etc/my.cnf
|
||
log-bin = my4log
|
||
server-id = 4
|
||
gtid_mode=ON
|
||
enforce_gtid_consistency=1
|
||
relay_log_info_repository = TABLE
|
||
master_info_repository = TABLE
|
||
relay_log_recovery = on
|
||
重启服务:
|
||
[root@slave-2 ~]# systemctl restart mysqld
|
||
从连接主服务器:
|
||
与Slave-1部署一样,无变化
|
||
|
||
验证:两个主服务器创建数据,别的三台都能看到代表成功
|
||
```
|
||
|
||
------
|
||
|
||
## 第七章:读写分离
|
||
|
||
### 一:读写分离部署
|
||
|
||
#### 1.环境介绍
|
||
|
||

|
||
|
||
------
|
||
|
||
#### 2.读写分离集群部署
|
||
|
||
##### A:数据库集群部署(略)
|
||
|
||
单主单从;多主多从等均可
|
||
|
||
##### B:Mycat部署
|
||
|
||
```shell
|
||
新机器,不需要安装mysql
|
||
安装jdk环境:
|
||
[root@mycat ~]# tar xf jdk-8u211-linux-x64.tar.gz -C /usr/local/
|
||
[root@mycat ~]# mv /usr/local/jdk1.8.0_211/ /usr/local/java
|
||
设置环境变量:
|
||
[root@mycat ~]# vi /etc/profile
|
||
JAVA_HOME=/usr/local/java
|
||
PATH=$JAVA_HOME/bin:$PATH
|
||
export JAVA_HOME PATH
|
||
[root@mycat ~]# source /etc/profile
|
||
[root@mycat ~]# java -version
|
||
安装mycat:
|
||
[root@mycat ~]# tar xf Mycat-server-1.6.7.1-release-20190627191042-linux.tar.gz -C /usr/local/
|
||
设置环境变量:
|
||
[root@mycat ~]# vi ~/.bash_profile
|
||
PATH=$PATH:$HOME/bin:/usr/local/mycat/bin
|
||
[root@mycat ~]# source ~/.bash_profile
|
||
```
|
||
|
||
------
|
||
|
||
##### C:数据库部署
|
||
|
||
Mysql中添加数据库和账户:
|
||
|
||
```shell
|
||
Mysql中添加数据库和账户:
|
||
[root@master-1 ~]# mysql -u root -pQianFeng@123
|
||
mysql> grant all on bbs.* to bbs@'%' identified by 'QianFeng@123';
|
||
```
|
||
|
||
```
|
||
注意:
|
||
创建的库跟mycat关联,原则上一个库对应一个项目,根据实际情况创建
|
||
|
||
创建的库需要单独授权用户进行管理,用户名和库名根据实际情况决定
|
||
```
|
||
|
||
------
|
||
|
||
##### D:Mycat配置
|
||
|
||
server.xml:Mycat的配置文件,设置账号、参数等
|
||
|
||
```shell
|
||
[root@mycat conf]# vim server.xml 修改
|
||
|
||
schema.xml:Mycat对应的物理数据库和数据库表的配置
|
||
[root@mycat conf]# cat schema.xml
|
||
```
|
||
|
||
------
|
||
|
||
注意:
|
||
|
||
```shell
|
||
user 用户配置节点
|
||
–name 登录的用户名,也就是连接Mycat的用户名
|
||
–password 登录的密码,也就是连接Mycat的密码
|
||
–schemas 数据库名,这里会和schema.xml中的配置关联,多个用逗号分开,例如需要这个用户需要管理两个数据库db1,db2,则配置db1,db2
|
||
```
|
||
|
||
------
|
||
|
||
注意:
|
||
|
||
```shell
|
||
balance=1 开启读写分离机制,所有读操作都发送到当前备用的 writeHost 上。
|
||
wirteType=0 所有写操作发送到第一个writeHost,第一个挂了切换到第二个
|
||
switchType=3 基于MySQL Galera cluster的切换机制,心跳语句为show status like 'wsrep%'
|
||
```
|
||
|
||
------
|
||
|
||
##### E:启动服务
|
||
|
||
```shell
|
||
[root@mycat conf]# mycat start
|
||
Starting Mycat-server...
|
||
[root@mycat conf]# jps
|
||
1494 WrapperSimpleApp
|
||
1528 Jps
|
||
查看端口:[root@mycat conf]# ss -antpl 8066端口
|
||
客户端测试: mysql -u shop -p123456 -P 8066 -h 10.0.0.47
|
||
从服务数据验证:
|
||
```
|
||
|
||
------
|
||
|
||
#### 3.Mycat配置文件
|
||
|
||
##### server.xml
|
||
|
||
```shell
|
||
一:server.xml 配置文件
|
||
1.privileges标签
|
||
对用户的 schema以及表进行精细化的DML(数据操纵语言)权限控制
|
||
<privileges check="false"> </privileges> --check 表示是否开启DML权限检查。默认是关闭。
|
||
--dml 顺序说明:insert,update,select,delete
|
||
<schema name="db1" dml="0110" >
|
||
<table name="tb01" dml="0000"></table>
|
||
<table name="tb02" dml="1111"></table> </schema>
|
||
db1的权限是update,select。
|
||
tb01的权限是啥都不能干。
|
||
tb02的权限是insert,update,select,delete。
|
||
其他表默认是udpate,select。
|
||
|
||
2.system标签
|
||
这个标签内嵌套的所有 property 标签都与系统配置有关。
|
||
<property name="charset">utf8</property>
|
||
字符集
|
||
<property name="processors">1</property>
|
||
处理线程数量,默认是cpu数量。
|
||
<property name="processorBufferChunk">4096</property>
|
||
每次读取留的数量,默认4096。
|
||
<property name="processorBufferPool">409600</property>
|
||
创建共享buffer需要占用的总空间大小。processorBufferChunk*processors*100。
|
||
<property name="processorBufferPoolType">0</property>
|
||
默认为0。0表示DirectByteBufferPool,1表示ByteBufferArena。
|
||
<property name="processorBufferLocalPercent">100</property>
|
||
二级共享buffer是processorBufferPool的百分比,这里设置的是百分比。
|
||
<property name="sequnceHandlerType">100</property>
|
||
全局ID生成方式。(0:为本地文件方式,1:为数据库方式;2:为时间戳序列方式;3:为ZK生成ID;4:为ZK递增ID生成。
|
||
<property name="useCompression">1</property>
|
||
是否开启mysql压缩协议。1为开启,0为关闭,默认关闭。
|
||
<property name="packetHeaderSize">4</property>
|
||
指定 Mysql 协议中的报文头长度。默认 4。
|
||
<property name="maxPacketSize">16M</property>
|
||
指定 Mysql 协议可以携带的数据最大长度。默认 16M。
|
||
<property name="idleTimeout">1800000</property>
|
||
指定连接的空闲超时时间。某连接在发起空闲检查下,发现距离上次使用超过了空闲时间,那么这个连接会被回收,就是被直接的关闭掉。默认 30 分钟,单位毫秒。
|
||
<property name="txIsolation">3</property>
|
||
前端连接的初始化事务隔离级别,只在初始化的时候使用,后续会根据客户端传递过来的属性对后端数据库连接进行同步。默认为 REPEATED_READ,设置值为数字默认 3。
|
||
READ_UNCOMMITTED = 1;
|
||
READ_COMMITTED = 2;
|
||
REPEATED_READ = 3;
|
||
SERIALIZABLE = 4;
|
||
<property name="sqlExecuteTimeout">300</property>
|
||
SQL 执行超时的时间,Mycat 会检查连接上最后一次执行 SQL 的时间,若超过这个时间则会直接关闭这连接。默认时间为 300 秒,单位秒。
|
||
<property name="processorCheckPeriod">1000</property>
|
||
清理 NIOProcessor 上前后端空闲、超时和关闭连接的间隔时间。默认是 1 秒,单
|
||
位毫秒。
|
||
<property name="dataNodeIdleCheckPeriod">300000</property>
|
||
对后端连接进行空闲、超时检查的时间间隔,默认是 300 秒,单位毫秒。
|
||
<property name="dataNodeHeartbeatPeriod">10000</property>
|
||
对后端所有读、写库发起心跳的间隔时间,默认是 10 秒,单位毫秒。
|
||
<property name="bindIp">0.0.0.0</property>
|
||
mycat 服务监听的 IP 地址,默认值为 0.0.0.0。
|
||
<property name="serverPort">8066</property>
|
||
定义 mycat 的使用端口,默认值为 8066。
|
||
<property name="managerPort">9066</property>
|
||
定义 mycat 的管理端口,默认值为 9066。
|
||
<property name="fakeMySQLVersion">5.6</property>
|
||
mycat 模拟的 mysql 版本号,默认值为 5.6 版本,如非特需,不要修改这个值,目前支持设置 5.5,5.6,5.7 版本,其他版本可能会有问题。
|
||
<property name="useSqlStat">0</property>
|
||
是否开启实时统计。1为开启;0为关闭 。
|
||
<property name="useGlobleTableCheck">0</property>
|
||
是否开启全局表一致性检测。1为开启;0为关闭 。
|
||
<property name="handleDistributedTransactions">0</property>
|
||
分布式事务开关。0为不过滤分布式事务;1为过滤分布式事务;2 为不过滤分布式事务,但是记录分布式事务日志。
|
||
<property name="maxStringLiteralLength">65535</property>
|
||
默认是65535。 64K 用于sql解析时最大文本长度
|
||
以上举例的属性仅仅是一部分,可以配置的变量很多。
|
||
System标签下的属性,一般是上线后,需要根据实际运行的情况,分析后调优的时候进行修改。
|
||
|
||
3. Firewall标签
|
||
防火墙的设置,也就是在网络层对请求的地址进行限制,主要是从安全角度来保证Mycat不被匿名IP进行访问
|
||
<firewall>
|
||
<whitehost>
|
||
<host host="127.0.0.1" user="mycat"/>
|
||
<host host="127.0.0.2" user="mycat"/>
|
||
</whitehost>
|
||
<blacklist check="false">
|
||
</blacklist>
|
||
</firewall>
|
||
```
|
||
|
||
##### schema.xml
|
||
|
||
```shell
|
||
一:schema.xml
|
||
–schema 数据库设置,此数据库为逻辑数据库,name与server.xml中schema对应
|
||
–dataNode 分片信息,也就是分库相关配置
|
||
–dataHost 物理数据库,真正存储数据的数据库
|
||
|
||
1、schema 标签
|
||
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="10"> </schema>
|
||
schema标签用来定义mycat实例中的逻辑库,mycat可以有多个逻辑库,每个逻辑库都有自己的相关配置。可以使用schema标签来划分这些不同的逻辑库,如果不配置schema标签,所有表的配置会属于同一个默认的逻辑库。逻辑库的概念和MySql的database的概念一样,我们在查询两个不同逻辑库中的表的时候,需要切换到该逻辑库下进行查询。
|
||
–name 逻辑数据库名,与server.xml中的schema对应
|
||
–checkSQLschema 数据库前缀相关设置,当该值为true时,例如我们执行语句select * from TESTDB.company 。mycat会把语句修改为 select * from company 去掉TESTDB。
|
||
–sqlMaxLimit 当该值设置为某个数值时,每条执行的sql语句,如果没有加上limit语句,Mycat会自动加上对应的值。不写的话,默认返回所有的值。需要自己sql语句加limit。
|
||
|
||
2、dataNode标签
|
||
<dataNode name="dn1" dataHost="localhost1" database="db1" />
|
||
datanode标签定义了mycat中的数据节点,也就是数据分片。一个datanode标签就是一个独立的数据分片。
|
||
localhost1数据库实例上的db1物理数据库,这就组成一个数据分片,最后我们用dn1来标示这个分片。
|
||
–name 定义数据节点的名字,这个名字需要唯一。我们在table标签上用这个名字来建立表与分片对应的关系
|
||
–dataHost 用于定义该分片属于哪个数据库实例,属性与datahost标签上定义的name对应
|
||
–database 用于定义该分片属于数据库实例上 的具体库。
|
||
|
||
3、dataHost标签
|
||
这个标签直接定义了具体数据库实例,读写分离配置和心跳语句。
|
||
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
|
||
<heartbeat>select user()</heartbeat>
|
||
<writeHost host="hostM1" url="192.168.1.100:3306" user="root" password="123456">
|
||
<readHost host="hostS1" url="192.168.1.101:3306" user="root" password="123456" />
|
||
</writeHost>
|
||
</dataHost>
|
||
|
||
–name 唯一标示dataHost标签,供上层使用
|
||
–maxCon 指定每个读写实例连接池的最大连接。
|
||
–minCon 指定每个读写实例连接池的最小连接,初始化连接池的大小
|
||
–balance 负载均称类型
|
||
balance=“0”:不开启读写分离机制,所有读操作都发送到当前可用的writeHost上
|
||
balance=“1”:全部的readHost与stand by writeHost参与select语句的负载均衡,简单的说,当双主双从模式(M1-S1,M2-S2 并且M1 M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡。
|
||
balance=“2”:所有读操作都随机的在writeHost、readHost上分发
|
||
balance=“3”:所有读请求随机的分发到writeHst对应的readHost执行,writeHost不负担读写压力。
|
||
–writeType 负载均衡类型。
|
||
writeType=“0”, 所有写操作发送到配置的第一个 writeHost,第一个挂了切到还生存的第二个writeHost,重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties .
|
||
writeType=“1”,所有写操作都随机的发送到配置的 writeHost。1.5以后版本废弃不推荐。
|
||
–switchType -1不自动切换
|
||
1 默认值 自动切换
|
||
2 基于MySql主从同步的状态决定是否切换心跳语句为 show slave status
|
||
3 基于mysql galary cluster 的切换机制(适合集群) 心跳语句为 show status like ‘wsrep%’
|
||
–dbType 指定后端链接的数据库类型目前支持二进制的mysql协议,还有其他使用jdbc链接的数据库,例如:mongodb,oracle,spark等
|
||
–dbDriver 指定连接后段数据库使用的driver,目前可选的值有native和JDBC。使用native的话,因为这个值执行的是二进制的mysql协议,所以可以使用mysql和maridb,其他类型的则需要使用JDBC驱动来支持。
|
||
如果使用JDBC的话需要符合JDBC4标准的驱动jar 放到mycat\lib目录下,并检查驱动jar包中包括如下目录结构文件 META-INF\services\java.sql.Driver。 在这个文件写上具体的driver类名,例如com.mysql.jdbc.Driver
|
||
writeHost readHost指定后端数据库的相关配置给mycat,用于实例化后端连接池。
|
||
–tempReadHostAvailable
|
||
如果配置了这个属性 writeHost 下面的 readHost 仍旧可用,默认 0 可配置(0、1)。
|
||
1)heartbeat标签
|
||
这个标签内指明用于和后端数据库进行心跳检查的语句。
|
||
例如:MYSQL 可以使用 select user(),Oracle 可以使用 select 1 from dual 等。
|
||
2) writeHost /readHost 标签
|
||
这两个标签都指定后端数据库的相关配置,用于实例化后端连接池。唯一不同的是,writeHost 指定写实例、readHost 指定读实例。
|
||
在一个 dataHost 内可以定义多个 writeHost 和 readHost。但是,如果 writeHost 指定的后端数据库宕机,那么这个 writeHost 绑定的所有 readHost 都将不可用。
|
||
另一方面,由于这个 writeHost 宕机,系统会自动的检测到,并切换到备用的 writeHost 上去。这两个标签的属性相同,这里就一起介绍。
|
||
–host 用于标识不同实例,一般 writeHost 我们使用M1,readHost 我们用S1。
|
||
–url 后端实例连接地址。Native:地址:端口 JDBC:jdbc的url
|
||
–password 后端存储实例需要的密码
|
||
–user 后端存储实例需要的用户名字
|
||
–weight 权重 配置在 readhost 中作为读节点的权重
|
||
–usingDecrypt 是否对密码加密,默认0。
|
||
```
|