暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

用VSCODE 编辑编译调试MYSQL8

1195

今天很开心终于搞定了MYSQL调试了,像开发程序一样,边写边运行,跟SHELL脚本那么方便了。


以前看大佬在LInux系统上使用源码编译,然后使用GDB,再用VIM+CSDOPE定位,跳转。实在不太方便!


如何在LINUX下源码编译MYSQL 8,请看我写的。


MYSQL 源码DEBUG编译


使用VSCODE 看了姜前辈的也不知所措,感觉跳跃比较大,好像很简单样


VSCode 编译和调试MySQL,每个DBA 都应 get的小技能

https://mp.weixin.qq.com/s/RO_Ipa9_SH8_DuVholrgvg

VScodeyyds!用VScode编译和调试MySQL

https://mp.weixin.qq.com/s/Q-hFTDzoTW5cFk3foW7BAw


对VSCODE 摸索了下 写了篇

VSCODE 从相恋到分手


大家最好是在一台干净的虚拟机上安装,也就是没有其他的MYSQL实例在运行,强占了/etc/my.cnf位置。否则会出现很多问题,不知道为啥的问题!
当然根据MYSQL 源码DEBUG编译 预先安装好了GCC5.5,CMAKE,MYSQLD预先包RPM,GDB。VIM和CSCOPE就不必了。然后MYSQLD能成功运行起来.

根据这篇 VSCODE 从相恋到分手 你安装好了对应的插件。VSCODE插件很多时候需要访问外网,有时候非常慢。


以上是前提条件!

以下VSCODE插件,安装在LINUX服务器上

创建CMAKE配置文件

链接到LINUX系统MYSQL8源码目录,看我这里是直接在当层目录

创建c_cpp_properties.json 文件


{
    "configurations": [
        {
            "name""Linux",
            "includePath": [
                "${workspaceFolder}/**"
            ],
            "defines": [],
            "compilerPath""/usr/local/bin/gcc",
            "cStandard""c11",
            "cppStandard""c++11",
            "intelliSenseMode""linux-gcc-x64",
            "configurationProvider""ms-vscode.cmake-tools"
        }
    ],
    "version"4
}



gcc5.5 一般安装在/usr/local/bin/gcc;
includePath 是头文件路径,workspaceFolder工作空间目录就是链接远程的目录


Settings.json  类似CMAKE编译配置

相对以前少了D开头

cmake .. \
-DWITH_BOOST=/u01/mysql8/source/boost/ \
-DWITH_DEBUG=ON \
-DWITH_SSL=bundled \
-DWITH_INNODB_MEMCACHED=ON \
-DWITH_ZLIB=system \
-DDEFAULT_CHARSET=utf8mb4 \
-DCMAKE_INSTALL_PREFIX=/u01/mysql8/soft \
-DMYSQL_DATADIR=/u01/mysql8/data \
-DWITHOUT_CSV_STORAGE_ENGINE=1 \
-DWITHOUT_BLACKHOLD_STORAGE_ENGINE=1 \
-DWITHOUT_FEDERATED_STORAGE_ENGINE=1 \
-DWITHOUT_ARCHIVE_STORAGE_ENGINE=1 \
-DWITHOUT_MRG_MYISAM_STORAGE_ENGINE=1 \
-DWITHOUT_NDBCLUSTER_STORAGE_ENGINE=1 \
-DFORCE_INSOURCE_BUILD=1 \
-DCMAKE_CXX_COMPILER=/usr/local/bin/g++ \
-DCMAKE_C_COMPILER=/usr/local/bin/gcc



{
    "cmake.buildBeforeRun"true,
    "cmake.buildDirectory""/home/source_code/mysql_8_buildr"
    "cmake.configureSettings": {     
      "WITH_DEBUG""1",
      "CMAKE_INSTALL_PREFIX""home/source_code/mysql_8_buildr",
      "MYSQL_DATADIR""home/source_code/mysql_8_buildr/data",
      "SYSCONFDIR""home/source_code/mysql_8_buildr/etc",
      "MYSQL_TCP_PORT""3309",
      "MYSQL_UNIX_ADDR""home/source_code/mysql_8_buildr/data/mysql-debug.sock",
      "DEFAULT_CHARSET""utf8mb4",
      "DEFAULT_COLLATION_FOR_UTF8MB4""utf8mb4_general_ci",
      "WITH_BOOST""${workspaceFolder}/mysql-8.0.24/boost",
      "DOWNLOAD_BOOST""0"
    },
    "files.associations": {
      "*.ipp""cpp",
      "*.cc" : "cpp"
    },
    "cmake.parallelJobs"0,         
    "cmake.cmakePath""cmake",    
    "cmake.sourceDirectory""${workspaceFolder}/mysql-8.0.24",   
  }



为了减少麻烦不要SSL和ZLIB 其它的也可以不要!


      "CMAKE_INSTALL_PREFIX""home/source_code/mysql_8_buildr",
      "MYSQL_DATADIR""home/source_code/mysql_8_buildr/data",
      "SYSCONFDIR""home/source_code/mysql_8_buildr/etc",
      "MYSQL_TCP_PORT""3309",
      "MYSQL_UNIX_ADDR""home/source_code/mysql_8_buildr/data/mysql-debug.sock",

这几个参数是因为本仙机器上已经安装了MYSQLD所以端口换成了3309,

另外直接在建造目录下跑数据库,不想在安装到其他目录下。不过大家还是按照编译安装方式安装到别的目录下。

设置好了就保存下 

CRTL+SHIFT+P 在顶部显示命令框,输入cmake:配置

然后CMAKE就检查你写的配置文件

也可以通过命令配置 输入SELECT A KIT 选择GCC版本

选择CMAKE 工程文件 CMAKELISTS.TXT  下面的图版本问题无关大雅,是MYSQL8源码根目录下的CMAKELISTS.TXT总工程文件,源码子目下有很多工程文件

遇到问题

解决了后删除重配

全量编译

 "cmake.parallelJobs": 0, 
这个参数表示 根据机器CPU多少自动配置并发线程,建议改成1.避免卡死!

[build] [100%] Linking CXX executable ../../../../runtime_output_directory/mysqlrouter_keyring
[build] [100%] Built target mysqlrouter_keyring
[build] Build finished with exit code 0

单线程编译比较久主要看SSD和CPU是否给力!

编译FAQ

9.2.1  error: ‘app_data_ptr’ does not name a type

这里有个问题, MYSQL 源码工程 插件部分 会在输出项目目录下 再生成源码文件,就是XCOM_VP.H

下图所示 XCOM->APP_DATA.H  调用XCOM_VP.H 文件, 该文件时编译产生的源码文件,奇怪吧!  没有生成完整,只有22行

实在找不到办法解决,直接从别的编译好的机器把代码贴过来。

9.2.2 CC1

[build] [ 73%] Generating xdr_gen/xcom_vp.h, xdr_gen/xcom_vp_xdr.c

[build] cpp: error trying to exec 'cc1': execvp: No such file or directory

[build] /usr/bin/rpcgen: C preprocessor failed with exit code 1

[build] cpp: error trying to exec 'cc1': execvp: No such file or directory

这个需要重新编译安装GCC 5.5

9.2.3 CXXABI_1.3.9

/runtime_output_directory/uca9dump: /lib64/libstdc++.so.6: version `CXXABI_1.3.9' not found

strings /home/source_code/gcc5/gcc-5.5.0/build/x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.21 | grep CXXABI

把它复制过去 然后创建软链接

以上你如果使用LINUX源码编译过了是不会发生的。

调试MYSQLD

添加调试文件

launch.json

{
    "version""0.2.0",
    "configurations": [
      {
        "name""(gdb) 启动",
        "type""cppdbg",
        "request""launch",
        "program""/home/source_code/mysql_8_buildr/bin/mysqld",
        "args": ["--defaults-file=/home/source_code/mysql_8_buildr/etc/my.cnf"],
        "stopAtEntry"false,
        "cwd""${fileDirname}",
        "environment": [],
        "externalConsole"false,
        "MIMode""gdb",
        "setupCommands": [
          {
            "description""为 gdb 启用整齐打印",
            "text""-enable-pretty-printing",
            "ignoreFailures"true
          },
          {
            "description""将反汇编风格设置为 Intel",
            "text""-gdb-set disassembly-flavor intel",
            "ignoreFailures"true
          }
        ]
      }
    ]
  }

下面是参数解释,上面是我具体目录,结合看大家就能理解

"program":"${workspaceRoot}/myexe",    //执行这个文件,相当于命令行中输入这行
"args":["param1","param2","2>&1",">","out"],    //program的参数,相当于命令行中在program后输入用空格隔开的这些参数。我这里前两个是执行文件自带的参数设置,后三个是将标准输出和标准错误输入到文件out中。
"stopAtEntry":false,    //大概是表示是否在main函数处停下,类似在main上打断点。
"cwd":"${workspaceRoot]",    //表示在哪个目录下执行program,相当于命令行中输入cd 该行

你们设置成安装目录, 参数可以为空,我这里设置参数避免去读/etc/my.cnf

启动调试程序

注意这里调试程序会启动MYSQLD服务器
启动调试,launch.json 文件配置完成之后,运行和调试
下拉框就能看到刚刚添加的配置,点击 (gdb)
启动
前面的小三角
,启动 MySQL,然后就可以开始调试了。

这样我们的MYSQL8版本成功启动了!

[root@localhost etc]# ps -ef | grep mysql
root     16509 16454  3 10:01 ?        00:00:02 /home/source_code/mysql_8_buildr/bin/mysqld --defaults-file=/home/source_code/mysql_8_buildr/etc/my.cnf
root     16675  6658  0 10:02 pts/22   00:00:00 grep --color mysql
root     27139     1  0 Feb20 ?        01:03:35 /usr/sbin/mysqld


设置断点

MySQL 源码中打个断点,先打开 sql/sql_parse.cc
 文件:

开始调试

 先暂时取消断点,启动MYSQL 客户端

再开启断点,然后在客户端输入SQL命令,输入完后就卡在那了

这时候VSCODE 断点被捕获

单步下去后我们看到边上的变量

通过选择,右键菜单,添加到监视器,我们看到这个SQL类型是SELECT

继续执行下去 这个ALL_TABLES变量 从语法解析获得数据,它是个结构体,在左边可以展开。

注意黄色的方块箭头,它指向的是将要执行的行代码,它上一行是执行过的。

增量编译

稍微改写下2038的限制

Sql_parse.cc

  if (thd->killed == THD::KILL_QUERY) thd->killed = THD::NOT_KILLED;
  thd->set_time();
  if (is_time_t_valid_for_timestamp(thd->query_start_in_secs()) == false) {

CTRL+鼠标 点击 is_time_t_valid_for_timestamp 进行跳转

my_time.h
inline bool is_time_t_valid_for_timestamp(time_t x) 
{
  return x <= TIMESTAMP_MAX_VALUE && x >= TIMESTAMP_MIN_VALUE;
}

2038 int32_t 改成4096 int64_t

/** Time handling defaults */
constexpr const int TIMESTAMP_MAX_YEAR = 2038;

/** Two-digit years < this are 20XX; >= this are 19XX */
constexpr const int YY_PART_YEAR = 70;
constexpr const int TIMESTAMP_MIN_YEAR = (1900 + YY_PART_YEAR - 1);

constexpr const int TIMESTAMP_MAX_VALUE = std::numeric_limits<std::int64_t>::max();
constexpr const int TIMESTAMP_MIN_VALUE = 1;


这个文件被#include <my_time.h> 很多地方,先看能否单独编译

CRTL+SHIFT+P

输入Cmake:B 然后选择生成目标

我们只生成MYSQLD 就行

这里选择建造的目录,然后手工复制到安装目录下

编译报错

改错 const int 改成const long 在linx 64下 long类型是64位,win下是32位

/** Time handling defaults */
constexpr const int TIMESTAMP_MAX_YEAR = 4096;

/** Two-digit years < this are 20XX; >= this are 19XX */
constexpr const int YY_PART_YEAR = 70;
constexpr const int TIMESTAMP_MIN_YEAR = (1900 + YY_PART_YEAR - 1);

constexpr const long TIMESTAMP_MAX_VALUE = std::numeric_limits<std::int64_t>::max();
constexpr const int TIMESTAMP_MIN_VALUE = 1;


编译成功

修改系统时间 提前进入2039年,原来PERCONA 8的数据库实例自动挂掉

[root@localhost etc]# date -s 20390308
Tue Mar  8 00:00:00 WIB 2039
[root@localhost etc]# hwclock
Wed 08 Mar 2023 02:10:27 PM WIB  -0.452625 seconds
[root@localhost etc]# hwclock -w
[root@localhost etc]# hwclock
Tue 08 Mar 2039 12:00:58 AM WIB  -0.822792 seconds

显示原来的SQLE数据库挂了
[root@localhost etc]# ps -ef | grep mysqld

我们的成功启动

[root@localhost etc]# clear
[root@localhost etc]# service mysql8debug start
Starting MySQL                                             [  OK  ]

测试效果

后言 KVM 虚拟机需要4G的内存,周四和周五 遇到了编译安装的时候说G++错误,然后就退出,错误信息很模糊,我以为自己的VBOX里安装的GCC CMAKE坏了.我以为删除了GCC和CMAKE 目录导致的,然后重新安装GCC,GCC编译需要1个多小时,.然后编译安装,已经用VSCODE编译过, 只是安装,可发现在VSCODE还是XSHELL里面都要再编译一次. 尤其是编译到52%,或者62%的时候才报. 浪费大把时间才能验证还会不会报错! 

MySQL 菜单

MYSQL OOM

获得MYSQL当前事务执行过的SQL

MYSQL 产生大量数据的过程

MYSQL 大页内存+锁定内存


文章转载自海鲨数据库架构师,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论