文章目录
1、锁概述
事务
的隔离性
由锁
来实现。
锁是计算机协调多个进程
或线程
并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、
RAM、I/O)的争用以外,数据也是一种供许多用户共享
的资源。如何保证数据并发访问的一致性
、有效性
是所有数据库必须解决的一个问题,锁冲突
也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。
2、MySQL中的锁,按照锁的粒度分,分为以下三类:
全局锁
:锁定数据库中的所有表
。表级锁
:每次操作锁住整张表
。行级锁
:每次操作锁住对应的行数据
。
3、全局锁
全局锁就是对整个数据库
实例加锁
,加锁后整个实例就处于只读状态
,后续的DML
的写语句,DDL
语句,已经更新操作的事务提交语句都将被阻塞
。其典型的使用场景是做全库的逻辑备份
,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性。
3.1、为什么全库逻辑备份,就需要加全就锁呢?
3.1.1、我们一起先来分析一下不加全局锁,可能存在的问题。
假设在数据库中存在这样三张表: tb_stock 库存表
,tb_order 订单表
,tb_orderlog 订单日志表
。
- 在进行数据备份时,先备份了 tb_stock 库存表。
- 然后接下来,在业务系统中,执行了下单操作,扣减库存,生成订单(更新tb_stock表,插入tb_order表)。
- 然后再执行备份 tb_order表的逻辑。
- 业务中执行插入订单日志操作。
- 最后,又备份了tb_orderlog表。
此时备份出来的数据,是存在问题的。因为备份出来的数据,tb_stock表与tb_order表的数据不一致(有最新操作的订单信息,但是库存数没减)。
3.1.2、那如何来规避这种问题呢? 此时就可以借助于MySQL的全局锁来解决。
对数据库进行进行逻辑备份之前
,先对整个数据库加上全局锁
,一旦加了全局锁之后,其他的DDL
、DML
全部都处于阻塞
状态,但是可以执行DQL
语句,也就是处于只读
状态,而数据备份就是查询操作。
那么数据在进行逻辑备份的过程中,数据库中的数据就是不会发生变化的,这样就保证了数据
的一致性
和完整性
。
4、通过全局锁实现备份操作
4.1、登录mysql并创建数据库backups
[root@localhost ~]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 26
Server version: 8.0.30 MySQL Community Server - GPL
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> create database backups;
Query OK, 1 row affected (0.31 sec)
4.2、创建表 student
create table student(
id int auto_increment primary key comment '主键ID',
name varchar(10) comment '姓名',
no varchar(10) comment '学号'
) comment '学生表';
insert into student values (null, '黛绮丝', '2000100101'),(null, '谢逊','2000100102'),(null, '殷天正', '2000100103'),(null, '韦一笑', '2000100104');
4.3、加全局锁
mysql> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)
mysql>
4.4、 执行数据备份到 Linux中的根目录
[root@localhost ~]# mysqldump -uroot -p123456 backups > /backups.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@localhost ~]#
4.5、释放锁
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)
mysql>
5、全局锁的特点
数据库中加全局锁,是一个比较重的操作
,存在以下问题:
- 如果在
主库
上备份,那么在备份期间都不能执行更新,业务基本上就得停摆
。- 如果在
从库
上备份,那么在备份期间从库不能执行主库同步过来的二进制日志(binlog),会导致主从延迟
。
在InnoDB引擎中,我们可以在备份时加上参数
--single-transaction
参数来完成不加锁的一致性数据备份。
[root@localhost ~]# mysqldump --single-transaction -uroot -p123456 backups > /backups2.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@localhost ~]#