《Redis官方文档》Redis调试指南

原文链接      译者:Adeline

Redis开发过程中十分注重其稳定性:我们尽一切努力来保证每一个版本的稳定,不出现突然崩溃等情况。但是即使在我们百分百的努力下,仍然没办法保证百分百的无bug。

Redis出现崩溃时,会生成一个详细的报告来描述当时的情景,但是有时候只看报告还不够,而且Redis的核心开发团队可能也没办法独立重现你出现崩溃时候的场景:在这种情况下,我们需要用户能够重现这个情景来帮助我们。

这个指南讲解了如何使用GDB来获得Redis开发者可能用到的信息。

GDB是什么?


GDB是一款GNU调试器:一个可以查看到其他程序内部状态的程序。通常来讲,跟踪和修正bug其实就是一个收集更多的bug出现时的信息的过程,所以GDB是一个极为有用的工具。

GDB有以下两种使用模式:

  • 可以连接到一个运行的程序上来观察程序正在运行时候的状态
  • 可以观察已经结束运行的程序的状态,使用程序运行时候的内存镜像,叫做核心文件(core file)来实现。

从调试Redis的bug的角度来看,我们需要用到GDB的这两种模式:用户可以通过把GDB连接到Redis实例上来重现bug出现时候的场景,当崩溃发生时,用户可以创建core file来给Redis开发人员,开发人员可以用它来查看崩溃发生时Redis的内部运行状态。

这种方法使得开发人员可以独立在自己的电脑上进行模拟和跟踪,不需要用户的配合,也就不需要用户在生产环境中为了配合调试来进行Redis的重启了。

不使用优化选项编译Redis


默认情况下,Redis是使用 -O2选项编译的(译者注:-O2是gcc编译时的优化选项),这表示编译器优化是启动的。这使得Redis运行更快,但同时也使得Redis(与其他程序一样)更难被GDB观测。

使用GDB连接时,最好使用make noopt命令来编译Redis,使其不进行编译优化(而不是仅仅使用make)。但是如果你已经在生产环境中使用了Redis,而且重新编译可能会带来一些问题和麻烦的话,就没有必要重新编译了。尽管是会有一些限制,但是对于使用优化选项编译的程序,GDB也是可以用的。

如果你能在第一次出现崩溃后就把Redis不使用优化的重新编译一下,那是极好的,因为下次出现问题的时候就很好跟踪了。

你不用担心不使用优化编译对性能的影响,因为Redis并非计算密集型(CPU-bound)软件(更偏向I/O密集型),这点小的影响很难在你的环境中构成问题。

把GDB连接到一个运行的进程上


如果你有一个运行中的Redis 服务器,你可以把GDB连接到上面,如果Redis崩溃你既可以查看内部运行状态也可以创建一个core dump文件。

把GDB连接到Redis进程上不会对Redis的运行性能有影响,所以这不是一件危险的事,可以放心去做。

为了把GDB连接上去,首先要知道Redis实例的进程ID(进行的pid)。你可以使用 redis-cli轻松获取到:


$ redis-cli info | grep process_id
process_id:58414


上面的例子中,进程ID是58414

  • 登录到Redis服务器上
  • (非强制但建议的步骤)使用screen  或者tmux 终端来保证ssh连接超时后GDB会话不会被关闭。如果不知道screen是什么,可以阅读这篇文章
  • 使用如下命令将GDB连接到Redis服务器:

  • gdb <path-to-redis-executable> <pid>
    例如:gdb /usr/local/bin/redis-server 58414

GDB会启动并连接到运行的服务器上,打印信息大致如下:


Reading symbols for shared libraries + done
0x00007fff8d4797e6 in epoll_wait ()
(gdb)


  • 这时候GDB已经连接上了,但是Redis实例现在被GDB阻塞了。为了使Redis实例继续运行,只需要在GDB提示界面中输入continue,然后回车即可。
  • 完成!现在你的Redis服务器已经连接了GDB,你可以等着下次崩溃啦:)
  • 如果你是使用screen/tmux运行GDB的话,现在是时候把GDB的运行和screen/tmux会话分离开了(译者理解就是关闭会话不会影响程序运行的意思),使用Ctrl-a a 即可。

崩溃发生后


Redis的DEBUG SEGFAULT命令可以模拟段故障(也就是一个严重的意外崩溃(当然不要在真正的生产系统中这个命令哈),现在我要用这个命令来使Redis崩溃,看看GDB中都做了什么:

(gdb) continue
Continuing.

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0xffffffffffffffff
debugCommand (c=0x7ffc32005000) at debug.c:220
220         *((char*)-1) = ‘x';

如你所见,GDB检测到了Redis的崩溃,甚至显示除了出错的文件名和行号。这已经比Redis的崩溃跟踪报告要详细了(报告只包括函数名和二进制偏移)

获取堆栈跟踪


第一件事儿就是使用GDB获得全栈跟踪信息。这非常简单,使用bt 命令就可以(bt是backtrace的简写)


(gdb) bt#0  debugCommand (c=0x7ffc32005000) at debug.c:220
#1  0x000000010d246d63 in call (c=0x7ffc32005000) at redis.c:1163
#2  0x000000010d247290 in processCommand (c=0x7ffc32005000) at redis.c:1305
#3  0x000000010d251660 in processInputBuffer (c=0x7ffc32005000) at networking.c:959
#4  0x000000010d251872 in readQueryFromClient (el=0x0, fd=5, privdata=0x7fff76f1c0b0, mask=220924512) at networking.c:1021
#5  0x000000010d243523 in aeProcessEvents (eventLoop=0x7fff6ce408d0, flags=220829559) at ae.c:352
#6  0x000000010d24373b in aeMain (eventLoop=0x10d429ef0) at ae.c:397
#7  0x000000010d2494ff in main (argc=1, argv=0x10d2b2900) at redis.c:2046
获得栈跟踪信息后,我们还需要使用info registers 命令来获得处理器寄存器信息
(gdb) info registersrax            0x0  0
rbx            0x7ffc32005000   140721147367424
rcx            0x10d2b0a60  4515891808
rdx            0x7fff76f1c0b0   140735188943024
rsi            0x10d299777  4515796855
rdi            0x0  0
rbp            0x7fff6ce40730   0x7fff6ce40730
rsp            0x7fff6ce40650   0x7fff6ce40650
r8             0x4f26b3f7   1327936503
r9             0x7fff6ce40718   140735020271384
r10            0x81 129
r11            0x10d430398  4517462936
r12            0x4b7c04f8babc0  1327936503000000
r13            0x10d3350a0  4516434080
r14            0x10d42d9f0  4517452272
r15            0x10d430398  4517462936
rip            0x10d26cfd4  0x10d26cfd4 <debugCommand+68>
eflags         0x10246  66118
cs             0x2b 43
ss             0x0  0
ds             0x0  0
es             0x0  0
fs             0x0  0
gs             0x0  0


请一定在bug报告中包括这两种信息。

获得核心文件(core file)


下一步就是生成core dump,这是运行的Redis 进程的内存镜像。使用gcore 命令来完成:


(gdb) gcoreSaved corefile core.58414


有一点很重要,你需要知道这包含Redis实例崩溃时其中包含的所有数据:Redis开发者可以保证不会泄露这些数据,并且在调试结束后第一时间删除,但你还是需要知道发送的core file中包含你的数据。

如果你的数据中包含比较敏感的信息,我们建议您把dump文件直接发给Salvatore Sanfilippo(就是这个文档的作者),邮箱地址是antirez at gmail dot com

需要给开发人员发送的信息


现在你可以把所有的信息发送给Redis核心团队了,这些包括:

  • 你正在使用的Redis可执行文件
  • 使用bt命令导出的堆栈跟踪和寄存器dump
  • 使用GDB生成的核心文件(core file)
  • 操作系统信息,GCC版本,Redis版本

感谢


您的帮助对我们来说非常重要!有许多的问题只能用这种方式来跟踪,非常感谢!而且帮助我们进行调试你有可能获得摩卡咖啡壶的奖励哦(Redis Moka Award). 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/285248.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java基础系列8:Java的序列化与反序列化(修)

一 简介 对象序列化就是把一个对象变成二进制的数据流的一种方法&#xff0c;通过对象序列化可以方便地实现对象的传输和存储。 把对象转换为字节序列的过程称为对象的序列化 把字节序列恢复为对象的过程称为对象的反序列化 对象的序列化主要有两种用途&#xff1a; 1&#xff…

[转]nginx学习,看这一篇就够了:下载、安装。使用:正向代理、反向代理、负载均衡。常用命令和配置文件

文章目录 前言一、nginx简介 1. 什么是 nginx 和可以做什么事情2.Nginx 作为 web 服务器3. 正向代理4. 反向代理5. 负载均衡6.动静分离二、Nginx 的安装(Linux:centos为例) 1. 准备工作2. 开始安装3. 运行nginx4. 防火墙问题三、 Nginx 的常用命令和配置文件 1. Nginx常用命令 …

在 .NET 6 中使用 Startup.cs 更简洁的方法

如果您在关注 .NET 6&#xff0c;那么您应该知道&#xff0c;在 .NET 6 项目中&#xff0c;没有 Startup.cs 文件&#xff0c;现在使用了 Program.cs 文件来完成统一的配置。我之前发了一篇使用在 .NET 6 项目中使用 Startup.cs 的文章。在 .NET 6 项目中使用 Startup.cs能否能…

【ArcGIS Pro微课1000例】0005:ArcGIS Pro 2.5基于矢量数据制作拉伸三维地图案例

ArcGIS Pro 2.5中,可以基于某个字段,对矢量数据进行拉伸,制作精美的三维地图。本文以中国省级行政区划数据为例,基于面积字段制作3d地图。 文章目录 1. 新建局部场景2. 地图符号化3. 三维矢量地图制作1. 新建局部场景 打开ArcGIS Pro 2.5,新建局部场景项目,并保存。 2. …

C语言试题144之编写函数输入,输出 5 个学生的数据记录。

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款模拟面试、刷题神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:编写 input()和 output()函数…

第十一次实验总结

知识点总结&#xff1a; 指针、数组和地址间的关系 数组的基地址是在内存中存储数组的起始位置&#xff0c;它是数组中第一个元素&#xff08;下标为0&#xff09;的地址&#xff0c;因此数组名本身是一个地址即指针值。 指针是以地址作为值的变量&#xff0c;而数组名的值是一…

Python统计列表中的重复项出现的次数的方法

本文实例展示了Python统计列表中的重复项出现的次数的方法&#xff0c;是一个很实用的功能&#xff0c;适合Python初学者学习借鉴。具体方法如下&#xff1a; 对一个列表&#xff0c;比如[1,2,2,2,2,3,3,3,4,4,4,4]&#xff0c;现在我们需要统计这个列表里的重复项&#xff0c;…

分布式(一致性协议)之领导人选举( DotNext.Net.Cluster 实现Raft 选举 )

分布式(一致性协议)之领导人选举( DotNext.Net.Cluster 实现Raft 选举 )继分布式锁之后的又一高可用技术爽文之分布式领导选举 或者说 分布式一致性协议的实现分布式选举是实现高可用的必备技术&#xff0c;想实现主从&#xff0c;就必须得有选举的策略&#xff0c;有主从才会有…

投巧解决JavaScript split方法出现空字符的问题

直接使用split&#xff0c;前后各有一个“”值。 >> var str,a,b,c,d,e,f,; >> str.split(,);//(8) ["", "a", "b", "c", "d", "e", "f", ""]临时方法&#xff1a;split后&…

C语言试题146之反向输出一个链表

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款模拟面试、刷题神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:反向输出一个链表 2 、温馨提…

【ArcGIS Pro微课1000例】0006:ArcGIS Pro 2.5三维显示DEM数字高程模型

通过ArcGIS的学习,我们知道,ArcScene可以实现二维数据的三维显示,是将二维数据(例如DEM)进行自定义表面浮动拉伸。那么ArcGIS Pro中能不能实现DEM的三维显示呢? ArcScene三维显示结果: 目前所采用的ArcGIS Pro 2.5版本还不能直接将DEM进行三维显示,我们的做法是参照Ar…

中国古代历朝首都一览

【五帝时期】&#xff08;约公元前26世纪初—公元前2070年&#xff09; 『黄帝』有熊&#xff08;今河南郑州新郑&#xff09; 『颛顼』帝丘&#xff08;今河南濮阳&#xff09; 『帝喾』帝丘&#xff08;今河南濮阳&#xff09;、西亳&#xff08;今河南洛阳偃师西&#xff09…

程序员的自我修养:有助于提高沟通能力的7本书

直接影响工作效率的四种能力&#xff1a;沟通能力、自学能力、自我管理能力、问题解决能力。提高沟通能力&#xff0c;是程序员提高自我修养的必要条件。相信很多人跟我一样&#xff0c;性格内向&#xff0c;信仰技术&#xff0c;很少有跟人说话的愿望&#xff0c;只是想看代码…

玩转 Linux 之:磁盘分区、挂载知多少?

转载于&#xff1a;http://my.oschina.net/leejun2005/blog/290073 在做日志机扩容的时候&#xff0c;发现运维同学将一块硬盘的挂载点没有同以前的日志机保持一致&#xff0c;考虑到这会给日后的维护带来麻烦&#xff0c;于是尝试着手修改&#xff0c;在修改的同时&#xff0c…

C# NanoFramework 点灯和按键 之 ESP32

本来周末是要搞个大的&#xff0c;WIFI 和 Web网页之类的&#xff0c;奈何搞了两天&#xff0c;并与外国友人聊过后&#xff0c;才发现是固件有问题&#xff0c;晚上与大佬进行交流后才发现&#xff0c;原来ESP32S的官方固件有问题&#xff0c;搞不了。所以&#xff0c;建议买的…

【ArcGIS Pro微课1000例】0002:ArcGIS Pro 2.5二三维联动显示

ArcGIS Pro是一款全新的桌面应用程序,它改变了桌面GIS的工作方式,以满足新一代WebGIS应用模式。ArcGIS Pro采用Ribbon界面风格,给人全新的用户体验。它作为一个高级的应用程序,可以对来自本地、ArcGIS Online、或者Portal for ArcGIS的数据进行可视化、编辑、分析。同时,实…

Spring Boot 解决跨域Cors问题

后端主要代码&#xff1a; &#xff08;http://localhost:8080/ &#xff09; /*WebCorsConfig.java*/ package com.example.demo.Controller;import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsR…

C语言试题147之创建一个链表并且排序输出这个链表

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款模拟面试、刷题神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:创建一个链表并且排序输出这…

DOM节点创建(jQuery)

1DOM创建节点及节点属性 通过JavaScript可以很方便的获取DOM节点&#xff0c;从而进行一系列的DOM操作。但实际上一般开发者都习惯性的先定义好HTML结构&#xff0c;但这样就非常不灵活了。 试想下这样的情况&#xff1a;如果我们通过AJAX获取到数据之后然后才能确定结构的话&a…

PHP中刷新输出缓冲

2019独角兽企业重金招聘Python工程师标准>>> http://www.cnblogs.com/mutuan/archive/2012/03/18/2404957.html 转载于:https://my.oschina.net/wuzhencan/blog/652259