概述
文章目录
- 锁机制
- 显示使用锁
- 加锁
- 解锁
- 关闭正在打开的表(清除查询缓存),通常在备份前加全局读锁
- 查询时加写或读锁
- 实验:读锁与写锁的差异
- 创建一个读锁
- 创建一个写锁
- 创建全局锁
- 总结差异
锁机制
锁粒度:
表级锁:直接锁定整张表,在锁定期间,其他进程无法对该表进行写操作,如果设置的是写锁,那么其他进程读也不允许
行级锁:只对指定的行进行锁定,其他进程还是可以对表中的其他行进行操作的。
行级锁是Mysql粒度最小的一种锁,它能大大的减少数据库操作的冲突,但是粒度越小实现成本也越大
锁类型:
读锁:共享锁,只读不可写(包括当前事务) ,多个读互不阻塞
写锁:独占锁,排它锁,写锁会阻塞其它事务(不包括当前事务)的读和它锁
实现
存储引擎:自行实现其锁策略和锁粒度
服务器级:实现了锁,表级锁,用户可显式请求
分类:
隐式锁:由存储引擎自动施加锁
显式锁:用户手动请求
锁策略:在锁粒度及数据安全性寻求的平衡机制
显示使用锁
加锁
LOCK TABLES
tbl_name [[AS] alias] lock_type
[, tbl_name [[AS] alias] lock_type] ...
lock_type: READ , WRITE
范例
MariaDB [bokebi]> LOCK TABLES bokebi_test READ;
Query OK, 0 rows affected (0.00 sec)
解锁
UNLOCK TABLES
范例
MariaDB [bokebi]> UNLOCK TABLES;
Query OK, 0 rows affected (0.00 sec)
关闭正在打开的表(清除查询缓存),通常在备份前加全局读锁
FLUSH TABLES [tb_name[,...]] [WITH READ LOCK]
范例
MariaDB [bokebi]> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (0.00 sec)
查询时加写或读锁
SELECT clause [FOR UPDATE | LOCK IN SHARE MODE]
实验:读锁与写锁的差异
创建一个读锁
MariaDB [bokebi]> LOCK TABLES bokebi_test READ;
Query OK, 0 rows affected (0.00 sec)
远程主机读取被加读锁表的数据
MariaDB [bokebi]> SELECT * FROM bokebi_test; #读取正常
+------+
| id
|
+------+
|
5 |
|
6 |
|
7 |
+------+
3 rows in set (0.01 sec)
远程主机插入数据
MariaDB [bokebi]> INSERT INTO bokebi_test VALUES(1); #无法插入,卡住了
本机释放锁
MariaDB [bokebi]> UNLOCK TABLES;
Query OK, 0 rows affected (0.00 sec)
远程主机卡住未执行的命令立即执行
MariaDB [bokebi]> INSERT INTO bokebi_test VALUES(1);
Query OK, 1 row affected (1 min 47.94 sec) #时间为从查询到主机解锁之间等待的时间
-----------------------------------------------------
MariaDB [bokebi]> SELECT * FROM bokebi_test; #查看表内容已被更改
+------+
| id
|
+------+
|
5 |
|
6 |
|
7 |
|
1 |
+------+
5 rows in set (0.00 sec)
创建一个写锁
MariaDB [bokebi]> LOCK TABLES bokebi_test WRITE;
Query OK, 0 rows affected (0.00 sec)
远程主机查看被加锁表信息
MariaDB [bokebi]> SELECT * FROM bokebi_test; #无法显示查询结果,卡住了
主机释放锁
MariaDB [bokebi]> UNLOCK TABLES;
Query OK, 0 rows affected (0.00 sec)
远程主机查询结果成功显示
MariaDB [bokebi]> SELECT * FROM bokebi_test;
+------+
| id
|
+------+
|
5 |
|
6 |
|
7 |
|
1 |
|
1 |
+------+
5 rows in set (1 min 44.20 sec) #时间为从查询到主机解锁之间等待的时间
创建全局锁
MariaDB [bokebi]> FLUSH TABLES WITH READ LOCK; #记住此命令是针对整个服务器
Query OK, 0 rows affected (0.00 sec)
什么是全局锁?
当你需要让整个库处于只读状态的时候,可以使用这个命令。
之后其他线程的以下语句会被阻塞:数据更新语句(数据的增删改)、数据定义语句(包括建表、修改表结构等)和更新类事务的提交语句。
全局运用场景
全局锁的典型使用场景是,做全库逻辑备份(mysqldump)、重新做主从时候。
也就是把整库每个表都 select 出来存成文本。
以前有一种做法,是通过 FTWRL 确保不会有其他线程对数据库做更新,然后对整个库做备份。
注意,在备份过程中整个库完全处于只读状态。
数据库只读状态的危险性:
如果你在主库上备份,那么在备份期间都不能执行更新,业务基本上就能停止。
如果你在从库上备份,那么备份期间从库不能执行主库同步过来的binlog,会导致主从延迟。
注:上面逻辑备份,是不加--single-transaction参数
MariaDB [bokebi]> SHOW PROCESSLIST; #查看服务器里所有正在运行的线程
+----+------+---------------------+--------+---------+------+-------+------------------+----------+
| Id | User | Host
| db
| Command | Time | State | Info
| Progress |
+----+------+---------------------+--------+---------+------+-------+------------------+----------+
|
4 | root | localhost
| bokebi | Query
|
0 | NULL
| SHOW PROCESSLIST |
0.000 |
|
8 | sun
| 192.168.26.27:38176 | bokebi | Sleep
|
755 |
| NULL
|
0.000 |
+----+------+---------------------+--------+---------+------+-------+------------------+----------+
2 rows in set (0.00 sec)
MariaDB [bokebi]> kill 8; #使用kill命令加ID号,清除在线的线程-谨慎用
Query OK, 0 rows affected (0.00 sec)
总结差异
读锁--允许其他进程对表进行读操作,不允许写操作。
写锁--不允许其他进程对表进行读写操作。
SQL语言的运行时间除了与复杂性有关外,还受数据库所处的环境影响。
(例如大量写操作的环境下,很难迅速通过FLUSH命令添加读锁)
FLUSH TABLES WITH READ LOCK全局只读锁可以用来维护数据库,进行全库逻辑备份使用。
最后
以上就是安静皮卡丘为你收集整理的linux进阶-MySQL锁机制小结锁机制显示使用锁实验:读锁与写锁的差异的全部内容,希望文章能够帮你解决linux进阶-MySQL锁机制小结锁机制显示使用锁实验:读锁与写锁的差异所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复