锁是计算机协调多个进程或线程并发访问某一资源的机制。
在数据库中,除传统的计算资源的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的问题,锁冲突也是影响数据库并发访问性能的一个重要的因素。
「从数据操作类型区分:」
「从数据操作颗粒度:」
MyISAM
的锁就是表锁。
MyISAM
在执行查询查询语句之前默认给所有的表加读锁,在执行增删改操作之前,会自动给涉及到的表加写锁
lock table 表名 read ;
lock table 表名 write ;
show open tables ;
unlock tables ;
mylock
加读锁MyISAM
表的读操作,不会阻塞其他进程对同一表的读操作,但会阻塞对同一个表的写操作。只有当读锁被释放以后,才可以进行写操作。MyISAM
表的写操作,会阻塞其他进程对同一表的读操作,只有当写锁释放以后,才可以进行读操作show status like 'table%';
table_locks_immediate
:产生表级锁定的次数。标识可以立即获取锁的查询次数,没立即获取锁值加一table_locks_waited
:出现标记锁定争用而发生的等待次数(不能获取立即获取锁的次数,没等待一次就加一)table-open_cache_hits
:从table share
的free list
中找到一个表的缓存,如果找到则加一table_open_cache_misses
:和上面的hits
相反,如果在缓存中找不到实例则需要重新实例化,每次加一table_open_cache_overflows
:超过缓存区大小的实例个数MyISAM
的读写锁调度是以写优先,这也是MyISAM
不适合做主表的引擎。因为写锁后,其他线程不能做任何的操作,大量的更新会使查询很难得到锁,从而造成永远阻塞。InnoDB
使用行锁,锁定粒度低,发生锁冲突的概率最低,并发度也最高。
「行锁演示:」
MySQL
在InnoDB
引擎下的自动隔离级别为「事务」,每一次请求都相当于提交一次事务这个的主要原因是:「由于出现索引失效导致只能从全表读取,导致行锁变表锁」
间隙锁:「MySQL在执行范围写操作的时候,会默认将这个范围内的数据全部加锁,如果当前进行没有进行提交,那么其他进程访问这个范围内的数据将会被阻塞。」
mysql> begin ;
Query OK, 0 rows affected (0.00 sec)
mysql>select * from 表名 where id = 3 for update #锁定id=3的行
mysql> commit ; # 如果不进行提交,那么其他进程将不能对该行进行写操作
mysql> show status like 'innodb_row_lock%';
+-------------------------------+--------+
| Variable_name | Value |
+-------------------------------+--------+
| Innodb_row_lock_current_waits | 0 |
| Innodb_row_lock_time | 397427 |
| Innodb_row_lock_time_avg | 39742 |
| Innodb_row_lock_time_max | 51038 |
| Innodb_row_lock_waits | 10 |
+-------------------------------+--------+
5 rows in set (0.00 sec)
Innodb_row_lock_current_waits
。当前正在等待锁定的数量Innodb_row_lock_time
。锁定以后进程等待时间总和Innodb_row_lock_time_avg
。每次等待的平均时间Innodb_row_lock_time_max
。等待的最大时间Innodb_row_lock_waits
。等待次数开销和加锁时间界于表锁和行锁之间:会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。
master
将改变记录记录到二进制文件中。slave
将master
的二进制日志文件中的记录拷贝到它的中继日志文件relay log
中slave
读取这个中继文件,将改变应用到自己的数据库中。MySQL的复制是异步且串行化的slave
只有一个master
slave
只能有一个唯一的服务器IDmaster
可以有多个slave
window
和linux
的配置相同,只不过修改的配置文件不一样而已。在window
中修改my.ini
,在linux
中修改my.cnf
文件。
server-id=1
log-bin=一个路径/mysqlbin
log-err=一个路径/mysqlerr
「可选参数」basedir='安装目录'
「可选参数」tmpdir=
「可选参数」read-only=0
读写均可binlog-lgnore-db=数据库名
「可选参数」binlog-do-db
「可选参数」server-id=2
mysql
服务service iptable stop
GRANT REPLICATION SLAVE ON*.* TO 'zhangsan'@'从机器数据库IP‘ IDENTIFIED BY '123456';
flush privileges;
master
状态。记录File
和position
的值show master status ;
CHANGE MASTER TO MASTER_HOST='主机IP',
MASTER_USER='zhangsan',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='File名字',
MASTER_LOG_POS=Position数字;
slave
start slave;
# 当Slave_IO_Running:YES
# Slave_SQL_Running:YES
# 这两个字段均为YES的时候才说明主从复制配置成功
stop slave;
#停止主从复制