锁
全局锁
全局锁就是对整个数据库实例加锁,加锁后整个实例就处于只读状态,后续的DML的写语句,DDL语 句,已经更新操作的事务提交语句都将被阻塞。
其典型的使用场景是做全库的逻辑备份,对所有的表进行锁定,从而获取一致性视图,保证数据的完整 性。
-
先来分析一下不加全局锁,可能存在的问题。
假设在数据库中存在这样三张表: tb_stock 库存表,tb_order 订单表,tb_orderlog 订单日 志表。
-
在进行数据备份时,先备份了tb_stock库存表。
-
然后接下来,在业务系统中,执行了下单操作,扣减库存,生成订单(更新tb_stock表,插入 tb_order表)。
-
然后再执行备份 tb_order表的逻辑。
-
业务中执行插入订单日志操作。
-
最后,又备份了tb_orderlog表。
此时备份出来的数据,是存在问题的。因为备份出来的数据,tb_stock表与tb_order表的数据不一 致(有最新操作的订单信息,但是库存数没减)。
-
再来分析一下加了全局锁后的情况
对数据库进行进行逻辑备份之前,先对整个数据库加上全局锁,一旦加了全局锁之后,其他的DDL、 DML全部都处于阻塞状态,但是可以执行DQL语句,也就是处于只读状态,而数据备份就是查询操作。 那么数据在进行逻辑备份的过程中,数据库中的数据就是不会发生变化的,这样就保证了数据的一致性 和完整性。
语法:
加全局锁:
flush tables with read lock ;
数据备份:
mysqldump -uroot –p1234 itcast > itcast.sql
释放锁:
unlock tables ;
注意:
如果出现报错mysqldump: Got error: 1045: Access denied for user 'root'@'server' (using password: YES) when trying to connect
这个错误是由于mysqldump命令在尝试连接到MySQL数据库时,使用的用户名和密码不正确导致的。解决方案如下:
-
确保你输入的用户名和密码是正确的,特别是密码是否正确。可以尝试重新输入密码,确保没有输入错误。
-
确保你有足够的权限来执行mysqldump命令。如果你是使用root用户执行该命令,可以尝试使用sudo命令来提升权限。
-
如果你使用的是远程连接MySQL数据库,确保了远程连接权限。可以检查MySQL服务器的配置文件,确认是否允许远程连接。
-
如果你使用的是localhost连接,可以尝试使用127.0.0.1代替localhost来连接MySQL数据库。有时候这个问题是由于DNS解析问题导致的。
-
如果以上方法都没有解决问题,可以尝试重置MySQL的root密码。具体方法可以参考MySQL官方文档或者相关教程。
特点
数据库中加全局锁,是一个比较重的操作,存在以下问题:
-
如果在主库上备份,那么在备份期间都不能执行更新,业务基本上就得停摆。
-
如果在从库上备份,那么在备份期间从库不能执行主库同步过来的二进制日志(binlog),会导 致主从延迟。
在InnoDB引擎中,我们可以在备份时加上参数 --single-transaction 参数来完成不加锁的一致 性数据备份。