createmutex(mysql数据库cpu飙升800)

1. createmutex,mysql数据库cpu飙升800?

mysql中CPU占用过高的诊断思路,举个栗子~

mpstat -P ALL 1,查看cpu使用情况,主要消耗在sys即os系统调用上

perf top,cpu主要消耗在_spin_lock

生成perf report查看详细情况

CPU主要消耗在mutex争用上,说明有锁热点。

采用pt-pmp跟踪mysqld执行情况,热点主要集中在mem_heap_alloc和mem_heap_free上。

Pstack提供更详细的API调用栈

#0 0x0000003e0caf80cf in __lll_unlock_wake_private () from /lib64/libc.so.6#1 0x0000003e0ca7cf6a in _L_unlock_5936 () from /lib64/libc.so.6#2 0x0000003e0ca78bbc in _int_free () from /lib64/libc.so.6#3 0x000000000097dcb3 in mem_area_free(void*, mem_pool_t*) ()#4 0x000000000097d2d2 in mem_heap_block_free(mem_block_info_t*, mem_block_info_t*) ()#5 0x00000000009e6474 in row_vers_build_for_consistent_read(unsigned char const*, mtr_t*, dict_index_t*, unsigned long**, read_view_t*, mem_block_info_t**, mem_block_info_t*, unsigned char**) ()#6 0x00000000009dce75 in row_search_for_mysql(unsigned char*, unsigned long, row_prebuilt_t*, unsigned long, unsigned long) ()#7 0x0000000000939c95 in ha_innobase::index_read(unsigned char*, unsigned char const*, unsigned int, ha_rkey_function) ()

Innodb在读取数据记录时的API路径为

row_search_for_mysql --》row_vers_build_for_consistent_read --》mem_heap_create_block_func --》mem_area_alloc --》malloc --》_L_unlock_10151 --》__lll_unlock_wait_private

row_vers_build_for_consistent_read会陷入一个死循环,跳出条件是该条记录不需要快照读或者已经从undo中找出对应的快照版本,每次循环都会调用mem_heap_alloc/free。

而该表的记录更改很频繁,导致其undo history list比较长,搜索快照版本的代价更大,就会频繁的申请和释放堆内存。

Linux原生的内存库函数为ptmalloc,malloc/free调用过多时很容易产生锁热点。

当多条 SQL 并发执行时,会最终触发os层面的spinlock,导致上述情形。

解决方案

将mysqld的内存库函数替换成tcmalloc,相比ptmalloc,tcmalloc可以更好的支持高并发调用。

修改my.cnf,添加如下参数并重启

[mysqld_safe]malloc-lib=tcmalloc

上周五早上7点执行的操作,到现在超过72小时,期间该实例没有再出现cpu长期飙高的情形。

以下是修改前后cpu使用率对比

createmutex(mysql数据库cpu飙升800)

2. 多线程编程主要用pthread还是c?

主要还是用pthread类

1、创建一个线程

类似使用pthread_create函数,前提需要引入相应的头文件

#include <pthread.h>

2、进入线程的回调函数,一般在回调函数中需要写一个死循环进行一些数据处理等等。

void t_callback()

{

While(true)

{}

}

3、由于线程会访问同一段数据或内存,所以一般需添加互拆锁lock防止访问同一段数据

pthread_mutex_t m_lock;

pthread_mutex_init(&m_lock,NULL);

pthread_mutex_lock(&m_lock);

pthread_mutex_unlock(&m_lock);

4、死循环会导致死机,所以在死循环中需要加入阻塞,

pthread_cond_t m_cond;

pthread_cond_init(&m_cond, NULL);

阻塞挂起时候调用:

pthread_cond_wait(&m_cond, &m_lock);

阻塞唤醒时候调用:

pthread_cond_singnal(&m_cond);

3. 现在学习分布式锁还来得及吗?

来得及,学无止境!

多线程情况下对共享资源的操作需要加锁,避免数据被写乱,在分布式系统中,这个问题也是存在的,此时就需要一个分布式锁服务。常见的分布式锁实现一般是基于DB、Redis、zookeeper。下面笔者会按照顺序分析下这3种分布式锁的设计与实现,想直接看分布式锁总结的小伙伴可直接翻到文档末尾处。分布式锁的实现由多种方式,但是不管怎样,分布式锁一般要有以下特点:排他性:任意时刻,只能有一个client能获取到锁容错性:分布式锁服务一般要满足AP,也就是说,只要分布式锁服务集群节点大部分存活,client就可以进行加锁解锁操作避免死锁:分布式锁一定能得到释放,即使client在释放之前崩溃或者网络不可达除了以上特点之外,分布式锁最好也能满足可重入、高性能、阻塞锁特性(AQS这种,能够及时从阻塞状态唤醒)等,下面就话不多说,赶紧上(开往分布式锁的设计与实现的)车~DB锁在数据库新建一张表用于控制并发控制,表结构可以如下所示:CREATE TABLE `lock_table` ( `id` int(11) unsigned NOT NULL COMMENT '主键', `key_id` bigint(20) NOT NULL COMMENT '分布式key', `memo` varchar(43) NOT NULL DEFAULT '' COMMENT '可记录操作内容', `update_time` datetime NOT NULL COMMENT '更新时间', PRIMARY KEY (`id`,`key_id`), UNIQUE KEY `key_id` (`key_id`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8;key_id作为分布式key用来并发控制,memo可用来记录一些操作内容(比如memo可用来支持重入特性,标记下当前加锁的client和加锁次数)。将key_id设置为唯一索引,保证了针对同一个key_id只有一个加锁(数据插入)能成功。此时lock和unlock伪代码如下:def lock : exec sql: insert into lock_table(key_id, memo, update_time) values (key_id, memo, NOW()) if result == true : return true else : return falsedef unlock : exec sql: delete from lock_table where key_id = 'key_id' and memo = 'memo'注意,伪代码中的lock操作是非阻塞锁,也就是tryLock,如果想实现阻塞(或者阻塞超时)加锁,只修反复执行lock伪代码直到加锁成功为止即可。基于DB的分布式锁其实有一个问题,那就是如果加锁成功后,client端宕机或者由于网络原因导致没有解锁,那么其他client就无法对该key_id进行加锁并且无法释放了。为了能够让锁失效,需要在应用层加上定时任务,去删除过期还未解锁的记录,比如删除2分钟前未解锁的伪代码如下:def clear_timeout_lock : exec sql : delete from lock_table where update_time < ADDTIME(NOW(),'-00:02:00')因为单实例DB的TPS一般为几百,所以基于DB的分布式性能上限一般也是1k以下,一般在并发量不大的场景下该分布式锁是满足需求的,不会出现性能问题。不过DB作为分布式锁服务需要考虑单点问题,对于分布式系统来说是不允许出现单点的,一般通过数据库的同步复制,以及使用vip切换Master就能解决这个问题。以上DB分布式锁是通过insert来实现的,如果加锁的数据已经在数据库中存在,那么用select xxx where key_id = xxx for udpate方式来做也是可以的。顺便在此给大家推荐一个Java架构方面的交流学习群:698581634,进群即可免费获取Java架构学习资料:里面有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系,群里一定有你需要的资料,大家赶紧加群吧。Redis锁Redis锁是通过以下命令对资源进行加锁:set key_id key_value NX PX expireTime其中,set nx命令只会在key不存在时给key进行赋值,px用来设置key过期时间,key_value一般是随机值,用来保证释放锁的安全性(释放时会判断是否是之前设置过的随机值,只有是才释放锁)。由于资源设置了过期时间,一定时间后锁会自动释放。set nx保证并发加锁时只有一个client能设置成功(Redis内部是单线程,并且数据存在内存中,也就是说redis内部执行命令是不会有多线程同步问题的),此时的lock/unlock伪代码如下:def lock: if (redis.call('set', KEYS[1], ARGV[1], 'ex', ARGV[2], 'nx')) then return true end return falsedef unlock: if (redis.call('get', KEYS[1]) == ARGV[1]) then redis.call('del', KEYS[1]) return true end return false分布式锁服务中的一个问题如果一个获取到锁的client因为某种原因导致没能及时释放锁,并且redis因为超时释放了锁,另外一个client获取到了锁,此时情况如下图所示: 那么如何解决这个问题呢,一种方案是引入锁续约机制,也就是获取锁之后,释放锁之前,会定时进行锁续约,比如以锁超时时间的1/3为间隔周期进行锁续约。关于开源的redis的分布式锁实现有很多,比较出名的有redisson、百度的dlock,关于分布式锁,笔者也写了一个简易版的分布式锁redis-lock,主要是增加了锁续约和可同时针对多个key加锁的机制。对于高可用性,一般可以通过集群或者master-slave来解决,redis锁优势是性能出色,劣势就是由于数据在内存中,一旦缓存服务宕机,锁数据就丢失了。像redis自带复制功能,可以对数据可靠性有一定的保证,但是由于复制也是异步完成的,因此依然可能出现master节点写入锁数据而未同步到slave节点的时候宕机,锁数据丢失问题。顺便在此给大家推荐一个Java架构方面的交流学习群:698581634,进群即可免费获取Java架构学习资料:里面有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系,群里一定有你需要的资料,大家赶紧加群吧。zookeeper分布式锁ZooKeeper是一个高可用的分布式协调服务,由雅虎创建,是Google Chubby的开源实现。ZooKeeper提供了一项基本的服务:分布式锁服务。zookeeper重要的3个特征是:zab协议、node存储模型和watcher机制。通过zab协议保证数据一致性,zookeeper集群部署保证可用性,node存储在内存中,提高了数据操作性能,使用watcher机制,实现了通知机制(比如加锁成功的client释放锁时可以通知到其他client)。zookeeper node模型支持临时节点特性,即client写入的数据时临时数据,当客户端宕机时临时数据会被删除,这样就不需要给锁增加超时释放机制了。当针对同一个path并发多个创建请求时,只有一个client能创建成功,这个特性用来实现分布式锁。注意:如果client端没有宕机,由于网络原因导致zookeeper服务与client心跳失败,那么zookeeper也会把临时数据给删除掉的,这时如果client还在操作共享数据,是有一定风险的。基于zookeeper实现分布式锁,相对于基于redis和DB的实现来说,使用上更容易,效率与稳定性较好。curator封装了对zookeeper的api操作,同时也封装了一些高级特性,如:Cache事件监听、选举、分布式锁、分布式计数器、分布式Barrier等,使用curator进行分布式加锁示例如下: org.apache.curator curator-framework 2.12.0 org.apache.curator curator-recipes 2.12.0public static void main(String[] args) throws Exception { String lockPath = "/curator_recipes_lock_path"; CuratorFramework client = CuratorFrameworkFactory.builder().connectString("192.168.193.128:2181") .retryPolicy(new ExponentialBackoffRetry(1000, 3)).build(); client.start(); InterProcessMutex lock = new InterProcessMutex(client, lockPath); Runnable task = () -> { try { lock.acquire(); try { System.out.println("zookeeper acquire success: " + Thread.currentThread().getName()); Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } finally { lock.release(); } } catch (Exception ex) { ex.printStackTrace(); } }; ExecutorService executor = Executors.newFixedThreadPool(10); for (int i = 0; i < 1000; i++) { executor.execute(task); } LockSupport.park();}总结从上面介绍的3种分布式锁的设计与实现中,我们可以看出每种实现都有各自的特点,针对潜在的问题有不同的解决方案,归纳如下:性能:redis > zookeeper > db。避免死锁:DB通过应用层设置定时任务来删除过期还未释放的锁,redis通过设置超时时间来解决,而zookeeper是通过临时节点来解决。可用性:DB可通过数据库同步复制,vip切换master来解决,redis可通过集群或者master-slave方式来解决,zookeeper本身自己是通过zab协议集群部署来解决的。注意,DB和redis的复制一般都是异步的,也就是说某些时刻分布式锁发生故障可能存在数据不一致问题,而zookeeper本身通过zab协议保证集群内(至少n/2+1个)节点数据一致性。锁唤醒:DB和redis分布式锁一般不支持唤醒机制(也可以通过应用层自己做轮询检测锁是否空闲,空闲就唤醒内部加锁线程),zookeeper可通过本身的watcher/notify机制来做。使用分布式锁,安全性上和多线程(同一个进程内)加锁是没法比的,可能由于网络原因,分布式锁服务(因为超时或者认为client挂了)将加锁资源给删除了,如果client端继续操作共享资源,此时是有隐患的。因此,对于分布式锁,一个是尽量提高分布式锁服务的可用性,另一个就是要部署同一内网,尽量降低网络问题发生几率。这样来看,貌似分布式锁服务不是“完美”的(PS:技术貌似也不好做到十全十美 :( ),那么开发人员该如何选择分布式锁呢?最好是结合自己的业务实际场景,来选择不同的分布式锁实现,一般来说,基于redis的分布式锁服务应用较多。

4. VB与VC中的互斥怎么写?

就是要同步一个MUTEX嘛,两个MUTEX的名字必须一致,而且你OPEN之前必须得创建噻,要先调用CreateMutex去创建,我看不出来你这两段代码的先后,总之先使用的就CREAT,用完后记得RELEASE掉。

然后给这个MUTEX一个名字,E,例如你上面的ddd3355。这个就在内核代码区标示了一个唯一的内核变量,你打开的时候就指定同一个名字就共享了。

那个错误提示已经告诉你了,你实际上是调用了ANSI版本的CreateMutexA,建议把参数全部改成UNICODE形式,即宽字符CreateMutexW。

免责声明:本文作者:“游客”,版权归作者所有,观点仅代表作者本人。本站仅提供信息存储分享服务,不拥有所有权。信息贵在分享,如有侵权请联系ynstorm@foxmail.com,我们将在24小时内对侵权内容进行删除。
(17)
激光彩打(激光打印机还是喷墨打印机)
上一篇 2023年11月05日
mouseratechecker(你极力
下一篇 2023年11月05日

相关推荐

  • 360密盘下载(下载下来的格式是专门的格式吗)

    电视剧要下载只能一集一集下载。一般的播放器都有下载功能。想把一集中的某个片段存起来,需要通过视频编辑软件进行剪辑。过去下载的网络视频格式多数是avi、mpg.等格式。现在视频下载格式都是mp4格式。下载的视频格式可以通过“视频格式转换”软件进...

    2023年11月02日
  • 我的ip地址(怎么在淘宝里看自己的IP)

    平时在使用手机的时候,无论是连接WiFi或者直接用SIM卡上网,手机都会有一个IP地址,那么怎么查看手机的IP地址呢?...

    2023年11月03日
  • argon(mag焊是什么焊)

    MAG焊(metalargongaswelding)是熔化极活性气体保护电弧焊的英文简称。它是以惰性气体与氧化性气体(O2、CO2)的混合气为保护气体,或以CO2气体或O2+CO2的混合气体为保护气体,以焊丝与工件之间燃烧的电弧作热源进行焊接...

    2023年11月13日
  • 大地系统官网(南京开通数控系统工件数怎么清零)

    1数控系统工件数清零的方法是存在的。2因为数控系统在加工工件时会自动计数,当需要清零时,可以通过以下步骤进行操作:打开数控系统的主页面,进入“工件数清零”功能页面,选择需要清零的工件数,点击确认即可。这样就可以将工件数清零了。3需要注意的是,...

    2023年11月16日
  • c盘满了怎么办(电脑c盘满了之人如何清理)

    电脑C盘满了可能是因为系统文件、临时文件、垃圾文件、应用程序等占用了过多的存储空间,为了解决此问题,可以按照以下步骤进行清理:...

    2023年11月21日
  • 鼠标中键不能用(abaqus鼠标中键不能旋转)

    2.Abaqus设置:在Abaqus中,您需要通过单击鼠标中键来旋转视图。如果此功能未启用,则无法旋转视图。请在菜单栏中选择“Options”&gt;“Graphics”&gt;“Rotation”选项卡,并确保“Usemiddlemouse...

    2023年12月02日
  • 黄士杰博士(加拿大阿尔伯塔大学学费需要多少)

    阿尔伯塔大学(UniversityofAlberta),简称“UA”,始建于1908年,是坐落于加拿大阿尔伯塔省会埃德蒙顿的一所世界著名研究型大学,是加拿大U15研究型大学联盟创始成员、世界大学联盟成员[1]以及世界能源大学联盟[2]成员。阿...

    2023年12月04日
  • 真我q2pro(和真我q2pro哪个好)

    iqooneo使用的处理器比q2pro他处理器更差一些,iqooneo采用的是骁龙845性能方面肯定是碾压的...

    2023年12月04日
  • cros(胡歌代言京尚吗)

    胡歌代言的衣服:卡路驰cros温纯服装阿尔卡特杉杉西服新踏运动鞋(XINTA)法罗宾男鞋引其中温纯是2010年最新代言的...

    2023年12月04日
  • 龙芯3b(龙芯3d5000相当于英特尔几代)

    根据目前公布的纸面参数,龙芯3D5000接近于英特尔在2015/2016年推出的至强服务器E5v3/v4。不过虽然主频接近,但英特尔拥有睿频加速技术,在频率方面龙芯还有不小的差距...

    2023年12月05日
返回顶部