企业案例一:

背景:公司的mysql数据版本为5.1.7,存储引擎为myisam,总出现问题

1.升级数据库方案

#1.提出升级的方案
    升级的方法,升级的时间,升级终会出现的问题,升级后出现的问题
#2.准备一台新机器,安装mysql-5.6版本
    源码包安装,二进制安装
#3.在旧数据库上备份数据(除了系统库以外的数据)
    mysqldump -uroot -p123 -R --trigers -B world --master-data=2 > /tmp/123.sql
#4.将备份的数据传到新的数据库服务器上
    scp  rsync 硬件设备  NFS
#5.修改存储引擎
    sed -i.bak 's#MyISAM#Innodb#g' /tmp/123.sql
#6.将修改的数据导入新的数据库
    mysql -uroot -p123 < /tmp/123.sql
    source /tmp/123.sql
    \. /tmp/123.sql
#7.将测试环境连接数据库的配置修改为新的地址
    为了测试功能和业务
#8.将测试环境数据清除,切换生产环境连接数据库配置为新的地址
    修改web端代码包的配置文件,修改数据库IP,端口(代码包里面写主机名,去web服务器修改hosts)
#9.通过binlog将升级过程中新写入的数据提取出来备份并导入到新库

企业案例二:

背景:数据库突然断电,导致数据库表损坏

1.解决数据库表损坏

#1.找到建表语句
CREATE TABLE `country_new` (
  `Code` char(3) NOT NULL DEFAULT '',
  `Name` char(52) NOT NULL DEFAULT '',
  `Continent` enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL DEFAULT 'Asia',
  `Region` char(26) NOT NULL DEFAULT '',
  `SurfaceArea` float(10,2) NOT NULL DEFAULT '0.00',
  `IndepYear` smallint(6) DEFAULT NULL,
  `Population` int(11) NOT NULL DEFAULT '0',
  `LifeExpectancy` float(3,1) DEFAULT NULL,
  `GNP` float(10,2) DEFAULT NULL,
  `GNPOld` float(10,2) DEFAULT NULL,
  `LocalName` char(45) NOT NULL DEFAULT '',
  `GovernmentForm` char(45) NOT NULL DEFAULT '',
  `HeadOfState` char(60) DEFAULT NULL,
  `Capital` int(11) DEFAULT NULL,
  `Code2` char(2) NOT NULL DEFAULT '',
  PRIMARY KEY (`Code`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

#2.移除新表的表数据
mysql> alter table country_new discard tablespace;
Query OK, 0 rows affected (0.00 sec)

#3.物理拷贝country的表数据
[root@db04 world]# cp -a country.ibd country_new.ibd

#4.新表读取新的表空间
mysql> alter table country_new import tablespace;
Query OK, 0 rows affected, 1 warning (0.02 sec)

#5.物理删除旧的表数据
mysql> drop table country;
ERROR 1051 (42S02): Unknown table 'world.country'
[root@db04 world]# rm country.ibd 

#6.修改表名
mysql> alter table country_new rename country;
Query OK, 0 rows affected (0.00 sec)

一、Innodb 核心特性 事务

1.什么是事务

一组数据操作执行步骤,这些步骤被视为一个工作单元:
1)用于对多个语句进行分组
2)可以在多个客户机并发访问同一个表中的数据时使用

所有步骤都成功或都失败
1)如果所有步骤正常,则执行
2)如果步骤出现错误或不完整,则取消

2.事务演示

#1.创建一个表
mysql> create table jiaoyi(id int,name varchar(10),money int);

#2.插入两条数据
mysql> insert into jiaoyi values(1,'qiudao',100);
Query OK, 1 row affected (0.01 sec)

mysql> insert into jiaoyi values(2,'lhd',200);
Query OK, 1 row affected (0.00 sec)

#3.再打开一个窗口
mysql> select * from jiaoyi;
数据与原窗口查看结果一致

#4.开启一个事务(符合逻辑)
mysql> begin;
mysql> update jiaoyi set money=0 where name='qiudao';
mysql> select * from jiaoyi;
mysql> update jiaoyi set money=400 where name='lhd';
mysql> select * from jiaoyi;
#在执行commit之前,另一个窗口是看不到数据变化的
mysql> commit;
#执行commit之后其他人都能看到数据的变化


#5.开启一个事务(不符合逻辑)
mysql> begin;
mysql> update jiaoyi set money=-100 where name='qiudao';
mysql> select * from jiaoyi;
+------+--------+-------+
| id   | name   | money |
+------+--------+-------+
|    1 | qiudao |  -100 |
|    2 | lhd    |   400 |
+------+--------+-------+
2 rows in set (0.00 sec)
#由于钱的值不能为负数,由逻辑判断,操作失败,回滚
mysql> rollback;
mysql> select * from jiaoyi;
+------+--------+-------+
| id   | name   | money |
+------+--------+-------+
|    1 | qiudao |     0 |
|    2 | lhd    |   400 |
+------+--------+-------+
2 rows in set (0.00 sec)

3.事务通俗理解

#伴随着“交易”出现的数据库概念。

我们理解的“交易”是什么?
1)物与物的交换(古代)
2)货币现金与实物的交换(现代1)
3)虚拟货币与实物的交换(现代2)
4)虚拟货币与虚拟实物交换(现代3)

数据库中的“交易”是什么?
1)事务又是如何保证“交易”的“和谐”?
2)ACID

4.一个成功事务的生命周期

begin;
sql1
sql2
sql3
...
commit;

5.一个失败事务的生命周期

begin;
sql1
sql2
sql3
...
rollback;

6.事务的特性 ACID

Atomic(原子性)
所有语句作为一个单元全部成功执行或全部取消。

Consistent(一致性)
如果数据库在事务开始时处于一致状态,则在执行该事务期间将保留一致状态。

Isolated(隔离性)
事务之间不相互影响。

Durable(持久性)
事务成功完成后,所做的所有更改都会准确地记录在数据库中。所做的更改不会丢失。

7.事务的控制语句

1)自动提交

#1.查看自动提交
mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.01 sec)

#2.临时关闭
set autocommit =0;

#3.永久关闭
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
autocommit=0

2)事务的隐式提交

1)现在版本在开启事务时,不需要手工begin,只要你输入的是DML语句,就会自动开启事务。
2)有些情况下事务会被隐式提交

#隐式提交触发条件
1.执行事务没有commit时,如果使用了DDL或者DCL会自动提交上一条事务
2.执行事务没有commit时,如果你手动执行begin,会自动提交上一条事务
3.执行事务没有commit时,如果执行锁表(lock tables)或者解锁(unlock tables),会自动提交上一条事务
4.load data infile(导数据)会自动提交上一条事务
5.select for update
6.在autocommit=1的时候,会自动提交上一条事务

update ....
commit;
insert into ....
begin;
update ....
create table ....
delete ....

3)控制语句

START TRANSACTION(或 BEGIN):显式开始一个新事务                #开启事务
SAVEPOINT:分配事务过程中的一个位置,以供将来引用                  #临时存档
COMMIT:永久记录当前事务所做的更改                             #提交
ROLLBACK:取消当前事务所做的更改                                #回滚
ROLLBACK TO SAVEPOINT:取消在 savepoint 之后执行的更改              #回到存档点
RELEASE SAVEPOINT:删除 savepoint 标识符                        #删除临时存档
SET AUTOCOMMIT:为当前连接禁用或启用默认 autocommit 模式

二、事务的日志

1.redo log

redo,顾名思义“重做日志”,是事务日志的一种。

1)作用

在事务ACID过程中,实现的是“ D ”持久化的作用。
REDO:记录的是,内存数据页的变化过程

特性:WAL(Write Ahead Log)日志优先写

1587615331051

2)REDO工作过程

#执行步骤
update t1 set num=2 where num=1; 
1)首先将t1表中num=1的行所在数据页加载到内存中buffer page
2)MySQL实例在内存中将num=1的数据页改成num=2
3)num=1变成num=2的变化过程会记录到,redo内存区域,也就是redo buffer page中

#提交事务执行步骤
commit; 
1)当敲下commit命令的瞬间,MySQL会将redo buffer page写入磁盘区域redo log
2)当写入成功之后,commit返回ok

2.undo log

1)作用

undo,顾名思义“回滚日志”,是事务日志的一种。

在事务ACID过程中,实现的是“A”原子性的作用。当然CI的特性也和undo有关

1587626059708

三、事务中的锁

1.什么是锁?锁的作用

锁”顾名思义就是锁定的意思。

在事务ACID特性过程中,“锁”和“隔离级别”一起来实现“I”隔离性的作用。

2.锁的类别

排他锁:保证在多事务操作时,数据的一致性。(在我修改数据时,其他人不得修改)
共享锁:保证在多事务工作期间,数据查询时不会被阻塞。

乐观锁:多事务操作时,数据可以被同时修改,谁先提交,谁修改成功。
悲观锁:多事务操作时,数据只有一个人可以修改。

3.多版本并发控制(MVCC)

1)只阻塞修改类操作(排它锁),不阻塞查询类操作(共享锁)
2)乐观锁的机制(谁先提交谁为准)

4.锁得粒度

MyISAM:表级锁
InnoDB:行级锁

5.事物的隔离级别

1)四种隔离级别

1.RU:READ UNCOMMITTED(独立提交)未提交读,允许事务查看其他事务所进行的未提交更改
2.RR:REPEATABLE READ 可重复读,确保每个事务的 SELECT 输出一致  InnoDB 的默认级别  #commit之后,其他窗口看不到数据,必须退出重新登录查看
3.RC:READ COMMITTED 允许其他事务查看已经提交的事务
4.串行化:SERIALIZABLE 讲一个事务于其他事务完全隔离   #当一个事务没有提交,查询也不行

2)修改隔离级别

#查看隔离级别
mysql> show variables like '%iso%';
+---------------+------------------+
| Variable_name | Value            |
+---------------+------------------+
| tx_isolation  | READ-UNCOMMITTED |
+---------------+------------------+
1 row in set (0.00 sec)

#配置隔离级别
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
transaction_isolation=read-uncommit

3)脏读、幻读、不可重复读

#1.脏读(RU级别)
执行一个事务,还没有提交就被读取,可是事务回滚了,那么之前被读取到的数据就是脏数据

#2.幻读
删除数据库所有内容,刚删除完,其他事物添加了数据,好像没有删除干净一样,以为是幻觉

#3.不可重复读
执行事物的时候需要读取两次数据,第一次读取与第二次读取之间数据被修改,导致第一次读取和第二次读取数据不同
Copyright © 高程程 all right reserved,powered by Gitbook修订于: 2021-05-18 21:14:41

results matching ""

    No results matching ""