1。MySQL锁定机制介绍每个存储引擎使用三种锁定机制行级锁定(row-level)表级锁定(table-level)页级锁定(page-level):页级锁定是行级之间锁定和表级锁定。2、MySQL数据库中的表级锁主要使用MyISAM、Memory、CSV等非事务性存储引擎。行级锁主要使用InnoDB存储引擎和NDBCluster存储引擎,页级锁主要使用BerkeleyDB存储引擎。3.MyISAM表Level级锁主要分为两种:读锁。当一个新的客户端申请读锁资源时,需要满足两个条件:请求加锁的资源当前没有被写锁锁定Pendingwrite-lockqueue没有更高优先级的写锁在等待(只影响写operations)writelocks(影响读操作,也影响写操作)4.MySQL主要分为4个队列来维护这两个锁:两个??存储当前正在加锁的读写锁信息,另外两个存储等待的读写锁信息,如下:当前读锁队列(lock->read)待读锁队列(lock->read_wait)当前写锁队列(lock->write)待写锁队列(lock->write_wait)5.InnoDB的行级锁分为四种共享锁(有的称为:读锁),允许一个事务读取一行,防止其他事务获取同一数据的独占锁。独占锁(称为:写锁)允许获取独占锁的事务更新数据,防止其他事务打算共享锁和打算独占锁。以及最后一个索引键执行后的空位spacemark锁定信息。这种锁定方式称为“NEXT-KEYlocking”(间隙锁定)。间隙锁弱点:锁定一个范围后,即使是一些不存在的键值也会被无辜地锁定,导致锁定任何数据时都无法插入键值锁。通过索引加锁的方式还有其他几个主要的性能风险:当Query不能使用索引时,InnoDB会放弃使用行级锁,转而使用表级锁,导致并发性能下降;当Query使用的索引没有包含所有的过滤条件时,用于数据检索的索引键中的数据可能会有一些不属于Query结果集的行和列,但它们也会被锁定,因为间隙锁锁定一个范围,而不是特定的索引键。Query使用索引定位数据时,如果使用的索引键相同,但访问的数据行不同(索引只是过滤条件的一部分),也会被加锁。7、MyISAM表锁优化建议缩短锁时间尽量减少大而复杂的查询,将复杂的查询拆分成若干小的查询执行。尽可能创建足够高效的索引,使数据检索更快。尽量让MyISAM存储引擎的表只存储必要的信息,控制字段类型。利用机会优化MyISAM表数据文件。可并行化的单独操作concurrent_insert=2,无论MyISAM存储引擎的表数据文件中间是否有删除数据剩余空闲空间,允许在数据文件末尾进行ConcurrentInsert。concurrent_insert=1,当MyISAM存储引擎表数据文件中间没有空闲空间时,可以从文件末尾进行ConcurrentInsert。Concurrent_insert=0,无论MyISAM存储引擎的表数据文件中间部分是否有删除数据剩余的空闲空间,都不允许ConcurrentInsert。(读锁时不允许插入)MyISAM不仅是完全可序列化的,MyISAM存储引擎还有一个特性ConcurrentInsert(并发插入)。MyISAM存储引擎有一个参数选项可以控制是否开启Concurrentinsert功能:concurrent_insert可以设置为0/1/2:具体如下:合理使用读写优先级表级锁默认,写优先级高于读,如果读操作较多时,可以将读优先级设置高,可以设置参数low_priority_updates=1。8.InnoDB行锁优化建议所有的数据检索都通过索引作为尽量避免InnoDB因为无法通过索引键加锁而升级为表级加锁。合理设计索引,让InnoDB锁定索引键。尽量准确,尽可能缩小加锁的范围,避免不必要的加锁影响其他查询的执行。尽量减少基于范围的数据检索过滤条件,以避免由于间隙锁的负面影响而锁定不应锁定的记录。尽量控制事务大小,减少锁定资源量和锁定时间。在业务环境允许的情况下,尽量使用较低级别的事务隔离,以减少MySQL为实现事务隔离级别而增加的额外成本。9、系统锁争用查询MySQL内部有两组专门的状态变量来记录系统内部资源争用情况。表级锁的争用状态变量mysql>showstatuslike'table%';table_locks_immediate:产生表级锁的次数;table_locks_waited:发生表级锁竞争和等待的次数table_locks_immediate的值大于table_locks_waited5000比较合适,在大学里,有必要分析问题。系统启动后记录这两个状态值,每出现一次加1。如果这里Table_locks_waited的状态值比较高,说明表级锁竞争严重,进一步分析是需要。InnoDB行级锁状态变量记录sql>showstatuslike'innodb_row_lock%';Innodb_row_lock_current_waites:当前等待的锁数;Innodb_row_lock_time:从系统启动到现在加锁时间的总长度;Innodb_row_lock_time_avg:每次平均等待时间;Innodb_row_lock_time_max:从系统启动到现在的最长等待时间;Innodb_row_lock_waits:从系统启动到现在的等待总数。5个状态,比较重要的是Innodb_row_lock_time_avg(平均等待时间),Innodb_row_lock_waits(总等待次数)和Innodb_row_lock_time(总等待时间)10.除了以上5个系统状态变量,InnoDB还提供了更丰富的实时state信息,实现方法如下:创建InnoDBMonitor表开启InnoDB监控函数mysql>createtableinnodb_monitor(aint)engine=innodb;然后执行“showinnodbstatus”查看详细信息为什么要创建innodb_monitor表?创建这张表是为了告诉InnoDB我们要开始监控它的详细信息,然后InnoDB会把更详细的事务级锁信息记录到MySQL的错误日志中,以供后面进一步分析。
