总结关系型数据库相关概念,关系,行,列,主键,惟一键,域。
- 关系relational:行列构成的二维表。表中行列次序不重要。
- 行row:表中每一行,即一条记录recoard。
- 列column:表中每一列,称为属性、字段filed。
- 主键primary key:PK ,一个或多个字段的组合, 用于惟一确定一个记录的字段,一张表只有一个主键,主键字段不能为空NULL
- 唯一键unique key:一个或多个字段的组合,用于惟一确定一个记录的字段,一张表可以有多个UK,而且UK字段可以为NULL
- 域Domain:属性的取值范围。
总结关联类型,1对1,1对多,多对多关系。可以自行设计表进行解释。
一对一
一个表中的每条记录都与另一个表中的一条记录相关联。每个人只有一个身份证信息,而每个身份证信息也只属于一个人。
一对多
一个表中的每条记录可以与另一个表中的多条记录相关联,但另一个表中的每条记录只能与一个表中的记录相关联。一个班级有多个学生,但每个学生只属于一个班级。
多对多
两个表中的每条记录都可以与另一个表中的多条记录相关联。一个学生可以选修多门课程,而一门课程也可以被多个学生选修。
总结mysql设计范式
三大范式
第一范式
原子性,字段属性不可再分。
第二范式
必须有主键,非主键字段必须依赖主键,其余字段不存在相互依赖
第三范式
不存在依赖传递,表中每一列都是和主键直接依赖的。
总结Mysql多种安装方式,及安全加固,并总结mysql配置文件。
安装方式
- 包安装:yum/dnf/apt
- 二进制安装:将包解压至特定路径,简单配置即可使用
- 源码编译安装:复杂,灵活
安全加固
MySQL5.6前版本需要进行安全加固,运行脚本:mysql_secure_installation
脚本位置:/usr/bin/mysql_secure_installation
脚本内容:设置MySQL管理员root密码、禁止root远程登录、删除anonymous用户账号、删除test数据库
MySQL配置文件格式
分类
/etc/my.cnf:全局配置
/etc/mysql/my.cnf:全局配置
~/.my.cnf:用户级别配置
格式
[mysqld] [mysqld_safe] [mysqld_multi] [mysql] [mysqladmin] [mysqldump] [server] [client]
其中:1、on、true意义相同;0、off、true意义相同;不区分大小写。_和-相同
掌握如何获取SQL命令的帮助
基于帮助完成添加testdb库,字符集utf8, 排序集合utf8_bin.创建host表,字段(id,host,ip,cname等)
官方帮助文档:https://dev.mysql.com/doc/refman/8.0/en/sql-statements.html
在MySQL中:help keyword;
mysql> create database testdb character set utf8 collate utf8_bin;
Query OK, 1 row affected, 2 warnings (0.00 sec)
mysql> create table host(id int primary key auto_increment,host varchar(20) not null,cname varchar(20));
Query OK, 0 rows affected (0.00 sec)
完成总结DDL, DML的用法
DDL数据库定义语言
DDL用来创建数据库中的各种对象,创建、删除、修改表的结构,比如表、视图、索引、同义词、聚簇等。其主要功能是定义数据库对象。
核心指令为create、drop、alter。
create table student:
alter table teacher rename s1;
drop table s1;
DML数据操纵语言
DML的主要功能是访问数据,因此其语法都是以读写数据库为主。
核心指令为insert、update、delete。
insert into user(user,host) values ('liubei','127.0.0.1');
update user set host='localhost' where user='caocao';
delete from user where user='caocao';
总结mysql架构原理
参考原文:https://baijiahao.baidu.com/s?id=1710034614164958724&wfr=spider&for=pc
MySQL是C/S架构。
连接层
提供与MySQL服务器建立连接的支持。
几乎支持所有主流的编程技术,Java、php、Python等。
服务层
MySQL Server的核心。主要包括 系统管理和控制工具、连接池、SQL接口、解析器、查询优化器、缓存 六部分。
系统管理和控制工具(Management Services & Utilities)
例如备份恢复、安全管理、集群 管理等。
连接池(Connection Pool)
用于接受客户端发送的各种SQL命令,并且返回用户需要查询的结果。比如DML、DDL、存储过程、视图、触发器等。
MySQL是单进程多线程模型的。分为长连接和短连接。
- 长连接:使用MySQL客户端登录数据库后,直到使用quit命令退出数据库。
- 短连接:使用mysql -e 选项,客户端向服务端申请运行一个命令后立即退出。
Authentication
认证。用户发送的账号密码是否正确。
Thread reuse
线程重用。当一个用户连接进来以后要用一个线程来响应它,而后当用户退出时,这个线程可能并非被销毁,而是把它清理完后,重新收归到线程池当中的空闲线程中,以完成线程重用。
Connection limit
连接限制。线程池的大小决定了连接并发数量的上限,例如,最多容纳100线程,一旦到达上限,后续的请求只能排队或拒绝连接。
Check memory
检测内存
caches
线程缓存
解析器(Parser)
负责将请求的SQL解析生成一个"解析树"。然后根据一些MySQL规则进一步检查解析树是否合法。
查询优化器(Optimizer)
当“解析树”通过解析器语法检查后,将交由优化器将其转化成执行计划,然后与存储引擎交互。
缓存(Cache&Buffer)
缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,权限缓存,引擎缓存等。如果查询缓存有命中的查询结果,查询语句就可以直接去查询缓存中取数据。
存储引擎层
存储引擎负责MySQL中数据的存储与提取,与底层系统文件进行交互。
最常见的是MyISAM和InnoDB。
系统文件层
负责将数据库的数据和日志存储在文件系统之上,并完成与存储引擎的交互,是文件的物理存储层。主要包含日志文件,数据文件,配置文件,pid 文件,socket 文件等。
总结myisam和Innodb存储引擎的区别。
MyISAM
特点
1、表级别锁定
2、不支持事务
3、读写相互阻塞,写时不能读,读时不能写
4、只缓存索引
5、不支持外键约束
6、不支持聚簇索引
7、不支持MVCC(多版本并发控制机制)高并发
8、崩溃恢复性较差
9、MySQL5.5.5 前默认的数据库引擎
引擎文件
table_name.frm 表格式定义
table_name.MYD 数据文件
table_name.MYI 索引文件
InnoDB
特点
1、行级别锁定
2、支持事务
3、读写阻塞与事务隔离级别相关
4、缓存数据和索引
5、支持聚簇索引
6、支持MVCC(多版本并发控制机制)高并发
7、崩溃恢复性更好
8、MySQL5.5.5 开始成为默认的数据库引擎
9、从MySQL5.5 后支持全文索引
引擎文件
1、所有InnoDB表的数据和索引放置于同一个表空间中
适合对数据的集中管理和简单的管理需求。
数据文件:ibdata,存放在datadir定义的目录下
表格式定义:tb_name.frm,存放在datadir定义的每个数据库对应目录下
2、每个表单独使用一个表空间存储表的数据和索引
适合需要更高的灵活性或更细粒度的存储管理。
两类文件放在每个数据库对应的独立目录中。
数据文件(存储数据和索引):tb_name.ibd
表格式定义:tb_name.frm
总结mysql索引作用
索引可以降低服务需要扫描的数据量,减少了IO次数
索引可以帮助服务器避免排序和使用临时表
索引可以帮助将随机I/O转为顺序 I/O
以下查询不会使用索引
- 全表扫描:当数据量大或查询列未被索引时,可能会选择全表扫描。
- 使用函数或表达式:在查询条件中对列使用函数或表达式可能导致索引失效。
- 非最左前缀:对于复合索引,如果查询条件没有涉及最左边的列,则索引可能不会被使用。
- 数据类型不匹配:查询条件中的数据类型与索引列的数据类型不匹配可能导致索引失效。
- OR条件:当使用OR条件时,如果每个条件涉及的列都未被同一个复合索引覆盖,则可能不会使用索引。
- LIKE查询:当LIKE查询的模式以通配符开始时,索引可能不会被使用。
- NULL值:对于包含NULL值的列,索引可能不会被使用。
总结事务ACID事务特性
原子性(Atomicity):事务被视为一个不可分割的工作单位,事务中的操作要么全部完成,要么全部不完成。
一致性(Consistency):事务必须使数据库从一个一致性状态转移到另一个一致性状态。
隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务。
持久性(Durability):一旦事务提交,其更改就是永久保存于数据库中。
总结事务日志工作原理
当事务发生时,MySQL会先将修改记录到重做日志redo中,而不是直接修改数据页。这样即使系统崩溃,也可以通过重做日志来恢复未提交的事务的修改。
如果事务需要回滚,MySQL可以利用回滚日志undo中的数据来撤销已经做的修改,恢复到事务开始前的状态。
总结mysql日志类型
事务日志 transaction log:包括redo log 和 undo log。通过设置innodb_flush_log_at_trx_commit=0|1|2 决定事务日志何时被写入并刷新到磁盘。默认启用。
错误日志 error log:mysqld运行中产生的错误信息。启用:log_error = /var/log/mysql/error.log
通用日志 general log:记录对数据库的通用操作,包括错误的SQL语句。启用:general_log = ON 和 general_log_file = /var/log/mysql/mysql.log
慢查询日志 slow query log:记录执行查询时长超出指定时长的操作。启用:slow_query_log = ON 和 slow_query_log_file = /var/log/mysql/mysql-slow.log 和 long_query_time = 2
二进制日志 bin log:记录导致数据改变或潜在导致数据改变的SQL语句。启用:log_bin = /var/log/mysql/mysql-bin.log
总结二进制日志的不同格式的使用场景。
二进制日志记录的三种格式(推荐row)
基于"语句"记录:statement,记录语句,默认模式( MariaDB 10.2.3 版本以下 ),日志量较少
基于"行"记录:row,记录数据,日志量较大,更加安全,建议使用的格式,MySQL8.0默认格式
混合模式:mixed, 让系统自行判定该基于哪种方式进行,默认模式( MariaDB 10.2.4及版本以上 )
MySQL备份
物理备份/冷备份
直接复制数据库文件,适用于大型数据库环境,不受存储引擎的限制,但不能恢复到不同的MySQL版本;拷贝数据,速度快,但是需要关闭MySQL服务
逻辑备份/热备份
备份的内容是 建库、建表、更新数据等操作所执行的SQL语句(DDL,DML,DCL),适用于中小型数据库;效率相对较低,MySQL服务可正常运行。
温备
读操作可执行;写操作不可执行
备份种类
完全备份
完全备份是对整个数据库的备份、数据库结构和文件结构的备份,保存的是备份完成时刻的数据库,是增量备份的基础。
优点:备份与恢复操作简单方便,缺点是数据存在大量重复,占用大量的备份空间,备份的时间长
增量备份(incremental backup)
针对于上一次备份(无论是哪种备份):备份上一次备份后,所有发生变化的文件。
差异备份(DifferentialBackup)
记录自上次完全数据库备份之后对数据库的更改的数据库备份。
mysqldump实现完全备份+通过binlog还原
1、记录二进制日志POS位置,并完全备份
[root@wenzi ~]$mysql -uroot -pAdmin.
mysql> select * from cs.student;
+----+-------+
| id | name |
+----+-------+
| 1 | zhao |
| 2 | qian |
| 3 | sun |
| 4 | li |
| 5 | zhou |
| 6 | wu |
| 7 | zheng |
| 8 | wang |
+----+-------+
8 rows in set (0.00 sec)
mysql> show master logs;
+---------------+-----------+-----------+
| Log_name | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000001 | 3369 | No |
+---------------+-----------+-----------+
[root@wenzi ~]$mysqldump -uroot -pAdmin. -A -E -R -F --triggers --single-transaction --master-data=2 --flush-privileges --default-character-set=utf8 --hex-blob > /data/all.sql
[root@wenzi ~]$ls /data/
all.sql
2、修改数据库数据
mysql> insert into student(name) values ('ABCD');
Query OK, 1 row affected (0.00 sec)
mysql> select * from student;
+----+-------+
| id | name |
+----+-------+
| 1 | zhao |
| 2 | qian |
| 3 | sun |
| 4 | li |
| 5 | zhou |
| 6 | wu |
| 7 | zheng |
| 8 | wang |
| 9 | ABCD |
+----+-------+
9 rows in set (0.00 sec)
3、备份二进制日志
[root@wenzi ~]$mysqlbinlog /var/lib/mysql/binlog.000001 /var/lib/mysql/binlog.000002 --start-position=3369 > /data/inc.sql
4、模拟数据库损坏
[root@wenzi ~]$systemctl stop mysqld
[root@wenzi ~]$rm -rf /var/lib/mysql/*
5、先还原完全备份,再还原二进制备份
[root@wenzi ~]$systemctl start mysqld
[root@wenzi ~]$mysql
mysql> set sql_log_bin=0;
mysql> source /data/all.sql
mysql> source /data/inc.sql
mysql> set sql_log_bin=1;
mysql> use cs;
Database changed
mysql> select * from student;
+----+-------+
| id | name |
+----+-------+
| 1 | zhao |
| 2 | qian |
| 3 | sun |
| 4 | li |
| 5 | zhou |
| 6 | wu |
| 7 | zheng |
| 8 | wang |
| 9 | ABCD |
+----+-------+
xtrabackup实现增量备份
------------------------------------------完整备份
[root@wenzi ~]# ls /var/lib/mysql
auto.cnf ca-key.pem client-key.pem ib_logfile0 #innodb_temp mysql.sock private_key.pem server-key.pem undo_001 wenzi-bin.000002
binlog.000001 ca.pem ib_buffer_pool ib_logfile1 mysql mysql.sock.lock public_key.pem sys undo_002 wenzi-bin.index
binlog.index client-cert.pem ibdata1 ibtmp1 mysql.ibd performance_schema server-cert.pem test wenzi-bin.000001
[root@wenzi ~]# mkdir -p /data/backups
[root@wenzi ~]# xtrabackup --backup --user=root --password='Admin.123' --target-dir=/data/backups/`date +'%F-%H-%M-%S'`
[root@wenzi ~]# ls /data/backups/2024-01-15-21-05-16/
backup-my.cnf ibdata1 mysql.ibd sys undo_001 wenzi-bin.000002 xtrabackup_binlog_info xtrabackup_info xtrabackup_tablespaces
ib_buffer_pool mysql performance_schema test undo_002 wenzi-bin.index xtrabackup_checkpoints xtrabackup_logfile
#查看二进制日志文件位置
[root@wenzi ~]# cat /data/backups/2024-01-15-21-05-16/xtrabackup_binlog_info
wenzi-bin.000002 155
------------------------------------------数据库新增数据
mysql> insert into test.student values (2,'zhaoyun');
Query OK, 1 row affected (0.00 sec)
mysql> select * from test.student;
+------+---------+
| id | name |
+------+---------+
| 1 | liubei |
| 2 | zhaoyun |
+------+---------+
2 rows in set (0.00 sec)
------------------------------------------第一次增量备份
[root@wenzi ~]# xtrabackup --backup -uroot -p'Admin.123' --target-dir=/data/backups/inc01 --incremental-basedir=/data/backups/2024-01-15-21-05-16/
[root@wenzi ~]# ls /data/backups/inc01/
backup-my.cnf ibdata1.meta mysql.ibd.meta test undo_002.delta wenzi-bin.index xtrabackup_info
ib_buffer_pool mysql performance_schema undo_001.delta undo_002.meta xtrabackup_binlog_info xtrabackup_logfile
ibdata1.delta mysql.ibd.delta sys undo_001.meta wenzi-bin.000004 xtrabackup_checkpoints xtrabackup_tablespaces
------------------------------------------数据库新增数据
mysql> insert into test.student values (3,'guanyu');
Query OK, 1 row affected (0.01 sec)
mysql> select * from test.student;
+------+---------+
| id | name |
+------+---------+
| 1 | liubei |
| 2 | zhaoyun |
| 3 | guanyu |
+------+---------+
3 rows in set (0.00 sec)
------------------------------------------第二次增量备份
[root@wenzi ~]# xtrabackup --backup -uroot -p'Admin.123' --target-dir=/data/backups/inc02 --incremental-basedir=/data/backups/inc01/
[root@wenzi ~]# ls /data/backups/inc02
backup-my.cnf ibdata1.meta mysql.ibd.meta test undo_002.delta wenzi-bin.index xtrabackup_info
ib_buffer_pool mysql performance_schema undo_001.delta undo_002.meta xtrabackup_binlog_info xtrabackup_logfile
ibdata1.delta mysql.ibd.delta sys undo_001.meta wenzi-bin.000005 xtrabackup_checkpoints xtrabackup_tablespaces
------------------------------------------模拟数据库损坏
[root@wenzi ~]# systemctl stop mysqld
[root@wenzi ~]# rm -rf /var/lib/mysql/*
[root@wenzi ~]# rm -f /var/log/mysqld.log
------------------------------------------恢复数据
#检查一致性
#先回滚 完整备份
[root@wenzi ~]# xtrabackup --prepare --apply-log-only --target-dir=/data/backups/2024-01-15-21-05-16/
#接着回滚第一次增量备份
[root@wenzi ~]# xtrabackup --prepare --apply-log-only --target-dir=/data/backups/2024-01-15-21-05-16/ --incremental-dir=/data/backups/inc01/
#再回滚第二次增量备份
[root@wenzi ~]# xtrabackup --prepare --apply-log-only --target-dir=/data/backups/2024-01-15-21-05-16/ --incremental-dir=/data/backups/inc02/
#此时所有备份文件已合并在完整备份文件中
#开始恢复
[root@wenzi ~]# xtrabackup --copy-back --target-dir=/data/backups/2024-01-15-21-05-16/
[root@wenzi ~]# chown -R mysql:mysql /var/lib/mysql*
[root@wenzi ~]# systemctl start mysqld
------------------------------------------检查数据
[root@wenzi ~]# mysql -uroot -p'Admin.123'
mysql> select * from test.student;
+------+---------+
| id | name |
+------+---------+
| 1 | liubei |
| 2 | zhaoyun |
| 3 | guanyu |
+------+---------+
3 rows in set (0.02 sec)
定时备份
一、编写crontab,每天按表备份所有mysql数据。将备份数据放在以天为时间的目录下。
[root@wenzi ~]#cat mysql_backup.sh
#备份使用的账号
user=root
#备份使用的密码
passwd=Admin.123
#mysqlserver的IP
#备份存储目录
dir=/data
mk_dir () {
mkdir -p ${dir}/`date +%F` || exit
}
backup () {
for db in `mysql -u${user} -p{passwd} -e 'show databases;' 2>/dev/null | grep -Ev "schema$|^Database"`;do
for tb in `mysql -u${user} -p{passwd} ${db} -e 'show tables' 2>/dev/null | awk 'NR>1 {print $1}'`;do
mysqldump -u${user} -p${passwd} ${db} ${tb} --single-transaction 2>/dev/null > ${dir}/`date +%F`/${db}-${tb}.sql || (echo "datbase ${db} backup fail!";exit)
done
echo "datbase ${db} backup success!"
done
}
mk_dir
backup
[root@wenzi ~]#crontab -e
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
* 2 * * * bash /root/mysql_backup.sh
二、基于xtrabackup,每周1,周5进行完全备份,周2到周4进行增量备份
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
#备份使用的账号
user=root
#备份使用的密码
passwd=Admin.123
#mysqlserver的IP
#备份存储目录
dir=/data
mk_dir () {
mkdir -p ${dir}/`date +%F` || exit
}
check_today () {
today=`date | awk '{print $1}'`
}
backup_full () {
xtrabackup --backup --user=${user} --password=${passwd} --target-dir=${dir}/`date +%F` || exit
}
#周二备份
backup_incre01 () {
xtrabackup --backup -u${user} -p${passwd} --target-dir=${dir}/inc01 --incremental-basedir=${dir}/`date +%F --date="-1day"`/
}
#周四备份
backup_incre02 () {
xtrabackup --backup -u${user} -p${passwd} --target-dir=${dir}/inc02 --incremental-basedir=${dir}/inc01/
}
check_today
case $today in
"Mon")
mk_dir
backup_full
;;
"Tue")
backup_incre01
;;
"Thu")
backup_incre02
;;
"Fri")
mk_dir
backup_full
;;
esac
[root@wenzi ~]$crontab -l
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
50 23 * * * bash /root/mysqlbackup.sh