Mysql(MyISAM)的读写互斥锁问题的解决方法

由于没办法在短期内增加读的服务器,所以采取对Mysql进行了一些配置,以牺牲数据实时性为代价,来换取所有服务器的生命安全。呵呵,具体相关调整以及思路如下:

MyISAM在读操作占主导的情况下是很高效的。可一旦出现大量的读写并发,同InnoDB相比,MyISAM的效率就会直线下降,而且,MyISAM和 InnoDB的数据存储方式也有显著不同:通常,在MyISAM里,新数据会被附加到数据文件的结尾,可如果时常做一些UPDATE,DELETE操作之后,数据文件就不再是连续的,形象一点来说,就是数据文件里出现了很多洞洞,此时再插入新数据时,按缺省设置会先看这些洞洞的大小是否可以容纳下新数据,如果可以,则直接把新数据保存到洞洞里,反之,则把新数据保存到数据文件的结尾。之所以这样做是为了减少数据文件的大小,降低文件碎片的产生。但 InnoDB里则不是这样,在InnoDB里,由于主键是cluster的,所以,数据文件始终是按照主键排序的,如果使用自增ID做主键,则新数据始终是位于数据文件的结尾。

了解了这些基础知识,下面说说MyISAM几个容易忽视的配置选项:

concurrent_insert:

通常来说,在MyISAM里读写操作是串行的,但当对同一个表进行查询和插入操作时,为了降低锁竞争的频率,根据concurrent_insert的设置,MyISAM是可以并行处理查询和插入的:

当concurrent_insert=0时,不允许并发插入功能。

当concurrent_insert=1时,允许对没有洞洞的表使用并发插入,新数据位于数据文件结尾(缺省)。

当concurrent_insert=2时,不管表有没有洞洞,都允许在数据文件结尾并发插入。

这样看来,把concurrent_insert设置为2是很划算的,至于由此产生的文件碎片,可以定期使用OPTIMIZE TABLE语法优化。

max_write_lock_count:

缺省情况下,写操作的优先级要高于读操作的优先级,即便是先发送的读请求,后发送的写请求,此时也会优先处理写请求,然后再处理读请求。这就造成一个问题:一旦我发出若干个写请求,就会堵塞所有的读请求,直到写请求全都处理完,才有机会处理读请求。此时可以考虑使用max_write_lock_count:

max_write_lock_count=1

有了这样的设置,当系统处理一个写操作后,就会暂停写操作,给读操作执行的机会。

low-priority-updates:

我们还可以更干脆点,直接降低写操作的优先级,给读操作更高的优先级。

low-priority-updates=1

综合来看,concurrent_insert=2是绝对推荐的,至于max_write_lock_count=1和low-priority-updates=1,则视情况而定,如果可以降低写操作的优先级,则使用low-priority-updates=1,否则使用max_write_lock_count=1。

(0)

相关推荐

  • MYSQL锁表问题的解决方法

    本文实例讲述了MYSQL锁表问题的解决方法.分享给大家供大家参考,具体如下: 很多时候!一不小心就锁表!这里讲解决锁表终极方法! 案例一 mysql>show processlist; 参看sql语句 一般少的话 mysql>kill thread_id; 就可以解决了 kill掉第一个锁表的进程, 依然没有改善. 既然不改善, 咱们就想办法将所有锁表的进程kill掉吧, 简单的脚本如下. #!/bin/bash mysql - u root - e " show processli

  • MySQL死锁问题分析及解决方法实例详解

    MySQL死锁问题是很多程序员在项目开发中常遇到的问题,现就MySQL死锁及解决方法详解如下: 1.MySQL常用存储引擎的锁机制 MyISAM和MEMORY采用表级锁(table-level locking) BDB采用页面锁(page-level locking)或表级锁,默认为页面锁 InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁 2.各种锁特点 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低 行级锁:开销大,加锁慢;

  • mysql 数据库死锁原因及解决办法

    死锁(Deadlock) 所谓死锁:是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程.由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象死锁. 一种情形,此时执行程序中两个或多个线程发生永久堵塞(等待),每个线程都在等待被其他线程占用并堵塞了的资源.例如,如果线程A锁住了记

  • mysql数据库锁的产生原因及解决办法

    数据库和操作系统一样,是一个多用户使用的共享资源.当多个用户并发地存取数据 时,在数据库中就会产生多个事务同时存取同一数据的情况.若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性.加锁是实现数据库并 发控制的一个非常重要的技术.在实际应用中经常会遇到的与锁相关的异常情况,当两个事务需要一组有冲突的锁,而不能将事务继续下去的话,就会出现死锁,严 重影响应用的正常执行. 在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Lock

  • mysql 锁表锁行语句分享(MySQL事务处理)

    复制代码 代码如下: mysql_query("set autocommit=0"); $list_one = $db->fetch_first("select * from prizes where id = ".$id." FOR UPDATE"); $db->query("DELETE from prizes WHERE id =".$list_one['id']); mysql_query("co

  • mysql锁表和解锁语句分享

    页级的典型代表引擎为BDB. 表级的典型代表引擎为MyISAM,MEMORY以及很久以前的ISAM. 行级的典型代表引擎为INNODB. -我们实际应用中用的最多的就是行锁. 行级锁的优点如下: 1).当很多连接分别进行不同的查询时减小LOCK状态. 2).如果出现异常,可以减少数据的丢失.因为一次可以只回滚一行或者几行少量的数据. 行级锁的缺点如下: 1).比页级锁和表级锁要占用更多的内存. 2).进行查询时比页级锁和表级锁需要的I/O要多,所以我们经常把行级锁用在写操作而不是读操作. 3).

  • MySQL中由load data语句引起死锁的解决案例

    一个线上项目报的死锁,简要说明一下产生原因.处理方案和相关的一些点. 1.背景 这是一个类似数据分析的项目,数据完全通过LOAD DATA语句导入一个InnoDB表中.为方便描述,表结构简化为如下: Create table tb(id int primary key auto_increment, c int not null) engine=innodb; 导入数据的语句对应为 Load data infile 'data1.csv' into table tb; Load data inf

  • Mysql(MyISAM)的读写互斥锁问题的解决方法

    由于没办法在短期内增加读的服务器,所以采取对Mysql进行了一些配置,以牺牲数据实时性为代价,来换取所有服务器的生命安全.呵呵,具体相关调整以及思路如下: MyISAM在读操作占主导的情况下是很高效的.可一旦出现大量的读写并发,同InnoDB相比,MyISAM的效率就会直线下降,而且,MyISAM和 InnoDB的数据存储方式也有显著不同:通常,在MyISAM里,新数据会被附加到数据文件的结尾,可如果时常做一些UPDATE,DELETE操作之后,数据文件就不再是连续的,形象一点来说,就是数据文件

  • 详解golang RWMutex读写互斥锁源码分析

    针对Golang 1.9的sync.RWMutex进行分析,与Golang 1.10基本一样除了将panic改为了throw之外其他的都一样. RWMutex是读写互斥锁.锁可以由任意数量的读取器或单个写入器来保持. RWMutex的零值是一个解锁的互斥锁. 以下代码均去除race竞态检测代码 源代码位置:sync\rwmutex.go 结构体 type RWMutex struct { w Mutex // 互斥锁 writerSem uint32 // 写锁信号量 readerSem uin

  • Go 互斥锁和读写互斥锁的实现

    目录 互斥锁 读写互斥锁 先来看这样一段代码,所存在的问题: var wg sync.WaitGroup var x int64 func main() { wg.Add(2) go f() go f() wg.Wait() fmt.Println(x) // 输出:12135 } func f() { for i:=0;i<10000;i++ { x = x+1 } wg.Done() } 这里为什么输出是 12135(不同的机器结果不一样),而不是20000. 因为 x 的赋值,总共分为三个

  • golang并发安全及读写互斥锁的示例分析

    目录 并发安全和锁 互斥锁 读写互斥锁 并发安全和锁 有时候在Go代码中可能会存在多个goroutine同时操作一个资源(临界区),这种情况会发生竞态问题(数据竞态).类比现实生活中的例子有十字路口被各个方向的的汽车竞争:还有火车上的卫生间被车厢里的人竞争. 举个例子: var x int64 var wg sync.WaitGroup func add() { for i := 0; i < 5000; i++ { x = x + 1 } wg.Done() } func main() { w

  • MySQL无法创建外键的原因及解决方法

    关联2张表时出现了无法创建外键的情况,从这个博客看到,问题出在第六点的Charset和Collate选项在表级和字段级上的一致性上.我的2张表的编码charset和collate不一致,2张表都执行执行SQL语句: alter table 表名 convert to character set utf8; 完美解决问题: ps:下面看下MySQL无法创建外键.查询外键的属性 MyISAM 和InnoDB 讲解 InnoDB和MyISAM是许多人在使用MySQL时最常用的两个表类型,这两个表类型各

  • MySql中表单输入数据出现中文乱码的解决方法

     MySQL会出现中文乱码的原因在于 1.server本身设定问题,一般来说是latin1 2.建库建表时没有制定编码格式. MySql中表单输入数据出现中文乱码的解决方法: 1.建库的时候 CREATE DATABASE test CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'; 2.建表的时候 CREATE TABLE content ( text VARCHAR(100) ) ENGINE=InnoDB DEFAULT CHARSET=utf8

  • MySQL修改my.cnf配置不生效的解决方法

    本文实例讲述了MySQL修改my.cnf配置不生效的解决方法.分享给大家供大家参考,具体如下: 一.问题: 修改了 my.cnf 配置文件后,却不生效,这是怎么回事? 二.原因: 我们注意到,这里只说了修改 my.cnf,并没有说清楚其绝对路径是哪个文件.也就是说,有可能修改的不是正确路径下的my.cnf文件. 在MySQL中,是允许存在多个 my.cnf 配置文件的,有的能对整个系统环境产生影响,例如:/etc/my.cnf.有的则只能影响个别用户,例如:~/.my.cnf. MySQL读取各

  • MySQL 出现错误1418 的原因分析及解决方法

    MySQL 出现错误1418 的原因分析及解决方法 具体错误: 使用mysql创建.调用存储过程,函数以及触发器的时候会有错误符号为1418错误. ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL,or READS SQL DATA in its declaration and binary logging is enabled(you *might* want to use the less safe log

  • MySql修改密码后phpMyAdmin无法登陆的解决方法

    安装wamp集成服务器并配置完成后,点击PhpMyAdmin,就可以进入mysql数据库在线客户端,但是当你修改了mysql管理员root用户密码后再点击将出现以下页面: 错误原因:这是因为修改了mysql密码后phpmyadmin配置文件没有同步更新 解决方法:打开config.inc.php(一般位于wamp/apps/phpmyadmin/下),修改数据库密码(我的数据库密码设置为root,所以此处也要同步),如下图所示 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持

  • Ubuntu 18.04 安装MySQL时未提示输入密码的问题及解决方法

    Ubuntu 1804 安装MySQL 5.7为例给大家介绍的很详细. 执行命令安装MySQL sudo apt install mysql-server sudo apt install mysql-client 安装后看下是否启动: sudo ps aux | grep mysql 如果已经启动,执行完上述命令可看到相应的信息,如果没有启动,则可执行下面命令启动mysql: sudo service mysql start 另外,一会要用到重启mysql命令,重启和关闭mysql的命令分别是

随机推荐